| // Copyright 2016 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. |
| |
| /** |
| * @unrestricted |
| */ |
| export default class CSSRule { |
| /** |
| * @param {!SDK.CSSModel} cssModel |
| * @param {{style: !Protocol.CSS.CSSStyle, styleSheetId: (string|undefined), origin: !Protocol.CSS.StyleSheetOrigin}} payload |
| */ |
| constructor(cssModel, payload) { |
| this._cssModel = cssModel; |
| this.styleSheetId = payload.styleSheetId; |
| |
| if (this.styleSheetId) { |
| const styleSheetHeader = cssModel.styleSheetHeaderForId(this.styleSheetId); |
| this.sourceURL = styleSheetHeader.sourceURL; |
| } |
| this.origin = payload.origin; |
| this.style = new SDK.CSSStyleDeclaration(this._cssModel, this, payload.style, SDK.CSSStyleDeclaration.Type.Regular); |
| } |
| |
| /** |
| * @param {!SDK.CSSModel.Edit} edit |
| */ |
| rebase(edit) { |
| if (this.styleSheetId !== edit.styleSheetId) { |
| return; |
| } |
| this.style.rebase(edit); |
| } |
| |
| /** |
| * @return {string} |
| */ |
| resourceURL() { |
| if (!this.styleSheetId) { |
| return ''; |
| } |
| const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId); |
| return styleSheetHeader.resourceURL(); |
| } |
| |
| /** |
| * @return {boolean} |
| */ |
| isUserAgent() { |
| return this.origin === Protocol.CSS.StyleSheetOrigin.UserAgent; |
| } |
| |
| /** |
| * @return {boolean} |
| */ |
| isInjected() { |
| return this.origin === Protocol.CSS.StyleSheetOrigin.Injected; |
| } |
| |
| /** |
| * @return {boolean} |
| */ |
| isViaInspector() { |
| return this.origin === Protocol.CSS.StyleSheetOrigin.Inspector; |
| } |
| |
| /** |
| * @return {boolean} |
| */ |
| isRegular() { |
| return this.origin === Protocol.CSS.StyleSheetOrigin.Regular; |
| } |
| |
| /** |
| * @return {!SDK.CSSModel} |
| */ |
| cssModel() { |
| return this._cssModel; |
| } |
| } |
| |
| /** |
| * @unrestricted |
| */ |
| class CSSValue { |
| /** |
| * @param {!Protocol.CSS.Value} payload |
| */ |
| constructor(payload) { |
| this.text = payload.text; |
| if (payload.range) { |
| this.range = TextUtils.TextRange.fromObject(payload.range); |
| } |
| } |
| |
| /** |
| * @param {!SDK.CSSModel.Edit} edit |
| */ |
| rebase(edit) { |
| if (!this.range) { |
| return; |
| } |
| this.range = this.range.rebaseAfterTextEdit(edit.oldRange, edit.newRange); |
| } |
| } |
| |
| /** |
| * @unrestricted |
| */ |
| export class CSSStyleRule extends CSSRule { |
| /** |
| * @param {!SDK.CSSModel} cssModel |
| * @param {!Protocol.CSS.CSSRule} payload |
| * @param {boolean=} wasUsed |
| */ |
| constructor(cssModel, payload, wasUsed) { |
| super(cssModel, payload); |
| |
| this._reinitializeSelectors(payload.selectorList); |
| this.media = payload.media ? SDK.CSSMedia.parseMediaArrayPayload(cssModel, payload.media) : []; |
| this.wasUsed = wasUsed || false; |
| } |
| |
| /** |
| * @param {!SDK.CSSModel} cssModel |
| * @param {string} selectorText |
| * @return {!CSSStyleRule} |
| */ |
| static createDummyRule(cssModel, selectorText) { |
| const dummyPayload = { |
| selectorList: { |
| selectors: [{text: selectorText}], |
| }, |
| style: {styleSheetId: '0', range: new TextUtils.TextRange(0, 0, 0, 0), shorthandEntries: [], cssProperties: []} |
| }; |
| return new CSSStyleRule(cssModel, /** @type {!Protocol.CSS.CSSRule} */ (dummyPayload)); |
| } |
| |
| /** |
| * @param {!Protocol.CSS.SelectorList} selectorList |
| */ |
| _reinitializeSelectors(selectorList) { |
| /** @type {!Array.<!CSSValue>} */ |
| this.selectors = []; |
| for (let i = 0; i < selectorList.selectors.length; ++i) { |
| this.selectors.push(new CSSValue(selectorList.selectors[i])); |
| } |
| } |
| |
| /** |
| * @param {string} newSelector |
| * @return {!Promise.<boolean>} |
| */ |
| setSelectorText(newSelector) { |
| const styleSheetId = this.styleSheetId; |
| if (!styleSheetId) { |
| throw 'No rule stylesheet id'; |
| } |
| const range = this.selectorRange(); |
| if (!range) { |
| throw 'Rule selector is not editable'; |
| } |
| return this._cssModel.setSelectorText(styleSheetId, range, newSelector); |
| } |
| |
| /** |
| * @return {string} |
| */ |
| selectorText() { |
| return this.selectors.select('text').join(', '); |
| } |
| |
| /** |
| * @return {?TextUtils.TextRange} |
| */ |
| selectorRange() { |
| const firstRange = this.selectors[0].range; |
| if (!firstRange) { |
| return null; |
| } |
| const lastRange = this.selectors.peekLast().range; |
| return new TextUtils.TextRange( |
| firstRange.startLine, firstRange.startColumn, lastRange.endLine, lastRange.endColumn); |
| } |
| |
| /** |
| * @param {number} selectorIndex |
| * @return {number} |
| */ |
| lineNumberInSource(selectorIndex) { |
| const selector = this.selectors[selectorIndex]; |
| if (!selector || !selector.range || !this.styleSheetId) { |
| return 0; |
| } |
| const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId); |
| return styleSheetHeader.lineNumberInSource(selector.range.startLine); |
| } |
| |
| /** |
| * @param {number} selectorIndex |
| * @return {number|undefined} |
| */ |
| columnNumberInSource(selectorIndex) { |
| const selector = this.selectors[selectorIndex]; |
| if (!selector || !selector.range || !this.styleSheetId) { |
| return undefined; |
| } |
| const styleSheetHeader = this._cssModel.styleSheetHeaderForId(this.styleSheetId); |
| console.assert(styleSheetHeader); |
| return styleSheetHeader.columnNumberInSource(selector.range.startLine, selector.range.startColumn); |
| } |
| |
| /** |
| * @override |
| * @param {!SDK.CSSModel.Edit} edit |
| */ |
| rebase(edit) { |
| if (this.styleSheetId !== edit.styleSheetId) { |
| return; |
| } |
| if (this.selectorRange().equal(edit.oldRange)) { |
| this._reinitializeSelectors(/** @type {!Protocol.CSS.SelectorList} */ (edit.payload)); |
| } else { |
| for (let i = 0; i < this.selectors.length; ++i) { |
| this.selectors[i].rebase(edit); |
| } |
| } |
| for (const media of this.media) { |
| media.rebase(edit); |
| } |
| |
| super.rebase(edit); |
| } |
| } |
| |
| |
| /** |
| * @unrestricted |
| */ |
| export class CSSKeyframesRule { |
| /** |
| * @param {!SDK.CSSModel} cssModel |
| * @param {!Protocol.CSS.CSSKeyframesRule} payload |
| */ |
| constructor(cssModel, payload) { |
| this._cssModel = cssModel; |
| this._animationName = new CSSValue(payload.animationName); |
| this._keyframes = payload.keyframes.map(keyframeRule => new CSSKeyframeRule(cssModel, keyframeRule)); |
| } |
| |
| /** |
| * @return {!CSSValue} |
| */ |
| name() { |
| return this._animationName; |
| } |
| |
| /** |
| * @return {!Array.<!CSSKeyframeRule>} |
| */ |
| keyframes() { |
| return this._keyframes; |
| } |
| } |
| |
| /** |
| * @unrestricted |
| */ |
| export class CSSKeyframeRule extends CSSRule { |
| /** |
| * @param {!SDK.CSSModel} cssModel |
| * @param {!Protocol.CSS.CSSKeyframeRule} payload |
| */ |
| constructor(cssModel, payload) { |
| super(cssModel, payload); |
| this._reinitializeKey(payload.keyText); |
| } |
| |
| /** |
| * @return {!CSSValue} |
| */ |
| key() { |
| return this._keyText; |
| } |
| |
| /** |
| * @param {!Protocol.CSS.Value} payload |
| */ |
| _reinitializeKey(payload) { |
| this._keyText = new CSSValue(payload); |
| } |
| |
| /** |
| * @override |
| * @param {!SDK.CSSModel.Edit} edit |
| */ |
| rebase(edit) { |
| if (this.styleSheetId !== edit.styleSheetId || !this._keyText.range) { |
| return; |
| } |
| if (edit.oldRange.equal(this._keyText.range)) { |
| this._reinitializeKey(/** @type {!Protocol.CSS.Value} */ (edit.payload)); |
| } else { |
| this._keyText.rebase(edit); |
| } |
| |
| super.rebase(edit); |
| } |
| |
| /** |
| * @param {string} newKeyText |
| * @return {!Promise.<boolean>} |
| */ |
| setKeyText(newKeyText) { |
| const styleSheetId = this.styleSheetId; |
| if (!styleSheetId) { |
| throw 'No rule stylesheet id'; |
| } |
| const range = this._keyText.range; |
| if (!range) { |
| throw 'Keyframe key is not editable'; |
| } |
| return this._cssModel.setKeyframeKey(styleSheetId, range, newKeyText); |
| } |
| } |
| |
| /* Legacy exported object */ |
| self.SDK = self.SDK || {}; |
| |
| /* Legacy exported object */ |
| SDK = SDK || {}; |
| |
| /** @constructor */ |
| SDK.CSSRule = CSSRule; |
| |
| /** @constructor */ |
| SDK.CSSStyleRule = CSSStyleRule; |
| |
| /** @constructor */ |
| SDK.CSSKeyframesRule = CSSKeyframesRule; |
| |
| /** @constructor */ |
| SDK.CSSKeyframeRule = CSSKeyframeRule; |