From e10bf5f2e97bc53f7da1dd223d075ac255c0a2ee Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Mon, 17 Aug 2015 15:49:20 -0700 Subject: [PATCH] Bug 952456 - Part 2: Support copy image in BrowserElement. r=kchen Add a new context menu option, copy image. --HG-- extra : histedit_source : 5af95cb5fa11727ad1034fcbe5fb855d914b2b62 --- .../BrowserElementChildPreload.js | 62 +++++++++++++------ 1 file changed, 44 insertions(+), 18 deletions(-) diff --git a/dom/browser-element/BrowserElementChildPreload.js b/dom/browser-element/BrowserElementChildPreload.js index ccbe01120fd3..2b737e9a2c17 100644 --- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -63,6 +63,7 @@ const OBSERVED_EVENTS = [ const COMMAND_MAP = { 'cut': 'cmd_cut', 'copy': 'cmd_copyAndCollapseToEnd', + 'copyImage': 'cmd_copyImage', 'paste': 'cmd_paste', 'selectall': 'cmd_selectAll' }; @@ -855,6 +856,11 @@ BrowserElementChild.prototype = { var elem = e.target; var menuData = {systemTargets: [], contextmenu: null}; var ctxMenuId = null; + var hasImgElement = false; + + // Set the event target as the copy image command needs it to + // determine what was context-clicked on. + docShell.contentViewer.QueryInterface(Ci.nsIContentViewerEdit).setCommandNode(elem); while (elem && elem.parentNode) { var ctxData = this._getSystemCtxMenuData(elem); @@ -868,14 +874,21 @@ BrowserElementChild.prototype = { if (!ctxMenuId && 'hasAttribute' in elem && elem.hasAttribute('contextmenu')) { ctxMenuId = elem.getAttribute('contextmenu'); } + + // Enable copy image option + if (elem.nodeName == 'IMG') { + hasImgElement = true; + } + elem = elem.parentNode; } - if (ctxMenuId) { - var menu = e.target.ownerDocument.getElementById(ctxMenuId); - if (menu) { - menuData.contextmenu = this._buildMenuObj(menu, ''); + if (ctxMenuId || hasImgElement) { + var menu = null; + if (ctxMenuId) { + menu = e.target.ownerDocument.getElementById(ctxMenuId); } + menuData.contextmenu = this._buildMenuObj(menu, '', hasImgElement); } // Pass along the position where the context menu should be located @@ -1208,31 +1221,44 @@ BrowserElementChild.prototype = { _recvFireCtxCallback: function(data) { debug("Received fireCtxCallback message: (" + data.json.menuitem + ")"); - // We silently ignore if the embedder uses an incorrect id in the callback - if (data.json.menuitem in this._ctxHandlers) { + + if (data.json.menuitem == 'copy-image') { + // Set command + data.json.command = 'copyImage'; + this._recvDoCommand(data); + } else if (data.json.menuitem in this._ctxHandlers) { this._ctxHandlers[data.json.menuitem].click(); this._ctxHandlers = {}; } else { + // We silently ignore if the embedder uses an incorrect id in the callback debug("Ignored invalid contextmenu invocation"); } }, - _buildMenuObj: function(menu, idPrefix) { + _buildMenuObj: function(menu, idPrefix, hasImgElement) { var menuObj = {type: 'menu', items: []}; - this._maybeCopyAttribute(menu, menuObj, 'label'); + // Customized context menu + if (menu) { + this._maybeCopyAttribute(menu, menuObj, 'label'); - for (var i = 0, child; child = menu.children[i++];) { - if (child.nodeName === 'MENU') { - menuObj.items.push(this._buildMenuObj(child, idPrefix + i + '_')); - } else if (child.nodeName === 'MENUITEM') { - var id = this._ctxCounter + '_' + idPrefix + i; - var menuitem = {id: id, type: 'menuitem'}; - this._maybeCopyAttribute(child, menuitem, 'label'); - this._maybeCopyAttribute(child, menuitem, 'icon'); - this._ctxHandlers[id] = child; - menuObj.items.push(menuitem); + for (var i = 0, child; child = menu.children[i++];) { + if (child.nodeName === 'MENU') { + menuObj.items.push(this._buildMenuObj(child, idPrefix + i + '_', false)); + } else if (child.nodeName === 'MENUITEM') { + var id = this._ctxCounter + '_' + idPrefix + i; + var menuitem = {id: id, type: 'menuitem'}; + this._maybeCopyAttribute(child, menuitem, 'label'); + this._maybeCopyAttribute(child, menuitem, 'icon'); + this._ctxHandlers[id] = child; + menuObj.items.push(menuitem); + } } } + // "Copy Image" menu item + if (hasImgElement) { + menuObj.items.push({id: 'copy-image'}); + } + return menuObj; },