// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /* eslint-disable indent */ (function(window) { // DevToolsAPI ---------------------------------------------------------------- /** * @unrestricted */ const DevToolsAPIImpl = class { constructor() { /** * @type {number} */ this._lastCallId = 0; /** * @type {!Object.} */ this._callbacks = {}; /** * @type {!Array.} */ this._pendingExtensionDescriptors = []; /** * @type {?function(!ExtensionDescriptor)} */ this._addExtensionCallback = null; } /** * @param {number} id * @param {?Object} arg */ embedderMessageAck(id, arg) { const callback = this._callbacks[id]; delete this._callbacks[id]; if (callback) { callback(arg); } } /** * @param {string} method * @param {!Array.<*>} args * @param {?function(?Object)} callback */ sendMessageToEmbedder(method, args, callback) { const callId = ++this._lastCallId; if (callback) { this._callbacks[callId] = callback; } const message = {'id': callId, 'method': method}; if (args.length) { message.params = args; } DevToolsHost.sendMessageToEmbedder(JSON.stringify(message)); } /** * @param {string} method * @param {!Array<*>} args */ _dispatchOnInspectorFrontendAPI(method, args) { const inspectorFrontendAPI = /** @type {!Object} */ (window['InspectorFrontendAPI']); inspectorFrontendAPI[method].apply(inspectorFrontendAPI, args); } // API methods below this line -------------------------------------------- /** * @param {!Array.} extensions */ addExtensions(extensions) { // Support for legacy front-ends (} devices */ devicesUpdated(devices) { this._dispatchOnInspectorFrontendAPI('devicesUpdated', [devices]); } /** * @param {string} message */ dispatchMessage(message) { this._dispatchOnInspectorFrontendAPI('dispatchMessage', [message]); } /** * @param {string} messageChunk * @param {number} messageSize */ dispatchMessageChunk(messageChunk, messageSize) { this._dispatchOnInspectorFrontendAPI('dispatchMessageChunk', [messageChunk, messageSize]); } enterInspectElementMode() { this._dispatchOnInspectorFrontendAPI('enterInspectElementMode', []); } /** * @param {!{r: number, g: number, b: number, a: number}} color */ eyeDropperPickedColor(color) { this._dispatchOnInspectorFrontendAPI('eyeDropperPickedColor', [color]); } /** * @param {!Array.} fileSystems */ fileSystemsLoaded(fileSystems) { this._dispatchOnInspectorFrontendAPI('fileSystemsLoaded', [fileSystems]); } /** * @param {string} fileSystemPath */ fileSystemRemoved(fileSystemPath) { this._dispatchOnInspectorFrontendAPI('fileSystemRemoved', [fileSystemPath]); } /** * @param {?string} error * @param {?{type: string, fileSystemName: string, rootURL: string, fileSystemPath: string}} fileSystem */ fileSystemAdded(error, fileSystem) { this._dispatchOnInspectorFrontendAPI('fileSystemAdded', [error, fileSystem]); } /** * @param {!Array} changedPaths * @param {!Array} addedPaths * @param {!Array} removedPaths */ fileSystemFilesChangedAddedRemoved(changedPaths, addedPaths, removedPaths) { // Support for legacy front-ends (} files */ searchCompleted(requestId, fileSystemPath, files) { this._dispatchOnInspectorFrontendAPI('searchCompleted', [requestId, fileSystemPath, files]); } /** * @param {string} tabId */ setInspectedTabId(tabId) { this._inspectedTabIdValue = tabId; // Support for legacy front-ends ()} callback */ getPreferences(callback) { DevToolsAPI.sendMessageToEmbedder('getPreferences', [], /** @type {function(?Object)} */ (callback)); } /** * @override * @param {string} name * @param {string} value */ setPreference(name, value) { DevToolsAPI.sendMessageToEmbedder('setPreference', [name, value], null); } /** * @override * @param {string} name */ removePreference(name) { DevToolsAPI.sendMessageToEmbedder('removePreference', [name], null); } /** * @override */ clearPreferences() { DevToolsAPI.sendMessageToEmbedder('clearPreferences', [], null); } /** * @override * @param {string} origin * @param {string} script */ setInjectedScriptForOrigin(origin, script) { DevToolsAPI.sendMessageToEmbedder('registerExtensionsAPI', [origin, script], null); } /** * @override * @param {string} url */ inspectedURLChanged(url) { DevToolsAPI.sendMessageToEmbedder('inspectedURLChanged', [url], null); } /** * @override * @param {string} text */ copyText(text) { DevToolsHost.copyText(text); } /** * @override * @param {string} url */ openInNewTab(url) { DevToolsAPI.sendMessageToEmbedder('openInNewTab', [url], null); } /** * @override * @param {string} fileSystemPath */ showItemInFolder(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder('showItemInFolder', [fileSystemPath], null); } /** * @override * @param {string} url * @param {string} content * @param {boolean} forceSaveAs */ save(url, content, forceSaveAs) { DevToolsAPI.sendMessageToEmbedder('save', [url, content, forceSaveAs], null); } /** * @override * @param {string} url * @param {string} content */ append(url, content) { DevToolsAPI.sendMessageToEmbedder('append', [url, content], null); } /** * @override * @param {string} url */ close(url) { } /** * @override * @param {string} message */ sendMessageToBackend(message) { DevToolsAPI.sendMessageToEmbedder('dispatchProtocolMessage', [message], null); } /** * @override * @param {string} actionName * @param {number} actionCode * @param {number} bucketSize */ recordEnumeratedHistogram(actionName, actionCode, bucketSize) { // Support for M49 frontend. if (actionName === 'DevTools.DrawerShown') { return; } DevToolsAPI.sendMessageToEmbedder('recordEnumeratedHistogram', [actionName, actionCode, bucketSize], null); } /** * @override * @param {string} histogramName * @param {number} duration */ recordPerformanceHistogram(histogramName, duration) { DevToolsAPI.sendMessageToEmbedder('recordPerformanceHistogram', [histogramName, duration], null); } /** * @override * @param {string} umaName */ recordUserMetricsAction(umaName) { DevToolsAPI.sendMessageToEmbedder('recordUserMetricsAction', [umaName], null); } /** * @override */ requestFileSystems() { DevToolsAPI.sendMessageToEmbedder('requestFileSystems', [], null); } /** * @override * @param {string=} type */ addFileSystem(type) { DevToolsAPI.sendMessageToEmbedder('addFileSystem', [type || ''], null); } /** * @override * @param {string} fileSystemPath */ removeFileSystem(fileSystemPath) { DevToolsAPI.sendMessageToEmbedder('removeFileSystem', [fileSystemPath], null); } /** * @override * @param {string} fileSystemId * @param {string} registeredName * @return {?DOMFileSystem} */ isolatedFileSystem(fileSystemId, registeredName) { return DevToolsHost.isolatedFileSystem(fileSystemId, registeredName); } /** * @override * @param {!FileSystem} fileSystem */ upgradeDraggedFileSystemPermissions(fileSystem) { DevToolsHost.upgradeDraggedFileSystemPermissions(fileSystem); } /** * @override * @param {number} requestId * @param {string} fileSystemPath * @param {string} excludedFolders */ indexPath(requestId, fileSystemPath, excludedFolders) { // |excludedFolders| added in M67. For backward compatibility, // pass empty array. excludedFolders = excludedFolders || '[]'; DevToolsAPI.sendMessageToEmbedder('indexPath', [requestId, fileSystemPath, excludedFolders], null); } /** * @override * @param {number} requestId */ stopIndexing(requestId) { DevToolsAPI.sendMessageToEmbedder('stopIndexing', [requestId], null); } /** * @override * @param {number} requestId * @param {string} fileSystemPath * @param {string} query */ searchInPath(requestId, fileSystemPath, query) { DevToolsAPI.sendMessageToEmbedder('searchInPath', [requestId, fileSystemPath, query], null); } /** * @override * @return {number} */ zoomFactor() { return DevToolsHost.zoomFactor(); } /** * @override */ zoomIn() { DevToolsAPI.sendMessageToEmbedder('zoomIn', [], null); } /** * @override */ zoomOut() { DevToolsAPI.sendMessageToEmbedder('zoomOut', [], null); } /** * @override */ resetZoom() { DevToolsAPI.sendMessageToEmbedder('resetZoom', [], null); } /** * @override * @param {string} shortcuts */ setWhitelistedShortcuts(shortcuts) { DevToolsAPI.sendMessageToEmbedder('setWhitelistedShortcuts', [shortcuts], null); } /** * @override * @param {boolean} active */ setEyeDropperActive(active) { DevToolsAPI.sendMessageToEmbedder('setEyeDropperActive', [active], null); } /** * @override * @param {!Array} certChain */ showCertificateViewer(certChain) { DevToolsAPI.sendMessageToEmbedder('showCertificateViewer', [JSON.stringify(certChain)], null); } /** * Only needed to run Lighthouse on old devtools. * @override * @param {function()} callback */ reattach(callback) { DevToolsAPI.sendMessageToEmbedder('reattach', [], callback); } /** * @override */ readyForTest() { DevToolsAPI.sendMessageToEmbedder('readyForTest', [], null); } /** * @override */ connectionReady() { DevToolsAPI.sendMessageToEmbedder('connectionReady', [], null); } /** * @override * @param {boolean} value */ setOpenNewWindowForPopups(value) { DevToolsAPI.sendMessageToEmbedder('setOpenNewWindowForPopups', [value], null); } /** * @override * @param {!Adb.Config} config */ setDevicesDiscoveryConfig(config) { DevToolsAPI.sendMessageToEmbedder( 'setDevicesDiscoveryConfig', [ config.discoverUsbDevices, config.portForwardingEnabled, JSON.stringify(config.portForwardingConfig), config.networkDiscoveryEnabled, JSON.stringify(config.networkDiscoveryConfig) ], null); } /** * @override * @param {boolean} enabled */ setDevicesUpdatesEnabled(enabled) { DevToolsAPI.sendMessageToEmbedder('setDevicesUpdatesEnabled', [enabled], null); } /** * @override * @param {string} pageId * @param {string} action */ performActionOnRemotePage(pageId, action) { DevToolsAPI.sendMessageToEmbedder('performActionOnRemotePage', [pageId, action], null); } /** * @override * @param {string} browserId * @param {string} url */ openRemotePage(browserId, url) { DevToolsAPI.sendMessageToEmbedder('openRemotePage', [browserId, url], null); } /** * @override */ openNodeFrontend() { DevToolsAPI.sendMessageToEmbedder('openNodeFrontend', [], null); } /** * @override * @param {number} x * @param {number} y * @param {!Array.} items * @param {!Document} document */ showContextMenuAtPoint(x, y, items, document) { DevToolsHost.showContextMenuAtPoint(x, y, items, document); } /** * @override * @return {boolean} */ isHostedMode() { return DevToolsHost.isHostedMode(); } /** * @override * @param {function(!ExtensionDescriptor)} callback */ setAddExtensionCallback(callback) { DevToolsAPI.setAddExtensionCallback(callback); } // Backward-compatible methods below this line -------------------------------------------- /** * Support for legacy front-ends (} */ const properties = [ 'advancedSearchConfig', 'auditsPanelSplitViewState', 'auditsSidebarWidth', 'blockedURLs', 'breakpoints', 'cacheDisabled', 'colorFormat', 'consoleHistory', 'consoleTimestampsEnabled', 'cpuProfilerView', 'cssSourceMapsEnabled', 'currentDockState', 'customColorPalette', 'customDevicePresets', 'customEmulatedDeviceList', 'customFormatters', 'customUserAgent', 'databaseTableViewVisibleColumns', 'dataGrid-cookiesTable', 'dataGrid-DOMStorageItemsView', 'debuggerSidebarHidden', 'disableDataSaverInfobar', 'disablePausedStateOverlay', 'domBreakpoints', 'domWordWrap', 'elementsPanelSplitViewState', 'elementsSidebarWidth', 'emulation.deviceHeight', 'emulation.deviceModeValue', 'emulation.deviceOrientationOverride', 'emulation.deviceScale', 'emulation.deviceScaleFactor', 'emulation.deviceUA', 'emulation.deviceWidth', 'emulation.geolocationOverride', 'emulation.showDeviceMode', 'emulation.showRulers', 'enableAsyncStackTraces', 'eventListenerBreakpoints', 'fileMappingEntries', 'fileSystemMapping', 'FileSystemViewSidebarWidth', 'fileSystemViewSplitViewState', 'filterBar-consoleView', 'filterBar-networkPanel', 'filterBar-promisePane', 'filterBar-timelinePanel', 'frameViewerHideChromeWindow', 'heapSnapshotRetainersViewSize', 'heapSnapshotSplitViewState', 'hideCollectedPromises', 'hideNetworkMessages', 'highlightNodeOnHoverInOverlay', 'highResolutionCpuProfiling', 'inlineVariableValues', 'Inspector.drawerSplitView', 'Inspector.drawerSplitViewState', 'InspectorView.panelOrder', 'InspectorView.screencastSplitView', 'InspectorView.screencastSplitViewState', 'InspectorView.splitView', 'InspectorView.splitViewState', 'javaScriptDisabled', 'jsSourceMapsEnabled', 'lastActivePanel', 'lastDockState', 'lastSelectedSourcesSidebarPaneTab', 'lastSnippetEvaluationIndex', 'layerDetailsSplitView', 'layerDetailsSplitViewState', 'layersPanelSplitViewState', 'layersShowInternalLayers', 'layersSidebarWidth', 'messageLevelFilters', 'messageURLFilters', 'monitoringXHREnabled', 'navigatorGroupByFolder', 'navigatorHidden', 'networkColorCodeResourceTypes', 'networkConditions', 'networkConditionsCustomProfiles', 'networkHideDataURL', 'networkLogColumnsVisibility', 'networkLogLargeRows', 'networkLogShowOverview', 'networkPanelSplitViewState', 'networkRecordFilmStripSetting', 'networkResourceTypeFilters', 'networkShowPrimaryLoadWaterfall', 'networkSidebarWidth', 'openLinkHandler', 'pauseOnCaughtException', 'pauseOnExceptionEnabled', 'preserveConsoleLog', 'prettyPrintInfobarDisabled', 'previouslyViewedFiles', 'profilesPanelSplitViewState', 'profilesSidebarWidth', 'promiseStatusFilters', 'recordAllocationStacks', 'requestHeaderFilterSetting', 'request-info-formData-category-expanded', 'request-info-general-category-expanded', 'request-info-queryString-category-expanded', 'request-info-requestHeaders-category-expanded', 'request-info-requestPayload-category-expanded', 'request-info-responseHeaders-category-expanded', 'resources', 'resourcesLastSelectedItem', 'resourcesPanelSplitViewState', 'resourcesSidebarWidth', 'resourceViewTab', 'savedURLs', 'screencastEnabled', 'scriptsPanelNavigatorSidebarWidth', 'searchInContentScripts', 'selectedAuditCategories', 'selectedColorPalette', 'selectedProfileType', 'shortcutPanelSwitch', 'showAdvancedHeapSnapshotProperties', 'showEventListenersForAncestors', 'showFrameowkrListeners', 'showHeaSnapshotObjectsHiddenProperties', 'showInheritedComputedStyleProperties', 'showMediaQueryInspector', 'showNativeFunctionsInJSProfile', 'showUAShadowDOM', 'showWhitespacesInEditor', 'sidebarPosition', 'skipContentScripts', 'skipStackFramesPattern', 'sourceMapInfobarDisabled', 'sourcesPanelDebuggerSidebarSplitViewState', 'sourcesPanelNavigatorSplitViewState', 'sourcesPanelSplitSidebarRatio', 'sourcesPanelSplitViewState', 'sourcesSidebarWidth', 'standardEmulatedDeviceList', 'StylesPaneSplitRatio', 'stylesPaneSplitViewState', 'textEditorAutocompletion', 'textEditorAutoDetectIndent', 'textEditorBracketMatching', 'textEditorIndent', 'textEditorTabMovesFocus', 'timelineCaptureFilmStrip', 'timelineCaptureLayersAndPictures', 'timelineCaptureMemory', 'timelineCaptureNetwork', 'timeline-details', 'timelineEnableJSSampling', 'timelineOverviewMode', 'timelinePanelDetailsSplitViewState', 'timelinePanelRecorsSplitViewState', 'timelinePanelTimelineStackSplitViewState', 'timelinePerspective', 'timeline-split', 'timelineTreeGroupBy', 'timeline-view', 'timelineViewMode', 'uiTheme', 'watchExpressions', 'WebInspector.Drawer.lastSelectedView', 'WebInspector.Drawer.showOnLoad', 'workspaceExcludedFolders', 'workspaceFolderExcludePattern', 'workspaceInfobarDisabled', 'workspaceMappingInfobarDisabled', 'xhrBreakpoints' ]; /** * @this {!{_storage: Object, _name: string}} */ function settingRemove() { this._storage[this._name] = undefined; } /** * @param {!Object} object * @param {function(!Array)} observer */ function objectObserve(object, observer) { if (window['WebInspector']) { const settingPrototype = /** @type {!Object} */ (window['WebInspector']['Setting']['prototype']); if (typeof settingPrototype['remove'] === 'function') { settingPrototype['remove'] = settingRemove; } } /** @type {!Set} */ const changedProperties = new Set(); let scheduled = false; function scheduleObserver() { if (scheduled) { return; } scheduled = true; setImmediate(callObserver); } function callObserver() { scheduled = false; const changes = /** @type {!Array} */ ([]); changedProperties.forEach(function(name) { changes.push({name: name}); }); changedProperties.clear(); observer.call(null, changes); } /** @type {!Map} */ const storage = new Map(); /** * @param {string} property */ function defineProperty(property) { if (property in object) { storage.set(property, object[property]); delete object[property]; } Object.defineProperty(object, property, { /** * @return {*} */ get: function() { return storage.get(property); }, /** * @param {*} value */ set: function(value) { storage.set(property, value); changedProperties.add(property); scheduleObserver(); } }); } for (let i = 0; i < properties.length; ++i) { defineProperty(properties[i]); } } window.Object.observe = objectObserve; } /** @type {!Map} */ const staticKeyIdentifiers = new Map([ [0x12, 'Alt'], [0x11, 'Control'], [0x10, 'Shift'], [0x14, 'CapsLock'], [0x5b, 'Win'], [0x5c, 'Win'], [0x0c, 'Clear'], [0x28, 'Down'], [0x23, 'End'], [0x0a, 'Enter'], [0x0d, 'Enter'], [0x2b, 'Execute'], [0x70, 'F1'], [0x71, 'F2'], [0x72, 'F3'], [0x73, 'F4'], [0x74, 'F5'], [0x75, 'F6'], [0x76, 'F7'], [0x77, 'F8'], [0x78, 'F9'], [0x79, 'F10'], [0x7a, 'F11'], [0x7b, 'F12'], [0x7c, 'F13'], [0x7d, 'F14'], [0x7e, 'F15'], [0x7f, 'F16'], [0x80, 'F17'], [0x81, 'F18'], [0x82, 'F19'], [0x83, 'F20'], [0x84, 'F21'], [0x85, 'F22'], [0x86, 'F23'], [0x87, 'F24'], [0x2f, 'Help'], [0x24, 'Home'], [0x2d, 'Insert'], [0x25, 'Left'], [0x22, 'PageDown'], [0x21, 'PageUp'], [0x13, 'Pause'], [0x2c, 'PrintScreen'], [0x27, 'Right'], [0x91, 'Scroll'], [0x29, 'Select'], [0x26, 'Up'], [0x2e, 'U+007F'], // Standard says that DEL becomes U+007F. [0xb0, 'MediaNextTrack'], [0xb1, 'MediaPreviousTrack'], [0xb2, 'MediaStop'], [0xb3, 'MediaPlayPause'], [0xad, 'VolumeMute'], [0xae, 'VolumeDown'], [0xaf, 'VolumeUp'], ]); /** * @param {number} keyCode * @return {string} */ function keyCodeToKeyIdentifier(keyCode) { let result = staticKeyIdentifiers.get(keyCode); if (result !== undefined) { return result; } result = 'U+'; const hexString = keyCode.toString(16).toUpperCase(); for (let i = hexString.length; i < 4; ++i) { result += '0'; } result += hexString; return result; } function installBackwardsCompatibility() { const majorVersion = getRemoteMajorVersion(); if (!majorVersion) { return; } /** @type {!Array} */ 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; } }); 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; }; } // 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); } } // Custom Elements V0 polyfill if (majorVersion <= 73 && !Document.prototype.hasOwnProperty('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); }; // DevTools front-ends mistakenly assume that // classList.toggle('a', undefined) works as // classList.toggle('a', false) rather than as // classList.toggle('a'); const originalDOMTokenListToggle = DOMTokenList.prototype.toggle; DOMTokenList.prototype.toggle = function(token, force) { if (arguments.length === 1) { force = !this.contains(token); } return originalDOMTokenListToggle.call(this, token, !!force); }; } if (majorVersion <= 66) { /** @type {(!function(number, number):Element|undefined)} */ ShadowRoot.prototype.__originalShadowRootElementFromPoint; if (!ShadowRoot.prototype.__originalShadowRootElementFromPoint) { ShadowRoot.prototype.__originalShadowRootElementFromPoint = ShadowRoot.prototype.elementFromPoint; /** * @param {number} x * @param {number} y * @return {Element} */ ShadowRoot.prototype.elementFromPoint = function(x, y) { const originalResult = ShadowRoot.prototype.__originalShadowRootElementFromPoint.apply(this, arguments); if (this.host && originalResult === this.host) { return null; } return originalResult; }; } } if (majorVersion <= 53) { Object.defineProperty(window.KeyboardEvent.prototype, 'keyIdentifier', { /** * @return {string} * @this {KeyboardEvent} */ get: function() { return keyCodeToKeyIdentifier(this.keyCode); } }); } if (majorVersion <= 50) { installObjectObserve(); } if (majorVersion <= 45) { /** * @param {string} property * @return {!CSSValue|null} * @this {CSSStyleDeclaration} */ function getValue(property) { // Note that |property| comes from another context, so we can't use === here. // eslint-disable-next-line eqeqeq if (property == 'padding-left') { return /** @type {!CSSValue} */ ({ /** * @return {number} * @this {!{__paddingLeft: number}} */ getFloatValue: function() { return this.__paddingLeft; }, __paddingLeft: parseFloat(this.paddingLeft) }); } throw new Error('getPropertyCSSValue is undefined'); } window.CSSStyleDeclaration.prototype.getPropertyCSSValue = getValue; function CSSPrimitiveValue() { } CSSPrimitiveValue.CSS_PX = 5; window.CSSPrimitiveValue = CSSPrimitiveValue; } if (majorVersion <= 45) { styleRules.push('* { min-width: 0; min-height: 0; }'); } if (majorVersion <= 51) { // Support for quirky border-image behavior (} styleRules */ function installExtraStyleRules(styleRules) { if (!styleRules.length) { return; } const styleText = styleRules.join('\n'); document.head.appendChild(createStyleElement(styleText)); const origCreateShadowRoot = HTMLElement.prototype.createShadowRoot; HTMLElement.prototype.createShadowRoot = function(...args) { const shadowRoot = origCreateShadowRoot.call(this, ...args); shadowRoot.appendChild(createStyleElement(styleText)); return shadowRoot; }; } /** * @param {string} styleText * @return {!Element} */ function createStyleElement(styleText) { const style = document.createElement('style'); style.textContent = styleText; return style; } installBackwardsCompatibility(); })(window);