--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -34,18 +34,17 @@ nsContextMenu.prototype = {
this.hasPageMenu = false;
this.isContentSelected = !this.selectionInfo.docSelectionIsCollapsed;
if (!aIsShift) {
if (this.isRemote) {
this.hasPageMenu =
PageMenuParent.addToPopup(gContextMenuContentData.customMenuItems,
this.browser, aXulMenu);
- }
- else {
+ } else {
this.hasPageMenu = PageMenuParent.buildAndAddToPopup(this.target, aXulMenu);
}
let subject = {
menu: aXulMenu,
tab: gBrowser ? gBrowser.getTabForBrowser(this.browser) : undefined,
isContentSelected: this.isContentSelected,
inFrame: this.inFrame,
@@ -185,17 +184,17 @@ nsContextMenu.prototype = {
if (shouldShow || this.onSocial) {
stopReloadItem = (stopped || this.onSocial) ? "reload" : "stop";
}
this.showItem("context-reload", stopReloadItem == "reload");
this.showItem("context-stop", stopReloadItem == "stop");
// XXX: Stop is determined in browser.js; the canStop broadcaster is broken
- //this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
+ // this.setItemAttrFromNode( "context-stop", "disabled", "canStop" );
},
initLeaveDOMFullScreenItems: function CM_initLeaveFullScreenItem() {
// only show the option if the user is in DOM fullscreen
var shouldShow = (this.target.ownerDocument.fullscreenElement != null);
this.showItem("context-leave-dom-fullscreen", shouldShow);
// Explicitly show if in DOM fullscreen, but do not hide it has already been shown
@@ -282,17 +281,17 @@ nsContextMenu.prototype = {
// View image depends on having an image that's not standalone
// (or is in a frame), or a canvas.
this.showItem("context-viewimage", (this.onImage &&
(!this.inSyntheticDoc || this.inFrame)) || this.onCanvas);
// View video depends on not having a standalone video.
this.showItem("context-viewvideo", this.onVideo && (!this.inSyntheticDoc || this.inFrame));
- this.setItemAttr("context-viewvideo", "disabled", !this.mediaURL);
+ this.setItemAttr("context-viewvideo", "disabled", !this.mediaURL);
// View background image depends on whether there is one, but don't make
// background images of a stand-alone media document available.
this.showItem("context-viewbgimage", shouldShow &&
!this._hasMultipleBGImages &&
!this.inSyntheticDoc);
this.showItem("context-sep-viewbgimage", shouldShow &&
!this._hasMultipleBGImages &&
@@ -336,19 +335,19 @@ nsContextMenu.prototype = {
this.showItem("context-bookmarkframe", !this.inSrcdocFrame);
this.showItem("open-frame-sep", !this.inSrcdocFrame);
this.showItem("frame-sep", this.inFrame && this.isTextSelected);
// Hide menu entries for images, show otherwise
if (this.inFrame) {
if (BrowserUtils.mimeTypeIsTextBased(this.target.ownerDocument.contentType))
- this.isFrameImage.removeAttribute('hidden');
+ this.isFrameImage.removeAttribute("hidden");
else
- this.isFrameImage.setAttribute('hidden', 'true');
+ this.isFrameImage.setAttribute("hidden", "true");
}
// BiDi UI
this.showItem("context-sep-bidi", !this.onNumeric && top.gBidiUI);
this.showItem("context-bidi-text-direction-toggle",
this.onTextInput && !this.onNumeric && top.gBidiUI);
this.showItem("context-bidi-page-direction-toggle",
!this.onTextInput && top.gBidiUI);
@@ -362,17 +361,17 @@ nsContextMenu.prototype = {
this.showItem("context-sharepage", pageShare);
this.showItem("context-shareselect", shareEnabled && this.isContentSelected);
this.showItem("context-sharelink", shareEnabled && (this.onLink || this.onPlainTextLink) && !this.onMailtoLink);
this.showItem("context-shareimage", shareEnabled && this.onImage);
this.showItem("context-sharevideo", shareEnabled && this.onVideo);
this.setItemAttr("context-sharevideo", "disabled", !this.mediaURL || this.mediaURL.startsWith("blob:"));
},
- initSpellingItems: function() {
+ initSpellingItems() {
var canSpell = InlineSpellCheckerUI.canSpellCheck &&
!InlineSpellCheckerUI.initialSpellCheckPending &&
this.canSpellCheck;
let showDictionaries = canSpell && InlineSpellCheckerUI.enabled;
var onMisspelling = InlineSpellCheckerUI.overMisspelling;
var showUndo = canSpell && InlineSpellCheckerUI.canUndo();
this.showItem("spell-check-enabled", canSpell);
this.showItem("spell-separator", canSpell);
@@ -386,41 +385,40 @@ nsContextMenu.prototype = {
this.showItem("spell-suggestions-separator", onMisspelling || showUndo);
if (onMisspelling) {
var suggestionsSeparator =
document.getElementById("spell-add-to-dictionary");
var numsug =
InlineSpellCheckerUI.addSuggestionsToMenu(suggestionsSeparator.parentNode,
suggestionsSeparator, 5);
this.showItem("spell-no-suggestions", numsug == 0);
+ } else {
+ this.showItem("spell-no-suggestions", false);
}
- else
- this.showItem("spell-no-suggestions", false);
// dictionary list
this.showItem("spell-dictionaries", showDictionaries);
if (canSpell) {
var dictMenu = document.getElementById("spell-dictionaries-menu");
var dictSep = document.getElementById("spell-language-separator");
let count = InlineSpellCheckerUI.addDictionaryListToMenu(dictMenu, dictSep);
this.showItem(dictSep, count > 0);
this.showItem("spell-add-dictionaries-main", false);
- }
- else if (this.onEditableArea) {
+ } else if (this.onEditableArea) {
// when there is no spellchecker but we might be able to spellcheck
// add the add to dictionaries item. This will ensure that people
// with no dictionaries will be able to download them
this.showItem("spell-language-separator", showDictionaries);
this.showItem("spell-add-dictionaries-main", showDictionaries);
+ } else {
+ this.showItem("spell-add-dictionaries-main", false);
}
- else
- this.showItem("spell-add-dictionaries-main", false);
},
- initClipboardItems: function() {
+ initClipboardItems() {
// Copy depends on whether there is selected text.
// Enabling this context menu item is now done through the global
// command updating system
// this.setItemAttr( "context-copy", "disabled", !this.isTextSelected() );
goUpdateGlobalEditMenuItems();
this.showItem("context-undo", this.onTextInput);
this.showItem("context-sep-undo", this.onTextInput);
@@ -453,28 +451,28 @@ nsContextMenu.prototype = {
// Note: the element doesn't exist on all platforms, but showItem() takes
// care of that by itself.
this.showItem("context-copyimage-contents", this.onImage);
// Copy image location depends on whether we're on an image.
this.showItem("context-copyimage", this.onImage);
this.showItem("context-copyvideourl", this.onVideo);
this.showItem("context-copyaudiourl", this.onAudio);
- this.setItemAttr("context-copyvideourl", "disabled", !this.mediaURL);
- this.setItemAttr("context-copyaudiourl", "disabled", !this.mediaURL);
+ this.setItemAttr("context-copyvideourl", "disabled", !this.mediaURL);
+ this.setItemAttr("context-copyaudiourl", "disabled", !this.mediaURL);
this.showItem("context-sep-copyimage", this.onImage ||
this.onVideo || this.onAudio);
},
- initMediaPlayerItems: function() {
+ initMediaPlayerItems() {
var onMedia = (this.onVideo || this.onAudio);
// Several mutually exclusive items... play/pause, mute/unmute, show/hide
- this.showItem("context-media-play", onMedia && (this.target.paused || this.target.ended));
+ this.showItem("context-media-play", onMedia && (this.target.paused || this.target.ended));
this.showItem("context-media-pause", onMedia && !this.target.paused && !this.target.ended);
- this.showItem("context-media-mute", onMedia && !this.target.muted);
+ this.showItem("context-media-mute", onMedia && !this.target.muted);
this.showItem("context-media-unmute", onMedia && this.target.muted);
this.showItem("context-media-playbackrate", onMedia && this.target.duration != Number.POSITIVE_INFINITY);
this.showItem("context-media-loop", onMedia);
this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
this.showItem("context-media-hidecontrols", this.target.controls && (this.onVideo || (this.onAudio && !this.inSyntheticDoc)));
this.showItem("context-video-fullscreen", this.onVideo && this.target.ownerDocument.fullscreenElement == null);
this.showItem("context-media-eme-learnmore", this.onDRMMedia);
this.showItem("context-media-eme-separator", this.onDRMMedia);
@@ -484,44 +482,44 @@ nsContextMenu.prototype = {
this.setItemAttr("context-media-playbackrate-050x", "checked", this.target.playbackRate == 0.5);
this.setItemAttr("context-media-playbackrate-100x", "checked", this.target.playbackRate == 1.0);
this.setItemAttr("context-media-playbackrate-125x", "checked", this.target.playbackRate == 1.25);
this.setItemAttr("context-media-playbackrate-150x", "checked", this.target.playbackRate == 1.5);
this.setItemAttr("context-media-playbackrate-200x", "checked", this.target.playbackRate == 2.0);
this.setItemAttr("context-media-loop", "checked", this.target.loop);
var hasError = this.target.error != null ||
this.target.networkState == this.target.NETWORK_NO_SOURCE;
- this.setItemAttr("context-media-play", "disabled", hasError);
+ this.setItemAttr("context-media-play", "disabled", hasError);
this.setItemAttr("context-media-pause", "disabled", hasError);
- this.setItemAttr("context-media-mute", "disabled", hasError);
+ this.setItemAttr("context-media-mute", "disabled", hasError);
this.setItemAttr("context-media-unmute", "disabled", hasError);
this.setItemAttr("context-media-playbackrate", "disabled", hasError);
this.setItemAttr("context-media-playbackrate-050x", "disabled", hasError);
this.setItemAttr("context-media-playbackrate-100x", "disabled", hasError);
this.setItemAttr("context-media-playbackrate-125x", "disabled", hasError);
this.setItemAttr("context-media-playbackrate-150x", "disabled", hasError);
this.setItemAttr("context-media-playbackrate-200x", "disabled", hasError);
this.setItemAttr("context-media-showcontrols", "disabled", hasError);
this.setItemAttr("context-media-hidecontrols", "disabled", hasError);
if (this.onVideo) {
let canSaveSnapshot = !this.onDRMMedia && this.target.readyState >= this.target.HAVE_CURRENT_DATA;
- this.setItemAttr("context-video-saveimage", "disabled", !canSaveSnapshot);
+ this.setItemAttr("context-video-saveimage", "disabled", !canSaveSnapshot);
this.setItemAttr("context-video-fullscreen", "disabled", hasError);
}
}
- this.showItem("context-media-sep-commands", onMedia);
+ this.showItem("context-media-sep-commands", onMedia);
},
- initClickToPlayItems: function() {
+ initClickToPlayItems() {
this.showItem("context-ctp-play", this.onCTPPlugin);
this.showItem("context-ctp-hide", this.onCTPPlugin);
this.showItem("context-sep-ctp", this.onCTPPlugin);
},
- initPasswordManagerItems: function() {
+ initPasswordManagerItems() {
let loginFillInfo = gContextMenuContentData && gContextMenuContentData.loginFillInfo;
// If we could not find a password field we
// don't want to show the form fill option.
let showFill = loginFillInfo && loginFillInfo.passwordField.found;
// Disable the fill option if the user has set a master password
// or if the password field or target field are disabled.
@@ -556,33 +554,33 @@ nsContextMenu.prototype = {
if (!fragment) {
return;
}
let popup = document.getElementById("fill-login-popup");
let insertBeforeElement = document.getElementById("fill-login-no-logins");
popup.insertBefore(fragment, insertBeforeElement);
},
- initSyncItems: function() {
+ initSyncItems() {
gFxAccounts.initPageContextMenu(this);
},
- openPasswordManager: function() {
+ openPasswordManager() {
LoginHelper.openPasswordManager(window, gContextMenuContentData.documentURIObject.host);
},
- inspectNode: function() {
+ inspectNode() {
let gBrowser = this.browser.ownerGlobal.gBrowser;
let { require } = Cu.import("resource://devtools/shared/Loader.jsm", {});
let { gDevToolsBrowser } = require("devtools/client/framework/devtools-browser");
return gDevToolsBrowser.inspectNode(gBrowser.selectedTab, this.target);
},
// Set various context menu attributes based on the state of the world.
- setTarget: function (aNode, aRangeParent, aRangeOffset) {
+ setTarget(aNode, aRangeParent, aRangeOffset) {
// gContextMenuContentData.isRemote tells us if the event came from a remote
// process. gContextMenuContentData can be null if something (like tests)
// opens the context menu directly.
let editFlags;
this.isRemote = gContextMenuContentData && gContextMenuContentData.isRemote;
if (this.isRemote) {
aNode = gContextMenuContentData.event.target;
aRangeParent = gContextMenuContentData.event.rangeParent;
@@ -691,100 +689,91 @@ nsContextMenu.prototype = {
}
this.mediaURL = this.target.currentURI.spec;
var descURL = this.target.getAttribute("longdesc");
if (descURL) {
this.imageDescURL = makeURLAbsolute(ownerDoc.body.baseURI, descURL);
}
- }
- else if (this.target instanceof HTMLCanvasElement) {
+ } else if (this.target instanceof HTMLCanvasElement) {
this.onCanvas = true;
- }
- else if (this.target instanceof HTMLVideoElement) {
+ } else if (this.target instanceof HTMLVideoElement) {
let mediaURL = this.target.currentSrc || this.target.src;
if (this.isMediaURLReusable(mediaURL)) {
this.mediaURL = mediaURL;
}
if (this._isProprietaryDRM()) {
this.onDRMMedia = true;
}
// Firefox always creates a HTMLVideoElement when loading an ogg file
// directly. If the media is actually audio, be smarter and provide a
// context menu with audio operations.
if (this.target.readyState >= this.target.HAVE_METADATA &&
(this.target.videoWidth == 0 || this.target.videoHeight == 0)) {
this.onAudio = true;
} else {
this.onVideo = true;
}
- }
- else if (this.target instanceof HTMLAudioElement) {
+ } else if (this.target instanceof HTMLAudioElement) {
this.onAudio = true;
let mediaURL = this.target.currentSrc || this.target.src;
if (this.isMediaURLReusable(mediaURL)) {
this.mediaURL = mediaURL;
}
if (this._isProprietaryDRM()) {
this.onDRMMedia = true;
}
- }
- else if (editFlags & (SpellCheckHelper.INPUT | SpellCheckHelper.TEXTAREA)) {
+ } else if (editFlags & (SpellCheckHelper.INPUT | SpellCheckHelper.TEXTAREA)) {
this.onTextInput = (editFlags & SpellCheckHelper.TEXTINPUT) !== 0;
this.onNumeric = (editFlags & SpellCheckHelper.NUMERIC) !== 0;
this.onEditableArea = (editFlags & SpellCheckHelper.EDITABLE) !== 0;
this.onPassword = (editFlags & SpellCheckHelper.PASSWORD) !== 0;
if (this.onEditableArea) {
if (this.isRemote) {
InlineSpellCheckerUI.initFromRemote(gContextMenuContentData.spellInfo);
- }
- else {
+ } else {
InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
}
}
this.onKeywordField = (editFlags & SpellCheckHelper.KEYWORD);
- }
- else if (this.target instanceof HTMLHtmlElement) {
+ } else if (this.target instanceof HTMLHtmlElement) {
var bodyElt = ownerDoc.body;
if (bodyElt) {
let computedURL;
try {
computedURL = this.getComputedURL(bodyElt, "background-image");
this._hasMultipleBGImages = false;
} catch (e) {
this._hasMultipleBGImages = true;
}
if (computedURL) {
this.hasBGImage = true;
this.bgImageURL = makeURLAbsolute(bodyElt.baseURI,
computedURL);
}
}
- }
- else if ((this.target instanceof HTMLEmbedElement ||
+ } else if ((this.target instanceof HTMLEmbedElement ||
this.target instanceof HTMLObjectElement ||
this.target instanceof HTMLAppletElement) &&
this.target.displayedType == HTMLObjectElement.TYPE_NULL &&
this.target.pluginFallbackType == HTMLObjectElement.PLUGIN_CLICK_TO_PLAY) {
this.onCTPPlugin = true;
}
this.canSpellCheck = this._isSpellCheckEnabled(this.target);
- }
- else if (this.target.nodeType == Node.TEXT_NODE) {
+ } else if (this.target.nodeType == Node.TEXT_NODE) {
// For text nodes, look at the parent node to determine the spellcheck attribute.
this.canSpellCheck = this.target.parentNode &&
this._isSpellCheckEnabled(this.target);
}
// Second, bubble out, looking for items of interest that can have childen.
// Always pick the innermost link, background image, etc.
- const XMLNS = "http://www.w3.org/XML/1998/namespace";
var elem = this.target;
while (elem) {
if (elem.nodeType == Node.ELEMENT_NODE) {
// Link?
if (!this.onLink &&
// Be consistent with what hrefAndLinkNodeForClickEvent
// does in browser.js
(isXULTextLinkLabel(elem) ||
@@ -806,18 +795,17 @@ nsContextMenu.prototype = {
this.onSaveableLink = this.isLinkSaveable( this.link );
this.linkHasNoReferrer = BrowserUtils.linkHasNoReferrer(elem);
try {
if (elem.download) {
// Ignore download attribute on cross-origin links
this.principal.checkMayLoad(this.linkURI, false, true);
this.linkDownload = elem.download;
}
- }
- catch (ex) {}
+ } catch (ex) {}
}
// Background image? Don't bother if we've already found a
// background image further down the hierarchy. Otherwise,
// we look for the computed background-image style.
if (!this.hasBGImage &&
!this._hasMultipleBGImages) {
let bgImgUrl;
@@ -868,18 +856,17 @@ nsContextMenu.prototype = {
this.onMathML = false;
this.inFrame = false;
this.inSrcdocFrame = false;
this.hasBGImage = false;
this.isDesignMode = true;
this.onEditableArea = true;
if (this.isRemote) {
InlineSpellCheckerUI.initFromRemote(gContextMenuContentData.spellInfo);
- }
- else {
+ } else {
var targetWin = ownerDoc.defaultView;
var editingSession = targetWin.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIEditingSession);
InlineSpellCheckerUI.init(editingSession.getEditorForWindow(targetWin));
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
}
@@ -887,74 +874,74 @@ nsContextMenu.prototype = {
this.showItem("spell-check-enabled", canSpell);
this.showItem("spell-separator", canSpell);
}
}
function isXULTextLinkLabel(node) {
return node.namespaceURI == xulNS &&
node.tagName == "label" &&
- node.classList.contains('text-link') &&
+ node.classList.contains("text-link") &&
node.href;
}
},
// Returns the computed style attribute for the given element.
- getComputedStyle: function(aElem, aProp) {
+ getComputedStyle(aElem, aProp) {
return aElem.ownerGlobal
.getComputedStyle(aElem).getPropertyValue(aProp);
},
// Returns a "url"-type computed style attribute value, with the url() stripped.
- getComputedURL: function(aElem, aProp) {
+ getComputedURL(aElem, aProp) {
var url = aElem.ownerGlobal.getComputedStyle(aElem)
.getPropertyCSSValue(aProp);
if (url instanceof CSSValueList) {
if (url.length != 1)
throw "found multiple URLs";
url = url[0];
}
return url.primitiveType == CSSPrimitiveValue.CSS_URI ?
url.getStringValue() : null;
},
// Returns true if clicked-on link targets a resource that can be saved.
- isLinkSaveable: function(aLink) {
+ isLinkSaveable(aLink) {
// We don't do the Right Thing for news/snews yet, so turn them off
// until we do.
return this.linkProtocol && !(
- this.linkProtocol == "mailto" ||
+ this.linkProtocol == "mailto" ||
this.linkProtocol == "javascript" ||
- this.linkProtocol == "news" ||
- this.linkProtocol == "snews" );
+ this.linkProtocol == "news" ||
+ this.linkProtocol == "snews");
},
- _isSpellCheckEnabled: function(aNode) {
+ _isSpellCheckEnabled(aNode) {
// We can always force-enable spellchecking on textboxes
if (this.isTargetATextBox(aNode)) {
return true;
}
// We can never spell check something which is not content editable
var editable = aNode.isContentEditable;
if (!editable && aNode.ownerDocument) {
editable = aNode.ownerDocument.designMode == "on";
}
if (!editable) {
return false;
}
// Otherwise make sure that nothing in the parent chain disables spellchecking
return aNode.spellcheck;
},
- _isProprietaryDRM: function() {
+ _isProprietaryDRM() {
return this.target.isEncrypted && this.target.mediaKeys &&
this.target.mediaKeys.keySystem != "org.w3.clearkey";
},
- _openLinkInParameters : function (extra) {
+ _openLinkInParameters(extra) {
let params = { charset: gContextMenuContentData.charSet,
originPrincipal: this.principal,
referrerURI: gContextMenuContentData.documentURIObject,
referrerPolicy: gContextMenuContentData.referrerPolicy,
frameOuterWindowID: gContextMenuContentData.frameOuterWindowID,
noReferrer: this.linkHasNoReferrer };
for (let p in extra) {
params[p] = extra[p];
@@ -971,101 +958,100 @@ nsContextMenu.prototype = {
params.userContextId != gContextMenuContentData.userContextId) {
params.noReferrer = true;
}
return params;
},
// Open linked-to URL in a new window.
- openLink : function () {
+ openLink() {
urlSecurityCheck(this.linkURL, this.principal);
openLinkIn(this.linkURL, "window", this._openLinkInParameters());
},
// Open linked-to URL in a new private window.
- openLinkInPrivateWindow : function () {
+ openLinkInPrivateWindow() {
urlSecurityCheck(this.linkURL, this.principal);
openLinkIn(this.linkURL, "window",
this._openLinkInParameters({ private: true }));
},
// Open linked-to URL in a new tab.
- openLinkInTab: function(event) {
+ openLinkInTab(event) {
urlSecurityCheck(this.linkURL, this.principal);
let referrerURI = gContextMenuContentData.documentURIObject;
// if its parent allows mixed content and the referring URI passes
// a same origin check with the target URI, we can preserve the users
// decision of disabling MCB on a page for it's child tabs.
let persistAllowMixedContentInChildTab = false;
if (gContextMenuContentData.parentAllowsMixedContent) {
const sm = Services.scriptSecurityManager;
try {
let targetURI = this.linkURI;
sm.checkSameOriginURI(referrerURI, targetURI, false);
persistAllowMixedContentInChildTab = true;
- }
- catch (e) { }
+ } catch (e) { }
}
let params = {
allowMixedContent: persistAllowMixedContentInChildTab,
- userContextId: parseInt(event.target.getAttribute('data-usercontextid')),
+ userContextId: parseInt(event.target.getAttribute("data-usercontextid")),
};
openLinkIn(this.linkURL, "tab", this._openLinkInParameters(params));
},
// open URL in current tab
- openLinkInCurrent: function() {
+ openLinkInCurrent() {
urlSecurityCheck(this.linkURL, this.principal);
openLinkIn(this.linkURL, "current", this._openLinkInParameters());
},
// Open frame in a new tab.
- openFrameInTab: function() {
+ openFrameInTab() {
let referrer = gContextMenuContentData.referrer;
openLinkIn(gContextMenuContentData.docLocation, "tab",
{ charset: gContextMenuContentData.charSet,
referrerURI: referrer ? makeURI(referrer) : null });
},
// Reload clicked-in frame.
- reloadFrame: function() {
+ reloadFrame() {
this.browser.messageManager.sendAsyncMessage("ContextMenu:ReloadFrame",
null, { target: this.target });
},
// Open clicked-in frame in its own window.
- openFrame: function() {
+ openFrame() {
let referrer = gContextMenuContentData.referrer;
openLinkIn(gContextMenuContentData.docLocation, "window",
{ charset: gContextMenuContentData.charSet,
referrerURI: referrer ? makeURI(referrer) : null });
},
// Open clicked-in frame in the same window.
- showOnlyThisFrame: function() {
+ showOnlyThisFrame() {
urlSecurityCheck(gContextMenuContentData.docLocation,
this.browser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
let referrer = gContextMenuContentData.referrer;
openUILinkIn(gContextMenuContentData.docLocation, "current",
{ disallowInheritPrincipal: true,
referrerURI: referrer ? makeURI(referrer) : null });
},
- reload: function(event) {
+ reload(event) {
BrowserReloadOrDuplicate(event);
},
// View Partial Source
- viewPartialSource: function(aContext) {
+ viewPartialSource(aContext) {
let inWindow = !Services.prefs.getBoolPref("view_source.tab");
let openSelectionFn = inWindow ? null : function() {
let tabBrowser = gBrowser;
// In the case of popups, we need to find a non-popup browser window.
if (!tabBrowser || !window.toolbar.visible) {
// This returns only non-popup browser windows by default.
let browserWindow = RecentWindow.getMostRecentBrowserWindow();
tabBrowser = browserWindow.gBrowser;
@@ -1077,89 +1063,88 @@ nsContextMenu.prototype = {
return tabBrowser.getBrowserForTab(tab);
}
let target = aContext == "mathml" ? this.target : null;
top.gViewSourceUtils.viewPartialSourceInBrowser(gBrowser.selectedBrowser, target, openSelectionFn);
},
// Open new "view source" window with the frame's URL.
- viewFrameSource: function() {
+ viewFrameSource() {
BrowserViewSourceOfDocument({
browser: this.browser,
URL: gContextMenuContentData.docLocation,
outerWindowID: this.frameOuterWindowID,
});
},
- viewInfo: function() {
+ viewInfo() {
BrowserPageInfo(gContextMenuContentData.docLocation, null, null, null, this.browser);
},
- viewImageInfo: function() {
+ viewImageInfo() {
BrowserPageInfo(gContextMenuContentData.docLocation, "mediaTab",
this.target, null, this.browser);
},
- viewImageDesc: function(e) {
+ viewImageDesc(e) {
urlSecurityCheck(this.imageDescURL,
this.browser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
openUILink(this.imageDescURL, e, { disallowInheritPrincipal: true,
referrerURI: gContextMenuContentData.documentURIObject });
},
- viewFrameInfo: function() {
+ viewFrameInfo() {
BrowserPageInfo(gContextMenuContentData.docLocation, null, null,
this.frameOuterWindowID, this.browser);
},
- reloadImage: function() {
+ reloadImage() {
urlSecurityCheck(this.mediaURL,
this.browser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
this.browser.messageManager.sendAsyncMessage("ContextMenu:ReloadImage",
null, { target: this.target });
},
- _canvasToBlobURL: function(target) {
+ _canvasToBlobURL(target) {
let mm = this.browser.messageManager;
return new Promise(function(resolve) {
mm.sendAsyncMessage("ContextMenu:Canvas:ToBlobURL", {}, { target });
let onMessage = (message) => {
mm.removeMessageListener("ContextMenu:Canvas:ToBlobURL:Result", onMessage);
resolve(message.data.blobURL);
};
mm.addMessageListener("ContextMenu:Canvas:ToBlobURL:Result", onMessage);
});
},
// Change current window to the URL of the image, video, or audio.
- viewMedia: function(e) {
+ viewMedia(e) {
let referrerURI = gContextMenuContentData.documentURIObject;
let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
if (this.onCanvas) {
this._canvasToBlobURL(this.target).then(function(blobURL) {
openUILink(blobURL, e, { disallowInheritPrincipal: true,
- referrerURI: referrerURI,
+ referrerURI,
originPrincipal: systemPrincipal});
}, Cu.reportError);
- }
- else {
+ } else {
urlSecurityCheck(this.mediaURL,
this.browser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
openUILink(this.mediaURL, e, { disallowInheritPrincipal: true,
- referrerURI: referrerURI });
+ referrerURI });
}
},
- saveVideoFrameAsImage: function () {
+ saveVideoFrameAsImage() {
let mm = this.browser.messageManager;
let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
let name = "";
if (this.mediaURL) {
try {
let uri = makeURI(this.mediaURL);
let url = uri.QueryInterface(Ci.nsIURL);
@@ -1179,84 +1164,83 @@ nsContextMenu.prototype = {
let dataURL = message.data.dataURL;
saveImageURL(dataURL, name, "SaveImageTitle", true, false,
document.documentURIObject, null, null, null,
isPrivate);
};
mm.addMessageListener("ContextMenu:SaveVideoFrameAsImage:Result", onMessage);
},
- leaveDOMFullScreen: function() {
+ leaveDOMFullScreen() {
document.exitFullscreen();
},
// Change current window to the URL of the background image.
- viewBGImage: function(e) {
+ viewBGImage(e) {
urlSecurityCheck(this.bgImageURL,
this.browser.contentPrincipal,
Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT);
openUILink(this.bgImageURL, e, { disallowInheritPrincipal: true,
referrerURI: gContextMenuContentData.documentURIObject });
},
- setDesktopBackground: function() {
+ setDesktopBackground() {
let mm = this.browser.messageManager;
mm.sendAsyncMessage("ContextMenu:SetAsDesktopBackground", null,
{ target: this.target });
let onMessage = (message) => {
mm.removeMessageListener("ContextMenu:SetAsDesktopBackground:Result",
onMessage);
if (message.data.disable)
return;
- let image = document.createElementNS('http://www.w3.org/1999/xhtml', 'img');
+ let image = document.createElementNS("http://www.w3.org/1999/xhtml", "img");
image.src = message.data.dataUrl;
// Confirm since it's annoying if you hit this accidentally.
const kDesktopBackgroundURL =
"chrome://browser/content/setDesktopBackground.xul";
if (AppConstants.platform == "macosx") {
// On Mac, the Set Desktop Background window is not modal.
// Don't open more than one Set Desktop Background window.
const wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
let dbWin = wm.getMostRecentWindow("Shell:SetDesktopBackground");
if (dbWin) {
dbWin.gSetBackground.init(image);
dbWin.focus();
- }
- else {
+ } else {
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog=no,dependent,resizable=no",
image);
}
} else {
// On non-Mac platforms, the Set Wallpaper dialog is modal.
openDialog(kDesktopBackgroundURL, "",
"centerscreen,chrome,dialog,modal,dependent",
image);
}
};
mm.addMessageListener("ContextMenu:SetAsDesktopBackground:Result", onMessage);
},
// Save URL of clicked-on frame.
- saveFrame: function () {
+ saveFrame() {
saveBrowser(this.browser, false, this.frameOuterWindowID);
},
// Helper function to wait for appropriate MIME-type headers and
// then prompt the user with a file picker
- saveHelper: function(linkURL, linkText, dialogTitle, bypassCache, doc, docURI,
- windowID, linkDownload) {
+ saveHelper(linkURL, linkText, dialogTitle, bypassCache, doc, docURI,
+ windowID, linkDownload) {
// canonical def in nsURILoader.h
const NS_ERROR_SAVE_LINK_AS_TIMEOUT = 0x805d0020;
// an object to proxy the data through to
// nsIExternalHelperAppService.doContent, which will wait for the
// appropriate MIME-type headers and then prompt the user with a
// file picker
function saveAsListener() {}
@@ -1342,17 +1326,16 @@ nsContextMenu.prototype = {
// if it we don't have the headers after a short time, the user
// won't have received any feedback from their click. that's bad. so
// we give up waiting for the filename.
function timerCallback() {}
timerCallback.prototype = {
notify: function sLA_timer_notify(aTimer) {
channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT);
- return;
}
}
// setting up a new channel for 'right click - save link as ...'
// ideally we should use:
// * doc - as the loadingNode, and/or
// * this.principal - as the loadingPrincipal
// for now lets use systemPrincipal to bypass mixedContentBlocker
@@ -1393,96 +1376,94 @@ nsContextMenu.prototype = {
timer.initWithCallback(new timerCallback(), timeToWait,
timer.TYPE_ONE_SHOT);
// kick off the channel with our proxy object as the listener
channel.asyncOpen2(new saveAsListener());
},
// Save URL of clicked-on link.
- saveLink: function() {
+ saveLink() {
urlSecurityCheck(this.linkURL, this.principal);
this.saveHelper(this.linkURL, this.linkTextStr, null, true, this.ownerDoc,
gContextMenuContentData.documentURIObject,
this.frameOuterWindowID,
this.linkDownload);
},
// Backwards-compatibility wrapper
- saveImage : function() {
+ saveImage() {
if (this.onCanvas || this.onImage)
this.saveMedia();
},
// Save URL of the clicked upon image, video, or audio.
- saveMedia: function() {
+ saveMedia() {
let doc = this.ownerDoc;
let referrerURI = gContextMenuContentData.documentURIObject;
let isPrivate = PrivateBrowsingUtils.isBrowserPrivate(this.browser);
if (this.onCanvas) {
// Bypass cache, since it's a data: URL.
this._canvasToBlobURL(this.target).then(function(blobURL) {
saveImageURL(blobURL, "canvas.png", "SaveImageTitle",
true, false, referrerURI, null, null, null,
isPrivate);
}, Cu.reportError);
- }
- else if (this.onImage) {
+ } else if (this.onImage) {
urlSecurityCheck(this.mediaURL, this.principal);
saveImageURL(this.mediaURL, null, "SaveImageTitle", false,
false, referrerURI, null, gContextMenuContentData.contentType,
gContextMenuContentData.contentDisposition, isPrivate);
- }
- else if (this.onVideo || this.onAudio) {
+ } else if (this.onVideo || this.onAudio) {
urlSecurityCheck(this.mediaURL, this.principal);
var dialogTitle = this.onVideo ? "SaveVideoTitle" : "SaveAudioTitle";
this.saveHelper(this.mediaURL, null, dialogTitle, false, doc, referrerURI,
this.frameOuterWindowID, "");
}
},
// Backwards-compatibility wrapper
- sendImage : function() {
+ sendImage() {
if (this.onCanvas || this.onImage)
this.sendMedia();
},
- sendMedia: function() {
+ sendMedia() {
MailIntegration.sendMessage(this.mediaURL, "");
},
- castVideo: function() {
+ castVideo() {
CastingApps.openExternal(this.target, window);
},
- populateCastVideoMenu: function(popup) {
+ populateCastVideoMenu(popup) {
let videoEl = this.target;
popup.innerHTML = null;
let doc = popup.ownerDocument;
let services = CastingApps.getServicesForVideo(videoEl);
services.forEach(service => {
let item = doc.createElement("menuitem");
item.setAttribute("label", service.friendlyName);
item.addEventListener("command", event => {
CastingApps.sendVideoToService(videoEl, service);
});
popup.appendChild(item);
});
},
- playPlugin: function() {
+ playPlugin() {
gPluginHandler.contextMenuCommand(this.browser, this.target, "play");
},
- hidePlugin: function() {
+ hidePlugin() {
gPluginHandler.contextMenuCommand(this.browser, this.target, "hide");
},
// Generate email address and put it on clipboard.
- copyEmail: function() {
+ copyEmail() {
// Copy the comma-separated list of email addresses only.
// There are other ways of embedding email addresses in a mailto:
// link, but such complex parsing is beyond us.
var url = this.linkURL;
var qmark = url.indexOf("?");
var addresses;
// 7 == length of "mailto:"
@@ -1490,207 +1471,202 @@ nsContextMenu.prototype = {
// Let's try to unescape it using a character set
// in case the address is not ASCII.
try {
const textToSubURI = Cc["@mozilla.org/intl/texttosuburi;1"].
getService(Ci.nsITextToSubURI);
addresses = textToSubURI.unEscapeURIForUI(gContextMenuContentData.charSet,
addresses);
- }
- catch(ex) {
+ } catch (ex) {
// Do nothing.
}
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(addresses);
},
- copyLink: function() {
+ copyLink() {
// If we're in a view source tab, remove the view-source: prefix
let linkURL = this.linkURL.replace(/^view-source:/, "");
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(linkURL);
},
- ///////////////
- // Utilities //
- ///////////////
+ /**
+ * Utilities
+ */
/**
* Show/hide one item (specified via name or the item element itself).
* If the element is not found, then this function finishes silently.
*
* @param {Element|String} aItemOrId The item element or the name of the element
* to show.
* @param {Boolean} aShow Set to true to show the item, false to hide it.
*/
- showItem: function(aItemOrId, aShow) {
+ showItem(aItemOrId, aShow) {
var item = aItemOrId.constructor == String ?
document.getElementById(aItemOrId) : aItemOrId;
if (item)
item.hidden = !aShow;
},
// Set given attribute of specified context-menu item. If the
// value is null, then it removes the attribute (which works
// nicely for the disabled attribute).
- setItemAttr: function(aID, aAttr, aVal ) {
+ setItemAttr(aID, aAttr, aVal ) {
var elem = document.getElementById(aID);
if (elem) {
if (aVal == null) {
// null indicates attr should be removed.
elem.removeAttribute(aAttr);
- }
- else {
+ } else {
// Set attr=val.
elem.setAttribute(aAttr, aVal);
}
}
},
// Set context menu attribute according to like attribute of another node
// (such as a broadcaster).
- setItemAttrFromNode: function(aItem_id, aAttr, aOther_id) {
+ setItemAttrFromNode(aItem_id, aAttr, aOther_id) {
var elem = document.getElementById(aOther_id);
if (elem && elem.getAttribute(aAttr) == "true")
this.setItemAttr(aItem_id, aAttr, "true");
else
this.setItemAttr(aItem_id, aAttr, null);
},
// Temporary workaround for DOM api not yet implemented by XUL nodes.
- cloneNode: function(aItem) {
+ cloneNode(aItem) {
// Create another element like the one we're cloning.
var node = document.createElement(aItem.tagName);
// Copy attributes from argument item to the new one.
var attrs = aItem.attributes;
for (var i = 0; i < attrs.length; i++) {
var attr = attrs.item(i);
node.setAttribute(attr.nodeName, attr.nodeValue);
}
// Voila!
return node;
},
// Generate fully qualified URL for clicked-on link.
- getLinkURL: function() {
+ getLinkURL() {
var href = this.link.href;
if (href)
return href;
href = this.link.getAttribute("href") ||
this.link.getAttributeNS("http://www.w3.org/1999/xlink", "href");
if (!href || !href.match(/\S/)) {
// Without this we try to save as the current doc,
// for example, HTML case also throws if empty
throw "Empty href";
}
return makeURLAbsolute(this.link.baseURI, href);
},
- getLinkURI: function() {
+ getLinkURI() {
try {
return makeURI(this.linkURL);
- }
- catch (ex) {
+ } catch (ex) {
// e.g. empty URL string
}
return null;
},
- getLinkProtocol: function() {
+ getLinkProtocol() {
if (this.linkURI)
return this.linkURI.scheme; // can be |undefined|
return null;
},
// Get text of link.
- getLinkText: function() {
+ getLinkText() {
var text = gatherTextUnder(this.link);
if (!text || !text.match(/\S/)) {
text = this.link.getAttribute("title");
if (!text || !text.match(/\S/)) {
text = this.link.getAttribute("alt");
if (!text || !text.match(/\S/))
text = this.linkURL;
}
}
return text;
},
// Kept for addon compat
- linkText: function() {
+ linkText() {
return this.linkTextStr;
},
- isMediaURLReusable: function(aURL) {
+ isMediaURLReusable(aURL) {
if (aURL.startsWith("blob:")) {
return URL.isValidURL(aURL);
}
return true;
},
- toString: function () {
+ toString() {
return "contextMenu.target = " + this.target + "\n" +
"contextMenu.onImage = " + this.onImage + "\n" +
"contextMenu.onLink = " + this.onLink + "\n" +
"contextMenu.link = " + this.link + "\n" +
"contextMenu.inFrame = " + this.inFrame + "\n" +
"contextMenu.hasBGImage = " + this.hasBGImage + "\n";
},
- isTargetATextBox: function(node) {
+ isTargetATextBox(node) {
if (node instanceof HTMLInputElement)
return node.mozIsTextField(false);
return (node instanceof HTMLTextAreaElement);
},
// Determines whether or not the separator with the specified ID should be
// shown or not by determining if there are any non-hidden items between it
// and the previous separator.
- shouldShowSeparator: function (aSeparatorID) {
+ shouldShowSeparator(aSeparatorID) {
var separator = document.getElementById(aSeparatorID);
if (separator) {
var sibling = separator.previousSibling;
while (sibling && sibling.localName != "menuseparator") {
if (!sibling.hidden)
return true;
sibling = sibling.previousSibling;
}
}
return false;
},
- addDictionaries: function() {
+ addDictionaries() {
var uri = formatURL("browser.dictionaries.download.url", true);
var locale = "-";
try {
locale = gPrefService.getComplexValue("intl.accept_languages",
Ci.nsIPrefLocalizedString).data;
- }
- catch (e) { }
+ } catch (e) { }
var version = "-";
try {
version = Cc["@mozilla.org/xre/app-info;1"].
getService(Ci.nsIXULAppInfo).version;
- }
- catch (e) { }
+ } catch (e) { }
uri = uri.replace(/%LOCALE%/, escape(locale)).replace(/%VERSION%/, version);
var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
var where = newWindowPref == 3 ? "tab" : "window";
openUILinkIn(uri, where);
},
@@ -1745,35 +1721,35 @@ nsContextMenu.prototype = {
printFrame: function CM_printFrame() {
PrintUtils.printWindow(this.frameOuterWindowID, this.browser);
},
switchPageDirection: function CM_switchPageDirection() {
this.browser.messageManager.sendAsyncMessage("SwitchDocumentDirection");
},
- mediaCommand : function CM_mediaCommand(command, data) {
+ mediaCommand: function CM_mediaCommand(command, data) {
let mm = this.browser.messageManager;
let win = this.browser.ownerGlobal;
let windowUtils = win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
mm.sendAsyncMessage("ContextMenu:MediaCommand",
- {command: command,
- data: data,
+ {command,
+ data,
handlingUserInput: windowUtils.isHandlingUserInput},
{element: this.target});
},
- copyMediaLocation : function () {
+ copyMediaLocation() {
var clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].
getService(Ci.nsIClipboardHelper);
clipboard.copyString(this.mediaURL);
},
- drmLearnMore: function(aEvent) {
+ drmLearnMore(aEvent) {
let drmInfoURL = Services.urlFormatter.formatURLPref("app.support.baseURL") + "drm-content";
let dest = whereToOpenLink(aEvent);
// Don't ever want this to open in the same tab as it'll unload the
// DRM'd video, which is going to be a bad idea in most cases.
if (dest == "current") {
dest = "tab";
}
openUILinkIn(drmInfoURL, dest);
@@ -1781,44 +1757,44 @@ nsContextMenu.prototype = {
get imageURL() {
if (this.onImage)
return this.mediaURL;
return "";
},
// Formats the 'Search <engine> for "<selection or link text>"' context menu.
- formatSearchContextItem: function() {
+ formatSearchContextItem() {
var menuItem = document.getElementById("context-searchselect");
let selectedText = this.isTextSelected ? this.textSelected : this.linkTextStr;
// Store searchTerms in context menu item so we know what to search onclick
menuItem.searchTerms = selectedText;
// Copied to alert.js' prefillAlertInfo().
// If the JS character after our truncation point is a trail surrogate,
// include it in the truncated string to avoid splitting a surrogate pair.
if (selectedText.length > 15) {
let truncLength = 15;
let truncChar = selectedText[15].charCodeAt(0);
if (truncChar >= 0xDC00 && truncChar <= 0xDFFF)
truncLength++;
- selectedText = selectedText.substr(0,truncLength) + this.ellipsis;
+ selectedText = selectedText.substr(0, truncLength) + this.ellipsis;
}
// format "Search <engine> for <selection>" string to show in menu
let engineName = Services.search.currentEngine.name;
var menuLabel = gNavigatorBundle.getFormattedString("contextMenuSearch",
[engineName,
selectedText]);
menuItem.label = menuLabel;
menuItem.accessKey = gNavigatorBundle.getString("contextMenuSearch.accesskey");
},
- _getTelemetryClickInfo: function(aXulMenu) {
+ _getTelemetryClickInfo(aXulMenu) {
this._onPopupHiding = () => {
aXulMenu.ownerDocument.removeEventListener("command", activationHandler, true);
aXulMenu.removeEventListener("popuphiding", this._onPopupHiding, true);
delete this._onPopupHiding;
let eventKey = [
this._telemetryPageContext,
this._telemetryHadCustomItems ? "withcustom" : "withoutcustom"
@@ -1844,38 +1820,38 @@ nsContextMenu.prototype = {
} else {
this._telemetryClickID = (e.target.id || "unknown").replace(/^context-/i, "");
}
};
aXulMenu.ownerDocument.addEventListener("command", activationHandler, true);
aXulMenu.addEventListener("popuphiding", this._onPopupHiding, true);
},
- _getTelemetryPageContextInfo: function() {
+ _getTelemetryPageContextInfo() {
let rv = [];
for (let k of ["isContentSelected", "onLink", "onImage", "onCanvas", "onVideo", "onAudio",
"onTextInput", "onSocial"]) {
if (this[k]) {
rv.push(k.replace(/^(?:is|on)(.)/, (match, firstLetter) => firstLetter.toLowerCase()));
}
}
if (!rv.length) {
- rv.push('other');
+ rv.push("other");
}
return JSON.stringify(rv);
},
- _checkTelemetryForMenu: function(aXulMenu) {
+ _checkTelemetryForMenu(aXulMenu) {
this._telemetryClickID = null;
this._telemetryPageContext = this._getTelemetryPageContextInfo();
this._telemetryHadCustomItems = this.hasPageMenu;
this._getTelemetryClickInfo(aXulMenu);
},
- createContainerMenu: function(aEvent) {
+ createContainerMenu(aEvent) {
let createMenuOptions = {
isContextMenu: true,
excludeUserContextId: gContextMenuContentData.userContextId,
};
return createUserContextMenu(aEvent, createMenuOptions);
},
};