DevTools: Shadow DOM v0 polyfill
This polyfills Shadow DOM v0 on top of Shadow DOM v1 for old devtools
front ends.
Bug: 685385
Change-Id: Ia2a79a86012cbec2fc7cff3cb36fe4c9b631a381
Reviewed-on: https://chromium-review.googlesource.com/c/1366325
Reviewed-by: Dmitry Gozman <[email protected]>
Commit-Queue: Joel Einbinder <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#614893}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: d828088b0546192c7cb08fd8404ead6422e39cdf
diff --git a/front_end/devtools_compatibility.js b/front_end/devtools_compatibility.js
index 1319616..788ebe8 100644
--- a/front_end/devtools_compatibility.js
+++ b/front_end/devtools_compatibility.js
@@ -1172,6 +1172,52 @@
/** @type {!Array<string>} */
const styleRules = [];
+ // Shadow DOM V0 polyfill
+ if (majorVersion <= 73 && !Element.prototype.createShadowRoot) {
+ Element.prototype.createShadowRoot = function() {
+ try {
+ return this.attachShadow({mode: 'open'});
+ } catch (e) {
+ // some elements we use to add shadow roots can no
+ // longer have shadow roots.
+ const fakeShadowHost = document.createElement('span');
+ this.appendChild(fakeShadowHost);
+ fakeShadowHost.className = 'fake-shadow-host';
+ return fakeShadowHost.createShadowRoot();
+ }
+ };
+
+ const origAdd = DOMTokenList.prototype.add;
+ DOMTokenList.prototype.add = function(...tokens) {
+ if (tokens[0].startsWith('insertion-point') || tokens[0].startsWith('tabbed-pane-header'))
+ this._myElement.slot = '.' + tokens[0];
+ return origAdd.apply(this, tokens);
+ };
+
+ const origCreateElement = Document.prototype.createElement;
+ Document.prototype.createElement = function(tagName, ...rest) {
+ if (tagName === 'content')
+ tagName = 'slot';
+ const element = origCreateElement.call(this, tagName, ...rest);
+ element.classList._myElement = element;
+ return element;
+ };
+
+ Object.defineProperty(HTMLSlotElement.prototype, 'select', {
+ async set(selector) {
+ 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;
+ };
+ }
if (majorVersion <= 66) {
/** @type {(!function(number, number):Element|undefined)} */