merge m-c to fx-team
authorTim Taubert <ttaubert@mozilla.com>
Tue, 19 Feb 2013 10:39:49 +0100
changeset 132157 3f0f2fc4bd0f4c9df2061a1ce9fd462a1a86fa4c
parent 132147 e8f8a3f6f1f67c07b9f62dab068ebb97c5f508d0 (current diff)
parent 132156 e884af799de8a163fd41b327dab601ebc5dbdb86 (diff)
child 132158 0577eb1893c44ccce6f6085603f4b12021c01d5f
child 132186 b35634fa6a4abe215c5b4a649a12b0dda6674264
child 132804 508f98d86cf0092b0ed7bac4827d8d1c4bd296d0
push id2323
push userbbajaj@mozilla.com
push dateMon, 01 Apr 2013 19:47:02 +0000
treeherdermozilla-beta@7712be144d91 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone21.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
merge m-c to fx-team
browser/base/content/browser.js
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4712,22 +4712,26 @@ var TabsProgressListener = {
         aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
         aStateFlags & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT &&
         gCrashReporter.enabled) {
       gCrashReporter.annotateCrashReport("URL", aRequest.URI.spec);
     }
 #endif
 
     // Collect telemetry data about tab load times.
-    if (aWebProgress.DOMWindow == aWebProgress.DOMWindow.top &&
-        aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
-      if (aStateFlags & Ci.nsIWebProgressListener.STATE_START)
-        TelemetryStopwatch.start("FX_PAGE_LOAD_MS", aBrowser);
-      else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
-        TelemetryStopwatch.finish("FX_PAGE_LOAD_MS", aBrowser);
+    if (aWebProgress.DOMWindow == aWebProgress.DOMWindow.top) {
+      if (aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
+        if (aStateFlags & Ci.nsIWebProgressListener.STATE_START)
+          TelemetryStopwatch.start("FX_PAGE_LOAD_MS", aBrowser);
+        else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP)
+          TelemetryStopwatch.finish("FX_PAGE_LOAD_MS", aBrowser);
+      } else if (aStateFlags & Ci.nsIWebProgressListener.STATE_STOP &&
+                 aStatus == Cr.NS_BINDING_ABORTED) {
+        TelemetryStopwatch.cancel("FX_PAGE_LOAD_MS", aBrowser);
+      }
     }
 
     // Attach a listener to watch for "click" events bubbling up from error
     // pages and other similar page. This lets us fix bugs like 401575 which
     // require error page UI to do privileged things, without letting error
     // pages have any privilege themselves.
     // We can't look for this during onLocationChange since at that point the
     // document URI is not yet the about:-uri of the error page.
--- a/browser/components/sessionstore/src/SessionStore.jsm
+++ b/browser/components/sessionstore/src/SessionStore.jsm
@@ -287,16 +287,21 @@ let SessionStoreInternal = {
   _restorePinnedTabsOnDemand: null,
 
   // The state from the previous session (after restoring pinned tabs). This
   // state is persisted and passed through to the next session during an app
   // restart to make the third party add-on warning not trash the deferred
   // session
   _lastSessionState: null,
 
+  // When starting Firefox with a single private window, this is the place
+  // where we keep the session we actually wanted to restore in case the user
+  // decides to later open a non-private window as well.
+  _deferredInitialState: null,
+
   // A promise resolved once initialization is complete
   _promiseInitialization: Promise.defer(),
 
   // Whether session has been initialized
   _sessionInitialized: false,
 
   // The original "sessionstore.resume_session_once" preference value before it
   // was modified by saveState.  saveState will set the
@@ -677,58 +682,81 @@ let SessionStoreInternal = {
     aWindow.__SSi = "window" + Date.now();
 
     // and create its data object
     this._windows[aWindow.__SSi] = { tabs: [], selected: 0, _closedTabs: [], busy: false };
 
     // and create its internal data object
     this._internalWindows[aWindow.__SSi] = { hosts: {} }
 
+    let isPrivateWindow = false;
     if (PrivateBrowsingUtils.isWindowPrivate(aWindow))
-      this._windows[aWindow.__SSi].isPrivate = true;
+      this._windows[aWindow.__SSi].isPrivate = isPrivateWindow = true;
     if (!this._isWindowLoaded(aWindow))
       this._windows[aWindow.__SSi]._restoring = true;
     if (!aWindow.toolbar.visible)
       this._windows[aWindow.__SSi].isPopup = true;
 
     // perform additional initialization when the first window is loading
     if (this._loadState == STATE_STOPPED) {
       this._loadState = STATE_RUNNING;
       this._lastSaveTime = Date.now();
 
       // restore a crashed session resp. resume the last session if requested
       if (this._initialState) {
-        TelemetryTimestamps.add("sessionRestoreRestoring");
-        // make sure that the restored tabs are first in the window
-        this._initialState._firstTabs = true;
-        this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
-        this.restoreWindow(aWindow, this._initialState,
-                           this._isCmdLineEmpty(aWindow, this._initialState));
-        delete this._initialState;
-
-        // _loadState changed from "stopped" to "running"
-        // force a save operation so that crashes happening during startup are correctly counted
-        this.saveState(true);
+        if (isPrivateWindow) {
+          // We're starting with a single private window. Save the state we
+          // actually wanted to restore so that we can do it later in case
+          // the user opens another, non-private window.
+          this._deferredInitialState = this._initialState;
+          delete this._initialState;
+
+          // Nothing to restore now, notify observers things are complete.
+          Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
+        } else {
+          TelemetryTimestamps.add("sessionRestoreRestoring");
+          // make sure that the restored tabs are first in the window
+          this._initialState._firstTabs = true;
+          this._restoreCount = this._initialState.windows ? this._initialState.windows.length : 0;
+          this.restoreWindow(aWindow, this._initialState,
+                             this._isCmdLineEmpty(aWindow, this._initialState));
+          delete this._initialState;
+
+          // _loadState changed from "stopped" to "running"
+          // force a save operation so that crashes happening during startup are correctly counted
+          this.saveState(true);
+        }
       }
       else {
         // Nothing to restore, notify observers things are complete.
         Services.obs.notifyObservers(null, NOTIFY_WINDOWS_RESTORED, "");
 
         // the next delayed save request should execute immediately
         this._lastSaveTime -= this._interval;
       }
     }
     // this window was opened by _openWindowWithState
     else if (!this._isWindowLoaded(aWindow)) {
       let followUp = this._statesToRestore[aWindow.__SS_restoreID].windows.length == 1;
       this.restoreWindow(aWindow, this._statesToRestore[aWindow.__SS_restoreID], true, followUp);
     }
+    // The user opened another, non-private window after starting up with
+    // a single private one. Let's restore the session we actually wanted to
+    // restore at startup.
+    else if (this._deferredInitialState && !isPrivateWindow &&
+             aWindow.toolbar.visible) {
+
+      this._deferredInitialState._firstTabs = true;
+      this._restoreCount = this._deferredInitialState.windows ?
+        this._deferredInitialState.windows.length : 0;
+      this.restoreWindow(aWindow, this._deferredInitialState, true);
+      this._deferredInitialState = null;
+    }
     else if (this._restoreLastWindow && aWindow.toolbar.visible &&
-             this._closedWindows.length &&
-             !PrivateBrowsingUtils.isWindowPrivate(aWindow)) {
+             this._closedWindows.length && !isPrivateWindow) {
 
       // default to the most-recently closed window
       // don't use popup windows
       let closedWindowState = null;
       let closedWindowIndex;
       for (let i = 0; i < this._closedWindows.length; i++) {
         // Take the first non-popup, point our object at it, and break out.
         if (!this._closedWindows[i].isPopup) {
@@ -3626,16 +3654,25 @@ let SessionStoreInternal = {
     for (let i = oState.windows.length - 1; i >= 0; i--) {
       if (oState.windows[i].isPrivate) {
         oState.windows.splice(i, 1);
         if (oState.selectedWindow >= i) {
           oState.selectedWindow--;
         }
       }
     }
+
+    // Don't save invalid states.
+    // Looks we currently have private windows, only.
+    if (oState.windows.length == 0) {
+      TelemetryStopwatch.cancel("FX_SESSION_RESTORE_COLLECT_DATA_MS");
+      TelemetryStopwatch.cancel("FX_SESSION_RESTORE_COLLECT_DATA_LONGEST_OP_MS");
+      return;
+    }
+
     for (let i = oState._closedWindows.length - 1; i >= 0; i--) {
       if (oState._closedWindows[i].isPrivate) {
         oState._closedWindows.splice(i, 1);
       }
     }
 
 #ifndef XP_MACOSX
     // We want to restore closed windows that are marked with _shouldRestore.
--- a/browser/devtools/profiler/ProfilerPanel.jsm
+++ b/browser/devtools/profiler/ProfilerPanel.jsm
@@ -465,18 +465,20 @@ ProfilerPanel.prototype = {
         viewSource(data.uri, null, this.document, data.line);
     }
 
     gDevTools.showToolbox(this.target, "jsdebugger").then(function (toolbox) {
       let dbg = toolbox.getCurrentPanel();
       panelWin = dbg.panelWin;
 
       let view = dbg.panelWin.DebuggerView;
-      if (view.Source && view.Sources.selectedValue === data.uri) {
-        return void view.editor.setCaretPosition(data.line - 1);
+      if (view.Sources.selectedValue === data.uri) {
+        view.editor.setCaretPosition(data.line - 1);
+        onOpen();
+        return;
       }
 
       panelWin.addEventListener("Debugger:SourceShown", onSourceShown, false);
       panelWin.DebuggerView.Sources.preferredSource = data.uri;
     }.bind(this));
   },
 
   /**
--- a/browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js
+++ b/browser/devtools/profiler/test/browser_profiler_bug_834878_source_buttons.js
@@ -13,17 +13,26 @@ function test() {
       let data = { uri: SCRIPT, line: 5, isChrome: false };
 
       panel.displaySource(data, function onOpen() {
         let target = TargetFactory.forTab(tab);
         let dbg = gDevTools.getToolbox(target).getPanel("jsdebugger");
         let view = dbg.panelWin.DebuggerView;
 
         is(view.Sources.selectedValue, data.uri, "URI is different");
-        is(view.editor.getCaretPosition().line, data.line - 1, "Line is different");
+        is(view.editor.getCaretPosition().line, data.line - 1,
+          "Line is different");
 
-        tearDown(tab);
+        // Test the case where script is already loaded.
+        view.editor.setCaretPosition(1);
+        gDevTools.showToolbox(target, "jsprofiler").then(function () {
+          panel.displaySource(data, function onOpenAgain() {
+            is(view.editor.getCaretPosition().line, data.line - 1,
+              "Line is different");
+            tearDown(tab);
+          });
+        });
       });
     });
 
     panel.createProfile();
   });
 }
--- a/browser/devtools/shared/DeveloperToolbar.jsm
+++ b/browser/devtools/shared/DeveloperToolbar.jsm
@@ -621,27 +621,26 @@ function DT__updateErrorsCount(aChangedT
     return;
   }
 
   let errors = this._errorsCount[tabId];
   let warnings = this._warningsCount[tabId];
   let btn = this._errorCounterButton;
   if (errors) {
     let errorsText = toolboxStrings
-                     .GetStringFromName("toolboxToggleButton.errorsCount");
-    errorsText = PluralForm.get(errors, errorsText);
+                     .GetStringFromName("toolboxToggleButton.errors");
+    errorsText = PluralForm.get(errors, errorsText).replace("#1", errors);
 
     let warningsText = toolboxStrings
-                       .GetStringFromName("toolboxToggleButton.warningsCount");
-    warningsText = PluralForm.get(warnings, warningsText);
+                       .GetStringFromName("toolboxToggleButton.warnings");
+    warningsText = PluralForm.get(warnings, warningsText).replace("#1", warnings);
 
     let tooltiptext = toolboxStrings
-                      .formatStringFromName("toolboxToggleButton.tooltiptext",
-                                            [errors, errorsText, warnings,
-                                             warningsText], 4);
+                      .formatStringFromName("toolboxToggleButton.tooltip",
+                                            [errorsText, warningsText], 2);
 
     btn.setAttribute("error-count", errors);
     btn.setAttribute("tooltiptext", tooltiptext);
   } else {
     btn.removeAttribute("error-count");
     btn.setAttribute("tooltiptext", btn._defaultTooltipText);
   }
 };
--- a/browser/locales/en-US/chrome/browser/devtools/toolbox.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/toolbox.properties
@@ -1,10 +1,22 @@
 toolboxDockButtons.bottom.tooltip=Dock to bottom of browser window
 toolboxDockButtons.side.tooltip=Dock to side of browser window
 toolboxDockButtons.window.tooltip=Show in separate window
 
-# LOCALIZATION NOTE (toolboxToggleButton): These strings are used for the button
-# that allows users to open/close the developer tools. You can find this button
-# on the developer toolbar.
-toolboxToggleButton.errorsCount=error;errors
-toolboxToggleButton.warningsCount=warning;warnings
-toolboxToggleButton.tooltiptext=%S %S, %S %S.\nClick to toggle the developer tools.
+# LOCALIZATION NOTE (toolboxToggleButton.errors): Semi-colon list of plural
+# forms.
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# #1 number of errors in the current web page
+toolboxToggleButton.errors=#1 error;#1 errors
+
+# LOCALIZATION NOTE (toolboxToggleButton.warnings): Semi-colon list of plural
+# forms.
+# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
+# #1 number of warnings in the current web page
+toolboxToggleButton.warnings=#1 warning;#1 warnings
+
+# LOCALIZATION NOTE (toolboxToggleButton.tooltip): This string is shown
+# as tooltip in the developer toolbar to open/close the developer tools.
+# It's using toolboxToggleButton.errors as first and
+# toolboxToggleButton.warnings as second argument to show the number of errors
+# and warnings.
+toolboxToggleButton.tooltip=%1$S, %2$S\nClick to toggle the developer tools.
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -1446,17 +1446,17 @@ nsDOMWindowUtils::GetScrollbarWidth(bool
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   *aResult = 0;
 
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   NS_ENSURE_STATE(window);
 
-  nsCOMPtr<nsIDocument> doc(do_QueryInterface(window->GetExtantDocument()));
+  nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
   NS_ENSURE_STATE(doc);
 
   if (aFlushLayout) {
     doc->FlushPendingNotifications(Flush_Layout);
   }
 
   nsIPresShell* presShell = doc->GetShell();
   NS_ENSURE_TRUE(presShell, NS_ERROR_NOT_AVAILABLE);