Bug 1030719 - Properly restore form data for contenteditables r=smacleod a=sylvestre
authorTim Taubert <ttaubert@mozilla.com>
Thu, 26 Jun 2014 15:55:16 +0200
changeset 208552 b435946629a08861721de385f8a3c3ddd72e277a
parent 208551 8e6d0f924669c9d62e468a5c32b41032df93ed24
child 208553 4e32c33cfb9083b25225c2be9c498f4fee68b5e4
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmacleod, sylvestre
bugs1030719
milestone32.0a2
Bug 1030719 - Properly restore form data for contenteditables r=smacleod a=sylvestre
browser/components/sessionstore/test/browser_formdata.js
toolkit/modules/sessionstore/FormData.jsm
--- a/browser/components/sessionstore/test/browser_formdata.js
+++ b/browser/components/sessionstore/test/browser_formdata.js
@@ -199,27 +199,39 @@ add_task(function test_design_mode() {
   // Load a tab with an editable document.
   let tab = gBrowser.selectedTab = gBrowser.addTab(URL);
   let browser = tab.linkedBrowser;
   yield promiseBrowserLoaded(browser);
 
   // Modify the document content.
   yield sendMessage(browser, "ss-test:sendKeyEvent", {key: "m"});
 
-  // Duplicate the modified tab.
-  let tab2 = gBrowser.duplicateTab(tab);
-  yield promiseTabRestored(tab2);
+  // Close and restore the tab.
+  gBrowser.removeTab(tab);
+  tab = ss.undoCloseTab(window, 0);
+  browser = tab.linkedBrowser;
+  yield promiseTabRestored(tab);
+
+  // Check that the innerHTML value was restored.
+  let html = yield getInnerHTML(browser);
+  let expected = "<h1>Mmozilla</h1><script>document.designMode='on'</script>";
+  is(html, expected, "editable document has been restored correctly");
+
+  // Close and restore the tab.
+  gBrowser.removeTab(tab);
+  tab = ss.undoCloseTab(window, 0);
+  browser = tab.linkedBrowser;
+  yield promiseTabRestored(tab);
 
   // Check that the innerHTML value was restored.
   let html = yield getInnerHTML(browser);
   let expected = "<h1>Mmozilla</h1><script>document.designMode='on'</script>";
   is(html, expected, "editable document has been restored correctly");
 
   // Cleanup.
-  gBrowser.removeTab(tab2);
   gBrowser.removeTab(tab);
 });
 
 function getInputValue(browser, id) {
   return sendMessage(browser, "ss-test:getInputValue", {id: id});
 }
 
 function setInputValue(browser, data) {
--- a/toolkit/modules/sessionstore/FormData.jsm
+++ b/toolkit/modules/sessionstore/FormData.jsm
@@ -221,16 +221,17 @@ let FormDataInternal = {
       // We know that the URL matches data.url right now, but the user
       // may navigate away before the setTimeout handler runs. We do
       // a simple comparison against savedURL to check for that.
       let savedURL = doc.documentURI;
 
       setTimeout(() => {
         if (doc.body && doc.designMode == "on" && doc.documentURI == savedURL) {
           doc.body.innerHTML = data.innerHTML;
+          this.fireEvent(doc.body, "input");
         }
       });
     }
   },
 
   /**
    * Iterates the given form data, retrieving nodes for all the keys and
    * restores their appropriate values.
@@ -306,24 +307,34 @@ let FormDataInternal = {
         if (!opt.defaultSelected) {
           eventType = "change";
         }
       });
     }
 
     // Fire events for this node if applicable
     if (eventType) {
-      let doc = aNode.ownerDocument;
-      let event = doc.createEvent("UIEvents");
-      event.initUIEvent(eventType, true, true, doc.defaultView, 0);
-      aNode.dispatchEvent(event);
+      this.fireEvent(aNode, eventType);
     }
   },
 
   /**
+   * Dispatches an event of type |type| to the given |node|.
+   *
+   * @param node (DOMNode)
+   * @param type (string)
+   */
+  fireEvent: function (node, type) {
+    let doc = node.ownerDocument;
+    let event = doc.createEvent("UIEvents");
+    event.initUIEvent(type, true, true, doc.defaultView, 0);
+    node.dispatchEvent(event);
+  },
+
+  /**
    * Restores form data for the current frame hierarchy starting at |root|
    * using the given form |data|.
    *
    * If the given |root| frame's hierarchy doesn't match that of the given
    * |data| object we will silently discard data for unreachable frames. For
    * security reasons we will never restore form data to the wrong frames as
    * we bail out silently if the stored URL doesn't match the frame's current
    * URL.