Bug 1525238 - Use actorID for tracked rules and stylesheets. r=pbro

Replaces custom generated hashes with the actorIDs which are stable
during the editing session enough to use as unique identifiers.

For future restore / persistence, we still have the metadata about each
rule and stylesheet to attempt to identify them again.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Razvan Caliman 2019-02-14 16:29:21 +00:00
Родитель 67db6ca162
Коммит c21e773cbd
3 изменённых файлов: 23 добавлений и 9 удалений

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

@ -45,6 +45,8 @@ function cloneState(state = {}) {
* @param {Object} ruleData
* Information about a CSS rule:
* {
* id: {String}
* Unique rule id.
* selector: {String}
* CSS selector text
* ancestors: {Array}
@ -66,7 +68,6 @@ function createRule(ruleData, rules) {
const ruleAncestry = [...ruleData.ancestors, { ...ruleData }];
return ruleAncestry
// First, generate a unique identifier for each rule.
.map((rule, index) => {
// Ensure each rule has ancestors excluding itself (expand the flattened rule tree).
rule.ancestors = ruleAncestry.slice(0, index);
@ -77,7 +78,9 @@ function createRule(ruleData, rules) {
`${rule.typeName} ${(rule.conditionText || rule.name || rule.keyText)}`;
}
return getRuleHash(rule);
// Bug 1525326: Remove getRuleHash() in Firefox 70. Until then, we fallback
// to the custom hashing method if the server did not provide a rule with an id.
return rule.id || getRuleHash(rule);
})
// Then, create new entries in the rules collection and assign dependencies.
.map((ruleId, index, array) => {
@ -194,19 +197,20 @@ const reducers = {
change = { ...defaults, ...change };
state = cloneState(state);
const { type, href, index, isFramed } = change.source;
const { selector, ancestors, ruleIndex, type: changeType } = change;
const sourceId = getSourceHash(change.source);
const ruleId = getRuleHash({ selector, ancestors, ruleIndex });
// Bug 1525326: remove getSourceHash() and getRuleHash() in Firefox 70 after we no
// longer support old servers which do not implement the id for the rule and source.
const sourceId = change.source.id || getSourceHash(change.source);
const ruleId = change.id || getRuleHash({ selector, ancestors, ruleIndex });
// Copy or create object identifying the source (styelsheet/element) for this change.
const source = Object.assign({}, state[sourceId], { type, href, index, isFramed });
const source = Object.assign({}, state[sourceId], change.source);
// Copy or create collection of all rules ever changed in this source.
const rules = Object.assign({}, source.rules);
// Refrence or create object identifying the rule for this change.
// Reference or create object identifying the rule for this change.
let rule = rules[ruleId];
if (!rule) {
rule = createRule({ selector, ancestors, ruleIndex }, rules);
rule = createRule(change, rules);
if (changeType.startsWith("rule-")) {
rule.changeType = changeType;
}

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

@ -21,3 +21,4 @@ support-files =
[browser_changes_declaration_remove.js]
[browser_changes_declaration_rename.js]
[browser_changes_rule_selector.js]
skip-if=true # Enable with Bug 1527924

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

@ -1085,10 +1085,12 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
*/
get metadata() {
const data = {};
data.id = this.actorID;
// Collect information about the rule's ancestors (@media, @supports, @keyframes).
// Used to show context for this change in the UI and to match the rule for undo/redo.
data.ancestors = this.ancestorRules.map(rule => {
return {
id: rule.actorID,
// Rule type as number defined by CSSRule.type (ex: 4, 7, 12)
// @see https://developer.mozilla.org/en-US/docs/Web/API/CSSRule
type: rule.rawRule.type,
@ -1106,7 +1108,7 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
});
// For changes in element style attributes, generate a unique selector.
if (this.type === ELEMENT_STYLE) {
if (this.type === ELEMENT_STYLE && this.rawNode) {
// findCssSelector() fails on XUL documents. Catch and silently ignore that error.
try {
data.selector = findCssSelector(this.rawNode);
@ -1122,6 +1124,12 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
// Whether the element lives in a different frame than the host document.
isFramed: this.rawNode.ownerGlobal !== this.pageStyle.ownerWindow,
};
const nodeActor = this.pageStyle.walker.getNode(this.rawNode);
if (nodeActor) {
data.source.id = nodeActor.actorID;
}
data.ruleIndex = 0;
} else {
data.selector = (this.type === CSSRule.KEYFRAME_RULE)
@ -1131,6 +1139,7 @@ var StyleRuleActor = protocol.ActorClassWithSpec(styleRuleSpec, {
// Inline stylesheets have a null href; Use window URL instead.
type: this.sheetActor.href ? "stylesheet" : "inline",
href: this.sheetActor.href || this.sheetActor.window.location.toString(),
id: this.sheetActor.actorID,
index: this.sheetActor.styleSheetIndex,
// Whether the stylesheet lives in a different frame than the host document.
isFramed: this.sheetActor.ownerWindow !== this.sheetActor.window,