Bug 1456391 - Part 8: Use mapFrameTree in Fennec. r=esawin
authorJan Henning <jh+bugzilla@buttercookie.de>
Wed, 25 Apr 2018 22:21:41 +0200
changeset 472839 95302e1c0022b11dee5216778b6564de482d947f
parent 472838 8f8e66175fd74c07cbae8f738c8f3ca266288794
child 472840 5969ba522eddc5eeed633ae7f367241f0a503b9d
push id1728
push userjlund@mozilla.com
push dateMon, 18 Jun 2018 21:12:27 +0000
treeherdermozilla-release@c296fde26f5f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersesawin
bugs1456391
milestone61.0a1
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
Bug 1456391 - Part 8: Use mapFrameTree in Fennec. r=esawin This brings us in line with Desktop's session store, in that we can now collect data for arbitrarily nested frame structures. At the same time, this also means that we no longer collect data for dynamically added frames, so the corresponding mochitest needs to be adapted accordingly. MozReview-Commit-ID: DfJ3C2ccUne
mobile/android/components/SessionStore.js
mobile/android/tests/browser/chrome/session_formdata_sample.html
--- a/mobile/android/components/SessionStore.js
+++ b/mobile/android/components/SessionStore.js
@@ -6,23 +6,24 @@
 ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
 ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
 ChromeUtils.import("resource://gre/modules/Services.jsm");
 
 XPCOMUtils.defineLazyModuleGetters(this, {
   EventDispatcher: "resource://gre/modules/Messaging.jsm",
   FormData: "resource://gre/modules/FormData.jsm",
   OS: "resource://gre/modules/osfile.jsm",
-  PrivacyLevel: "resource://gre/modules/sessionstore/PrivacyLevel.jsm",
+  PrivacyFilter: "resource://gre/modules/sessionstore/PrivacyFilter.jsm",
   PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
   ScrollPosition: "resource://gre/modules/ScrollPosition.jsm",
   SessionHistory: "resource://gre/modules/sessionstore/SessionHistory.jsm",
   SharedPreferences: "resource://gre/modules/SharedPreferences.jsm",
   Task: "resource://gre/modules/Task.jsm",
   TelemetryStopwatch: "resource://gre/modules/TelemetryStopwatch.jsm",
+  Utils: "resource://gre/modules/sessionstore/Utils.jsm",
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "Log", "resource://gre/modules/AndroidLog.jsm", "AndroidLog");
 
 function dump(a) {
   Services.console.logStringMessage(a);
 }
 
@@ -885,51 +886,23 @@ SessionStore.prototype = {
 
     // Don't bother trying to save text data if we don't have history yet
     let data = aBrowser.__SS_data;
     if (!data || data.entries.length == 0) {
       sendEvent(aBrowser, "SSTabInputCaptured");
       return;
     }
 
-    // Start with storing the main content
+    // Store the form data.
     let content = aBrowser.contentWindow;
-
-    // If the main content document has an associated URL that we are not
-    // allowed to store data for, bail out. We explicitly discard data for any
-    // children as well even if storing data for those frames would be allowed.
-    if (!PrivacyLevel.check(content.document.documentURI)) {
-      sendEvent(aBrowser, "SSTabInputCaptured");
-      return;
-    }
-
-    // Store the main content
-    let formdata = FormData.collect(content) || {};
-
-    // Loop over direct child frames, and store the text data
-    let children = [];
-    for (let i = 0; i < content.frames.length; i++) {
-      let frame = content.frames[i];
-      if (!PrivacyLevel.check(frame.document.documentURI)) {
-        continue;
-      }
-
-      let result = FormData.collect(frame);
-      if (result && Object.keys(result).length) {
-        children[i] = result;
-      }
-    }
-
-    // If any frame had text data, add it to the main form data
-    if (children.length) {
-      formdata.children = children;
-    }
+    let [formdata] = Utils.mapFrameTree(content, FormData.collect);
+    formdata = PrivacyFilter.filterFormData(formdata || {});
 
     // If we found any form data, main content or frames, let's save it
-    if (Object.keys(formdata).length) {
+    if (formdata && Object.keys(formdata).length) {
       data.formdata = formdata;
       log("onTabInput() ran for tab " + aWindow.BrowserApp.getTabForBrowser(aBrowser).id);
       this.saveStateDelayed();
     }
     sendEvent(aBrowser, "SSTabInputCaptured");
   },
 
   onTabScroll: function ss_onTabScroll(aWindow, aBrowser) {
@@ -952,37 +925,20 @@ SessionStore.prototype = {
       return;
     }
 
     // Neither bother if we're yet to restore the previous scroll position.
     if (aBrowser.__SS_restoreDataOnLoad || aBrowser.__SS_restoreDataOnPageshow) {
       return;
     }
 
-    // Start with storing the main content.
+    // Save the scroll position itself.
     let content = aBrowser.contentWindow;
-
-    // Store the main content.
-    let scrolldata = ScrollPosition.collect(content) || {};
-
-    // Loop over direct child frames, and store the scroll positions.
-    let children = [];
-    for (let i = 0; i < content.frames.length; i++) {
-      let frame = content.frames[i];
-
-      let result = ScrollPosition.collect(frame);
-      if (result && Object.keys(result).length) {
-        children[i] = result;
-      }
-    }
-
-    // If any frame had scroll positions, add them to the main scroll data.
-    if (children.length) {
-      scrolldata.children = children;
-    }
+    let [scrolldata] = Utils.mapFrameTree(content, ScrollPosition.collect);
+    scrolldata = scrolldata || {};
 
     // Save the current document resolution.
     let zoom = { value: 1 };
     content.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(
       Ci.nsIDOMWindowUtils).getResolution(zoom);
     scrolldata.zoom = {};
     scrolldata.zoom.resolution = zoom.value;
     log("onTabScroll() zoom level: " + zoom.value);
--- a/mobile/android/tests/browser/chrome/session_formdata_sample.html
+++ b/mobile/android/tests/browser/chrome/session_formdata_sample.html
@@ -1,20 +1,20 @@
 <!DOCTYPE html>
 <html lang="en">
   <head>
     <meta charset="utf-8">
     <title>session_formdata_sample.html</title>
   </head>
   <body>
     <input id="txt" />
+    <iframe id="iframe"></iframe>
 
     <script type="text/javascript">
       let isOuter = window == window.top;
 
       if (isOuter) {
-        let iframe = document.createElement("iframe");
+        let iframe = document.getElementById("iframe");
         iframe.setAttribute("src", "https://example.com" + location.pathname);
-        document.body.appendChild(iframe);
       }
     </script>
   </body>
 </html>