Merge beta to m-r. a=merge
authorRyan VanderMeulen <ryanvm@gmail.com>
Thu, 19 Feb 2015 16:33:16 -0500
changeset 245415 2f2abd6ffebb
parent 245411 49e493494178 (current diff)
parent 245414 89cfa8ff9fc5 (diff)
child 245420 a2ffa9047bf4
push id661
push userryanvm@gmail.com
push date2015-02-19 21:33 +0000
treeherdermozilla-release@2f2abd6ffebb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone36.0
Merge beta to m-r. a=merge
--- a/browser/components/loop/MozLoopService.jsm
+++ b/browser/components/loop/MozLoopService.jsm
@@ -1521,23 +1521,39 @@ this.MozLoopService = {
    *
    * @param {String} aSrc A string representing the entry point to begin the tour, optional.
    * @param {Object} aAdditionalParams An object with keys used as query parameter names
    */
   getTourURL: function(aSrc = null, aAdditionalParams = {}) {
     let urlStr = this.getLoopPref("gettingStarted.url");
     let url = new URL(Services.urlFormatter.formatURL(urlStr));
     for (let paramName in aAdditionalParams) {
-      url.searchParams.append(paramName, aAdditionalParams[paramName]);
+      url.searchParams.set(paramName, aAdditionalParams[paramName]);
     }
     if (aSrc) {
       url.searchParams.set("utm_source", "firefox-browser");
       url.searchParams.set("utm_medium", "firefox-browser");
       url.searchParams.set("utm_campaign", aSrc);
     }
+
+    // Find the most recent pageID that has the Loop prefix.
+    let mostRecentLoopPageID = {id: null, lastSeen: null};
+    for (let pageID of UITour.pageIDsForSession) {
+      if (pageID[0] && pageID[0].startsWith("hello-tour_OpenPanel_") &&
+          pageID[1] && pageID[1].lastSeen > mostRecentLoopPageID.lastSeen) {
+        mostRecentLoopPageID.id = pageID[0];
+        mostRecentLoopPageID.lastSeen = pageID[1].lastSeen;
+      }
+    }
+
+    const PAGE_ID_EXPIRATION_MS = 60 * 60 * 1000;
+    if (mostRecentLoopPageID.id &&
+        mostRecentLoopPageID.lastSeen > Date.now() - PAGE_ID_EXPIRATION_MS) {
+      url.searchParams.set("utm_content", mostRecentLoopPageID.id);
+    }
     return url;
   },
 
   resumeTour: function(aIncomingConversationState) {
     if (!this.getLoopPref("gettingStarted.resumeOnFirstJoin")) {
       return;
     }
 
--- a/browser/modules/UITour.jsm
+++ b/browser/modules/UITour.jsm
@@ -67,16 +67,19 @@ XPCOMUtils.defineLazyGetter(this, "log",
     prefix: "UITour",
   };
   return new ConsoleAPI(consoleOptions);
 });
 
 this.UITour = {
   url: null,
   seenPageIDs: null,
+  // This map is not persisted and is used for
+  // building the content source of a potential tour.
+  pageIDsForSession: new Map(),
   pageIDSourceBrowsers: new WeakMap(),
   /* Map from browser chrome windows to a Set of <browser>s in which a tour is open (both visible and hidden) */
   tourBrowsersByWindow: new WeakMap(),
   urlbarCapture: new WeakMap(),
   appMenuOpenForAnnotation: new Set(),
   availableTargetsCache: new WeakMap(),
 
   _annotationPanelMutationObservers: new WeakMap(),
@@ -373,26 +376,32 @@ this.UITour = {
     window.gBrowser.tabContainer.addEventListener("TabSelect", this);
 
     if (!window.gMultiProcessBrowser) { // Non-e10s. See bug 1089000.
       contentDocument = browser.contentWindow.document;
     }
 
     switch (action) {
       case "registerPageID": {
-        // This is only relevant if Telemtry is enabled.
+        if (typeof data.pageID != "string") {
+          log.warn("registerPageID: pageID must be a string");
+          break;
+        }
+
+        this.pageIDsForSession.set(data.pageID, {lastSeen: Date.now()});
+
+        // The rest is only relevant if Telemetry is enabled.
         if (!UITelemetry.enabled) {
-          log.debug("registerPageID: Telemery disabled, not doing anything");
+          log.debug("registerPageID: Telemetry disabled, not doing anything");
           break;
         }
 
         // We don't want to allow BrowserUITelemetry.BUCKET_SEPARATOR in the
         // pageID, as it could make parsing the telemetry bucket name difficult.
-        if (typeof data.pageID != "string" ||
-            data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
+        if (data.pageID.contains(BrowserUITelemetry.BUCKET_SEPARATOR)) {
           log.warn("registerPageID: Invalid page ID specified");
           break;
         }
 
         this.addSeenPageID(data.pageID);
         this.pageIDSourceBrowsers.set(browser, data.pageID);
         this.setTelemetryBucket(data.pageID);
 
--- a/browser/modules/test/browser.ini
+++ b/browser/modules/test/browser.ini
@@ -24,17 +24,17 @@ skip-if = e10s # Bug 941428 - UITour.jsm
 skip-if = os == "linux" || e10s # Linux: Bug 986760, Bug 989101; e10s: Bug 941428 - UITour.jsm not e10s friendly
 [browser_UITour_availableTargets.js]
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly
 [browser_UITour_detach_tab.js]
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly
 [browser_UITour_annotation_size_attributes.js]
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
 [browser_UITour_loop.js]
-skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
+skip-if = os == "linux" || e10s # Bug 941428 - UITour.jsm not e10s friendly.
 [browser_UITour_modalDialog.js]
 run-if = os == "mac" # modal dialog disabling only working on OS X
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly
 [browser_UITour_observe.js]
 skip-if = e10s # Bug 941428 - UITour.jsm not e10s friendly.
 [browser_UITour_panel_close_annotation.js]
 skip-if = true # Disabled due to frequent failures, bugs 1026310 and 1032137
 [browser_UITour_registerPageID.js]
--- a/browser/modules/test/browser_UITour_loop.js
+++ b/browser/modules/test/browser_UITour_loop.js
@@ -13,17 +13,94 @@ Components.utils.import("resource:///mod
 const { LoopRooms } = Components.utils.import("resource:///modules/loop/LoopRooms.jsm", {});
 const { MozLoopServiceInternal } = Cu.import("resource:///modules/loop/MozLoopService.jsm", {});
 
 function test() {
   UITourTest();
 }
 
 let tests = [
+  taskify(function* test_gettingStartedClicked_linkOpenedWithExpectedParams() {
+    Services.prefs.setBoolPref("loop.gettingStarted.seen", false);
+    Services.prefs.setCharPref("loop.gettingStarted.url", "http://example.com");
+    ise(loopButton.open, false, "Menu should initially be closed");
+    loopButton.click();
+
+    yield waitForConditionPromise(() => {
+      return loopButton.open;
+    }, "Menu should be visible after showMenu()");
+
+    gContentAPI.registerPageID("hello-tour_OpenPanel_testPage");
+    yield new Promise(resolve => {
+      gContentAPI.ping(() => resolve());
+    });
+
+    let loopDoc = document.getElementById("loop-notification-panel").children[0].contentDocument;
+    let gettingStartedButton = loopDoc.getElementById("fte-button");
+    ok(gettingStartedButton, "Getting Started button should be found");
+
+    let newTabPromise = waitForConditionPromise(() => {
+      return gBrowser.currentURI.path.contains("utm_source=firefox-browser");
+    }, "New tab with utm_content=testPageNewID should have opened");
+
+    gettingStartedButton.click();
+    yield newTabPromise;
+    ok(gBrowser.currentURI.path.contains("utm_content=hello-tour_OpenPanel_testPage"),
+        "Expected URL opened (" + gBrowser.currentURI.path + ")");
+    yield gBrowser.removeCurrentTab();
+
+    checkLoopPanelIsHidden();
+  }),
+  taskify(function* test_gettingStartedClicked_linkOpenedWithExpectedParams2() {
+    Services.prefs.setBoolPref("loop.gettingStarted.seen", false);
+    // Force a refresh of the loop panel since going from seen -> unseen doesn't trigger
+    // automatic re-rendering.
+    let loopWin = document.getElementById("loop-notification-panel").children[0].contentWindow;
+    var event = new loopWin.CustomEvent("GettingStartedSeen");
+    loopWin.dispatchEvent(event);
+
+    UITour.pageIDsForSession.clear();
+    Services.prefs.setCharPref("loop.gettingStarted.url", "http://example.com");
+    ise(loopButton.open, false, "Menu should initially be closed");
+    loopButton.click();
+
+    yield waitForConditionPromise(() => {
+      return loopButton.open;
+    }, "Menu should be visible after showMenu()");
+
+
+    gContentAPI.registerPageID("hello-tour_OpenPanel_testPageOldId");
+    yield new Promise(resolve => {
+      gContentAPI.ping(() => resolve());
+    });
+    // Set the time of the page ID to 10 hours earlier, so that it is considered "expired".
+    UITour.pageIDsForSession.set("hello-tour_OpenPanel_testPageOldId",
+                                   {lastSeen: Date.now() - (10 * 60 * 60 * 1000)});
+
+    let loopDoc = loopWin.document;
+    let gettingStartedButton = loopDoc.getElementById("fte-button");
+    ok(gettingStartedButton, "Getting Started button should be found");
+
+    let newTabPromise = waitForConditionPromise(() => {
+      Services.console.logStringMessage(gBrowser.currentURI.path);
+      return gBrowser.currentURI.path.contains("utm_source=firefox-browser");
+    }, "New tab with utm_content=testPageNewID should have opened");
+
+    gettingStartedButton.click();
+    yield newTabPromise;
+    ok(!gBrowser.currentURI.path.contains("utm_content=hello-tour_OpenPanel_testPageOldId"),
+       "Expected URL opened without the utm_content parameter (" +
+        gBrowser.currentURI.path + ")");
+    yield gBrowser.removeCurrentTab();
+
+    checkLoopPanelIsHidden();
+  }),
   taskify(function* test_menu_show_hide() {
+    // The targets to highlight only appear after getting started is launched.
+    Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
     ise(loopButton.open, false, "Menu should initially be closed");
     gContentAPI.showMenu("loop");
 
     yield waitForConditionPromise(() => {
       return loopButton.open;
     }, "Menu should be visible after showMenu()");
 
     ok(loopPanel.hasAttribute("noautohide"), "@noautohide should be on the loop panel");
@@ -310,18 +387,16 @@ function setupFakeRoom() {
     [room.roomToken, room]
   ]);
   LoopRooms.stubCache(roomsMap);
   return roomsMap;
 }
 
 if (Services.prefs.getBoolPref("loop.enabled")) {
   loopButton = window.LoopUI.toolbarButton.node;
-  // The targets to highlight only appear after getting started is launched.
-  Services.prefs.setBoolPref("loop.gettingStarted.seen", true);
 
   registerCleanupFunction(() => {
     Services.prefs.clearUserPref("loop.gettingStarted.resumeOnFirstJoin");
     Services.prefs.clearUserPref("loop.gettingStarted.seen");
     Services.prefs.clearUserPref("loop.gettingStarted.url");
 
     // Copied from browser/components/loop/test/mochitest/head.js
     // Remove the iframe after each test. This also avoids mochitest complaining
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -3729,17 +3729,18 @@ nsDocument::SetHeaderData(nsIAtom* aHead
       aHeaderField == nsGkAtoms::viewport_initial_scale ||
       aHeaderField == nsGkAtoms::viewport_height ||
       aHeaderField == nsGkAtoms::viewport_width ||
       aHeaderField ==  nsGkAtoms::viewport_user_scalable) {
     mViewportType = Unknown;
   }
 
   // Referrer policy spec says to ignore any empty referrer policies.
-  if (aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
+  // Disabled for now.
+  if (false && aHeaderField == nsGkAtoms::referrer && !aData.IsEmpty()) {
     ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aData);
 
     // Referrer policy spec (section 6.1) says that once the referrer policy
     // is set, any future attempts to change it result in No-Referrer.
     if (!mReferrerPolicySet) {
       mReferrerPolicy = policy;
       mReferrerPolicySet = true;
     } else if (mReferrerPolicy != policy) {
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -595,19 +595,21 @@ skip-if = buildapp == 'b2g'
 [test_bug693875.html]
 [test_bug694754.xhtml]
 [test_bug696301-1.html]
 [test_bug696301-2.html]
 [test_bug698381.html]
 [test_bug698384.html]
 [test_bug704063.html]
 [test_bug704320.html]
-skip-if = buildapp == 'b2g' || toolkit == 'android' || e10s # b2g (Needs multiple window.open support) android(times out, bug 1100609) e10s(randomly fails, bug 1100362)
+skip-if = true
 [test_bug704320_policyset.html]
+skip-if = true
 [test_bug704320_preload.html]
+skip-if = true
 [test_bug707142.html]
 [test_bug708620.html]
 [test_bug711047.html]
 [test_bug711180.html]
 [test_bug719533.html]
 [test_bug726364.html]
 [test_bug737087.html]
 [test_bug737565.html]
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -326,16 +326,19 @@ TexClientFromReadback(SharedSurface* src
 }
 
 ////////////////////////////////////////
 
 static TemporaryRef<gl::ShSurfHandle>
 CloneSurface(gl::SharedSurface* src, gl::SurfaceFactory* factory)
 {
     RefPtr<gl::ShSurfHandle> dest = factory->NewShSurfHandle(src->mSize);
+    if (!dest) {
+        return nullptr;
+    }
     SharedSurface::ProdCopy(src, dest->Surf(), factory);
     return dest.forget();
 }
 
 void
 CanvasClientSharedSurface::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   if (mFront) {
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -954,16 +954,18 @@ nsHtml5TreeOpExecutor::SetSpeculationBas
   DebugOnly<nsresult> rv = NS_NewURI(getter_AddRefs(mSpeculationBaseURI), aURL,
                                      charset.get(), mDocument->GetDocumentURI());
   NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Failed to create a URI");
 }
 
 void
 nsHtml5TreeOpExecutor::SetSpeculationReferrerPolicy(const nsAString& aReferrerPolicy)
 {
+  // Disabled for now.
+  return;
   ReferrerPolicy policy = mozilla::net::ReferrerPolicyFromString(aReferrerPolicy);
 
   if (mSpeculationReferrerPolicyWasSet &&
       policy != mSpeculationReferrerPolicy) {
     // According to the Referrer Policy spec, if there's already been a policy
     // set and another attempt is made to set a _different_ policy, the result
     // is a "No Referrer" policy.
     mSpeculationReferrerPolicy = mozilla::net::RP_No_Referrer;