Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
META-INF.dirigible.dev-tools.sdk.CSSModel.js Maven / Gradle / Ivy
/*
* Copyright (C) 2010 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import * as Common from '../common/common.js';
import * as HostModule from '../host/host.js';
import * as Platform from '../platform/platform.js';
import * as ProtocolClient from '../protocol_client/protocol_client.js';
import {CSSMatchedStyles} from './CSSMatchedStyles.js';
import {CSSMedia} from './CSSMedia.js';
import {CSSStyleRule} from './CSSRule.js';
import {CSSStyleDeclaration, Type} from './CSSStyleDeclaration.js';
import {CSSStyleSheetHeader} from './CSSStyleSheetHeader.js';
import {DOMModel, DOMNode} from './DOMModel.js'; // eslint-disable-line no-unused-vars
import {Events as ResourceTreeModelEvents, ResourceTreeModel} from './ResourceTreeModel.js';
import {Capability, SDKModel, Target} from './SDKModel.js'; // eslint-disable-line no-unused-vars
import {SourceMapManager} from './SourceMapManager.js';
/**
* @unrestricted
*/
export class CSSModel extends SDKModel {
/**
* @param {!Target} target
*/
constructor(target) {
super(target);
this._domModel = /** @type {!DOMModel} */ (target.model(DOMModel));
/** @type {!SourceMapManager} */
this._sourceMapManager = new SourceMapManager(target);
this._agent = target.cssAgent();
this._styleLoader = new ComputedStyleLoader(this);
this._resourceTreeModel = target.model(ResourceTreeModel);
if (this._resourceTreeModel) {
this._resourceTreeModel.addEventListener(
ResourceTreeModelEvents.MainFrameNavigated, this._resetStyleSheets, this);
}
target.registerCSSDispatcher(new CSSDispatcher(this));
if (!target.suspended()) {
this._enable();
}
/** @type {!Map.} */
this._styleSheetIdToHeader = new Map();
/** @type {!Map.>>} */
this._styleSheetIdsForURL = new Map();
/** @type {!Map.>} */
this._originalStyleSheetText = new Map();
/** @type {boolean} */
this._isRuleUsageTrackingEnabled = false;
this._sourceMapManager.setEnabled(Common.Settings.Settings.instance().moduleSetting('cssSourceMapsEnabled').get());
Common.Settings.Settings.instance()
.moduleSetting('cssSourceMapsEnabled')
.addChangeListener(event => this._sourceMapManager.setEnabled(/** @type {boolean} */ (event.data)));
}
/**
* @param {string} sourceURL
* @return {!Array}
*/
headersForSourceURL(sourceURL) {
const headers = [];
for (const headerId of this.styleSheetIdsForURL(sourceURL)) {
const header = this.styleSheetHeaderForId(headerId);
if (header) {
headers.push(header);
}
}
return headers;
}
/**
* @param {string} sourceURL
* @param {number} lineNumber
* @param {number} columnNumber
* @return {!Array}
*/
createRawLocationsByURL(sourceURL, lineNumber, columnNumber) {
const headers = this.headersForSourceURL(sourceURL);
headers.sort(stylesheetComparator);
const compareToArgLocation = (_, header) => lineNumber - header.startLine || columnNumber - header.startColumn;
const endIndex = headers.upperBound(undefined, compareToArgLocation);
if (!endIndex) {
return [];
}
const locations = [];
const last = headers[endIndex - 1];
for (let index = endIndex - 1;
index >= 0 && headers[index].startLine === last.startLine && headers[index].startColumn === last.startColumn;
--index) {
if (headers[index].containsLocation(lineNumber, columnNumber)) {
locations.push(new CSSLocation(headers[index], lineNumber, columnNumber));
}
}
return locations;
/**
* @param {!CSSStyleSheetHeader} a
* @param {!CSSStyleSheetHeader} b
* @return {number}
*/
function stylesheetComparator(a, b) {
return a.startLine - b.startLine || a.startColumn - b.startColumn || a.id.localeCompare(b.id);
}
}
/**
* @return {!SourceMapManager}
*/
sourceMapManager() {
return this._sourceMapManager;
}
/**
* @param {string} text
* @return {string}
*/
static trimSourceURL(text) {
let sourceURLIndex = text.lastIndexOf('/*# sourceURL=');
if (sourceURLIndex === -1) {
sourceURLIndex = text.lastIndexOf('/*@ sourceURL=');
if (sourceURLIndex === -1) {
return text;
}
}
const sourceURLLineIndex = text.lastIndexOf('\n', sourceURLIndex);
if (sourceURLLineIndex === -1) {
return text;
}
const sourceURLLine = text.substr(sourceURLLineIndex + 1).split('\n', 1)[0];
const sourceURLRegex = /[\040\t]*\/\*[#@] sourceURL=[\040\t]*([^\s]*)[\040\t]*\*\/[\040\t]*$/;
if (sourceURLLine.search(sourceURLRegex) === -1) {
return text;
}
return text.substr(0, sourceURLLineIndex) + text.substr(sourceURLLineIndex + sourceURLLine.length + 1);
}
/**
* @return {!DOMModel}
*/
domModel() {
return this._domModel;
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!TextUtils.TextRange} range
* @param {string} text
* @param {boolean} majorChange
* @return {!Promise}
*/
async setStyleText(styleSheetId, range, text, majorChange) {
try {
await this._ensureOriginalStyleSheetText(styleSheetId);
const stylePayloads =
await this._agent.setStyleTexts([{styleSheetId: styleSheetId, range: range.serializeToObject(), text: text}]);
if (!stylePayloads || stylePayloads.length !== 1) {
return false;
}
this._domModel.markUndoableState(!majorChange);
const edit = new Edit(styleSheetId, range, text, stylePayloads[0]);
this._fireStyleSheetChanged(styleSheetId, edit);
return true;
} catch (e) {
return false;
}
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!TextUtils.TextRange} range
* @param {string} text
* @return {!Promise}
*/
async setSelectorText(styleSheetId, range, text) {
HostModule.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
try {
await this._ensureOriginalStyleSheetText(styleSheetId);
const selectorPayload = await this._agent.setRuleSelector(styleSheetId, range, text);
if (!selectorPayload) {
return false;
}
this._domModel.markUndoableState();
const edit = new Edit(styleSheetId, range, text, selectorPayload);
this._fireStyleSheetChanged(styleSheetId, edit);
return true;
} catch (e) {
return false;
}
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!TextUtils.TextRange} range
* @param {string} text
* @return {!Promise}
*/
async setKeyframeKey(styleSheetId, range, text) {
HostModule.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
try {
await this._ensureOriginalStyleSheetText(styleSheetId);
const payload = await this._agent.setKeyframeKey(styleSheetId, range, text);
if (!payload) {
return false;
}
this._domModel.markUndoableState();
const edit = new Edit(styleSheetId, range, text, payload);
this._fireStyleSheetChanged(styleSheetId, edit);
return true;
} catch (e) {
return false;
}
}
startCoverage() {
this._isRuleUsageTrackingEnabled = true;
return this._agent.startRuleUsageTracking();
}
/**
* @return {!Promise<{timestamp: number, coverage:!Array}>}
*/
async takeCoverageDelta() {
const r = await this._agent.invoke_takeCoverageDelta({});
const timestamp = (r && r.timestamp) || 0;
const coverage = (r && r.coverage) || [];
return {timestamp, coverage};
}
/**
* @return {!Promise}
*/
stopCoverage() {
this._isRuleUsageTrackingEnabled = false;
return this._agent.stopRuleUsageTracking();
}
/**
* @return {!Promise>}
*/
async mediaQueriesPromise() {
const payload = await this._agent.getMediaQueries();
return payload ? CSSMedia.parseMediaArrayPayload(this, payload) : [];
}
/**
* @return {boolean}
*/
isEnabled() {
return this._isEnabled;
}
/**
* @return {!Promise}
*/
async _enable() {
await this._agent.enable();
this._isEnabled = true;
if (this._isRuleUsageTrackingEnabled) {
await this.startCoverage();
}
this.dispatchEventToListeners(Events.ModelWasEnabled);
}
/**
* @param {!Protocol.DOM.NodeId} nodeId
* @return {!Promise}
*/
async matchedStylesPromise(nodeId) {
const response = await this._agent.invoke_getMatchedStylesForNode({nodeId});
if (response[ProtocolClient.InspectorBackend.ProtocolError]) {
return null;
}
const node = this._domModel.nodeForId(nodeId);
if (!node) {
return null;
}
return new CSSMatchedStyles(
this, /** @type {!DOMNode} */ (node), response.inlineStyle || null, response.attributesStyle || null,
response.matchedCSSRules || [], response.pseudoElements || [], response.inherited || [],
response.cssKeyframesRules || []);
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @return {!Promise>}
*/
classNamesPromise(styleSheetId) {
return this._agent.collectClassNames(styleSheetId).then(classNames => classNames || []);
}
/**
* @param {!Protocol.DOM.NodeId} nodeId
* @return {!Promise>}
*/
computedStylePromise(nodeId) {
return this._styleLoader.computedStylePromise(nodeId);
}
/**
* @param {number} nodeId
* @return {!Promise}
*/
async backgroundColorsPromise(nodeId) {
const response = this._agent.invoke_getBackgroundColors({nodeId});
if (response[ProtocolClient.InspectorBackend.ProtocolError]) {
return null;
}
return response;
}
/**
* @param {number} nodeId
* @return {!Promise>}
*/
platformFontsPromise(nodeId) {
return this._agent.getPlatformFontsForNode(nodeId);
}
/**
* @return {!Array.}
*/
allStyleSheets() {
const values = [...this._styleSheetIdToHeader.values()];
/**
* @param {!CSSStyleSheetHeader} a
* @param {!CSSStyleSheetHeader} b
* @return {number}
*/
function styleSheetComparator(a, b) {
if (a.sourceURL < b.sourceURL) {
return -1;
}
if (a.sourceURL > b.sourceURL) {
return 1;
}
return a.startLine - b.startLine || a.startColumn - b.startColumn;
}
values.sort(styleSheetComparator);
return values;
}
/**
* @param {!Protocol.DOM.NodeId} nodeId
* @return {!Promise}
*/
async inlineStylesPromise(nodeId) {
const response = await this._agent.invoke_getInlineStylesForNode({nodeId});
if (response[ProtocolClient.InspectorBackend.ProtocolError] || !response.inlineStyle) {
return null;
}
const inlineStyle = new CSSStyleDeclaration(this, null, response.inlineStyle, Type.Inline);
const attributesStyle = response.attributesStyle ?
new CSSStyleDeclaration(this, null, response.attributesStyle, Type.Attributes) :
null;
return new InlineStyleResult(inlineStyle, attributesStyle);
}
/**
* @param {!DOMNode} node
* @param {string} pseudoClass
* @param {boolean} enable
* @return {boolean}
*/
forcePseudoState(node, pseudoClass, enable) {
const pseudoClasses = node.marker(PseudoStateMarker) || [];
if (enable) {
if (pseudoClasses.indexOf(pseudoClass) >= 0) {
return false;
}
pseudoClasses.push(pseudoClass);
node.setMarker(PseudoStateMarker, pseudoClasses);
} else {
if (pseudoClasses.indexOf(pseudoClass) < 0) {
return false;
}
Platform.ArrayUtilities.removeElement(pseudoClasses, pseudoClass);
if (pseudoClasses.length) {
node.setMarker(PseudoStateMarker, pseudoClasses);
} else {
node.setMarker(PseudoStateMarker, null);
}
}
this._agent.forcePseudoState(node.id, pseudoClasses);
this.dispatchEventToListeners(Events.PseudoStateForced, {node: node, pseudoClass: pseudoClass, enable: enable});
return true;
}
/**
* @param {!DOMNode} node
* @return {?Array} state
*/
pseudoState(node) {
return node.marker(PseudoStateMarker) || [];
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!TextUtils.TextRange} range
* @param {string} newMediaText
* @return {!Promise}
*/
async setMediaText(styleSheetId, range, newMediaText) {
HostModule.userMetrics.actionTaken(Host.UserMetrics.Action.StyleRuleEdited);
try {
await this._ensureOriginalStyleSheetText(styleSheetId);
const mediaPayload = await this._agent.setMediaText(styleSheetId, range, newMediaText);
if (!mediaPayload) {
return false;
}
this._domModel.markUndoableState();
const edit = new Edit(styleSheetId, range, newMediaText, mediaPayload);
this._fireStyleSheetChanged(styleSheetId, edit);
return true;
} catch (e) {
return false;
}
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {string} ruleText
* @param {!TextUtils.TextRange} ruleLocation
* @return {!Promise}
*/
async addRule(styleSheetId, ruleText, ruleLocation) {
try {
await this._ensureOriginalStyleSheetText(styleSheetId);
const rulePayload = await this._agent.addRule(styleSheetId, ruleText, ruleLocation);
if (!rulePayload) {
return null;
}
this._domModel.markUndoableState();
const edit = new Edit(styleSheetId, ruleLocation, ruleText, rulePayload);
this._fireStyleSheetChanged(styleSheetId, edit);
return new CSSStyleRule(this, rulePayload);
} catch (e) {
return null;
}
}
/**
* @param {!DOMNode} node
* @return {!Promise}
*/
async requestViaInspectorStylesheet(node) {
const frameId = node.frameId() || (this._resourceTreeModel ? this._resourceTreeModel.mainFrame.id : '');
const headers = [...this._styleSheetIdToHeader.values()];
const styleSheetHeader = headers.find(header => header.frameId === frameId && header.isViaInspector());
if (styleSheetHeader) {
return styleSheetHeader;
}
try {
const styleSheetId = await this._agent.createStyleSheet(frameId);
return styleSheetId && this._styleSheetIdToHeader.get(styleSheetId) || null;
} catch (e) {
return null;
}
}
mediaQueryResultChanged() {
this.dispatchEventToListeners(Events.MediaQueryResultChanged);
}
fontsUpdated() {
this.dispatchEventToListeners(Events.FontsUpdated);
}
/**
* @param {!Protocol.CSS.StyleSheetId} id
* @return {?CSSStyleSheetHeader}
*/
styleSheetHeaderForId(id) {
return this._styleSheetIdToHeader.get(id) || null;
}
/**
* @return {!Array.}
*/
styleSheetHeaders() {
return [...this._styleSheetIdToHeader.values()];
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!Edit=} edit
*/
_fireStyleSheetChanged(styleSheetId, edit) {
this.dispatchEventToListeners(Events.StyleSheetChanged, {styleSheetId: styleSheetId, edit: edit});
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @return {!Promise}
*/
_ensureOriginalStyleSheetText(styleSheetId) {
const header = this.styleSheetHeaderForId(styleSheetId);
if (!header) {
return Promise.resolve(/** @type {?string} */ (null));
}
let promise = this._originalStyleSheetText.get(header);
if (!promise) {
promise = this.getStyleSheetText(header.id);
this._originalStyleSheetText.set(header, promise);
this._originalContentRequestedForTest(header);
}
return promise;
}
/**
* @param {!CSSStyleSheetHeader} header
*/
_originalContentRequestedForTest(header) {
}
/**
* @param {!CSSStyleSheetHeader} header
* @return {!Promise}
*/
originalStyleSheetText(header) {
return this._ensureOriginalStyleSheetText(header.id);
}
/**
*
* @return {!Iterable}
*/
getAllStyleSheetHeaders() {
return this._styleSheetIdToHeader.values();
}
/**
* @param {!Protocol.CSS.CSSStyleSheetHeader} header
*/
_styleSheetAdded(header) {
console.assert(!this._styleSheetIdToHeader.get(header.styleSheetId));
const styleSheetHeader = new CSSStyleSheetHeader(this, header);
this._styleSheetIdToHeader.set(header.styleSheetId, styleSheetHeader);
const url = styleSheetHeader.resourceURL();
if (!this._styleSheetIdsForURL.get(url)) {
this._styleSheetIdsForURL.set(url, new Map());
}
const frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
let styleSheetIds = frameIdToStyleSheetIds.get(styleSheetHeader.frameId);
if (!styleSheetIds) {
styleSheetIds = new Set();
frameIdToStyleSheetIds.set(styleSheetHeader.frameId, styleSheetIds);
}
styleSheetIds.add(styleSheetHeader.id);
this._sourceMapManager.attachSourceMap(styleSheetHeader, styleSheetHeader.sourceURL, styleSheetHeader.sourceMapURL);
this.dispatchEventToListeners(Events.StyleSheetAdded, styleSheetHeader);
}
/**
* @param {!Protocol.CSS.StyleSheetId} id
*/
_styleSheetRemoved(id) {
const header = this._styleSheetIdToHeader.get(id);
console.assert(header);
if (!header) {
return;
}
this._styleSheetIdToHeader.delete(id);
const url = header.resourceURL();
const frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
console.assert(frameIdToStyleSheetIds, 'No frameId to styleSheetId map is available for given style sheet URL.');
frameIdToStyleSheetIds.get(header.frameId).delete(id);
if (!frameIdToStyleSheetIds.get(header.frameId).size) {
frameIdToStyleSheetIds.delete(header.frameId);
if (!frameIdToStyleSheetIds.size) {
this._styleSheetIdsForURL.delete(url);
}
}
this._originalStyleSheetText.delete(header);
this._sourceMapManager.detachSourceMap(header);
this.dispatchEventToListeners(Events.StyleSheetRemoved, header);
}
/**
* @param {string} url
* @return {!Array.}
*/
styleSheetIdsForURL(url) {
const frameIdToStyleSheetIds = this._styleSheetIdsForURL.get(url);
if (!frameIdToStyleSheetIds) {
return [];
}
const result = [];
for (const styleSheetIds of frameIdToStyleSheetIds.values()) {
result.push(...styleSheetIds);
}
return result;
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {string} newText
* @param {boolean} majorChange
* @return {!Promise}
*/
async setStyleSheetText(styleSheetId, newText, majorChange) {
const header = /** @type {!CSSStyleSheetHeader} */ (this._styleSheetIdToHeader.get(styleSheetId));
console.assert(header);
newText = CSSModel.trimSourceURL(newText);
if (header.hasSourceURL) {
newText += '\n/*# sourceURL=' + header.sourceURL + ' */';
}
await this._ensureOriginalStyleSheetText(styleSheetId);
const response = await this._agent.invoke_setStyleSheetText({styleSheetId: header.id, text: newText});
const sourceMapURL = response.sourceMapURL;
this._sourceMapManager.detachSourceMap(header);
header.setSourceMapURL(sourceMapURL);
this._sourceMapManager.attachSourceMap(header, header.sourceURL, header.sourceMapURL);
if (sourceMapURL === null) {
return 'Error in CSS.setStyleSheetText';
}
this._domModel.markUndoableState(!majorChange);
this._fireStyleSheetChanged(styleSheetId);
return null;
}
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @return {!Promise}
*/
async getStyleSheetText(styleSheetId) {
try {
const text = await this._agent.getStyleSheetText(styleSheetId);
return text && CSSModel.trimSourceURL(text);
} catch (e) {
return null;
}
}
_resetStyleSheets() {
const headers = [...this._styleSheetIdToHeader.values()];
this._styleSheetIdsForURL.clear();
this._styleSheetIdToHeader.clear();
for (const header of headers) {
this._sourceMapManager.detachSourceMap(header);
this.dispatchEventToListeners(Events.StyleSheetRemoved, header);
}
}
/**
* @override
* @return {!Promise}
*/
suspendModel() {
this._isEnabled = false;
return this._agent.disable().then(this._resetStyleSheets.bind(this));
}
/**
* @override
* @return {!Promise}
*/
async resumeModel() {
return this._enable();
}
/**
* @param {number} nodeId
* @param {string} name
* @param {string} value
*/
setEffectivePropertyValueForNode(nodeId, name, value) {
this._agent.setEffectivePropertyValueForNode(nodeId, name, value);
}
/**
* @param {!DOMNode} node
* @return {!Promise.}
*/
cachedMatchedCascadeForNode(node) {
if (this._cachedMatchedCascadeNode !== node) {
this.discardCachedMatchedCascade();
}
this._cachedMatchedCascadeNode = node;
if (!this._cachedMatchedCascadePromise) {
this._cachedMatchedCascadePromise = this.matchedStylesPromise(node.id);
}
return this._cachedMatchedCascadePromise;
}
discardCachedMatchedCascade() {
delete this._cachedMatchedCascadeNode;
delete this._cachedMatchedCascadePromise;
}
/**
* @override
*/
dispose() {
super.dispose();
this._sourceMapManager.dispose();
}
}
/** @enum {symbol} */
export const Events = {
FontsUpdated: Symbol('FontsUpdated'),
MediaQueryResultChanged: Symbol('MediaQueryResultChanged'),
ModelWasEnabled: Symbol('ModelWasEnabled'),
PseudoStateForced: Symbol('PseudoStateForced'),
StyleSheetAdded: Symbol('StyleSheetAdded'),
StyleSheetChanged: Symbol('StyleSheetChanged'),
StyleSheetRemoved: Symbol('StyleSheetRemoved')
};
const PseudoStateMarker = 'pseudo-state-marker';
/**
* @unrestricted
*/
export class Edit {
/**
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
* @param {!TextUtils.TextRange} oldRange
* @param {string} newText
* @param {?Object} payload
*/
constructor(styleSheetId, oldRange, newText, payload) {
this.styleSheetId = styleSheetId;
this.oldRange = oldRange;
this.newRange = TextUtils.TextRange.fromEdit(oldRange, newText);
this.newText = newText;
this.payload = payload;
}
}
export class CSSLocation {
/**
* @param {!CSSStyleSheetHeader} header
* @param {number} lineNumber
* @param {number=} columnNumber
*/
constructor(header, lineNumber, columnNumber) {
this._cssModel = header.cssModel();
this.styleSheetId = header.id;
this.url = header.resourceURL();
this.lineNumber = lineNumber;
this.columnNumber = columnNumber || 0;
}
/**
* @return {!CSSModel}
*/
cssModel() {
return this._cssModel;
}
/**
* @return {?CSSStyleSheetHeader}
*/
header() {
return this._cssModel.styleSheetHeaderForId(this.styleSheetId);
}
}
/**
* @implements {Protocol.CSSDispatcher}
* @unrestricted
*/
class CSSDispatcher {
/**
* @param {!CSSModel} cssModel
*/
constructor(cssModel) {
this._cssModel = cssModel;
}
/**
* @override
*/
mediaQueryResultChanged() {
this._cssModel.mediaQueryResultChanged();
}
/**
* @override
*/
fontsUpdated() {
this._cssModel.fontsUpdated();
}
/**
* @override
* @param {!Protocol.CSS.StyleSheetId} styleSheetId
*/
styleSheetChanged(styleSheetId) {
this._cssModel._fireStyleSheetChanged(styleSheetId);
}
/**
* @override
* @param {!Protocol.CSS.CSSStyleSheetHeader} header
*/
styleSheetAdded(header) {
this._cssModel._styleSheetAdded(header);
}
/**
* @override
* @param {!Protocol.CSS.StyleSheetId} id
*/
styleSheetRemoved(id) {
this._cssModel._styleSheetRemoved(id);
}
}
/**
* @unrestricted
*/
class ComputedStyleLoader {
/**
* @param {!CSSModel} cssModel
*/
constructor(cssModel) {
this._cssModel = cssModel;
/** @type {!Map>>} */
this._nodeIdToPromise = new Map();
}
/**
* @param {!Protocol.DOM.NodeId} nodeId
* @return {!Promise>}
*/
computedStylePromise(nodeId) {
let promise = this._nodeIdToPromise.get(nodeId);
if (promise) {
return promise;
}
promise = this._cssModel._agent.getComputedStyleForNode(nodeId).then(parsePayload.bind(this));
this._nodeIdToPromise.set(nodeId, promise);
return promise;
/**
* @param {?Array} computedPayload
* @return {?Map}
* @this {ComputedStyleLoader}
*/
function parsePayload(computedPayload) {
this._nodeIdToPromise.delete(nodeId);
if (!computedPayload || !computedPayload.length) {
return null;
}
const result = new Map();
for (const property of computedPayload) {
result.set(property.name, property.value);
}
return result;
}
}
}
/**
* @unrestricted
*/
export class InlineStyleResult {
/**
* @param {?CSSStyleDeclaration} inlineStyle
* @param {?CSSStyleDeclaration} attributesStyle
*/
constructor(inlineStyle, attributesStyle) {
this.inlineStyle = inlineStyle;
this.attributesStyle = attributesStyle;
}
}
SDKModel.register(CSSModel, Capability.DOM, true);
/** @typedef {{backgroundColors: ?Array, computedFontSize: string, computedFontWeight: string}} */
export let ContrastInfo;