merge m-c to fx-team
authorTim Taubert <tim.taubert@gmx.de>
Thu, 05 Jan 2012 10:19:15 +0100
changeset 83800 4795500b7c1d62f7659c9cd2e0c26e8b7a705bd4
parent 83795 10894668e37f17be5b8bee6fa33fa24eb0b534c0 (current diff)
parent 83799 93e89c2fd0964403d910f7b6df968e4f4e1c3220 (diff)
child 83801 5413ba3ed406e2caa85af69d3ace66fd45ae8d27
child 83858 fcbdb7dc7fee5350a61199197efdbdb8cac01c5f
child 84015 ffedccc6bf24c5c2a3fb6ee8a77c19606d3b4fd1
push id21793
push usertim.taubert@gmx.de
push dateThu, 05 Jan 2012 09:26:35 +0000
treeherdermozilla-central@4795500b7c1d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
first release with
nightly win32
4795500b7c1d / 12.0a1 / 20120105031049 / files
nightly win64
4795500b7c1d / 12.0a1 / 20120105031049 / files
nightly linux32
nightly linux64
nightly mac
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly win32
nightly win64
merge m-c to fx-team
--- a/browser/base/content/browser.css
+++ b/browser/base/content/browser.css
@@ -8,23 +8,28 @@ searchbar {
 tabbrowser {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser");
 }
 
 .tabbrowser-tabs {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tabs");
 }
 
+#tabbrowser-tabs:not([overflow="true"]) ~ #alltabs-button,
 #tabbrowser-tabs:not([overflow="true"]) + #new-tab-button,
 #tabbrowser-tabs[overflow="true"] > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[currentset]:not([currentset*="tabbrowser-tabs,new-tab-button"]) > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button,
 #TabsToolbar[customizing="true"] > #tabbrowser-tabs > .tabbrowser-arrowscrollbox > .tabs-newtab-button {
   visibility: collapse;
 }
 
+#tabbrowser-tabs:not([overflow="true"])[using-closing-tabs-spacer] ~ #alltabs-button {
+  visibility: hidden; /* temporary space to keep a tab's close button under the cursor */
+}
+
 .tabbrowser-tab {
   -moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-tab");
 }
 
 .tabbrowser-tab:not([pinned]) {
   -moz-box-flex: 100;
   max-width: 250px;
   min-width: 100px;
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -2922,17 +2922,16 @@
 
       <field name="_closingTabsSpacer">
         document.getAnonymousElementByAttribute(this, "anonid", "closing-tabs-spacer");
       </field>
 
       <field name="_tabDefaultMaxWidth">NaN</field>
       <field name="_lastTabClosedByMouse">false</field>
       <field name="_hasTabTempMaxWidth">false</field>
-      <field name="_usingClosingTabsSpacer">false</field>
 
       <!-- Try to keep the active tab's close button under the mouse cursor -->
       <method name="_lockTabSizing">
         <parameter name="aTab"/>
         <body><![CDATA[
           var tabs = this.tabbrowser.visibleTabs;
           if (!tabs.length)
             return;
@@ -2990,34 +2989,36 @@
         ]]></body>
       </method>
 
       <method name="_expandSpacerBy">
         <parameter name="pixels"/>
         <body><![CDATA[
           let spacer = this._closingTabsSpacer;
           spacer.style.width = parseFloat(spacer.style.width) + pixels + "px";
-          this._usingClosingTabsSpacer = true;
+          this.setAttribute("using-closing-tabs-spacer", "true");
           this.tabbrowser.addEventListener("mousemove", this, false);
           window.addEventListener("mouseout", this, false);
         ]]></body>
       </method>
 
       <method name="_unlockTabSizing">
         <body><![CDATA[
           this.tabbrowser.removeEventListener("mousemove", this, false);
           window.removeEventListener("mouseout", this, false);
+
           if (this._hasTabTempMaxWidth) {
             this._hasTabTempMaxWidth = false;
             let tabs = this.tabbrowser.visibleTabs;
             for (let i = 0; i < tabs.length; i++)
               tabs[i].style.maxWidth = "";
           }
-          if (this._usingClosingTabsSpacer) {
-            this._usingClosingTabsSpacer = false;
+
+          if (this.hasAttribute("using-closing-tabs-spacer")) {
+            this.removeAttribute("using-closing-tabs-spacer");
             this._closingTabsSpacer.style.width = 0;
           }
         ]]></body>
       </method>
 
       <method name="_positionPinnedTabs">
         <body><![CDATA[
           var numPinned = this.tabbrowser._numPinnedTabs;
--- a/browser/devtools/scratchpad/scratchpad.js
+++ b/browser/devtools/scratchpad/scratchpad.js
@@ -327,31 +327,17 @@ var Scratchpad = {
   evalInContentSandbox: function SP_evalInContentSandbox(aString)
   {
     let error, result;
     try {
       result = Cu.evalInSandbox(aString, this.contentSandbox, "1.8",
                                 "Scratchpad", 1);
     }
     catch (ex) {
-      this.openWebConsole();
-
-      let contentWindow = this.gBrowser.selectedBrowser.contentWindow;
-
-      let scriptError = Cc["@mozilla.org/scripterror;1"].
-                        createInstance(Ci.nsIScriptError);
-
-      scriptError.initWithWindowID(ex.message + "\n" + ex.stack, ex.fileName,
-                                   "", ex.lineNumber, 0, scriptError.errorFlag,
-                                   "content javascript",
-                                   this.getInnerWindowId(contentWindow));
-
-      Services.console.logMessage(scriptError);
-
-      error = true;
+      error = ex;
     }
 
     return [error, result];
   },
 
   /**
    * Evaluate a string in the most recent navigator:browser chrome window.
    *
@@ -363,21 +349,17 @@ var Scratchpad = {
   evalInChromeSandbox: function SP_evalInChromeSandbox(aString)
   {
     let error, result;
     try {
       result = Cu.evalInSandbox(aString, this.chromeSandbox, "1.8",
                                 "Scratchpad", 1);
     }
     catch (ex) {
-      Cu.reportError(ex);
-      Cu.reportError(ex.stack);
-      this.openErrorConsole();
-
-      error = true;
+      error = ex;
     }
 
     return [error, result];
   },
 
   /**
    * Evaluate a string in the currently desired context, that is either the
    * chrome window or the tab content window object.
@@ -392,66 +374,110 @@ var Scratchpad = {
     return this.executionContext == SCRATCHPAD_CONTEXT_CONTENT ?
            this.evalInContentSandbox(aString) :
            this.evalInChromeSandbox(aString);
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context.
+   * @return mixed
+   *         The script evaluation result.
+   */
+  execute: function SP_execute()
+  {
+    let selection = this.selectedText || this.getText();
+    let [error, result] = this.evalForContext(selection);
+    return [selection, error, result];
+  },
+
+  /**
+   * Execute the selected text (if any) or the entire editor content in the
+   * current context.
    */
   run: function SP_run()
   {
-    let selection = this.selectedText || this.getText();
-    let [error, result] = this.evalForContext(selection);
-    this.deselect();
+    let [selection, error, result] = this.execute();
+
+    if (!error) {
+      this.deselect();
+    } else {
+      this.writeAsErrorComment(error);
+    }
+
     return [selection, error, result];
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context. The resulting object is opened up in the Property Panel
    * for inspection.
    */
   inspect: function SP_inspect()
   {
-    let [selection, error, result] = this.run();
+    let [selection, error, result] = this.execute();
 
     if (!error) {
+      this.deselect();
       this.openPropertyPanel(selection, result);
+    } else {
+      this.writeAsErrorComment(error);
     }
   },
 
   /**
    * Execute the selected text (if any) or the entire editor content in the
    * current context. The evaluation result is inserted into the editor after
    * the selected text, or at the end of the editor content if there is no
    * selected text.
    */
   display: function SP_display()
   {
+    let [selectedText, error, result] = this.execute();
+
+    if (!error) {
+      this.writeAsComment(result);
+    } else {
+      this.writeAsErrorComment(error);
+    }
+  },
+
+  /**
+   * Write out a value at the current insertion point as a block comment
+   * @param object aValue
+   *        The Object to write out as a string
+   */
+  writeAsComment: function SP_writeAsComment(aValue)
+  {
     let selection = this.getSelectionRange();
     let insertionPoint = selection.start != selection.end ?
                          selection.end : // after selected text
                          this.editor.getCharCount(); // after text end
-
-    let [selectedText, error, result] = this.run();
-    if (error) {
-      return;
-    }
-
-    let newComment = "/*\n" + result + "\n*/";
-
+                         
+    let newComment = "/*\n" + aValue + "\n*/";
+    
     this.setText(newComment, insertionPoint, insertionPoint);
 
     // Select the new comment.
     this.selectRange(insertionPoint, insertionPoint + newComment.length);
   },
 
   /**
+   * Write out an error at the current insertion point as a block comment
+   * @param object aValue
+   *        The Error object to write out the message and stack trace
+   */
+  writeAsErrorComment: function SP_writeAsErrorComment(aError)
+  {
+    let newComment = "Exception: " + aError.message + "\n" + aError.stack.substring(0, aError.stack.length - 1);
+    
+    this.writeAsComment(newComment);
+  },
+
+  /**
    * Open the Property Panel to inspect the given object.
    *
    * @param string aEvalString
    *        The string that was evaluated. This is re-used when the user updates
    *        the properties list, by clicking the Update button.
    * @param object aOutputObject
    *        The object to inspect, which is the aEvalString evaluation result.
    * @return object
--- a/browser/devtools/scratchpad/test/Makefile.in
+++ b/browser/devtools/scratchpad/test/Makefile.in
@@ -56,11 +56,12 @@ include $(topsrcdir)/config/rules.mk
 		browser_scratchpad_open.js \
 		browser_scratchpad_restore.js \
 		browser_scratchpad_bug_679467_falsy.js \
 		browser_scratchpad_bug_699130_edit_ui_updates.js \
 		browser_scratchpad_bug_669612_unsaved.js \
 		head.js \
 		browser_scratchpad_bug_653427_confirm_close.js \
 		browser_scratchpad_bug684546_reset_undo.js \
+		browser_scratchpad_bug690552_display_outputs_errors.js \
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug690552_display_outputs_errors.js
@@ -0,0 +1,53 @@
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function test()
+{
+  waitForExplicitFinish();
+
+  gBrowser.selectedTab = gBrowser.addTab();
+  gBrowser.selectedBrowser.addEventListener("load", function browserLoad() {
+    gBrowser.selectedBrowser.removeEventListener("load", browserLoad, true);
+    openScratchpad(runTests, {"state":{"text":""}});
+  }, true);
+
+  content.location = "data:text/html,<p>test that exceptions our output as " +
+      "comments for 'display' and not sent to the console in Scratchpad";
+}
+
+function runTests()
+{
+  scratchpad = gScratchpadWindow.Scratchpad;
+
+  var message = "\"Hello World!\""
+  var openComment = "/*\n";
+  var closeComment = "\n*/";
+  var error = "throw new Error(\"Ouch!\")";
+  let messageArray = {};
+  let count = {};
+
+  scratchpad.setText(message);
+  scratchpad.display();
+  is(scratchpad.getText(),
+      message + openComment + "Hello World!" + closeComment,
+      "message display output");
+
+  scratchpad.setText(error);
+  scratchpad.display();
+  is(scratchpad.getText(), 
+      error + openComment + "Exception: Ouch!\n@Scratchpad:1" + closeComment,
+      "error display output");
+
+  scratchpad.setText(message);
+  scratchpad.run();
+  is(scratchpad.getText(), message, "message run output");
+
+  scratchpad.setText(error);
+  scratchpad.run();
+  is(scratchpad.getText(), 
+      error + openComment + "Exception: Ouch!\n@Scratchpad:1" + closeComment,
+      "error display output");
+
+  finish();
+}
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -1357,16 +1357,21 @@ function HUD_SERVICE()
    * Response headers for requests that haven't finished yet.
    */
   this.openResponseHeaders = {};
 };
 
 HUD_SERVICE.prototype =
 {
   /**
+   * Last value entered
+   */
+  lastInputValue: "",
+
+  /**
    * L10N shortcut function
    *
    * @param string aName
    * @returns string
    */
   getStr: function HS_getStr(aName)
   {
     return stringBundle.GetStringFromName(aName);
--- a/toolkit/mozapps/extensions/content/extensions.js
+++ b/toolkit/mozapps/extensions/content/extensions.js
@@ -3287,18 +3287,18 @@ var gDragDrop = {
 
     var pos = 0;
     var installs = [];
 
     function buildNextInstall() {
       if (pos == urls.length) {
         if (installs.length > 0) {
           // Display the normal install confirmation for the installs
-          AddonManager.installAddonsFromWebpage("application/x-xpinstall", this,
-                                                null, installs);
+          AddonManager.installAddonsFromWebpage("application/x-xpinstall",
+                                                window, null, installs);
         }
         return;
       }
 
       AddonManager.getInstallForURL(urls[pos++], function(aInstall) {
         installs.push(aInstall);
         buildNextInstall();
       }, "application/x-xpinstall");
--- a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
+++ b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js
@@ -70,16 +70,27 @@ WindowOpenListener.prototype = {
     this.domwindow = null;
 
     // Let the window close complete
     executeSoon(this.closecallback);
     this.closecallback = null;
   }
 };
 
+var gSawInstallNotification = false;
+var gInstallNotificationObserver = {
+  observe: function(aSubject, aTopic, aData) {
+    var installInfo = aSubject.QueryInterface(Ci.amIWebInstallInfo);
+    isnot(installInfo.originatingWindow, null, "Notification should have non-null originatingWindow");
+    gSawInstallNotification = true;
+    Services.obs.removeObserver(this, "addon-install-started");
+  }
+};
+
+
 function test() {
   waitForExplicitFinish();
 
   open_manager("addons://list/extension", function(aWindow) {
     gManagerWindow = aWindow;
     run_next_test();
   });
 }
@@ -108,84 +119,114 @@ function test_confirmation(aWindow, aExp
 
   aWindow.document.documentElement.cancelDialog();
 }
 
 // Simulates dropping a URL onto the manager
 add_test(function() {
   var url = TESTROOT + "addons/browser_dragdrop1.xpi";
 
+  Services.obs.addObserver(gInstallNotificationObserver,
+                           "addon-install-started", false);
+
   new WindowOpenListener(INSTALL_URI, function(aWindow) {
     test_confirmation(aWindow, [url]);
-  }, run_next_test);
+  }, function() {
+    is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
+    run_next_test();
+  });
 
   var viewContainer = gManagerWindow.document.getElementById("view-port");
   var effect = chromeUtils.synthesizeDrop(viewContainer, viewContainer,
                [[{type: "text/x-moz-url", data: url}]],
                "copy", gManagerWindow, EventUtils);
   is(effect, "copy", "Drag should be accepted");
 });
 
 // Simulates dropping a file onto the manager
 add_test(function() {
   var fileurl = get_addon_file_url("browser_dragdrop1.xpi");
 
+  Services.obs.addObserver(gInstallNotificationObserver,
+                           "addon-install-started", false);
+
   new WindowOpenListener(INSTALL_URI, function(aWindow) {
     test_confirmation(aWindow, [fileurl.spec]);
-  }, run_next_test);
+  }, function() {
+    is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
+    run_next_test();
+  });
 
   var viewContainer = gManagerWindow.document.getElementById("view-port");
   var effect = chromeUtils.synthesizeDrop(viewContainer, viewContainer,
                [[{type: "application/x-moz-file", data: fileurl.file}]],
                "copy", gManagerWindow, EventUtils);
   is(effect, "copy", "Drag should be accepted");
 });
 
 // Simulates dropping two urls onto the manager
 add_test(function() {
   var url1 = TESTROOT + "addons/browser_dragdrop1.xpi";
   var url2 = TESTROOT2 + "addons/browser_dragdrop2.xpi";
 
+  Services.obs.addObserver(gInstallNotificationObserver,
+                           "addon-install-started", false);
+
   new WindowOpenListener(INSTALL_URI, function(aWindow) {
     test_confirmation(aWindow, [url1, url2]);
-  }, run_next_test);
+  }, function() {
+    is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
+    run_next_test();
+  });
 
   var viewContainer = gManagerWindow.document.getElementById("view-port");
   var effect = chromeUtils.synthesizeDrop(viewContainer, viewContainer,
                [[{type: "text/x-moz-url", data: url1}],
                 [{type: "text/x-moz-url", data: url2}]],
                "copy", gManagerWindow, EventUtils);
   is(effect, "copy", "Drag should be accepted");
 });
 
 // Simulates dropping two files onto the manager
 add_test(function() {
   var fileurl1 = get_addon_file_url("browser_dragdrop1.xpi");
   var fileurl2 = get_addon_file_url("browser_dragdrop2.xpi");
 
+  Services.obs.addObserver(gInstallNotificationObserver,
+                           "addon-install-started", false);
+
   new WindowOpenListener(INSTALL_URI, function(aWindow) {
     test_confirmation(aWindow, [fileurl1.spec, fileurl2.spec]);
-  }, run_next_test);
+  }, function() {
+    is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
+    run_next_test();
+  });
 
   var viewContainer = gManagerWindow.document.getElementById("view-port");
   var effect = chromeUtils.synthesizeDrop(viewContainer, viewContainer,
                [[{type: "application/x-moz-file", data: fileurl1.file}],
                 [{type: "application/x-moz-file", data: fileurl2.file}]],
                "copy", gManagerWindow, EventUtils);
   is(effect, "copy", "Drag should be accepted");
 });
 
 // Simulates dropping a file and a url onto the manager (weird, but should still work)
 add_test(function() {
   var url = TESTROOT + "addons/browser_dragdrop1.xpi";
   var fileurl = get_addon_file_url("browser_dragdrop2.xpi");
 
+  Services.obs.addObserver(gInstallNotificationObserver,
+                           "addon-install-started", false);
+
   new WindowOpenListener(INSTALL_URI, function(aWindow) {
     test_confirmation(aWindow, [url, fileurl.spec]);
-  }, run_next_test);
+  }, function() {
+    is(gSawInstallNotification, true, "Should have seen addon-install-started notification.");
+    run_next_test();
+  });
 
   var viewContainer = gManagerWindow.document.getElementById("view-port");
   var effect = chromeUtils.synthesizeDrop(viewContainer, viewContainer,
                [[{type: "text/x-moz-url", data: url}],
                 [{type: "application/x-moz-file", data: fileurl.file}]],
                "copy", gManagerWindow, EventUtils);
   is(effect, "copy", "Drag should be accepted");
 });