Bug 1476366 - (Part 1) Instrument Rule and TextProperty models to emit event on change.
MozReview-Commit-ID: LD1sA6QWtTP
--- a/devtools/client/inspector/rules/models/rule.js
+++ b/devtools/client/inspector/rules/models/rule.js
@@ -12,16 +12,17 @@ const {ELEMENT_STYLE} = require("devtool
const TextProperty = require("devtools/client/inspector/rules/models/text-property");
const {promiseWarn} = require("devtools/client/inspector/shared/utils");
const {parseNamedDeclarations} = require("devtools/shared/css/parsing-utils");
const Services = require("Services");
const STYLE_INSPECTOR_PROPERTIES = "devtools/shared/locales/styleinspector.properties";
const {LocalizationHelper} = require("devtools/shared/l10n");
const STYLE_INSPECTOR_L10N = new LocalizationHelper(STYLE_INSPECTOR_PROPERTIES);
+const EventEmitter = require("devtools/shared/event-emitter");
/**
* Rule is responsible for the following:
* Manages a single style declaration or rule.
* Applies changes to the properties in a rule.
* Maintains a list of TextProperty objects.
*
* @param {ElementStyle} elementStyle
@@ -31,16 +32,18 @@ const STYLE_INSPECTOR_L10N = new Localiz
* rule: A StyleRuleActor
* inherited: An element this rule was inherited from. If omitted,
* the rule applies directly to the current element.
* isSystem: Is this a user agent style?
* isUnmatched: True if the rule does not match the current selected
* element, otherwise, false.
*/
function Rule(elementStyle, options) {
+ EventEmitter.decorate(this);
+
this.elementStyle = elementStyle;
this.domRule = options.rule;
this.matchedSelectors = options.matchedSelectors || [];
this.pseudoElement = options.pseudoElement || "";
this.isSystem = options.isSystem;
this.isUnmatched = options.isUnmatched || false;
this.inherited = options.inherited || null;
@@ -81,16 +84,20 @@ Rule.prototype = {
eltText += "#" + this.inherited.id;
}
this._inheritedSource =
STYLE_INSPECTOR_L10N.getFormatStr("rule.inheritedFrom", eltText);
}
return this._inheritedSource;
},
+ get isInlineStyle() {
+ return this.domRule.type === ELEMENT_STYLE;
+ },
+
get keyframesName() {
if (this._keyframesName) {
return this._keyframesName;
}
this._keyframesName = "";
if (this.keyframes) {
this._keyframesName =
STYLE_INSPECTOR_L10N.getFormatStr("rule.keyframe", this.keyframes.name);
@@ -163,16 +170,21 @@ Rule.prototype = {
this.applyProperties((modifications) => {
modifications.createProperty(ind, name, value, priority, enabled);
// Now that the rule has been updated, the server might have given us data
// that changes the state of the property. Update it now.
prop.updateEditor();
});
+ const change = {
+ rule: this,
+ add: { property: name, value }
+ };
+ this.emit("track-change", change);
return prop;
},
/**
* Helper function for applyProperties that is called when the actor
* does not support as-authored styles. Store disabled properties
* in the element style's store.
*/
@@ -395,16 +407,21 @@ Rule.prototype = {
removeProperty: function(property) {
const index = this.textProps.indexOf(property);
this.textProps.splice(index, 1);
// Need to re-apply properties in case removing this TextProperty
// exposes another one.
this.applyProperties((modifications) => {
modifications.removeProperty(index, property.name);
});
+ const change = {
+ rule: this,
+ remove: { property: property.name, value: property.value }
+ };
+ this.emit("track-change", change);
},
/**
* Get the list of TextProperties from the style. Needs
* to parse the style's authoredText.
*/
_getTextProperties: function() {
const textProps = [];
--- a/devtools/client/inspector/rules/models/text-property.js
+++ b/devtools/client/inspector/rules/models/text-property.js
@@ -112,21 +112,34 @@ TextProperty.prototype = {
if (changed) {
this.updateEditor();
}
},
setValue: function(value, priority, force = false) {
const store = this.rule.elementStyle.store;
+ const isValueUpdated = this.editor && value !== this.editor.committed.value;
- if (this.editor && value !== this.editor.committed.value || force) {
+ if (isValueUpdated || force) {
store.userProperties.setProperty(this.rule.domRule, this.name, value);
}
+ const change = {
+ rule: this.rule,
+ add: { property: this.name, value },
+ remove: isValueUpdated && this.editor.committed.value
+ ? {
+ property: this.name,
+ value: this.editor.committed.value
+ }
+ : null
+ };
+
+ this.rule.emit("track-change", change);
this.rule.setPropertyValue(this, value, priority);
this.updateEditor();
},
/**
* Called when the property's value has been updated externally, and
* the property and editor should update to reflect that value.
*
@@ -153,16 +166,21 @@ TextProperty.prototype = {
},
setEnabled: function(value) {
this.rule.setPropertyEnabled(this, value);
this.updateEditor();
},
remove: function() {
+ const change = {
+ rule: this.rule,
+ remove: { property: this.name, value: this.value }
+ };
+ this.rule.emit("track-change", change);
this.rule.removeProperty(this);
},
/**
* Return a string representation of the rule property.
*/
stringifyProperty: function() {
// Get the displayed property value