DevTools: Polyfill Custom Elements V0 for old frontends
Bug: 685385
Change-Id: I1adae3ac86a2af361b1253f7e723aa86a7ce397e
Reviewed-on: https://chromium-review.googlesource.com/c/1371086
Reviewed-by: Dmitry Gozman <[email protected]>
Commit-Queue: Joel Einbinder <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#615780}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 64e9bfb30b51952e956210ce1c60a6b69e2b405f
diff --git a/front_end/devtools_compatibility.js b/front_end/devtools_compatibility.js
index 788ebe8..8ff215b 100644
--- a/front_end/devtools_compatibility.js
+++ b/front_end/devtools_compatibility.js
@@ -1208,14 +1208,59 @@
this.name = selector;
}
});
- const origCreateElementWithClass = Document.prototype.createElementWithClass;
- Document.prototype.createElementWithClass = function(tagName, className, ...rest) {
- if (tagName !== 'button' || (className !== 'soft-dropdown' && className !== 'dropdown-button'))
- return origCreateElementWithClass.call(this, tagName, className, ...rest);
- const element = origCreateElementWithClass.call(this, 'div', className, ...rest);
- element.tabIndex = 0;
- element.role = 'button';
- return element;
+
+ // Document.prototype.createElementWithClass is a DevTools method, so we
+ // need to wait for DOMContentLoaded in order to override it.
+ if (window.document.head &&
+ (window.document.readyState === 'complete' || window.document.readyState === 'interactive'))
+ overrideCreateElementWithClass();
+ else
+ window.addEventListener('DOMContentLoaded', overrideCreateElementWithClass);
+
+ function overrideCreateElementWithClass() {
+ window.removeEventListener('DOMContentLoaded', overrideCreateElementWithClass);
+
+ const origCreateElementWithClass = Document.prototype.createElementWithClass;
+ Document.prototype.createElementWithClass = function(tagName, className, ...rest) {
+ if (tagName !== 'button' || (className !== 'soft-dropdown' && className !== 'dropdown-button'))
+ return origCreateElementWithClass.call(this, tagName, className, ...rest);
+ const element = origCreateElementWithClass.call(this, 'div', className, ...rest);
+ element.tabIndex = 0;
+ element.role = 'button';
+ return element;
+ };
+ }
+ }
+
+ // Custom Elements V0 polyfill
+ if (majorVersion <= 73 && !Document.prototype.registerElement) {
+ const fakeRegistry = new Map();
+ Document.prototype.registerElement = function(typeExtension, options) {
+ const {prototype, extends: localName} = options;
+ const document = this;
+ const callback = function() {
+ const element = document.createElement(localName || typeExtension);
+ const skip = new Set(['constructor', '__proto__']);
+ for (const key of Object.keys(Object.getOwnPropertyDescriptors(prototype.__proto__ || {}))) {
+ if (skip.has(key))
+ continue;
+ element[key] = prototype[key];
+ }
+ element.setAttribute('is', typeExtension);
+ if (element['createdCallback'])
+ element['createdCallback']();
+ return element;
+ };
+ fakeRegistry.set(typeExtension, callback);
+ return callback;
+ };
+
+ const origCreateElement = Document.prototype.createElement;
+ Document.prototype.createElement = function(tagName, fakeCustomElementType) {
+ const fakeConstructor = fakeRegistry.get(fakeCustomElementType);
+ if (fakeConstructor)
+ return fakeConstructor();
+ return origCreateElement.call(this, tagName, fakeCustomElementType);
};
}
@@ -1359,16 +1404,7 @@
return style;
}
- function windowLoaded() {
- window.removeEventListener('DOMContentLoaded', windowLoaded, false);
- installBackwardsCompatibility();
- }
-
- if (window.document.head &&
- (window.document.readyState === 'complete' || window.document.readyState === 'interactive'))
- installBackwardsCompatibility();
- else
- window.addEventListener('DOMContentLoaded', windowLoaded, false);
+ installBackwardsCompatibility();
/** @type {(!function(string, boolean=):boolean)|undefined} */
DOMTokenList.prototype.__originalDOMTokenListToggle;