Backed out 3 changesets (bug 1317322)
authorWes Kocher <wkocher@mozilla.com>
Wed, 01 Mar 2017 15:38:02 -0800
changeset 374567 d64711bdb426e8dda8a2a0f54f17e410290c451e
parent 374566 42ddfa8072f309be87065547b6525c515fd14e30
child 374568 413a21e421dbeb4be715a5cd28967719ba5bd886
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1317322
milestone54.0a1
backs outee9b08930b6563a28f621f6220cd2e4bb60f83dd
1eb8e1322979bdd375acaa3b8b6ecb257c0729ab
39cba44c517d9a4060215449ddab6956c7abfe86
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_