1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
10 } = require("resource://devtools/shared/protocol.js");
13 } = require("resource://devtools/shared/specs/style-rule.js");
15 loader
.lazyRequireGetter(
18 "resource://devtools/client/fronts/inspector/rule-rewriter.js"
22 * StyleRuleFront, the front for the StyleRule actor.
24 class StyleRuleFront
extends FrontClassWithSpec(styleRuleSpec
) {
25 constructor(client
, targetFront
, parentFront
) {
26 super(client
, targetFront
, parentFront
);
28 this.before("location-changed", this._locationChangedPre
.bind(this));
32 this.actorID
= form
.actor
;
34 this.traits
= form
.traits
|| {};
38 * Ensure _form is updated when location-changed is emitted.
40 _locationChangedPre(line
, column
) {
41 this._form
.line
= line
;
42 this._form
.column
= column
;
46 * Return a new RuleModificationList or RuleRewriter for this node.
47 * A RuleRewriter will be returned when the rule's canSetRuleText
48 * trait is true; otherwise a RuleModificationList will be
51 * @param {CssPropertiesFront} cssProperties
52 * This is needed by the RuleRewriter.
53 * @return {RuleModificationList}
55 startModifyingProperties(cssProperties
) {
56 if (this.canSetRuleText
) {
57 return new RuleRewriter(cssProperties
.isKnown
, this, this.authoredText
);
59 return new RuleModificationList(this);
63 return this._form
.type
;
66 return this._form
.line
|| -1;
69 return this._form
.column
|| -1;
72 return this._form
.cssText
;
74 get isNestedDeclarations() {
75 return !!this._form
.isNestedDeclarations
;
78 return typeof this._form
.authoredText
=== "string"
79 ? this._form
.authoredText
83 return this._form
.declarations
|| [];
86 return this._form
.keyText
;
89 return this._form
.name
;
92 return this._form
.selectors
;
94 get selectorsSpecificity() {
95 return this._form
.selectorsSpecificity
;
99 * Returns a concatenation of the rule's selector and all its ancestor "selectors".
100 * This is different from a "desugared" selector as what's returned is not an
101 * actual selector, but some kind of key that represent the rule selectors.
102 * This is used for the selector highlighter, where we need to know what's
107 get computedSelector() {
109 for (const ancestor
of this.ancestorData
) {
110 let ancestorSelector
;
111 if (ancestor
.selectors
) {
112 ancestorSelector
= ancestor
.selectors
.join(",");
113 } else if (ancestor
.type
=== "container") {
115 ancestor
.containerName
+ " " + ancestor
.containerQuery
;
116 } else if (ancestor
.type
=== "supports") {
117 ancestorSelector
= ancestor
.conditionText
;
118 } else if (ancestor
.value
) {
119 ancestorSelector
= ancestor
.value
;
122 "/" + (ancestor
.type
? ancestor
.type
+ " " : "") + ancestorSelector
;
125 return (selector
? selector
+ "/" : "") + this._form
.selectors
.join(",");
128 get selectorWarnings() {
129 return this._form
.selectorWarnings
;
132 get parentStyleSheet() {
133 const resourceCommand
= this.targetFront
.commands
.resourceCommand
;
134 return resourceCommand
.getResourceById(
135 resourceCommand
.TYPES
.STYLESHEET
,
136 this._form
.parentStyleSheet
141 return this.conn
.getFrontByID(this._form
.element
);
145 if (this._form
.href
) {
146 return this._form
.href
;
148 const sheet
= this.parentStyleSheet
;
149 return sheet
? sheet
.href
: "";
153 const sheet
= this.parentStyleSheet
;
154 return sheet
? sheet
.nodeHref
: "";
157 get canSetRuleText() {
158 return this._form
.traits
&& this._form
.traits
.canSetRuleText
;
163 source
: this.parentStyleSheet
,
171 return this._form
.ancestorData
;
175 return this._form
.userAdded
;
178 async
modifySelector(node
, value
) {
179 const response
= await
super.modifySelector(
185 if (response
.ruleProps
) {
186 response
.ruleProps
= response
.ruleProps
.entries
[0];
191 setRuleText(newText
, modifications
) {
192 this._form
.authoredText
= newText
;
193 return super.setRuleText(newText
, modifications
);
197 exports
.StyleRuleFront
= StyleRuleFront
;
198 registerFront(StyleRuleFront
);
201 * Convenience API for building a list of attribute modifications
202 * for the `modifyProperties` request. A RuleModificationList holds a
203 * list of modifications that will be applied to a StyleRuleActor.
204 * The modifications are processed in the order in which they are
205 * added to the RuleModificationList.
207 * Objects of this type expose the same API as @see RuleRewriter.
208 * This lets the inspector use (mostly) the same code, regardless of
209 * whether the server implements setRuleText.
211 class RuleModificationList
{
213 * Initialize a RuleModificationList.
214 * @param {StyleRuleFront} rule the associated rule
218 this.modifications
= [];
222 * Apply the modifications in this object to the associated rule.
224 * @return {Promise} A promise which will be resolved when the modifications
225 * are complete; @see StyleRuleActor.modifyProperties.
228 return this.rule
.modifyProperties(this.modifications
);
232 * Add a "set" entry to the modification list.
234 * @param {Number} index index of the property in the rule.
235 * This can be -1 in the case where
236 * the rule does not support setRuleText;
237 * generally for setting properties
238 * on an element's style.
239 * @param {String} name the property's name
240 * @param {String} value the property's value
241 * @param {String} priority the property's priority, either the empty
242 * string or "important"
244 setProperty(index
, name
, value
, priority
) {
245 this.modifications
.push({ type
: "set", index
, name
, value
, priority
});
249 * Add a "remove" entry to the modification list.
251 * @param {Number} index index of the property in the rule.
252 * This can be -1 in the case where
253 * the rule does not support setRuleText;
254 * generally for setting properties
255 * on an element's style.
256 * @param {String} name the name of the property to remove
258 removeProperty(index
, name
) {
259 this.modifications
.push({ type
: "remove", index
, name
});
263 * Rename a property. This implementation acts like
264 * |removeProperty|, because |setRuleText| is not available.
266 * @param {Number} index index of the property in the rule.
267 * This can be -1 in the case where
268 * the rule does not support setRuleText;
269 * generally for setting properties
270 * on an element's style.
271 * @param {String} name current name of the property
273 * This parameter is also passed, but as it is not used in this
274 * implementation, it is omitted. It is documented here as this
275 * code also defined the interface implemented by @see RuleRewriter.
276 * @param {String} newName new name of the property
278 renameProperty(index
, name
) {
279 this.removeProperty(index
, name
);
283 * Enable or disable a property. This implementation acts like
284 * a no-op when enabling, because |setRuleText| is not available.
286 * @param {Number} index index of the property in the rule.
287 * This can be -1 in the case where
288 * the rule does not support setRuleText;
289 * generally for setting properties
290 * on an element's style.
291 * @param {String} name current name of the property
292 * @param {Boolean} isEnabled true if the property should be enabled;
293 * false if it should be disabled
295 setPropertyEnabled(index
, name
, isEnabled
) {
297 this.modifications
.push({ type
: "disable", index
, name
});
302 * Create a new property. This implementation does nothing, because
303 * |setRuleText| is not available.
305 * These parameters are passed, but as they are not used in this
306 * implementation, they are omitted. They are documented here as
307 * this code also defined the interface implemented by @see
310 * @param {Number} index index of the property in the rule.
311 * This can be -1 in the case where
312 * the rule does not support setRuleText;
313 * generally for setting properties
314 * on an element's style.
315 * @param {String} name name of the new property
316 * @param {String} value value of the new property
317 * @param {String} priority priority of the new property; either
318 * the empty string or "important"
319 * @param {Boolean} enabled True if the new property should be
320 * enabled, false if disabled