Closed Bug 1524548 Opened 1 year ago Closed 1 year ago

Export Changes - copy list of CSS changes for a rule


(DevTools :: Inspector: Changes, enhancement, P2)



(firefox67 fixed)

Firefox 67
Tracking Status
firefox67 --- fixed


(Reporter: rcaliman, Assigned: rcaliman)


(Blocks 1 open bug)



(4 files)

Provide a context menu option to copy the list of CSS declarations changed for the target rule in the Changes panel.

The clipboard content will be a CSS rule with:

  • the CSS selector of the target rule
  • removed declarations will be commented out
  • added declarations will be listed as-is


This plain text of changes:

body {
- color: black;
+ color: white;
+ background: red;

Is copied to the clipboard as:

body {
 /* color: black; */
 color: white;
 background: red;

This output gives users a way to copy the subset of CSS changes to a rule to communicate the CSS mutations. This valid CSS rule can be pasted into a code editor, but must be reconciled manually to ensure all changes take effect, including declarations which are only removed and not updated.

If the target is an ancestor rule (@media, @supports), the output will include all changes from their nested CSS child rules.

Duplicate of this bug: 1505332
Depends on: 1525238

The diff for this change looks needlessly scary. The only material change is the introduction of the filter parameter to the getChangesTree() selector to restrict the output to a subtree that includes only the martching rules and sources provided in as arrays of ids in the filters argument.

The sources and rules are filtered, if any corresponding ids are provided, then the same logic to build the tree is used.

The meaningful blocks of code introduced are:

.filter(([sourceId, source]) => {
  // Use only matching sources if an array to filter by was provided.
  if (sourceIdsFilter.length) {
    return sourceIdsFilter.includes(sourceId);

  return true;


.filter(([ruleId, rule]) => {
  // Use only matching rules if an array to filter by was provided.
  if (rulesIdsFilter.length) {
    return rulesIdsFilter.includes(ruleId);

  return true;

Introducing a newline confused the diff algorithm to consider that much bigger changes have occured.

Introducing these filtering options lays the ground work for building subtrees of changes per-rule and per-stylesheet to be copied to the clipboard or saved as a file.

Depends on D18703

Adds a new selector method to build the CSS text for a stylesheet with the aggregated changes for one or more rules.

Makes use of the filtering capabilities introduced in Part 1 to be able to build a stylesheet from just a subset of rules or sources.

Depends on D18704

Adds a new option to the context menu to copy the changes for a rule as valid CSS text.
Removed properties are commented out. Added properties are used as-is. Style source information is listed as a code comment above the CSS rule.

Makes use of the new Redux selector introduced in Part 2 (see D18704) to build a stylesheet text with the changes per-rule. That will be reused for copying all changes per-stylesheet.

Moves the copy text selection handler out to the ChangesView to co-locate it with other (upcoming) copy actions.

Adds data-ruleid and data-sourceid to DOM elements to help match the target element to the rule/source in the Redux store.

Depends on D18706

Follow up for D18704. Adds xpcshell unit test to check that stylesheets are genereated in the expected formats for single or deeply nested CSS rules.

Pushed by
(Part 1) Add support to filter by ruleId and sourceId when building the changes tree. r=pbro
(Part 2) Add Redux selector method to build a stylesheet from a tree of changes. r=pbro
(Part 3) Add option to Changes panel context menu to copy changes. r-gl r=gl
(Part 4) Add unit test to check stylesheets generated from tracked changes. r=pbro
Assignee: nobody → rcaliman
You need to log in before you can comment on or make changes to this bug.