Bug 1456391 - Part 8: Use mapFrameTree in Fennec. r?esawin draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Wed, 25 Apr 2018 22:21:41 +0200
changeset 790741 d5d7cc56a70f6215abe1ded8c7c05f4154fa6d09
parent 790284 5469e55f537cb04b4c009e8b67e34a29707e3e82
child 790742 da8935ed70d3ad83859ab092a6635f3ba40d2a78
child 790755 ed3edf3c2eaf80644b717b5b50a957edaeba1e55
push id108566
push usermozilla@buttercookie.de
push dateWed, 02 May 2018 17:36:39 +0000
reviewersesawin
bugs1456391
milestone61.0a1
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>