Permalink
Browse files

Resolve conflicts

  • Loading branch information...
2 parents a03fa10 + c0653f4 commit 9eb4df34943ccda6da5ebcd2bbdf3ee34ea25000 @janodvarko janodvarko committed Aug 1, 2012
Showing with 11,519 additions and 2,180 deletions.
  1. +4 −0 .gitignore
  2. +17 −5 extension/bootstrap.js
  3. +1 −1 extension/build.js
  4. +1 −0 extension/build.xml
  5. +14 −11 extension/chrome.bz.tpl.manifest
  6. +1 −1 extension/chrome.manifest
  7. +8 −8 extension/content/firebug/accessible/a11y.js
  8. +2 −2 extension/content/firebug/branch.properties
  9. +2 −2 extension/content/firebug/bti/inProcess/browser.js
  10. +15 −6 extension/content/firebug/chrome/activation.js
  11. +101 −27 extension/content/firebug/chrome/chrome.js
  12. +10 −1 extension/content/firebug/chrome/firefox.js
  13. +3 −2 extension/content/firebug/chrome/knownIssues.js
  14. +1 −1 extension/content/firebug/chrome/menu.js
  15. +1 −0 extension/content/firebug/chrome/panelActivation.js
  16. +118 −56 extension/content/firebug/chrome/reps.js
  17. +10 −10 extension/content/firebug/chrome/shortcuts.js
  18. +1 −1 extension/content/firebug/chrome/tabContext.js
  19. +40 −12 extension/content/firebug/chrome/tabWatcher.js
  20. +321 −122 extension/content/firebug/console/autoCompleter.js
  21. +60 −43 extension/content/firebug/console/commandEditor.js
  22. +70 −20 extension/content/firebug/console/commandLine.js
  23. +58 −33 extension/content/firebug/console/commandLineExposed.js
  24. +162 −0 extension/content/firebug/console/commandLineHelp.js
  25. +3 −3 extension/content/firebug/console/commandLinePopup.js
  26. +5 −5 extension/content/firebug/console/console.js
  27. +5 −4 extension/content/firebug/console/consoleExposed.js
  28. +2 −2 extension/content/firebug/console/consoleInjector.js
  29. +39 −11 extension/content/firebug/console/consolePanel.js
  30. +18 −39 extension/content/firebug/console/errors.js
  31. +3 −3 extension/content/firebug/console/memoryProfiler.js
  32. +8 −9 extension/content/firebug/console/profiler.js
  33. +37 −0 extension/content/firebug/cookies/baseObserver.js
  34. +405 −0 extension/content/firebug/cookies/breakpoints.js
  35. +165 −0 extension/content/firebug/cookies/cookie.js
  36. +171 −0 extension/content/firebug/cookies/cookieClipboard.js
  37. +54 −0 extension/content/firebug/cookies/cookieEvents.js
  38. +1,378 −0 extension/content/firebug/cookies/cookieModule.js
  39. +438 −0 extension/content/firebug/cookies/cookieObserver.js
  40. +550 −0 extension/content/firebug/cookies/cookiePanel.js
  41. +150 −0 extension/content/firebug/cookies/cookiePanel.xul
  42. +229 −0 extension/content/firebug/cookies/cookiePermissions.js
  43. +1,353 −0 extension/content/firebug/cookies/cookieReps.js
  44. +134 −0 extension/content/firebug/cookies/cookieUtils.js
  45. +5 −0 extension/content/firebug/cookies/cookies.css
  46. +52 −0 extension/content/firebug/cookies/dateTimePicker.xml
  47. +11 −0 extension/content/firebug/cookies/editCookie.css
  48. +293 −0 extension/content/firebug/cookies/editCookie.js
  49. +75 −0 extension/content/firebug/cookies/editCookie.xul
  50. +230 −0 extension/content/firebug/cookies/headerResizer.js
  51. +270 −0 extension/content/firebug/cookies/httpObserver.js
  52. +85 −0 extension/content/firebug/cookies/legacy.js
  53. +72 −0 extension/content/firebug/cookies/menuUtils.js
  54. +47 −0 extension/content/firebug/cookies/popupFilterPanel.xml
  55. +90 −30 extension/content/firebug/css/computedPanel.js
  56. +72 −16 extension/content/firebug/css/cssModule.js
  57. +311 −110 extension/content/firebug/css/cssPanel.js
  58. +2 −1 extension/content/firebug/css/cssReps.js
  59. +134 −55 extension/content/firebug/css/stylePanel.js
  60. +23 −12 extension/content/firebug/dom/domBreakpointGroup.js
  61. +33 −17 extension/content/firebug/dom/domPanel.js
  62. +62 −10 extension/content/firebug/editor/editor.js
  63. +3 −4 extension/content/firebug/editor/editorSelector.js
  64. +16 −1 extension/content/firebug/firebug.css
  65. +148 −71 extension/content/firebug/firebug.js
  66. +33 −27 extension/content/firebug/firebugOverlay.xul
  67. +27 −6 extension/content/firebug/firefox/bindings.xml
  68. +37 −5 extension/content/firebug/firefox/browserOverlay.css
  69. +340 −228 extension/content/firebug/firefox/browserOverlay.js
  70. +0 −20 extension/content/firebug/firefox/external-editors/editorsOverlay.xul
  71. +52 −27 extension/content/firebug/firefox/external-editors/externalEditors.js
  72. +1 −0 extension/content/firebug/firefox/firebug.xul
  73. +4 −4 extension/content/firebug/firefox/firebugFrame.xul
  74. +0 −61 extension/content/firebug/firefox/firebugMenu.js
  75. +89 −90 extension/content/firebug/firefox/firebugMenuOverlay.xul
  76. +94 −45 extension/content/firebug/firefox/start-button/startButtonOverlay.js
  77. +159 −0 extension/content/firebug/html/highlighterCache.js
  78. +226 −96 extension/content/firebug/html/htmlPanel.js
  79. +9 −8 extension/content/firebug/html/insideOutBox.js
  80. +45 −155 extension/content/firebug/html/inspector.js
  81. +0 −10 extension/content/firebug/html/layout.js
  82. +157 −17 extension/content/firebug/js/breakpoint.js
  83. +16 −12 extension/content/firebug/js/callstack.js
  84. +103 −40 extension/content/firebug/js/debugger.js
  85. +20 −20 extension/content/firebug/js/scriptPanel.js
  86. +2 −2 extension/content/firebug/js/sourceBox.js
  87. +3 −3 extension/content/firebug/js/sourceCache.js
  88. +8 −4 extension/content/firebug/js/sourceFile.js
  89. +8 −8 extension/content/firebug/js/stackFrame.js
  90. +11 −9 extension/content/firebug/js/tabCache.js
  91. +9 −3 extension/content/firebug/js/watchPanel.js
  92. +43 −18 extension/content/firebug/lib/array.js
  93. +610 −257 extension/content/firebug/lib/css.js
  94. +2 −2 extension/content/firebug/lib/deprecated.js
  95. +87 −19 extension/content/firebug/lib/dom.js
  96. +2 −2 extension/content/firebug/lib/domplate.js
  97. +1 −1 extension/content/firebug/lib/events.js
  98. +2 −2 extension/content/firebug/lib/http.js
  99. +2 −2 extension/content/firebug/lib/locale.js
  100. +5 −2 extension/content/firebug/lib/object.js
  101. +29 −7 extension/content/firebug/lib/options.js
  102. +85 −93 extension/content/firebug/lib/string.js
  103. +3 −11 extension/content/firebug/lib/xml.js
  104. +50 −9 extension/content/firebug/lib/xpath.js
  105. +3 −6 extension/content/firebug/main.js
  106. +5 −4 extension/content/firebug/moduleConfig.js
  107. +23 −13 extension/content/firebug/net/netDebugger.js
  108. +3 −1 extension/content/firebug/net/netMonitor.js
  109. +48 −4 extension/content/firebug/net/netPanel.js
  110. +8 −4 extension/content/firebug/net/netProgress.js
  111. +50 −12 extension/content/firebug/net/netReps.js
  112. +4 −1 extension/content/firebug/net/requestObserver.js
  113. +76 −28 extension/content/firebug/net/spy.js
  114. +21 −0 extension/defaults/preferences/cookies.js
  115. +164 −0 extension/defaults/preferences/firebug.js
  116. +69 −0 extension/defaults/preferences/tracingConsole.js
  117. +14 −5 extension/install.rdf
  118. +16 −7 extension/install.rdf.tpl.xml
  119. +43 −0 extension/locale/ca-AD/cookies.properties
  120. +126 −0 extension/locale/cs/cookies.properties
  121. +267 −0 extension/locale/de/cookies.properties
  122. +3 −3 extension/locale/de/firebug-amo.properties
Sorry, we could not display the entire diff because too many files (558) changed.
View
4 .gitignore
@@ -4,6 +4,7 @@
*.swp
*.tmp
.*.gz
+*.patch
# Temporary files created by Eclipse
.tmp*
@@ -19,10 +20,13 @@
# Build Files
/extension/build/
/extension/release/
+/tests/FBTest/release/
*.graphml
+/extension/bz-locale/
# Files from NPM
/extension/node_modules/
# Extensions
/extension/firebug@software.joehewitt.com
+
View
22 extension/bootstrap.js
@@ -3,7 +3,9 @@
// ********************************************************************************************* //
// Constants
-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
// List of firebug modules that must be loaded at startup and unloaded on shutdown.
// !important every new module loaded with Cu.import must be added here
@@ -13,9 +15,12 @@ var FIREBUG_MODULES = [
"resource://firebug/firebug-http-observer.js",
"resource://firebug/firebug-service.js",
"resource://firebug/firebug-trace-service.js",
+ "resource://firebug/gcli.js",
"resource://firebug/loader.js",
"resource://firebug/locale.js",
+ "resource://firebug/mini-require.js",
"resource://firebug/observer-service.js",
+ "resource://firebug/prefLoader.js",
"resource://firebug/require-debug.js",
"resource://firebug/require.js",
"resource://firebug/storageService.js"
@@ -45,12 +50,16 @@ function startup(params, reason)
// Add our chrome registration. not needed for 10+
Components.manager.addBootstrappedManifestLocation(params.installPath);
+ Cu.import("resource://firebug/prefLoader.js");
+
+ // Register default preferences
+ PrefLoader.loadDefaultPrefs(params.installPath, "firebug.js");
+ PrefLoader.loadDefaultPrefs(params.installPath, "cookies.js");
+ PrefLoader.loadDefaultPrefs(params.installPath, "tracingConsole.js");
+
// Load the overlay manager
Cu.import("resource://firebug/loader.js");
- // register default values
- FirebugLoader.registerDefaultPrefs();
-
//register extensions
FirebugLoader.startup();
@@ -61,6 +70,9 @@ function startup(params, reason)
// Listen for new windows, Firebug must be loaded into them too.
Services.ww.registerNotification(windowWatcher);
+
+ // GCLI commands
+ Cu.import("resource://firebug/gcli.js");
}
function shutdown(params, reason)
@@ -89,7 +101,7 @@ function shutdown(params, reason)
fbs.shutdown();
// remove default preferences
- FirebugLoader.clearDefaultPrefs();
+ PrefLoader.clearDefaultPrefs();
// Unload all Firebug modules added with Cu.import
FIREBUG_MODULES.forEach(Cu.unload, Cu);
View
2 extension/build.js
@@ -146,7 +146,7 @@ function prepareBuild()
"firebug/firefox/external-editors/externalEditors",
"firebug/firefox/firebugMenu",
"firebug/chrome/panelActivation",
- "firebug/console/memoryProfiler",
+ //"firebug/console/memoryProfiler", xxxHonza: removed from 1.10 (issue 5599)
"firebug/chrome/tableRep",
"firebug/html/htmlPanel",
"firebug/console/commandLinePopup",
View
1 extension/build.xml
@@ -134,6 +134,7 @@
<include name="**/*.dtd"/>
<include name="**/*.png"/>
<include name="**/*.gif"/>
+ <include name="**/*.svg"/>
<include name="**/*.ico"/>
<include name="**/*.manifest"/>
<include name="**/*.txt"/>
View
25 extension/chrome.bz.tpl.manifest
@@ -2,10 +2,10 @@ content firebug content/firebug/
content firebug content/firebug/ contentaccessible=yes
# Maps resource://firebug/* to files in modules/*
-resource firebug modules/
+# resource firebug modules/
# Maps resource://moduleloader/* to files in modules/*
-resource moduleloader modules/
+# resource moduleloader modules/
skin firebug classic/1.0 skin/classic/
skin firebug-os classic/1.0 skin/classic/win/
@@ -58,21 +58,24 @@ locale firebug sl-SI locale/sl-SI/
locale firebug sr locale/sr/
locale firebug sv-SE locale/sv-SE/
locale firebug te-IN locale/te-IN/
-locale firebug tr-TR locale/tr-TR/
+locale firebug tr locale/tr/
locale firebug uk-UA locale/uk-UA/
locale firebug vi locale/vi/
locale firebug zh-CN locale/zh-CN/
locale firebug zh-TW locale/zh-TW/
-overlay chrome://browser/content/browser.xul chrome://firebug/content/browserOverlay.xul
+#overlay chrome://browser/content/browser.xul chrome://firebug/content/browserOverlay.xul
#overlay chrome://browser/content/browser.xul chrome://firebug/content/firefox/browserOverlayWithFrame.xul
-overlay chrome://global/content/customizeToolbar.xul chrome://firebug/content/firefox/start-button/customizeToolbarOverlay.xul
-overlay chrome://mozapps/content/extensions/about.xul chrome://firebug/content/firefox/aboutOverlay.xul
-overlay chrome://navigator/content/navigator.xul chrome://firebug/content/browserOverlay.xul
+#overlay chrome://global/content/customizeToolbar.xul chrome://firebug/content/firefox/start-button/customizeToolbarOverlay.xul
+#overlay chrome://mozapps/content/extensions/about.xul chrome://firebug/content/firefox/aboutOverlay.xul
+
+# Sea Monkey
+#overlay chrome://navigator/content/navigator.xul chrome://firebug/content/browserOverlay.xul
+#overlay chrome://navigator/content/navigator.xul chrome://firebug/content/firefox/browserOverlayWithFrame.xul
# Support for Mac
-override chrome://firebug/skin/debugger.css chrome://firebug/skin/mac/debugger.css os=Darwin
-override chrome://firebug-os/skin/firebug.css chrome://firebug/skin/mac/firebug.css os=Darwin
-override chrome://firebug-os/skin/panel.css chrome://firebug/skin/mac/panel.css os=Darwin
-override chrome://firebug-os/skin/window.css chrome://firebug/skin/mac/window.css os=Darwin
+override chrome://firebug/skin/debugger.css chrome://firebug/skin/mac/debugger.css os=Darwin
+override chrome://firebug-os/skin/firebug.css chrome://firebug/skin/mac/firebug.css os=Darwin
+override chrome://firebug-os/skin/panel.css chrome://firebug/skin/mac/panel.css os=Darwin
+override chrome://firebug-os/skin/window.css chrome://firebug/skin/mac/window.css os=Darwin
View
2 extension/chrome.manifest
@@ -40,7 +40,7 @@ locale firebug sk-SK locale/sk-SK/
locale firebug sl-SI locale/sl-SI/
locale firebug sr locale/sr/
locale firebug sv-SE locale/sv-SE/
-locale firebug tr-TR locale/tr-TR/
+locale firebug tr locale/tr/
locale firebug uk-UA locale/uk-UA/
locale firebug vi locale/vi/
locale firebug zh-CN locale/zh-CN/
View
16 extension/content/firebug/accessible/a11y.js
@@ -132,7 +132,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
//manage all key events in toolbox (including tablists)
tmpElem = chrome.$("fbContentBox");
if (tmpElem)
- Events.addEventListener(tmpElem, "keypress", this.handlePanelBarKeyPress , true);
+ Events.addEventListener(tmpElem, "keypress", this.handlePanelBarKeyPress, true);
//make focus stick to inspect button when clicked
tmpElem = chrome.$("fbInspectButton");
@@ -175,7 +175,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
tmpElem = chrome.$("fbPanelBar1");
if (tmpElem)
- Events.removeEventListener(tmpElem, "keypress", this.handlePanelBarKeyPress , true);
+ Events.removeEventListener(tmpElem, "keypress", this.handlePanelBarKeyPress, true);
tmpElem = chrome.$("fbInspectButton");
if (tmpElem)
@@ -828,7 +828,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
{
if (Css.hasClass(row, "opened"))
{
- this.focusSiblingRow(panel, target , false);
+ this.focusSiblingRow(panel, target, false);
}
else if (toggleElem)
{
@@ -2241,7 +2241,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
box.a11yCaretOffset = offset = 0;
}
var startNode = node.getElementsByClassName("sourceRowText").item(0)
- if (startNode && startNode.firstChild && startNode.firstChild.nodeType == 3)
+ if (startNode && startNode.firstChild && startNode.firstChild.nodeType == Node.TEXT_NODE)
{
startNode = startNode.firstChild;
if (offset >= startNode.length)
@@ -2948,7 +2948,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
isVisibleByStyle: function (elem)
{
- if (!elem || elem.nodeType != 1)
+ if (!elem || elem.nodeType != Node.ELEMENT_NODE)
return false;
var style = elem.ownerDocument.defaultView.getComputedStyle(elem, null);
return style.visibility !== "hidden" && style.display !== "none";
@@ -3027,7 +3027,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
return null;
function criteria(node) {
- return node.nodeType == 1 && Css.hasClass(node, className);
+ return node.nodeType == Node.ELEMENT_NODE && Css.hasClass(node, className);
}
for (var sib = node.previousSibling; sib; sib = sib.previousSibling)
@@ -3062,7 +3062,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
return null;
function criteria(node) {
- return node.nodeType == 1 && Css.hasClass(node, className);
+ return node.nodeType == Node.ELEMENT_NODE && Css.hasClass(node, className);
}
if (!upOnly)
@@ -3135,4 +3135,4 @@ Firebug.registerModule(Firebug.A11yModel);
return Firebug.A11yModel;
// ************************************************************************************************
-});
+});
View
4 extension/content/firebug/branch.properties
@@ -1,6 +1,6 @@
# DO NOT MERGE INTO TRUNK
-RELEASE=.0a8
-VERSION=1.10
+RELEASE=.0a0
+VERSION=1.11
TRUNK=
# To allow build.xml to drop the xpi directly into the svn working copy for getfirebug.com
# the root of the fbug svn tree must be be at the same level as the root of getfirebug.com
View
4 extension/content/firebug/bti/inProcess/browser.js
@@ -460,8 +460,8 @@ Browser.prototype.disconnect = function()
this.removeListener(Firebug);
TabWatcher.destroy();
- // Remove the listener after the Firebug.TabWatcher.destroy() method is called so,
- // destroyContext event is properly dispatched to the Firebug object and
+ // Remove the listener after the Firebug.TabWatcher.destroy() method is called, so
+ // that the destroyContext event is properly dispatched to the Firebug object and
// consequently to all registered modules.
TabWatcher.removeListener(this);
View
21 extension/content/firebug/chrome/activation.js
@@ -89,7 +89,7 @@ Firebug.Activation = Obj.extend(Firebug.Module,
" for "+uri.spec+" in "+browser.contentWindow.location +
" using activateSameOrigin: "+Firebug.activateSameOrigin);
- // Annotated so, return the value.
+ // Annotated, so return the value.
if (hasAnnotation)
return this.checkAnnotation(browser, uri);
@@ -165,8 +165,16 @@ Firebug.Activation = Obj.extend(Firebug.Module,
// Firebug is opened in browser
watchBrowser: function(browser)
{
- var annotation = "firebugged.showFirebug";
- this.setPageAnnotation(browser.currentURI.spec, annotation);
+ try
+ {
+ var annotation = "firebugged.showFirebug";
+ this.setPageAnnotation(browser.currentURI.spec, annotation);
+ }
+ catch (e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("activation.watchBrowser; EXCEPTION " + e, e);
+ }
},
// Firebug closes in browser
@@ -221,12 +229,13 @@ Firebug.Activation = Obj.extend(Firebug.Module,
var host = shortURI.host;
if (host)
{
- // Slice the subdomain (if any) from the URL so, activateSameOrigin works for
- // domains (including TLD domains). So we want:
+ // Slice the subdomain (if any) from the URL so that activateSameOrigin works
+ // for domains (including TLD domains). So we want:
// 1) www.google.com -> google.com
// 2) www.stuff.co.nz -> stuff.co.nz
// 3) getfirebug.com -> getfirebug.com
- // 4) xxxHonza: what about: mail.cn.mozilla.com -> mozilla.com ?
+ // (XXX: This makes a.co.uk -> co.uk and mail.cn.mozilla.com -> cn.mozilla.com,
+ // which is wrong. See issue 2202.)
var levels = host.split('.');
if (levels.length > 2)
levels = levels.slice(1);
View
128 extension/content/firebug/chrome/chrome.js
@@ -17,9 +17,10 @@ define([
"firebug/lib/events",
"firebug/js/fbs",
"firebug/chrome/window",
+ "firebug/lib/options"
],
function chromeFactory(Obj, Firefox, Dom, Css, System, Menu, Toolbar, Url, Locale, String,
- Events, FBS, Win) {
+ Events, FBS, Win, Options) {
// ********************************************************************************************* //
// Constants
@@ -38,6 +39,21 @@ const LOAD_FLAGS_NONE = nsIWebNavigation.LOAD_FLAGS_NONE;
const panelURL = "chrome://firebug/content/panel.html";
+// URLs used in the Firebug Menu and several other places
+const firebugURLs =
+{
+ main: "https://getfirebug.com",
+ help: "https://getfirebug.com/help",
+ FAQ: "https://getfirebug.com/wiki/index.php/FAQ",
+ docs: "https://getfirebug.com/docs.html",
+ keyboard: "https://getfirebug.com/wiki/index.php/Keyboard_and_Mouse_Shortcuts",
+ discuss: "https://groups.google.com/forum/#!forum/firebug",
+ issues: "http://code.google.com/p/fbug/issues/list?can=1",
+ donate: "https://getfirebug.com/getinvolved",
+ extensions: "https://getfirebug.com/wiki/index.php/Firebug_Extensions",
+ issue5110: "http://code.google.com/p/fbug/issues/detail?id=5110"
+};
+
const statusCropSize = 20;
// ********************************************************************************************* //
@@ -74,6 +90,7 @@ var FirebugChrome =
*/
initialize: function()
{
+
if (FBTrace.DBG_INITIALIZE)
FBTrace.sysout("chrome.initialize;");
@@ -293,6 +310,21 @@ var FirebugChrome =
FBTrace.sysout("chrome.shutdown; Done for " + win.location);
},
+ /**
+ * Checking first window in back order, (Most recent window). is itself firebug ?
+ */
+ hasFocus: function()
+ {
+ try
+ {
+ return (wm.getMostRecentWindow(null).location.href.indexOf("firebug.xul") > 0);
+ }
+ catch(ex)
+ {
+ return false;
+ }
+ },
+
appendStylesheet: function(uri)
{
var cmdPopupBrowser = this.getElementById("fbCommandPopupBrowser");
@@ -319,8 +351,12 @@ var FirebugChrome =
if (name == "textSize")
this.applyTextSize(value);
- if (name =="omitObjectPathStack")
+
+ if (name == "omitObjectPathStack")
this.obeyOmitObjectPathStack(value);
+
+ if (name == "viewPanelOrient")
+ this.updateOrient(value);
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -625,7 +661,9 @@ var FirebugChrome =
" sidePanelName:"+sidePanelName+" forceUpdate:"+forceUpdate+"\n");
var bestPanelName = getBestPanelName(object, Firebug.currentContext, panelName);
- var panel = this.selectPanel(bestPanelName, sidePanelName, true);
+
+ // Allow refresh if needed (the last argument).
+ var panel = this.selectPanel(bestPanelName, sidePanelName/*, true*/);
if (panel)
panel.select(object, forceUpdate);
@@ -1023,14 +1061,24 @@ var FirebugChrome =
toggleOrient: function(preferredValue)
{
+ var value = Options.get("viewPanelOrient");
+ if (value == preferredValue)
+ return;
+
+ Options.togglePref("viewPanelOrient");
+ },
+
+ updateOrient: function(value)
+ {
var panelPane = FirebugChrome.$("fbPanelPane");
- if(panelPane.orient == preferredValue)
+ if (!panelPane)
+ return;
+
+ var newOrient = value ? "vertical" : "horizontal";
+ if (panelPane.orient == newOrient)
return;
- var newValue = panelPane.orient == "vertical" ? "horizontal" : "vertical";
- panelSplitter.orient = panelPane.orient = newValue;
- var option = FirebugChrome.$("menu_toggleOrient").getAttribute("option");
- Firebug.Options.set(option, newValue == "vertical");
+ panelSplitter.orient = panelPane.orient = newOrient;
},
setPosition: function(pos)
@@ -1356,14 +1404,14 @@ var FirebugChrome =
onMenuShowing: function(popup)
{
- var detachFirebug = Dom.getElementsByAttribute(popup, "id", "menu_detachFirebug")[0];
+ var detachFirebug = Dom.getElementsByAttribute(popup, "id", "menu_firebug_detachFirebug")[0];
if (detachFirebug)
{
detachFirebug.setAttribute("label", (Firebug.isDetached() ?
Locale.$STR("firebug.AttachFirebug") : Locale.$STR("firebug.DetachFirebug")));
}
- var toggleFirebug = Dom.getElementsByAttribute(popup, "id", "menu_toggleFirebug")[0];
+ var toggleFirebug = Dom.getElementsByAttribute(popup, "id", "menu_firebug_toggleFirebug")[0];
if (toggleFirebug)
{
var fbContentBox = FirebugChrome.$("fbContentBox");
@@ -1439,7 +1487,7 @@ var FirebugChrome =
// selected in the panel.
var sel = target.ownerDocument.defaultView.getSelection();
if (!this.contextMenuObject &&
- !FirebugChrome.$("cmd_copy").getAttribute("disabled") &&
+ !FirebugChrome.$("cmd_copy").getAttribute("disabled") &&
!sel.isCollapsed)
{
var menuitem = Menu.createMenuItem(popup, {label: "Copy"});
@@ -1632,7 +1680,7 @@ var FirebugChrome =
try
{
// Firefox 4.0+ implements a new AddonManager. In case of Firefox 3.6 the module
- // is not avaialble and there is an exception.
+ // is not available and there is an exception.
Components.utils["import"]("resource://gre/modules/AddonManager.jsm");
}
catch (err)
@@ -1661,7 +1709,7 @@ var FirebugChrome =
breakOnNext: function(context, event)
{
// Avoid bubbling from associated options.
- if (event.target.id != "cmd_toggleBreakOn")
+ if (event.target.id != "cmd_firebug_toggleBreakOn")
return;
if (!context)
@@ -1682,6 +1730,20 @@ var FirebugChrome =
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ visitWebsite: function(which, arg)
+ {
+ var url = firebugURLs[which];
+ if (url)
+ {
+ if (arg)
+ url += arg;
+
+ Win.openNewTab(url);
+ }
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main Toolbar
appendToolbarButton: function(button, before)
@@ -1727,7 +1789,7 @@ function getBestPanelName(object, context, panelName)
if (!panelName && context)
panelName = context.panelName;
- // Check, if the panel type of the suggested panel supports the object, and if so, go with it
+ // Check if the panel type of the suggested panel supports the object, and if so, go with it
if (panelName)
{
var panelType = Firebug.getPanelType(panelName);
@@ -1842,6 +1904,7 @@ function onBlur(event)
// XXXhh Is this really necessary? I disabled it for now as this was preventing me
// to show highlights on focus
//Firebug.Inspector.highlightObject(null, Firebug.currentContext);
+
}
function onSelectLocation(event)
@@ -2005,19 +2068,6 @@ function onPanelClick(event)
}
}
}
- else if (Events.isControlClick(event) || Events.isMiddleClick(event))
- {
- if (!realRep || !realRep.browseObject(realObject, Firebug.currentContext))
- {
- if (rep && !(rep != realRep && rep.browseObject(object, Firebug.currentContext)))
- {
- var panel = Firebug.getElementPanel(event.target);
- if (!panel || !panel.browseObject(realObject))
- return;
- }
- }
- Events.cancelEvent(event);
- }
}
}
@@ -2087,6 +2137,30 @@ function onPanelMouseUp(event)
}
}
}
+ else if (Events.isControlClick(event) || Events.isMiddleClick(event))
+ {
+ var repNode = Firebug.getRepNode(event.target);
+ if (!repNode)
+ return;
+
+ var object = repNode.repObject;
+ var rep = Firebug.getRep(object, Firebug.currentContext);
+ var realObject = rep ? rep.getRealObject(object, Firebug.currentContext) : null;
+ var realRep = realObject ? Firebug.getRep(realObject, Firebug.currentContext) : rep;
+ if (!realObject)
+ realObject = object;
+
+ if (!realRep || !realRep.browseObject(realObject, Firebug.currentContext))
+ {
+ if (rep && !(rep != realRep && rep.browseObject(object, Firebug.currentContext)))
+ {
+ var panel = Firebug.getElementPanel(event.target);
+ if (!panel || !panel.browseObject(realObject))
+ return;
+ }
+ }
+ Events.cancelEvent(event);
+ }
}
function onMainTabBoxMouseDown(event)
View
11 extension/content/firebug/chrome/firefox.js
@@ -16,7 +16,16 @@ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMe
function getBrowserDocument()
{
// TODO: this function is called very frequently, worth optimizing
- return Firebug.chrome.inDetachedScope ? Firebug.chrome.originalBrowser.ownerDocument : top.document;
+ try
+ {
+ var chrome = Firebug.chrome;
+ return chrome.inDetachedScope ? chrome.originalBrowser.ownerDocument : top.document;
+ }
+ catch (e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("firefox.getBrowserDocument; EXCEPTION " + e, e);
+ }
}
// ********************************************************************************************* //
View
5 extension/content/firebug/chrome/knownIssues.js
@@ -62,12 +62,13 @@ Firebug.KnownIssues = Obj.extend(Firebug.Module,
{
// See also issue 4529. Since the memory profiler is still a lab thing,
// hide the "Memory Profiler" button begin a pref.
- if (!Options.get("memoryProfilerEnable"))
+ // xxxHonza: removed from 1.10 (issue 5599)
+ /*if (!Options.get("memoryProfilerEnable"))
{
var button = doc.getElementById("fbToggleMemoryProfiling");
if (button)
Dom.collapse(button, true);
- }
+ }*/
}
});
View
2 extension/content/firebug/chrome/menu.js
@@ -147,7 +147,7 @@ Menu.optionMenu = function(label, option, tooltiptext)
option: option,
tooltiptext: tooltiptext,
command: function() {
- return Options.set(option, !Firebug[option]);
+ return Options.togglePref(option);
}
};
};
View
1 extension/content/firebug/chrome/panelActivation.js
@@ -208,6 +208,7 @@ Firebug.PanelActivation = Obj.extend(Firebug.Module,
panelType.prototype.onActivationChanged(enable);
+ Firebug.chrome.$("fbPanelBar1").updateTab(panelType);
Firebug.chrome.syncPanel();
},
View
174 extension/content/firebug/chrome/reps.js
@@ -465,6 +465,49 @@ FirebugReps.Obj = domplate(Firebug.Rep,
});
// ********************************************************************************************* //
+// Reference
+
+/**
+ * A placeholder used instead of cycle reference within arrays.
+ * @param {Object} target The original referenced object
+ */
+FirebugReps.ReferenceObj = function(target)
+{
+ this.target = target;
+}
+
+/**
+ * Rep for cycle reference in an array.
+ */
+FirebugReps.Reference = domplate(Firebug.Rep,
+{
+ tag:
+ OBJECTLINK({_repObject: "$object"},
+ SPAN({title: "$object|getTooltip"},
+ "[...]")
+ ),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ className: "Reference",
+
+ supportsObject: function(object, type)
+ {
+ return (object instanceof FirebugReps.ReferenceObj);
+ },
+
+ getTooltip: function(object)
+ {
+ return Locale.$STR("firebug.reps.reference");
+ },
+
+ getRealObject: function(object)
+ {
+ return object.target;
+ },
+});
+
+// ********************************************************************************************* //
FirebugReps.Arr = domplate(Firebug.Rep,
{
@@ -513,12 +556,16 @@ FirebugReps.Arr = domplate(Firebug.Rep,
{
var delim = (i == array.length-1 ? "" : ", ");
var value = array[i];
+
+ // Cycle detected
+ if (value === array)
+ value = new FirebugReps.ReferenceObj(value);
+
var rep = Firebug.getRep(value);
var tag = rep.shortTag || rep.tag;
-
items.push({object: value, tag: tag, delim: delim});
}
- catch(exc)
+ catch (exc)
{
var rep = Firebug.getRep(exc);
var tag = rep.shortTag || rep.tag;
@@ -1054,7 +1101,12 @@ FirebugReps.Element = domplate(Firebug.Rep,
getTooltip: function(elt)
{
- return this.getXPath(elt) + " (" + elt.namespaceURI+")";
+ var tooltip = this.getXPath(elt);
+
+ if (elt.namespaceURI)
+ tooltip += " (" + elt.namespaceURI + ")";
+
+ return tooltip;
},
getContextMenuItems: function(elt, target, context)
@@ -2278,7 +2330,7 @@ FirebugReps.ErrorMessage = domplate(Firebug.Rep,
if (Firebug.A11yModel.enabled)
{
var panel = Firebug.getElementPanel(event.target);
- Events.dispatch(panel.fbListeners, "modifyLogRow", [panel , traceBox]);
+ Events.dispatch(panel.fbListeners, "modifyLogRow", [panel, traceBox]);
}
}
else
@@ -2608,7 +2660,8 @@ FirebugReps.Storage = domplate(Firebug.Rep,
summarize: function(storage)
{
- return Locale.$STRP("firebug.storage.totalItems", [storage.length]);
+ var object = this.objectView(storage);
+ return Locale.$STRP("firebug.storage.totalItems", [Object.keys(object).length]);
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -2633,67 +2686,75 @@ FirebugReps.Storage = domplate(Firebug.Rep,
return this.propIterator(object, Options.get("ObjectShortIteratorMax"));
},
- propIterator: function(object, max)
+ propIterator: function(storage, max)
{
- // we can't utilize the existing function due to:
- // https://bugzilla.mozilla.org/show_bug.cgi?id=573875
- //return FirebugReps.Obj.propIterator(object, max);
-
- max = max || 3;
- if (!object)
- return [];
+ var object = this.objectView(storage);
+ return FirebugReps.Obj.propIterator(object, max);
+ },
- var props = [];
- var len = 0, count = 0;
+ objectView: function(storage)
+ {
+ var object = this.makeObject(storage);
+ for (var any in object)
+ return object;
- try
- {
- for (var i=0; i<object.length; i++)
+ // We might have hit upon an https site (bug 709238).
+ // As a hack, we'll check if the current context's window
+ // contains the object as localStorage or sessionStorage.
+ try {
+ var context = Firebug.currentContext;
+ var win = context && context.window;
+ if (win && win.location.protocol === "https:")
{
- var value;
- var name;
- try
+ var names = ["localStorage", "sessionStorage"], done = false;
+ for (var i = 0; i < 2; ++i)
{
- name = object.key(i);
- value = object.getItem(name);
- if (value instanceof window.StorageItem)
- value = value.value;
- }
- catch (exc)
- {
- continue;
+ if (win[names[i]] !== storage)
+ continue;
+ Firebug.CommandLine.evaluate(
+ "((" + this.makeObject + ")(" + names[i] + "))",
+ context,
+ null, null,
+ function(result) {
+ object = result;
+ done = true;
+ },
+ function() {},
+ true
+ );
+ if (done)
+ break;
}
-
- var rep = Firebug.getRep(value);
- var tag = rep.shortTag || rep.tag;
-
- count++;
- if (count <= max)
- props.push({tag: tag, name: name, object: value, equal: "=", delim: ", "});
- else
- break;
}
+ }
+ catch(e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("reps.Storage.objectView; EXCEPTION " + e, e);
+ }
- if (count > max)
- {
- props[Math.max(1,max-1)] = {
- object: Locale.$STR("firebug.reps.more") + "...",
- tag: FirebugReps.Caption.tag,
- name: "",
- equal:"",
- delim:""
- };
- }
- else if (props.length > 0)
+ return object;
+ },
+
+ makeObject: function(storage)
+ {
+ // Create a raw object, free from getItem etc., from a storage.
+ // May be serialized and run in page scope.
+ var object = {};
+ try
+ {
+ for (var name in storage)
{
- props[props.length-1].delim = '';
+ var value = storage.getItem(name);
+ Object.defineProperty(object, name, {value: value, enumerable: true});
}
}
- catch (exc)
+ catch(e)
{
+ // We can't log an error in page scope.
}
- return props;
- },
+ return object;
+ }
});
// ********************************************************************************************* //
@@ -3026,8 +3087,8 @@ FirebugReps.NamedNodeMap = domplate(Firebug.Rep,
for (var i=0; i<object.length && i<max; i++)
{
var item = object.item(i);
- var name = item.nodeName;
- var value = item.nodeValue;
+ var name = item.name;
+ var value = item.value;
var rep = Firebug.getRep(value);
var tag = rep.tag;
@@ -3149,7 +3210,8 @@ Firebug.registerRep(
FirebugReps.StorageList,
FirebugReps.Attr,
FirebugReps.Date,
- FirebugReps.NamedNodeMap
+ FirebugReps.NamedNodeMap,
+ FirebugReps.Reference
);
Firebug.setDefaultReps(FirebugReps.Func, FirebugReps.Obj);
View
20 extension/content/firebug/chrome/shortcuts.js
@@ -61,16 +61,16 @@ Firebug.ShortcutsModel = Obj.extend(Firebug.Module,
var shortcut = branch.getCharPref("shortcut." + element);
var tokens = shortcut.split(" ");
var key = tokens.pop();
- var modifiers = tokens.join(",")
+ var modifiers = tokens.join(",");
- var keyElem = document.getElementById("key_" + element);
+ var keyElem = document.getElementById("key_firebug_" + element);
if (!keyElem)
{
// If key is not defined in xul, add it
keyElem = document.createElement("key");
keyElem.className = "fbOnlyKey";
- keyElem.id = "key_"+element;
- keyElem.command = "cmd_"+element;
+ keyElem.id = "key_firebug_" + element;
+ keyElem.command = "cmd_firebug_" + element;
document.getElementById("mainKeyset").appendChild(keyElem);
}
@@ -101,8 +101,7 @@ Firebug.ShortcutsModel = Obj.extend(Firebug.Module,
this.keysets.push(keyElem.parentNode);
// Modify shortcut for global key, if it exists
- var keyElem = Firefox.getElementById("key_" + element);
-
+ var keyElem = Firefox.getElementById("key_firebug_" + element);
if (!keyElem)
return;
@@ -113,10 +112,11 @@ Firebug.ShortcutsModel = Obj.extend(Firebug.Module,
}
// Disable existing global shortcuts
- var selector = "key["+attr+"='"+key+"'][modifiers='"+modifiers+"']"
- + ":not([id='key_"+element+"']):not([disabled='true'])";
+ var selector = "key[" + attr + "='" + key + "'][modifiers='" + modifiers + "']"
+ + ":not([id='key_firebug_" + element + "']):not([disabled='true'])";
+
var existingKeyElements = keyElem.ownerDocument.querySelectorAll(selector);
- for (var i = existingKeyElements.length - 1; i >= 0; i--)
+ for (var i=existingKeyElements.length-1; i>=0; i--)
{
var existingKeyElement = existingKeyElements[i];
existingKeyElement.setAttribute("disabled", "true");
@@ -139,7 +139,7 @@ Firebug.ShortcutsModel = Obj.extend(Firebug.Module,
FBTrace: FBTrace
};
- // Open customize shortcuts dialog. Pass FBL into the XUL window so,
+ // Open the "customize shortcuts" dialog. Pass FBL into the XUL window so that
// common APIs can be used (e.g. localization).
window.openDialog("chrome://firebug/content/firefox/customizeShortcuts.xul", "",
"chrome,centerscreen,dialog,modal,resizable=yes", args);
View
2 extension/content/firebug/chrome/tabContext.js
@@ -38,7 +38,7 @@ Firebug.TabContext = function(win, browser, chrome, persistedState)
this.sourceFileByTag = {}; // mozilla only
// New nsITraceableChannel interface (introduced in FF3.0.4) makes possible
- // to re-implement source-cache so, it solves the double-load problem.
+ // to re-implement source-cache so that it solves the double-load problem.
// Anyway, keep the previous cache implementation for backward compatibility
// (with Firefox 3.0.3 and lower)
if (Components.interfaces.nsITraceableChannel)
View
52 extension/content/firebug/chrome/tabWatcher.js
@@ -167,7 +167,16 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
return; // did not create a context
}
- // else we should show
+
+ // Special case for about:blank (see issue 5120)
+ // HTML panel's edit mode can cause onStateChange changes and context
+ // recreation.
+ if (context.loaded && context == Firebug.currentContext &&
+ context.getName() == "about:blank")
+ {
+ FBTrace.sysout("tabWatcher.watchTopWindow; page already watched");
+ return;
+ }
}
else // then we've not looked this window in this session
{
@@ -191,7 +200,7 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
if (win instanceof Ci.nsIDOMWindow && win.parent == win && context)
{
- // xxxHonza: This place can be called multiple times for one window so,
+ // xxxHonza: This place can be called multiple times for one window, so
// make sure event listeners are not registered twice.
// There should be a better way to find out whether the listeneres are actually
// registered for the window.
@@ -330,7 +339,7 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
}
if (FBTrace.DBG_ACTIVATION)
- FBTrace.sysout("-> shouldCreateContext FBLISTENERS" , this.fbListeners);
+ FBTrace.sysout("-> shouldCreateContext FBLISTENERS", this.fbListeners);
// Create if any listener says true to showCreateContext
if (Events.dispatch2(this.fbListeners, "shouldCreateContext",
@@ -433,7 +442,7 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
/**
* Attaches to a window that may be either top-level or a frame within the page.
*/
- watchWindow: function(win, context)
+ watchWindow: function(win, context, skipCompletedDocuments)
{
if (!context)
context = this.getContextByWindow(Win.getRootWindow(win));
@@ -445,6 +454,21 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
if (context)
TabWatcherUnloader.registerWindow(win);
+ try
+ {
+ // If the documents is already completed do not register the window
+ // it should be registered already at this point
+ // This condition avoids situation when "about:document-onload-blocker"
+ // and STATE_START is fired for a window, which is consequently never
+ // firing "unload" and so, stays registered within context.windows
+ // See issue 5582 (comment #4)
+ if (skipCompletedDocuments && win.document.readyState == "complete")
+ return;
+ }
+ catch (err)
+ {
+ }
+
// Unfortunately, dummy requests that trigger the call to watchWindow
// are called several times, so we have to avoid dispatching watchWindow
// more than once
@@ -453,8 +477,11 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
context.windows.push(win);
if (FBTrace.DBG_WINDOWS)
- FBTrace.sysout("-> watchWindow register *** FRAME *** to context for " +
- "win.location: " + location);
+ {
+ FBTrace.sysout("-> tabWatcher.watchWindow; " + Win.safeGetWindowLocation(win) +
+ " [" + Win.getWindowId(win).toString() + "] " + context.windows.length +
+ " - " + win.document.readyState);
+ }
Events.dispatch(this.fbListeners, "watchWindow", [context, win]);
@@ -509,7 +536,7 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
{
if (FBTrace.DBG_ERRORS)
{
- FBTrace.sysout("unwatchWindow: no context for win " +
+ FBTrace.sysout("unwatchWindow: ERROR no context for win " +
Win.safeGetWindowLocation(win));
}
return;
@@ -518,8 +545,9 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
var index = context.windows.indexOf(win);
if (FBTrace.DBG_WINDOWS)
{
- FBTrace.sysout("-> tabWatcher.unwatchWindow context: " + context.getName() +
- " index of win: " + index + "/" + context.windows.length, context.windows);
+ FBTrace.sysout("-> tabWatcher.unwatchWindow; " + Win.safeGetWindowLocation(win) +
+ " [" + Win.getWindowId(win).toString() + "] " + context.windows.length +
+ " - " + win.document.readyState);
}
if (index != -1)
@@ -890,7 +918,7 @@ var FrameProgressListener = Obj.extend(Http.BaseProgressListener,
FBTrace.sysout("-> FrameProgressListener.onStateChanged for: " +
Http.safeGetRequestName(request) + ", win: " + win.location.href +
", content URL: " + (win.document ? win.document.URL : "no content URL") +
- " " + Http.getStateDescription(flag));
+ " " + Http.getStateDescription(flag) + ", " + status);
}
if (flag & STATE_IS_REQUEST && flag & STATE_START)
@@ -914,7 +942,7 @@ var FrameProgressListener = Obj.extend(Http.BaseProgressListener,
}
else
{
- Firebug.TabWatcher.watchWindow(win);
+ Firebug.TabWatcher.watchWindow(win, null, true);
}
}
}
@@ -1030,7 +1058,7 @@ var TabWatcherHttpObserver = Obj.extend(Object,
if (win == win.parent)
{
- // Make sure the frame listener is registered for top level window so,
+ // Make sure the frame listener is registered for top level window, so
// we can get all onStateChange events and init context for all opened tabs.
var browser = Firebug.TabWatcher.getBrowserByWindow(win);
View
443 extension/content/firebug/console/autoCompleter.js
@@ -21,6 +21,8 @@ function(Obj, Firebug, Domplate, FirebugReps, Locale, Events, Wrapper, Dom, Str,
const Cc = Components.classes;
const Ci = Components.interfaces;
+const kwActions = ["throw", "return", "in", "instanceof", "delete", "new",
+ "typeof", "void", "yield"];
const reOpenBracket = /[\[\(\{]/;
const reCloseBracket = /[\]\)\}]/;
const reJSChar = /[a-zA-Z0-9$_]/;
@@ -31,10 +33,14 @@ const reLiteralExpr = /^[ "0-9,]*$/;
Firebug.JSAutoCompleter = function(textBox, completionBox, options)
{
+ var popupSize = 40;
+
this.textBox = textBox;
- this.completionBox = completionBox;
this.options = options;
+ this.completionBox = completionBox;
+ this.popupTop = this.popupBottom = null;
+
this.completionBase = {
pre: null,
expr: null,
@@ -77,7 +83,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
};
this.completions = null;
- this.showCompletions();
+ this.showCompletions(false);
};
/**
@@ -90,7 +96,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionBase.candidates = [];
this.completions = null;
- this.showCompletions();
+ this.showCompletions(false);
};
/**
@@ -102,7 +108,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
if (!this.completions)
return true;
- if (this.getCompletionBoxValue() === this.textBox.value)
+ if (this.getCompletionValue() === this.textBox.value)
{
// The user wouldn't see a difference if we completed. This can
// happen for example if you type 'alert' and press enter,
@@ -121,7 +127,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
{
this.revertValue = null;
this.createCandidates(context);
- this.showCompletions();
+ this.showCompletions(false);
};
/**
@@ -174,6 +180,8 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
FBTrace.sysout("Completing: " + this.completionBase.pre + sep + preExpr + sep + prop);
}
+ var prevCompletions = this.completions;
+
// We only need to calculate a new candidate list if the expression has
// changed (we can ignore this.completionBase.pre since completions do not
// depend upon that).
@@ -182,42 +190,79 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionBase.expr = preExpr;
this.completionBase.candidates = autoCompleteEval(context, preExpr, spreExpr,
this.options.includeCurrentScope);
+ prevCompletions = null;
}
- this.createCompletions(prop);
+ this.createCompletions(prop, prevCompletions);
};
/**
* From a valid completion base, create a list of completions (containing
- * those completion candidates that share a prefix with the user's input)
- * and a default completion.
+ * those completion candidates that share a (sometimes case-insensitive)
+ * prefix with the user's input) and a default completion. The completions
+ * for the previous expression (null if none) are used to help with the
+ * latter.
*/
- this.createCompletions = function(prefix)
+ this.createCompletions = function(prefix, prevCompletions)
{
var candidates = this.completionBase.candidates;
- var valid = [];
+ var valid = [], ciValid = [];
if (!this.completionBase.expr && !prefix)
{
// Don't complete "".
+ this.completions = null;
+ return;
}
- else
+
+ var lowPrefix = prefix.toLowerCase();
+ for (var i = 0; i < candidates.length; ++i)
{
- for (var i = 0; i < candidates.length; ++i)
+ // Mark a candidate as matching if it matches the prefix case-
+ // insensitively, and shares its upper-case characters.
+ var name = candidates[i];
+ if (!Str.hasPrefix(name.toLowerCase(), lowPrefix))
+ continue;
+
+ var fail = false;
+ for (var j = 0; j < prefix.length; ++j)
{
- var name = candidates[i];
+ var ch = prefix.charAt(j);
+ if (ch !== ch.toLowerCase() && ch !== name.charAt(j))
+ {
+ fail = true;
+ break;
+ }
+ }
+ if (!fail)
+ {
+ ciValid.push(name);
if (Str.hasPrefix(name, prefix))
valid.push(name);
}
}
- if (valid.length > 0)
+ if (ciValid.length > 0)
{
+ // If possible, default to a candidate matching the case by picking
+ // a default from 'valid' and correcting its index.
+ var hasMatchingCase = (valid.length > 0);
+
this.completions = {
- list: valid,
+ list: (hasMatchingCase ? valid : ciValid),
prefix: prefix
};
- this.pickDefaultCandidate();
+ this.completions.index = this.pickDefaultCandidate(prevCompletions);
+
+ if (hasMatchingCase)
+ {
+ var find = valid[this.completions.index];
+ this.completions = {
+ list: ciValid,
+ prefix: prefix,
+ index: ciValid.indexOf(find)
+ };
+ }
}
else
{
@@ -226,34 +271,71 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
};
/**
- * Chose a default candidate from the list of completions. This is currently
- * selected as the shortest completion, to make completions disappear when
- * typing a variable name that is also the prefix of another.
+ * Choose a default candidate from the list of completions. The first of all
+ * shortest completions is current used for this, except in some very hacky,
+ * but useful, special cases (issue 5593).
*/
- this.pickDefaultCandidate = function()
+ this.pickDefaultCandidate = function(prevCompletions)
{
- var pick = 0;
- var ar = this.completions.list;
- for (var i = 1; i < ar.length; i++)
+ var list = this.completions.list, ind;
+
+ // If the typed expression is an extension of the previous completion, keep it.
+ if (prevCompletions && Str.hasPrefix(this.completions.prefix, prevCompletions.prefix))
+ {
+ var lastCompletion = prevCompletions.list[prevCompletions.index];
+ ind = list.indexOf(lastCompletion);
+ if (ind !== -1)
+ return ind;
+ }
+
+ // Special-case certain expressions.
+ var special = {
+ "": ["document", "console", "window", "parseInt", "undefined"],
+ "window.": ["console"],
+ "location.": ["href"],
+ "document.": ["getElementById", "addEventListener", "createElement",
+ "documentElement"]
+ };
+ if (special.hasOwnProperty(this.completionBase.expr))
+ {
+ var ar = special[this.completionBase.expr];
+ for (var i = 0; i < ar.length; ++i)
+ {
+ var prop = ar[i];
+ if (Str.hasPrefix(prop, this.completions.prefix))
+ {
+ // Use 'prop' as a completion, if it exists.
+ ind = list.indexOf(prop);
+ if (ind !== -1)
+ return ind;
+ }
+ }
+ }
+
+ ind = 0;
+ for (var i = 1; i < list.length; ++i)
{
- if (ar[i].length < ar[pick].length)
- pick = i;
+ if (list[i].length < list[ind].length)
+ ind = i;
}
- this.completions.index = pick;
+ return ind;
};
/**
- * Go backward or forward one step in the list of completions.
- * dir is the relative movement in the list; -1 means backward and 1 forward.
+ * Go backward or forward by some number of steps in the list of completions.
+ * dir is the relative movement in the list (negative for backwards movement).
*/
- this.cycle = function(dir)
+ this.cycle = function(dir, clamp)
{
- this.completions.index += dir;
- if (this.completions.index >= this.completions.list.length)
- this.completions.index = 0;
- else if (this.completions.index < 0)
- this.completions.index = this.completions.list.length - 1;
- this.showCompletions();
+ var ind = this.completions.index + dir;
+ if (clamp)
+ ind = Math.max(Math.min(ind, this.completions.list.length - 1), 0);
+ else if (ind >= this.completions.list.length)
+ ind = 0;
+ else if (ind < 0)
+ ind = this.completions.list.length - 1;
+ this.completions.index = ind;
+ this.showCompletions(true);
};
/**
@@ -282,21 +364,24 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
var completion = this.getCurrentCompletion();
if (completion === null)
return "";
- return this.completionBase.pre + this.completionBase.expr + completion;
+ var userTyped = this.textBox.value;
+ var value = this.completionBase.pre + this.completionBase.expr + completion;
+ return userTyped + value.substr(userTyped.length);
};
/**
* Update the completion box and popup to be consistent with the current
- * state of the auto-completer.
+ * state of the auto-completer. If just cycling, the old scolling state
+ * for the popup is preserved.
*/
- this.showCompletions = function()
+ this.showCompletions = function(cycling)
{
this.completionBox.value = this.getCompletionBoxValue();
var show = this.showCompletionPopup ||
(this.completionPopup && this.completionPopup.state === "open");
if (show && this.completions && this.completions.list.length > 1)
- this.popupCandidates();
+ this.popupCandidates(cycling);
else
this.closePopup();
};
@@ -369,11 +454,32 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
}
}
}
- else if (event.keyCode === KeyEvent.DOM_VK_UP || event.keyCode === KeyEvent.DOM_VK_DOWN)
+ else if (event.keyCode === KeyEvent.DOM_VK_UP ||
+ event.keyCode === KeyEvent.DOM_VK_DOWN)
+ {
+ if (this.completions)
+ {
+ this.cycle(event.keyCode === KeyEvent.DOM_VK_UP ? -1 : 1, false);
+ Events.cancelEvent(event);
+ return true;
+ }
+ }
+ else if (event.keyCode === KeyEvent.DOM_VK_PAGE_UP ||
+ event.keyCode === KeyEvent.DOM_VK_PAGE_DOWN)
{
if (this.completions)
{
- this.cycle((event.keyCode === KeyEvent.DOM_VK_UP ? -1 : 1));
+ this.pageCycle(event.keyCode === KeyEvent.DOM_VK_PAGE_UP ? -1 : 1);
+ Events.cancelEvent(event);
+ return true;
+ }
+ }
+ else if (event.keyCode === KeyEvent.DOM_VK_HOME ||
+ event.keyCode === KeyEvent.DOM_VK_END)
+ {
+ if (this.isPopupOpen())
+ {
+ this.topCycle(event.keyCode === KeyEvent.DOM_VK_HOME ? -1 : 1);
Events.cancelEvent(event);
return true;
}
@@ -405,7 +511,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.complete(context);
}
if (this.completionPopup && this.completions)
- this.popupCandidates();
+ this.popupCandidates(false);
}
};
@@ -429,14 +535,44 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
};
/**
- * Accept the currently shown completion in the text box.
+ * Get what should be completed to; this is only vaguely related to what is
+ * shown in the completion box.
*/
- this.acceptCompletion = function()
+ this.getCompletionValue = function()
{
- var completion = this.getCurrentCompletion();
- completion = adjustCompletionOnAccept(this.completionBase.pre,
- this.completionBase.expr, completion);
+ var property = this.getCurrentCompletion();
+ var preParsed = this.completionBase.pre, preExpr = this.completionBase.expr;
+ var res = preParsed + preExpr + property;
+ // Don't adjust index completions.
+ if (/^\[['"]$/.test(preExpr.slice(-2)))
+ return res;
+
+ if (!isValidProperty(property))
+ {
+ // The property name is actually invalid in free form, so replace
+ // it with array syntax.
+
+ if (preExpr)
+ {
+ res = preParsed + preExpr.slice(0, -1);
+ }
+ else
+ {
+ // Global variable access - assume the variable is a member of 'window'.
+ res = preParsed + "window";
+ }
+ res += '["' + Str.escapeJS(property) + '"]';
+ }
+ return res;
+ };
+
+ /**
+ * Accept the current completion into the text box.
+ */
+ this.acceptCompletion = function()
+ {
+ var completion = this.getCompletionValue();
var originalValue = this.textBox.value;
this.textBox.value = completion;
setCursorToEOL(this.textBox);
@@ -445,10 +581,61 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.revertValue = originalValue;
};
- this.popupCandidates = function()
+ this.pageCycle = function(dir)
+ {
+ var list = this.completions.list, selIndex = this.completions.index;
+
+ if (!this.isPopupOpen())
+ {
+ // When no popup is open, cycle by a fixed amount and stop at edges.
+ this.cycle(dir * 15, true);
+ return;
+ }
+
+ var top = this.popupTop, bottom = this.popupBottom;
+ if (top === 0 && bottom === list.length)
+ {
+ // For a single scroll page, act like home/end.
+ this.topCycle(dir);
+ return;
+ }
+
+ var immediateTarget;
+ if (dir === -1)
+ immediateTarget = (top === 0 ? top : top + 2);
+ else
+ immediateTarget = (bottom === list.length ? bottom: bottom - 2) - 1;
+ if ((selIndex - immediateTarget) * dir < 0)
+ {
+ // The selection has not yet reached the edge target, so jump to it.
+ selIndex = immediateTarget;
+ }
+ else
+ {
+ // Show the next page.
+ if (dir === -1 && top - popupSize <= 0)
+ selIndex = 0;
+ else if (dir === 1 && bottom + popupSize >= list.length)
+ selIndex = list.length - 1;
+ else
+ selIndex = immediateTarget + dir*popupSize;
+ }
+
+ this.completions.index = selIndex;
+ this.showCompletions(true);
+ };
+
+ this.topCycle = function(dir)
{
- var commandCompletionLineLimit = 40;
+ if (dir === -1)
+ this.completions.index = 0;
+ else
+ this.completions.index = this.completions.list.length - 1;
+ this.showCompletions(true);
+ };
+ this.popupCandidates = function(cycling)
+ {
Dom.eraseNode(this.completionPopup);
this.selectedPopupElement = null;
@@ -462,47 +649,75 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
title.classList.add("fbPopupTitle");
vbox.appendChild(title);
- var escPrefix = Str.escapeForTextNode(this.textBox.value);
+ var list = this.completions.list, selIndex = this.completions.index;
- var showTop = 0;
- var showBottom = this.completions.list.length;
- if (this.completions.list.length > commandCompletionLineLimit)
+ if (this.completions.list.length <= popupSize)
{
- if (this.completions.index <= (commandCompletionLineLimit - 3))
+ this.popupTop = 0;
+ this.popupBottom = list.length;
+ }
+ else
+ {
+ var self = this;
+ var setTop = function(val)
+ {
+ if (val < 0)
+ val = 0;
+ self.popupTop = val;
+ self.popupBottom = val + popupSize;
+ if (self.popupBottom > list.length)
+ setBottom(list.length);
+ };
+ var setBottom = function(val)
+ {
+ if (val > list.length)
+ val = list.length;
+ self.popupBottom = val;
+ self.popupTop = val - popupSize;
+ if (self.popupTop < 0)
+ setTop(0);
+ };
+
+ if (!cycling)
{
- // We are in the top part of the list.
- showBottom = commandCompletionLineLimit;
+ // Show the selection at nearly the bottom of the popup, where
+ // it is more local.
+ setBottom(selIndex + 3);
}
else
{
- // Implement manual scrolling.
- if (this.completions.index > (this.completions.list.length - 3))
- showBottom = this.completions.list.length;
- else
- showBottom = this.completions.index + 3;
+ // Scroll the popup such that selIndex fits.
+ if (selIndex - 2 < this.popupTop)
+ setTop(selIndex - 2);
+ else if (selIndex + 3 > this.popupBottom)
+ setBottom(selIndex + 3);
}
-
- showTop = showBottom - commandCompletionLineLimit;
}
- for (var i = showTop; i < showBottom; i++)
+ for (var i = this.popupTop; i < this.popupBottom; i++)
{
+ var completion = list[i];
+ var prefixLen = this.completions.prefix.length;
+
var hbox = this.completionPopup.ownerDocument.
createElementNS("http://www.w3.org/1999/xhtml","div");
hbox.completionIndex = i;
var pre = this.completionPopup.ownerDocument.
createElementNS("http://www.w3.org/1999/xhtml","span");
- pre.innerHTML = escPrefix;
+ var preText = this.textBox.value;
+ if (prefixLen)
+ preText = preText.slice(0, -prefixLen) + completion.slice(0, prefixLen);
+ pre.innerHTML = Str.escapeForTextNode(preText);
pre.classList.add("userTypedText");
- var completion = this.completions.list[i].substr(this.completions.prefix.length);
var post = this.completionPopup.ownerDocument.
createElementNS("http://www.w3.org/1999/xhtml","span");
- post.innerHTML = Str.escapeForTextNode(completion);
+ var postText = completion.substr(prefixLen);
+ post.innerHTML = Str.escapeForTextNode(postText);
post.classList.add("completionText");
- if (i === this.completions.index)
+ if (i === selIndex)
this.selectedPopupElement = hbox;
hbox.appendChild(pre);
@@ -516,9 +731,14 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionPopup.openPopup(this.textBox, "before_start", 0, 0, false, false);
};
+ this.isPopupOpen = function()
+ {
+ return (this.completionPopup && this.completionPopup.state !== "closed");
+ };
+
this.closePopup = function()
{
- if (!this.completionPopup || this.completionPopup.state === "closed")
+ if (!this.isPopupOpen())
return;
try
@@ -556,6 +776,15 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionBox.value = this.getCompletionBoxValue();
};
+ this.popupScroll = function(event)
+ {
+ if (event.axis !== event.VERTICAL_AXIS)
+ return;
+ if (!this.getCompletionPopupElementFromEvent(event))
+ return;
+ this.cycle(event.detail, true);
+ };
+
this.popupClick = function(event)
{
var el = this.getCompletionPopupElementFromEvent(event);
@@ -567,6 +796,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
};
this.popupMousedown = Obj.bind(this.popupMousedown, this);
+ this.popupScroll = Obj.bind(this.popupScroll, this);
this.popupClick = Obj.bind(this.popupClick, this);
/**
@@ -579,13 +809,15 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
if (this.completionPopup)
{
Events.removeEventListener(this.completionPopup, "mousedown", this.popupMousedown, true);
+ Events.removeEventListener(this.completionPopup, "DOMMouseScroll", this.popupScroll, true);
Events.removeEventListener(this.completionPopup, "click", this.popupClick, true);
}
};
if (this.completionPopup)
{
Events.addEventListener(this.completionPopup, "mousedown", this.popupMousedown, true);
+ Events.addEventListener(this.completionPopup, "DOMMouseScroll", this.popupScroll, true);
Events.addEventListener(this.completionPopup, "click", this.popupClick, true);
}
};
@@ -779,11 +1011,17 @@ function prevWord(str, from)
return 0;
}
+/**
+ * Check if a position 'pos', marking the start of a property name, is
+ * preceded by a function-declaring keyword.
+ */
function isFunctionName(expr, pos)
{
- pos -= 9;
- return (pos >= 0 && expr.substr(pos, 9) === "function " &&
- (pos === 0 || !reJSChar.test(expr.charAt(pos-1))));
+ var ind = prevNonWs(expr, pos);
+ if (ind === -1 || !reJSChar.test(expr.charAt(ind)))
+ return false;
+ var word = expr.substring(prevWord(expr, ind), ind+1);
+ return (word === "function" || word === "get" || word === "set");
}
function bwFindMatchingParen(expr, from)
@@ -806,8 +1044,6 @@ function bwFindMatchingParen(expr, from)
*/
function endingDivIsRegex(expr)
{
- var kwActions = ["throw", "return", "in", "instanceof", "delete", "new",
- "do", "else", "typeof", "void", "yield"];
var kwCont = ["function", "if", "while", "for", "switch", "catch", "with"];
var ind = prevNonWs(expr, expr.length), ch = (ind === -1 ? "{" : expr.charAt(ind));
@@ -817,7 +1053,7 @@ function endingDivIsRegex(expr)
// If so, we have a regex, otherwise, we have a division (a variable
// or literal being divided by something).
var w = expr.substring(prevWord(expr, ind), ind+1);
- return (kwActions.indexOf(w) !== -1);
+ return (kwActions.indexOf(w) !== -1 || w === "do" || w === "else");
}
else if (ch === ")")
{