Backed out 3 changesets (bug 1317322)
authorWes Kocher <wkocher@mozilla.com>
Wed, 01 Mar 2017 15:38:02 -0800
changeset 394517 d64711bdb426e8dda8a2a0f54f17e410290c451e
parent 394516 42ddfa8072f309be87065547b6525c515fd14e30
child 394518 413a21e421dbeb4be715a5cd28967719ba5bd886
push id1468
push userasasaki@mozilla.com
push dateMon, 05 Jun 2017 19:31:07 +0000
treeherdermozilla-release@0641fc6ee9d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1317322
milestone54.0a1
backs outee9b08930b6563a28f621f6220cd2e4bb60f83dd
1eb8e1322979bdd375acaa3b8b6ecb257c0729ab
39cba44c517d9a4060215449ddab6956c7abfe86
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 3 changesets (bug 1317322) Backed out changeset ee9b08930b65 (bug 1317322) Backed out changeset 1eb8e1322979 (bug 1317322) Backed out changeset 39cba44c517d (bug 1317322) MozReview-Commit-ID: 3uruqVonhEG
devtools/client/framework/test/browser_toolbox_textbox_context_menu.js
devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/TextEditorDataTransfer.cpp
editor/libeditor/tests/chrome.ini
editor/libeditor/tests/mochitest.ini
editor/libeditor/tests/test_pasteImgTextarea.html
editor/libeditor/tests/test_pasteImgTextarea.xul
widget/windows/nsClipboard.cpp
widget/windows/nsDataObj.cpp
widget/windows/nsDataObj.h
--- a/devtools/client/framework/test/browser_toolbox_textbox_context_menu.js
+++ b/devtools/client/framework/test/browser_toolbox_textbox_context_menu.js
@@ -31,21 +31,25 @@ add_task(function* () {
   let onContextMenuPopup = once(textboxContextMenu, "popupshowing");
   textboxContextMenu.openPopupAtScreen(0, 0, true);
   yield onContextMenuPopup;
 
   is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
   is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
   is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
 
-  // Cut/Copy/Paste items are enabled in context menu even if there
-  // is no selection. See also Bug 1303033, and 1317322
+  // Cut/Copy items are enabled in context menu even if there
+  // is no selection. See also Bug 1303033
   is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
   is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
-  is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+
+  if (isWindows()) {
+    // emptyClipboard only works on Windows (666254), assert paste only for this OS.
+    is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
+  }
 
   yield cleanup(toolbox);
 });
 
 function* cleanup(toolbox) {
   yield toolbox.destroy();
   gBrowser.removeCurrentTab();
 }
--- a/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
+++ b/devtools/client/inspector/computed/test/browser_computed_search-filter_context-menu.js
@@ -40,21 +40,25 @@ add_task(function* () {
   EventUtils.synthesizeMouse(searchField, 2, 2,
     {type: "contextmenu", button: 2}, win);
   yield onContextMenuPopup;
 
   is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
   is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
   is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
 
-  // Cut/Copy/Paste items are enabled in context menu even if there is no
-  // selection. See also Bug 1303033, and 1317322
+  // Cut/Copy items are enabled in context menu even if there
+  // is no selection. See also Bug 1303033
   is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
   is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
-  is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+
+  if (isWindows()) {
+    // emptyClipboard only works on Windows (666254), assert paste only for this OS.
+    is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
+  }
 
   info("Closing context menu");
   let onContextMenuHidden = once(searchContextMenu, "popuphidden");
   searchContextMenu.hidePopup();
   yield onContextMenuHidden;
 
   info("Copy text in search field using the context menu");
   searchField.value = TEST_INPUT;
--- a/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
+++ b/devtools/client/inspector/rules/test/browser_rules_search-filter_context-menu.js
@@ -39,21 +39,25 @@ add_task(function* () {
   EventUtils.synthesizeMouse(searchField, 2, 2,
     {type: "contextmenu", button: 2}, win);
   yield onContextMenuPopup;
 
   is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
   is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
   is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
 
-  // Cut/Copy/Paste items are enabled in context menu even if there is no
-  // selection. See also Bug 1303033, and 1317322
+  // Cut/Copy items are enabled in context menu even if there
+  // is no selection. See also Bug 1303033
   is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
   is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
-  is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+
+  if (isWindows()) {
+    // emptyClipboard only works on Windows (666254), assert paste only for this OS.
+    is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
+  }
 
   info("Closing context menu");
   let onContextMenuHidden = once(searchContextMenu, "popuphidden");
   searchContextMenu.hidePopup();
   yield onContextMenuHidden;
 
   info("Copy text in search field using the context menu");
   searchField.value = TEST_INPUT;
--- a/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
+++ b/devtools/client/inspector/test/browser_inspector_search-filter_context-menu.js
@@ -38,20 +38,24 @@ add_task(function* () {
     {type: "contextmenu", button: 2}, win);
   yield onContextMenuPopup;
 
   is(cmdUndo.getAttribute("disabled"), "true", "cmdUndo is disabled");
   is(cmdDelete.getAttribute("disabled"), "true", "cmdDelete is disabled");
   is(cmdSelectAll.getAttribute("disabled"), "true", "cmdSelectAll is disabled");
 
   // Cut/Copy items are enabled in context menu even if there
-  // is no selection. See also Bug 1303033, and 1317322
+  // is no selection. See also Bug 1303033
   is(cmdCut.getAttribute("disabled"), "", "cmdCut is enabled");
   is(cmdCopy.getAttribute("disabled"), "", "cmdCopy is enabled");
-  is(cmdPaste.getAttribute("disabled"), "", "cmdPaste is enabled");
+
+  if (isWindows()) {
+    // emptyClipboard only works on Windows (666254), assert paste only for this OS.
+    is(cmdPaste.getAttribute("disabled"), "true", "cmdPaste is disabled");
+  }
 
   info("Closing context menu");
   let onContextMenuHidden = once(searchContextMenu, "popuphidden");
   searchContextMenu.hidePopup();
   yield onContextMenuHidden;
 
   info("Copy text in search field using the context menu");
   searchBox.value = TEST_INPUT;
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -1533,23 +1533,16 @@ static const char* textHtmlEditorFlavors
 
 NS_IMETHODIMP
 HTMLEditor::CanPaste(int32_t aSelectionType,
                      bool* aCanPaste)
 {
   NS_ENSURE_ARG_POINTER(aCanPaste);
   *aCanPaste = false;
 
-  // Always enable the paste command when inside of a HTML or XHTML document.
-  nsCOMPtr<nsIDocument> doc = GetDocument();
-  if (doc && doc->IsHTMLOrXHTML()) {
-    *aCanPaste = true;
-    return NS_OK;
-  }
-
   // can't paste if readonly
   if (!IsModifiable()) {
     return NS_OK;
   }
 
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/libeditor/TextEditorDataTransfer.cpp
+++ b/editor/libeditor/TextEditorDataTransfer.cpp
@@ -377,23 +377,16 @@ TextEditor::PasteTransferable(nsITransfe
 
 NS_IMETHODIMP
 TextEditor::CanPaste(int32_t aSelectionType,
                      bool* aCanPaste)
 {
   NS_ENSURE_ARG_POINTER(aCanPaste);
   *aCanPaste = false;
 
-  // Always enable the paste command when inside of a HTML or XHTML document.
-  nsCOMPtr<nsIDocument> doc = GetDocument();
-  if (doc && doc->IsHTMLOrXHTML()) {
-    *aCanPaste = true;
-    return NS_OK;
-  }
-
   // can't paste if readonly
   if (!IsModifiable()) {
     return NS_OK;
   }
 
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
--- a/editor/libeditor/tests/chrome.ini
+++ b/editor/libeditor/tests/chrome.ini
@@ -6,9 +6,8 @@ support-files = green.png
 [test_bug599983.xul]
 [test_bug607584.xul]
 [test_bug616590.xul]
 [test_bug780908.xul]
 [test_contenteditable_text_input_handling.html]
 [test_htmleditor_keyevent_handling.html]
 [test_texteditor_keyevent_handling.html]
 skip-if = (debug && os=='win') || (os == 'linux') # Bug 1116205, leaks on windows debug, fails delete key on linux
-[test_pasteImgTextarea.xul]
--- a/editor/libeditor/tests/mochitest.ini
+++ b/editor/libeditor/tests/mochitest.ini
@@ -246,10 +246,8 @@ skip-if = os == 'android'
 [test_root_element_replacement.html]
 [test_select_all_without_body.html]
 [test_spellcheck_pref.html]
 skip-if = toolkit == 'android'
 [test_backspace_vs.html]
 [test_css_chrome_load_access.html]
 skip-if = toolkit == 'android' # chrome urls not available due to packaging
 [test_selection_move_commands.html]
-[test_pasteImgTextarea.html]
-skip-if = toolkit == 'android' # bug 1299578
deleted file mode 100644
--- a/editor/libeditor/tests/test_pasteImgTextarea.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!doctype html>
-<script src="/tests/SimpleTest/SimpleTest.js"></script>
-<script src="/tests/SimpleTest/SpawnTask.js"></script>
-<img id="i" src="green.png">
-<textarea id="t"></textarea>
-
-<script>
-let loaded = new Promise(resolve => addLoadEvent(resolve));
-    add_task(function*() {
-        yield loaded;
-        SpecialPowers.setCommandNode(window, document.getElementById("i"));
-        SpecialPowers.doCommand(window, "cmd_copyImageContents");
-        let input = document.getElementById("t");
-        input.focus();
-        var controller =
-          SpecialPowers.wrap(input).controllers.getControllerForCommand("cmd_paste");
-        is(controller.isCommandEnabled("cmd_paste"), true,
-           "paste should be enabled in html textareas when an image is on the clipboard");
-    });
-</script>
deleted file mode 100644
--- a/editor/libeditor/tests/test_pasteImgTextarea.xul
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window xmlns:html="http://www.w3.org/1999/xhtml"
-        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-  <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml">
-    <html:img id="i" src="green.png" />
-    <html:textarea id="t"></html:textarea>
-  </body>
-  <script type="text/javascript"><![CDATA[
-    let loaded = new Promise(resolve => addLoadEvent(resolve));
-    add_task(function*() {
-        yield loaded;
-        SpecialPowers.setCommandNode(window, document.getElementById("i"));
-        SpecialPowers.doCommand(window, "cmd_copyImageContents");
-        let input = document.getElementById("t");
-        input.focus();
-        var controller =
-          SpecialPowers.wrap(input).controllers.getControllerForCommand("cmd_paste");
-        is(controller.isCommandEnabled("cmd_paste"), false,
-           "paste should not be enabled in xul textareas when an image is on the clipboard");
-    });
-  ]]></script>
-</window>
--- a/widget/windows/nsClipboard.cpp
+++ b/widget/windows/nsClipboard.cpp
@@ -60,17 +60,17 @@ nsClipboard::nsClipboard() : nsBaseClipb
   mIgnoreEmptyNotification = false;
   mWindow         = nullptr;
 
   // Register for a shutdown notification so that we can flush data
  // to the OS clipboard.
   nsCOMPtr<nsIObserverService> observerService =
     do_GetService("@mozilla.org/observer-service;1");
   if (observerService) {
-    observerService->AddObserver(this, NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID, PR_FALSE);
+    observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
   }
 }
 
 //-------------------------------------------------------------------------
 // nsClipboard destructor
 //-------------------------------------------------------------------------
 nsClipboard::~nsClipboard()
 {
--- a/widget/windows/nsDataObj.cpp
+++ b/widget/windows/nsDataObj.cpp
@@ -436,111 +436,40 @@ STDMETHODIMP nsDataObj::QueryInterface(R
 //-----------------------------------------------------
 STDMETHODIMP_(ULONG) nsDataObj::AddRef()
 {
 	++m_cRef;
 	NS_LOG_ADDREF(this, m_cRef, "nsDataObj", sizeof(*this));
 	return m_cRef;
 }
 
-namespace {
-class RemoveTempFileHelper : public nsIObserver
-{
-public:
-  explicit RemoveTempFileHelper(nsIFile* aTempFile)
-    : mTempFile(aTempFile)
-  {
-    MOZ_ASSERT(mTempFile);
-  }
-
-  // The attach method is seperate from the constructor as we may be addref-ing
-  // ourself, and we want to be sure someone has a strong reference to us.
-  void Attach()
-  {
-    // We need to listen to both the xpcom shutdown message and our timer, and
-    // fire when the first of either of these two messages is received.
-    nsresult rv;
-    mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
-    if (NS_WARN_IF(NS_FAILED(rv))) {
-      return;
-    }
-    mTimer->Init(this, 500, nsITimer::TYPE_ONE_SHOT);
-
-    nsCOMPtr<nsIObserverService> observerService =
-      do_GetService("@mozilla.org/observer-service;1");
-    if (NS_WARN_IF(!observerService)) {
-      mTimer->Cancel();
-      mTimer = nullptr;
-      return;
-    }
-    observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
-  }
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIOBSERVER
-
-private:
-  ~RemoveTempFileHelper()
-  {
-    if (mTempFile) {
-      mTempFile->Remove(false);
-    }
-  }
-
-  nsCOMPtr<nsIFile> mTempFile;
-  nsCOMPtr<nsITimer> mTimer;
-};
-
-NS_IMPL_ISUPPORTS(RemoveTempFileHelper, nsIObserver);
-
-NS_IMETHODIMP
-RemoveTempFileHelper::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData)
-{
-  // Let's be careful and make sure that we don't die immediately
-  RefPtr<RemoveTempFileHelper> grip = this;
-
-  // Make sure that we aren't called again by destroying references to ourself.
-  nsCOMPtr<nsIObserverService> observerService =
-    do_GetService("@mozilla.org/observer-service;1");
-  if (observerService) {
-    observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
-  }
-
-  if (mTimer) {
-    mTimer->Cancel();
-    mTimer = nullptr;
-  }
-
-  // Remove the tempfile
-  if (mTempFile) {
-    mTempFile->Remove(false);
-    mTempFile = nullptr;
-  }
-  return NS_OK;
-}
-} // namespace
 
 //-----------------------------------------------------
 STDMETHODIMP_(ULONG) nsDataObj::Release()
 {
 	--m_cRef;
 	
 	NS_LOG_RELEASE(this, m_cRef, "nsDataObj");
 	if (0 != m_cRef)
 		return m_cRef;
 
   // We have released our last ref on this object and need to delete the
   // temp file. External app acting as drop target may still need to open the
   // temp file. Addref a timer so it can delay deleting file and destroying
-  // this object.
+  // this object. Delete file anyway and destroy this obj if there's a problem.
   if (mCachedTempFile) {
-    RefPtr<RemoveTempFileHelper> helper =
-      new RemoveTempFileHelper(mCachedTempFile);
+    nsresult rv;
+    mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv);
+    if (NS_SUCCEEDED(rv)) {
+      mTimer->InitWithFuncCallback(nsDataObj::RemoveTempFile, this,
+                                   500, nsITimer::TYPE_ONE_SHOT);
+      return AddRef();
+    }
+    mCachedTempFile->Remove(false);
     mCachedTempFile = nullptr;
-    helper->Attach();
   }
 
 	delete this;
 
 	return 0;
 }
 
 //-----------------------------------------------------
@@ -2217,8 +2146,18 @@ HRESULT nsDataObj::GetFileContents_IStre
   NS_ENSURE_TRUE(pStream, E_FAIL);
 
   aSTG.tymed = TYMED_ISTREAM;
   aSTG.pstm = pStream;
   aSTG.pUnkForRelease = nullptr;
 
   return S_OK;
 }
+
+void nsDataObj::RemoveTempFile(nsITimer* aTimer, void* aClosure)
+{
+  nsDataObj *timedDataObj = static_cast<nsDataObj *>(aClosure);
+  if (timedDataObj->mCachedTempFile) {
+    timedDataObj->mCachedTempFile->Remove(false);
+    timedDataObj->mCachedTempFile = nullptr;
+  }
+  timedDataObj->Release();
+}
--- a/widget/windows/nsDataObj.h
+++ b/widget/windows/nsDataObj.h
@@ -284,12 +284,13 @@ protected:
       STGMEDIUM   stgm;
     } DATAENTRY, *LPDATAENTRY;
 
     nsTArray <LPDATAENTRY> mDataEntryList;
     nsCOMPtr<nsITimer> mTimer;
 
     bool LookupArbitraryFormat(FORMATETC *aFormat, LPDATAENTRY *aDataEntry, BOOL aAddorUpdate);
     bool CopyMediumData(STGMEDIUM *aMediumDst, STGMEDIUM *aMediumSrc, LPFORMATETC aFormat, BOOL aSetData);
+    static void RemoveTempFile(nsITimer* aTimer, void* aClosure);
 };
 
 
 #endif  // _NSDATAOBJ_H_