Bug 1364977 - Do not remove obs_documentCreated observer in its notification processing to avoid a crash. r=IanN a=IanN SEA_COMM510_20170330_RELBRANCH
authorFrank-Rainer Grahl <frgrahl@gmx.net>
Tue, 06 Jun 2017 09:56:20 +0200
branchSEA_COMM510_20170330_RELBRANCH
changeset 31415 f31ed651074b50355fdbc0192dfa8217da997951
parent 31414 c21b30423012fea4ded271ff70db633dbe15a3d4
child 31416 37c3d0aea1854db2d276cd6b3834940bc0dfa26d
push id1
push userclokep@gmail.com
push dateMon, 07 May 2018 22:45:56 +0000
treeherdercomm-esr60@57eacde5ef40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersIanN, IanN
bugs1364977, 468740
Bug 1364977 - Do not remove obs_documentCreated observer in its notification processing to avoid a crash. r=IanN a=IanN Also change attachment handling to avoid hitting bug 468740 when the observer is only removed during close.
suite/mailnews/compose/MsgComposeCommands.js
--- a/suite/mailnews/compose/MsgComposeCommands.js
+++ b/suite/mailnews/compose/MsgComposeCommands.js
@@ -1261,18 +1261,16 @@ var gMsgEditorCreationObserver =
         InitEditor(editor);
       // Now that we know this document is an editor, update commands now if
       // the document has focus, or next time it receives focus via
       // CommandUpdate_MsgCompose()
       if (gLastWindowToHaveFocus == document.commandDispatcher.focusedWindow)
         updateComposeItems();
       else
         gLastWindowToHaveFocus = null;
-
-      commandManager.removeCommandObserver(this, "obs_documentCreated");
     }
   }
 }
 
 function WizCallback(state)
 {
   if (state){
     ComposeStartup(null);
@@ -1335,16 +1333,18 @@ function ComposeLoad()
 }
 
 function ComposeUnload()
 {
   // Send notification that the window is going away completely.
   document.getElementById("msgcomposeWindow").dispatchEvent(
     new Event("compose-window-unload", { bubbles: false, cancelable: false }));
 
+  GetCurrentCommandManager().removeCommandObserver(gMsgEditorCreationObserver,
+                                                   "obs_documentCreated");
   UnloadCommandUpdateHandlers();
 
   // Stop InlineSpellCheckerUI so personal dictionary is saved
   EnableInlineSpellCheck(false);
 
   EditorCleanup();
 
   RemoveMessageComposeOfflineQuitObserver();
@@ -2474,46 +2474,101 @@ function FocusOnFirstAttachment()
 function AttachmentElementHasItems()
 {
   var element = GetMsgAttachmentElement();
   return element ? element.childNodes.length : 0;
 }
 
 function OpenSelectedAttachment()
 {
-  var bucket = GetMsgAttachmentElement();
-  if (bucket.selectedItems.length == 1)
-  {
-    var attachmentUrl = bucket.getSelectedItem(0).attachment.url;
-
-    var messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
-    if (messagePrefix.test(attachmentUrl))
-    {
-      // we must be dealing with a forwarded attachment, treat this specially
-      var msgHdr = gMessenger.msgHdrFromURI(attachmentUrl);
-      if (msgHdr)
-      {
-        var folderUri = msgHdr.folder.folderURL;
-        window.openDialog("chrome://messenger/content/messageWindow.xul", "_blank", "all,chrome,dialog=no,status,toolbar",
-                          attachmentUrl, folderUri, null);
+  let bucket = document.getElementById("attachmentBucket");
+  if (bucket.selectedItems.length == 1) {
+    let attachmentUrl = bucket.getSelectedItem(0).attachment.url;
+
+    let messagePrefix = /^mailbox-message:|^imap-message:|^news-message:/i;
+    if (messagePrefix.test(attachmentUrl)) {
+      // We must be dealing with a forwarded attachment, treat this special.
+      let msgHdr = gMessenger.msgHdrFromURI(attachmentUrl);
+      if (msgHdr) {
+        MailUtils.openMessageInNewWindow(msgHdr);
       }
-    }
-    else
-    {
-      var editorElement = GetCurrentEditorElement();
-      if (editorElement) {
-        const loadFlags = Components.interfaces.nsIWebNavigation.LOAD_FLAGS_IS_LINK;
-        try {
-          editorElement.webNavigation.loadURI(attachmentUrl, loadFlags, null, null, null);
-        } catch (e) {}
+    } else {
+      // Turn the URL into a nsIURI object then open it.
+      let uri = Services.io.newURI(attachmentUrl);
+      if (uri) {
+        let channel = Services.io.newChannelFromURI2(uri,
+                                                     null,
+                                                     Services.scriptSecurityManager.getSystemPrincipal(),
+                                                     null,
+                                                     Components.interfaces.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+                                                     Components.interfaces.nsIContentPolicy.TYPE_OTHER);
+        if (channel) {
+          let uriLoader = Components.classes["@mozilla.org/uriloader;1"].getService(Components.interfaces.nsIURILoader);
+          uriLoader.openURI(channel, true, new nsAttachmentOpener());
+        }
       }
     }
   } // if one attachment selected
 }
 
+function nsAttachmentOpener()
+{
+}
+
+nsAttachmentOpener.prototype =
+{
+  QueryInterface: function(iid)
+  {
+    if (iid.equals(Components.interfaces.nsIURIContentListener) ||
+        iid.equals(Components.interfaces.nsIInterfaceRequestor) ||
+        iid.equals(Components.interfaces.nsISupports)) {
+      return this;
+    }
+    throw Components.results.NS_NOINTERFACE;
+  },
+
+  onStartURIOpen: function(uri)
+  {
+    return false;
+  },
+
+  doContent: function(contentType, isContentPreferred, request, contentHandler)
+  {
+    return false;
+  },
+
+  isPreferred: function(contentType, desiredContentType)
+  {
+    return false;
+  },
+
+  canHandleContent: function(contentType, isContentPreferred, desiredContentType)
+  {
+    return false;
+  },
+
+  getInterface: function(iid)
+  {
+    if (iid.equals(Components.interfaces.nsIDOMWindow)) {
+      return window;
+    }
+
+    if (iid.equals(Components.interfaces.nsIDocShell)) {
+      return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                   .getInterface(Components.interfaces.nsIWebNavigation)
+                   .QueryInterface(Components.interfaces.nsIDocShell);
+    }
+
+    return this.QueryInterface(iid);
+  },
+
+  loadCookie: null,
+  parentContentListener: null
+}
+
 function DetermineHTMLAction(convertible)
 {
   try {
     gMsgCompose.expandMailingLists();
   } catch(ex) {
     dump("gMsgCompose.expandMailingLists failed: " + ex + "\n");
   }