Bug 1273609 - [webext] Support manual_subframe transitionType in webNavigation events details. r?krizsa draft
authorLuca Greco <lgreco@mozilla.com>
Tue, 17 May 2016 19:08:10 +0200
changeset 368209 62463a1ad341130570d973b8aeedf89f0fe00fce
parent 367897 c480fcee4fc0af1e22f08124937cc7602ed16032
child 521208 1b01237d3254c8e5ed7a3047b04eb76249df2c9c
push id18465
push userluca.greco@alcacoop.it
push dateWed, 18 May 2016 10:47:52 +0000
reviewerskrizsa
bugs1273609
milestone49.0a1
Bug 1273609 - [webext] Support manual_subframe transitionType in webNavigation events details. r?krizsa MozReview-Commit-ID: F5Z3XppNDYm
toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe.html
toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe_page1.html
toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe_page2.html
toolkit/components/extensions/test/mochitest/mochitest.ini
toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html
toolkit/modules/addons/WebNavigation.jsm
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+
+<html>
+<body>
+
+<iframe src="file_webNavigation_manualSubframe_page1.html" width="200" height="200"></iframe>
+
+<form>
+</form>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe_page1.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+
+<html>
+  <body>
+    <h1>page1</h1>
+    <a href="file_webNavigation_manualSubframe_page2.html">page2</a>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/mochitest/file_webNavigation_manualSubframe_page2.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+
+<html>
+  <body>
+    <h1>page2</h1>
+  </body>
+</html>
--- a/toolkit/components/extensions/test/mochitest/mochitest.ini
+++ b/toolkit/components/extensions/test/mochitest/mochitest.ini
@@ -8,16 +8,19 @@ support-files =
   file_WebRequest_page1.html
   file_WebRequest_page2.html
   file_WebRequest_page3.html
   file_webNavigation_clientRedirect.html
   file_webNavigation_clientRedirect_httpHeaders.html
   file_webNavigation_clientRedirect_httpHeaders.html^headers^
   file_webNavigation_frameClientRedirect.html
   file_webNavigation_frameRedirect.html
+  file_webNavigation_manualSubframe.html
+  file_webNavigation_manualSubframe_page1.html
+  file_webNavigation_manualSubframe_page2.html
   file_WebNavigation_page1.html
   file_WebNavigation_page2.html
   file_WebNavigation_page3.html
   file_image_good.png
   file_image_bad.png
   file_image_redirect.png
   file_style_good.css
   file_style_bad.css
--- a/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html
+++ b/toolkit/components/extensions/test/mochitest/test_ext_webnavigation.html
@@ -1,23 +1,26 @@
 <!DOCTYPE HTML>
 <html>
 <head>
   <title>Test for simple WebExtension</title>
   <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
   <script type="text/javascript" src="/tests/SimpleTest/ExtensionTestUtils.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
   <script type="text/javascript" src="head.js"></script>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
 </head>
 <body>
 
 <script type="text/javascript">
 "use strict";
 
+/* globals sendMouseEvent */
+
 function backgroundScript() {
   const BASE = "http://mochi.test:8888/tests/toolkit/components/extensions/test/mochitest";
   const URL = BASE + "/file_WebNavigation_page1.html";
 
   const EVENTS = [
     "onBeforeNavigate",
     "onCommitted",
     "onDOMContentLoaded",
@@ -71,16 +74,19 @@ const FRAME = BASE + "/file_WebNavigatio
 const FRAME2 = BASE + "/file_WebNavigation_page3.html";
 const FRAME_PUSHSTATE = BASE + "/file_WebNavigation_page3_pushState.html";
 const REDIRECT = BASE + "/redirection.sjs";
 const REDIRECTED = BASE + "/dummy_page.html";
 const CLIENT_REDIRECT = BASE + "/file_webNavigation_clientRedirect.html";
 const CLIENT_REDIRECT_HTTPHEADER = BASE + "/file_webNavigation_clientRedirect_httpHeaders.html";
 const FRAME_CLIENT_REDIRECT = BASE + "/file_webNavigation_frameClientRedirect.html";
 const FRAME_REDIRECT = BASE + "/file_webNavigation_frameRedirect.html";
+const FRAME_MANUAL = BASE + "/file_webNavigation_manualSubframe.html";
+const FRAME_MANUAL_PAGE1 = BASE + "/file_webNavigation_manualSubframe_page1.html";
+const FRAME_MANUAL_PAGE2 = BASE + "/file_webNavigation_manualSubframe_page2.html";
 
 const REQUIRED = [
   "onBeforeNavigate",
   "onCommitted",
   "onDOMContentLoaded",
   "onCompleted",
 ];
 
@@ -293,16 +299,46 @@ add_task(function* webnav_transitions_pr
     // BUG 1264936: currently the server_redirect is not detected in sub-frames
     // once we fix it we can test it here:
     //
     // ok(Array.isArray(found.details.transitionQualifiers) &&
     //    found.details.transitionQualifiers.find((q) => q == "server_redirect"),
     //    "Got the expected 'server_redirect' transitionQualifiers in the OnCommitted events");
   }
 
+  // transitionType: manual_subframe
+  received = [];
+  yield loadAndWait(win, "onCompleted", FRAME_MANUAL, () => { win.location = FRAME_MANUAL; });
+  found = received.find((data) => (data.event == "onCommitted" &&
+                                   data.url == FRAME_MANUAL_PAGE1));
+
+  ok(found, "Got the onCommitted event");
+
+  if (found) {
+    is(found.details.transitionType, "auto_subframe",
+       "Got the expected 'auto_subframe' transitionType in the OnCommitted event");
+  }
+
+  received = [];
+  yield loadAndWait(win, "onCompleted", FRAME_MANUAL_PAGE2, () => {
+    let el = win.document.querySelector("iframe")
+                .contentDocument.querySelector("a");
+    sendMouseEvent({type: "click"}, el, win);
+  });
+
+  found = received.find((data) => (data.event == "onCommitted" &&
+                                   data.url == FRAME_MANUAL_PAGE2));
+
+  ok(found, "Got the onCommitted event");
+
+  if (found) {
+    is(found.details.transitionType, "manual_subframe",
+       "Got the expected 'manual_subframe' transitionType in the OnCommitted event");
+  }
+
   // cleanup phase
   win.close();
 
   yield extension.unload();
   info("webnavigation extension unloaded");
 });
 
 add_task(function* webnav_ordering() {
--- a/toolkit/modules/addons/WebNavigation.jsm
+++ b/toolkit/modules/addons/WebNavigation.jsm
@@ -28,32 +28,36 @@ var Manager = {
   listeners: new Map(),
 
   init() {
     // Collect recent tab transition data in a WeakMap:
     //   browser -> tabTransitionData
     this.recentTabTransitionData = new WeakMap();
     Services.obs.addObserver(this, "autocomplete-did-enter-text", true);
 
+    Services.mm.addMessageListener("Content:Click", this);
     Services.mm.addMessageListener("Extension:DOMContentLoaded", this);
     Services.mm.addMessageListener("Extension:StateChange", this);
     Services.mm.addMessageListener("Extension:DocumentChange", this);
     Services.mm.addMessageListener("Extension:HistoryChange", this);
+
     Services.mm.loadFrameScript("resource://gre/modules/WebNavigationContent.js", true);
   },
 
   uninit() {
     // Stop collecting recent tab transition data and reset the WeakMap.
     Services.obs.removeObserver(this, "autocomplete-did-enter-text", true);
     this.recentTabTransitionData = new WeakMap();
 
+    Services.mm.removeMessageListener("Content:Click", this);
     Services.mm.removeMessageListener("Extension:StateChange", this);
     Services.mm.removeMessageListener("Extension:DocumentChange", this);
     Services.mm.removeMessageListener("Extension:HistoryChange", this);
     Services.mm.removeMessageListener("Extension:DOMContentLoaded", this);
+
     Services.mm.removeDelayedFrameScript("resource://gre/modules/WebNavigationContent.js");
     Services.mm.broadcastAsyncMessage("Extension:DisableWebNavigation");
   },
 
   addListener(type, listener) {
     if (this.listeners.size == 0) {
       this.init();
     }
@@ -229,16 +233,31 @@ var Manager = {
 
       case "Extension:HistoryChange":
         this.onHistoryChange(target, data);
         break;
 
       case "Extension:DOMContentLoaded":
         this.onLoad(target, data);
         break;
+
+      case "Content:Click":
+        this.onContentClick(target, data);
+        break;
+    }
+  },
+
+  onContentClick(target, data) {
+    // We are interested only on clicks to links which are not "add to bookmark" commands
+    if (data.href && !data.bookmark) {
+      let ownerWin = target.ownerDocument.defaultView;
+      let where = ownerWin.whereToOpenLink(data);
+      if (where == "current") {
+        this.setRecentTabTransitionData({link: true});
+      }
     }
   },
 
   onStateChange(browser, data) {
     let stateFlags = data.stateFlags;
     if (stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
       let url = data.requestURL;
       if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {