ChangesContextMenu.js (3107B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const Menu = require("resource://devtools/client/framework/menu.js"); 8 loader.lazyRequireGetter( 9 this, 10 "MenuItem", 11 "resource://devtools/client/framework/menu-item.js" 12 ); 13 14 const { 15 getStr, 16 } = require("resource://devtools/client/inspector/changes/utils/l10n.js"); 17 18 /** 19 * Context menu for the Changes panel with options to select, copy and export CSS changes. 20 */ 21 class ChangesContextMenu extends Menu { 22 constructor(config = {}) { 23 super(config); 24 this.onCopy = config.onCopy; 25 this.onCopyAllChanges = config.onCopyAllChanges; 26 this.onCopyDeclaration = config.onCopyDeclaration; 27 this.onCopyRule = config.onCopyRule; 28 this.onSelectAll = config.onSelectAll; 29 this.toolboxDocument = config.toolboxDocument; 30 this.window = config.window; 31 } 32 33 show(event) { 34 this._openMenu({ 35 target: event.target, 36 screenX: event.screenX, 37 screenY: event.screenY, 38 }); 39 } 40 41 _openMenu({ target, screenX = 0, screenY = 0 } = {}) { 42 this.window.focus(); 43 // Remove existing menu items. 44 this.clear(); 45 46 // Copy option 47 const menuitemCopy = new MenuItem({ 48 id: "changes-contextmenu-copy", 49 label: getStr("changes.contextmenu.copy"), 50 accesskey: getStr("changes.contextmenu.copy.accessKey"), 51 click: this.onCopy, 52 disabled: !this._hasTextSelected(), 53 }); 54 this.append(menuitemCopy); 55 56 const declEl = target.closest(".changes__declaration"); 57 const ruleEl = target.closest("[data-rule-id]"); 58 const ruleId = ruleEl ? ruleEl.dataset.ruleId : null; 59 60 if (ruleId || declEl) { 61 // Copy Rule option 62 this.append( 63 new MenuItem({ 64 id: "changes-contextmenu-copy-rule", 65 label: getStr("changes.contextmenu.copyRule"), 66 click: () => this.onCopyRule(ruleId, true), 67 }) 68 ); 69 70 // Copy Declaration option. Visible only if there is a declaration element target. 71 this.append( 72 new MenuItem({ 73 id: "changes-contextmenu-copy-declaration", 74 label: getStr("changes.contextmenu.copyDeclaration"), 75 click: () => this.onCopyDeclaration(declEl), 76 visible: !!declEl, 77 }) 78 ); 79 80 this.append( 81 new MenuItem({ 82 type: "separator", 83 }) 84 ); 85 } 86 87 // Select All option 88 const menuitemSelectAll = new MenuItem({ 89 id: "changes-contextmenu-select-all", 90 label: getStr("changes.contextmenu.selectAll"), 91 accesskey: getStr("changes.contextmenu.selectAll.accessKey"), 92 click: this.onSelectAll, 93 }); 94 this.append(menuitemSelectAll); 95 96 this.popup(screenX, screenY, this.toolboxDocument); 97 } 98 99 _hasTextSelected() { 100 const selection = this.window.getSelection(); 101 return selection.toString() && !selection.isCollapsed; 102 } 103 104 destroy() { 105 this.window = null; 106 this.toolboxDocument = null; 107 } 108 } 109 110 module.exports = ChangesContextMenu;