Bug 1524548 - (Part 3) Add option to Changes panel context menu to copy changes. r-gl r=gl

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.

Differential Revision: https://phabricator.services.mozilla.com/D18706
This commit is contained in:
Razvan Caliman
2019-02-06 19:07:42 +00:00
parent 42b5c9c139
commit 9b46124531
4 changed files with 57 additions and 21 deletions

View File

@@ -10,8 +10,10 @@ const { createFactory, createElement } = require("devtools/client/shared/vendor/
const { Provider } = require("devtools/client/shared/vendor/react-redux");
loader.lazyRequireGetter(this, "ChangesContextMenu", "devtools/client/inspector/changes/ChangesContextMenu");
loader.lazyRequireGetter(this, "clipboardHelper", "devtools/shared/platform/clipboard");
const ChangesApp = createFactory(require("./components/ChangesApp"));
const { getChangesStylesheet } = require("./selectors/changes");
const {
TELEMETRY_SCALAR_CONTEXTMENU,
@@ -30,6 +32,7 @@ class ChangesView {
this.inspector = inspector;
this.store = this.inspector.store;
this.telemetry = this.inspector.telemetry;
this.window = window;
this.onAddChange = this.onAddChange.bind(this);
this.onClearChanges = this.onClearChanges.bind(this);
@@ -100,6 +103,32 @@ class ChangesView {
}
}
/**
* Handler for the "Copy Changes" option from the context menu.
* Builds a CSS text with the changes aggregated for the target rule and copies it to
* the clipboard.
*
* @param {String} ruleId
* Rule id of the target rule.
* @param {String} sourceId
* Source id of the target rule.
*/
copyChanges(ruleId, sourceId) {
const state = this.store.getState().changes || {};
const filter = { ruleIds: [ruleId], sourceIds: [sourceId] };
const text = getChangesStylesheet(state, filter);
clipboardHelper.copyString(text);
}
/**
* Handler for the "Copy" option from the context menu.
* Copies the current text selection to the clipboard.
*/
copySelection() {
clipboardHelper.copyString(this.window.getSelection().toString());
this.telemetry.scalarAdd(TELEMETRY_SCALAR_CONTEXTMENU_COPY, 1);
}
onAddChange(change) {
// Turn data into a suitable change to send to the store.
this.store.dispatch(trackChange(change));
@@ -118,14 +147,6 @@ class ChangesView {
this.telemetry.scalarAdd(TELEMETRY_SCALAR_CONTEXTMENU, 1);
}
/**
* Callback function ran after the "Copy" option from the context menu is used.
* This is not an event handler. The copy event cannot be prevented from this method.
*/
onContextMenuCopy() {
this.telemetry.scalarAdd(TELEMETRY_SCALAR_CONTEXTMENU_COPY, 1);
}
/**
* Event handler for the "copy" event fired when content is copied to the clipboard.
* We don't change the default behavior. We only log the increment count of this action.