diff --git a/CefSharp.BrowserSubprocess.Core/Async/JavascriptAsyncMethodHandler.cpp b/CefSharp.BrowserSubprocess.Core/Async/JavascriptAsyncMethodHandler.cpp index 525f6626f0..7c45a4b01f 100644 --- a/CefSharp.BrowserSubprocess.Core/Async/JavascriptAsyncMethodHandler.cpp +++ b/CefSharp.BrowserSubprocess.Core/Async/JavascriptAsyncMethodHandler.cpp @@ -59,11 +59,10 @@ namespace CefSharp SerializeV8Object(arguments[i], params, i, _callbackRegistry); } - SetInt64(argList, 0, frame->GetIdentifier()); - SetInt64(argList, 1, _objectId); - SetInt64(argList, 2, callbackId); - argList->SetString(3, name); - argList->SetList(4, params); + SetInt64(argList, 0, _objectId); + SetInt64(argList, 1, callbackId); + argList->SetString(2, name); + argList->SetList(3, params); frame->SendProcessMessage(CefProcessId::PID_BROWSER, request); diff --git a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp index 4a7136db43..49488c0657 100644 --- a/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp +++ b/CefSharp.BrowserSubprocess.Core/CefAppUnmanagedWrapper.cpp @@ -123,8 +123,6 @@ namespace CefSharp //have been created auto contextCreatedMessage = CefProcessMessage::Create(kOnContextCreatedRequest); - SetInt64(contextCreatedMessage->GetArgumentList(), 0, frame->GetIdentifier()); - frame->SendProcessMessage(CefProcessId::PID_BROWSER, contextCreatedMessage); }; @@ -141,8 +139,6 @@ namespace CefSharp auto contextReleasedMessage = CefProcessMessage::Create(kOnContextReleasedRequest); - SetInt64(contextReleasedMessage->GetArgumentList(), 0, frame->GetIdentifier()); - frame->SendProcessMessage(CefProcessId::PID_BROWSER, contextReleasedMessage); auto browserWrapper = FindBrowserWrapper(browser->GetIdentifier()); @@ -172,19 +168,16 @@ namespace CefSharp auto focusedNodeChangedMessage = CefProcessMessage::Create(kOnFocusedNodeChanged); auto list = focusedNodeChangedMessage->GetArgumentList(); - // Needed in the browser process to get the frame. - SetInt64(list, 0, frame->GetIdentifier()); - // The node will be empty if an element loses focus but another one // doesn't gain focus. Only transfer information if the node is an // element. if (node != nullptr && node->IsElement()) { // True when a node exists, false if it doesn't. - list->SetBool(1, true); + list->SetBool(0, true); // Store the tag name. - list->SetString(2, node->GetElementTagName()); + list->SetString(1, node->GetElementTagName()); // Transfer the attributes in a Dictionary. auto attributes = CefDictionaryValue::Create(); @@ -195,11 +188,11 @@ namespace CefSharp attributes->SetString(iter.first, iter.second); } - list->SetDictionary(3, attributes); + list->SetDictionary(2, attributes); } else { - list->SetBool(1, false); + list->SetBool(0, false); } frame->SendProcessMessage(CefProcessId::PID_BROWSER, focusedNodeChangedMessage); @@ -210,9 +203,7 @@ namespace CefSharp auto uncaughtExceptionMessage = CefProcessMessage::Create(kOnUncaughtException); auto list = uncaughtExceptionMessage->GetArgumentList(); - // Needed in the browser process to get the frame. - SetInt64(list, 0, frame->GetIdentifier()); - list->SetString(1, exception->GetMessage()); + list->SetString(0, exception->GetMessage()); auto frames = CefListValue::Create(); for (auto i = 0; i < stackTrace->GetFrameCount(); i++) @@ -228,7 +219,7 @@ namespace CefSharp frames->SetList(i, frame); } - list->SetList(2, frames); + list->SetList(1, frames); frame->SendProcessMessage(CefProcessId::PID_BROWSER, uncaughtExceptionMessage); } @@ -336,7 +327,7 @@ namespace CefSharp } //both messages have the frameId stored at 0 and callbackId stored at index 1 - auto frameId = GetInt64(argList, 0); + auto frameId = frame->GetIdentifier(); int64 callbackId = GetInt64(argList, 1); if (name == kEvaluateJavascriptRequest) @@ -478,7 +469,7 @@ namespace CefSharp else if (name == kJavascriptCallbackDestroyRequest) { auto jsCallbackId = GetInt64(argList, 0); - auto frameId = GetInt64(argList, 1); + auto frameId = frame->GetIdentifier(); JavascriptRootObjectWrapper^ rootObjectWrapper; browserWrapper->JavascriptRootObjectWrappers->TryGetValue(frameId, rootObjectWrapper); if (rootObjectWrapper != nullptr && rootObjectWrapper->CallbackRegistry != nullptr) @@ -517,10 +508,10 @@ namespace CefSharp } else { - auto browserId = argList->GetInt(1); - auto frameId = GetInt64(argList, 2); - auto callbackId = GetInt64(argList, 3); - auto javascriptObjects = DeserializeJsObjects(argList, 4); + auto browserId = browser->GetIdentifier(); + auto frameId = frame->GetIdentifier(); + auto callbackId = GetInt64(argList, 1); + auto javascriptObjects = DeserializeJsObjects(argList, 2); //Caching of JavascriptObjects //TODO: JSB Should caching be configurable? On a per object basis? @@ -609,7 +600,7 @@ namespace CefSharp } else if (name == kJavascriptAsyncMethodCallResponse) { - auto frameId = GetInt64(argList, 0); + auto frameId = frame->GetIdentifier(); auto callbackId = GetInt64(argList, 1); JavascriptRootObjectWrapper^ rootObjectWrapper; diff --git a/CefSharp.BrowserSubprocess.Core/JavascriptPostMessageHandler.h b/CefSharp.BrowserSubprocess.Core/JavascriptPostMessageHandler.h index 33d352079b..8e6971c765 100644 --- a/CefSharp.BrowserSubprocess.Core/JavascriptPostMessageHandler.h +++ b/CefSharp.BrowserSubprocess.Core/JavascriptPostMessageHandler.h @@ -53,15 +53,13 @@ namespace CefSharp auto request = CefProcessMessage::Create(kJavascriptMessageReceived); auto argList = request->GetArgumentList(); - SetInt64(argList, 0, frame->GetIdentifier()); - auto params = CefListValue::Create(); SerializeV8Object(arguments[0], params, 0, _javascriptCallbackRegistry); //We're only interested in the first param if (params->GetSize() > 0) { - argList->SetValue(1, params->GetValue(0)); + argList->SetValue(0, params->GetValue(0)); } frame->SendProcessMessage(CefProcessId::PID_BROWSER, request); diff --git a/CefSharp.BrowserSubprocess.Core/RegisterBoundObjectHandler.h b/CefSharp.BrowserSubprocess.Core/RegisterBoundObjectHandler.h index 64da2d6985..4693a2c9c9 100644 --- a/CefSharp.BrowserSubprocess.Core/RegisterBoundObjectHandler.h +++ b/CefSharp.BrowserSubprocess.Core/RegisterBoundObjectHandler.h @@ -282,10 +282,8 @@ namespace CefSharp //Obtain a callbackId then send off the Request for objects auto callbackId = _callbackRegistry->SaveMethodCallback(callback); - argList->SetInt(0, browser->GetIdentifier()); - SetInt64(argList, 1, frame->GetIdentifier()); - SetInt64(argList, 2, callbackId); - argList->SetList(3, params); + SetInt64(argList, 0, callbackId); + argList->SetList(1, params); frame->SendProcessMessage(CefProcessId::PID_BROWSER, request); } diff --git a/CefSharp.Core/Internals/CefFrameWrapper.cpp b/CefSharp.Core/Internals/CefFrameWrapper.cpp index 9351f70b7c..6109008495 100644 --- a/CefSharp.Core/Internals/CefFrameWrapper.cpp +++ b/CefSharp.Core/Internals/CefFrameWrapper.cpp @@ -10,6 +10,11 @@ #include "Internals\CefFrameWrapper.h" #include "Internals\StringVisitor.h" #include "Internals\ClientAdapter.h" +#include "Internals\Serialization\Primitives.h" +#include "Internals\Messaging\Messages.h" + +using namespace CefSharp::Internals::Messaging; +using namespace CefSharp::Internals::Serialization; /// // True if this object is currently attached to a valid frame. @@ -240,9 +245,30 @@ Task^ CefFrameWrapper::EvaluateScriptAsync(String^ script, auto browser = _frame->GetBrowser(); auto host = browser->GetHost(); + //If we're unable to get the underlying browser/browserhost then return null + if (!browser.get() || !host.get()) + { + return nullptr; + } + auto client = static_cast(host->GetClient().get()); - return client->EvaluateScriptAsync(browser->GetIdentifier(), browser->IsPopup(), _frame->GetIdentifier(), script, scriptUrl, startLine, timeout); + auto pendingTaskRepository = client->GetPendingTaskRepository(); + + //create a new taskcompletionsource + auto idAndComplectionSource = pendingTaskRepository->CreatePendingTask(timeout); + + auto message = CefProcessMessage::Create(kEvaluateJavascriptRequest); + auto argList = message->GetArgumentList(); + SetInt64(argList, 0, _frame->GetIdentifier()); + SetInt64(argList, 1, idAndComplectionSource.Key); + argList->SetString(2, StringUtils::ToNative(script)); + argList->SetString(3, StringUtils::ToNative(scriptUrl)); + argList->SetInt(4, startLine); + + _frame->SendProcessMessage(CefProcessId::PID_RENDERER, message); + + return idAndComplectionSource.Value->Task; } /// @@ -388,4 +414,4 @@ void CefFrameWrapper::ThrowIfFrameInvalid() { throw gcnew Exception(L"The underlying frame is no longer valid - please check the IsValid property before calling!"); } -} \ No newline at end of file +} diff --git a/CefSharp.Core/Internals/ClientAdapter.cpp b/CefSharp.Core/Internals/ClientAdapter.cpp index baa14efea0..c791fa5632 100644 --- a/CefSharp.Core/Internals/ClientAdapter.cpp +++ b/CefSharp.Core/Internals/ClientAdapter.cpp @@ -635,10 +635,8 @@ namespace CefSharp auto msg = CefProcessMessage::Create(kJavascriptRootObjectResponse); auto responseArgList = msg->GetArgumentList(); responseArgList->SetBool(0, true); //Use Legacy Behaviour (auto bind on context creation) - responseArgList->SetInt(1, -1); //BrowserId - SetInt64(responseArgList, 2, 0); //FrameId - SetInt64(responseArgList, 3, 0); //CallbackId - SerializeJsObjects(objectRepository->GetObjects(nullptr), responseArgList, 4); + SetInt64(responseArgList, 1, 0); //CallbackId + SerializeJsObjects(objectRepository->GetObjects(nullptr), responseArgList, 2); browser->GetMainFrame()->SendProcessMessage(CefProcessId::PID_RENDERER, msg); } @@ -1050,10 +1048,8 @@ namespace CefSharp { auto objectRepository = _browserAdapter->JavascriptObjectRepository; - auto browserId = argList->GetInt(0); - auto frameId = GetInt64(argList, 1); - auto callbackId = GetInt64(argList, 2); - auto objectNames = argList->GetList(3); + auto callbackId = GetInt64(argList, 0); + auto objectNames = argList->GetList(1); auto names = gcnew List(objectNames->GetSize()); for (auto i = 0; i < objectNames->GetSize(); i++) @@ -1069,10 +1065,8 @@ namespace CefSharp auto msg = CefProcessMessage::Create(kJavascriptRootObjectResponse); auto responseArgList = msg->GetArgumentList(); responseArgList->SetBool(0, false); //Use LegacyBehaviour (false) - responseArgList->SetInt(1, browserId); - SetInt64(responseArgList, 2, frameId); - SetInt64(responseArgList, 3, callbackId); - SerializeJsObjects(objs, responseArgList, 4); + SetInt64(responseArgList, 1, callbackId); + SerializeJsObjects(objs, responseArgList, 2); frame->SendProcessMessage(CefProcessId::PID_RENDERER, msg); } @@ -1103,11 +1097,9 @@ namespace CefSharp } else if (name == kOnContextCreatedRequest) { - auto frame = browser->GetFrame(GetInt64(argList, 0)); - //In certain circumstances the frame has already been destroyed by the time //we get here, only continue if we have a valid frame reference - if (frame.get()) + if (frame.get() && frame->IsValid()) { if (frame->IsMain()) { @@ -1129,11 +1121,9 @@ namespace CefSharp } else if (name == kOnContextReleasedRequest) { - auto frame = browser->GetFrame(GetInt64(argList, 0)); - //In certain circumstances the frame has already been destroyed by the time //we get here, only continue if we have a valid frame reference - if (frame.get()) + if (frame.get() && frame->IsValid()) { if (frame->IsMain()) { @@ -1160,19 +1150,18 @@ namespace CefSharp { IDomNode^ node = nullptr; - // 0: frame ID (int 64) - // 1: is a node (bool) - // 2: tag name (string) - // 3: attributes (dictionary) + // 0: is a node (bool) + // 1: tag name (string) + // 2: attributes (dictionary) auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup()); - CefFrameWrapper frameWrapper(browser->GetFrame(GetInt64(argList, 0))); + CefFrameWrapper frameWrapper(frame); - auto notEmpty = argList->GetBool(1); + auto notEmpty = argList->GetBool(0); if (notEmpty) { // Node information was passed from the render process. - auto tagName = StringUtils::ToClr(argList->GetString(2)); - auto argAttributes = argList->GetDictionary(3); + auto tagName = StringUtils::ToClr(argList->GetString(1)); + auto argAttributes = argList->GetDictionary(2); auto attributes = gcnew System::Collections::Generic::Dictionary(); CefDictionaryValue::KeyList keys; argAttributes->GetKeys(keys); @@ -1194,14 +1183,14 @@ namespace CefSharp if (handler != nullptr) { auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup()); - CefFrameWrapper frameWrapper(browser->GetFrame(GetInt64(argList, 0))); + CefFrameWrapper frameWrapper(frame); auto exception = gcnew JavascriptException(); - exception->Message = StringUtils::ToClr(argList->GetString(1)); + exception->Message = StringUtils::ToClr(argList->GetString(0)); auto stackTrace = gcnew System::Collections::Generic::List(); - auto argFrames = argList->GetList(2); + auto argFrames = argList->GetList(1); for (auto i = 0; i < static_cast(argFrames->GetSize()); i++) { @@ -1248,11 +1237,11 @@ namespace CefSharp } else if (name == kJavascriptAsyncMethodCallRequest && !_browserAdapter->IsDisposed) { - auto frameId = GetInt64(argList, 0); - auto objectId = GetInt64(argList, 1); - auto callbackId = GetInt64(argList, 2); - auto methodName = StringUtils::ToClr(argList->GetString(3)); - auto arguments = argList->GetList(4); + auto frameId = frame->GetIdentifier(); + auto objectId = GetInt64(argList, 0); + auto callbackId = GetInt64(argList, 1); + auto methodName = StringUtils::ToClr(argList->GetString(2)); + auto arguments = argList->GetList(3); auto methodInvocation = gcnew MethodInvocation(browser->GetIdentifier(), frameId, objectId, methodName, (callbackId > 0 ? Nullable(callbackId) : Nullable())); for (auto i = 0; i < static_cast(arguments->GetSize()); i++) { @@ -1265,16 +1254,14 @@ namespace CefSharp } else if (name == kJavascriptMessageReceived) { - auto frame = browser->GetFrame(GetInt64(argList, 0)); - //In certain circumstances the frame has already been destroyed by the time //we get here, only continue if we have a valid frame reference - if (frame.get()) + if (frame.get() && frame->IsValid()) { auto browserWrapper = GetBrowserWrapper(browser->GetIdentifier(), browser->IsPopup()); CefFrameWrapper frameWrapper(frame); - auto message = DeserializeObject(argList, 1, callbackFactory); + auto message = DeserializeObject(argList, 0, callbackFactory); _browserControl->SetJavascriptMessageReceived(gcnew JavascriptMessageReceivedEventArgs(browserWrapper, %frameWrapper, message)); } @@ -1285,37 +1272,6 @@ namespace CefSharp return handled; } - Task^ ClientAdapter::EvaluateScriptAsync(int browserId, bool isBrowserPopup, int64 frameId, String^ script, String^ scriptUrl, int startLine, Nullable timeout) - { - auto browser = GetBrowserWrapper(browserId, isBrowserPopup); - - //If we're unable to get the underlying browser wrapper then return null - if (browser == nullptr) - { - return nullptr; - } - - auto browserWrapper = static_cast(browser); - auto cefBrowser = browserWrapper->Browser; - - //create a new taskcompletionsource - auto idAndComplectionSource = _pendingTaskRepository->CreatePendingTask(timeout); - - auto message = CefProcessMessage::Create(kEvaluateJavascriptRequest); - auto argList = message->GetArgumentList(); - SetInt64(argList, 0, frameId); - SetInt64(argList, 1, idAndComplectionSource.Key); - argList->SetString(2, StringUtils::ToNative(script)); - argList->SetString(3, StringUtils::ToNative(scriptUrl)); - argList->SetInt(4, startLine); - - auto frame = cefBrowser->GetFrame(frameId); - - frame->SendProcessMessage(CefProcessId::PID_RENDERER, message); - - return idAndComplectionSource.Value->Task; - } - PendingTaskRepository^ ClientAdapter::GetPendingTaskRepository() { return _pendingTaskRepository; diff --git a/CefSharp.Core/Internals/ClientAdapter.h b/CefSharp.Core/Internals/ClientAdapter.h index d5ff0c54cb..2a16876acc 100644 --- a/CefSharp.Core/Internals/ClientAdapter.h +++ b/CefSharp.Core/Internals/ClientAdapter.h @@ -207,9 +207,6 @@ namespace CefSharp virtual DECL void OnAudioStreamPacket(CefRefPtr browser, int audio_stream_id, const float** data, int frames, int64 pts) OVERRIDE; virtual DECL void OnAudioStreamStopped(CefRefPtr browser, int audio_stream_id) OVERRIDE; - //sends out an eval script request to the render process - Task^ EvaluateScriptAsync(int browserId, bool isBrowserPopup, int64 frameId, String^ script, String^ scriptUrl, int startLine, Nullable timeout); - IMPLEMENT_REFCOUNTING(ClientAdapter); }; } diff --git a/CefSharp.Example/Resources/BindingTestSingle.html b/CefSharp.Example/Resources/BindingTestSingle.html index 7499863105..5160431aaa 100644 --- a/CefSharp.Example/Resources/BindingTestSingle.html +++ b/CefSharp.Example/Resources/BindingTestSingle.html @@ -5,11 +5,6 @@ -
- These tests require CefSharpSettings.ConcurrentTaskExecution = true; - Which by default is set to false -
-
@@ -19,43 +14,15 @@ { await CefSharp.BindObjectAsync("boundAsync"); - QUnit.test("ReturnTaskStringAsync:", function (assert) - { - let asyncCallback = assert.async(); - - boundAsync.returnTaskStringAsync().then(function (actualResult) - { - const expectedResult = 'ReturnTaskStringAsync'; - - assert.equal(expectedResult, actualResult, "Return string " + expectedResult); - - asyncCallback(); - }); - }); - - QUnit.test("VoidReturnAsync Test:", function (assert) + QUnit.test("Async call (Divide 16 / 2):", function (assert) { - let asyncCallback = assert.async(); + var asyncCallback = assert.async(); - boundAsync.voidReturnAsync().then(function (actualResult) + boundAsync.div(16, 2).then(function (actualResult) { - const expectedResult = null; + const expectedResult = 8 - assert.equal(expectedResult, actualResult, "Return null"); - - asyncCallback(); - }); - }); - - QUnit.test("AsyncWaitTwoSeconds Test:", function (assert) - { - let asyncCallback = assert.async(); - - const expectedResult = "This method waited two seconds"; - - boundAsync.asyncWaitTwoSeconds(expectedResult).then(function (actualResult) - { - assert.equal(expectedResult, actualResult, "Return string " + expectedResult); + assert.equal(expectedResult, actualResult, "Divide 16 / 2 resulted in " + expectedResult); asyncCallback(); });