From 2a7ba9d47643fb00e9b2407f67de817e08cf9d5d Mon Sep 17 00:00:00 2001 From: eve_ <51251605+tofuandeve@users.noreply.github.com> Date: Mon, 5 Oct 2020 15:36:19 -0700 Subject: [PATCH 1/4] DOMContentLoaded API review spec - draft --- specs/DOMContentLoaded.md | 117 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 specs/DOMContentLoaded.md diff --git a/specs/DOMContentLoaded.md b/specs/DOMContentLoaded.md new file mode 100644 index 000000000..452288948 --- /dev/null +++ b/specs/DOMContentLoaded.md @@ -0,0 +1,117 @@ +# Background + +In response to consumers' requests for an event similar to the old [WebView DOMContentLoaded](https://docs.microsoft.com/en-us/microsoft-edge/hosting/webview#mswebviewdomcontentloaded), the WebView2 team has introduced DOMContentLoaded API which indicates that the main DOM elements have finished loading. +In this document we describe the new API. We'd appreciate your feedback. + +# Description +We propose adding DOMContentLoaded to CoreWebView2. This allows the developer to have an event that fires when the DOM is loaded after the WebView2 navigates to a page. + +# Examples +## Win32 C++ +``` +ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(AppWindow* appWindow) + : m_appWindow(appWindow), m_webView(appWindow->GetWebView()) +{ + //! [DOMContentLoaded] + // Register a handler for the DOMContentLoaded event. + // Check whether the DOM content loaded + CHECK_FAILURE(m_webView->add_DOMContentLoaded( + Callback( + [this](ICoreWebView2* sender, ICoreWebView2DOMContentLoadedEventArgs* args) + -> HRESULT { + m_webView->ExecuteScript( + L"let " + L"content=document.createElement(\"h2\");content.style.color='blue';" + L"content.textContent=\"This text was added by the host " + L"app\";document.body.appendChild(content);", + Callback( + [](HRESULT error, PCWSTR result) -> HRESULT { return S_OK; }) + .Get()); + return S_OK; + }) + .Get(), + &m_DOMContentLoadedToken)); + //! [DOMContentLoaded] +``` + +## C# +``` +webView.CoreWebView2.DOMContentLoaded += (object sender, CoreWebView2DOMContentLoadedEventArgs arg) => +{ + webView.ExecuteScriptAsync("let " + "content=document.createElement(\"h2\");content.style.color=" + "'blue';content.textContent= \"This text was added by the " + "host app\";document.body.appendChild(content);"); +}; +webView.NavigateToString(@"

DOMContentLoaded sample page

The content below will be added after DOM content is loaded

"); + +``` + +# API Notes + +See [API Details](#api-details) section below for API reference. +# API Details + +## Win32 C++ + +```IDL +interface ICoreWebView2_2; +interface ICoreWebView2DOMContentLoadedEventArgs; +interface ICoreWebView2DOMContentLoadedEventHandler; + +[uuid(9810c82b-8483-4f1c-b2f4-6244f1010c05), object, pointer_default(unique)] +interface ICoreWebView2_2 : ICoreWebView2 { + /// Add an event handler for the DOMContentLoaded event. + /// DOMContentLoaded fires when the initial html document has been parsed. + /// This aligns with the the document's DOMContentLoaded event in html + /// + /// \snippet ScenarioDOMContentLoaded-Staging.cpp + HRESULT add_DOMContentLoaded( + [in] ICoreWebView2StagingDOMContentLoadedEventHandler* eventHandler, + [out] EventRegistrationToken* token); + /// Remove an event handler previously added with add_DOMContentLoaded. + HRESULT remove_DOMContentLoaded( + [in] EventRegistrationToken token); +} + +/// Event args for the DOMContentLoaded event. +[uuid(E8BA4206-D6F8-42F1-9A6D-43C8A99C1F39), object, pointer_default(unique)] +interface ICoreWebView2DOMContentLoadedEventArgs : IUnknown { + /// The ID of the navigation. + [propget] HRESULT NavigationId([out, retval] UINT64* navigation_id); +} + +/// The caller implements this interface to receive the DOMContentLoaded +/// event. +[uuid(1E649181-785D-40B2-B4AE-AFACD3C6B8DD), object, pointer_default(unique)] +interface ICoreWebView2DOMContentLoadedEventHandler : IUnknown { + /// Called to provide the implementer with the event args for the + /// corresponding event. + HRESULT Invoke( + [in] ICoreWebView2* sender, + [in] ICoreWebView2DOMContentLoadedEventArgs* args); +} +``` + +## .NET and WinRT + +```c# +namespace Microsoft.Web.WebView2.Core +{ + runtimeclass CoreWebView2DOMContentLoadedEventArgs; + + runtimeclass CoreWebView2DOMContentLoadedEventArgs + { + // CoreWebView2DOMContentLoadedEventArgs + UInt64 NavigationId { get; }; + } + + runtimeclass CoreWebView2 + { + // CoreWebView2 + event Windows.Foundation.TypedEventHandler DOMContentLoaded; + } + + +} +``` From 8ef97a06578c0938779909cb9c54d79c64fdf054 Mon Sep 17 00:00:00 2001 From: Eve Le Date: Mon, 12 Oct 2020 13:19:40 -0700 Subject: [PATCH 2/4] Address comments on DOMContentLoaded API spec --- specs/DOMContentLoaded.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/specs/DOMContentLoaded.md b/specs/DOMContentLoaded.md index 452288948..d7c9b6e0b 100644 --- a/specs/DOMContentLoaded.md +++ b/specs/DOMContentLoaded.md @@ -14,16 +14,18 @@ ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(AppWindow* appWindow) { //! [DOMContentLoaded] // Register a handler for the DOMContentLoaded event. - // Check whether the DOM content loaded + // Event is raised when the DOM content is loaded CHECK_FAILURE(m_webView->add_DOMContentLoaded( Callback( [this](ICoreWebView2* sender, ICoreWebView2DOMContentLoadedEventArgs* args) -> HRESULT { m_webView->ExecuteScript( - L"let " - L"content=document.createElement(\"h2\");content.style.color='blue';" - L"content.textContent=\"This text was added by the host " - L"app\";document.body.appendChild(content);", + LR"~( + let content=document.createElement("h2"); + content.style.color='blue'; + content.textContent="This text was added by the host app"; + document.body.appendChild(content); + )~", Callback( [](HRESULT error, PCWSTR result) -> HRESULT { return S_OK; }) .Get()); @@ -38,9 +40,9 @@ ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(AppWindow* appWindow) ``` webView.CoreWebView2.DOMContentLoaded += (object sender, CoreWebView2DOMContentLoadedEventArgs arg) => { - webView.ExecuteScriptAsync("let " - "content=document.createElement(\"h2\");content.style.color=" - "'blue';content.textContent= \"This text was added by the " + webView.ExecuteScriptAsync("let " + + "content=document.createElement(\"h2\");content.style.color=" + + "'blue';content.textContent= \"This text was added by the " + "host app\";document.body.appendChild(content);"); }; webView.NavigateToString(@"

DOMContentLoaded sample page

The content below will be added after DOM content is loaded

"); @@ -62,7 +64,7 @@ interface ICoreWebView2DOMContentLoadedEventHandler; [uuid(9810c82b-8483-4f1c-b2f4-6244f1010c05), object, pointer_default(unique)] interface ICoreWebView2_2 : ICoreWebView2 { /// Add an event handler for the DOMContentLoaded event. - /// DOMContentLoaded fires when the initial html document has been parsed. + /// DOMContentLoaded is raised when the initial html document has been parsed. /// This aligns with the the document's DOMContentLoaded event in html /// /// \snippet ScenarioDOMContentLoaded-Staging.cpp From 18c2a3131b2255c9febd8150e51037194a4559d0 Mon Sep 17 00:00:00 2001 From: Eve Le Date: Wed, 14 Oct 2020 11:03:27 -0700 Subject: [PATCH 3/4] Address reviews on DOMContentLoaded API spec --- specs/DOMContentLoaded.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/DOMContentLoaded.md b/specs/DOMContentLoaded.md index d7c9b6e0b..c599e5ea2 100644 --- a/specs/DOMContentLoaded.md +++ b/specs/DOMContentLoaded.md @@ -40,7 +40,7 @@ ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(AppWindow* appWindow) ``` webView.CoreWebView2.DOMContentLoaded += (object sender, CoreWebView2DOMContentLoadedEventArgs arg) => { - webView.ExecuteScriptAsync("let " + + _ = webView.ExecuteScriptAsync("let " + "content=document.createElement(\"h2\");content.style.color=" + "'blue';content.textContent= \"This text was added by the " + "host app\";document.body.appendChild(content);"); @@ -79,8 +79,8 @@ interface ICoreWebView2_2 : ICoreWebView2 { /// Event args for the DOMContentLoaded event. [uuid(E8BA4206-D6F8-42F1-9A6D-43C8A99C1F39), object, pointer_default(unique)] interface ICoreWebView2DOMContentLoadedEventArgs : IUnknown { - /// The ID of the navigation. - [propget] HRESULT NavigationId([out, retval] UINT64* navigation_id); + /// The ID of the navigation which corresponds to other navigation ID properties on other navigation events. + [propget] HRESULT NavigationId([out, retval] UINT64* navigationId); } /// The caller implements this interface to receive the DOMContentLoaded From 6fba0572ca08641ebd9184fba094f810b7bd34aa Mon Sep 17 00:00:00 2001 From: Eve Le Date: Fri, 16 Oct 2020 16:11:21 -0700 Subject: [PATCH 4/4] Change AppWindow to SampleAppWindow --- specs/DOMContentLoaded.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/DOMContentLoaded.md b/specs/DOMContentLoaded.md index c599e5ea2..76bacad94 100644 --- a/specs/DOMContentLoaded.md +++ b/specs/DOMContentLoaded.md @@ -9,8 +9,8 @@ We propose adding DOMContentLoaded to CoreWebView2. This allows the developer to # Examples ## Win32 C++ ``` -ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(AppWindow* appWindow) - : m_appWindow(appWindow), m_webView(appWindow->GetWebView()) +ScenarioDOMContentLoaded::ScenarioDOMContentLoaded(SampleAppWindow* sampleAppWindow) + : m_sampleAppWindow(sampleAppWindow), m_webView(sampleAppWindow->GetWebView()) { //! [DOMContentLoaded] // Register a handler for the DOMContentLoaded event.