interface ICoreWebView2ExperimentalFrame3

Note

This reference is no longer being maintained. For the latest API reference, see WebView2 API Reference.

Note

This an experimental API that is shipped with our prerelease SDK. See WebView2 release notes.

interface ICoreWebView2ExperimentalFrame3
  : public IUnknown

This is an extension of the ICoreWebView2Frame Experimental interface.

Summary

Members Descriptions
add_PermissionRequested Add an event handler for the PermissionRequested event.
remove_PermissionRequested Remove an event handler previously added with add_PermissionRequested

Applies to

Product Introduced
WebView2 Win32 N/A
WebView2 Win32 Prerelease 1.0.1133

Members

add_PermissionRequested

Add an event handler for the PermissionRequested event.

public HRESULT add_PermissionRequested(ICoreWebView2ExperimentalFramePermissionRequestedEventHandler * handler, EventRegistrationToken * token)

PermissionRequested is raised when content in an iframe any of its descendant iframes requests permission to privileged resources.

This relates to the PermissionRequested event on the CoreWebView2. Both these events will be raised in the case of an iframe requesting permission. The CoreWebView2Frame's event handlers will be invoked before the event handlers on the CoreWebView2. If the Handled property of the PermissionRequestedEventArgs is set to TRUE within the CoreWebView2Frame event handler, then the event will not be raised on the CoreWebView2, and it's event handlers will not be invoked.

In the case of nested iframes, the 'PermissionRequested' event will be raised from the top level iframe.

If a deferral is not taken on the event args, the subsequent scripts are blocked until the event handler returns. If a deferral is taken, the scripts are blocked until the deferral is completed.

    m_webView4 = m_webView.try_query<ICoreWebView2_4>();
    if (m_webView4)
    {
        CHECK_FAILURE(m_webView4->add_FrameCreated(
            Callback<ICoreWebView2FrameCreatedEventHandler>(
                [this](ICoreWebView2* sender, ICoreWebView2FrameCreatedEventArgs* args) -> HRESULT {
                    wil::com_ptr<ICoreWebView2Frame> webviewFrame;
                    CHECK_FAILURE(args->get_Frame(&webviewFrame));

                    m_experimentalFrame3 = webviewFrame.try_query<ICoreWebView2ExperimentalFrame3>();
                    if (m_experimentalFrame3)
                    {
                        CHECK_FAILURE(m_experimentalFrame3->add_PermissionRequested(
                            Callback<ICoreWebView2ExperimentalFramePermissionRequestedEventHandler>(
                                [this](ICoreWebView2Frame* sender,
                                   ICoreWebView2ExperimentalPermissionRequestedEventArgs* args)
                                      -> HRESULT {
                                        // If we set Handled to true, then we will not fire the PermissionRequested
                                        // event off of the CoreWebView2.
                                        args->put_Handled(true);

                                        auto showDialog = [this, args]
                                        {
                                          COREWEBVIEW2_PERMISSION_KIND kind =
                                              COREWEBVIEW2_PERMISSION_KIND_UNKNOWN_PERMISSION;
                                          BOOL userInitiated = FALSE;
                                          wil::unique_cotaskmem_string uri;

                                          CHECK_FAILURE(args->get_PermissionKind(&kind));
                                          CHECK_FAILURE(args->get_IsUserInitiated(&userInitiated));
                                          CHECK_FAILURE(args->get_Uri(&uri));

                                          auto cached_key = std::make_tuple(
                                              std::wstring(uri.get()), kind, userInitiated);

                                          auto cached_permission =
                                              m_cached_permissions.find(cached_key);
                                          if (cached_permission != m_cached_permissions.end())
                                          {
                                              bool allow = cached_permission->second;
                                              if (allow)
                                              {
                                                  CHECK_FAILURE(args->put_State(
                                                      COREWEBVIEW2_PERMISSION_STATE_ALLOW));
                                              }
                                              else
                                              {
                                                  CHECK_FAILURE(args->put_State(
                                                      COREWEBVIEW2_PERMISSION_STATE_DENY));
                                              }
                                              return S_OK;
                                          }

                                          std::wstring message =
                                            L"An iframe has requested device permission for ";
                                          message += SettingsComponent::NameOfPermissionKind(kind);
                                          message += L" to the website at ";
                                          message += uri.get();
                                          message += L"?\n\n";
                                          message += L"Do you want to grant permission?\n";
                                          message +=
                                              (userInitiated
                                                  ? L"This request came from a user gesture."
                                                  : L"This request did not come from a user "
                                                    L"gesture.");

                                          int response = MessageBox(
                                              nullptr, message.c_str(), L"Permission Request",
                                              MB_YESNOCANCEL | MB_ICONWARNING);

                                          if (response == IDYES)
                                          {
                                              m_cached_permissions[cached_key] = true;
                                          }

                                          if (response == IDNO)
                                          {
                                              m_cached_permissions[cached_key] = false;
                                          }

                                          COREWEBVIEW2_PERMISSION_STATE state =
                                              response == IDYES
                                                  ? COREWEBVIEW2_PERMISSION_STATE_ALLOW
                                                  : response == IDNO ? COREWEBVIEW2_PERMISSION_STATE_DENY
                                                                  : COREWEBVIEW2_PERMISSION_STATE_DEFAULT;

                                          CHECK_FAILURE(args->put_State(state));
                                          return S_OK;
                                        };

                                        // Obtain a deferral for the event so that the CoreWebView2
                                        // doesn't examine the properties we set on the event args until
                                        // after we call the Complete method asynchronously later.
                                        wil::com_ptr<ICoreWebView2Deferral> deferral;
                                        CHECK_FAILURE(args->GetDeferral(&deferral));

                                        m_appWindow->RunAsync([deferral, showDialog]() {
                                            showDialog();
                                            CHECK_FAILURE(deferral->Complete());
                                        });

                                        return S_OK;
                            }).Get(),
                            &m_PermissionRequestedToken));
                    }

                    return S_OK;
            }).Get(),
            &m_FrameCreatedToken));
    }

remove_PermissionRequested

Remove an event handler previously added with add_PermissionRequested

public HRESULT remove_PermissionRequested(EventRegistrationToken token)