Commit 684f471c authored by Kevin McNee's avatar Kevin McNee Committed by Commit Bot

Reland "Define guest view custom elements synchronously"

This reverts commit 331504cf.

Define guest view custom elements synchronously

Previously, we've had to wait for readystatechange before defining
the guest view custom elements because
1) there were circular dependencies that would cause errors if we
tried to perform the definition immediately, and
2) the Custom Elements V0 registration context was scoped to the
document rather than the window, so if we defined the elements
while the document was still on about:blank, the definition would
be available on about:blank, but not for the extension.

Now that the circular dependencies are fixed and guest view is
migrated to Custom Elements V1 (whose registration context is
scoped to the window), it is no longer necessary to wait for
readystatechange.

We now perform the definition immediately.

Bug: 810012
Change-Id: I009dbc7710316dd9f4b7fbe5a12ad091e6b597bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1869115Reviewed-by: default avatarJames MacLean <wjmaclean@chromium.org>
Commit-Queue: Kevin McNee <mcnee@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713584}
parent 5fbc82af
......@@ -15,20 +15,11 @@ var GuestViewInternalNatives = requireNative('guest_view_internal');
var IdGenerator = requireNative('id_generator');
var logging = requireNative('logging');
// Registers the browserplugin and guestview as custom elements once the
// document has loaded.
// Registers the browserplugin and guestview as custom elements.
// |containerElementType| is a GuestViewContainerElement (e.g. WebViewElement)
function registerElement(elementName, containerElementType) {
var useCapture = true;
window.addEventListener('readystatechange', function listener(event) {
if (document.readyState == 'loading')
return;
registerInternalElement($String.toLowerCase(elementName));
registerGuestViewElement(elementName, containerElementType);
$EventTarget.removeEventListener(window, event.type, listener, useCapture);
}, useCapture);
registerInternalElement($String.toLowerCase(elementName));
registerGuestViewElement(elementName, containerElementType);
}
// Registers the browser plugin <object> custom element. |viewType| is the
......
......@@ -11,7 +11,35 @@ var $CustomElementRegistry =
var $EventTarget = require('safeMethods').SafeMethods.$EventTarget;
var GuestViewInternalNatives = requireNative('guest_view_internal');
function registerDeniedElementInternal(viewType, permissionName) {
// Once the document has loaded, expose the error-providing element's
// constructor to user code via |window|.
// GuestView elements used to be defined only once the document had loaded (see
// https://crbug.com/810012). This has been fixed, but as seen in
// https://crbug.com/1014385, user code that does not have permission for a
// GuestView could be using the same name for another purpose. In order to avoid
// potential name collisions with user code, we preserve the previous
// asynchronous behaviour for exposing the constructor of the error-providing
// element via |window|.
function asyncProvideElementConstructor(viewType, elementConstructor) {
let useCapture = true;
window.addEventListener('readystatechange', function listener(event) {
if (document.readyState == 'loading')
return;
// If user code did use the name, we won't overwrite with the
// error-providing element.
if (!$Object.hasOwnProperty(window, viewType)) {
$Object.defineProperty(window, viewType, {
value: elementConstructor,
});
}
$EventTarget.removeEventListener(window, event.type, listener, useCapture);
}, useCapture);
}
// Registers an error-providing GuestView custom element.
function registerDeniedElement(viewType, permissionName) {
GuestViewInternalNatives.AllowGuestViewElementDefinition(() => {
var DeniedElement = class extends HTMLElement {
constructor() {
......@@ -23,29 +51,9 @@ function registerDeniedElementInternal(viewType, permissionName) {
}
$CustomElementRegistry.define(
window.customElements, $String.toLowerCase(viewType), DeniedElement);
// User code that does not have permission for this GuestView could be
// using the same name for another purpose, in which case we won't overwrite
// with the error-providing element.
if (!$Object.hasOwnProperty(window, viewType)) {
$Object.defineProperty(window, viewType, {
value: DeniedElement,
});
}
asyncProvideElementConstructor(viewType, DeniedElement);
});
}
// Registers an error-providing GuestView custom element.
function registerDeniedElement(viewType, permissionName) {
let useCapture = true;
window.addEventListener('readystatechange', function listener(event) {
if (document.readyState == 'loading')
return;
registerDeniedElementInternal(viewType, permissionName);
$EventTarget.removeEventListener(window, event.type, listener, useCapture);
}, useCapture);
}
// Exports.
exports.$set('registerDeniedElement', registerDeniedElement);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment