Bug 1503896 - (Part 4) Track changes to CSS selectors; r=pbro

Depends on D10585
Renames the logChange() to logDeclarationChange() to distinguish it from the newly introduced logSelectorChange() method which tracks selector rename by logging two changes: a whole rule remove using the old selector and a whole rule insertion add using the new selector.

MozReview-Commit-ID: 9VoVMHYXumE

Differential Revision: https://phabricator.services.mozilla.com/D10586

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Razvan Caliman 2018-11-06 21:49:40 +00:00
Родитель e0e5a38637
Коммит 40321f65d7
1 изменённых файлов: 43 добавлений и 5 удалений

Просмотреть файл

@ -1412,7 +1412,7 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
} }
// Log the changes before applying them so we have access to the previous values. // Log the changes before applying them so we have access to the previous values.
modifications.map(mod => this.logChange(mod)); modifications.map(mod => this.logDeclarationChange(mod));
if (this.type === ELEMENT_STYLE) { if (this.type === ELEMENT_STYLE) {
// For element style rules, set the node's style attribute. // For element style rules, set the node's style attribute.
@ -1472,7 +1472,7 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
const tempElement = document.createElementNS(XHTML_NS, "div"); const tempElement = document.createElementNS(XHTML_NS, "div");
for (const mod of modifications) { for (const mod of modifications) {
this.logChange(mod); this.logDeclarationChange(mod);
if (mod.type === "set") { if (mod.type === "set") {
tempElement.style.setProperty(mod.name, mod.value, mod.priority || ""); tempElement.style.setProperty(mod.name, mod.value, mod.priority || "");
this.rawStyle.setProperty(mod.name, this.rawStyle.setProperty(mod.name,
@ -1548,13 +1548,13 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
}, },
/** /**
* Take an object with instructions to modify a CSS declaration and emit a * Take an object with instructions to modify a CSS declaration and log an object with
* "track-change" event with normalized metadata which describes the change. * normalized metadata which describes the change in the context of this rule.
* *
* @param {Object} change * @param {Object} change
* Data about a modification to a rule. @see |modifyProperties()| * Data about a modification to a rule. @see |modifyProperties()|
*/ */
logChange(change) { logDeclarationChange(change) {
// Destructure properties from the previous CSS declaration at this index, if any, // Destructure properties from the previous CSS declaration at this index, if any,
// to new variable names to indicate the previous state. // to new variable names to indicate the previous state.
let { let {
@ -1608,6 +1608,41 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
TrackChangeEmitter.trackChange(data); TrackChangeEmitter.trackChange(data);
}, },
/**
* Helper method for tracking CSS changes. Logs the change of this rule's selector as
* two operations: a rule removal, including its CSS declarations, using the old
* selector and a rule addition using the new selector.
*
* @param {String} oldSelector
* This rule's previous selector.
* @param {String} newSelector
* This rule's new selector.
*/
logSelectorChange(oldSelector, newSelector) {
// Build a collection of CSS declarations existing on this rule.
const declarations = this._declarations.reduce((acc, decl) => {
acc[decl.name] = decl.priority ? decl.value + " !important" : decl.value;
return acc;
}, {});
// Logging two distinct operations to remove the old rule and add a new one.
// TODO: Make TrackChangeEmitter support transactions so these two operations are
// grouped together when implementing undo/redo.
TrackChangeEmitter.trackChange({
...this.metadata,
add: null,
remove: declarations,
selector: oldSelector,
});
TrackChangeEmitter.trackChange({
...this.metadata,
add: declarations,
remove: null,
selector: newSelector,
});
},
/** /**
* Calls modifySelector2() which needs to be kept around for backwards compatibility. * Calls modifySelector2() which needs to be kept around for backwards compatibility.
* TODO: Once Firefox 64 is no longer supported, inline that mehtod's content, * TODO: Once Firefox 64 is no longer supported, inline that mehtod's content,
@ -1645,11 +1680,14 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
return { ruleProps: null, isMatching: true }; return { ruleProps: null, isMatching: true };
} }
// The rule's previous selector is lost after calling _addNewSelector(). Save it now.
const oldValue = this.rawRule.selectorText;
let selectorPromise = this._addNewSelector(value, editAuthored); let selectorPromise = this._addNewSelector(value, editAuthored);
if (editAuthored) { if (editAuthored) {
selectorPromise = selectorPromise.then((newCssRule) => { selectorPromise = selectorPromise.then((newCssRule) => {
if (newCssRule) { if (newCssRule) {
this.logSelectorChange(oldValue, value);
const style = this.pageStyle._styleRef(newCssRule); const style = this.pageStyle._styleRef(newCssRule);
// See the comment in |form| to understand this. // See the comment in |form| to understand this.
return style.getAuthoredCssText().then(() => newCssRule); return style.getAuthoredCssText().then(() => newCssRule);