diff --git a/mail/base/content/nsContextMenu.js b/mail/base/content/nsContextMenu.js index 275587b7f7..2726b5ed15 100644 --- a/mail/base/content/nsContextMenu.js +++ b/mail/base/content/nsContextMenu.js @@ -478,7 +478,8 @@ class nsContextMenu { this.onCanvas || this.onLink || this.onImage || - this.onPlayableMedia || + this.onAudio || + this.onVideo || this.onTextInput ); // Ensure these commands are updated with their current status. @@ -740,179 +741,6 @@ class nsContextMenu { this.checkLastSeparator(this.xulMenu); } - /* eslint-disable complexity */ - /** - * Set the nsContextMenu properties based on the selected node and - * its ancestors. - */ - setTarget(aNode) { - // Clear any old spellchecking items from the menu, this used to - // be in the menu hiding code but wasn't getting called in all - // situations. Here, we can ensure it gets cleaned up any time the - // menu is shown. Note: must be before uninit because that clears the - // internal vars - // We also need to do that before we possibly bail because we just clicked - // on some XUL node. Otherwise, dictionary choices just accumulate until we - // right-click on some HTML element again. - gSpellChecker.clearSuggestionsFromMenu(); - gSpellChecker.clearDictionaryListFromMenu(); - gSpellChecker.uninit(); - - if ( - aNode.namespaceURI == - "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - ) { - if (aNode.localName == "treecol") { - // The column header was clicked, show the column picker. - let treecols = aNode.parentNode; - let treeColPicker = treecols.querySelector("treecolpicker"); - let popup = treeColPicker.querySelector(`menupopup[anonid="popup"]`); - treeColPicker.buildPopup(popup); - popup.openPopup(aNode, "before_start", 0, 0, true); - this.shouldDisplay = false; - } - return; - } - this.onImage = false; - this.onLoadedImage = false; - this.onMetaDataItem = false; - this.onTextInput = false; - this.onEditable = false; - this.imageURL = ""; - this.onLink = false; - this.onVideo = false; - this.onAudio = false; - this.mediaURL = ""; - this.linkURL = ""; - this.linkURI = null; - this.linkProtocol = null; - this.onMathML = false; - - this.target = aNode; - - // Set up early the right flags for editable / not editable. - let editFlags = SpellCheckHelper.isEditable(this.target, window); - this.onTextInput = (editFlags & SpellCheckHelper.TEXTINPUT) !== 0; - this.onEditable = (editFlags & SpellCheckHelper.EDITABLE) !== 0; - - // First, do checks for nodes that never have children. - if (this.target.nodeType == Node.ELEMENT_NODE) { - if ( - this.target instanceof Ci.nsIImageLoadingContent && - this.target.currentURI - ) { - this.onImage = true; - this.onMetaDataItem = true; - - var request = this.target.getRequest( - Ci.nsIImageLoadingContent.CURRENT_REQUEST - ); - if (request && request.imageStatus & request.STATUS_SIZE_AVAILABLE) { - this.onLoadedImage = true; - } - - this.imageURL = this.target.currentURI.spec; - } else if (this.target instanceof HTMLInputElement) { - this.onTextInput = this.isTargetATextBox(this.target); - } else if ( - editFlags & - (SpellCheckHelper.INPUT | SpellCheckHelper.TEXTAREA) - ) { - if (!this.target.readOnly) { - this.onEditable = true; - gSpellChecker.init(this.target.editor); - gSpellChecker.initFromEvent( - document.popupRangeParent, - document.popupRangeOffset - ); - } - } else if (editFlags & SpellCheckHelper.CONTENTEDITABLE) { - let targetWin = this.target.ownerGlobal; - let editingSession = targetWin - ?.getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIEditingSession); - gSpellChecker.init(editingSession.getEditorForWindow(targetWin)); - gSpellChecker.initFromEvent( - document.popupRangeParent, - document.popupRangeOffset - ); - } else if (this.target instanceof HTMLCanvasElement) { - this.onCanvas = true; - } else if (this.target instanceof HTMLVideoElement) { - this.onVideo = true; - this.onPlayableMedia = true; - this.mediaURL = this.target.currentSrc || this.target.src; - } else if (this.target instanceof HTMLAudioElement) { - this.onAudio = true; - this.onPlayableMedia = true; - this.mediaURL = this.target.currentSrc || this.target.src; - // Browser supports background images here but we don't need to. - } - } - - // Second, bubble out, looking for items of interest that might be - // parents of the click target, picking the innermost of each. - 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 && - ((elem instanceof HTMLAnchorElement && elem.href) || - (elem instanceof HTMLAreaElement && elem.href) || - elem instanceof HTMLLinkElement || - elem.getAttributeNS("http://www.w3.org/1999/xlink", "type") == - "simple") - ) { - // Target is a link or a descendant of a link. - this.onLink = true; - this.onMetaDataItem = true; - // Remember corresponding element. - this.link = elem; - this.linkURL = this.getLinkURL(); - this.linkURI = this.getLinkURI(); - this.linkProtocol = this.getLinkProtocol(); - this.onMailtoLink = this.linkProtocol == "mailto"; - this.onSaveableLink = this.isLinkSaveable(); - } - - // Text input? - if (!this.onTextInput) { - this.onTextInput = this.isTargetATextBox(elem); - } - - // Metadata item? - if (!this.onMetaDataItem) { - if ( - (elem instanceof HTMLQuoteElement && elem.cite) || - (elem instanceof HTMLTableElement && elem.summary) || - (elem instanceof HTMLModElement && (elem.cite || elem.dateTime)) || - (elem instanceof HTMLElement && (elem.title || elem.lang)) || - elem.getAttributeNS(XMLNS, "lang") - ) { - this.onMetaDataItem = true; - } - } - - // Browser supports background images here but we don't need to. - } - elem = elem.parentNode; - } - - // See if the user clicked on MathML. - const NS_MathML = "http://www.w3.org/1998/Math/MathML"; - if ( - (this.target.nodeType == Node.TEXT_NODE && - this.target.parentNode.namespaceURI == NS_MathML) || - this.target.namespaceURI == NS_MathML - ) { - this.onMathML = true; - } - } - /* eslint-enable complexity */ - setMessageTargets() { if (this.browser) { this.inAMessage = ["imap", "mailbox", "news", "snews"].includes( @@ -1003,7 +831,7 @@ class nsContextMenu { */ saveImage() { saveURL( - this.imageURL, + this.imageInfo.currentSrc, null, "SaveImageTitle", false, diff --git a/mail/base/test/browser/browser_mailContext.js b/mail/base/test/browser/browser_mailContext.js index 9ddcf98fbe..7d3af6cfb4 100644 --- a/mail/base/test/browser/browser_mailContext.js +++ b/mail/base/test/browser/browser_mailContext.js @@ -16,9 +16,26 @@ var { MessageGenerator } = ChromeUtils.import( const TEST_DOCUMENT_URL = "http://mochi.test:8888/browser/comm/mail/base/test/browser/files/sampleContent.html"; +const TEST_MESSAGE_URL = + "http://mochi.test:8888/browser/comm/mail/base/test/browser/files/sampleContent.eml"; +const TEST_IMAGE_URL = + "http://mochi.test:8888/browser/comm/mail/base/test/browser/files/tb-logo.png"; let testFolder; +async function getImageArrayBuffer() { + let response = await fetch(TEST_IMAGE_URL); + let blob = await response.blob(); + + return new Promise((resolve, reject) => { + let reader = new FileReader(); + reader.addEventListener("loadend", event => { + resolve(event.target.result); + }); + reader.readAsArrayBuffer(blob); + }); +} + function checkMenuitems(menu, ...expectedItems) { if (expectedItems.length == 0) { // Menu should not be shown. @@ -47,6 +64,8 @@ async function checkABrowser(browser) { let mailContext = browser.ownerDocument.getElementById("mailContext"); + // Just some text. + let shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown"); await BrowserTestUtils.synthesizeMouseAtCenter( "p", @@ -62,6 +81,8 @@ async function checkABrowser(browser) { ); mailContext.hidePopup(); + // A link. + shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown"); await BrowserTestUtils.synthesizeMouseAtCenter( "a", @@ -78,6 +99,8 @@ async function checkABrowser(browser) { ); mailContext.hidePopup(); + // A text input widget. + await BrowserTestUtils.synthesizeMouseAtCenter("input", {}, browser); shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown"); await BrowserTestUtils.synthesizeMouseAtCenter( @@ -96,6 +119,37 @@ async function checkABrowser(browser) { "mailContext-spell-check-enabled" ); mailContext.hidePopup(); + + // An image. Also checks Save Image As works. + + shownPromise = BrowserTestUtils.waitForEvent(mailContext, "popupshown"); + await BrowserTestUtils.synthesizeMouseAtCenter( + "img", + { type: "contextmenu" }, + browser + ); + await shownPromise; + checkMenuitems( + mailContext, + "mailContext-selectall", + "mailContext-copyimage", + "mailContext-saveimage" + ); + + let pickerPromise = new Promise(resolve => { + SpecialPowers.MockFilePicker.init(window); + SpecialPowers.MockFilePicker.showCallback = picker => { + resolve(picker.defaultString); + return Ci.nsIFilePicker.returnCancel; + }; + }); + EventUtils.synthesizeMouseAtCenter( + browser.ownerDocument.getElementById("mailContext-saveimage"), + {}, + browser.ownerGlobal + ); + Assert.equal(await pickerPromise, "tb-logo.png"); + SpecialPowers.MockFilePicker.cleanup(); } add_task(async function testMessagePane() { @@ -107,6 +161,8 @@ add_task(async function testMessagePane() { testFolder = rootFolder .getChildNamed("test") .QueryInterface(Ci.nsIMsgLocalMailFolder); + let message = await fetch(TEST_MESSAGE_URL).then(r => r.text()); + testFolder.addMessageBatch([message]); let messages = new MessageGenerator().makeMessages({ count: 5 }); let messageStrings = messages.map(message => message.toMboxString()); testFolder.addMessageBatch(messageStrings); @@ -279,6 +335,7 @@ add_task(async function testExtensionPopupWindow() { "sampleContent.html": await fetch(TEST_DOCUMENT_URL).then(response => response.text() ), + "tb-logo.png": await getImageArrayBuffer(), }, }); @@ -300,6 +357,7 @@ add_task(async function testExtensionBrowserAction() { "sampleContent.html": await fetch(TEST_DOCUMENT_URL).then(response => response.text() ), + "tb-logo.png": await getImageArrayBuffer(), }, manifest: { applications: { @@ -338,6 +396,7 @@ add_task(async function testExtensionComposeAction() { "sampleContent.html": await fetch(TEST_DOCUMENT_URL).then(response => response.text() ), + "tb-logo.png": await getImageArrayBuffer(), }, manifest: { applications: { @@ -391,6 +450,7 @@ add_task(async function testExtensionMessageDisplayAction() { "sampleContent.html": await fetch(TEST_DOCUMENT_URL).then(response => response.text() ), + "tb-logo.png": await getImageArrayBuffer(), }, manifest: { applications: { diff --git a/mail/base/test/browser/files/sampleContent.eml b/mail/base/test/browser/files/sampleContent.eml new file mode 100644 index 0000000000..89ca45360b --- /dev/null +++ b/mail/base/test/browser/files/sampleContent.eml @@ -0,0 +1,153 @@ +From andy@anway.invalid +Content-Type: multipart/related; + boundary="--------------CHOPCHOP0" +Subject: Big Meeting Today +From: "Andy Anway" +To: "Bob Bell" +Message-Id: <0@made.up.invalid> +Date: Tue, 01 Feb 2000 00:00:00 +1300 + +This is a multi-part message in MIME format. +----------------CHOPCHOP0 +Content-Type: text/html; charset=ISO-8859-1; format=flowed +Content-Transfer-Encoding: 7bit + +

This is a page of sample content for tests.

+

Link to a web page

+
+ +
+

+ + +----------------CHOPCHOP0 +Content-Type: image/png; charset=ISO-8859-1; format=flowed; + name="tb-logo.png" +Content-Transfer-Encoding: base64 +Content-Disposition: attachment; + filename="tb-logo.png" +Content-ID: + +iVBORw0KGgoAAAANSUhEUgAAATAAAABUCAMAAAAyN5s5AAAC91BMVEVMaXErLDVPU1wYFx1O +T1RPT1RNT1MTExoFBwZNTlNOTlNNT1RNTlNMTFRNTlMGBgoDBgYFBQZNTlQGBgdOTlNNTlMA +AwMEBQVNTlNOUFRMTFUAAABNTlMEBgdNT1QFBwoEBAZOTlNNTlMuOoNNTlQACghNTlRNTlNO +T1RNTlMTDytNT1N/qs1NTlMxPolNTlSZydyfmI8pMHosPIYaFSFNTlMdEkRNUFVNTlMrM38U +EBczT5hNTlMtNX8UDy8+XqIqN4AkGmCTiIEwN4JHaKgRCygnLHdzmsNYdq2Fd3N2nMRvlL8g +G00RCi0TCzAsQYsqHGJMbq5pjLsWDj9HYqV/qdh6nsxpYFljhsL////7+PL38+z59u////z8 ++/f8+vT28ufz7+UoG2D+/fnx7ODu6NvRyb3g2c7k39bSzcXr5NbIvq/Z0si9sqLJw7jDuKjb +0cCJhYHOxbbn3s/n5eGjn5mtqKPY1M+0r6rl2MS9ubVwbW54dXZgXl5HREZnZWHHxcJWVlU/ +PjevpJXazbR/fX0cJGV/d29UaaFPTka5rZx0b2P/++T77c9UVEphW01BQFtXTl6QnavN3exg +hcBIa65bgL0rS5dOcbGKt9NKZ6dPdLZdhbk8ZKlDcbNVd7RWe7l0pcszX6c5WpyKvN5EYaI9 +aK8yWaNJdrRff7OBsdc0RZUvUppukr8xN3knRZItLXkoUqFiisUoPIlsnMVpirxKfcdekL+Z +yusoQY4EAQktOIQOBVVWicRBaqgqMmp3msRTgr40VJ1SiLhAbrFwmc1glc5DWaEqMoBRcKtp +kMh0ntRMfrlHdronKVek1vYVCzd/ptg7aaEYGG83UZM6X6JDc6taea1cZXwkIUJDV5kLAyW3 +6P2PwOlhp+A4QIIcDg8+TpYoIXQiFVY0SYuClLAFABlZKzUdFWgyN4zU//82MTUrIGkpHWVO +T1SUjoosIm0eK3oSCS89RYwpGjNNQHREVIaXdlSjqrsmJCHZ+P6hTAAuJnRz9RRfAAAAWXRS +TlMAAw0H2DaeARv9u/JCJ39bSVawUY/kECNSFBsL6jdqQS2nyiBjFnOGWS6XSv75/cP+/Y1X +gpf+INIxbcWMRrneatP7sn305HhA1FEovMfh4/W3xtjNzNPUx47MeaUAABWdSURBVHhe7JTH +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 + +----------------CHOPCHOP0-- + diff --git a/mail/base/test/browser/files/sampleContent.html b/mail/base/test/browser/files/sampleContent.html index 9975a72d5e..ee11d14fdd 100644 --- a/mail/base/test/browser/files/sampleContent.html +++ b/mail/base/test/browser/files/sampleContent.html @@ -10,5 +10,6 @@
+

diff --git a/mail/base/test/browser/files/tb-logo.png b/mail/base/test/browser/files/tb-logo.png new file mode 100644 index 0000000000..aac56e2546 Binary files /dev/null and b/mail/base/test/browser/files/tb-logo.png differ