merge m-c to fx-team
authorTim Taubert <tim.taubert@gmx.de>
Wed, 13 Jun 2012 15:34:08 +0200
changeset 96560 bdbed29aaaa600b8a43ba1038f1a4366a75b27da
parent 96556 efbb6480e98e01786ed6d6b96b6ffaa5dda00151 (current diff)
parent 96559 cfe3d2e340405e3f8ac719126454a1d272717239 (diff)
child 96561 a36acb51ca855f170850ed1666f98e4492cf17a4
child 96568 10d9e7c6fac1167aa52b7c6896b66f938795eae3
child 96595 ffc7f6a20da6d29ba4fb642a25746afef2477b7e
push id22912
push usertim.taubert@gmx.de
push dateWed, 13 Jun 2012 13:37:46 +0000
treeherdermozilla-central@bdbed29aaaa6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.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
--- a/browser/devtools/commandline/GcliCommands.jsm
+++ b/browser/devtools/commandline/GcliCommands.jsm
@@ -244,17 +244,17 @@ gcli.addCommand({
 });
 
 /**
  * 'edit' command
  */
 gcli.addCommand({
   name: "edit",
   description: gcli.lookup("editDesc"),
-  manual: gcli.lookup("editManual"),
+  manual: gcli.lookup("editManual2"),
   params: [
      {
        name: 'resource',
        type: {
          name: 'resource',
          include: 'text/css'
        },
        description: gcli.lookup("editResourceDesc")
--- a/browser/devtools/commandline/gcli.jsm
+++ b/browser/devtools/commandline/gcli.jsm
@@ -7915,53 +7915,57 @@ help.startup = function() {
 help.shutdown = function() {
   canon.removeCommand(helpCommandSpec);
 };
 
 /**
  * Create a block of data suitable to be passed to the help_list.html template
  */
 function getListTemplateData(args, context) {
+  var matchingCommands = canon.getCommands().filter(function(command) {
+    if (command.hidden) {
+      return false;
+    }
+
+    if (args.search && command.name.indexOf(args.search) !== 0) {
+      // Filtered out because they don't match the search
+      return false;
+    }
+    if (!args.search && command.name.indexOf(' ') != -1) {
+      // We don't show sub commands with plain 'help'
+      return false;
+    }
+    return true;
+  });
+  matchingCommands.sort();
+
+  var heading;
+  if (matchingCommands.length === 0) {
+    heading = l10n.lookupFormat('helpListNone', [ args.search ]);
+  }
+  else if (args.search == null) {
+    heading = l10n.lookup('helpListAll');
+  }
+  else {
+    heading = l10n.lookupFormat('helpListPrefix', [ args.search ]);
+  }
+
   return {
     l10n: l10n.propertyLookup,
     includeIntro: args.search == null,
+    matchingCommands: matchingCommands,
+    heading: heading,
 
     onclick: function(ev) {
       util.updateCommand(ev.currentTarget, context);
     },
 
     ondblclick: function(ev) {
       util.executeCommand(ev.currentTarget, context);
     },
-
-    getHeading: function() {
-      return args.search == null ?
-              'Available Commands:' :
-              'Commands starting with \'' + args.search + '\':';
-    },
-
-    getMatchingCommands: function() {
-      var matching = canon.getCommands().filter(function(command) {
-        if (command.hidden) {
-          return false;
-        }
-
-        if (args.search && command.name.indexOf(args.search) !== 0) {
-          // Filtered out because they don't match the search
-          return false;
-        }
-        if (!args.search && command.name.indexOf(' ') != -1) {
-          // We don't show sub commands with plain 'help'
-          return false;
-        }
-        return true;
-      });
-      matching.sort();
-      return matching;
-    }
   };
 }
 
 /**
  * Create a block of data suitable to be passed to the help_man.html template
  */
 function getManTemplateData(command, context) {
   var manTemplateData = {
@@ -7981,20 +7985,20 @@ function getManTemplateData(command, con
       var parent = element.ownerDocument.createElement('div');
       util.setContents(parent, text);
       return parent.childNodes;
     },
 
     getTypeDescription: function(param) {
       var input = '';
       if (param.defaultValue === undefined) {
-        input = 'required';
+        input = l10n.lookup('helpManRequired');
       }
       else if (param.defaultValue === null) {
-        input = 'optional';
+        input = l10n.lookup('helpManOptional');
       }
       else {
         input = param.defaultValue;
       }
       return '(' + param.type.name + ', ' + input + ')';
     }
   };
 
@@ -8061,20 +8065,20 @@ define("text!gcli/commands/help_man.html
   "    </ul>\n" +
   "  </div>\n" +
   "\n" +
   "</div>\n" +
   "");
 
 define("text!gcli/commands/help_list.html", [], "\n" +
   "<div>\n" +
-  "  <h3>${getHeading()}</h3>\n" +
+  "  <h3>${heading}</h3>\n" +
   "\n" +
   "  <table>\n" +
-  "    <tr foreach=\"command in ${getMatchingCommands()}\"\n" +
+  "    <tr foreach=\"command in ${matchingCommands}\"\n" +
   "        onclick=\"${onclick}\" ondblclick=\"${ondblclick}\">\n" +
   "      <th class=\"gcli-help-name\">${command.name}</th>\n" +
   "      <td class=\"gcli-help-arrow\">-</td>\n" +
   "      <td>\n" +
   "        ${command.description}\n" +
   "        <span class=\"gcli-out-shortcut\" data-command=\"help ${command.name}\">help ${command.name}</span>\n" +
   "      </td>\n" +
   "    </tr>\n" +
--- a/browser/devtools/commandline/test/browser_gcli_web.js
+++ b/browser/devtools/commandline/test/browser_gcli_web.js
@@ -2010,33 +2010,33 @@ define('gclitest/testHelp', ['require', 
           /Get help/
         ]
       });
     }
 
     helpers.exec(options, {
       typed: 'help nomatch',
       args: { search: 'nomatch' },
-      outputMatch: /Commands starting with 'nomatch':$/
+      outputMatch: /No commands starting with 'nomatch'$/
     });
 
     helpers.exec(options, {
       typed: 'help help',
       args: { search: 'help' },
       outputMatch: [
         /Synopsis:/,
         /Provide help either/,
         /\(string, optional\)/
       ]
     });
 
     helpers.exec(options, {
       typed: 'help a b',
       args: { search: 'a b' },
-      outputMatch: /Commands starting with 'a b':$/
+      outputMatch: /No commands starting with 'a b'$/
     });
 
     helpers.exec(options, {
       typed: 'help hel',
       args: { search: 'hel' },
       outputMatch: [
         /Commands starting with 'hel':/,
         /Get help on the available commands/
--- a/browser/locales/en-US/chrome/browser/devtools/gcli.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gcli.properties
@@ -132,16 +132,38 @@ helpManDescription=Description
 # LOCALIZATION NOTE (helpManParameters): A heading shown above the parameters
 # in a help page for a command in the console.
 helpManParameters=Parameters
 
 # LOCALIZATION NOTE (helpManNone): Some text shown under the parameters
 # heading in a help page for a command which has no parameters.
 helpManNone=None
 
+# LOCALIZATION NOTE (helpListAll): The heading shown in response to the 'help'
+# command when used without a filter, just above the list of known commands.
+helpListAll=Available Commands:
+
+# LOCALIZATION NOTE (helpListPrefix): The heading shown in response to the
+# 'help <search>' command (i.e. with a search string), just above the list of
+# matching commands.
+helpListPrefix=Commands starting with '%1$S':
+
+# LOCALIZATION NOTE (helpListNone): The heading shown in response to the 'help
+# <search>' command (i.e. with a search string), when there are no matching
+# commands.
+helpListNone=No commands starting with '%1$S'
+
+# LOCALIZATION NOTE (helpManRequired): When the 'help x' command wants to show
+# the manual for the 'x' command it needs to be able to describe the
+# parameters as either required or optional. See also 'helpManOptional'.
+helpManRequired=required
+
+# LOCALIZATION NOTE (helpManOptional): See description of 'helpManRequired'
+helpManOptional=optional
+
 # LOCALIZATION NOTE (subCommands): Text shown as part of the output of the
 # 'help' command when the command in question has sub-commands, before a list
 # of the matching sub-commands
 subCommands=Sub-Commands
 
 # LOCALIZATION NOTE (subCommandsNone): Text shown as part of the output of the
 # 'help' command when the command in question should have sub-commands but in
 # fact has none
--- a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
@@ -309,24 +309,24 @@ breakNotFound=Breakpoint was not found
 consolecloseDesc=Close the console
 
 # LOCALIZATION NOTE (consoleopenDesc) A very short description of the
 # 'console open' command. This string is designed to be shown in a menu
 # alongside the command name, which is why it should be as short as possible.
 consoleopenDesc=Open the console
 
 # LOCALIZATION NOTE (editDesc) A very short description of the 'edit'
-# command. See editManual for a fuller description of what it does. This
+# command. See editManual2 for a fuller description of what it does. This
 # string is designed to be shown in a menu alongside the command name, which
 # is why it should be as short as possible.
 editDesc=Tweak a page resource
 
-# LOCALIZATION NOTE (editManual) A fuller description of the 'edit' command,
+# LOCALIZATION NOTE (editManual2) A fuller description of the 'edit' command,
 # displayed when the user asks for help on what it does.
-editManual=Edit one of the resources that is part of this page (or maybe any generic web resource?)
+editManual2=Edit one of the resources that is part of this page
 
 # LOCALIZATION NOTE (editResourceDesc) A very short string to describe the
 # 'resource' parameter to the 'edit' command, which is displayed in a dialog
 # when the user is using this command.
 editResourceDesc=URL to edit
 
 # LOCALIZATION NOTE (editLineToJumpToDesc) A very short string to describe the
 # 'line' parameter to the 'edit' command, which is displayed in a dialog
--- a/toolkit/devtools/debugger/server/dbg-script-actors.js
+++ b/toolkit/devtools/debugger/server/dbg-script-actors.js
@@ -391,17 +391,21 @@ ThreadActor.prototype = {
       line: line,
       column: location.column
     };
 
     return this._setBreakpoint(location);
   },
 
   /**
-   * Set a breakpoint using the jsdbg2 API.
+   * Set a breakpoint using the jsdbg2 API. If the line on which the breakpoint
+   * is being set contains no code, then the breakpoint will slide down to the
+   * next line that has runnable code. In this case the server breakpoint cache
+   * will be updated, so callers that iterate over the breakpoint cache should
+   * take that into account.
    *
    * @param object aLocation
    *        The location of the breakpoint as specified in the protocol.
    */
   _setBreakpoint: function TA__setBreakpoint(aLocation) {
     // Fetch the list of scripts in that url.
     let scripts = this._scripts[aLocation.url];
     // Fetch the specified script in that list.
@@ -415,26 +419,30 @@ ThreadActor.prototype = {
           continue;
         }
         script = scripts[i];
         break;
       }
     }
 
     let location = { url: aLocation.url, line: aLocation.line };
+    // Get the list of cached breakpoints in this URL.
+    let scriptBreakpoints = this._breakpointStore[location.url];
     let bpActor;
-    if (this._breakpointStore[location.url] &&
-        this._breakpointStore[location.url][location.line] &&
-        this._breakpointStore[location.url][location.line].actor) {
-      bpActor = this._breakpointStore[location.url][location.line].actor;
+    if (scriptBreakpoints &&
+        scriptBreakpoints[location.line] &&
+        scriptBreakpoints[location.line].actor) {
+      bpActor = scriptBreakpoints[location.line].actor;
     }
     if (!bpActor) {
       bpActor = new BreakpointActor(this, location);
       this._hooks.addToBreakpointPool(bpActor);
-      this._breakpointStore[location.url][location.line].actor = bpActor;
+      if (scriptBreakpoints[location.line]) {
+        scriptBreakpoints[location.line].actor = bpActor;
+      }
     }
 
     if (!script) {
       return { error: "noScript", actor: bpActor.actorID };
     }
 
     script = this._getInnermostContainer(script, aLocation.line);
     bpActor.addScript(script, this);
@@ -445,25 +453,33 @@ ThreadActor.prototype = {
       script.setBreakpoint(offsets[i], bpActor);
       codeFound = true;
     }
 
     let actualLocation;
     if (offsets.length == 0) {
       // No code at that line in any script, skipping forward.
       let lines = script.getAllOffsets();
-      for (let line = aLocation.line; line < lines.length; ++line) {
+      let oldLine = aLocation.line;
+      for (let line = oldLine; line < lines.length; ++line) {
         if (lines[line]) {
           for (let i = 0; i < lines[line].length; i++) {
             script.setBreakpoint(lines[line][i], bpActor);
             codeFound = true;
           }
-          actualLocation = aLocation;
-          actualLocation.line = line;
+          actualLocation = {
+            url: aLocation.url,
+            line: line,
+            column: aLocation.column
+          };
           bpActor.location = actualLocation;
+          // Update the cache as well.
+          scriptBreakpoints[line] = scriptBreakpoints[oldLine];
+          scriptBreakpoints[line].line = line;
+          delete scriptBreakpoints[oldLine];
           break;
         }
       }
     }
     if (!codeFound) {
       return  { error: "noCodeAtLineColumn", actor: bpActor.actorID };
     }
 
@@ -924,17 +940,20 @@ ThreadActor.prototype = {
     if (!this._scripts[aScript.url]) {
       this._scripts[aScript.url] = [];
     }
     this._scripts[aScript.url][aScript.startLine] = aScript;
 
     // Set any stored breakpoints.
     let existing = this._breakpointStore[aScript.url];
     if (existing) {
-      for (let bp of existing) {
+      // Iterate over the lines backwards, so that sliding breakpoints don't
+      // affect the loop.
+      for (let line = existing.length - 1; line >= 0; line--) {
+        let bp = existing[line];
         if (bp) {
           this._setBreakpoint(bp);
         }
       }
     }
   }
 
 };