[Pkg-mozext-commits] [firebug] 01/16: Sync FBTrace and Firebug code base
David Prévot
taffit at moszumanska.debian.org
Mon Mar 31 22:45:30 UTC 2014
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to tag fbtest-1.11.1
in repository firebug.
commit df0c88febfa89367d82ba4bbc13ce31774f9548f
Author: Jan Odvarko <odvarko at gmail.com>
Date: Tue Dec 4 09:54:22 2012 +0100
Sync FBTrace and Firebug code base
---
.../chrome/firebug/content/accessible/a11y.js | 31 +-
.../chrome/firebug/content/branch.properties | 2 +-
.../firebug/content/bti/inProcess/browser.js | 89 +-
.../content/bti/inProcess/compilationunit.js | 9 +-
.../content/bti/inProcess/javascripttool.js | 21 +-
.../chrome/firebug/content/chrome/activation.js | 91 +-
.../chrome/firebug/content/chrome/annotations.js | 15 +-
.../chrome/firebug/content/chrome/chrome.js | 231 ++--
.../FBTrace/chrome/firebug/content/chrome/menu.js | 63 +-
.../firebug/content/chrome/panelActivation.js | 15 +-
.../FBTrace/chrome/firebug/content/chrome/reps.js | 629 ++++++----
.../chrome/firebug/content/chrome/tabContext.js | 4 +-
.../chrome/firebug/content/chrome/tabWatcher.js | 11 +-
.../chrome/firebug/content/chrome/tableRep.js | 13 +-
.../chrome/firebug/content/chrome/window.js | 10 +-
.../firebug/content/console/autoCompleter.js | 525 +++++---
.../firebug/content/console/commandEditor.js | 9 +-
.../firebug/content/console/commandHistory.js | 47 +-
.../chrome/firebug/content/console/commandLine.js | 269 ++---
.../firebug/content/console/commandLineExposed.js | 112 +-
.../firebug/content/console/commandLineHelp.js | 61 +-
.../firebug/content/console/commandLineInclude.js | 542 +++++++++
.../firebug/content/console/commandLinePopup.js | 2 +-
.../chrome/firebug/content/console/console.js | 27 +-
.../chrome/firebug/content/console/consolePanel.js | 51 +-
.../chrome/firebug/content/console/errors.js | 18 +-
.../chrome/firebug/content/console/eventMonitor.js | 83 +-
.../firebug/content/console/functionMonitor.js | 191 +++
.../firebug/content/console/performanceTiming.js | 630 ++++++++++
.../chrome/firebug/content/console/profiler.js | 30 +-
.../chrome/firebug/content/cookies/cookie.js | 13 +-
.../firebug/content/cookies/cookieClipboard.js | 9 +
.../chrome/firebug/content/cookies/cookieModule.js | 80 +-
.../firebug/content/cookies/cookieObserver.js | 41 +-
.../chrome/firebug/content/cookies/cookiePanel.js | 28 +
.../firebug/content/cookies/cookiePermissions.js | 2 +-
.../chrome/firebug/content/cookies/cookieReps.js | 58 +-
.../chrome/firebug/content/cookies/cookieUtils.js | 10 +-
.../chrome/firebug/content/cookies/menuUtils.js | 8 +-
.../chrome/firebug/content/css/computedPanel.js | 13 +-
.../chrome/firebug/content/css/cssModule.js | 52 +-
.../FBTrace/chrome/firebug/content/css/cssPanel.js | 769 ++++++------
.../FBTrace/chrome/firebug/content/css/cssReps.js | 8 +-
.../chrome/firebug/content/css/selectorEditor.js | 252 ++++
.../chrome/firebug/content/css/selectorModule.js | 74 ++
.../chrome/firebug/content/css/selectorPanel.js | 460 +++++++
.../chrome/firebug/content/css/stylePanel.js | 94 +-
.../FBTrace/chrome/firebug/content/dom/domPanel.js | 48 +-
.../chrome/firebug/content/editor/editor.js | 22 +-
trace/FBTrace/chrome/firebug/content/firebug.css | 8 +-
trace/FBTrace/chrome/firebug/content/firebug.js | 87 +-
.../chrome/firebug/content/firebugOverlay.xul | 17 +-
.../chrome/firebug/content/firefox/bindings.xml | 9 +-
.../firebug/content/firefox/browserCommands.js | 107 ++
.../chrome/firebug/content/firefox/browserMenu.js | 522 ++++++++
.../firebug/content/firefox/browserOverlay.css | 6 +-
.../firebug/content/firefox/browserOverlay.js | 1258 ++++----------------
.../firebug/content/firefox/browserOverlayLib.js | 272 +++++
.../firebug/content/firefox/browserToolbar.js | 136 +++
.../firefox/external-editors/changeeditor.js | 4 +-
.../content/firefox/external-editors/editors.xul | 100 +-
.../firefox/external-editors/externalEditors.js | 17 +-
.../chrome/firebug/content/firefox/firebug.xul | 11 +-
.../firefox/start-button/startButtonOverlay.js | 27 +-
.../chrome/firebug/content/html/highlighter.css | 6 +-
.../chrome/firebug/content/html/htmlPanel.js | 132 +-
.../chrome/firebug/content/html/insideOutBox.js | 1 +
.../chrome/firebug/content/html/inspector.js | 53 +-
.../FBTrace/chrome/firebug/content/html/layout.js | 281 +++--
.../chrome/firebug/content/js/breakpoint.js | 3 +-
.../FBTrace/chrome/firebug/content/js/debugger.js | 62 +-
.../chrome/firebug/content/js/scriptPanel.js | 49 +-
.../chrome/firebug/content/js/sourceCache.js | 5 +-
.../FBTrace/chrome/firebug/content/js/tabCache.js | 4 +-
.../chrome/firebug/content/js/watchPanel.js | 59 +-
trace/FBTrace/chrome/firebug/content/lib/array.js | 39 +-
trace/FBTrace/chrome/firebug/content/lib/css.js | 201 ++--
.../chrome/firebug/content/lib/deprecated.js | 6 +-
trace/FBTrace/chrome/firebug/content/lib/dom.js | 330 ++++-
.../FBTrace/chrome/firebug/content/lib/domplate.js | 58 +-
trace/FBTrace/chrome/firebug/content/lib/events.js | 9 +
trace/FBTrace/chrome/firebug/content/lib/fonts.js | 10 +-
trace/FBTrace/chrome/firebug/content/lib/object.js | 19 +-
.../FBTrace/chrome/firebug/content/lib/options.js | 12 +-
trace/FBTrace/chrome/firebug/content/lib/string.js | 95 +-
trace/FBTrace/chrome/firebug/content/lib/system.js | 52 +-
trace/FBTrace/chrome/firebug/content/lib/trace.js | 63 +-
trace/FBTrace/chrome/firebug/content/lib/url.js | 25 +
.../FBTrace/chrome/firebug/content/lib/wrapper.js | 16 +-
trace/FBTrace/chrome/firebug/content/main.js | 2 +-
.../FBTrace/chrome/firebug/content/moduleConfig.js | 19 +-
.../chrome/firebug/content/net/fontViewer.js | 9 +-
.../chrome/firebug/content/net/netMonitor.js | 15 +
.../FBTrace/chrome/firebug/content/net/netPanel.js | 10 +-
.../chrome/firebug/content/net/netProgress.js | 43 +-
.../FBTrace/chrome/firebug/content/net/netReps.js | 44 +-
.../FBTrace/chrome/firebug/content/net/netUtils.js | 2 +
.../chrome/firebug/content/net/requestObserver.js | 5 +-
.../chrome/firebug/content/net/responseObserver.js | 2 +-
trace/FBTrace/chrome/firebug/content/net/spy.js | 204 ++--
.../chrome/firebug/content/net/xmlViewer.js | 1 +
trace/FBTrace/chrome/firebug/content/trace.js | 10 +-
.../firebug/modules/firebug-http-observer.js | 30 +-
.../chrome/firebug/modules/firebug-service.js | 66 +-
.../firebug/modules/firebug-trace-service.js | 281 ++++-
trace/FBTrace/chrome/firebug/modules/gcli.js | 111 +-
trace/FBTrace/chrome/firebug/modules/loader.js | 35 +-
trace/FBTrace/chrome/firebug/modules/locale.js | 16 +-
.../FBTrace/chrome/firebug/modules/mini-require.js | 15 +-
.../chrome/firebug/modules/observer-service.js | 4 +-
trace/FBTrace/chrome/firebug/modules/prefLoader.js | 6 +
.../chrome/firebug/modules/require-debug.js | 36 +-
.../chrome/firebug/modules/storageService.js | 44 +-
.../chrome/firebug/skin/classic/callstack.css | 8 +
.../chrome/firebug/skin/classic/console.css | 47 +-
.../firebug/skin/classic/cookies/cookies.css | 4 +-
trace/FBTrace/chrome/firebug/skin/classic/css.css | 26 +-
.../chrome/firebug/skin/classic/debugger.css | 4 +-
trace/FBTrace/chrome/firebug/skin/classic/dom.css | 13 +-
.../chrome/firebug/skin/classic/firebug.css | 36 +-
trace/FBTrace/chrome/firebug/skin/classic/html.css | 7 +-
.../FBTrace/chrome/firebug/skin/classic/layout.css | 2 +-
.../chrome/firebug/skin/classic/linux/firebug.css | 6 +
.../chrome/firebug/skin/classic/mac/debugger.css | 4 +-
.../chrome/firebug/skin/classic/mac/firebug.css | 31 +-
.../chrome/firebug/skin/classic/mac/panel.css | 3 +
trace/FBTrace/chrome/firebug/skin/classic/net.css | 14 +-
.../FBTrace/chrome/firebug/skin/classic/panel.css | 3 +-
.../chrome/firebug/skin/classic/panelbase.css | 2 +-
.../firebug/skin/classic/performanceTiming.css | 192 +++
.../chrome/firebug/skin/classic/selector.css | 42 +
.../chrome/firebug/skin/classic/tableRep.css | 1 +
.../chrome/firebug/skin/classic/win/firebug.css | 24 +-
.../chrome/firebug/skin/classic/win/linux.css | 0
.../chrome/firebug/skin/classic/win/panel.css | 2 +
135 files changed, 8030 insertions(+), 3494 deletions(-)
diff --git a/trace/FBTrace/chrome/firebug/content/accessible/a11y.js b/trace/FBTrace/chrome/firebug/content/accessible/a11y.js
index 68e086a..1875286 100644
--- a/trace/FBTrace/chrome/firebug/content/accessible/a11y.js
+++ b/trace/FBTrace/chrome/firebug/content/accessible/a11y.js
@@ -57,7 +57,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
this.onNetFocus = Obj.bind(this.onNetFocus, this);
this.onNetBlur = Obj.bind(this.onNetBlur, this);
- // mark ourselves disabled so we don't performDisable() if we are not enabled.
+ // Mark ourselves disabled, so we don't performDisable() if we are not enabled.
Firebug.chrome.window.a11yEnabled = false;
Firebug.connection.addListener(this);
@@ -98,7 +98,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
{
// Update for current chrome
this.set(value, Firebug.chrome);
- // If the current chrome is external window, update also original chrome.
+ // If the current chrome is an external window, update also the original chrome.
if (Firebug.chrome != Firebug.originalChrome)
{
this.set(value, Firebug.originalChrome);
@@ -584,7 +584,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
ensurePanelTabStops: function()
{
- // XXXjjb: seems like this shoudl be !Firebug.chrome
+ // XXXjjb: seems like this should be !Firebug.chrome
if (!Firebug.currentContext || !Firebug.currentContext.chrome)
return;
var panel = Firebug.chrome.getSelectedPanel();
@@ -1037,7 +1037,7 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
cell = Dom.getChildByClass(cell, "a11yFocus");
this.focus(cell);
}
- // for Net Panel. Focus selected tab rather than the tablist
+ // for Net Panel. Focus selected tab rather than the tab list
else if (Css.hasClass(row, "netInfoTabs"))
{
var tabs = row.getElementsByClassName("netInfoTab");
@@ -1237,6 +1237,11 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
onObjectBoxSelected: function(objectBox, forceFocus)
{
var panel = Firebug.getElementPanel(objectBox);
+
+ // See issue 5934
+ if (panel.editing)
+ return;
+
var panelA11y = this.getPanelA11y(panel);
if (!panelA11y)
return;
@@ -1547,7 +1552,8 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
onBeforeCSSRulesAdded: function(panel)
{
// Panel content is about to be recreated, possibly wiping out focus.
- // Use the focused element's xpath to remember which rule had focus so that it can be refocused when the panel content is drawn again
+ // Use the focused element's xpath to remember which rule had focus,
+ // so that it can be refocused when the panel content is drawn again
var panelA11y = this.getPanelA11y(panel);
if (!panelA11y || !this.panelHasFocus(panel))
return;
@@ -2285,7 +2291,8 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
var node = line.getElementsByClassName("sourceRowText").item(0);
this.insertCaretToNode(panel, node);
- this.focus(focusElem); // move focus back to where it was
+ // move focus back to where it was
+ this.focus(focusElem);
},
insertCaretToNode: function(panel, node, startOffset)
@@ -2628,10 +2635,12 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
}
var rangeParent = Dom.getAncestorByClass(target, "netRow");
var browser = Firebug.chrome.getPanelBrowser(panel);
- // these two lines are necessary, because otherwise the infoTip will not have the correct dimensions when it's positioned, and the contents
- // could be placed outside FB's viewport (making it impossible to read for keyboard users)
+ // these two lines are necessary, because otherwise the info tip will not have the correct
+ // dimensions when it's positioned, and the contentscould be placed outside of Firebug's
+ // viewport (making it impossible to read for keyboard users)
+ // This will be called again in showInfoTip
panel.showInfoTip(browser.infoTip, target, target.offsetLeft, target.offsetTop,
- rangeParent, 0); //will be called again in showInfoTip
+ rangeParent, 0);
browser.infoTip.setAttribute("active", "true");
var left = Css.hasClass(target, "netTimeCol") ?
target.offsetLeft - browser.infoTip.offsetWidth - 12 :
@@ -3019,8 +3028,8 @@ Firebug.A11yModel = Obj.extend(Firebug.Module,
},
// These utils are almost the same as their DOM namesakes,
- // except that that the routine skips containers that are not visible
- // (rather than wasting time on their childnodes)
+ // except that the routine skips invisible containers
+ // (rather than wasting time on their child nodes)
getPreviousByClass: function (node, className, downOnly, maxRoot)
{
if (!node)
diff --git a/trace/FBTrace/chrome/firebug/content/branch.properties b/trace/FBTrace/chrome/firebug/content/branch.properties
index 165fb92..9ab088f 100644
--- a/trace/FBTrace/chrome/firebug/content/branch.properties
+++ b/trace/FBTrace/chrome/firebug/content/branch.properties
@@ -1,5 +1,5 @@
# DO NOT MERGE INTO TRUNK
-RELEASE=.0a0
+RELEASE=.0
VERSION=1.11
TRUNK=
# To allow build.xml to drop the xpi directly into the svn working copy for getfirebug.com
diff --git a/trace/FBTrace/chrome/firebug/content/bti/inProcess/browser.js b/trace/FBTrace/chrome/firebug/content/bti/inProcess/browser.js
index f76d18d..9483eb7 100644
--- a/trace/FBTrace/chrome/firebug/content/bti/inProcess/browser.js
+++ b/trace/FBTrace/chrome/firebug/content/bti/inProcess/browser.js
@@ -155,7 +155,8 @@ Browser.prototype.clearAllBreakpoints = function()
*/
Browser.prototype.clearAnnotations = function()
{
- Firebug.Activation.clearAnnotations(); // should trigger event onClearAnnotations
+ // should trigger event onClearAnnotations
+ Firebug.Activation.clearAnnotations();
}
Browser.prototype.getWebAppByWindow = function(win)
@@ -270,9 +271,17 @@ Browser.prototype.getOrCreateContextByWebApp = function(webApp)
var context = TabWatcher.watchTopWindow(topWindow, browser.currentURI, true);
this.setContextByWebApp(webApp, context);
+ // TEMP; Watch also all iframes. Firebug has been initialized when the page is already
+ // loaded and so, we can't rely on auto-registration done by FrameProgressListener.
+ Win.iterateWindows(context.window, function (win)
+ {
+ TabWatcher.watchWindow(win, context, false);
+ });
+
browser.showFirebug = true;
- Events.dispatch(TabWatcher.fbListeners, "watchBrowser", [browser]); // TODO remove
+ // TODO remove
+ Events.dispatch(TabWatcher.fbListeners, "watchBrowser", [browser]);
}
return context;
}
@@ -480,13 +489,18 @@ Browser.prototype.toggleResume = function(resume)
FBTrace.sysout("BTI.toggleResume" + (Firebug.getSuspended() ? "OFF" : "ON") +
" -> " + (!!resume ? "ON" : "OFF"));
- // this should be the only method to call suspend and resume.
- if (resume) // either a new context or revisiting an old one
+ // This should be the only method to call suspend() and resume().
+ // either a new context or revisiting an old one
+ if (resume)
{
if (Firebug.getSuspended())
- Firebug.resume(); // This will cause onResumeFirebug for every context including this one.
+ {
+ // This will cause onResumeFirebug for every context including this one.
+ Firebug.resume();
+ }
}
- else // this browser has no context
+ // this browser has no context
+ else
{
Firebug.suspend();
}
@@ -681,7 +695,8 @@ var TabWatchListener =
{
dispatchName: "TabWatchListener",
- initContext: function(context, persistedState) // called after a context is created.
+ // called after a context is created.
+ initContext: function(context, persistedState)
{
context.panelName = context.browser.panelName;
if (context.browser.sidePanelNames)
@@ -699,25 +714,29 @@ var TabWatchListener =
Firebug.connection.toggleResume(context);
},
- /**
- * To be called from Firebug.TabWatcher only, see selectContext
- */
- showContext: function(browser, context) // Firebug.TabWatcher showContext. null context means we don't debug that browser
+
+ // To be called from Firebug.TabWatcher only, see selectContext
+ // null as context means we don't debug that browser
+ showContext: function(browser, context)
{
- Firebug.chrome.setFirebugContext(context); // the context becomes the default for its view
- Firebug.connection.toggleResume(context); // resume, after setting Firebug.currentContext
+ // the context becomes the default for its view
+ Firebug.chrome.setFirebugContext(context);
+ // resume, after setting Firebug.currentContext
+ Firebug.connection.toggleResume(context);
- Events.dispatch(Firebug.modules, "showContext", [browser, context]); // tell modules we may show UI
+ // tell modules we may show UI
+ Events.dispatch(Firebug.modules, "showContext", [browser, context]);
Firebug.showContext(browser, context);
},
- unwatchBrowser: function(browser) // the context for this browser has been destroyed and removed
+ // The context for this browser has been destroyed and removed.
+ unwatchBrowser: function(browser)
{
Firebug.connection.toggleResume(false);
},
- // Either a top level or a frame, (interior window) for an exist context is seen by the tabWatcher.
+ // Either a top level or a frame (interior window) for an existing context is seen by the TabWatcher.
watchWindow: function(context, win)
{
for (var panelName in context.panelMap)
@@ -750,29 +769,41 @@ var TabWatchListener =
destroyContext: function(context, persistedState, browser)
{
- if (!context) // then we are called just to clean up
+ // then we are called just to clean up
+ if (!context)
return;
Events.dispatch(Firebug.modules, "destroyContext", [context, persistedState]);
- // xxxHonza: not sure if this code is correct. Test case: Firebug active, reload
+ // xxxHonza: Not sure if this code is correct. Test case: Firebug active, reload
// 1) The Firebug.currentContext can be already set to the new one
// 2) The Firebug.currentContext can be already null.
- // Calling clearPanels is important because it also clears the statuPath, which
- // contains references to panel objects (e.g. Page document in case of the HTML panel)
+ // Calling clearPanels() is important, because it also clears the statusPath, which
+ // contains references to panel objects (e.g. the page document in case of the HTML panel)
if (Firebug.currentContext == context || !Firebug.currentContext)
{
- Firebug.chrome.clearPanels(); // disconnect the to-be-destroyed panels from the panelBar
- Firebug.chrome.setFirebugContext(null); // Firebug.currentContext is about to be destroyed
+ // disconnect the to-be-destroyed panels from the panelBar
+ Firebug.chrome.clearPanels();
+ // Firebug.currentContext is about to be destroyed
+ Firebug.chrome.setFirebugContext(null);
}
var browser = context.browser;
+
// Persist remnants of the context for restoration if the user reloads
- browser.panelName = context.panelName;
- browser.sidePanelNames = context.sidePanelNames;
+ try
+ {
+ browser.panelName = context.panelName;
+ browser.sidePanelNames = context.sidePanelNames;
+ }
+ catch (e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("browser.destroyContext; " + e, e);
+ }
- // next the context is deleted and removed from the Firebug.TabWatcher,
- // we clean up in unWatchBrowser
+ // Next time the context is deleted and removed from the Firebug.TabWatcher,
+ // we clean up in unWatchBrowser.
},
onSourceFileCreated: function()
@@ -809,11 +840,11 @@ var TabWatchListener =
Browser.prototype.connect = function ()
{
- // Events fired on browser are re-broadcast to Firebug.modules
+ // Events fired on browser are re-broadcasted to Firebug.modules
Firebug.connection.addListener(Firebug);
- //Listen for preference changes. This way options module is not dependent on tools
- //xxxHonza: can this be in Browser interface?
+ // Listen for preference changes. This way the options module is not dependent on tools
+ // xxxHonza: can this be in Browser interface?
Options.addListener(
{
updateOption: function(name, value)
diff --git a/trace/FBTrace/chrome/firebug/content/bti/inProcess/compilationunit.js b/trace/FBTrace/chrome/firebug/content/bti/inProcess/compilationunit.js
index f686e47..f275e6f 100644
--- a/trace/FBTrace/chrome/firebug/content/bti/inProcess/compilationunit.js
+++ b/trace/FBTrace/chrome/firebug/content/bti/inProcess/compilationunit.js
@@ -58,7 +58,8 @@ CompilationUnit.prototype.getKind = function getKind()
CompilationUnit.prototype.isExecutableLine = function isExecutableLine(lineNo)
{
- return this.sourceFile.isExecutableLine(lineNo); // TODO no sourceFiles!
+ // TODO no sourceFiles!
+ return this.sourceFile.isExecutableLine(lineNo);
}
/**
@@ -103,7 +104,7 @@ CompilationUnit.prototype.getBrowserContext = function()
*/
CompilationUnit.prototype.getBreakpoints = function()
{
- // return a copy of scripts so the master copy is not corrupted
+ // Return a copy of the breakpoints, so the master copy is not corrupted.
var bps = [];
for ( var i = 0; i < this.breakpoints.length; i++)
bps.push(this.breakpoints[i]);
@@ -135,8 +136,8 @@ CompilationUnit.prototype.eachBreakpoint = function( fnOfLineProps )
*/
CompilationUnit.prototype.getSourceLines = function(firstLine, lastLine, listener)
{
- // xxxHonza: do not cache the source lines in compilation unit
- // The Script panel doesn't display whole script if it's downloaded
+ // xxxHonza: Do not cache the source lines in the compilation unit.
+ // The Script panel doesn't display the whole script if it's downloaded
// partially and the following caching happens sooner.
// Or tabCache.storeSplitLines should trigger an update.
//if (!this.lines)
diff --git a/trace/FBTrace/chrome/firebug/content/bti/inProcess/javascripttool.js b/trace/FBTrace/chrome/firebug/content/bti/inProcess/javascripttool.js
index 2e15fed..9851083 100644
--- a/trace/FBTrace/chrome/firebug/content/bti/inProcess/javascripttool.js
+++ b/trace/FBTrace/chrome/firebug/content/bti/inProcess/javascripttool.js
@@ -39,7 +39,7 @@ JavaScriptTool.breakOnNext = function(context, enable)
JavaScriptTool.setBreakpoint = function(context, url, lineNumber)
{
- // TODO we should be sending urls over not compilation units
+ // TODO we should be sending URLs over, not compilation units
var compilationUnit = context.getCompilationUnit(url);
JSDebugger.setBreakpoint(compilationUnit, lineNumber);
};
@@ -71,7 +71,7 @@ JavaScriptTool.getBreakpointCondition = function(context, url, lineNumber)
};
// ********************************************************************************************* //
-// These functions should be on stack instead
+// These functions should be on the stack instead.
JavaScriptTool.rerun = function(context)
{
@@ -111,7 +111,8 @@ JavaScriptTool.onConnect = function(connection)
{
if (!Firebug.connection.getTool("script"))
{
- JavaScriptTool.asTool = new Tool("script"), // this is the script tool
+ // this is the script tool
+ JavaScriptTool.asTool = new Tool("script"),
connection.registerTool(JavaScriptTool.asTool);
}
else
@@ -188,8 +189,12 @@ JavaScriptTool.onStartDebugging = function(context, frame)
JavaScriptTool.onStopDebugging = function(context)
{
var panel = context.getPanel("script", true);
- if (panel && panel === Firebug.chrome.getSelectedPanel()) // then we are looking at the script panel
- panel.showNoStackFrame(); // unhighlight and remove toolbar-status line
+ // Then we are looking at the Script panel.
+ if (panel && panel === Firebug.chrome.getSelectedPanel())
+ {
+ // unhighlight and remove toolbar-status line
+ panel.showNoStackFrame();
+ }
if (panel)
panel.onStopDebugging();
@@ -217,12 +222,14 @@ JavaScriptTool.initialize = function()
if (FBTrace.DBG_INITIALIZE)
FBTrace.sysout("JavaScriptTool initialize");
- Firebug.connection.addListener(JavaScriptTool); // This is how we get events
+ // This is how we get events.
+ Firebug.connection.addListener(JavaScriptTool);
}
JavaScriptTool.shutdown = function()
{
- Firebug.connection.removeListener(JavaScriptTool); // This is how we get events
+ // This is how we get events.
+ Firebug.connection.removeListener(JavaScriptTool);
}
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/activation.js b/trace/FBTrace/chrome/firebug/content/chrome/activation.js
index cbb9eef..c1e1f75 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/activation.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/activation.js
@@ -65,7 +65,7 @@ Firebug.Activation = Obj.extend(Firebug.Module,
if (Firebug.allPagesActivation == "on")
return true;
- // if about:blank gets thru, 1483 fails
+ // if about:blank gets through, issue 1483 fails
if (Firebug.filterSystemURLs && Url.isSystemURL(url))
return false;
@@ -85,23 +85,31 @@ Firebug.Activation = Obj.extend(Firebug.Module,
var hasAnnotation = Annotations.pageHasAnnotation(uri);
if (FBTrace.DBG_ACTIVATION)
- FBTrace.sysout("shouldCreateContext hasAnnotation "+hasAnnotation +
- " for "+uri.spec+" in "+browser.contentWindow.location +
- " using activateSameOrigin: "+Firebug.activateSameOrigin);
+ {
+ FBTrace.sysout("shouldCreateContext hasAnnotation " + hasAnnotation +
+ " for " + uri.spec + " in " +
+ (browser ? browser.contentWindow.location : "no browser") +
+ " using activateSameOrigin: " + Firebug.activateSameOrigin);
+ }
// Annotated, so return the value.
if (hasAnnotation)
return this.checkAnnotation(browser, uri);
- if (browser.FirebugLink) // then Firebug.TabWatcher found a connection
+ // Then Firebug.TabWatcher found a connection.
+ if (browser.FirebugLink)
{
var dst = browser.FirebugLink.dst;
var dstURI = this.convertToURIKey(dst.spec, Firebug.activateSameOrigin);
+
if (FBTrace.DBG_ACTIVATION)
+ {
FBTrace.sysout("shouldCreateContext found FirebugLink pointing to " +
dstURI.spec, browser.FirebugLink);
+ }
- if (dstURI && dstURI.equals(uri)) // and it matches us now
+ // And it matches us now.
+ if (dstURI && dstURI.equals(uri))
{
var srcURI = this.convertToURIKey(browser.FirebugLink.src.spec,
Firebug.activateSameOrigin);
@@ -109,18 +117,25 @@ Firebug.Activation = Obj.extend(Firebug.Module,
if (srcURI)
{
if (FBTrace.DBG_ACTIVATION)
+ {
FBTrace.sysout("shouldCreateContext found FirebugLink pointing from " +
srcURI.spec, browser.FirebugLink);
+ }
- // and it's on the same domain
+ // And it's on the same domain.
if (srcURI.schemeIs("file") || (dstURI.host == srcURI.host))
{
hasAnnotation = Annotations.pageHasAnnotation(srcURI);
- if (hasAnnotation) // and the source page was annotated.
+ // And the source page was annotated.
+ if (hasAnnotation)
{
var srcShow = this.checkAnnotation(browser, srcURI);
- if (srcShow) // and the source annotation said show it
- this.watchBrowser(browser); // so we show dst as well.
+ // And the source annotation said show it.
+ if (srcShow)
+ {
+ // So we show dst as well.
+ this.watchBrowser(browser);
+ }
return srcShow;
}
}
@@ -144,10 +159,14 @@ Firebug.Activation = Obj.extend(Firebug.Module,
browser.contentWindow.opener.location);
if (openerContext)
- return true; // popup windows of Firebugged windows are Firebugged
+ {
+ // popup windows of Firebugged windows are Firebugged
+ return true;
+ }
}
- return false; // don't createContext
+ // don't createContext
+ return false;
}
catch (exc)
{
@@ -162,7 +181,7 @@ Firebug.Activation = Obj.extend(Firebug.Module,
return this.shouldCreateContext(context.browser, context.getWindowLocation().toString());
},
- // Firebug is opened in browser
+ // Firebug is opened in the browser.
watchBrowser: function(browser)
{
try
@@ -177,14 +196,20 @@ Firebug.Activation = Obj.extend(Firebug.Module,
}
},
- // Firebug closes in browser
+ // Firebug closes in the browser.
unwatchBrowser: function(browser, userCommands)
{
var uri = browser.currentURI.spec;
- if (userCommands) // then mark to not open virally.
+ // Then mark to not open virally.
+ if (userCommands)
+ {
this.setPageAnnotation(uri, "firebugged.closed");
+ }
else
- this.removePageAnnotation(uri); // unmark this URI
+ {
+ // unmark this URI
+ this.removePageAnnotation(uri);
+ }
},
clearAnnotations: function()
@@ -195,10 +220,10 @@ Firebug.Activation = Obj.extend(Firebug.Module,
Firebug.connection.dispatch("onClearAnnotations", []);
},
- // process the URL to canonicalize it. Need not be reversible.
+ // Process the URL to canonicalize it. This needs not be reversible.
convertToURIKey: function(url, sameOrigin)
{
- // Remove fragment, it shouldn't have any impact on the activation.
+ // Remove the fragment. It shouldn't have any impact on the activation.
url = url.replace(/#.*/, "");
var uri = Url.makeURI(Url.normalizeURL(url));
@@ -206,26 +231,32 @@ Firebug.Activation = Obj.extend(Firebug.Module,
if (Firebug.filterSystemURLs && Url.isSystemURL(url))
return uri;
- if (url == "about:blank") // avoid exceptions.
+ // avoid exceptions
+ if (url == "about:blank")
return uri;
if (uri && sameOrigin)
{
try
{
- // returns the string before the path (such as "scheme://user:password@host:port").
+ // Returns the string before the path (such as "scheme://user:password@host:port").
var prePath = uri.prePath;
var shortURI = Url.makeURI(prePath);
if (!shortURI)
return uri;
- // annoying "about" URIs throw if you access .host
+ // Annoying "about" URIs throw if .host is accessed
if (shortURI.scheme === "about")
return shortURI;
if (shortURI.scheme === "file")
return shortURI;
+ return shortURI;
+
+ // This makes a.co.uk -> co.uk, mail.cn.mozilla.com -> cn.mozilla.com and
+ // blog.getfirebug.com -> getfirebug.com, which is wrong. See issue 2202.)
+ /*
var host = shortURI.host;
if (host)
{
@@ -234,14 +265,13 @@ Firebug.Activation = Obj.extend(Firebug.Module,
// 1) www.google.com -> google.com
// 2) www.stuff.co.nz -> stuff.co.nz
// 3) getfirebug.com -> getfirebug.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);
shortURI.host = levels.join('.');
return shortURI;
}
+ */
}
catch (exc)
{
@@ -253,6 +283,7 @@ Firebug.Activation = Obj.extend(Firebug.Module,
return uri;
}
}
+
return uri;
},
@@ -264,11 +295,17 @@ Firebug.Activation = Obj.extend(Firebug.Module,
FBTrace.sysout("shouldCreateContext read back annotation " + annotation +
" for uri " + uri.spec);
- // then the user closed Firebug on this page last time
+ // Then the user closed Firebug on this page last time.
if ((Firebug.allPagesActivation != "on") && (annotation.indexOf("closed") > 0))
- return false; // annotated as 'closed', don't create
+ {
+ // annotated as 'closed', don't create
+ return false;
+ }
else
- return true; // annotated, createContext
+ {
+ // annotated, createContext
+ return true;
+ }
},
setPageAnnotation: function(currentURI, annotation)
@@ -310,7 +347,7 @@ Firebug.Activation = Obj.extend(Firebug.Module,
FBTrace.sysout("Firebug.Activation.unwatchBrowser untagged "+uri.spec);
},
- // stops at the first fn(uri) that returns a true value
+ // Stops at the first fn(uri) that returns a true value.
iterateAnnotations: function(fn)
{
var annotations = Annotations.getAnnotations(this.annotationName);
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/annotations.js b/trace/FBTrace/chrome/firebug/content/chrome/annotations.js
index 9ca46b8..dc52dd1 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/annotations.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/annotations.js
@@ -98,7 +98,9 @@ var Annotations = Obj.extend(Firebug.Module,
// Initialize output stream.
var outputStream = Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(Ci.nsIFileOutputStream);
- outputStream.init(this.file, 0x02 | 0x08 | 0x20, 0666, 0); // write, create, truncate
+ // write, create, truncate
+ // see https://developer.mozilla.org/en-US/docs/PR_Open#Parameters
+ outputStream.init(this.file, 0x02 | 0x08 | 0x20, 0666, 0);
// Convert data to JSON.
var arr = [];
@@ -112,7 +114,7 @@ var Annotations = Obj.extend(Firebug.Module,
var jsonString = JSON.stringify(arr);
- // Store annotations.
+ // Store annotations
outputStream.write(jsonString, jsonString.length);
outputStream.close();
@@ -151,11 +153,12 @@ var Annotations = Obj.extend(Firebug.Module,
var cstream = Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Ci.nsIConverterInputStream);
- // loadAnnotations input stream.
- inputStream.init(this.file, 0x01 | 0x08, 0666, 0); // read, create
+ // loadAnnotations input stream
+ // read, create
+ inputStream.init(this.file, 0x01 | 0x08, 0666, 0);
cstream.init(inputStream, "UTF-8", 0, 0);
- // Load annotations.
+ // Load annotations
var json = "";
var data = {};
while (cstream.readString(-1, data) != 0)
@@ -168,7 +171,7 @@ var Annotations = Obj.extend(Firebug.Module,
if (!arr)
return;
- // Convert to map for faster lookup.
+ // convert to map for faster lookup
for (var i=0; i<arr.length; i++)
this.annotations[arr[i].uri] = arr[i].value;
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/chrome.js b/trace/FBTrace/chrome/firebug/content/chrome/chrome.js
index eaf6c62..a557cd2 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/chrome.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/chrome.js
@@ -58,10 +58,12 @@ const statusCropSize = 20;
// ********************************************************************************************* //
-var ChromeFactory = // factory is global in module loading window
+// factory is global in module loading window
+var ChromeFactory =
{
-createFirebugChrome: function(win) // chrome is created in caller window.
+// chrome is created in caller window.
+createFirebugChrome: function(win)
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Private
@@ -77,7 +79,6 @@ createFirebugChrome: function(win) // chrome is created in caller window.
var FirebugChrome =
{
// TODO: remove this property, add getters for location, title, focusedElement, setter popup
-
dispatchName: "FirebugChrome",
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -156,13 +157,14 @@ var FirebugChrome =
(panelBar1 ? panelBar1.browser.ownerDocument.documentURI : "no panel bar"), win);
// At this point both panelBars can be loaded already, since the src is specified
- // in firebugOveralay.xul (asynchronously loaded). If yes, start up
- // the initialization sequence now.
+ // in firebugOverlay.xul (asynchronously loaded). If yes, start up the initialization
+ // sequence now.
if (browser1Complete && browser2Complete)
{
setTimeout(function()
{
- FirebugChrome.initializeUI(); // the chrome bound into this scope
+ // chrome bound into this scope
+ FirebugChrome.initializeUI();
})
}
},
@@ -175,7 +177,7 @@ var FirebugChrome =
if (FBTrace.DBG_INITIALIZE)
FBTrace.sysout("chrome.initializeUI;");
- // we listen for panel update
+ // listen for panel updates
Firebug.registerUIListener(this);
try
@@ -210,7 +212,7 @@ var FirebugChrome =
var mainTabBox = panelBar1.ownerDocument.getElementById("fbPanelBar1-tabBox");
Events.addEventListener(mainTabBox, "mousedown", onMainTabBoxMouseDown, false);
- // The side panel bar doesn't care about this event. It must, however,
+ // The side panel bar doesn't care about this event. It must, however,
// prevent it from bubbling now that we allow the side panel bar to be
// *inside* the main panel bar.
Events.addEventListener(panelBar2, "selectingPanel", stopBubble, false);
@@ -225,11 +227,11 @@ var FirebugChrome =
Firebug.internationalizeUI(win.document);
Firebug.internationalizeUI(top.document);
- // xxxHonza: Is there any reason why we don't distribute "initializeUI"
+ // xxxHonza: Is there any reason why we don't distribute "initializeUI"?
// event to modules?
Firebug.initializeUI();
- // Append all registered stylesheets into Firebug UI.
+ // Append all registered stylesheets into Firebug UI
for (var i=0; i<Firebug.stylesheets.length; i++)
{
var uri = Firebug.stylesheets[i];
@@ -240,7 +242,7 @@ var FirebugChrome =
FBTrace.sysout("chrome.initializeUI; Custom stylesheet appended " +
Firebug.stylesheets.length, Firebug.stylesheets);
- // Fire event for window event listeners.
+ // Fire event for window event listeners
Firebug.sendLoadEvent();
}
catch (exc)
@@ -311,7 +313,7 @@ var FirebugChrome =
},
/**
- * Checking first window in back order, (Most recent window). is itself firebug ?
+ * Checks if the Firebug window has the focus (is the most recent window)
*/
hasFocus: function()
{
@@ -363,7 +365,7 @@ var FirebugChrome =
disableOff: function(collapse)
{
- // disable/enable this button in the Firebug.chrome window.
+ // disable/enable this button in the Firebug.chrome window
Dom.collapse(FirebugChrome.$("fbCloseButton"), collapse);
},
@@ -376,7 +378,8 @@ var FirebugChrome =
// Command Line Popup can be displayed for all the other panels
// (except for the Console panel)
- // XXXjjb, xxxHonza: this should be somehow better, more generic and extensible...
+ // XXXjjb, xxxHonza, xxxsz: this should be somehow better, more generic and extensible,
+ // e.g. by asking each panel if it supports the Command Line Popup
var consolePanelType = Firebug.getPanelType("console");
if (consolePanelType == panelType)
{
@@ -415,16 +418,20 @@ var FirebugChrome =
.getService(Components.interfaces.nsIProperties)
.get("TmpD", Components.interfaces.nsIFile);
- file.append("firebug"); // extensions sub-directory
+ // extensions sub-directory
+ file.append("firebug");
file.append("panelSave.html");
file.createUnique(Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 0666);
- foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
- serializer.serializeToStream(doc, foStream, ""); // rememeber, doc is the DOM tree
+ // write, create, truncate
+ foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
+ // remember, doc is the DOM tree
+ serializer.serializeToStream(doc, foStream, "");
foStream.close();
return file.path;
},
- updatePanelBar1: function(panelTypes) // part of initializeUI
+ // part of initializeUI
+ updatePanelBar1: function(panelTypes)
{
var mainPanelTypes = [];
for (var i = 0; i < panelTypes.length; ++i)
@@ -501,7 +508,10 @@ var FirebugChrome =
{
this.positionInitialzed = true;
if (Firebug.framePosition != "detached" && Firebug.framePosition != "bottom")
- this.setPosition(); // null only updates frame position without side effects
+ {
+ // null only updates frame position without side effects
+ this.setPosition();
+ }
}
},
@@ -519,11 +529,12 @@ var FirebugChrome =
Dom.collapse(Firebug.chrome.$("fbContentBox"), false);
},
- syncResumeBox: function(context) // only called when detached
+ // only called when detached
+ syncResumeBox: function(context)
{
var resumeBox = Firebug.chrome.$('fbResumeBox');
- // xxxHonza: Don't focus Firebug window now. It would bring Firebug detached window
+ // xxxHonza: Don't focus the Firebug window now. It would bring the detached Firebug window
// to the top every time the attached Firefox page is refreshed, which is annoying.
//this.focus(); // bring to users attention
@@ -537,7 +548,8 @@ var FirebugChrome =
{
Firebug.chrome.toggleOpen(false);
Dom.collapse(resumeBox, false);
- Firebug.chrome.window.top.document.title =
+
+ Firebug.chrome.window.parent.document.title =
Locale.$STR("Firebug - inactive for current website");
}
},
@@ -570,7 +582,7 @@ var FirebugChrome =
var i, currentIndex = newIndex = -1, currentPanel = this.getSelectedPanel(), newPanel;
var panelTypes = Firebug.getMainPanelTypes(Firebug.currentContext);
- // Get current panel's index (is there a simpler way for this?
+ // get the current panel's index (is there a simpler way for this?)
for (i = 0; i < panelTypes.length; i++)
{
if (panelTypes[i].prototype.name === currentPanel.name)
@@ -628,10 +640,10 @@ var FirebugChrome =
/**
* Set this.location on the current panel or one given by name.
* The location object should be known to the caller to be of the correct type for the panel,
- * eg SourceFile for Script panel
- * @param object the location object, null selects default location
- * @param panelName the .name field for the desired panel, null means current panel
- * @param sidePanelName I don't know how this affects the outcome
+ * e.g. SourceFile for Script panel
+ * @param object location object, null selects default location
+ * @param panelName name of the panel to select, null means current panel
+ * @param sidePanelName name of the side panel to select
*/
navigate: function(object, panelName, sidePanelName)
{
@@ -648,9 +660,9 @@ var FirebugChrome =
/**
* Set this.selection by object type analysis, passing the object to all panels to
* find the best match
- * @param object the new this.selection object
- * @param panelName matching panel.name will be used, if its supportsObject returns true value
- * @param sidePanelName default side panel name used, if its supportsObject returns true value
+ * @param object new this.selection object
+ * @param panelName matching panel.name will be used, if its supportsObject returns true
+ * @param sidePanelName default side panel name used, if its supportsObject returns true
* @param forceUpdate if true, then (object === this.selection) is ignored and
* updateSelection is called
*/
@@ -662,7 +674,7 @@ var FirebugChrome =
var bestPanelName = getBestPanelName(object, Firebug.currentContext, panelName);
- // Allow refresh if needed (the last argument).
+ // allow refresh if needed (last argument)
var panel = this.selectPanel(bestPanelName, sidePanelName/*, true*/);
if (panel)
panel.select(object, forceUpdate);
@@ -712,7 +724,7 @@ var FirebugChrome =
switchToPanel: function(context, switchToPanelName)
{
- // Remember the previous panel and bar state so we can revert if the user cancels
+ // Remember the previous panel and bar state so we can revert if the user cancels.
this.previousPanelName = context.panelName;
this.previousSidePanelName = context.sidePanelName;
this.previouslyCollapsed = FirebugChrome.$("fbContentBox").collapsed;
@@ -850,7 +862,7 @@ var FirebugChrome =
if (!panelName)
panelName = context.panelName? context.panelName : Firebug.defaultPanelName;
- // Make HTML panel the default panel, which is displayed
+ // Make the HTML panel the default panel, which is displayed
// to the user the very first time.
if (!panelName || !Firebug.getPanelType(panelName))
panelName = "html";
@@ -874,7 +886,7 @@ var FirebugChrome =
var panelTypes = Firebug.getMainPanelTypes(Firebug.currentContext);
panelBar1.updatePanels(panelTypes);
- // Upadate also BON tab flag (orange background if BON is active)
+ // Update also BON tab flag (orange background if BON is active)
// every time the user changes the current tab in Firefox.
Firebug.Breakpoint.updatePanelTabs(Firebug.currentContext);
}
@@ -913,7 +925,7 @@ var FirebugChrome =
}
else
{
- // if the context changes we need to refresh the panel
+ // If the context changes, we need to refresh the panel.
panelBar2.selectPanel(panelBar2.selectedPanel.name, true);
}
}
@@ -936,11 +948,11 @@ var FirebugChrome =
if (Firebug.currentContext)
{
var title = Firebug.currentContext.getTitle();
- win.top.document.title = Locale.$STRF("WindowTitle", [title]);
+ win.parent.document.title = Locale.$STRF("WindowTitle", [title]);
}
else
{
- win.top.document.title = Locale.$STR("Firebug");
+ win.parent.document.title = Locale.$STR("Firebug");
}
},
@@ -994,8 +1006,8 @@ var FirebugChrome =
}
else
{
- // Alright, let's update visibility of the separator. The separator
- // is displayed only, if there are some other buttons on the left side.
+ // Update the visibility of the separator. The separator
+ // is displayed only if there are some other buttons on the left side.
// Before showing the status separator let's see whether there are any other
// buttons on the left.
var hide = true;
@@ -1016,7 +1028,7 @@ var FirebugChrome =
panelStatus.lastPanelName = panel.name;
- // If the object already exists in the list, just select it and keep the path
+ // If the object already exists in the list, just select it and keep the path.
var selection = panel.selection;
var existingItem = panelStatus.getItemByObject(panel.selection);
if (existingItem)
@@ -1110,7 +1122,7 @@ var FirebugChrome =
var vertical = pos == "top" || pos == "bottom";
var after = pos == "bottom" || pos == "right";
- var document = window.top.document;
+ var document = window.parent.document;
var container = document.getElementById(vertical ? "appcontent" : "browser");
var splitter = Firefox.getElementById("fbContentSplitter");
@@ -1151,7 +1163,7 @@ var FirebugChrome =
swapBrowsers: function(oldBrowser, newBrowser)
{
var oldDoc = oldBrowser.contentDocument
- // Panels remember top window, for which they were first opened.
+ // Panels remember the top window, for which they were first opened.
// So we need to destroy their views.
var styleSheet = oldDoc.styleSheets[0];
var rulePos = styleSheet.cssRules.length;
@@ -1231,8 +1243,8 @@ var FirebugChrome =
setChromeDocumentAttribute: function(id, name, value)
{
- // Call as Firebug.chrome.setChromeDocumentAttribute() to set attributes
- // in another window.
+ // call as Firebug.chrome.setChromeDocumentAttribute() to set attributes
+ // in another window
var elt = FirebugChrome.$(id);
if (elt)
elt.setAttribute(name, value);
@@ -1296,7 +1308,7 @@ var FirebugChrome =
getElementById: function(id)
{
- // The document we close over not the global.
+ // The document we close over, not the global.
return win.document.getElementById(id);
},
@@ -1310,7 +1322,9 @@ var FirebugChrome =
var zoom = Firebug.Options.getZoomByTextSize(value);
var zoomString = (zoom * 100) + "%";
- var fontSizeAdjust = zoom * 0.547; // scale the aspect relative to 11pt Lucida Grande
+ // scale the aspect relative to 11pt Lucida Grande
+ // xxxsz: The magic number 0.547 should be replaced some logic retrieving this value.
+ var fontSizeAdjust = zoom * 0.547;
var contentBox = Firebug.chrome.$("fbContentBox");
contentBox.style.fontSizeAdjust = fontSizeAdjust;
@@ -1376,16 +1390,16 @@ var FirebugChrome =
var sidePanel = panelBar2.selectedPanel;
if (sidePanel)
- sidePanel.select(object);
+ sidePanel.refresh();
}
},
- // called on setTimeout after sourceBox viewport has been repainted
+ // called on setTimeout() after sourceBox viewport has been repainted
onApplyDecorator: function(sourceBox)
{
},
- // called on scrollTo, passing in the selected line
+ // called on scrollTo() passing in the selected line
onViewportChange: function(sourceLink)
{
},
@@ -1427,7 +1441,7 @@ var FirebugChrome =
toggleFirebug.setAttribute("tooltiptext", Locale.$STR("firebug.menu.tip.Minimize_Firebug"));
}
- // If Firebug is detached, hide the menu ('Open Firebug' shortcut doesn't hide,
+ // If Firebug is detached, hide the menu. ('Open Firebug' shortcut doesn't hide
// but just focuses the external window)
if (Firebug.isDetached())
toggleFirebug.setAttribute("collapsed", (collapsed == "true" ? "false" : "true"));
@@ -1465,7 +1479,7 @@ var FirebugChrome =
onContextShowing: function(event)
{
- // xxxHonza: This context-menu support can be used even in a separate window, which
+ // xxxHonza: This context menu support can be used even in a separate window, which
// doesn't contain the Firebug UI (panels).
//if (!panelBar1.selectedPanel)
// return false;
@@ -1477,13 +1491,13 @@ var FirebugChrome =
var target = win.document.popupNode;
var panel = target ? Firebug.getElementPanel(target) : null;
- // the event must be on our chrome not inside the panel
+ // The event must be on our chrome not inside the panel.
if (!panel)
panel = panelBar1 ? panelBar1.selectedPanel : null;
Dom.eraseNode(popup);
- // Make sure the Copy action is only available if there is actually someting
+ // Make sure the Copy action is only available if there is actually something
// selected in the panel.
var sel = target.ownerDocument.defaultView.getSelection();
if (!this.contextMenuObject &&
@@ -1502,7 +1516,7 @@ var FirebugChrome =
else if (target && panel)
object = panel.getPopupObject(target);
else if (target)
- // xxxHonza: What about a node from different document? Is that OK?
+ // xxxHonza: What about a node from a different document? Is that OK?
object = Firebug.getRepObject(target);
this.contextMenuObject = null;
@@ -1511,68 +1525,55 @@ var FirebugChrome =
var realObject = rep ? rep.getRealObject(object, Firebug.currentContext) : null;
var realRep = realObject ? Firebug.getRep(realObject, Firebug.currentContext) : null;
- if (FBTrace.DBG_OPTIONS)
- FBTrace.sysout("chrome.onContextShowing object:"+object+" rep: "+rep+
- " realObject: "+realObject+" realRep:"+realRep);
+ if (FBTrace.DBG_MENU)
+ {
+ FBTrace.sysout("chrome.onContextShowing object:"+object+", rep: "+rep+
+ ", realObject: "+realObject+", realRep:"+realRep);
+ }
+ // 1. Add the custom menu items from the realRep
if (realObject && realRep)
{
- // 1. Add the custom menu items from the realRep
- var menu = realRep.getContextMenuItems(realObject, target, Firebug.currentContext);
- if (menu)
- {
- for (var i = 0; i < menu.length; ++i)
- Menu.createMenuItem(popup, menu[i]);
- }
+ var items = realRep.getContextMenuItems(realObject, target, Firebug.currentContext);
+ if (items)
+ Menu.createMenuItems(popup, items);
}
+ // 2. Add the custom menu items from the original rep
if (object && rep && rep != realRep)
{
- // 1. Add the custom menu items from the original rep
var items = rep.getContextMenuItems(object, target, Firebug.currentContext);
if (items)
- {
- for (var i = 0; i < items.length; ++i)
- Menu.createMenuItem(popup, items[i]);
- }
+ Menu.createMenuItems(popup, items);
}
- // 1. Add the custom menu items from the panel
+ // 3. Add the custom menu items from the panel
if (panel)
{
var items = panel.getContextMenuItems(realObject, target);
if (items)
- {
- for (var i = 0; i < items.length; ++i)
- Menu.createMenuItem(popup, items[i]);
- }
+ Menu.createMenuItems(popup, items);
}
- // 2. Add the inspect menu items
+ // 4. Add the inspect menu items
if (realObject && rep && rep.inspectable)
{
- var separator = null;
-
var items = this.getInspectMenuItems(realObject);
- for (var i = 0; i < items.length; ++i)
- {
- if (popup.firstChild && !separator)
- separator = Menu.createMenuSeparator(popup);
- Menu.createMenuItem(popup, items[i]);
- }
+ // Separate existing menu items from 'inspect' menu items.
+ if (popup.firstChild && items.length > 0)
+ Menu.createMenuSeparator(popup);
+
+ Menu.createMenuItems(popup, items);
}
- // 3. Add menu items from uiListeners
+ // 5. Add menu items from uiListeners
var items = [];
Events.dispatch(Firebug.uiListeners, "onContextMenu", [items, object, target,
Firebug.currentContext, panel, popup]);
if (items)
- {
- for (var i = 0; i < items.length; ++i)
- Menu.createMenuItem(popup, items[i]);
- }
+ Menu.createMenuItems(popup, items);
if (!popup.firstChild)
return false;
@@ -1624,14 +1625,14 @@ var FirebugChrome =
var object;
- /* XXXjjb This causes the Script panel to show the function body over and over.
- * We need to clear it at least, but really we need to understand why the tooltip
+ /* XXXjjb: This causes the Script panel to show the function body over and over.
+ * We need to clear it at least, but actually we need to understand why the tooltip
* should show the context menu object at all. One thing the contextMenuObject supports
* is peeking at function bodies when stopped at a breakpoint.
* That case could be supported with clearing the contextMenuObject, but we don't
- * know, if that breaks something else. So maybe a popupMenuObject should be set
- * on the context if that is what we want to support
- * The other complication is, that there seems to be another tooltip.
+ * know if that breaks something else. So maybe a popupMenuObject should be set
+ * on the context if that is what we want to support.
+ * The other complication is that there seems to be another tooltip.
if (this.contextMenuObject)
{
object = this.contextMenuObject;
@@ -1708,7 +1709,7 @@ var FirebugChrome =
breakOnNext: function(context, event)
{
- // Avoid bubbling from associated options.
+ // avoid bubbling from associated options
if (event.target.id != "cmd_firebug_toggleBreakOn")
return;
@@ -1764,9 +1765,8 @@ var FirebugChrome =
break;
}
}
- },
-
-}; // end of FirebugChrome
+ }
+};
// ********************************************************************************************* //
// Local Helpers
@@ -1776,7 +1776,7 @@ function panelSupportsObject(panelType, object, context)
if (panelType)
{
try {
- // This tends to throw exceptions often, because some objects are weird
+ // This tends to throw exceptions often because some objects are weird
return panelType.prototype.supportsObject(object, typeof object, context)
} catch (exc) {}
}
@@ -1789,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);
@@ -1798,7 +1798,7 @@ function getBestPanelName(object, context, panelName)
}
// The suggested name didn't pan out, so search for the panel type with the
- // most specific level of support
+ // most specific level of support.
return getBestPanelSupportingObject(object, context);
}
@@ -1834,7 +1834,7 @@ function getBestSidePanelName(sidePanelName, panelTypes)
{
if (sidePanelName)
{
- // Verify, that the suggested panel name is in the acceptable list
+ // Verify, that the suggested panel name is in the acceptable list.
for (var i = 0; i < panelTypes.length; ++i)
{
if (panelTypes[i].prototype.name == sidePanelName)
@@ -1842,7 +1842,7 @@ function getBestSidePanelName(sidePanelName, panelTypes)
}
}
- // Default to the first panel type in the list
+ // Default to the first panel type in the list.
return panelTypes.length ? panelTypes[0].prototype.name : null;
}
@@ -1863,10 +1863,11 @@ function browser1Loaded()
if (browser1.complete && browser2.complete)
{
- // initializeUI is executed asynchronously, which solves the issue 3442
- // The problem has been introduced (from unknown reason) by revision R12210
+ // initializeUI() is executed asynchronously (solves issue 3442)
+ // The problem has been introduced (for an unknown reason) by revision R12210
setTimeout(function() {
- FirebugChrome.initializeUI(); // the chrome bound into this scope
+ // chrome bound into this scope
+ FirebugChrome.initializeUI();
});
}
@@ -1890,7 +1891,8 @@ function browser2Loaded()
{
// See browser1Loaded for more info.
setTimeout(function() {
- FirebugChrome.initializeUI(); // the chrome bound into this scope
+ // chrome bound into this scope
+ FirebugChrome.initializeUI();
});
}
@@ -1900,11 +1902,10 @@ function browser2Loaded()
function onBlur(event)
{
- // XXXjjb this seems like a waste: called continuously to clear possible highlight I guess.
- // XXXhh Is this really necessary? I disabled it for now as this was preventing me
+ // XXXjjb: this seems like a waste: called continuously to clear possible highlight I guess.
+ // 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)
@@ -1940,9 +1941,9 @@ function onSelectingPanel(event)
panel.navigate(panel.location);
// Hide all toolbars now. It's a responsibility of the new selected panel to show
- // those toolbars, that are necessary. This avoids the situation, when naughty panel
- // doesn't clean up its toolbars. This must be done before 'showPanel', where visibility
- // of the BON buttons is managed.
+ // those toolbars, that are necessary. This avoids the situation when a naughty panel
+ // doesn't clean up its toolbars. This must be done before 'showPanel' is dispatched,
+ // where the visibility of the BON buttons is managed.
var toolbar = FirebugChrome.$("fbToolbarInner");
var child = toolbar.firstChild;
while (child)
@@ -1951,14 +1952,14 @@ function onSelectingPanel(event)
child = child.nextSibling;
}
- // Those extensions that don't use XUL overlays (e.g. bootstrapped extensions)
+ // Those extensions that don't use XUL overlays (i.e. bootstrapped extensions)
// can provide toolbar buttons throug Firebug APIs.
var panelToolbar = FirebugChrome.$("fbPanelToolbar");
Dom.eraseNode(panelToolbar);
if (panel)
{
- // Get buttons from the current panel.
+ // get buttons from current panel
var buttons;
if (panel.getPanelToolbarButtons)
buttons = panel.getPanelToolbarButtons();
@@ -1984,7 +1985,7 @@ function onSelectingPanel(event)
Firebug.chrome.syncLocationList();
Firebug.chrome.syncStatusPath();
- //xxxjjb unfortunately the callstack side panel depends on the status path (sync after.)
+ //xxxjjb: unfortunately the Stack side panel depends on the status path (sync after.)
Firebug.chrome.syncSidePanels();
}
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/menu.js b/trace/FBTrace/chrome/firebug/content/chrome/menu.js
index 57b3508..c156834 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/menu.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/menu.js
@@ -4,9 +4,10 @@ define([
"firebug/lib/trace",
"firebug/lib/locale",
"firebug/lib/options",
- "firebug/lib/css"
+ "firebug/lib/css",
+ "firebug/lib/deprecated"
],
-function(FBTrace, Locale, Options, Css) {
+function(FBTrace, Locale, Options, Css, Deprecated) {
// ********************************************************************************************* //
// Constants
@@ -15,23 +16,47 @@ var Menu = {};
// ********************************************************************************************* //
-Menu.createMenu = function(popup, label)
+Menu.createMenu = function(popup, item)
{
+ if (typeof item == "string")
+ {
+ return Deprecated.deprecated("The function's header changed to "+
+ "createMenu(popup, item)",
+ Menu.createMenu, [popup, {label: item}])();
+ }
+
var menu = popup.ownerDocument.createElement("menu");
- menu.setAttribute("label", label);
+
+ Menu.setItemIntoElement(menu, item);
var menuPopup = popup.ownerDocument.createElement("menupopup");
popup.appendChild(menu);
menu.appendChild(menuPopup);
+ if (item.items)
+ {
+ for (var i = 0, len = item.items.length; i < len; ++i)
+ Menu.createMenuItem(menuPopup, item.items[i]);
+ }
+
return menuPopup;
};
+// Menu.createMenuItems(popup, items[, before])
+Menu.createMenuItems = function(popup, items, before)
+{
+ for (var i=0; i<items.length; i++)
+ Menu.createMenuItem(popup, items[i], before);
+};
+
Menu.createMenuItem = function(popup, item, before)
{
- if (typeof(item) == "string" && item.charAt(0) == "-")
- return Menu.createMenuSeparator(popup, before);
+ if ((typeof(item) == "string" && item == "-") || item.label == "-")
+ return Menu.createMenuSeparator(popup, item, before);
+
+ if (item.items)
+ return Menu.createMenu(popup, item);
var menuitem = popup.ownerDocument.createElement("menuitem");
@@ -100,6 +125,9 @@ Menu.setItemIntoElement = function(element, item)
if (item.name)
element.setAttribute("name", item.name);
+ if (item.items && (item.command || item.commandID))
+ element.setAttribute("type", "splitmenu");
+
return element;
}
@@ -116,17 +144,30 @@ Menu.createMenuHeader = function(popup, item)
return header;
};
-Menu.createMenuSeparator = function(popup, before)
+Menu.createMenuSeparator = function(popup, item, before)
{
+ if (item instanceof Node)
+ {
+ return Deprecated.deprecated("The function's header changed to "+
+ "createMenuSeparator(popup, item, before)",
+ Menu.createMenuSeparator, [popup, null, before])();
+ }
+
if (!popup.firstChild)
return;
- var menuitem = popup.ownerDocument.createElement("menuseparator");
+ if (FBTrace.DBG_MENU)
+ FBTrace.sysout("createMenuSeparator", {popup: popup, item: item, before: before});
+
+ var menuItem = popup.ownerDocument.createElement("menuseparator");
+ if (typeof item == "object" && item.id)
+ menuItem.setAttribute("id", item.id);
+
if (before)
- popup.insertBefore(menuitem, before);
+ popup.insertBefore(menuItem, before);
else
- popup.appendChild(menuitem);
- return menuitem;
+ popup.appendChild(menuItem);
+ return menuItem;
};
/**
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/panelActivation.js b/trace/FBTrace/chrome/firebug/content/chrome/panelActivation.js
index a66b00f..5e436e1 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/panelActivation.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/panelActivation.js
@@ -8,9 +8,8 @@ define([
"firebug/lib/domplate",
"firebug/lib/url",
"firebug/lib/dom",
- "firebug/js/fbs", // bug712289
],
-function(Obj, Firebug, Firefox, Locale, Domplate, Url, Dom, FBS) {
+function(Obj, Firebug, Firefox, Locale, Domplate, Url, Dom) {
// ************************************************************************************************
// Constants
@@ -18,7 +17,7 @@ function(Obj, Firebug, Firefox, Locale, Domplate, Url, Dom, FBS) {
const Cc = Components.classes;
const Ci = Components.interfaces;
-const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
/**
@@ -334,16 +333,6 @@ Firebug.DisabledPanelBox = domplate(Firebug.Rep,
var parentNode = this.getParentNode(browser);
this.tag.replace(args, parentNode, this);
parentNode.removeAttribute("collapsed");
-
- // bug712289
- if (panelName == "script" && !FBS.isJSDAvailable())
- {
- Dom.hide(parentNode.querySelector(".descImage"), true);
- Dom.hide(parentNode.querySelector(".objectLink"), true);
-
- var desc = parentNode.querySelector(".disabledPanelDescription");
- desc.innerHTML = Locale.$STR("moduleManager.scriptPanelNotAvailable");
- }
},
/**
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/reps.js b/trace/FBTrace/chrome/firebug/content/chrome/reps.js
index 8e34005..71e124f 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/reps.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/reps.js
@@ -103,6 +103,17 @@ FirebugReps.Null = domplate(Firebug.Rep,
// ********************************************************************************************* //
+FirebugReps.Hint = domplate(Firebug.Rep,
+{
+ tag: OBJECTBOX("$object"),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ className: "hint",
+});
+
+// ********************************************************************************************* //
+
FirebugReps.Nada = domplate(Firebug.Rep,
{
tag: SPAN(""),
@@ -285,6 +296,7 @@ FirebugReps.Func = domplate(Firebug.Rep,
var monitored = scriptInfo ? FBS.fbs.isMonitored(scriptInfo.sourceFile.href,
scriptInfo.lineNo) : false;
+ var self = this;
var name = script ? StackFrame.getFunctionName(script, context) : fn.name;
return [
{
@@ -293,7 +305,11 @@ FirebugReps.Func = domplate(Firebug.Rep,
nol10n: true,
type: "checkbox",
checked: monitored,
- command: Obj.bindFixed(this.monitor, this, fn, monitored)
+ command: function()
+ {
+ var checked = this.hasAttribute("checked");
+ self.monitor(fn, !checked);
+ }
},
"-",
{
@@ -509,42 +525,34 @@ FirebugReps.Reference = domplate(Firebug.Rep,
// ********************************************************************************************* //
-FirebugReps.Arr = domplate(Firebug.Rep,
+FirebugReps.ArrBase = domplate(FirebugReps.Obj,
{
- tag:
- OBJECTBOX({_repObject: "$object",
- $hasTwisty: "$object|hasSpecialProperties",
- onclick: "$onToggleProperties"},
- SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
- FOR("item", "$object|longArrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
- ),
- SPAN({"class": "arrayRightBracket", role: "presentation"}, "]"),
- SPAN({"class": "arrayProperties", role: "group"})
- ),
+ className: "array",
+ toggles: new ToggleBranch.ToggleBranch(),
- shortTag:
- OBJECTBOX({_repObject: "$object",
- $hasTwisty: "$object|hasSpecialProperties",
- onclick: "$onToggleProperties"},
- SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
- FOR("item", "$object|shortArrayIterator",
- TAG("$item.tag", {object: "$item.object"}),
- SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
- ),
- SPAN({"class": "arrayRightBracket"}, "]"),
- SPAN({"class": "arrayProperties", role: "group"})
- ),
+ titleTag:
+ SPAN({"class": "objectTitle"}, "$object|getTitleTag"),
+
+ getTitle: function(object, context)
+ {
+ return "[" + object.length + "]";
+ },
+
+ supportsObject: function(object, type)
+ {
+ return this.isArray(object);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
longArrayIterator: function(array)
{
- return this.arrayIterator(array, 300);
+ return this.arrayIterator(array, 300);
},
shortArrayIterator: function(array)
{
- return this.arrayIterator(array, Options.get("ObjectShortIteratorMax"));
+ return this.arrayIterator(array, Options.get("ObjectShortIteratorMax"));
},
arrayIterator: function(array, max)
@@ -586,8 +594,6 @@ FirebugReps.Arr = domplate(Firebug.Rep,
return items;
},
- toggles: new ToggleBranch.ToggleBranch(),
-
getItemIndex: function(child)
{
var arrayIndex = 0;
@@ -662,23 +668,16 @@ FirebugReps.Arr = domplate(Firebug.Rep,
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- className: "array",
-
- supportsObject: function(object, type, context)
- {
- return this.isArray(object, context ? context.window : null);
- },
-
highlightObject: function(object, context, target)
{
- // Highlighting huge amount of elements on the page can cause sericous performance
+ // Highlighting huge amount of elements on the page can cause serious performance
// problems (see issue 4736). So, avoid highlighting if the number of elements in
// the array exceeds specified limit.
var arr = this.getRealObject(object, context);
var limit = Options.get("multiHighlightLimit");
if (!arr || (limit > 0 && arr.length > limit))
{
- if (Css.hasClass(target, "arrayLeftBracket ") ||
+ if (Css.hasClass(target, "arrayLeftBracket") ||
Css.hasClass(target, "arrayRightBracket"))
{
var tooltip = Locale.$STRF("console.multiHighlightLimitExceeded", [limit]);
@@ -695,61 +694,160 @@ FirebugReps.Arr = domplate(Firebug.Rep,
Firebug.Inspector.highlightObject(arr, context);
},
- // http://code.google.com/p/fbug/issues/detail?id=874
- // BEGIN Yahoo BSD Source (modified here) YAHOO.lang.isArray, YUI 2.2.2 June 2007
- isArray: function(obj, win)
+ isArray: function(obj)
{
- win = win || window;
+ return false;
+ }
+});
+
+// ********************************************************************************************* //
+
+FirebugReps.Arr = domplate(FirebugReps.ArrBase,
+{
+ tag:
+ OBJECTBOX({_repObject: "$object",
+ $hasTwisty: "$object|hasSpecialProperties",
+ onclick: "$onToggleProperties"},
+ SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
+ FOR("item", "$object|longArrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
+ ),
+ SPAN({"class": "arrayRightBracket", role: "presentation"}, "]"),
+ SPAN({"class": "arrayProperties", role: "group"})
+ ),
- var view = Wrapper.getContentView(win);
+ shortTag:
+ OBJECTBOX({_repObject: "$object",
+ $hasTwisty: "$object|hasSpecialProperties",
+ onclick: "$onToggleProperties"},
+ SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
+ FOR("item", "$object|shortArrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
+ ),
+ SPAN({"class": "arrayRightBracket"}, "]"),
+ SPAN({"class": "arrayProperties", role: "group"})
+ ),
+ // http://code.google.com/p/fbug/issues/detail?id=874
+ isArray: function(obj)
+ {
try
{
- if (!obj)
- return false;
- // do this first to avoid security 1000 errors
- else if (obj instanceof Ci.nsIDOMHistory)
- return false;
- // do this first to avoid security 1000 errors
- else if ("StorageList" in view && obj instanceof view.StorageList)
- return false;
- // do this first to avoid exceptions
- else if (obj.toString() === "[xpconnect wrapped native prototype]")
- return false;
- else if (isFinite(obj.length) && typeof obj.splice === "function")
+ if (Arr.isArray(obj))
return true;
else if (isFinite(obj.length) && typeof obj.callee === "function") // arguments
return true;
- else if (obj instanceof view.HTMLCollection)
- return true;
- else if (obj instanceof view.NodeList)
- return true;
}
- catch (exc)
- {
- try
- {
- if (FBTrace.DBG_ERRORS)
- {
- // Something weird: without the try/catch, OOM, with no exception??
- FBTrace.sysout("isArray FAILS: " + exc, exc);
- FBTrace.sysout("isArray Fails on obj " + obj);
- }
- }
- catch (exexc)
- {
- FBTrace.sysout("isArray double ERROR " + exexc, exexc);
- }
- }
-
+ catch (exc) {}
return false;
+ }
+});
+
+// ********************************************************************************************* //
+
+/**
+ * Any arrayish object that is not directly Array type (e.g. HTMLCollection, NodeList, etc.)
+ */
+FirebugReps.ArrayLikeObject = domplate(FirebugReps.ArrBase,
+{
+ tag:
+ OBJECTBOX({_repObject: "$object",
+ $hasTwisty: "$object|hasSpecialProperties",
+ onclick: "$onToggleProperties"},
+ A({"class": "objectTitle objectLink", onclick: "$onClickTitle"},
+ "$object|getTitle"
+ ),
+ SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
+ FOR("item", "$object|longArrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
+ ),
+ SPAN({"class": "arrayRightBracket", role: "presentation"}, "]"),
+ SPAN({"class": "arrayProperties", role: "group"})
+ ),
+
+ shortTag:
+ OBJECTBOX({_repObject: "$object",
+ $hasTwisty: "$object|hasSpecialProperties",
+ onclick: "$onToggleProperties"},
+ A({"class": "objectTitle objectLink", onclick: "$onClickTitle"},
+ "$object|getTitle"
+ ),
+ SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
+ FOR("item", "$object|shortArrayIterator",
+ TAG("$item.tag", {object: "$item.object"}),
+ SPAN({"class": "arrayComma", role: "presentation"}, "$item.delim")
+ ),
+ SPAN({"class": "arrayRightBracket"}, "]"),
+ SPAN({"class": "arrayProperties", role: "group"})
+ ),
+
+ onClickTitle: function(event)
+ {
+ var obj = Firebug.getRepObject(event.target);
+ Firebug.chrome.select(obj);
},
- // END Yahoo BSD SOURCE See license below.
- getTitle: function(object, context)
+ getTitle: function(obj, context)
{
- return "[" + object.length + "]";
- }
+ var arr = Wrapper.unwrapObject(obj);
+ const re =/\[object ([^\]]*)/;
+ var label = Str.safeToString(arr);
+ var m = re.exec(label);
+ if (m)
+ return m[1] || label;
+
+ if ((arr instanceof Ci.nsIDOMDOMTokenList) || (this.isTokenList_Fx19(obj)))
+ return "DOMTokenList";
+
+ return "";
+ },
+
+ isArray: function(obj)
+ {
+ if (this.isArrayLike_Fx19(obj))
+ return true;
+
+ return Arr.isArrayLike(obj);
+ },
+
+ /**
+ * Hack for Firefox 19 where obj instanceof Ci.nsIDOMDOMTokenList doesn't work.
+ */
+ isTokenList_Fx19: function(obj)
+ {
+ var context = Firebug.currentContext;
+ if (!context)
+ return false;
+
+ var view = Wrapper.getContentView(context.window);
+ if (!view)
+ return false;
+
+ obj = Wrapper.unwrapObject(obj);
+ return (obj instanceof view.DOMTokenList);
+ },
+
+ /**
+ * Hack for Firefox 19 where obj instanceof Ci.nsIDOMDOMTokenList,
+ * Ci.nsIDOMHTMLCollection and nsIDOMNodeList doesn't work.
+ */
+ isArrayLike_Fx19: function(obj)
+ {
+ var context = Firebug.currentContext;
+ if (!context)
+ return false;
+
+ var view = Wrapper.getContentView(context.window);
+ if (!view)
+ return false;
+
+ obj = Wrapper.unwrapObject(obj);
+ return (obj instanceof view.DOMTokenList) || (obj instanceof view.HTMLCollection) ||
+ (obj instanceof view.NodeList);
+ },
});
// ********************************************************************************************* //
@@ -910,14 +1008,12 @@ FirebugReps.Element = domplate(Firebug.Rep,
{
try
{
- return elt.getAttribute("class")
- ? ("." + elt.getAttribute("class").split(" ")[0])
- : "";
+ return elt.classList.length > 0 ? ("." + elt.classList[0]) : "";
}
catch (err)
{
+ return "";
}
- return "";
},
getValue: function(elt)
@@ -1054,6 +1150,57 @@ FirebugReps.Element = domplate(Firebug.Rep,
System.copyToClipboard(csspath);
},
+ paste: function(elt, clipboardContent, mode)
+ {
+ if (elt instanceof window.HTMLElement)
+ return this.pasteHTML.apply(this, arguments);
+ else
+ return this.pasteXML.apply(this, arguments);
+ },
+
+ pasteHTML: function(elt, clipboardContent, mode)
+ {
+ if (mode === "replaceInner")
+ elt.innerHTML = clipboardContent;
+ else if (mode === "replaceOuter")
+ elt.outerHTML = clipboardContent;
+ else
+ elt.insertAdjacentHTML(mode, clipboardContent);
+ },
+
+ pasteXML: function(elt, clipboardContent, mode)
+ {
+ var contextNode, parentNode = elt.parentNode;
+ if (["beforeBegin", "afterEnd", "replaceOuter"].indexOf(mode) >= 0)
+ contextNode = parentNode;
+ else
+ contextNode = elt;
+
+ var pastedElements = Dom.markupToDocFragment(clipboardContent, contextNode);
+ switch (mode)
+ {
+ case "beforeBegin":
+ parentNode.insertBefore(pastedElements, elt);
+ break;
+ case "afterBegin":
+ elt.insertBefore(pastedElements, elt.firstChild);
+ break;
+ case "beforeEnd":
+ elt.appendChild(pastedElements);
+ break;
+ case "afterEnd":
+ Dom.insertAfter(pastedElements, elt);
+ break;
+ case "replaceInner":
+ Dom.eraseNode(elt);
+ elt.appendChild(pastedElements);
+ break;
+ case "replaceOuter":
+ parentNode.replaceChild(pastedElements, elt);
+ break;
+ }
+ },
+
persistor: function(context, xpath)
{
var elts = xpath
@@ -1111,9 +1258,14 @@ FirebugReps.Element = domplate(Firebug.Rep,
getContextMenuItems: function(elt, target, context)
{
+ // XXX: Temporary fix for issue 5577.
+ if (Dom.getAncestorByClass(target, "cssElementRuleContainer"))
+ return;
+
var type;
- var monitored = EventMonitor.areEventsMonitored(elt, null, context);
var items = [];
+ var clipboardContent = System.getStringDataFromClipboard();
+ var isEltRoot = (elt === elt.ownerDocument.documentElement);
if (Xml.isElementHTML(elt) || Xml.isElementXHTML(elt))
type = "HTML";
@@ -1155,6 +1307,57 @@ FirebugReps.Element = domplate(Firebug.Rep,
tooltiptext: "html.tip.Copy_CSS_Path",
id: "fbCopyCSSPath",
command: Obj.bindFixed(this.copyCSSPath, this, elt)
+ },
+ {
+ label: Locale.$STRF("html.menu.Paste", [type]),
+ tooltiptext: Locale.$STRF("html.tip.Paste", [type]),
+ disabled: !clipboardContent,
+ id: "fbPaste",
+ items: [
+ {
+ label: "html.menu.Paste_Replace_Content",
+ tooltiptext: "html.tip.Paste_Replace_Content",
+ id: "fbPasteReplaceInner",
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent,
+ "replaceInner")
+ },
+ {
+ label: "html.menu.Paste_Replace_Node",
+ tooltiptext: "html.tip.Paste_Replace_Node",
+ id: "fbPasteReplaceOuter",
+ disabled: isEltRoot,
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent,
+ "replaceOuter")
+ },
+ {
+ label: "html.menu.Paste_AsFirstChild",
+ tooltiptext: "html.tip.Paste_AsFirstChild",
+ id: "fbPasteFirstChild",
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent,
+ "afterBegin")
+ },
+ {
+ label: "html.menu.Paste_AsLastChild",
+ tooltiptext: "html.tip.Paste_AsLastChild",
+ id: "fbPasteLastChild",
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent, "beforeEnd")
+ },
+ {
+ label: "html.menu.Paste_Before",
+ tooltiptext: "html.tip.Paste_Before",
+ id: "fbPasteBefore",
+ disabled: isEltRoot,
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent,
+ "beforeBegin")
+ },
+ {
+ label: "html.menu.Paste_After",
+ tooltiptext: "html.tip.Paste_After",
+ id: "fbPasteAfter",
+ disabled: isEltRoot,
+ command: Obj.bindFixed(this.paste, this, elt, clipboardContent, "afterEnd")
+ }
+ ]
}
]);
@@ -1178,9 +1381,12 @@ FirebugReps.Element = domplate(Firebug.Rep,
tooltiptext: "html.tip.Show_Events_In_Console",
id: "fbShowEventsInConsole",
type: "checkbox",
- checked: monitored,
- command: Obj.bindFixed(EventMonitor.toggleMonitorEvents,
- EventMonitor, elt, null, monitored, context)
+ checked: EventMonitor.areEventsMonitored(elt, null, context),
+ command: function()
+ {
+ var checked = this.hasAttribute("checked");
+ EventMonitor.toggleMonitorEvents(elt, null, !checked, context);
+ }
},
"-",
{
@@ -1239,7 +1445,6 @@ FirebugReps.TextNode = domplate(Firebug.Rep,
// ********************************************************************************************* //
-var regexpConstructorRE = /RegExp/;
FirebugReps.RegExp = domplate(Firebug.Rep,
{
tag:
@@ -1255,8 +1460,7 @@ FirebugReps.RegExp = domplate(Firebug.Rep,
{
try
{
- return type == "object" && object && object.constructor && object.constructor.toString &&
- regexpConstructorRE.test(object.constructor.toString());
+ return type == "object" && Object.prototype.toString.call(object) === "[object RegExp]";
}
catch (err)
{
@@ -1591,20 +1795,29 @@ FirebugReps.Window = domplate(Firebug.Rep,
FirebugReps.Event = domplate(Firebug.Rep,
{
- tag: TAG("$copyEventTag", {object: "$object|copyEvent"}),
+ className: "event",
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ tag:
+ TAG("$copyEventTag", {object: "$object|copyEvent"}),
copyEventTag:
OBJECTLINK("$object|summarizeEvent"),
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
summarizeEvent: function(event)
{
- var info = [event.type, ' '];
+ var info = [event.type, " "];
var eventFamily = Events.getEventFamily(event.type);
if (eventFamily == "mouse")
info.push("clientX=", event.clientX, ", clientY=", event.clientY);
else if (eventFamily == "key")
info.push("charCode=", event.charCode, ", keyCode=", event.keyCode);
+ else if (event.type == "message")
+ info.push("origin=", event.origin, ", data=", event.data);
return info.join("");
},
@@ -1616,8 +1829,6 @@ FirebugReps.Event = domplate(Firebug.Rep,
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- className: "object",
-
supportsObject: function(object, type)
{
return object instanceof window.Event || object instanceof Dom.EventCopy;
@@ -1631,6 +1842,52 @@ FirebugReps.Event = domplate(Firebug.Rep,
// ********************************************************************************************* //
+FirebugReps.EventLog = domplate(FirebugReps.Event,
+{
+ className: "eventLog",
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ tag:
+ TAG("$copyEventTag", {object: "$object|copyEvent"}),
+
+ copyEventTag:
+ SPAN(
+ OBJECTLINK("$object|summarizeEvent"),
+ SPAN(" "),
+ SPAN("»"),
+ SPAN(" "),
+ TAG("$object|getTargetTag", {object: "$object|getTarget"})
+ ),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ copyEvent: function(log)
+ {
+ return new Dom.EventCopy(log.event);
+ },
+
+ getTarget: function(event)
+ {
+ return event.target;
+ },
+
+ getTargetTag: function(event)
+ {
+ var rep = Firebug.getRep(event.target);
+ return rep.shortTag ? rep.shortTag : rep.tag;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ supportsObject: function(object, type)
+ {
+ return object instanceof EventMonitor.EventLog;
+ },
+});
+
+// ********************************************************************************************* //
+
FirebugReps.SourceLink = domplate(Firebug.Rep,
{
tag:
@@ -2289,12 +2546,13 @@ FirebugReps.ErrorMessage = domplate(Firebug.Rep,
// so let's try to skip those
if (error.source)
return "syntax";
- else if (error.lineNo == 1 && Url.getFileExtension(error.href) != "js")
- return "none";
else if (error.category == "css")
return "show";
else if (!error.href || !error.lineNo)
return "none";
+ // Why do we have that at all?
+ else if (error.lineNo == 1 && Url.getFileExtension(error.href) != "js")
+ return "none";
else
return "show";
},
@@ -2573,9 +2831,9 @@ FirebugReps.nsIDOMHistory = domplate(Firebug.Rep,
try
{
var items = history.length;
- return items + " history entries";
+ return Locale.$STRP("firebug.reps.historyEntries", [items]);
}
- catch(exc)
+ catch (exc)
{
return "object does not support history (nsIDOMHistory)";
}
@@ -2586,7 +2844,7 @@ FirebugReps.nsIDOMHistory = domplate(Firebug.Rep,
try
{
var history = event.currentTarget.repObject;
- var items = history.length; // if this throws, then unsupported
+ history.length; // if this throws, then unsupported
Firebug.chrome.select(history);
}
catch (exc)
@@ -2759,112 +3017,6 @@ FirebugReps.Storage = domplate(Firebug.Rep,
// ********************************************************************************************* //
-FirebugReps.StorageList = domplate(Firebug.Rep,
-{
- tag:
- OBJECTLINK(
- SPAN({"class": "storageTitle"}, "$object|summarize "),
- FOR("prop", "$object|longPropIterator",
- "$prop.name",
- SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
- TAG("$prop.tag", {object: "$prop.object"}),
- SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
- )
- ),
-
- shortTag:
- OBJECTLINK({onclick: "$onClick"},
- SPAN({"class": "storageTitle"}, "$object|summarize "),
- FOR("prop", "$object|shortPropIterator",
- "$prop.name",
- SPAN({"class": "objectEqual", role: "presentation"}, "$prop.equal"),
- TAG("$prop.tag", {object: "$prop.object"}),
- SPAN({"class": "objectComma", role: "presentation"}, "$prop.delim")
- )
- ),
-
- onClick: function(event)
- {
- var globalStorage = event.currentTarget.repObject;
- var context = Firebug.currentContext;
- var domain = context.window.location.hostname;
-
- Firebug.chrome.select(globalStorage.namedItem(domain));
- Events.cancelEvent(event);
- },
-
- summarize: function(globalStorage)
- {
- try
- {
- var context = Firebug.currentContext;
- var domain = context.window.location.hostname;
- var length = globalStorage.namedItem(domain).length;
- return Locale.$STRP("firebug.storage.totalItems", [length]) + " ";
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("reps.StorageList.summarize; EXCEPTION " + e, e);
- }
- return "";
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
- className: "StorageList",
-
- supportsObject: function(object, type)
- {
- return ("StorageList" in window && object instanceof window.StorageList);
- },
-
- getRealObject: function(object, context)
- {
- try
- {
- var domain = context.window.location.hostname;
- return globalStorage.namedItem(domain);
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("reps.StorageList.getRealObject; EXCEPTION " + e, e);
- }
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- // Iterator
-
- longPropIterator: function(object)
- {
- return this.propIterator(object, 100);
- },
-
- shortPropIterator: function(object)
- {
- return this.propIterator(object, Options.get("ObjectShortIteratorMax"));
- },
-
- propIterator: function(object, max)
- {
- try
- {
- var context = Firebug.currentContext;
- var domain = context.window.location.hostname;
- return FirebugReps.Storage.propIterator(object.namedItem(domain), max);
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("reps.StorageList.propIterator; EXCEPTION " + e, e);
- }
- return [];
- },
-});
-
-// ********************************************************************************************* //
-
FirebugReps.XPathResult = domplate(FirebugReps.Arr,
{
className: "array xPathResult",
@@ -3034,7 +3186,7 @@ FirebugReps.NamedNodeMap = domplate(Firebug.Rep,
),
shortTag:
- OBJECTLINK({onclick: "$onClick"},
+ OBJECTLINK(
SPAN({"class": "arrayLeftBracket", role: "presentation"}, "["),
FOR("prop", "$object|shortPropIterator",
SPAN({"class": "nodeName"}, "$prop.name"),
@@ -3045,16 +3197,6 @@ FirebugReps.NamedNodeMap = domplate(Firebug.Rep,
SPAN({"class": "arrayRightBracket", role: "presentation"}, "]")
),
- onClick: function(event)
- {
- var globalStorage = event.currentTarget.repObject;
- var context = Firebug.currentContext;
- var domain = context.window.location.hostname;
-
- Firebug.chrome.select(globalStorage.namedItem(domain));
- Events.cancelEvent(event);
- },
-
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
className: "NamedNodeMap",
@@ -3181,14 +3323,14 @@ FirebugReps.ErrorCopy = function(message)
// Registration
Firebug.registerRep(
- FirebugReps.nsIDOMHistory, // make this early to avoid exceptions
FirebugReps.Undefined,
FirebugReps.Null,
FirebugReps.Number,
- FirebugReps.RegExp,
FirebugReps.String,
+ FirebugReps.nsIDOMHistory, // make this early to avoid exceptions
+ FirebugReps.ApplicationCache, // this also
+ FirebugReps.RegExp,
FirebugReps.Window,
- FirebugReps.ApplicationCache, // must come before Arr (array) else exceptions.
FirebugReps.ErrorMessage,
FirebugReps.Element,
FirebugReps.TextNode,
@@ -3205,13 +3347,14 @@ Firebug.registerRep(
FirebugReps.Except,
FirebugReps.XML,
FirebugReps.Arr,
+ FirebugReps.ArrayLikeObject,
FirebugReps.XPathResult,
FirebugReps.Storage,
- FirebugReps.StorageList,
FirebugReps.Attr,
FirebugReps.Date,
FirebugReps.NamedNodeMap,
- FirebugReps.Reference
+ FirebugReps.Reference,
+ FirebugReps.EventLog
);
Firebug.setDefaultReps(FirebugReps.Func, FirebugReps.Obj);
@@ -3220,43 +3363,3 @@ return Firebug.Reps = FirebugReps;
// ********************************************************************************************* //
}});
-
-// ********************************************************************************************* //
-
-/*
- * The following is http://developer.yahoo.com/yui/license.txt and applies to only code labeled
- * "Yahoo BSD Source" in only this file reps.js. John J. Barton June 2007.
- *
-Software License Agreement (BSD License)
-
-Copyright (c) 2006, Yahoo! Inc.
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms, with or without modification, are
-permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of Yahoo! Inc. nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of Yahoo! Inc.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/tabContext.js b/trace/FBTrace/chrome/firebug/content/chrome/tabContext.js
index ea334f6..4ca0aa9 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/tabContext.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/tabContext.js
@@ -215,7 +215,7 @@ Firebug.TabContext.prototype =
// to iframes (documents), which can be already unloaded at this point.
// Removing listeners from such 'unloaded' documents (or window) can throw
// "TypeError: can't access dead object"
- // We should avoid these exceptions (event if they are not representing mem leaks)
+ // We should avoid these exceptions (even if they are not representing memory leaks)
this.unregisterAllListeners();
state.panelState = {};
@@ -350,7 +350,7 @@ Firebug.TabContext.prototype =
catch (exc)
{
if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("tabContext.destroy FAILS "+exc, exc);
+ FBTrace.sysout("tabContext.destroy FAILS (" + panelName + ") " + exc, exc);
// the destroy failed, don't keep the bad state
delete state.panelState[panelName];
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/tabWatcher.js b/trace/FBTrace/chrome/firebug/content/chrome/tabWatcher.js
index f08513a..5103f10 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/tabWatcher.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/tabWatcher.js
@@ -99,7 +99,16 @@ Firebug.TabWatcher = Obj.extend(new Firebug.Listener(),
var tabBrowser = Firefox.getElementById("content");
if (tabBrowser)
{
- tabBrowser.removeProgressListener(TabProgressListener);
+ try
+ {
+ // Exception thrown: tabBrowser.removeProgressListener is not a function
+ // when Firebug is in detached state and the origin browser window is closed.
+ tabBrowser.removeProgressListener(TabProgressListener);
+ }
+ catch (e)
+ {
+ FBTrace.sysout("tabWatcher.destroy; EXCEPTION " + e, e);
+ }
var browsers = Firefox.getBrowsers();
for (var i = 0; i < browsers.length; ++i)
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/tableRep.js b/trace/FBTrace/chrome/firebug/content/chrome/tableRep.js
index eb230f0..aad5f43 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/tableRep.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/tableRep.js
@@ -19,10 +19,10 @@ with (Domplate) {
FirebugReps.Table = domplate(Firebug.Rep,
{
className: "table",
-
+ tableClassName: "dataTable",
tag:
DIV({"class": "dataTableSizer", "tabindex": "-1" },
- TABLE({"class": "dataTable", cellspacing: 0, cellpadding: 0, width: "100%",
+ TABLE({"class": "$tableClassName", cellspacing: 0, cellpadding: 0, width: "100%",
"role": "grid"},
THEAD({"class": "dataTableThead", "role": "presentation"},
TR({"class": "headerRow focusRow dataTableRow subFocusRow", "role": "row",
@@ -194,7 +194,7 @@ FirebugReps.Table = domplate(Firebug.Rep,
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Console logging
- log: function(data, cols, context)
+ log: function(data, cols, context, object)
{
// No arguments passed into console.table method, bail out for now,
// but some error message could be displayed in the future.
@@ -211,7 +211,12 @@ FirebugReps.Table = domplate(Firebug.Rep,
try
{
this.columns = columns;
- var row = Firebug.Console.log({data: data, columns: columns}, context, "table", this, true);
+
+ var object = object || {};
+ object.data = data;
+ object.columns = columns;
+
+ var row = Firebug.Console.log(object, context, "table", this, true);
// Set vertical height for scroll bar.
var tBody = row.querySelector(".dataTableTbody");
diff --git a/trace/FBTrace/chrome/firebug/content/chrome/window.js b/trace/FBTrace/chrome/firebug/content/chrome/window.js
index 5759451..1a97330 100644
--- a/trace/FBTrace/chrome/firebug/content/chrome/window.js
+++ b/trace/FBTrace/chrome/firebug/content/chrome/window.js
@@ -101,9 +101,17 @@ Win.getRootWindow = function(win)
{
for (; win; win = win.parent)
{
- if (!win.parent || win == win.parent || !(win.parent instanceof win.Window) )
+ if (!win.parent || win == win.parent)
+ return win;
+
+ // When checking the 'win.parent' type we need to use the target
+ // type from the same scope. i.e. from win.parent
+ // Iframes from different domains can use different Window type than
+ // the top level window.
+ if (!(win.parent instanceof win.parent.Window))
return win;
}
+
return null;
};
diff --git a/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js b/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
index 225feec..2a23b88 100644
--- a/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
+++ b/trace/FBTrace/chrome/firebug/content/console/autoCompleter.js
@@ -4,7 +4,6 @@ define([
"firebug/lib/object",
"firebug/firebug",
"firebug/lib/domplate",
- "firebug/chrome/reps",
"firebug/lib/locale",
"firebug/lib/events",
"firebug/lib/wrapper",
@@ -13,14 +12,11 @@ define([
"firebug/lib/array",
"firebug/editor/editor"
],
-function(Obj, Firebug, Domplate, FirebugReps, Locale, Events, Wrapper, Dom, Str, Arr, Editor) {
+function(Obj, Firebug, Domplate, Locale, Events, Wrapper, Dom, Str, Arr, Editor) {
// ********************************************************************************************* //
// Constants
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-
const kwActions = ["throw", "return", "in", "instanceof", "delete", "new",
"typeof", "void", "yield"];
const reOpenBracket = /[\[\(\{]/;
@@ -28,6 +24,8 @@ const reCloseBracket = /[\]\)\}]/;
const reJSChar = /[a-zA-Z0-9$_]/;
const reLiteralExpr = /^[ "0-9,]*$/;
+var measureCache = {};
+
// ********************************************************************************************* //
// JavaScript auto-completion
@@ -44,7 +42,9 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionBase = {
pre: null,
expr: null,
- candidates: []
+ forceShowPopup: false,
+ candidates: [],
+ hiddenCandidates: []
};
this.completions = null;
@@ -79,7 +79,9 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completionBase = {
pre: null,
expr: null,
- candidates: []
+ forceShowPopup: false,
+ candidates: [],
+ hiddenCandidates: []
};
this.completions = null;
@@ -94,6 +96,7 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.hideForExpression = function()
{
this.completionBase.candidates = [];
+ this.completionBase.hiddenCandidates = [];
this.completions = null;
this.showCompletions(false);
@@ -183,14 +186,17 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
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
+ // changed (we can ignore completionBase.pre since completions do not
// depend upon that).
if (preExpr !== this.completionBase.expr)
{
this.completionBase.expr = preExpr;
- this.completionBase.candidates = autoCompleteEval(context, preExpr, spreExpr,
+ var ev = autoCompleteEval(context, preExpr, spreExpr,
this.options.includeCurrentScope);
prevCompletions = null;
+ this.completionBase.candidates = ev.completions;
+ this.completionBase.hiddenCandidates = ev.hiddenCompletions;
+ this.completionBase.forceShowPopup = false;
}
this.createCompletions(prop, prevCompletions);
@@ -205,41 +211,60 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
*/
this.createCompletions = function(prefix, prevCompletions)
{
- var candidates = this.completionBase.candidates;
- var valid = [], ciValid = [];
-
if (!this.completionBase.expr && !prefix)
{
// Don't complete "".
this.completions = null;
return;
}
+ if (!this.completionBase.candidates.length && !prefix)
+ {
+ // Don't complete empty objects -> toString.
+ this.completions = null;
+ return;
+ }
+ var mustMatchFirstLetter = (this.completionBase.expr === "");
+ var clist = [
+ this.completionBase.candidates,
+ this.completionBase.hiddenCandidates
+ ], cind = 0;
+ var valid = [], ciValid = [];
var lowPrefix = prefix.toLowerCase();
- for (var i = 0; i < candidates.length; ++i)
+ while (ciValid.length === 0 && cind < 2)
{
- // 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 candidates = clist[cind];
+ for (var i = 0; i < candidates.length; ++i)
{
- var ch = prefix.charAt(j);
- if (ch !== ch.toLowerCase() && ch !== name.charAt(j))
+ // Mark a candidate as matching if it matches the prefix case-
+ // insensitively, and shares its upper-case characters. The
+ // exception to this is that for global completions, the first
+ // character must match exactly (see issue 6030).
+ var name = candidates[i];
+ if (!Str.hasPrefix(name.toLowerCase(), lowPrefix))
+ continue;
+
+ if (mustMatchFirstLetter && name.charAt(0) !== prefix.charAt(0))
+ continue;
+
+ var fail = false;
+ for (var j = 0; j < prefix.length; ++j)
{
- fail = true;
- break;
+ 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 (!fail)
- {
- ciValid.push(name);
- if (Str.hasPrefix(name, prefix))
- valid.push(name);
- }
+ ++cind;
}
if (ciValid.length > 0)
@@ -250,18 +275,16 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.completions = {
list: (hasMatchingCase ? valid : ciValid),
- prefix: prefix
+ prefix: prefix,
+ hidePopup: (cind === 2)
};
this.completions.index = this.pickDefaultCandidate(prevCompletions);
if (hasMatchingCase)
{
var find = valid[this.completions.index];
- this.completions = {
- list: ciValid,
- prefix: prefix,
- index: ciValid.indexOf(find)
- };
+ this.completions.list = ciValid;
+ this.completions.index = ciValid.indexOf(find);
}
}
else
@@ -290,11 +313,13 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
// Special-case certain expressions.
var special = {
- "": ["document", "console", "window", "parseInt", "undefined"],
+ "": ["document", "console", "frames", "window", "parseInt", "undefined",
+ "Array", "Math", "Object", "String", "XMLHttpRequest", "Window"],
"window.": ["console"],
"location.": ["href"],
"document.": ["getElementById", "addEventListener", "createElement",
- "documentElement"]
+ "documentElement"],
+ "Object.prototype.toString": ["call"]
};
if (special.hasOwnProperty(this.completionBase.expr))
{
@@ -312,12 +337,32 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
}
}
+ // 'prototype' is a good default if it exists.
+ ind = list.indexOf("prototype");
+ if (ind !== -1)
+ return ind;
+
ind = 0;
for (var i = 1; i < list.length; ++i)
{
if (list[i].length < list[ind].length)
ind = i;
}
+
+ // Avoid some completions in favor of others.
+ var replacements = {
+ "toSource": "toString",
+ "toFixed": "toString",
+ "watch": "toString",
+ "pattern": "parentNode"
+ };
+ if (replacements.hasOwnProperty(list[ind]))
+ {
+ var ind2 = list.indexOf(replacements[list[ind]]);
+ if (ind2 !== -1)
+ return ind2;
+ }
+
return ind;
};
@@ -378,12 +423,16 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
{
this.completionBox.value = this.getCompletionBoxValue();
- var show = this.showCompletionPopup ||
- (this.completionPopup && this.completionPopup.state === "open");
- if (show && this.completions && this.completions.list.length > 1)
+ if (this.completions && (this.completionBase.forceShowPopup ||
+ (this.completions.list.length > 1 && this.showCompletionPopup &&
+ !this.completions.hidePopup)))
+ {
this.popupCandidates(cycling);
+ }
else
+ {
this.closePopup();
+ }
};
/**
@@ -498,20 +547,24 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
// does not close itself and prevent event propagation on keypress.
// (Unless the popup is only open due to Ctrl+Space, in which case
// that's precisely what we want.)
- if (this.showCompletionPopup)
+ if (!this.forceShowPopup)
this.closePopup();
}
else if (event.keyCode === KeyEvent.DOM_VK_SPACE && Events.isControl(event))
{
- // Force-show the completion popup.
if (!this.completions)
{
// If completions have been hidden, show them again.
this.hide();
this.complete(context);
}
- if (this.completionPopup && this.completions)
+
+ if (this.completions && !this.isPopupOpen())
+ {
+ // Force-show the completion popup.
+ this.completionBase.forceShowPopup = true;
this.popupCandidates(false);
+ }
}
};
@@ -640,12 +693,12 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
this.selectedPopupElement = null;
var vbox = this.completionPopup.ownerDocument.createElement("vbox");
- this.completionPopup.appendChild(vbox);
vbox.classList.add("fbCommandLineCompletions");
+ this.completionPopup.appendChild(vbox);
var title = this.completionPopup.ownerDocument.
- createElementNS("http://www.w3.org/1999/xhtml","div");
- title.innerHTML = Locale.$STR("console.Use Arrow keys, Tab or Enter");
+ createElementNS("http://www.w3.org/1999/xhtml", "div");
+ title.textContent = Locale.$STR("console.Use Arrow keys, Tab or Enter");
title.classList.add("fbPopupTitle");
vbox.appendChild(title);
@@ -696,25 +749,23 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
for (var i = this.popupTop; i < this.popupBottom; i++)
{
- var completion = list[i];
var prefixLen = this.completions.prefix.length;
+ var completion = list[i];
var hbox = this.completionPopup.ownerDocument.
- createElementNS("http://www.w3.org/1999/xhtml","div");
+ createElementNS("http://www.w3.org/1999/xhtml", "div");
hbox.completionIndex = i;
var pre = this.completionPopup.ownerDocument.
- createElementNS("http://www.w3.org/1999/xhtml","span");
- var preText = this.textBox.value;
- if (prefixLen)
- preText = preText.slice(0, -prefixLen) + completion.slice(0, prefixLen);
- pre.innerHTML = Str.escapeForTextNode(preText);
+ createElementNS("http://www.w3.org/1999/xhtml", "span");
+ var preText = this.completionBase.expr + completion.substr(0, prefixLen);
+ pre.textContent = preText;
pre.classList.add("userTypedText");
var post = this.completionPopup.ownerDocument.
- createElementNS("http://www.w3.org/1999/xhtml","span");
+ createElementNS("http://www.w3.org/1999/xhtml", "span");
var postText = completion.substr(prefixLen);
- post.innerHTML = Str.escapeForTextNode(postText);
+ post.textContent = postText;
post.classList.add("completionText");
if (i === selIndex)
@@ -728,7 +779,24 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
if (this.selectedPopupElement)
this.selectedPopupElement.setAttribute("selected", "true");
- this.completionPopup.openPopup(this.textBox, "before_start", 0, 0, false, false);
+ // Open the popup at the pixel position of the start of the completed
+ // expression. The text length times the width of a single character,
+ // plus apparent padding, is a good enough approximation of this.
+ var chWidth = this.getCharWidth(this.completionBase.pre);
+ var offsetX = Math.round(this.completionBase.pre.length * chWidth) + 2;
+ this.completionPopup.openPopup(this.textBox, "before_start", offsetX, 0, false, false);
+ };
+
+ this.getCharWidth = function(text)
+ {
+ var size = Firebug.textSize;
+ if (!measureCache[size])
+ {
+ var measurer = this.options.popupMeasurer;
+ measurer.style.fontSizeAdjust = this.textBox.style.fontSizeAdjust;
+ measureCache[size] = measurer.offsetWidth / 60;
+ }
+ return measureCache[size];
};
this.isPopupOpen = function()
@@ -825,25 +893,6 @@ Firebug.JSAutoCompleter = function(textBox, completionBox, options)
// ********************************************************************************************* //
/**
- * A dummy auto-completer, set as current by CommandLine.setAutoCompleter when
- * no completion is supposed to be done (such as in the large command line,
- * currently, or when there is no context).
- */
-Firebug.EmptyJSAutoCompleter = function()
-{
- this.empty = true;
- this.shutdown = function() {};
- this.hide = function() {};
- this.complete = function() {};
- this.acceptReturn = function() { return true; };
- this.revert = function() { return false; };
- this.handleKeyDown = function() {};
- this.handleKeyPress = function() {};
-};
-
-// ********************************************************************************************* //
-
-/**
* An (abstract) editor with simple JavaScript auto-completion.
*/
Firebug.JSEditor = function()
@@ -1271,8 +1320,7 @@ function killCompletions(expr, origExpr)
}
// Types the autocompletion knows about, some of their non-enumerable properties,
-// and the return types of some member functions, included in the Firebug.CommandLine
-// object to make it more easily extensible.
+// and the return types of some member functions.
var AutoCompletionKnownTypes = {
"void": {
@@ -1457,9 +1505,8 @@ var AutoCompletionKnownTypes = {
"tan": "|Number"
},
"Number": {
- // There are also toFixed and valueOf, but they are left out because
- // they steal focus from toString by being shorter (in the case of
- // toFixed), and because they are used very seldom.
+ "valueOf": "|Number",
+ "toFixed": "|String",
"toExponential": "|String",
"toPrecision": "|String",
"toLocaleString": "|String",
@@ -1471,8 +1518,7 @@ var LinkType = {
"PROPERTY": 0,
"INDEX": 1,
"CALL": 2,
- "SAFECALL": 3,
- "RETVAL_HEURISTIC": 4
+ "RETVAL_HEURISTIC": 3
};
function getKnownType(t)
@@ -1535,77 +1581,178 @@ function getTypeExtractionExpression(command)
return ret;
}
-function propChainBuildComplete(out, context, tempExpr, result)
+/**
+ * Compare two property names a and b with a custom sort order. The comparison
+ * is lexicographical, but treats _ as higher than other letters in the
+ * beginning of the word, so that:
+ * $ < AutoCompleter < add_widget < additive < _ < _priv < __proto__
+ * @return -1, 0 or 1 depending on whether (a < b), (a == b) or (a > b).
+ */
+function comparePropertyNames(lhs, rhs)
{
- var complete = null, command = null;
- if (tempExpr.fake)
+ var len = Math.min(lhs.length, rhs.length);
+ for (var i = 0; i < len; ++i)
{
- var name = tempExpr.value.val;
- complete = getFakeCompleteKeys(name);
- if (!getKnownType(name)._fb_ignorePrototype)
- command = name + ".prototype";
+ var u1 = (lhs.charAt(i) === "_");
+ var u2 = (rhs.charAt(i) === "_");
+ if (!u1 && !u2)
+ break;
+ if (!u1 || !u2)
+ return (u1 ? 1 : -1);
}
- else
+
+ if (lhs < rhs)
+ return -1;
+ return (lhs === rhs ? 0 : 1);
+}
+
+function propertiesToHide(expr, obj)
+{
+ var ret = [];
+
+ // __{define,lookup}[SG]etter__ appear as own properties on lots of DOM objects.
+ ret.push("__defineGetter__", "__defineSetter__",
+ "__lookupGetter__", "__lookupSetter__");
+
+ // function.caller/argument are deprecated and ugly.
+ if (typeof obj === "function")
+ ret.push("caller", "arguments");
+
+ if (Object.prototype.toString.call(obj) === "[object String]")
+ {
+ // Unused, cluttery.
+ ret.push("toLocaleLowerCase", "toLocaleUpperCase", "quote", "bold",
+ "italics", "fixed", "fontsize", "fontcolor", "link", "anchor",
+ "strike", "small", "big", "blink", "sup", "sub");
+ }
+
+ if (expr === "" || expr === "window.")
+ {
+ // Internal Firefox things.
+ ret.push("getInterface", "Components", "XPCNativeWrapper",
+ "InstallTrigger", "WindowInternal", "DocumentXBL",
+ "startProfiling", "stopProfiling", "pauseProfilers",
+ "resumeProfilers", "dumpProfile", "netscape",
+ "BoxObject", "BarProp", "BrowserFeedWriter", "ChromeWindow",
+ "ElementCSSInlineStyle", "JSWindow", "NSEditableElement",
+ "NSRGBAColor", "NSEvent", "NSXPathExpression", "ToString",
+ "OpenWindowEventDetail", "Parser", "ParserJS", "Rect",
+ "RGBColor", "ROCSSPrimitiveValue", "RequestService",
+ "PaintRequest", "PaintRequestList", "WindowUtils",
+ "GlobalPropertyInitializer", "GlobalObjectConstructor"
+ );
+
+ // Hide ourselves.
+ ret.push("_FirebugCommandLine", "_firebug");
+ }
+
+ // Old and ugly.
+ if (expr === "document.")
+ ret.push("fgColor", "vlinkColor", "linkColor");
+ if (expr === "document.body.")
+ ret.push("link", "aLink", "vLink");
+
+ // Rather universal and feel like built-ins.
+ ret.push("valueOf", "toSource", "constructor", "QueryInterface");
+
+ return ret;
+}
+
+
+function setCompletionsFromObject(out, object, context)
+{
+ // 'object' is a user-level, non-null object.
+ try
{
- if (typeof result === "string")
+ var isObjectPrototype = function(obj)
{
- // Strings only have indices as properties, use the fake object
- // completions instead.
- tempExpr.fake = true;
- tempExpr.value = getKnownTypeInfo("String");
- propChainBuildComplete(out, context, tempExpr);
- return;
+ // Check if an object is "Object.prototype". This isn't as simple
+ // as 'obj === context.window.wrappedJSObject.Object.prototype' due
+ // to cross-window properties, nor just '!Object.getPrototypeOf(obj)'
+ // because of Object.create.
+ return !Object.getPrototypeOf(obj) && "hasOwnProperty" in obj;
+ }
+
+ var obj = object;
+ while (obj !== null)
+ {
+ var target = (isObjectPrototype(obj) ?
+ out.hiddenCompletions : out.completions);
+ target.push.apply(target, Object.getOwnPropertyNames(obj));
+ obj = Object.getPrototypeOf(obj);
+ }
+
+ // As a special case, when completing "Object.prototype." no properties
+ // should be hidden.
+ if (isObjectPrototype(object))
+ {
+ out.completions = out.hiddenCompletions;
+ out.hiddenCompletions = [];
}
- else if (FirebugReps.Arr.isArray(result, context.window))
- complete = nonNumericKeys(result);
else
- complete = Arr.keys(result);
- command = getTypeExtractionExpression(tempExpr.command);
+ {
+ // Hide a list of well-chosen annoying properties.
+ var hide = propertiesToHide(out.spreExpr, object);
+ var hideMap = Object.create(null);
+ for (var i = 0; i < hide.length; ++i)
+ hideMap[hide[i]] = 1;
+ var hideRegex = /^XUL[A-Za-z]+$/;
+
+ var newCompletions = [];
+ out.completions.forEach(function(prop)
+ {
+ if (prop in hideMap || hideRegex.test(prop))
+ out.hiddenCompletions.push(prop);
+ else
+ newCompletions.push(prop);
+ });
+ out.completions = newCompletions;
+ }
+
+ // Firefox hides __proto__ - add it back.
+ if ("__proto__" in object)
+ out.hiddenCompletions.push("__proto__");
}
+ catch (exc)
+ {
+ if (FBTrace.DBG_COMMANDLINE)
+ FBTrace.sysout("autoCompleter.getCompletionsFromPrototypeChain failed", exc);
+ }
+}
- var done = function()
+function propChainBuildComplete(out, context, tempExpr, result)
+{
+ var done = function(result)
{
- if (out.indexCompletion)
+ if (result !== undefined && result !== null)
{
- complete = complete.map(function(x)
+ if (typeof result !== "object" && typeof result !== "function")
{
- x = (out.indexQuoteType === '"') ? Str.escapeJS(x): Str.escapeSingleQuoteJS(x);
- return x + out.indexQuoteType + "]";
- });
+ // Convert the primitive into its scope's matching object type.
+ result = Wrapper.getContentView(out.window).Object(result);
+ }
+ setCompletionsFromObject(out, result, context);
}
-
- // Properties may be taken from several sources, so filter out duplicates.
- out.complete = Arr.sortUnique(complete);
};
- if (command === null)
- {
- done();
- }
- else
+ if (tempExpr.fake)
{
- Firebug.CommandLine.evaluate(command, context, context.thisValue, null,
+ var name = tempExpr.value.val;
+ if (getKnownType(name)._fb_ignorePrototype)
+ return;
+ var command = name + ".prototype";
+ Firebug.CommandLine.evaluate(name + ".prototype", context, context.thisValue, null,
function found(result, context)
{
- if (tempExpr.fake)
- {
- complete = complete.concat(Arr.keys(result));
- }
- else
- {
- if (typeof result === "string" && getKnownType(result))
- {
- complete = complete.concat(getFakeCompleteKeys(result));
- }
- }
- done();
+ done(result);
},
- function failed(result, context)
- {
- done();
- }
+ function failed(result, context) { }
);
}
+ else
+ {
+ done(result);
+ }
}
function evalPropChainStep(step, tempExpr, evalChain, out, context)
@@ -1658,14 +1805,18 @@ function evalPropChainStep(step, tempExpr, evalChain, out, context)
tempExpr.thisCommand = "window";
tempExpr.command += "[" + link.cont + "]";
}
- else if (type === LinkType.SAFECALL)
- {
- tempExpr.thisCommand = "window";
- tempExpr.command += "(" + link.origCont + ")";
- }
else if (type === LinkType.CALL)
{
- if (link.name === "")
+ if (link.origCont !== null &&
+ (link.name.substr(0, 3) === "get" ||
+ (link.name.charAt(0) === "$" && link.cont.indexOf(",") === -1)))
+ {
+ // Names beginning with get or $ are almost always getters, so
+ // assume we can safely just call it.
+ tempExpr.thisCommand = "window";
+ tempExpr.command += "(" + link.origCont + ")";
+ }
+ else if (!link.name)
{
// We cannot know about functions without name; try the
// heuristic directly.
@@ -1673,22 +1824,14 @@ function evalPropChainStep(step, tempExpr, evalChain, out, context)
evalPropChainStep(step, tempExpr, evalChain, out, context);
return;
}
-
- funcCommand = getTypeExtractionExpression(tempExpr.thisCommand);
- break;
+ else
+ {
+ funcCommand = getTypeExtractionExpression(tempExpr.thisCommand);
+ break;
+ }
}
else if (type === LinkType.RETVAL_HEURISTIC)
{
- if (link.origCont !== null &&
- (link.name.substr(0, 3) === "get" ||
- (link.name.charAt(0) === "$" && link.cont.indexOf(",") === -1)))
- {
- // Names beginning with get or $ are almost always getters, so
- // assume it is a safecall and start over.
- link.type = LinkType.SAFECALL;
- evalPropChainStep(step, tempExpr, evalChain, out, context);
- return;
- }
funcCommand = "Function.prototype.toString.call(" + tempExpr.command + ")";
break;
}
@@ -1896,9 +2039,13 @@ function evalPropChain(out, preExpr, origExpr, context)
function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
{
- var out = {};
-
- out.complete = [];
+ var out = {
+ spreExpr: spreExpr,
+ completions: [],
+ hiddenCompletions: [],
+ window: context.baseWindow || context.window
+ };
+ var indexCompletion = false;
try
{
@@ -1908,11 +2055,10 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
// In case of array indexing, remove the bracket and set a flag to
// escape completions.
- out.indexCompletion = false;
var len = spreExpr.length;
if (len >= 2 && spreExpr[len-2] === "[" && spreExpr[len-1] === '"')
{
- out.indexCompletion = true;
+ indexCompletion = true;
out.indexQuoteType = preExpr[len-1];
spreExpr = spreExpr.substr(0, len-2);
preExpr = preExpr.substr(0, len-2);
@@ -1934,7 +2080,7 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
// Don't auto-complete '.'.
if (spreExpr === "")
- return out.complete;
+ return out;
evalPropChain(out, spreExpr, preExpr, context);
}
@@ -1942,35 +2088,56 @@ function autoCompleteEval(context, preExpr, spreExpr, includeCurrentScope)
{
// Complete variables from the local scope
- var contentView = Wrapper.getContentView(context.window);
+ var contentView = Wrapper.getContentView(out.window);
if (context.stopped && includeCurrentScope)
{
- out.complete = Firebug.Debugger.getCurrentFrameKeys(context);
+ out.completions = Firebug.Debugger.getCurrentFrameKeys(context);
}
else if (contentView && contentView.Window &&
contentView.constructor.toString() === contentView.Window.toString())
// Cross window type pseudo-comparison
{
- out.complete = Arr.keys(contentView); // return is safe
-
- // Add some known window properties
- out.complete = out.complete.concat(getFakeCompleteKeys("Window"));
+ setCompletionsFromObject(out, contentView, context);
}
else // hopefully sandbox in Chromebug
{
- out.complete = Arr.keys(context.global);
+ setCompletionsFromObject(out, context.global, context);
}
+ }
- // Sort the completions, and avoid duplicates.
- out.complete = Arr.sortUnique(out.complete);
+ // Add "] to properties if we are doing index-completions.
+ if (indexCompletion)
+ {
+ function convertQuotes(x)
+ {
+ x = (out.indexQuoteType === '"') ? Str.escapeJS(x): Str.escapeSingleQuoteJS(x);
+ return x + out.indexQuoteType + "]";
+ }
+ out.completions = out.completions.map(convertQuotes);
+ out.hiddenCompletions = out.hiddenCompletions.map(convertQuotes);
}
+
+ // Remove numeric keys.
+ var rePositiveNumber = /^[1-9][0-9]*$/;
+ var nonNumeric = function(x)
+ {
+ return x !== '0' && !rePositiveNumber.test(x);
+ }
+ out.completions = out.completions.filter(nonNumeric);
+ out.hiddenCompletions = out.hiddenCompletions.filter(nonNumeric);
+
+ // Sort the completions, and avoid duplicates.
+ // XXX: If we make it possible to show both regular and hidden completions
+ // at the same time, completions must shadow hiddenCompletions.
+ out.completions = Arr.sortUnique(out.completions, comparePropertyNames);
+ out.hiddenCompletions = Arr.sortUnique(out.hiddenCompletions, comparePropertyNames);
}
catch (exc)
{
if (FBTrace.DBG_ERRORS && FBTrace.DBG_COMMANDLINE)
FBTrace.sysout("commandLine.autoCompleteEval FAILED", exc);
}
- return out.complete;
+ return out;
}
var reValidJSToken = /^[A-Za-z_$][A-Za-z_$0-9]*$/;
@@ -1988,26 +2155,6 @@ function isValidProperty(value)
return reValidJSToken.test(value);
}
-const rePositiveNumber = /^[1-9][0-9]*$/;
-function nonNumericKeys(map) // keys will be on user-level window objects
-{
- var keys = [];
- try
- {
- for (var name in map) // enumeration is safe
- {
- if (! (name === "0" || rePositiveNumber.test(name)) )
- keys.push(name);
- }
- }
- catch (exc)
- {
- // Sometimes we get exceptions trying to iterate properties
- }
-
- return keys; // return is safe
-}
-
function setCursorToEOL(input)
{
// textbox version, https://developer.mozilla.org/en/XUL/Property/inputField
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandEditor.js b/trace/FBTrace/chrome/firebug/content/console/commandEditor.js
index 81241d6..3bfc49d 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandEditor.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandEditor.js
@@ -148,7 +148,8 @@ Firebug.CommandEditor = Obj.extend(Firebug.Module,
if (Firebug.CommandEditor.ignoreChanges)
return;
- Firebug.CommandLine.onCommandLineInput(event);
+ var context = Firebug.currentContext;
+ Firebug.CommandLine.update(context);
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@@ -159,12 +160,8 @@ Firebug.CommandEditor = Obj.extend(Firebug.Module,
var popup = document.getElementById("fbCommandEditorPopup");
Dom.eraseNode(popup);
- var browserWindow = Firebug.chrome.window;
- var commandDispatcher = browserWindow.document.commandDispatcher;
-
var items = Firebug.CommandEditor.getContextMenuItems();
- for (var i=0; i<items.length; i++)
- Menu.createMenuItem(popup, items[i]);
+ Menu.createMenuItems(popup, items);
if (!popup.childNodes.length)
return;
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandHistory.js b/trace/FBTrace/chrome/firebug/content/console/commandHistory.js
index 2419eda..76494db 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandHistory.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandHistory.js
@@ -24,7 +24,7 @@ Firebug.CommandHistory = function()
const commandHistoryMax = 1000;
var commandsPopup = Firebug.chrome.$("fbCommandHistory");
- var commands = [];
+ var commands = this.commands = [];
var commandPointer = 0;
var commandInsertPointer = -1;
@@ -78,25 +78,21 @@ Firebug.CommandHistory = function()
var command;
var commandLine = Firebug.CommandLine.getCommandLine(context);
- if (dir < 0)
- {
- if (commandPointer > 0)
- commandPointer--;
- }
- else
- {
- if (commandPointer < commands.length)
- commandPointer++;
- }
+ commandPointer += dir;
+ if (commandPointer < 0)
+ commandPointer = 0;
+ else if (commandPointer > commands.length)
+ commandPointer = commands.length;
if (commandPointer < commands.length)
{
command = commands[commandPointer];
if (commandsPopup.state == "open")
{
- var commandElements = commandsPopup.ownerDocument.getElementsByClassName(
- "commandHistoryItem");
- this.selectCommand(commandElements[commandPointer]);
+ var commandElement = commandsPopup.children[commandPointer];
+ this.selectCommand(commandElement);
+
+ Dom.scrollMenupopup(commandsPopup, commandElement);
}
}
else
@@ -119,40 +115,42 @@ Firebug.CommandHistory = function()
this.show = function(element)
{
if (this.isShown())
- return this.hide;
+ return this.hide();
Dom.eraseNode(commandsPopup);
if(commands.length == 0)
return;
- var vbox = commandsPopup.ownerDocument.createElement("vbox");
+ var doc = commandsPopup.ownerDocument;
for (var i = 0; i < commands.length; i++)
{
- var hbox = commandsPopup.ownerDocument.
- createElementNS("http://www.w3.org/1999/xhtml", "div");
+ var hbox = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
hbox.classList.add("commandHistoryItem");
var shortExpr = Str.cropString(Str.stripNewLines(commands[i]), 50);
hbox.innerHTML = Str.escapeForTextNode(shortExpr);
hbox.value = i;
- vbox.appendChild(hbox);
+ commandsPopup.appendChild(hbox);
if (i === commandPointer)
this.selectCommand(hbox);
}
- commandsPopup.appendChild(vbox);
commandsPopup.openPopup(element, "before_start", 0, 0, false, false);
+ // make sure last element is visible
+ setTimeout(Dom.scrollMenupopup, 10, commandsPopup, hbox);
+ this.isOpen = true;
+
return true;
};
this.hide = function()
{
commandsPopup.hidePopup();
-
+ this.isOpen = false;
return true;
};
@@ -186,9 +184,13 @@ Firebug.CommandHistory = function()
this.onMouseUp = function(event)
{
+ var i = event.target.value;
+ if (i == undefined)
+ return;
+
var commandLine = Firebug.CommandLine.getCommandLine(Firebug.currentContext);
- commandLine.value = commands[event.target.value];
+ commandLine.value = commands[i];
commandPointer = event.target.value;
Firebug.CommandLine.commandHistory.hide();
@@ -198,6 +200,7 @@ Firebug.CommandHistory = function()
{
Firebug.chrome.setGlobalAttribute("fbCommandLineHistoryButton", "checked", "false");
Firebug.chrome.setGlobalAttribute("fbCommandEditorHistoryButton", "checked", "false");
+ this.isOpen = false;
};
};
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLine.js b/trace/FBTrace/chrome/firebug/content/console/commandLine.js
index ff77b31..d0dada8 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLine.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLine.js
@@ -18,16 +18,17 @@ define([
"firebug/lib/xml",
"firebug/lib/array",
"firebug/lib/persist",
- "firebug/console/eventMonitor",
"firebug/lib/keywords",
"firebug/console/console",
"firebug/console/commandLineHelp",
+ "firebug/console/commandLineInclude",
"firebug/console/commandLineExposed",
"firebug/console/autoCompleter",
"firebug/console/commandHistory"
],
function(Obj, Firebug, FirebugReps, Locale, Events, Wrapper, Url, Css, Dom, Firefox, Win, System,
- Xpath, Str, Xml, Arr, Persist, EventMonitor, Keywords, Console, CommandLineHelp) {
+ Xpath, Str, Xml, Arr, Persist, Keywords, Console, CommandLineHelp,
+ CommandLineInclude, CommandLineExposed) {
// ********************************************************************************************* //
// Constants
@@ -351,7 +352,8 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
evaluateInWebPage: function(expr, context, targetWindow)
{
- var win = targetWindow || context.window;
+ var win = targetWindow ? targetWindow :
+ (context.baseWindow ? context.baseWindow : context.window);
var element = Dom.addScript(win.document, "_firebugInWebPage", expr);
if (!element)
return;
@@ -450,6 +452,10 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
if (noscript && noScriptURI)
noscript.setJSEnabled(noScriptURI, false);
+
+ var consolePanel = Firebug.currentContext.panelMap.console;
+ if (consolePanel)
+ Dom.scrollToBottom(consolePanel.panelNode);
},
enterInspect: function(context)
@@ -564,7 +570,8 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
var commandLine = this.getSingleRowCommandLine();
var commandEditor = this.getCommandEditor();
- if (saveMultiLine) // we are just closing the view
+ // we are just closing the view
+ if (saveMultiLine)
{
commandLine.value = commandEditor.value;
return;
@@ -579,8 +586,6 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
commandEditor.value = Str.cleanIndentation(text);
else
commandLine.value = Str.stripNewLines(text);
-
- this.setAutoCompleter();
}
// else we may be hiding a panel while turning Firebug off
},
@@ -623,56 +628,40 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
Firebug.Module.initialize.apply(this, arguments);
- this.autoCompleter = new Firebug.EmptyJSAutoCompleter();
+ this.setAutoCompleter();
this.commandHistory = new Firebug.CommandHistory();
if (Firebug.commandEditor)
this.setMultiLine(true, Firebug.chrome);
},
+ // (Re)create the auto-completer for the small command line.
setAutoCompleter: function()
{
- var context = Firebug.currentContext;
-
- // xxxHonza: see http://code.google.com/p/fbug/issues/detail?id=4901#c21
if (this.autoCompleter)
this.autoCompleter.shutdown();
- // Set the auto-completer even if the command-editor is currently displayed
- // in the Console panel. This is to make the auto-completion work even in
- // the small-command-line available on other panels (see issue 5006).
-
- if (!context/* || Firebug.commandEditor*/)
- {
- this.autoCompleter = new Firebug.EmptyJSAutoCompleter();
- }
- else
- {
- // Always create the auto-completer for the single command line.
- var commandLine = this.getSingleRowCommandLine();
- var completionBox = this.getCompletionBox();
-
- var options = {
- showCompletionPopup: Firebug.Options.get("commandLineShowCompleterPopup"),
- completionPopup: Firebug.chrome.$("fbCommandLineCompletionList"),
- tabWarnings: true,
- includeCurrentScope: true
- };
+ var commandLine = this.getSingleRowCommandLine();
+ var completionBox = this.getCompletionBox();
+
+ var options = {
+ showCompletionPopup: Firebug.Options.get("commandLineShowCompleterPopup"),
+ completionPopup: Firebug.chrome.$("fbCommandLineCompletionList"),
+ popupMeasurer: Firebug.chrome.$("fbCommandLineMeasurer"),
+ tabWarnings: true,
+ includeCurrentScope: true
+ };
- this.autoCompleter = new Firebug.JSAutoCompleter(commandLine,
- completionBox, options);
- }
+ this.autoCompleter = new Firebug.JSAutoCompleter(commandLine, completionBox, options);
},
initializeUI: function()
{
- this.onCommandLineFocus = Obj.bind(this.onCommandLineFocus, this);
this.onCommandLineInput = Obj.bind(this.onCommandLineInput, this);
- this.onCommandLineBlur = Obj.bind(this.onCommandLineBlur, this);
+ this.onCommandLineOverflow = Obj.bind(this.onCommandLineOverflow, this);
this.onCommandLineKeyUp = Obj.bind(this.onCommandLineKeyUp, this);
this.onCommandLineKeyDown = Obj.bind(this.onCommandLineKeyDown, this);
this.onCommandLineKeyPress = Obj.bind(this.onCommandLineKeyPress, this);
- this.onCommandLineOverflow = Obj.bind(this.onCommandLineOverflow, this);
this.attachListeners();
},
@@ -680,35 +669,28 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
var commandLine = this.getSingleRowCommandLine();
- Events.addEventListener(commandLine, "focus", this.onCommandLineFocus, true);
Events.addEventListener(commandLine, "input", this.onCommandLineInput, true);
Events.addEventListener(commandLine, "overflow", this.onCommandLineOverflow, true);
Events.addEventListener(commandLine, "keyup", this.onCommandLineKeyUp, true);
Events.addEventListener(commandLine, "keydown", this.onCommandLineKeyDown, true);
Events.addEventListener(commandLine, "keypress", this.onCommandLineKeyPress, true);
- Events.addEventListener(commandLine, "blur", this.onCommandLineBlur, true);
-
- Firebug.Console.addListener(this); // to get onConsoleInjected
},
shutdown: function()
{
var commandLine = this.getSingleRowCommandLine();
- // Make sure all listeners registered by the auto completer are removed.
if (this.autoCompleter)
this.autoCompleter.shutdown();
if (this.commandHistory)
this.commandHistory.detachListeners();
- Events.removeEventListener(commandLine, "focus", this.onCommandLineFocus, true);
Events.removeEventListener(commandLine, "input", this.onCommandLineInput, true);
Events.removeEventListener(commandLine, "overflow", this.onCommandLineOverflow, true);
Events.removeEventListener(commandLine, "keyup", this.onCommandLineKeyUp, true);
Events.removeEventListener(commandLine, "keydown", this.onCommandLineKeyDown, true);
Events.removeEventListener(commandLine, "keypress", this.onCommandLineKeyPress, true);
- Events.removeEventListener(commandLine, "blur", this.onCommandLineBlur, true);
},
destroyContext: function(context, persistedState)
@@ -810,6 +792,11 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
onCommandLineKeyDown: function(event)
{
+ // XXX: Temporary hack to make FireClosure work (until that gets a new
+ // release out)
+ if (!this.autoCompleter.shouldIncludeHint && Firebug.JSAutoCompleter.transformScopeExpr)
+ this.setAutoCompleter();
+
var context = Firebug.currentContext;
this.autoCompleter.handleKeyDown(event, context);
@@ -875,6 +862,9 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
return true;
}
+ if (this.commandHistory.isOpen && !event.metaKey && !event.ctrlKey && !event.altKey)
+ this.commandHistory.hide();
+
return false;
},
@@ -882,32 +872,10 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
{
var context = Firebug.currentContext;
- if (!this.commandHistory.isShown())
- {
- this.autoCompleter.complete(context);
- }
-
- // Always update the buffer in context, even if command line is empty.
+ this.autoCompleter.complete(context);
this.update(context);
},
- onCommandLineBlur: function(event)
- {
- },
-
- onCommandLineFocus: function(event)
- {
- if (FBTrace.DBG_COMMANDLINE)
- {
- var context = Firebug.currentContext;
- FBTrace.sysout("commandLine.onCommandLineFocus; for: " +
- (context ? context.getName() : "no context"));
- }
-
- if (this.autoCompleter.empty)
- this.setAutoCompleter();
- },
-
isAttached: function(context, win)
{
if (!context)
@@ -935,20 +903,6 @@ Firebug.CommandLine = Obj.extend(Firebug.Module,
Dom.collapse(Firebug.chrome.$("fbSidePanelDeck"), true);
},
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- // Firebug.Console listener
-
- onConsoleInjected: function(context, win)
- {
- // for some reason the console has been injected. If the user had focus in the command
- // line they want it added in the page also. If the user has the cursor in the command
- // line and reloads, the focus will already be there. issue 1339
- var isFocused = Firebug.CommandEditor.hasFocus();
- isFocused = isFocused || (this.getSingleRowCommandLine().getAttribute("focused") == "true");
- if (isFocused)
- setTimeout(this.onCommandLineFocus);
- },
-
getCommandLine: function(context)
{
return (!this.isInOtherPanel(context) && Firebug.commandEditor) ?
@@ -1034,27 +988,66 @@ Firebug.CommandLine.CommandHandler = Obj.extend(Object,
});
// ********************************************************************************************* //
-// Command line APIs definition
-//
-// These functions will be called in the extension like this:
-// subHandler.apply(api, userObjects);
-// where subHandler is one of the entries below, api is this object and userObjects are entries in
-// an array we created in the web page.
+// Command Line API
+/**
+ * These functions will be called in the extension like this:
+ *
+ * subHandler.apply(api, userObjects);
+ *
+ * Where subHandler is one of the entries below, api is this object and userObjects
+ * are entries in an array we created in the web page.
+ */
function FirebugCommandLineAPI(context)
{
- this.$ = function(id) // returns unwrapped elements from the page
+ // returns unwrapped elements from the page
+ this.$ = function(selector, start)
{
- return Wrapper.unwrapObject(context.baseWindow.document).getElementById(id);
+ if (start && start.querySelector && (
+ start.nodeType == Node.ELEMENT_NODE ||
+ start.nodeType == Node.DOCUMENT_NODE ||
+ start.nodeType == Node.DOCUMENT_FRAGMENT_NODE))
+ {
+ return start.querySelector(selector);
+ }
+
+ var result = context.baseWindow.document.querySelector(selector);
+ if (result == null && (selector || "")[0] !== "#")
+ {
+ if (context.baseWindow.document.getElementById(selector))
+ {
+ // This should be removed in the next minor (non-bugfix) version
+ var msg = Locale.$STRF("warning.dollar_change", [selector]);
+ Firebug.Console.log(msg, context, "warn");
+ result = null;
+ }
+ }
+
+ return result;
};
- this.$$ = function(selector) // returns unwrapped elements from the page
+ // returns unwrapped elements from the page
+ this.$$ = function(selector, start)
{
- var result = Wrapper.unwrapObject(context.baseWindow.document).querySelectorAll(selector);
+ var result;
+
+ if (start && start.querySelectorAll && (
+ start.nodeType == Node.ELEMENT_NODE ||
+ start.nodeType == Node.DOCUMENT_NODE ||
+ start.nodeType == Node.DOCUMENT_FRAGMENT_NODE))
+ {
+ result = start.querySelectorAll(selector);
+ }
+ else
+ {
+ result = context.baseWindow.document.querySelectorAll(selector);
+ }
+
return Arr.cloneArray(result);
};
- this.$x = function(xpath, contextNode, resultType) // returns unwrapped elements from the page
+ // returns unwrapped elements from the page
+ this.$x = function(xpath, contextNode, resultType)
{
var XPathResultType = XPathResult.ANY_TYPE;
@@ -1075,18 +1068,18 @@ function FirebugCommandLineAPI(context)
case "node":
XPathResultType = XPathResult.FIRST_ORDERED_NODE_TYPE;
break;
-
+
case "nodes":
XPathResultType = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
break;
}
var doc = Wrapper.unwrapObject(context.baseWindow.document);
-
return Xpath.evaluateXPath(doc, xpath, contextNode, XPathResultType);
};
- this.$n = function(index) // values from the extension space
+ // values from the extension space
+ this.$n = function(index)
{
var htmlPanel = context.getPanel("html", true);
if (!htmlPanel)
@@ -1119,17 +1112,20 @@ function FirebugCommandLineAPI(context)
if (entry)
context.baseWindow = entry.win;
- Firebug.Console.log(["Current window:", context.baseWindow], context, "info");
+ var format = Locale.$STR("commandline.CurrentWindow") + " %o";
+ Firebug.Console.logFormatted([format, context.baseWindow], context, "info");
return Firebug.Console.getDefaultReturnValue(context.window);
};
- this.clear = function() // no web page interaction
+ // no web page interaction
+ this.clear = function()
{
Firebug.Console.clear(context);
return Firebug.Console.getDefaultReturnValue(context.window);
};
- this.inspect = function(obj, panelName) // no web page interaction
+ // no web page interaction
+ this.inspect = function(obj, panelName)
{
Firebug.chrome.select(obj, panelName);
return Firebug.Console.getDefaultReturnValue(context.window);
@@ -1137,12 +1133,14 @@ function FirebugCommandLineAPI(context)
this.keys = function(o)
{
- return Arr.keys(o); // the object is from the page, unwrapped
+ // the object is from the page, unwrapped
+ return Arr.keys(o);
};
this.values = function(o)
{
- return Arr.values(o); // the object is from the page, unwrapped
+ // the object is from the page, unwrapped
+ return Arr.values(o);
};
this.debug = function(fn)
@@ -1193,42 +1191,12 @@ function FirebugCommandLineAPI(context)
return Firebug.Console.getDefaultReturnValue(context.window);
};
- this.monitorEvents = function(object, types)
- {
- EventMonitor.monitorEvents(object, types, context);
- return Firebug.Console.getDefaultReturnValue(context.window);
- };
-
- this.unmonitorEvents = function(object, types)
- {
- EventMonitor.unmonitorEvents(object, types, context);
- return Firebug.Console.getDefaultReturnValue(context.window);
- };
-
- this.profile = function(title)
- {
- Firebug.Profiler.startProfiling(context, title);
- return Firebug.Console.getDefaultReturnValue(context.window);
- };
-
- this.profileEnd = function()
- {
- Firebug.Profiler.stopProfiling(context);
- return Firebug.Console.getDefaultReturnValue(context.window);
- };
-
this.copy = function(x)
{
System.copyToClipboard(x);
return Firebug.Console.getDefaultReturnValue(context.window);
};
- this.help = function()
- {
- CommandLineHelp.render(context);
- return Firebug.Console.getDefaultReturnValue(context.window);
- };
-
// xxxHonza: removed from 1.10 (issue 5599)
/*this.memoryProfile = function(title)
{
@@ -1241,6 +1209,35 @@ function FirebugCommandLineAPI(context)
Firebug.MemoryProfiler.stop(context);
return Firebug.Console.getDefaultReturnValue(context.window);
};*/
+
+ function createHandler(config, name)
+ {
+ return function()
+ {
+ try
+ {
+ return config.handler.call(null, context, arguments);
+ }
+ catch (err)
+ {
+ Firebug.Console.log(err, context, "errorMessage");
+
+ if (FBTrace.DBG_ERRORS)
+ {
+ FBTrace.sysout("commandLine.api; EXCEPTION when executing " +
+ "a command: " + name + ", " + err, err);
+ }
+ }
+ }
+ }
+
+ // Register user commands.
+ var commands = CommandLineExposed.userCommands;
+ for (var name in commands)
+ {
+ var config = commands[name];
+ this[name] = createHandler(config, name);
+ }
}
// ********************************************************************************************* //
@@ -1350,15 +1347,19 @@ Firebug.CommandLine.injector =
delete context.activeCommandLineHandlers[consoleHandler.token];
if (FBTrace.DBG_COMMANDLINE)
- FBTrace.sysout("commandLine.detachCommandLineListener "+boundHandler+
- " in window with console "+win.location);
+ {
+ FBTrace.sysout("commandLine.detachCommandLineListener " + boundHandler +
+ " in window with console " + win.location);
+ }
}
else
{
if (FBTrace.DBG_ERRORS || FBTrace.DBG_COMMANDLINE)
+ {
FBTrace.sysout("commandLine.removeCommandLineListener; ERROR no handler! " +
"This could cause memory leaks, please report an issue if you see this. " +
context.getName());
+ }
}
},
@@ -1405,7 +1406,7 @@ function CommandLineHandler(context, win)
// Appends variables into the api.
var htmlPanel = context.getPanel("html", true);
- var vars = htmlPanel ? htmlPanel.getInspectorVars():null;
+ var vars = htmlPanel ? htmlPanel.getInspectorVars() : null;
for (var prop in vars)
{
@@ -1420,7 +1421,8 @@ function CommandLineHandler(context, win)
}
}
- this.api[prop] = createHandler(prop); // XXXjjb should these be removed?
+ // XXXjjb should these be removed?
+ this.api[prop] = createHandler(prop);
}
if (!Firebug.CommandLine.CommandHandler.handle(event, this.api, win))
@@ -1449,6 +1451,7 @@ function getNoScript()
return this.noscript;
}
+
// ********************************************************************************************* //
// Registration
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js b/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
index 6f4b298..bc29ef3 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineExposed.js
@@ -1,11 +1,10 @@
/* See license.txt for terms of usage */
define([
- "firebug/firebug",
"firebug/lib/wrapper",
"firebug/lib/events",
],
-function(Firebug, Wrapper, Events) {
+function(Wrapper, Events) {
// ********************************************************************************************* //
// Command Line APIs
@@ -13,14 +12,16 @@ function(Firebug, Wrapper, Events) {
// List of command line APIs
var commands = ["$", "$$", "$x", "$n", "cd", "clear", "inspect", "keys",
"values", "debug", "undebug", "monitor", "unmonitor", "traceCalls", "untraceCalls",
- "traceAll", "untraceAll", "monitorEvents", "unmonitorEvents", "profile", "profileEnd",
- "copy" /*, "memoryProfile", "memoryProfileEnd"*/];
+ "traceAll", "untraceAll", "copy" /*, "memoryProfile", "memoryProfileEnd"*/];
// List of shortcuts for some console methods
var consoleShortcuts = ["dir", "dirxml", "table"];
// List of console variables.
-var props = ["$0", "$1", "help"];
+var props = ["$0", "$1"];
+
+// Registered commands, name -> config object.
+var userCommands = {};
// ********************************************************************************************* //
// Command Line Implementation
@@ -52,6 +53,24 @@ function createFirebugCommandLine(context, win)
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Exposed Properties
+ function createCommandHandler(cmd) {
+ return function() {
+ return notifyFirebug(arguments, cmd, "firebugExecuteCommand");
+ }
+ }
+
+ function createShortcutHandler(cmd) {
+ return function() {
+ return console[cmd].apply(console, arguments);
+ }
+ }
+
+ function createVariableHandler(prop) {
+ return function() {
+ return notifyFirebug(arguments, prop, "firebugExecuteCommand");
+ }
+ }
+
// Define command line methods
for (var i=0; i<commands.length; i++)
{
@@ -61,16 +80,12 @@ function createFirebugCommandLine(context, win)
if (command in contentView)
continue;
- function createCommandHandler(cmd) {
- return function() {
- return notifyFirebug(arguments, cmd, "firebugExecuteCommand");
- }
- }
-
commandLine[command] = createCommandHandler(command);
commandLine.__exposedProps__[command] = "rw";
}
+ var console = Firebug.ConsoleExposed.createFirebugConsole(context, win);
+
// Define shortcuts for some console methods
for (var i=0; i<consoleShortcuts.length; i++)
{
@@ -80,14 +95,8 @@ function createFirebugCommandLine(context, win)
if (command in contentView)
continue;
- function createShortcutHandler(cmd) {
- return function() {
- return contentView.console[cmd].apply(contentView.console, arguments);
- }
- }
-
commandLine[command] = createShortcutHandler(command);
- commandLine.__exposedProps__[command] = "rw";
+ commandLine.__exposedProps__[command] = "r";
}
// Define console variables.
@@ -97,16 +106,31 @@ function createFirebugCommandLine(context, win)
if (prop in contentView)
continue;
- function createVariableHandler(prop) {
- return function() {
- return notifyFirebug(arguments, prop, "firebugExecuteCommand");
- }
- }
-
commandLine.__defineGetter__(prop, createVariableHandler(prop));
commandLine.__exposedProps__[prop] = "r";
}
+ // Define user registered commands.
+ for (var name in userCommands)
+ {
+ // If the method is already defined, don't override it.
+ if (name in contentView)
+ continue;
+
+ var config = userCommands[name];
+
+ if (config.getter)
+ {
+ commandLine.__defineGetter__(name, createVariableHandler(name));
+ commandLine.__exposedProps__[name] = "r";
+ }
+ else
+ {
+ commandLine[name] = createCommandHandler(name);
+ commandLine.__exposedProps__[name] = "r";
+ }
+ }
+
attachCommandLine();
// xxxHonza: TODO make this private.
@@ -245,6 +269,43 @@ document.documentElement.appendChild(script);
*/
// ********************************************************************************************* //
+// User Commands
+
+function registerCommand(name, config)
+{
+ if (commands[name] || consoleShortcuts[name] || props[name] || userCommands[name])
+ {
+ if (FBTrace.DBG_ERRORS)
+ {
+ FBTrace.sysout("firebug.registerCommand; ERROR This command is already " +
+ "registered: " + name);
+ }
+
+ return false;
+ }
+
+ userCommands[name] = config;
+ return true;
+}
+
+function unregisterCommand(name)
+{
+ if (!userCommands[name])
+ {
+ if (FBTrace.DBG_ERRORS)
+ {
+ FBTrace.sysout("firebug.unregisterCommand; ERROR This command is not " +
+ "registered: " + name);
+ }
+
+ return false;
+ }
+
+ delete userCommands[name];
+ return true;
+}
+
+// ********************************************************************************************* //
// Registration
Firebug.CommandLineExposed =
@@ -253,6 +314,9 @@ Firebug.CommandLineExposed =
commands: commands,
consoleShortcuts: consoleShortcuts,
properties: props,
+ userCommands: userCommands,
+ registerCommand: registerCommand,
+ unregisterCommand: unregisterCommand,
};
return Firebug.CommandLineExposed;
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js b/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
index 7d9b607..b0e385e 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineHelp.js
@@ -1,13 +1,17 @@
/* See license.txt for terms of usage */
define([
+ "firebug/firebug",
"firebug/lib/domplate",
"firebug/lib/locale",
"firebug/lib/dom",
"firebug/console/commandLineExposed",
"firebug/chrome/window",
+ "firebug/lib/xpcom",
+ "firebug/lib/events",
],
-function(Domplate, Locale, Dom, CommandLineExposed, Win) { with (Domplate) {
+function(Firebug, Domplate, Locale, Dom, CommandLineExposed, Win, Xpcom, Events) {
+with (Domplate) {
// ********************************************************************************************* //
// Constants
@@ -19,6 +23,8 @@ var CMD_TYPE_COMMAND = 1;
var CMD_TYPE_SHORTCUT = 2;
var CMD_TYPE_PROPERTY = 3;
+const prompts = Xpcom.CCSV("@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService");
+
// ********************************************************************************************* //
// Domplates
@@ -35,6 +41,7 @@ var HelpCaption = domplate(
)
});
+// The table UI should be based on tableRep
var HelpTable = domplate(
{
tag:
@@ -85,8 +92,22 @@ var HelpEntry = domplate(
onClick: function(event)
{
+ Events.cancelEvent(event);
+
var object = Firebug.getRepObject(event.target);
- Win.openNewTab("http://getfirebug.com/wiki/index.php/" + object.name);
+
+ if (object.noUserHelpUrl)
+ {
+ prompts.alert(null, Locale.$STR("Firebug"),
+ Locale.$STR("console.cmd.helpUrlNotAvailable"));
+ return;
+ }
+
+ var helpUrl = "http://getfirebug.com/wiki/index.php/" + object.name;
+ if (object.helpUrl)
+ helpUrl = object.helpUrl;
+
+ Win.openNewTab(helpUrl);
},
getName: function(object)
@@ -99,6 +120,9 @@ var HelpEntry = domplate(
getDesc: function(object)
{
+ if (object.nol10n)
+ return object.desc;
+
return Locale.$STR(object.desc);
}
});
@@ -147,6 +171,23 @@ var CommandLineHelp = domplate(
})
}
+ for (var name in CommandLineExposed.userCommands)
+ {
+ var config = CommandLineExposed.userCommands[name];
+ commands.push({
+ name: name,
+ desc: config.description,
+ nol10n: true,
+ noUserHelpUrl: !config.helpUrl,
+ helpUrl: config.helpUrl ? config.helpUrl: null,
+ type: config.getter ? CMD_TYPE_PROPERTY : CMD_TYPE_COMMAND,
+ })
+ }
+
+ // Sort commands
+ commands.sort(function sortName(a, b) { return a.name > b.name ? 1 : -1; });
+
+ // Generate table
HelpEntry.tag.insertRows({commands: commands}, tBody);
return row;
@@ -154,8 +195,24 @@ var CommandLineHelp = domplate(
});
// ********************************************************************************************* //
+// Command Implementation
+
+function onExecuteCommand(context)
+{
+ CommandLineHelp.render(context);
+ return Firebug.Console.getDefaultReturnValue(context.window);
+}
+
+// ********************************************************************************************* //
// Registration
+Firebug.registerCommand("help", {
+ getter: true,
+ helpUrl: "http://getfirebug.com/wiki/index.php/help",
+ handler: onExecuteCommand.bind(this),
+ description: Locale.$STR("console.cmd.help.help")
+});
+
return CommandLineHelp;
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js b/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js
new file mode 100644
index 0000000..c5489b1
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLineInclude.js
@@ -0,0 +1,542 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/chrome/reps",
+ "firebug/lib/domplate",
+ "firebug/lib/locale",
+ "firebug/lib/dom",
+ "firebug/chrome/window",
+ "firebug/lib/css",
+ "firebug/lib/string",
+ "firebug/lib/options",
+ "firebug/chrome/menu",
+ "firebug/lib/system",
+ "firebug/lib/xpcom",
+ "firebug/lib/object",
+ "firebug/editor/editor",
+],
+function(FirebugReps, Domplate, Locale, Dom, Win, Css, Str, Options, Menu, System, Xpcom, Obj) {
+with (Domplate) {
+
+// ********************************************************************************************* //
+// Constants
+
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const removeConfirmation = "commandline.include.removeConfirmation";
+const prompts = Xpcom.CCSV("@mozilla.org/embedcomp/prompt-service;1", "nsIPromptService");
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+var ScratchpadManager;
+
+try
+{
+ var scope = {};
+ Cu.import("resource:///modules/devtools/scratchpad-manager.jsm", scope);
+ ScratchpadManager = scope.ScratchpadManager;
+}
+catch(ex)
+{
+ // Scratchpad does not exists (when using Seamonkey ...)
+}
+
+var storageScope = {};
+Cu.import("resource://firebug/storageService.js", storageScope);
+
+// ********************************************************************************************* //
+// Implementation
+
+var CommandLineIncludeRep = domplate(FirebugReps.Table,
+{
+ tableClassName: "tableCommandLineInclude dataTable",
+
+ tag:
+ FirebugReps.OBJECTBOX({_repObject: "$object"},
+ FirebugReps.Table.tag
+ ),
+
+ inspectable: false,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Domplate Handlers
+
+ getValueTag: function(object)
+ {
+ if (object.cons === DomplateTag)
+ return object;
+ else
+ return FirebugReps.Table.getValueTag(object);
+ },
+
+ getUrlTag: function(href, aliasName)
+ {
+ var urlTag =
+ SPAN({style:"height:100%"},
+ A({"href": href, "target": "_blank", "class": "url"},
+ Str.cropString(href, 100)
+ ),
+ SPAN({"class": "commands"}
+ // xxxFlorent: temporarily disabled, see:
+ // http://code.google.com/p/fbug/issues/detail?id=5878#c27
+ /*,
+ IMG({
+ "src":"blank.gif",
+ "class":"closeButton ",
+ onclick: this.deleteAlias.bind(this, aliasName),
+ })*/
+ )
+ );
+
+ return urlTag;
+ },
+
+ displayAliases: function(context)
+ {
+ var store = CommandLineInclude.getStore();
+ var keys = store.getKeys();
+ var arrayToDisplay = [];
+ var returnValue = Firebug.Console.getDefaultReturnValue(context.window);
+
+ if (keys.length === 0)
+ {
+ var msg = Locale.$STR("commandline.include.noDefinedAlias");
+ Firebug.Console.log(msg, context, null, FirebugReps.Hint);
+ return returnValue;
+ }
+
+ for (var i=0; i<keys.length; i++)
+ {
+ var aliasName = keys[i];
+ arrayToDisplay.push({
+ "alias": SPAN({"class":"aliasName", "data-aliasname": aliasName}, aliasName),
+ "URL": this.getUrlTag(store.getItem(aliasName), aliasName, context)
+ });
+ }
+
+ var input = new CommandLineIncludeObject();
+ this.log(arrayToDisplay, ["alias", "URL"], context, input);
+ return returnValue;
+ },
+
+ deleteAlias: function(aliasName, ev)
+ {
+ // NOTE: that piece of code has not been tested since deleting aliases through the table
+ // has been disabled.
+ // Once it is enabled again, make sure FBTests is available for this feature
+ var store = CommandLine.getStore();
+ if (! Options.get(removeConfirmation))
+ {
+ var check = {value: false};
+ var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
+ prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO;
+
+ if (prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
+ Locale.$STR("commandline.include.confirmDelete"), flags, "", "", "",
+ Locale.$STR("Do_not_show_this_message_again"), check) > 0)
+ {
+ return;
+ }
+
+ // Update 'Remove Cookies' confirmation option according to the value
+ // of the dialog's "do not show again" checkbox.
+ Options.set(removeConfirmation, !check.value);
+ }
+ store.removeItem(aliasName);
+ },
+
+ startEditing: function(target)
+ {
+ var editor = this.getEditor(target.ownerDocument);
+ Firebug.Editor.startEditing(target, target.dataset.aliasname, editor);
+ },
+
+ editAliasName: function(tr)
+ {
+ var target = tr.querySelector(".aliasName");
+ this.startEditing(target);
+ },
+
+ editAliasURL: function(tr)
+ {
+ var target = tr.querySelector(".url");
+ this.startEditing(target);
+ },
+
+ openInScratchpad: function(url)
+ {
+ var spWin = ScratchpadManager.openScratchpad();
+ var scriptContent = null;
+ var editor = null;
+
+ spWin.onload = function()
+ {
+ var spInstance = spWin.Scratchpad;
+ //intro = spInstance.strings.GetStringFromName("scratchpadIntro");
+ spInstance.addObserver(
+ {
+ onReady: function()
+ {
+ editor = spInstance.editor;
+
+ // if the content of the script is loaded, we write the content in the editor
+ // otherwise, we write a text that asks the user to wait
+ if (scriptContent)
+ editor.setText(scriptContent);
+ else
+ editor.setText("// "+Locale.$STR("scratchpad.loading"));
+ }
+ });
+ }
+
+ var xhr = new XMLHttpRequest({mozAnon: true});
+ xhr.open("GET", url, true);
+
+ xhr.onload = function()
+ {
+ if (spWin.closed)
+ return;
+
+ scriptContent = xhr.responseText;
+
+ // if the editor is ready, we put the content on it now
+ // otherwise, we wait for the editor
+ if (editor)
+ editor.setText(scriptContent);
+ }
+
+ xhr.onerror = function()
+ {
+ if (spWin.closed)
+ return;
+
+ spInstance.setText("// "+Locale.$STR("scratchpad.failLoading"));
+ }
+
+ xhr.send(null);
+ },
+
+ supportsObject: function(object, type)
+ {
+ return object instanceof CommandLineIncludeObject;
+ },
+
+ getContextMenuItems: function(object, target, context)
+ {
+ var tr = Dom.getAncestorByTagName(target, "tr");
+ if (!tr)
+ return [];
+
+ var url = tr.querySelector("a.url").href;
+ var aliasName = tr.querySelector(".aliasName").dataset.aliasname;
+ var context = Firebug.currentContext;
+ var items = [
+ {
+ label: "CopyLocation",
+ id: "fbCopyLocation",
+ tooltiptext: "clipboard.tip.Copy_Location",
+ command: Obj.bindFixed(System.copyToClipboard, System, url)
+ },
+ // xxxFlorent: temporarily disabled, see:
+ // http://code.google.com/p/fbug/issues/detail?id=5878#c27
+ /*"-",
+ {
+ label: "commandline.label.EditAliasName",
+ id: "fbEditAliasName",
+ tooltiptext: "commandline.tip.Edit_Alias_Name",
+ command: this.editAliasName.bind(this, tr)
+ },
+ {
+ label: "commandline.label.EditAliasURL",
+ id: "fbEditAliasUrl",
+ tooltiptext: "commandline.tip.Edit_Alias_URL",
+ command: this.editAliasURL.bind(this, tr)
+ },
+ {
+ label: "commandline.label.DeleteAlias",
+ id: "fbDeleteAlias",
+ tooltiptext: "commandline.tip.Delete_Alias",
+ command: this.deleteAlias.bind(this, aliasName, ev)
+ },*/
+ "-",
+ {
+ label: Locale.$STRF("commandline.label.IncludeScript", [aliasName]),
+ id: "fbInclude",
+ tooltiptext: "commandline.tip.Include_Script",
+ command: Obj.bindFixed(CommandLineInclude.include, CommandLineInclude,
+ context, aliasName)
+ },
+ "-",
+ {
+ label: "OpenInTab",
+ id: "fbOpenInTab",
+ tooltiptext: "firebug.tip.Open_In_Tab",
+ command: Obj.bindFixed(Win.openNewTab, Win, url)
+ }
+ ];
+
+ if (ScratchpadManager)
+ {
+ items.push({
+ label: "commandline.label.OpenInScratchpad",
+ id: "fbOpenInScratchpad",
+ tooltiptext: "commandline.tip.Open_In_Scratchpad",
+ command: this.openInScratchpad.bind(this, url)
+ });
+ }
+
+ return items;
+ },
+
+ getEditor: function(doc)
+ {
+ if (!this.editor)
+ this.editor = new IncludeEditor(doc);
+ return this.editor;
+ }
+});
+
+// ********************************************************************************************* //
+
+function CommandLineIncludeObject()
+{
+}
+
+// ********************************************************************************************* //
+
+var CommandLineInclude =
+{
+ onSuccess: function(newAlias, context, loadingMsgRow, xhr)
+ {
+ var urlComponent = xhr.channel.URI.QueryInterface(Ci.nsIURL);
+ var filename = urlComponent.fileName, url = urlComponent.spec;
+ // clear the message saying "loading..."
+ this.clearLoadingMessage(loadingMsgRow);
+
+ if (newAlias)
+ {
+ var store = this.getStore();
+ store.setItem(newAlias, url);
+ this.log("aliasCreated", [newAlias], [context, "info"]);
+ }
+
+ this.log("includeSuccess", [filename], [context, "info", true]);
+ },
+
+ onError: function(context, url, loadingMsgRow)
+ {
+ this.clearLoadingMessage(loadingMsgRow);
+ this.log("loadFail", [url], [context, "error"]);
+ },
+
+ clearLoadingMessage: function(loadingMsgRow)
+ {
+ if (loadingMsgRow && loadingMsgRow.parentNode)
+ loadingMsgRow.parentNode.removeChild(loadingMsgRow);
+ },
+
+ getStore: function()
+ {
+ if (!this.store)
+ this.store = storageScope.StorageService.getStorage("includeAliases.json");
+ return this.store;
+ },
+
+ log: function(localeStr, localeArgs, logArgs, noAutoPrefix)
+ {
+ var prefixedLocaleStr = (noAutoPrefix ? localeStr : "commandline.include."+localeStr);
+
+ var msg = Locale.$STRF(prefixedLocaleStr, localeArgs);
+ logArgs.unshift([msg]);
+ return Firebug.Console.logFormatted.apply(Firebug.Console, logArgs);
+ },
+
+ // include(context, url[, newAlias])
+ // includes a remote script
+ include: function(context, url, newAlias)
+ {
+ var reNotAlias = /[\.\/]/;
+ var urlIsAlias = url !== null && !reNotAlias.test(url);
+ var returnValue = Firebug.Console.getDefaultReturnValue(context.window);
+
+ // checking arguments:
+ if ((newAlias !== undefined && typeof newAlias !== "string") || newAlias === "")
+ {
+ this.log("invalidAliasArgumentType", [], [context, "error"]);
+ return returnValue;
+ }
+
+ if (url !== null && typeof url !== "string" || !url && !newAlias)
+ {
+ this.log("invalidUrlArgumentType", [], [context, "error"]);
+ return returnValue;
+ }
+
+ if (newAlias !== undefined)
+ newAlias = newAlias.toLowerCase();
+
+ if ((urlIsAlias && url.length > 30) || (newAlias && newAlias.length > 30))
+ {
+ this.log("tooLongAliasName", [newAlias || url], [context, "error"]);
+ return returnValue;
+ }
+
+ if (newAlias !== undefined && reNotAlias.test(newAlias))
+ {
+ this.log("invalidAliasName", [newAlias], [context, "error"]);
+ return returnValue;
+ }
+
+ if (urlIsAlias)
+ {
+ var store = this.getStore();
+ var aliasName = url.toLowerCase();
+ url = store.getItem(aliasName);
+ if (url === undefined)
+ {
+ this.log("aliasNotFound", [aliasName], [context, "error"]);
+ return returnValue;
+ }
+ }
+
+ // if the URL is null, we delete the alias
+ if (newAlias !== undefined && url === null)
+ {
+ var store = this.getStore();
+ if (store.getItem(newAlias) === undefined)
+ {
+ this.log("aliasNotFound", [newAlias], [context, "error"]);
+ return returnValue;
+ }
+
+ store.removeItem(newAlias);
+ this.log("aliasRemoved", [newAlias], [context, "info"]);
+ return returnValue;
+ }
+ var loadingMsgRow = this.log("Loading", [], [context, "loading", true], true);
+ var onSuccess = this.onSuccess.bind(this, newAlias, context, loadingMsgRow);
+ var onError = Obj.bindFixed(this.onError, this, context, url, loadingMsgRow);
+ this.evaluateRemoteScript(url, context, onSuccess, onError, loadingMsgRow);
+
+ return returnValue;
+ },
+
+ evaluateRemoteScript: function(url, context, successFunction, errorFunction, loadingMsgRow)
+ {
+ var xhr = new XMLHttpRequest({ mozAnon: true, timeout:30});
+ var acceptedSchemes = ["http", "https"];
+ var absoluteURL = context.browser.currentURI.resolve(url);
+
+ xhr.onload = function()
+ {
+ if (xhr.status !== 200)
+ return errorFunction.apply(this, arguments);
+ var codeToEval = xhr.responseText;
+ Firebug.CommandLine.evaluateInWebPage(codeToEval, context);
+ if (successFunction)
+ successFunction(xhr);
+ }
+
+ if (errorFunction)
+ {
+ xhr.ontimeout = xhr.onerror = errorFunction;
+ }
+
+ try
+ {
+ xhr.open("GET", absoluteURL, true);
+ }
+ catch(ex)
+ {
+ this.clearLoadingMessage(loadingMsgRow);
+ if (ex.name === "NS_ERROR_UNKNOWN_PROTOCOL")
+ {
+ this.log("invalidRequestProtocol", [], [context, "error"]);
+ return;
+ }
+ throw ex;
+ }
+
+ if (!~acceptedSchemes.indexOf(xhr.channel.URI.scheme))
+ {
+ this.log("invalidRequestProtocol", [], [context, "error"]);
+ this.clearLoadingMessage(loadingMsgRow);
+ return;
+ }
+
+ xhr.send(null);
+
+ // xxxFlorent: TODO show XHR progress
+ }
+};
+
+// ********************************************************************************************* //
+// Command Handler
+
+function onCommand(context, args)
+{
+ if (args.length === 0)
+ return CommandLineIncludeRep.displayAliases(context);
+
+ var self = CommandLineInclude;
+ Array.unshift(args, context);
+ return CommandLineInclude.include.apply(self, args);
+}
+
+// ********************************************************************************************* //
+// Local Helpers
+
+function IncludeEditor(doc)
+{
+ Firebug.InlineEditor.call(this, doc);
+}
+
+IncludeEditor.prototype = domplate(Firebug.InlineEditor.prototype,
+{
+ endEditing: function(target, value, cancel)
+ {
+ if (cancel)
+ return;
+
+ var context = Firebug.currentContext;
+ if (Css.hasClass(target, "aliasName"))
+ this.updateAliasName(target, value, context);
+ else if (Css.hasClass(target, "url"))
+ this.updateURL(target, value, context);
+ },
+
+ updateURL: function(target, value, context)
+ {
+ var tr = Dom.getAncestorByTagName(target, "tr");
+ var aliasName = tr.querySelector(".aliasName").textContent;
+ CommandLineInclude.include(context, value, aliasName, {"onlyUpdate":true});
+ target.textContent = value;
+ },
+
+ updateAliasName: function(target, value, context)
+ {
+ var oldAliasName = target.textContent;
+ var store = CommandLineInclude.getStore();
+ var url = store.getItem(oldAliasName);
+ store.removeItem(oldAliasName);
+ store.setItem(value, url);
+ target.dataset.aliasname = value;
+ target.textContent = value;
+ }
+});
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerCommand("include", {
+ handler: onCommand,
+ description: Locale.$STR("console.cmd.help.include"),
+ helpUrl: "http://getfirebug.com/wiki/index.php/include"
+});
+
+Firebug.registerRep(CommandLineIncludeRep);
+
+return CommandLineInclude;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/console/commandLinePopup.js b/trace/FBTrace/chrome/firebug/content/console/commandLinePopup.js
index baf80b6..ab7d556 100644
--- a/trace/FBTrace/chrome/firebug/content/console/commandLinePopup.js
+++ b/trace/FBTrace/chrome/firebug/content/console/commandLinePopup.js
@@ -158,7 +158,7 @@ Firebug.CommandLine.Popup = Obj.extend(Firebug.Module,
// If all the visual parts are already visible then bail out.
if (visible && !Dom.isCollapsed(popup) && !Dom.isCollapsed(splitter) &&
- !Dom.isCollapsed(cmdbox) && !Dom.isCollapsed(toggle))
+ !Dom.isCollapsed(cmdbox) && Dom.isCollapsed(toggle))
return;
Dom.collapse(popup, !visible);
diff --git a/trace/FBTrace/chrome/firebug/content/console/console.js b/trace/FBTrace/chrome/firebug/content/console/console.js
index cc47a06..6d42589 100644
--- a/trace/FBTrace/chrome/firebug/content/console/console.js
+++ b/trace/FBTrace/chrome/firebug/content/console/console.js
@@ -13,6 +13,8 @@ define([
"firebug/chrome/searchBox",
"firebug/console/consolePanel",
"firebug/console/commandEditor",
+ "firebug/console/functionMonitor",
+ "firebug/console/performanceTiming",
],
function(Obj, Firebug, Firefox, Events, Win, Search, Xml, Options) {
@@ -39,17 +41,20 @@ Firebug.ConsoleBase =
logFormatted: function(objects, context, className, noThrottle, sourceLink)
{
Events.dispatch(this.fbListeners,"logFormatted",[context, objects, className, sourceLink]);
- return this.logRow(appendFormatted, objects, context, className, null, sourceLink, noThrottle);
+ return this.logRow(appendFormatted, objects, context, className, null, sourceLink,
+ noThrottle);
},
openGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush)
{
- return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink, noThrottle);
+ return this.logRow(appendOpenGroup, objects, context, className, rep, sourceLink,
+ noThrottle);
},
openCollapsedGroup: function(objects, context, className, rep, noThrottle, sourceLink, noPush)
{
- return this.logRow(appendCollapsedGroup, objects, context, className, rep, sourceLink, noThrottle);
+ return this.logRow(appendCollapsedGroup, objects, context, className, rep, sourceLink,
+ noThrottle);
},
closeGroup: function(context, noThrottle)
@@ -405,22 +410,6 @@ Firebug.Console = Obj.extend(ActivableConsole,
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- // Firebug.Debugger listener
-
- onMonitorScript: function(context, frame)
- {
- Firebug.Console.log(frame, context);
- },
-
- onFunctionCall: function(context, frame, depth, calling)
- {
- if (calling)
- Firebug.Console.openGroup([frame, "depth:"+depth], context);
- else
- Firebug.Console.closeGroup(context);
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// BTI
/**
diff --git a/trace/FBTrace/chrome/firebug/content/console/consolePanel.js b/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
index 5189047..20778b8 100644
--- a/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
+++ b/trace/FBTrace/chrome/firebug/content/console/consolePanel.js
@@ -155,12 +155,12 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
if (state)
wasScrolledToBottom = state.wasScrolledToBottom;
- if (typeof(wasScrolledToBottom) == "boolean")
+ if (typeof wasScrolledToBottom == "boolean")
{
this.wasScrolledToBottom = wasScrolledToBottom;
delete state.wasScrolledToBottom;
}
- else
+ else if (typeof this.wasScrolledToBottom != "boolean")
{
// If the previous state doesn't says where to scroll,
// scroll to the bottom by default.
@@ -250,8 +250,8 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
"console.option.tip.Show_JavaScript_Warnings"),
Menu.optionMenu("ShowCSSErrors", "showCSSErrors",
"console.option.tip.Show_CSS_Errors"),
- Menu.optionMenu("ShowXMLErrors", "showXMLErrors",
- "console.option.tip.Show_XML_Errors"),
+ Menu.optionMenu("ShowXMLHTMLErrors", "showXMLErrors",
+ "console.option.tip.Show_XML_HTML_Errors"),
Menu.optionMenu("ShowXMLHttpRequests", "showXMLHttpRequests",
"console.option.tip.Show_XMLHttpRequests"),
Menu.optionMenu("ShowChromeErrors", "showChromeErrors",
@@ -294,8 +294,11 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
type: "checkbox",
checked: strictValue,
tooltiptext: "console.option.tip.Show_Strict_Warnings",
- command: Obj.bindFixed(Options.setPref, Options,
- strictDomain, strictName, !strictValue)
+ command: function()
+ {
+ var checked = this.hasAttribute("checked");
+ Options.setPref(strictDomain, strictName, checked);
+ }
};
},
@@ -497,9 +500,11 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
{
function logText(text, row)
{
- Css.setClass(row, "logRowHint");
+ var nodeSpan = row.ownerDocument.createElement("span");
+ Css.setClass(nodeSpan, "logRowHint");
var node = row.ownerDocument.createTextNode(text);
- row.appendChild(node);
+ row.appendChild(nodeSpan);
+ nodeSpan.appendChild(node);
}
function logTextNode(text, row)
@@ -563,23 +568,35 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
}
}
+ // Last CSS style defined using "%c" that should be applied on
+ // created log-row parts (elements). See issue 6064.
+ // Example: console.log('%cred-text %cgreen-text', 'color:red', 'color:green');
+ var lastStyle;
+
for (var i = 0; i < parts.length; ++i)
{
+ var node;
var part = parts[i];
if (part && typeof(part) == "object")
{
var object = objects[objIndex++];
if (part.type == "%c")
- row.setAttribute("style", object.toString());
+ lastStyle = object.toString();
else if (typeof(object) != "undefined")
- this.appendObject(object, row, part.rep);
+ node = this.appendObject(object, row, part.rep);
else
- this.appendObject(part.type, row, FirebugReps.Text);
+ node = this.appendObject(part.type, row, FirebugReps.Text);
}
else
{
- FirebugReps.Text.tag.append({object: part}, row);
+ node = FirebugReps.Text.tag.append({object: part}, row);
}
+
+ // Apply custom style if available.
+ if (lastStyle && node)
+ node.setAttribute("style", lastStyle);
+
+ node = null;
}
for (var i = objIndex; i < objects.length; ++i)
@@ -748,6 +765,16 @@ Firebug.ConsolePanel.prototype = Obj.extend(Firebug.ActivablePanel,
if (this.wasScrolledToBottom)
Dom.scrollToBottom(this.panelNode);
},
+
+ showInfoTip: function(infoTip, target, x, y)
+ {
+ var object = Firebug.getRepObject(target);
+ var rep = Firebug.getRep(object, this.context);
+ if (!rep)
+ return false;
+
+ return rep.showInfoTip(infoTip, target, x, y);
+ }
});
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/console/errors.js b/trace/FBTrace/chrome/firebug/content/console/errors.js
index 7f3c440..93a33d3 100644
--- a/trace/FBTrace/chrome/firebug/content/console/errors.js
+++ b/trace/FBTrace/chrome/firebug/content/console/errors.js
@@ -146,6 +146,9 @@ var Errors = Firebug.Errors = Obj.extend(Firebug.Module,
startObserving: function()
{
+ if (this.isObserving)
+ return;
+
if (FBTrace.DBG_ERRORLOG)
FBTrace.sysout("Errors.startObserving");
@@ -157,6 +160,9 @@ var Errors = Firebug.Errors = Obj.extend(Firebug.Module,
stopObserving: function()
{
+ if (!this.isObserving)
+ return;
+
if (FBTrace.DBG_ERRORLOG)
FBTrace.sysout("Errors.stopObserving");
@@ -371,8 +377,12 @@ var Errors = Firebug.Errors = Obj.extend(Firebug.Module,
correctLineNumbersOnExceptions(object, error);
}
- if (Firebug.showStackTrace && Firebug.errorStackTrace)
+ if (Firebug.errorStackTrace)
+ {
error.correctWithStackTrace(Firebug.errorStackTrace);
+ if (!Firebug.showStackTrace)
+ error.trace = null;
+ }
var msgId = lessTalkMoreAction(context, object, isWarning);
if (!msgId)
@@ -666,6 +676,7 @@ const categoryMap =
"DOM": "js",
"Events": "js",
"CSS": "css",
+ "HTML": "xml",
"XML": "xml",
"malformed-xml": "xml"
};
@@ -704,9 +715,10 @@ function whyNotShown(url, categoryList, isWarning)
{
return "showCSSErrors";
}
- else if ((category == "XML" || category == "malformed-xml" ) && !Firebug.showXMLErrors)
+ else if ((category == "HTML" || category == "XML" || category == "malformed-xml" ) &&
+ !Firebug.showXMLErrors)
{
- return "showXMLErors";
+ return "showXMLErrors";
}
else if ((category == "javascript" || category == "JavaScript" || category == "DOM")
&& !isWarning && !Firebug.showJSErrors)
diff --git a/trace/FBTrace/chrome/firebug/content/console/eventMonitor.js b/trace/FBTrace/chrome/firebug/content/console/eventMonitor.js
index e5ba4bd..42e6d4d 100644
--- a/trace/FBTrace/chrome/firebug/content/console/eventMonitor.js
+++ b/trace/FBTrace/chrome/firebug/content/console/eventMonitor.js
@@ -5,13 +5,14 @@ define([
"firebug/firebug",
"firebug/lib/trace",
"firebug/lib/events",
+ "firebug/lib/locale",
],
-function(Obj, Firebug, FBTrace, Events) {
+function(Obj, Firebug, FBTrace, Events, Locale) {
// ********************************************************************************************* //
// EventMonitor Module
-Firebug.EventMonitor = Obj.extend(Firebug.Module,
+var EventMonitor = Obj.extend(Firebug.Module,
{
dispatchName: "eventMonitor",
@@ -52,7 +53,12 @@ Firebug.EventMonitor = Obj.extend(Firebug.Module,
if (object && object.addEventListener)
{
if (!context.onMonitorEvent)
- context.onMonitorEvent = function(event) { Firebug.Console.log(event, context); };
+ {
+ var self = this;
+ context.onMonitorEvent = function(event) {
+ self.onMonitorEvent(event, context);
+ };
+ }
if (!context.eventsMonitored)
context.eventsMonitored = [];
@@ -88,7 +94,7 @@ Firebug.EventMonitor = Obj.extend(Firebug.Module,
if (eventsMonitored[j].object == object && eventsMonitored[j].type == eventTypes[i])
{
eventsMonitored.splice(j, 1);
-
+
Events.removeEventListener(object, eventTypes[i], context.onMonitorEvent, false);
break;
}
@@ -127,22 +133,44 @@ Firebug.EventMonitor = Obj.extend(Firebug.Module,
if (!monitored)
{
if (FBTrace.DBG_EVENTS)
- FBTrace.sysout("EventMonitor.areEventsMonitored - Events not monitored for '"+eventTypes[i]+"'");
-
+ {
+ FBTrace.sysout("EventMonitor.areEventsMonitored - Events not monitored for '" +
+ eventTypes[i] + "'");
+ }
+
return false;
}
else
{
if (FBTrace.DBG_EVENTS)
- FBTrace.sysout("EventMonitor.areEventsMonitored - Events monitored for '"+eventTypes[i]+"'");
+ {
+ FBTrace.sysout("EventMonitor.areEventsMonitored - Events monitored for '" +
+ eventTypes[i] + "'");
+ }
}
}
return true;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Logging
+
+ onMonitorEvent: function(event, context)
+ {
+ var obj = new EventMonitor.EventLog(event);
+ Firebug.Console.log(obj, context);
}
});
-//********************************************************************************************* //
+// ********************************************************************************************* //
+
+EventMonitor.EventLog = function(event)
+{
+ this.event = event;
+}
+
+// ********************************************************************************************* //
// Helpers
function getMonitoredEventTypes(types)
@@ -180,11 +208,44 @@ function getMonitoredEventTypes(types)
}
// ********************************************************************************************* //
-// Registration & Export
+// CommandLine Support
+
+function monitorEvents(context, args)
+{
+ var object = args[0];
+ var types = args[1];
+
+ EventMonitor.monitorEvents(object, types, context);
+ return Firebug.Console.getDefaultReturnValue(context.window);
+}
+
+function unmonitorEvents(context, args)
+{
+ var object = args[0];
+ var types = args[1];
+
+ EventMonitor.unmonitorEvents(object, types, context);
+ return Firebug.Console.getDefaultReturnValue(context.window);
+}
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerModule(EventMonitor);
+
+Firebug.registerCommand("monitorEvents", {
+ handler: monitorEvents.bind(this),
+ helpUrl: "http://getfirebug.com/wiki/index.php/monitorEvents",
+ description: Locale.$STR("console.cmd.help.monitorEvents")
+})
-Firebug.registerModule(Firebug.EventMonitor);
+Firebug.registerCommand("unmonitorEvents", {
+ handler: unmonitorEvents.bind(this),
+ helpUrl: "http://getfirebug.com/wiki/index.php/unmonitorEvents",
+ description: Locale.$STR("console.cmd.help.unmonitorEvents")
+})
-return Firebug.EventMonitor;
+return EventMonitor;
// ********************************************************************************************* //
});
diff --git a/trace/FBTrace/chrome/firebug/content/console/functionMonitor.js b/trace/FBTrace/chrome/firebug/content/console/functionMonitor.js
new file mode 100644
index 0000000..9957856
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/console/functionMonitor.js
@@ -0,0 +1,191 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/lib/trace",
+ "firebug/lib/object",
+ "firebug/lib/domplate",
+ "firebug/chrome/reps",
+ "firebug/js/stackFrame",
+ "firebug/lib/events",
+ "firebug/lib/css",
+ "firebug/lib/dom",
+ "firebug/lib/url",
+],
+function(FBTrace, Obj, Domplate, Reps, StackFrame, Events, Css, Dom, Url) { with (Domplate) {
+
+// ********************************************************************************************* //
+// Function Monitor
+
+var FunctionMonitor = Obj.extend(Firebug.Module,
+{
+ dispatchName: "functionMonitor",
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Module
+
+ initialize: function()
+ {
+ Firebug.Module.initialize.apply(this, arguments);
+ Firebug.connection.addListener(this);
+ },
+
+ shutdown: function()
+ {
+ Firebug.connection.removeListener(this);
+ Firebug.Module.shutdown.apply(this, arguments);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug.Debugger listener
+
+ onMonitorScript: function(context, frame)
+ {
+ var stackTrace = StackFrame.buildStackTrace(frame);
+ Firebug.Console.log(new FunctionLog(frame, stackTrace), context);
+ },
+
+ onFunctionCall: function(context, frame, depth, calling)
+ {
+ //var url = Url.normalizeURL(frame.script.fileName);
+ //var sourceFile = context.sourceFileMap[url];
+ // Firebug.errorStackTrace = StackFrame.getCorrectedStackTrace(frame, context);
+ //var sourceFile = Firebug.SourceFile.getSourceFileByScript(context, frame.script);
+ if (Url.isSystemURL(Url.normalizeURL(frame.script.fileName)))
+ return;
+
+ // xxxHonza: traceCall and traceCallAll need to be fixed yet.
+ FBTrace.sysout("functionMonitor.onFunctionCall; ", sourceFile);
+
+ if (calling)
+ Firebug.Console.openGroup([frame, "depth:" + depth], context);
+ else
+ Firebug.Console.closeGroup(context);
+ },
+});
+
+// ********************************************************************************************* //
+// Rep Object
+
+function FunctionLog(frame, stackTrace)
+{
+ this.frame = frame;
+ this.stackTrace = stackTrace;
+}
+
+// ********************************************************************************************* //
+// Function Monitor Rep
+
+var FunctionMonitorRep = domplate(Firebug.Rep,
+{
+ className: "functionCall",
+
+ tag:
+ Reps.OBJECTBLOCK({$hasTwisty: "$object|hasStackTrace", _repObject: "$object",
+ onclick: "$onToggleStackTrace"},
+ A({"class": "objectLink functionCallTitle a11yFocus", _repObject: "$object"},
+ "$object|getCallName"
+ ),
+ SPAN("("),
+ SPAN({"class": "arguments"},
+ FOR("arg", "$object|argIterator",
+ SPAN({"class": "argName"}, "$arg.name"),
+ SPAN("="),
+ TAG("$arg.tag", {object: "$arg.value"}),
+ SPAN({"class": "arrayComma"}, "$arg.delim")
+ )
+ ),
+ SPAN(")"),
+ SPAN({"class": "objectLink-sourceLink objectLink a11yFocus",
+ _repObject: "$object|getSourceLink",
+ role: "link"},
+ "$object|getSourceLinkTitle"),
+ DIV({"class": "stackTrace"})
+ ),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ hasStackTrace: function(object)
+ {
+ return true;
+ },
+
+ getTitle: function(object)
+ {
+ return object.frame.getFunctionName();
+ },
+
+ getCallName: function(object)
+ {
+ return this.getTitle(object);
+ },
+
+ getSourceLink: function(object)
+ {
+ return Reps.StackFrame.getSourceLink(object.frame);
+ },
+
+ getSourceLinkTitle: function(object)
+ {
+ return Reps.StackFrame.getSourceLinkTitle(object.frame);
+ },
+
+ argIterator: function(object)
+ {
+ return Reps.StackFrame.argIterator(object.frame);
+ },
+
+ onToggleStackTrace: function(event)
+ {
+ var target = event.originalTarget;
+
+ // Only clicking on the expand button or the function title actually expands
+ // the function call log. All other clicks keep default behavior
+ if (!(Css.hasClass(target, "objectBox-functionCall") ||
+ Css.hasClass(target, "functionCallTitle")))
+ {
+ return;
+ }
+
+ var objectBox = Dom.getAncestorByClass(target, "objectBox-functionCall");
+ if (!objectBox)
+ return;
+
+ var traceBox = objectBox.getElementsByClassName("stackTrace").item(0);
+ Css.toggleClass(traceBox, "opened");
+
+ if (Css.hasClass(traceBox, "opened"))
+ {
+ var functionCall = objectBox.repObject;
+ Reps.StackTrace.tag.append({object: functionCall.stackTrace}, traceBox);
+ }
+ else
+ {
+ Dom.clearNode(traceBox);
+ }
+
+ Events.cancelEvent(event);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ supportsObject: function(object, type)
+ {
+ return object instanceof FunctionLog;
+ },
+
+ getRealObject: function(object)
+ {
+ return object.frame;
+ },
+});
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerModule(FunctionMonitor);
+Firebug.registerRep(FunctionMonitorRep);
+
+return FunctionMonitor;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/console/performanceTiming.js b/trace/FBTrace/chrome/firebug/content/console/performanceTiming.js
new file mode 100644
index 0000000..b601e27
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/console/performanceTiming.js
@@ -0,0 +1,630 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/firebug",
+ "firebug/lib/trace",
+ "firebug/lib/domplate",
+ "firebug/lib/object",
+ "firebug/lib/locale",
+ "firebug/lib/dom",
+ "firebug/lib/events",
+ "firebug/lib/string",
+ "firebug/lib/wrapper",
+ "firebug/lib/css",
+],
+function(Firebug, FBTrace, Domplate, Obj, Locale, Dom, Events, Str, Wrapper, Css) {
+with (Domplate) {
+
+// ********************************************************************************************* //
+// Docs
+
+// See http://www.w3.org/TR/navigation-timing/
+
+// ********************************************************************************************* //
+// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+// List of timing properties in performance.timing structure.
+var timingProps = [
+ "connectEnd",
+ "connectStart",
+ "domComplete",
+ "domContentLoadedEventEnd",
+ "domContentLoadedEventStart",
+ "domInteractive",
+ "domLoading",
+ "domainLookupEnd",
+ "domainLookupStart",
+ "fetchStart",
+ "loadEventEnd",
+ "loadEventStart",
+ "navigationStart",
+ "redirectCount",
+ "redirectEnd",
+ "redirectStart",
+ "requestStart",
+ "responseEnd",
+ "responseStart",
+ "unloadEventEnd",
+ "unloadEventStart",
+];
+
+// ********************************************************************************************* //
+// Module
+
+var PerformanceTimingModule = Obj.extend(Firebug.Module,
+{
+ initialize: function(prefDomain, prefNames)
+ {
+ Firebug.Module.initialize.apply(this, arguments);
+ Firebug.Console.addListener(ConsoleListener);
+ },
+
+ shutdown: function()
+ {
+ Firebug.Module.shutdown.apply(this, arguments);
+ Firebug.Console.removeListener(ConsoleListener);
+ },
+});
+
+// ********************************************************************************************* //
+// Domplate
+
+/**
+ * This template is used to render the timing waterfall graph.
+ */
+var PerformanceTimingRep = domplate(Firebug.Rep,
+/** @lends PerformanceTimingRep */
+{
+ className: "perfTiming",
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ tag:
+ TABLE({"class": "perfTimingTable", cellspacing: 0, cellpadding: 0, width: "100%",
+ "role": "grid", _repObject: "$object"},
+ TBODY({"class": "perfTimingTbody", "role": "presentation"},
+ FOR("bar", "$object.bars",
+ TR(
+ TD(
+ DIV({"class": "perfTimingBox"},
+ DIV({"class": "perfTimingBar $bar.className",
+ style: "left: $bar.left%; width: $bar.width%"},
+ SPAN({"class": "perfTimingBarLabel"}, "$bar.label")
+ ),
+ DIV({"class": "perfTimingEvent domLoading",
+ style: "left: $bar.domLoading%;"}
+ ),
+ DIV({"class": "perfTimingEvent domInteractive",
+ style: "left: $bar.domInteractive%;"}
+ ),
+ DIV({"class": "perfTimingEvent domContentLoaded",
+ style: "left: $bar.domContentLoaded%;"}
+ ),
+ DIV({"class": "perfTimingEvent onLoad",
+ style: "left: $bar.onLoad%;"}
+ ),
+ DIV({"class": "perfTimingEvent cursor"})
+ )
+ )
+ )
+ )
+ )
+ ),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ getRealObject: function(object)
+ {
+ return Wrapper.unwrapObject(object.timing);
+ },
+
+ supportsObject: function(object, type)
+ {
+ return (object instanceof PerfTimingObj);
+ },
+
+ getContextMenuItems: function(object, target, context)
+ {
+ return [];
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ showInfoTip: function(infoTip, target, x, y)
+ {
+ var table = Dom.getAncestorByClass(target, "perfTimingTable");
+ if (!table)
+ return false;
+
+ var timingObj = table.repObject;
+ return PerfInfoTip.render(timingObj.timing, infoTip);
+ }
+});
+
+// ********************************************************************************************* //
+// InfoTip
+
+/**
+ * Hovering mouse over the waterfall graph shows an infotip. This template is responsible
+ * for rendering its content.
+ */
+var PerfInfoTip = domplate(Firebug.Rep,
+/** @lends PerfInfoTip */
+{
+ tableTag:
+ TABLE({"class": "timeInfoTip", "id": "fbPerfTimingInfoTip"},
+ TBODY()
+ ),
+
+ timingsTag:
+ FOR("bar", "$bars",
+ TR({"class": "timeInfoTipRow", $collapsed: "$bar|hideBar"},
+ TD({"class": "timeInfoTipBar $bar|getClassName"}),
+ TD({"class": "timeInfoTipCell startTime"},
+ "$bar.start|formatStartTime"
+ ),
+ TD({"class": "timeInfoTipCell elapsedTime"},
+ "$bar.elapsed|formatTime"
+ ),
+ TD("$bar|getLabel")
+ )
+ ),
+
+ separatorTag:
+ TR(
+ TD({"class": "timeInfoTipSeparator", "colspan": 4, "height": "10px"},
+ SPAN("$label")
+ )
+ ),
+
+ eventsTag:
+ FOR("event", "$events",
+ TR({"class": "timeInfoTipEventRow"},
+ TD({"class": "timeInfoTipBar", align: "center"},
+ DIV({"class": "$event|getClassName timeInfoTipEventBar"})
+ ),
+ TD("$event.start|formatStartTime"),
+ TD({"class": "timeInfotTipEventName", "colspan": 2},
+ "$event|getTimeStampLabel"
+ )
+ )
+ ),
+
+ hideBar: function(obj)
+ {
+ return !obj.elapsed && obj.className == "redirect";
+ },
+
+ getClassName: function(obj)
+ {
+ return obj.className;
+ },
+
+ formatTime: function(time)
+ {
+ return Str.formatTime(time);
+ },
+
+ formatStartTime: function(time)
+ {
+ var label = Str.formatTime(time);
+ if (!time)
+ return label;
+
+ return (time > 0 ? "+" : "") + label;
+ },
+
+ getLabel: function(obj)
+ {
+ return Locale.$STR("perftiming." + obj.label);
+ },
+
+ getTimeStampLabel: function(obj)
+ {
+ return obj.name;
+ },
+
+ render: function(timing, parentNode)
+ {
+ var infoTip = Firebug.NetMonitor.TimeInfoTip.tableTag.replace({}, parentNode);
+
+ // Insert top description.
+ this.separatorTag.insertRows({label: Locale.$STR("perftiming.bars.label")},
+ infoTip.firstChild);
+
+ // Insert request timing info.
+ var bars = calculateBars(timing);
+ this.timingsTag.insertRows({bars: bars}, infoTip.firstChild);
+
+ var t = timing;
+
+ var events = [];
+ events.push({
+ name: "DOM Loading",
+ className: "domLoading",
+ start: t.domLoading - t.navigationStart
+ });
+
+ events.push({
+ name: "DOM Interactive",
+ className: "domInteractive",
+ start: t.domInteractive - t.navigationStart,
+ });
+
+ events.push({
+ name: "DOMContentLoaded",
+ className: "domContentLoaded",
+ start: t.domContentLoadedEventStart - t.navigationStart,
+ });
+
+ events.push({
+ name: "load",
+ className: "onLoad",
+ start: t.loadEventStart - t.navigationStart,
+ })
+
+ // Insert separator.
+ this.separatorTag.insertRows({label: Locale.$STR("requestinfo.timings.label")},
+ infoTip.firstChild);
+
+ this.eventsTag.insertRows({events: events}, infoTip.firstChild);
+
+ return true;
+ }
+});
+
+// ********************************************************************************************* //
+// Rep Object
+
+function PerfTimingObj(bars, timing)
+{
+ this.bars = bars;
+ this.timing = timing;
+}
+
+// ********************************************************************************************* //
+
+/**
+ * Console listener is responsible for rendering the Performance visualization every time
+ * the user logs 'performance.timing' on the command line.
+ */
+var ConsoleListener =
+/** @lends ConsoleListener */
+{
+ tag:
+ DIV({_repObject: "$object"},
+ DIV({"class": "documentCookieBody"})
+ ),
+
+ log: function(context, object, className, sourceLink)
+ {
+ if (!context || !object)
+ return;
+
+ var type = Object.prototype.toString.call(object);
+ if (type === "[object PerformanceTiming]")
+ performanceTiming(context, object);
+ },
+
+ logFormatted: function(context, objects, className, sourceLink)
+ {
+ }
+};
+
+// ********************************************************************************************* //
+// Console Logging
+
+/**
+ * This function is responsible for inserting the waterfall graph into the Console panel.
+ */
+function performanceTiming(context, timing)
+{
+ var t = timing;
+ var elapsed = t.loadEventEnd - t.navigationStart;
+
+ var objects = [];
+ var rep = PerformanceTimingRep;
+ var bars = calculateBars(t);
+
+ var result = []
+ for (var i=0; i<bars.length; i++)
+ {
+ var bar = bars[i];
+
+ // Filter our empty bars.
+ if (!bar.elapsed)
+ continue;
+
+ bar.left = calculatePos(bar.start, elapsed);
+ bar.width = calculatePos(bar.elapsed, elapsed);
+ bar.label = bar.label + " " + Str.formatTime(bar.elapsed);
+
+ result.push(bar);
+ }
+
+ // Events
+ var domLoading = calculatePos(t.domLoading - t.navigationStart, elapsed);
+ var domInteractive = calculatePos(t.domInteractive - t.navigationStart, elapsed);
+ var domContentLoaded = calculatePos(t.domContentLoadedEventStart - t.navigationStart, elapsed);
+ var onLoad = calculatePos(t.loadEventStart - t.navigationStart, elapsed);
+
+ for (var i=0; i<result.length; i++)
+ {
+ var bar = result[i];
+ bar.domLoading = domLoading;
+ bar.domInteractive = domInteractive;
+ bar.domContentLoaded = domContentLoaded;
+ bar.onLoad = onLoad;
+ }
+
+ var input = new PerfTimingObj(result, t);
+ Firebug.Console.log(input, context, "perfTiming", rep, true);
+
+ // Details
+ var row = Firebug.Console.openCollapsedGroup("perfTimingDetails", context, "perfTimingDetails",
+ DetailsCaption, true, null, true);
+ Firebug.Console.closeGroup(context, true);
+
+ var logGroupBody = row.lastChild;
+ var table = DetailsTable.tag.replace({object: t}, logGroupBody);
+ var tBody = table.lastChild;
+
+ // Iterate only known properties (these are also localized).
+ var timings = [];
+ for (var i=0; i<timingProps.length; i++)
+ {
+ var name = timingProps[i];
+ var value = t[name];
+ var startTime = value ? (value - t.navigationStart) : 0;
+ var timing = {
+ name: name,
+ timeLabel: startTime ? "+" + Str.formatTime(startTime) : 0,
+ desc: Locale.$STR("perftiming." + name),
+ time: startTime,
+ }
+ timings.push(timing);
+ }
+
+ timings.sort(function(a, b) {
+ return a.time > b.time ? 1 : -1;
+ })
+
+ DetailsEntry.tag.insertRows({timings: timings}, tBody);
+
+ return Firebug.Console.getDefaultReturnValue(context.window);
+}
+
+// ********************************************************************************************* //
+// Detailed Log
+
+/**
+ * A capation for detailed performance timing info.
+ */
+var DetailsCaption = domplate(
+/** @lends DetailsCaption */
+{
+ tag:
+ SPAN({"class": "timingTitle"},
+ SPAN({"class": "timingCaption"},
+ Locale.$STR("perftiming.details_title")
+ ),
+ SPAN({"class": "timingCaptionDesc"},
+ Locale.$STR("perftiming.details_title_desc")
+ )
+ )
+});
+
+// ********************************************************************************************* //
+
+/**
+ * This template represents a table with detailed timing info.
+ */
+var DetailsTable = domplate(
+/** @lends DetailsTable */
+{
+ tag:
+ TABLE({"class": "timingTable", cellspacing: 0, cellpadding: 0, width: "100%",
+ "role": "grid", _repObject: "$object"},
+ THEAD({"class": "timingThead", "role": "presentation"},
+ TR({"class": "headerRow focusRow timingRow subFocusRow", "role": "row"},
+ TH({"class": "headerCell a11yFocus", "role": "columnheader", width: "10%"},
+ DIV({"class": "headerCellBox"},
+ Locale.$STR("Name")
+ )
+ ),
+ TH({"class": "headerCell a11yFocus", "role": "columnheader", width: "10%"},
+ DIV({"class": "headerCellBox"},
+ Locale.$STR("Time")
+ )
+ ),
+ TH({"class": "headerCell a11yFocus", "role": "columnheader", width: "70%"},
+ DIV({"class": "headerCellBox"},
+ Locale.$STR("Description")
+ )
+ )
+ )
+ ),
+ TBODY({"class": "perfTimingTbody", "role": "presentation"}
+ )
+ ),
+});
+
+// ********************************************************************************************* //
+
+/**
+ * A row within detailed performance timing info.
+ */
+var DetailsEntry = domplate(
+/** @lends DetailsEntry */
+{
+ tag:
+ FOR("timing", "$timings",
+ TR({"class": "focusRow timingRow subFocusRow", "role": "row", _repObject: "$timing",
+ onmousemove: "$onMouseMove", onmouseout: "$onMouseOut"},
+ TD({"class": "a11yFocus timingCell timingName", "role": "gridcell"},
+ "$timing.name"
+ ),
+ TD({"class": "a11yFocus timingCell timingTime", "role": "gridcell"},
+ "$timing.timeLabel"
+ ),
+ TD({"class": "a11yFocus timingCell timingDesc", "role": "gridcell"},
+ "$timing.desc"
+ )
+ )
+ ),
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ onMouseMove: function(event)
+ {
+ var row = Dom.getAncestorByClass(event.target, "timingRow");
+ if (!row)
+ return;
+
+ var log = Dom.getAncestorByClass(row, "logRow-perfTimingDetails");
+ var graph = log.previousSibling;
+ if (!Css.hasClass(graph, "logRow-perfTiming"))
+ return;
+
+ var table = Dom.getAncestorByClass(row, "timingTable");
+ var timing = table.repObject;
+
+ var elapsed = timing.loadEventEnd - timing.navigationStart;
+ var startTime = row.repObject.time;
+
+ var tBody = graph.getElementsByClassName("perfTimingTbody")[0];
+ var rows = tBody.getElementsByTagName("tr");
+ for (var i=0; i<rows.length; i++)
+ {
+ var row = rows[i];
+ var cursor = row.getElementsByClassName("cursor")[0];
+
+ Dom.hide(cursor, false);
+ cursor.style.left = calculatePos(startTime, elapsed) + "%";
+ }
+ },
+
+ onMouseOut: function(event)
+ {
+ var row = Dom.getAncestorByClass(event.target, "timingRow");
+ if (!row)
+ return;
+
+ var log = Dom.getAncestorByClass(row, "logRow-perfTimingDetails");
+ var graph = log.previousSibling;
+ if (!Css.hasClass(graph, "logRow-perfTiming"))
+ return;
+
+ var tBody = graph.getElementsByClassName("perfTimingTbody")[0];
+ var rows = tBody.getElementsByTagName("tr");
+ for (var i=0; i<rows.length; i++)
+ {
+ var row = rows[i];
+ var cursor = row.getElementsByClassName("cursor")[0];
+ Dom.hide(cursor, true);
+ }
+ }
+});
+
+// ********************************************************************************************* //
+// Helpers
+
+function calculatePos(time, elapsed)
+{
+ return Math.round((time / elapsed) * 100);
+}
+
+function calculateBars(timing)
+{
+ var result = [];
+ var t = timing;
+
+ // Page Load bar
+ result.push({
+ className: "pageLoad",
+ start: 0,
+ elapsed: t.loadEventEnd - t.navigationStart,
+ label: Locale.$STR("Page Load"),
+ });
+
+ // Redirect
+ result.push({
+ className: "redirect",
+ start: t.redirectStart ? t.redirectStart - t.navigationStart : 0,
+ elapsed: t.redirectStart ? t.redirectEnd - t.redirectStart : 0,
+ label: Locale.$STR("Redirect"),
+ });
+
+ // DNS
+ var dns = t.domainLookupEnd - t.domainLookupStart;
+ result.push({
+ className: "dns",
+ start: t.domainLookupStart - t.navigationStart,
+ elapsed: t.domainLookupEnd - t.domainLookupStart,
+ label: Locale.$STR("DNS"),
+ });
+
+ // Connect bar
+ result.push({
+ className: "connecting",
+ start: t.connectStart - t.navigationStart,
+ elapsed: t.connectEnd - t.connectStart,
+ label: Locale.$STR("Connecting"),
+ });
+
+ // Waiting bar
+ result.push({
+ className: "waiting",
+ start: t.requestStart - t.navigationStart,
+ elapsed: t.responseStart - t.requestStart,
+ label: Locale.$STR("Waiting"),
+ });
+
+ // Response bar
+ result.push({
+ className: "response",
+ start: t.responseStart - t.navigationStart,
+ elapsed: t.responseEnd - t.responseStart,
+ label: Locale.$STR("Receiving"),
+ });
+
+ // Processing bar
+ result.push({
+ className: "processing",
+ start: t.responseEnd - t.navigationStart,
+ elapsed: t.loadEventStart - t.responseEnd,
+ label: Locale.$STR("DOM Processing"),
+ });
+
+ // DOMContentLoaded
+ result.push({
+ className: "DOMContentLoaded",
+ start: t.domContentLoadedEventStart - t.navigationStart,
+ elapsed: t.domContentLoadedEventEnd - t.domContentLoadedEventStart,
+ label: Locale.$STR("DOMContentLoaded"),
+ });
+
+ // onLoad
+ result.push({
+ className: "onLoad",
+ start: t.loadEventStart - t.navigationStart,
+ elapsed: t.loadEventEnd - t.loadEventStart,
+ label: Locale.$STR("onLoad"),
+ });
+
+ return result;
+}
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerRep(PerformanceTimingRep);
+Firebug.registerModule(PerformanceTimingModule);
+
+return PerformanceTimingModule;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/console/profiler.js b/trace/FBTrace/chrome/firebug/content/console/profiler.js
index c6c4e12..387caab 100644
--- a/trace/FBTrace/chrome/firebug/content/console/profiler.js
+++ b/trace/FBTrace/chrome/firebug/content/console/profiler.js
@@ -172,7 +172,7 @@ Firebug.Profiler = Obj.extend(Firebug.Module,
var sourceFileMap = context.sourceFileMap;
if (FBTrace.DBG_PROFILER)
{
- for (url in sourceFileMap)
+ for (var url in sourceFileMap)
FBTrace.sysout("logProfileReport: "+sourceFileMap[url]+"\n");
}
@@ -513,11 +513,39 @@ function ProfileCall(script, context, callCount, totalTime, totalOwnTime, minTim
}
// ********************************************************************************************* //
+// CommandLine Support
+
+function profile(context, args)
+{
+ var title = args[0];
+ Firebug.Profiler.startProfiling(context, title);
+ return Firebug.Console.getDefaultReturnValue(context.window);
+};
+
+function profileEnd(context)
+{
+ Firebug.Profiler.stopProfiling(context);
+ return Firebug.Console.getDefaultReturnValue(context.window);
+};
+
+// ********************************************************************************************* //
// Registration
Firebug.registerModule(Firebug.Profiler);
Firebug.registerRep(Firebug.Profiler.ProfileCall);
+Firebug.registerCommand("profile", {
+ handler: profile.bind(this),
+ helpUrl: "http://getfirebug.com/wiki/index.php/profile",
+ description: Locale.$STR("console.cmd.help.profile")
+})
+
+Firebug.registerCommand("profileEnd", {
+ handler: profileEnd.bind(this),
+ helpUrl: "http://getfirebug.com/wiki/index.php/profileEnd",
+ description: Locale.$STR("console.cmd.help.profileEnd")
+})
+
return Firebug.Profiler;
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookie.js b/trace/FBTrace/chrome/firebug/content/cookies/cookie.js
index ada86f4..be7248b 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookie.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookie.js
@@ -3,6 +3,7 @@
define([
"firebug/lib/xpcom",
"firebug/lib/json",
+ "firebug/lib/string",
],
function(Xpcom, Json) {
@@ -140,7 +141,17 @@ Cookie.prototype =
}
return null;
- }
+ },
+
+ getSize: function()
+ {
+ return this.cookie.name.length + this.cookie.value.length;
+ },
+
+ getRawSize: function()
+ {
+ return this.cookie.name.length + this.cookie.rawValue.length
+ },
};
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookieClipboard.js b/trace/FBTrace/chrome/firebug/content/cookies/cookieClipboard.js
index 01ed2e4..e389f33 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookieClipboard.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookieClipboard.js
@@ -100,6 +100,10 @@ var CookieClipboard = Obj.extend(Object,
{
var trans = Xpcom.CCIN("@mozilla.org/widget/transferable;1", "nsITransferable");
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=722872
+ if (typeof(trans.init) == "function")
+ trans.init(null);
+
var json = cookie.toJSON();
var wrapper1 = Xpcom.CCIN("@mozilla.org/supports-string;1", "nsISupportsString");
wrapper1.data = json;
@@ -124,6 +128,11 @@ var CookieClipboard = Obj.extend(Object,
getTransferData: function()
{
var trans = Xpcom.CCIN("@mozilla.org/widget/transferable;1", "nsITransferable");
+
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=722872
+ if (typeof(trans.init) == "function")
+ trans.init(null);
+
trans.addDataFlavor(this.cookieFlavour);
clipboard.getData(trans, Ci.nsIClipboard.kGlobalClipboard);
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookieModule.js b/trace/FBTrace/chrome/firebug/content/cookies/cookieModule.js
index 0015b05..9b1e6a0 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookieModule.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookieModule.js
@@ -64,7 +64,7 @@ const prompts = Xpcom.CCSV("@mozilla.org/embedcomp/prompt-service;1", "nsIPrompt
// Preferences
const PrefService = Cc["@mozilla.org/preferences-service;1"];
const prefService = PrefService.getService(Ci.nsIPrefService);
-const prefs = PrefService.getService(Ci.nsIPrefBranch2);
+const prefs = PrefService.getService(Ci.nsIPrefBranch);
// Cookie panel ID.
const panelName = "cookies";
@@ -676,45 +676,30 @@ Firebug.CookieModule = Obj.extend(Firebug.ActivableModule,
return true;
},
- onRemoveAllShared: function(context, sessionOnly)
+ /**
+ * Removes cookies defined for a website
+ * @param {Object} context context, in which the cookies are defined
+ * @param {Object} [filter] filter to define, which cookies should be removed
+ * (format: {session: true/false, host: string})
+ */
+ removeCookies: function(context, filter)
{
var panel = context.getPanel(panelName, true);
if (!panel)
return;
- var cookies = [];
-
- // Remove all cookies in the list. Notice that the list can be further
- // filtered by the search-box (the right side of Firebug's tab bar)
- // So, make sure in case of searching-on, only visible (matched)
- // cookies are removed.
- var searching = Css.hasClass(panel.panelNode, "searching");
- var row = Dom.getElementByClass(panel.panelNode, "cookieRow");
- while (row)
+ for (var host in context.cookies.activeHosts)
{
- if (!searching || Css.hasClass(row, "matched"))
+ var cookieEnumerator = cookieManager.getCookiesFromHost(host);
+
+ while (cookieEnumerator.hasMoreElements())
{
- var cookie = row.repObject;
+ var cookie = cookieEnumerator.getNext().QueryInterface(Ci.nsICookie2);
- // Some entries within the Cookies panel don't represent a cookie.
- if (cookie)
- {
- // If sessionOnly flag is true, only session cookies will be removed.
- if (sessionOnly)
- {
- if (!cookie.cookie.expires)
- cookies.push(cookie);
- }
- else
- cookies.push(cookie);
- }
+ if (!filter || ((!filter.session || cookie.isSession) && (!filter.host || filter.host == cookie.host)))
+ cookieManager.remove(cookie.host, cookie.name, cookie.path, false);
}
-
- row = row.nextSibling;
}
-
- for (var i=0; i<cookies.length; i++)
- CookieReps.CookieRow.onRemove(cookies[i]);
},
onRemoveAll: function(context)
@@ -723,11 +708,11 @@ Firebug.CookieModule = Obj.extend(Firebug.ActivableModule,
{
var check = {value: false};
var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
- prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO;
+ prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO;
if (!prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
Locale.$STR("cookies.confirm.removeall"), flags, "", "", "",
- Locale.$STR("cookies.msg.Do_not_show_this_message_again"), check) == 0)
+ Locale.$STR("Do_not_show_this_message_again"), check) == 0)
{
return;
}
@@ -737,9 +722,9 @@ Firebug.CookieModule = Obj.extend(Firebug.ActivableModule,
Options.set(removeConfirmation, !check.value);
}
- Firebug.CookieModule.onRemoveAllShared(context, false);
+ Firebug.CookieModule.removeCookies(context);
},
-
+
onRemoveAllSession: function(context)
{
if (Options.get(removeSessionConfirmation))
@@ -750,7 +735,7 @@ Firebug.CookieModule = Obj.extend(Firebug.ActivableModule,
if (!prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
Locale.$STR("cookies.confirm.removeallsession"), flags, "", "", "",
- Locale.$STR("cookies.msg.Do_not_show_this_message_again"), check) == 0)
+ Locale.$STR("Do_not_show_this_message_again"), check) == 0)
{
return;
}
@@ -760,7 +745,30 @@ Firebug.CookieModule = Obj.extend(Firebug.ActivableModule,
Options.set(removeSessionConfirmation, !check.value)
}
- Firebug.CookieModule.onRemoveAllShared(context, true);
+ Firebug.CookieModule.removeCookies(context, {session: true});
+ },
+
+ onRemoveAllFromHost: function(context, host)
+ {
+ if (Options.get(removeConfirmation))
+ {
+ var check = {value: false};
+ var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_YES +
+ prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_NO;
+
+ if (!prompts.confirmEx(context.chrome.window, Locale.$STR("Firebug"),
+ Locale.$STRF("cookies.confirm.Remove_All_From_Host", [host]), flags, "", "", "",
+ Locale.$STR("Do_not_show_this_message_again"), check) == 0)
+ {
+ return;
+ }
+
+ // Update 'Remove Cookies' confirmation option according to the value
+ // of the dialog's "do not show again" checkbox.
+ Options.set(removeConfirmation, !check.value);
+ }
+
+ Firebug.CookieModule.removeCookies(context, {host: host});
},
onCreateCookieShowTooltip: function(tooltip, context)
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookieObserver.js b/trace/FBTrace/chrome/firebug/content/cookies/cookieObserver.js
index d2f92cb..345b363 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookieObserver.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookieObserver.js
@@ -34,6 +34,8 @@ const filterByPath = "cookies.filterByPath";
const panelName = "cookies";
+const idnService = Xpcom.CCSV("@mozilla.org/network/idn-service;1", "nsIIDNService");
+
// ********************************************************************************************* //
// Cookie observer
@@ -126,21 +128,27 @@ var CookieObserver = Obj.extend(BaseObserver,
{
var pathFilter = Options.get(filterByPath);
- // Get directory path (without the file name)
- var queryStringPos = activeUri.path.lastIndexOf("?");
- var activePath = queryStringPos != -1 ?
- activeUri.path.substr(0, queryStringPos) : activeUri.path;
-
- // Remove slash at the end of the active path according to step 4 of RFC 6265 section 5.1.4
- var lastChar = activePath.charAt(activePath.length - 1);
- if (lastChar == "/")
- activePath = activePath.substr(0, activePath.length - 1);
+ // Compute the default path of the cookie according to the algorithm
+ // defined in RFC 6265 section 5.1.4
+ //
+ // Steps 2 and 3 (output "/" in case the cookie path is empty, its first
+ // character is "/" or there is no more than one "/")
+ if (cookiePath.length == 0 || cookiePath.charAt(0) != "/" ||
+ cookiePath.lastIndexOf("/") == 0)
+ {
+ cookiePath = "/";
+ }
+ else
+ {
+ // Step 4 (remove slash at the end of the active path according to)
+ cookiePath = cookiePath.substr(0, cookiePath.lastIndexOf("/"));
+ }
// If the path filter is on, only cookies that match given path
// according to RFC 6265 section 5.1.4 will be displayed.
- if (pathFilter && (activePath != cookiePath && !(Str.hasPrefix(activePath, cookiePath) &&
- (cookiePath.charAt(cookiePath.length - 1) == "/" ||
- activePath.substr(cookiePath.length, 1) == "/"))))
+ var requestPath = activeUri.path;
+ if (pathFilter && (cookiePath != requestPath && !(Str.hasPrefix(requestPath, cookiePath) &&
+ (Str.endsWith(cookiePath, "/") || requestPath.substr(cookiePath.length, 1) == "/"))))
{
return false;
}
@@ -165,6 +173,15 @@ var CookieObserver = Obj.extend(BaseObserver,
isHostFromContext: function(context, host, path)
{
var location;
+ try
+ {
+ host = idnService.convertACEtoUTF8(host);
+ }
+ catch(exc)
+ {
+ if (FBTrace.DBG_ERRORS || FBTrace.DBG_COOKIES)
+ FBTrace.sysout("Host could not be converted to UTF-8", exc);
+ }
// Invalid in Chromebug.
try
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookiePanel.js b/trace/FBTrace/chrome/firebug/content/cookies/cookiePanel.js
index 306f640..57bf681 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookiePanel.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookiePanel.js
@@ -481,6 +481,34 @@ CookiePanel.prototype = Obj.extend(Firebug.ActivablePanel,
Firebug.Console.removeListener(Firebug.CookieModule.ConsoleListener);
}
},
+
+ // Support for info tips.
+ showInfoTip: function(infoTip, target, x, y)
+ {
+ var row = Dom.getAncestorByClass(target, "cookieRow");
+ if (row && row.repObject)
+ {
+ if (Dom.getAncestorByClass(target, "cookieSizeCol"))
+ {
+ var infoTipCookieId = "cookiesize-"+row.repObject.name;
+ if (infoTipCookieId == this.infoTipCookieId && row.repObject == this.infoTipCookie)
+ return true;
+
+ this.infoTipCookieId = infoTipCookieId;
+ this.infoTipCookie = row.repObject;
+ return this.populateSizeInfoTip(infoTip, row.repObject);
+ }
+ }
+
+ delete this.infoTipCookieId;
+ return false;
+ },
+
+ populateSizeInfoTip: function(infoTip, cookie)
+ {
+ CookieReps.SizeInfoTip.render(cookie, infoTip);
+ return true;
+ },
});
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookiePermissions.js b/trace/FBTrace/chrome/firebug/content/cookies/cookiePermissions.js
index 9c111ae..6f6df0e 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookiePermissions.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookiePermissions.js
@@ -154,7 +154,7 @@ var CookiePermissions = Obj.extend(Object,
case "default-deny":
if (Options.get("cookies.clearWhenDeny"))
- Firebug.CookieModule.onRemoveAll(context);
+ Firebug.CookieModule.onRemoveAllFromHost(context, location.host);
break;
}
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookieReps.js b/trace/FBTrace/chrome/firebug/content/cookies/cookieReps.js
index 69c5edd..e1a842a 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookieReps.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookieReps.js
@@ -236,19 +236,7 @@ CookieReps.CookieRow = domplate(CookieReps.Rep,
getSize: function(cookie)
{
var size = cookie.cookie.name.length + cookie.cookie.value.length;
- return this.formatSize(size);
- },
-
- formatSize: function(bytes)
- {
- if (bytes == -1 || bytes == undefined)
- return "?";
- else if (bytes < 1024)
- return bytes + " B";
- else if (bytes < 1024*1024)
- return Math.ceil(bytes/1024) + " KB";
- else
- return (Math.ceil(bytes/1024)/1024) + " MB"; // OK, this is probable not necessary ;-)
+ return Str.formatSize(size);
},
getPath: function(cookie)
@@ -940,6 +928,50 @@ CookieReps.CookieCleared = domplate(CookieReps.Rep,
}
});
+
+CookieReps.SizeInfoTip = domplate(Firebug.Rep,
+{
+ tag:
+ TABLE({"class": "sizeInfoTip", "id": "cookiesSizeInfoTip", role:"presentation"},
+ TBODY(
+ FOR("size", "$sizeInfo",
+ TAG("$size|sizeTag", {size: "$size"})
+ )
+ )
+ ),
+
+ sizeTag:
+ TR({"class": "sizeInfoRow"},
+ TD({"class": "sizeInfoLabelCol"}, "$size.label"),
+ TD({"class": "sizeInfoSizeCol"}, "$size|formatSize"),
+ TD({"class": "sizeInfoDetailCol"}, "$size|formatNumber")
+ ),
+
+ formatSize: function(size)
+ {
+ return Str.formatSize(size.size);
+ },
+
+ formatNumber: function(size)
+ {
+ return size.size && size.size >= 1024 ? "(" + Str.formatNumber(size.size) + " B)" : "";
+ },
+
+ render: function(cookie, parentNode)
+ {
+ var size = cookie.getSize();
+ var rawSize = cookie.getRawSize();
+ var sizeInfo = [];
+
+ sizeInfo.push({label: Locale.$STR("cookie.sizeinfo.Size"), size: size});
+
+ if (size != rawSize)
+ sizeInfo.push({label: Locale.$STR("cookie.sizeinfo.Raw_Size"), size: rawSize});
+
+ this.tag.replace({sizeInfo: sizeInfo}, parentNode);
+ },
+});
+
// ********************************************************************************************* //
// Header Template (domplate)
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/cookieUtils.js b/trace/FBTrace/chrome/firebug/content/cookies/cookieUtils.js
index 9a2ed28..57fa879 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/cookieUtils.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/cookieUtils.js
@@ -36,9 +36,17 @@ var CookieUtils =
if (value)
value = value.replace(/\+/g, " ");
+ value = unescape(value);
+
+ try
+ {
+ value = Str.convertToUnicode(value);
+ }
+ catch (exc) { }
+
var c = {
name : cookie.name,
- value : Str.convertToUnicode(unescape(value)),
+ value : value,
isDomain : cookie.isDomain,
host : cookie.host,
path : cookie.path,
diff --git a/trace/FBTrace/chrome/firebug/content/cookies/menuUtils.js b/trace/FBTrace/chrome/firebug/content/cookies/menuUtils.js
index 4b1d7c2..d708ffe 100644
--- a/trace/FBTrace/chrome/firebug/content/cookies/menuUtils.js
+++ b/trace/FBTrace/chrome/firebug/content/cookies/menuUtils.js
@@ -13,13 +13,17 @@ var MenuUtils =
{
optionMenu: function(context, label, tooltiptext, domain, option)
{
- var value = Options.getPref(domain, option);
+ var value = Options.getPref(domain, option), self = this;
return {
label: label,
tooltiptext: tooltiptext,
type: "checkbox",
checked: value,
- command: Obj.bindFixed(this.setPref, this, domain, option, !value)
+ command: function()
+ {
+ var checked = this.hasAttribute("checked");
+ self.setPref(domain, option, checked);
+ }
};
},
diff --git a/trace/FBTrace/chrome/firebug/content/css/computedPanel.js b/trace/FBTrace/chrome/firebug/content/css/computedPanel.js
index a992248..c7cc75a 100644
--- a/trace/FBTrace/chrome/firebug/content/css/computedPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/css/computedPanel.js
@@ -97,7 +97,7 @@ CSSComputedPanel.prototype = Obj.extend(Firebug.Panel,
_repObject: "$selector"},
TD({"class": "selectorName", role: "presentation"},
"$selector.selector.text"),
- TD({role: "presentation"},
+ TD({"class": "propValue", role: "presentation"},
SPAN({"class": "stylePropValue"}, "$selector.value|formatValue")),
TD({"class": "styleSourceLink", role: "presentation"},
TAG(FirebugReps.SourceLink.tag, {object: "$selector|getSourceLink"})
@@ -142,6 +142,10 @@ CSSComputedPanel.prototype = Obj.extend(Firebug.Panel,
else if (Options.get("colorDisplay") == "hsl")
value = Css.rgbToHSL(value);
+ var limit = Options.get("stringCropLength");
+ if (limit > 0)
+ value = Str.cropString(value, limit);
+
// Add a zero-width space after a comma to allow line breaking
return value.replace(/,/g, ",\u200B");
}
@@ -670,6 +674,7 @@ CSSComputedPanel.prototype = Obj.extend(Firebug.Panel,
return CSSInfoTip.populateImageInfoTip(infoTip, absURL, repeat);
}
+ break;
case "fontFamily":
return CSSInfoTip.populateFontFamilyInfoTip(infoTip, cssValue.value);
@@ -678,6 +683,8 @@ CSSComputedPanel.prototype = Obj.extend(Firebug.Panel,
delete this.infoTipType;
delete this.infoTipValue;
delete this.infoTipObject;
+
+ return false;
}
},
@@ -840,8 +847,8 @@ const styleGroups =
"overflow-x", // http://www.w3.org/TR/2002/WD-css3-box-20021024/#overflow
"overflow-y",
"overflow-clip",
- "-moz-transform",
- "-moz-transform-origin",
+ "transform",
+ "transform-origin",
"white-space",
"clip",
"float",
diff --git a/trace/FBTrace/chrome/firebug/content/css/cssModule.js b/trace/FBTrace/chrome/firebug/content/css/cssModule.js
index 7e7dca5..3339fe4 100644
--- a/trace/FBTrace/chrome/firebug/content/css/cssModule.js
+++ b/trace/FBTrace/chrome/firebug/content/css/cssModule.js
@@ -10,9 +10,10 @@ define([
"firebug/chrome/window",
"firebug/lib/xml",
"firebug/lib/options",
- "firebug/lib/array"
+ "firebug/lib/array",
+ "firebug/editor/editorSelector"
],
-function(Obj, Firebug, Xpcom, Events, Url, Css, Win, Xml, Options, Arr) {
+function(Obj, Firebug, Xpcom, Events, Url, Css, Win, Xml, Options, Arr, EditorSelector) {
// ********************************************************************************************* //
// Constants
@@ -27,7 +28,7 @@ const reRepeat = /no-repeat|repeat-x|repeat-y|repeat/;
// ********************************************************************************************* //
// CSS Module
-Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector),
+Firebug.CSSModule = Obj.extend(Firebug.Module, Firebug.EditorSelector,
{
dispatchName: "cssModule",
@@ -87,15 +88,34 @@ Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector
return insertIndex;
},
- deleteRule: function(styleSheet, ruleIndex)
+ deleteRule: function(src, ruleIndex)
{
+ var inlineStyle = (src instanceof window.Element);
if (FBTrace.DBG_CSS)
- FBTrace.sysout("deleteRule: " + ruleIndex + " " + styleSheet.cssRules.length,
- styleSheet.cssRules);
+ {
+ if (inlineStyle)
+ {
+ FBTrace.sysout("deleteRule: element.style", src);
+ }
+ else
+ {
+ FBTrace.sysout("deleteRule: " + ruleIndex + " " + src.cssRules.length,
+ src.cssRules);
+ }
+ }
- Events.dispatch(this.fbListeners, "onCSSDeleteRule", [styleSheet, ruleIndex]);
+ var rule = (inlineStyle ? src : src.cssRules[ruleIndex]);
+ var afterParams = [src, rule.style.cssText];
+ afterParams.push(inlineStyle ? "" : rule.selectorText);
- styleSheet.deleteRule(ruleIndex);
+ Events.dispatch(this.fbListeners, "onCSSDeleteRule", [src, ruleIndex]);
+
+ if (src instanceof window.Element)
+ src.removeAttribute("style");
+ else
+ src.deleteRule(ruleIndex);
+
+ Events.dispatch(this.fbListeners, "onAfterCSSDeleteRule", afterParams);
},
setProperty: function(rule, propName, propValue, propPriority)
@@ -192,7 +212,7 @@ Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector
cleanupSheets: function(doc, context)
{
if (!context)
- return;
+ return false;
// Due to the manner in which the layout engine handles multiple
// references to the same sheet we need to kick it a little bit.
@@ -206,7 +226,7 @@ Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector
/*if (!Xml.isXMLPrettyPrint(context))
{
var style = Css.createStyleSheet(doc);
- style.innerHTML = "#fbIgnoreStyleDO_NOT_USE {}";
+ style.textContent = "#fbIgnoreStyleDO_NOT_USE {}";
Css.addStyleSheet(doc, style);
if (style.parentNode)
@@ -220,6 +240,8 @@ Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector
}
}*/
+ var result = true;
+
// https://bugzilla.mozilla.org/show_bug.cgi?id=500365
// This voodoo touches each style sheet to force some Firefox internal change
// to allow edits.
@@ -238,11 +260,17 @@ Firebug.CSSModule = Obj.extend(Obj.extend(Firebug.Module, Firebug.EditorSelector
}
catch(e)
{
+ result = false;
+
if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("css.show: sheet.cssRules FAILS for "+
- (styleSheets[i]?styleSheets[i].href:"null sheet")+e, e);
+ FBTrace.sysout("css.show: sheet.cssRules FAILS for " +
+ (styleSheets[i] ? styleSheets[i].href : "null sheet") + e, e);
}
}
+
+ // Return true only if all stylesheets are fully loaded and there is no
+ // excpetion when accessing them.
+ return result;
},
cleanupSheetHandler: function(event, context)
diff --git a/trace/FBTrace/chrome/firebug/content/css/cssPanel.js b/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
index 814f58f..89e1f29 100644
--- a/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/css/cssPanel.js
@@ -23,12 +23,14 @@ define([
"firebug/lib/options",
"firebug/css/cssModule",
"firebug/css/cssReps",
+ "firebug/css/selectorEditor",
"firebug/editor/editor",
"firebug/editor/editorSelector",
"firebug/chrome/searchBox"
],
function(Obj, Firebug, Domplate, FirebugReps, Locale, Events, Url, SourceLink, Css, Dom, Win,
- Search, Str, Arr, Fonts, Xml, Persist, System, Menu, Options, CSSModule, CSSInfoTip) {
+ Search, Str, Arr, Fonts, Xml, Persist, System, Menu, Options, CSSModule, CSSInfoTip,
+ SelectorEditor) {
with (Domplate) {
@@ -50,6 +52,18 @@ var CSSDomplateBase =
isSelectorEditable: function(rule)
{
return rule.isSelectorEditable && this.isEditable(rule);
+ },
+
+ getPropertyValue: function(prop)
+ {
+ // Disabled, see http://code.google.com/p/fbug/issues/detail?id=5880
+ /*
+ var limit = Options.get("stringCropLength");
+ */
+ var limit = 0;
+ if (limit > 0)
+ return Str.cropString(prop.value, limit);
+ return prop.value;
}
};
@@ -69,12 +83,11 @@ var CSSPropTag = domplate(CSSDomplateBase,
// Use a space here, so that "copy to clipboard" has it (issue 3266).
SPAN({"class": "cssColon"}, ": "),
- SPAN({"class": "cssPropValue", $editable: "$rule|isEditable"},
- "$prop.value$prop.important"
+ SPAN({"class": "cssPropValue", $editable: "$rule|isEditable",
+ _repObject: "$prop.value$prop.important"}, "$prop|getPropertyValue$prop.important"
),
- SPAN({"class": "cssSemi"}, ";"
+ SPAN({"class": "cssSemi"}, ";")
)
- )
});
var CSSRuleTag =
@@ -159,12 +172,12 @@ var CSSStyleRuleTag = domplate(CSSDomplateBase,
$insertInto: "$rule|isEditable",
$editGroup: "$rule|isSelectorEditable",
_repObject: "$rule.rule",
- "ruleId": "$rule.id", role: "presentation"},
+ role: "presentation"},
DIV({"class": "cssHead focusRow", role: "listitem"},
SPAN({"class": "cssSelector", $editable: "$rule|isSelectorEditable"},
"$rule.selector"),
- " {"
- ),
+ " {"
+ ),
DIV({role: "group"},
DIV({"class": "cssPropertyListBox", _rule: "$rule", role: "listbox"},
FOR("prop", "$rule.props",
@@ -186,7 +199,6 @@ Firebug.CSSStyleRuleTag = CSSStyleRuleTag;
const reSplitCSS = /(url\("?[^"\)]+?"?\))|(rgba?\([^)]*\)?)|(hsla?\([^)]*\)?)|(#[\dA-Fa-f]+)|(-?\d+(\.\d+)?(%|[a-z]{1,4})?)|"([^"]*)"?|'([^']*)'?|([^,\s\/!\(\)]+)|(!(.*)?)/;
const reURL = /url\("?([^"\)]+)?"?\)/;
const reRepeat = /no-repeat|repeat-x|repeat-y|repeat/;
-const reSelectorChar = /[-_0-9a-zA-Z]/;
// ********************************************************************************************* //
// CSS Module
@@ -385,7 +397,7 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
var rules = [];
var appendRules = function(cssRules)
{
- var i, props, ruleId;
+ var i, props;
if (!cssRules)
return;
@@ -396,14 +408,10 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
if (rule instanceof window.CSSStyleRule)
{
props = this.getRuleProperties(context, rule);
- ruleId = this.getRuleId(rule);
rules.push({
tag: CSSStyleRuleTag.tag,
rule: rule,
- id: ruleId,
- // Show universal selectors with pseudo-class
- // (http://code.google.com/p/fbug/issues/detail?id=3683)
- selector: rule.selectorText.replace(/ :/g, " *:"),
+ selector: rule.selectorText.replace(/ :/g, " *:"), // (issue 3683)
props: props,
isSystemSheet: isSystemSheet,
isSelectorEditable: true
@@ -510,21 +518,34 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
{
var props = this.parseCSSProps(rule.style, inheritMode);
- var ruleId = this.getRuleId(rule);
- this.addOldProperties(context, ruleId, inheritMode, props);
+ this.addDisabledProperties(context, rule, inheritMode, props);
this.sortProperties(props);
return props;
},
- addOldProperties: function(context, ruleId, inheritMode, props)
+ addDisabledProperties: function(context, rule, inheritMode, props)
{
- if (context.selectorMap && context.selectorMap.hasOwnProperty(ruleId) )
+ var disabledMap = this.getDisabledMap(context);
+ var moreProps = disabledMap.get(rule);
+ if (moreProps)
{
- var moreProps = context.selectorMap[ruleId];
+ var propMap = {};
+ for (var i = 0; i < props.length; ++i)
+ propMap[props[i].name] = true;
+
for (var i = 0; i < moreProps.length; ++i)
{
var prop = moreProps[i];
+ if (propMap.hasOwnProperty(prop.name))
+ {
+ // A (probably enabled) property with the same name as this
+ // disabled one has appeared - remove this one entirely.
+ moreProps.splice(i, 1);
+ --i;
+ continue;
+ }
+ propMap[prop.name] = true;
this.addProperty(prop.name, prop.value, prop.important, true, inheritMode, props);
}
}
@@ -532,17 +553,13 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
addProperty: function(name, value, important, disabled, inheritMode, props)
{
- if (inheritMode && !Css.inheritedStyleNames[name])
+ if (inheritMode && !Dom.domUtils.isInheritedProperty(name))
return;
name = this.translateName(name, value);
if (name)
{
- if (Options.get("colorDisplay") == "hex")
- value = Css.rgbToHex(value);
- else if (Options.get("colorDisplay") == "hsl")
- value = Css.rgbToHSL(value);
- value = Css.stripUnits(value);
+ value = Css.stripUnits(formatColor(value));
important = important ? " !important" : "";
var prop = {name: name, value: value, important: important, disabled: disabled};
@@ -588,6 +605,22 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ getDisabledMap: function(context)
+ {
+ // Ideally, we'd use a WeakMap here, but WeakMaps don't allow CSS rules
+ // as keys before Firefox 17. A Map is used instead. (cf. bug 777373.)
+ if (!context.cssDisabledMap)
+ context.cssDisabledMap = new Map();
+ return context.cssDisabledMap;
+ },
+
+ remapRule: function(context, oldRule, newRule)
+ {
+ var map = this.getDisabledMap(context);
+ if (map.has(oldRule))
+ map.set(newRule, map.get(oldRule));
+ },
+
editElementStyle: function()
{
var rulesBox = this.panelNode.getElementsByClassName("cssElementRuleContainer")[0];
@@ -721,22 +754,13 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
{
var rule = Firebug.getRepObject(row);
var propName = Dom.getChildByClass(row, "cssPropName").textContent;
- CSSModule.deleteProperty(rule, propName, this.context);
- // Remove the property from the selector map, if it was disabled
- var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
- if ( this.context.selectorMap && this.context.selectorMap.hasOwnProperty(ruleId) )
- {
- var map = this.context.selectorMap[ruleId];
- for (var i = 0; i < map.length; ++i)
- {
- if (map[i].name == propName)
- {
- map.splice(i, 1);
- break;
- }
- }
- }
+ // Try removing the property from the "disabled" map.
+ var wasDisabled = this.removeDisabledProperty(rule, propName);
+
+ // If that fails, remove the actual property instead.
+ if (!wasDisabled)
+ CSSModule.deleteProperty(rule, propName, this.context);
if (this.name == "stylesheet")
Events.dispatch(this.fbListeners, "onInlineEditorClose", [this, row.firstChild, true]);
@@ -745,6 +769,23 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
this.markChange(this.name == "stylesheet");
},
+ removeDisabledProperty: function(rule, propName)
+ {
+ var disabledMap = this.getDisabledMap(this.context);
+ var map = disabledMap.get(rule);
+ if (!map)
+ return false;
+ for (var i = 0; i < map.length; ++i)
+ {
+ if (map[i].name === propName)
+ {
+ map.splice(i, 1);
+ return true;
+ }
+ }
+ return false;
+ },
+
disablePropertyRow: function(row)
{
Css.toggleClass(row, "disabledStyle");
@@ -752,16 +793,12 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
var rule = Firebug.getRepObject(row);
var propName = Dom.getChildByClass(row, "cssPropName").textContent;
- if (!this.context.selectorMap)
- this.context.selectorMap = {};
+ var disabledMap = this.getDisabledMap(this.context);
+ if (!disabledMap.has(rule))
+ disabledMap.set(rule, []);
+ var map = disabledMap.get(rule);
- // XXXjoe Generate unique key for elements too
- var ruleId = Firebug.getRepNode(row).getAttribute("ruleId");
- if (!(this.context.selectorMap.hasOwnProperty(ruleId)))
- this.context.selectorMap[ruleId] = [];
-
- var map = this.context.selectorMap[ruleId];
- var propValue = Dom.getChildByClass(row, "cssPropValue").textContent;
+ var propValue = Firebug.getRepObject(Dom.getChildByClass(row, "cssPropValue"));
var parsedValue = parsePriority(propValue);
CSSModule.disableProperty(Css.hasClass(row, "disabledStyle"), rule,
@@ -1114,30 +1151,34 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
);
}
- if (this.infoTipType == "color")
- {
- items.push(
- {
- label: "CopyColor",
- tooltiptext: "css.tip.Copy_Color",
- command: Obj.bindFixed(System.copyToClipboard, System, this.infoTipObject)
- }
- );
- }
- else if (this.infoTipType == "image")
+ var propValue = Dom.getAncestorByClass(target, "cssPropValue");
+ if (propValue)
{
- items.push(
- {
- label: "CopyImageLocation",
- tooltiptext: "css.tip.Copy_Image_Location",
- command: Obj.bindFixed(System.copyToClipboard, System, this.infoTipObject)
- },
- {
- label: "OpenImageInNewTab",
- tooltiptext: "css.tip.Open_Image_In_New_Tab",
- command: Obj.bindFixed(Win.openNewTab, Win, this.infoTipObject)
- }
- );
+ if (this.infoTipType == "color")
+ {
+ items.push(
+ {
+ label: "CopyColor",
+ tooltiptext: "css.tip.Copy_Color",
+ command: Obj.bindFixed(System.copyToClipboard, System, this.infoTipObject)
+ }
+ );
+ }
+ else if (this.infoTipType == "image")
+ {
+ items.push(
+ {
+ label: "CopyImageLocation",
+ tooltiptext: "css.tip.Copy_Image_Location",
+ command: Obj.bindFixed(System.copyToClipboard, System, this.infoTipObject)
+ },
+ {
+ label: "OpenImageInNewTab",
+ tooltiptext: "css.tip.Open_Image_In_New_Tab",
+ command: Obj.bindFixed(Win.openNewTab, Win, this.infoTipObject)
+ }
+ );
+ }
}
if (!Url.isSystemStyleSheet(this.selection))
@@ -1198,10 +1239,12 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
{
label: Locale.$STRF("DeleteProp", [propName]),
tooltiptext: Locale.$STRF("css.tip.Delete_Prop", [propName]),
+ id: "fbDeleteCSSProp",
nol10n: true,
command: Obj.bindFixed(this.deletePropertyRow, this, propRow)
},
{
+ id: "fbDisableCSSProp",
label: Locale.$STRF("DisableProp", [propName]),
tooltiptext: Locale.$STRF("css.tip.Disable_Prop", [propName]),
nol10n: true,
@@ -1229,6 +1272,7 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
items.push(
"-",
{
+ id: "fbRefresh",
label: "Refresh",
command: Obj.bind(this.refresh, this),
tooltiptext: "panel.tip.Refresh"
@@ -1252,10 +1296,35 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
var propValue = Dom.getAncestorByClass(target, "cssPropValue");
if (propValue)
{
- var text = propValue.textContent;
var prop = Dom.getAncestorByClass(target, "cssProp");
+ var styleRule = Firebug.getRepObject(prop);
var propNameNode = prop.getElementsByClassName("cssPropName").item(0);
var propName = propNameNode.textContent.toLowerCase();
+ var priority = styleRule.style.getPropertyPriority(propName);
+ var text = styleRule.style.getPropertyValue(propName) +
+ (priority ? " !" + priority : "");
+
+ if (text != "")
+ {
+ text = formatColor(text);
+ }
+ else
+ {
+ var disabledMap = this.getDisabledMap(this.context);
+ var disabledProps = disabledMap.get(styleRule);
+ if (disabledProps)
+ {
+ for (var i = 0, len = disabledProps.length; i < len; ++i)
+ {
+ if (disabledProps[i].name == propName)
+ {
+ priority = disabledProps[i].important;
+ text = disabledProps[i].value + (priority ? " !" + priority : "");
+ break;
+ }
+ }
+ }
+ }
var cssValue;
if (propName == "font" || propName == "font-family")
@@ -1292,7 +1361,8 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
if (Css.isImageRule(Xml.getElementSimpleType(Firebug.getRepObject(target)),
propNameNode.textContent))
{
- var rule = Firebug.getRepObject(target);
+ var prop = Dom.getAncestorByClass(target, "cssProp");
+ var rule = Firebug.getRepObject(prop);
var baseURL = this.getStylesheetURL(rule, true);
var relURL = CSSModule.parseURLValue(cssValue.value);
var absURL = Url.isDataURL(relURL) ? relURL : Url.absoluteURL(relURL, baseURL);
@@ -1303,6 +1373,7 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
return CSSInfoTip.populateImageInfoTip(infoTip, absURL, repeat);
}
+ break;
case "fontFamily":
return CSSInfoTip.populateFontFamilyInfoTip(infoTip, cssValue.value);
@@ -1311,6 +1382,8 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
delete this.infoTipType;
delete this.infoTipValue;
delete this.infoTipObject;
+
+ return false;
}
},
@@ -1536,17 +1609,21 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
getStyleDeclaration: function(cssSelector)
{
var cssRule = Dom.getAncestorByClass(cssSelector, "cssRule");
- var cssRules = cssRule.getElementsByClassName("cssPropertyListBox")[0].rule;
- var props = [];
+ var propRows = cssRule.getElementsByClassName("cssProp");
- for (var p in cssRules.props)
+ var lines = [];
+ for (var i = 0; i < propRows.length; ++i)
{
- var prop = cssRules.props[p];
- if (!(prop.disabled || prop.overridden))
- props.push(prop.name + ": " + prop.value + prop.important + ";");
+ var row = propRows[i];
+ if (row.classList.contains("disabledStyle"))
+ continue;
+
+ var name = Dom.getChildByClass(row, "cssPropName").textContent;
+ var value = Firebug.getRepObject(Dom.getChildByClass(row, "cssPropValue"));
+ lines.push(name + ": " + value + ";");
}
- return props;
+ return lines;
},
copyRuleDeclaration: function(cssSelector)
@@ -1575,33 +1652,15 @@ Firebug.CSSStyleSheetPanel.prototype = Obj.extend(Firebug.Panel,
CSSModule.deleteRule(styleSheet, ruleIndex);
- if (this.context.panelName == "stylesheet")
- {
- var rule = Dom.getAncestorByClass(cssSelector, "cssRule");
- if (rule)
- rule.parentNode.removeChild(rule);
- }
- else
- {
- var sidePanel = Firebug.chrome.getSelectedSidePanel();
- sidePanel.refresh();
- }
+ var rule = Dom.getAncestorByClass(cssSelector, "cssRule");
+ if (rule)
+ rule.parentNode.removeChild(rule);
},
copyStyleDeclaration: function(cssSelector)
{
var props = this.getStyleDeclaration(cssSelector);
System.copyToClipboard(props.join(Str.lineBreak()));
- },
-
- getRuleId: function(rule)
- {
- var line = Dom.domUtils.getRuleLine(rule);
-
- // xxxjjb I hope % is invalid in selectortext
- const reQuotes = /['"]/g;
- var ruleId = rule.selectorText.replace(reQuotes,"%")+"/"+line;
- return ruleId;
}
});
@@ -1638,103 +1697,86 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
if (FBTrace.DBG_CSS)
FBTrace.sysout("CSSEditor.saveEdit", arguments);
- var propValue, parsedValue, propName;
-
- target.innerHTML = Str.escapeForCss(value);
-
- var row = Dom.getAncestorByClass(target, "cssProp");
- if (Css.hasClass(row, "disabledStyle"))
- Css.toggleClass(row, "disabledStyle");
-
- var rule = Firebug.getRepObject(target);
+ var cssRule = Dom.getAncestorByClass(target, "cssRule");
+ var rule = Firebug.getRepObject(cssRule);
if (rule instanceof window.CSSStyleRule || rule instanceof window.Element)
{
- if (Css.hasClass(target, "cssPropName"))
- {
-
- if (value && previousValue != value) // name of property has changed.
- {
- // Record the original CSS text for the inline case so we can reconstruct at a later
- // point for diffing purposes
- var baseText = rule.style ? rule.style.cssText : rule.cssText;
-
- propValue = Dom.getChildByClass(row, "cssPropValue").textContent;
- parsedValue = parsePriority(propValue);
-
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("CSSEditor.saveEdit : " + previousValue + "->" + value +
- " = " + propValue);
-
- if (propValue && propValue != "undefined")
- {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("CSSEditor.saveEdit : " + previousValue + "->" + value +
- " = " + propValue);
-
- if (previousValue)
- CSSModule.removeProperty(rule, previousValue);
-
- CSSModule.setProperty(rule, value, parsedValue.value,
- parsedValue.priority);
- }
-
- Events.dispatch(CSSModule.fbListeners, "onCSSPropertyNameChanged", [rule, value,
- previousValue, baseText]);
- }
- else if (!value)
- {
- // name of the property has been deleted, so remove the property.
- CSSModule.removeProperty(rule, previousValue);
- }
- }
- else if (Dom.getAncestorByClass(target, "cssPropValue"))
+ var prop = Dom.getAncestorByClass(target, "cssProp");
+
+ if (prop)
{
- propName = Dom.getChildByClass(row, "cssPropName").textContent;
- propValue = Dom.getChildByClass(row, "cssPropValue").textContent;
-
- if (FBTrace.DBG_CSS)
+ var propName = Dom.getChildByClass(prop, "cssPropName").textContent;
+ // If the property was previously disabled, remove it from the "disabled"
+ // map. (We will then proceed to enable the property.)
+ if (prop && prop.classList.contains("disabledStyle"))
{
- FBTrace.sysout("CSSEditor.saveEdit propName=propValue: "+propName +
- " = "+propValue+"\n");
- // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style);
+ prop.classList.remove("disabledStyle");
+
+ this.panel.removeDisabledProperty(rule, propName);
}
-
- if (value && value != "null")
+
+ if (Css.hasClass(target, "cssPropName"))
{
- parsedValue = parsePriority(value);
- CSSModule.setProperty(rule, propName, parsedValue.value,
- parsedValue.priority);
+ // Actual saving is done in endEditing, see the comment there.
+ target.textContent = value;
}
- else if (previousValue && previousValue != "null")
+ else if (Dom.getAncestorByClass(target, "cssPropValue"))
{
- CSSModule.removeProperty(rule, propName);
+ target.textContent = CSSDomplateBase.getPropertyValue({value: value});
+
+ propName = Dom.getChildByClass(prop, "cssPropName").textContent;
+
+ if (FBTrace.DBG_CSS)
+ {
+ FBTrace.sysout("CSSEditor.saveEdit \"" + propName + "\" = \"" + value + "\"");
+ // FBTrace.sysout("CSSEditor.saveEdit BEFORE style:",style);
+ }
+
+ if (value && value != "null")
+ {
+ var parsedValue = parsePriority(value);
+ CSSModule.setProperty(rule, propName, parsedValue.value,
+ parsedValue.priority);
+ // Save in rep object.
+ Dom.getAncestorByClass(target, "cssPropValue").repObject = value;
+ }
+ else if (previousValue && previousValue != "null")
+ {
+ CSSModule.removeProperty(rule, propName);
+ }
}
- }
-
- if (value)
- {
- var saveSuccess = !!rule.style.getPropertyValue(propName || value);
- if(!saveSuccess && !propName)
+
+ if (value)
{
- propName = value.replace(/-./g, function(match)
+ var saveSuccess = false;
+ if (Css.hasClass(target, "cssPropName"))
{
- return match[1].toUpperCase()
- });
+ var propName = value.replace(/-./g, function(match)
+ {
+ return match[1].toUpperCase();
+ });
- if (propName in rule.style || propName == "float")
- saveSuccess = "almost";
- }
+ if (propName in rule.style || propName == "float")
+ saveSuccess = "almost";
+ }
+ else
+ {
+ saveSuccess = !!rule.style.getPropertyValue(propName);
+ }
- this.box.setAttribute("saveSuccess", saveSuccess);
- }
- else
- {
- this.box.removeAttribute("saveSuccess");
+ this.box.setAttribute("saveSuccess", saveSuccess);
+ }
+ else
+ {
+ this.box.removeAttribute("saveSuccess");
+ }
}
}
else if (rule instanceof window.CSSImportRule && Css.hasClass(target, "cssMediaQuery"))
{
+ target.textContent = value;
+
if (FBTrace.DBG_CSS)
{
FBTrace.sysout("CSSEditor.saveEdit: @import media query: " +
@@ -1747,12 +1789,17 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
rule.parentStyleSheet.disabled = true;
rule.parentStyleSheet.disabled = false;
- row = Dom.getAncestorByClass(target, "importRule");
- row.getElementsByClassName("separator").item(0).innerHTML =
- value == "" ? "" : " ";
+ var row = Dom.getAncestorByClass(target, "importRule");
+ row.getElementsByClassName("separator").item(0).textContent =
+ value == "" ? "" : String.fromCharCode(160);
+
+ var saveSuccess = rule.media.mediaText != "not all" || value == "not all";
+ this.box.setAttribute("saveSuccess", saveSuccess);
}
else if (rule instanceof window.CSSCharsetRule)
{
+ target.textContent = value;
+
if (FBTrace.DBG_CSS)
FBTrace.sysout("CSSEditor.saveEdit: @charset: " + previousValue + "->" + value);
@@ -1767,6 +1814,57 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
FBTrace.sysout("CSSEditor.saveEdit (ending) " + this.panel.name, value);
},
+ beginEditing: function(target, value)
+ {
+ var row = Dom.getAncestorByClass(target, "cssProp");
+ this.initialValue = value;
+ this.initiallyDisabled = (row && row.classList.contains("disabledStyle"));
+ },
+
+ endEditing: function(target, value, cancel)
+ {
+ if (!cancel && target.classList.contains("cssPropName"))
+ {
+ // Save changed property names here instead of in saveEdit, because otherwise
+ // unrelated properties might get discarded (see issue 5204).
+ var previous = this.initialValue;
+ if (FBTrace.DBG_CSS)
+ {
+ FBTrace.sysout("CSSEditor.endEditing: renaming property " + previous + " -> " + value);
+ }
+
+ var cssRule = Dom.getAncestorByClass(target, "cssRule");
+ var rule = Firebug.getRepObject(cssRule);
+ var baseText = rule.style ? rule.style.cssText : rule.cssText;
+ var prop = Dom.getAncestorByClass(target, "cssProp");
+ var propValue = Firebug.getRepObject(Dom.getChildByClass(prop, "cssPropValue"));
+ var parsedValue = parsePriority(propValue);
+
+ if (previous)
+ CSSModule.removeProperty(rule, previous);
+ if (propValue)
+ CSSModule.setProperty(rule, value, parsedValue.value, parsedValue.priority);
+
+ Events.dispatch(CSSModule.fbListeners, "onCSSPropertyNameChanged", [rule, value,
+ previous, baseText]);
+
+ Firebug.Inspector.repaint();
+ this.panel.markChange(this.panel.name == "stylesheet");
+ }
+ return true;
+ },
+
+ cancelEditing: function(target, value)
+ {
+ if (this.initiallyDisabled)
+ {
+ // Disable the property again.
+ var row = Dom.getAncestorByClass(target, "cssProp");
+ if (row && !row.classList.contains("disabledStyle"))
+ this.panel.disablePropertyRow(row);
+ }
+ },
+
advanceToNext: function(target, charCode)
{
if (charCode == 58 /*":"*/ && Css.hasClass(target, "cssPropName"))
@@ -1783,6 +1881,20 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
}
},
+ getInitialValue: function(target, value)
+ {
+ if (value == "")
+ return value;
+
+ var propValue = Dom.getAncestorByClass(target, "cssPropValue");
+ if (propValue)
+ {
+ var row = Dom.getAncestorByClass(target, "cssProp");
+ value = Firebug.getRepObject(propValue);
+ }
+ return value;
+ },
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
getAutoCompleteRange: function(value, offset)
@@ -1912,19 +2024,8 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
keywords = Css.getCSSKeywordsByProperty(nodeType, propName, avoid);
}
- // Don't complete minus signs into -moz-calc (issue 5603). (Unless we
- // have other specialized values as completions, like '-moz-available',
- // in which case completion is still interesting.)
- var isMoz = function(x)
- {
- return (x.charAt(0) === "-");
- };
- if (expr === "-" && keywords.filter(isMoz).join(",") === "-moz-calc()")
- {
- keywords = [];
- }
-
// Add the magic inherit property, if it's sufficiently alone.
+ // XXX Firefox 19 also has "initial"
if (!preExpr)
keywords = keywords.concat(["inherit"]);
@@ -1942,7 +2043,7 @@ CSSEditor.prototype = domplate(Firebug.InlineEditor.prototype,
}
}
- return stripCompletedParens(keywords, postExpr);
+ return SelectorEditor.stripCompletedParens(keywords, postExpr);
}
},
@@ -2156,8 +2257,7 @@ function CSSRuleEditor(doc)
this.initializeInline(doc);
}
-CSSRuleEditor.uniquifier = 0;
-CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
+CSSRuleEditor.prototype = domplate(SelectorEditor.prototype,
{
insertNewRow: function(target, insertWhere)
{
@@ -2176,18 +2276,19 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
saveEdit: function(target, value, previousValue)
{
+ var context = this.panel.context;
+
if (FBTrace.DBG_CSS)
FBTrace.sysout("CSSRuleEditor.saveEdit: '" + value + "' '" + previousValue +
"'", target);
target.innerHTML = Str.escapeForCss(value);
-
if (value === previousValue)
return;
var row = Dom.getAncestorByClass(target, "cssRule");
-
var rule = Firebug.getRepObject(target);
+
var searchRule = rule || Firebug.getRepObject(row.nextSibling);
var oldRule, ruleIndex;
@@ -2217,7 +2318,7 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
styleSheet = this.panel.location;
if (!styleSheet)
{
- var doc = this.panel.context.window.document;
+ var doc = context.window.document;
this.panel.location = styleSheet =
CSSModule.getDefaultStyleSheet(doc);
}
@@ -2243,6 +2344,8 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
CSSModule.deleteRule(styleSheet, ruleIndex);
}
+ var doMarkChange = true;
+
// Firefox does not follow the spec for the update selector text case.
// When attempting to update the value, firefox will silently fail.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=37468 for the quite
@@ -2255,23 +2358,25 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
var props = row.getElementsByClassName("cssProp");
for (var i = 0; i < props.length; i++)
{
+
var propEl = props[i];
if (!Css.hasClass(propEl, "disabledStyle"))
{
- cssText.push(Dom.getChildByClass(propEl, "cssPropName").textContent);
- cssText.push(":");
- cssText.push(Dom.getChildByClass(propEl, "cssPropValue").textContent);
- cssText.push(";");
+ var propName = Dom.getChildByClass(propEl, "cssPropName").textContent;
+ var propValue = Dom.getChildByClass(propEl, "cssPropValue").repObject;
+ cssText.push(propName + ":" + propValue + ";");
}
}
cssText.push("}");
cssText = cssText.join("");
-
+
try
{
var insertLoc = CSSModule.insertRule(styleSheet, cssText, ruleIndex);
+
rule = cssRules[insertLoc];
+
ruleIndex++;
var saveSuccess = (this.panel.name != "css");
@@ -2296,237 +2401,43 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
this.box.setAttribute('saveSuccess', false);
- row.repObject = rule;
- return;
+ doMarkChange = false;
}
}
else
{
+ // XXX There is currently no way to re-add the rule after this happens.
rule = undefined;
}
// Update the rep object
row.repObject = rule;
- if (!oldRule)
- {
- // Who knows what the domutils will return for rule line
- // for a recently created rule. To be safe we just generate
- // a unique value as this is only used as an internal key.
- var ruleId = "new/"+value+"/"+(++CSSRuleEditor.uniquifier);
- row.setAttribute("ruleId", ruleId);
- }
+ if (oldRule && rule)
+ this.panel.remapRule(context, oldRule, rule);
- this.panel.markChange(this.panel.name == "stylesheet");
+ if (doMarkChange)
+ this.panel.markChange(this.panel.name == "stylesheet");
},
getAutoCompleteRange: function(value, offset)
{
if (!Css.hasClass(this.target, "cssSelector"))
return;
-
- // Find the word part of an identifier.
- var reIdent = /[-_a-zA-Z0-9]*/;
- var rbefore = Str.reverseString(value.substr(0, offset));
- var after = value.substr(offset);
- var start = offset - reIdent.exec(rbefore)[0].length;
- var end = offset + reIdent.exec(after)[0].length;
-
- // Expand it to include '.', '#', ':', or '::'.
- if (start > 0 && ".#:".indexOf(value.charAt(start-1)) !== -1)
- {
- --start;
- if (start > 0 && value.substr(start-1, 2) === "::")
- --start;
- }
- return {start: start, end: end};
+ return SelectorEditor.prototype.getAutoCompleteRange.apply(this, arguments);
},
getAutoCompleteList: function(preExpr, expr, postExpr, range, cycle, context, out)
{
if (!Css.hasClass(this.target, "cssSelector"))
return [];
-
- // Don't support attribute selectors, for now.
- if (preExpr.lastIndexOf("[") > preExpr.lastIndexOf("]"))
- return [];
-
- if (preExpr.lastIndexOf("(") > preExpr.lastIndexOf(")"))
- {
- // We are in an parenthesized expression, where we can only complete
- // for a few particular pseudo-classes that take selector-like arguments.
- var par = preExpr.lastIndexOf("("), colon = preExpr.lastIndexOf(":", par);
- if (colon === -1)
- return;
- var allowed = ["-moz-any", "not", "-moz-empty-except-children-with-localname"];
- var name = preExpr.substring(colon+1, par);
- if (allowed.indexOf(name) === -1)
- return [];
- }
-
- var includeTagNames = true;
- var includeIds = true;
- var includeClasses = true;
- var includePseudoClasses = true;
- var includePseudoElements = true;
-
- if (expr.length > 0)
- {
- includeTagNames = includeClasses = includeIds =
- includePseudoClasses = includePseudoElements = false;
- if (Str.hasPrefix(expr, "::"))
- includePseudoElements = true;
- else if (expr.charAt(0) === ":")
- includePseudoClasses = true;
- else if (expr.charAt(0) === "#")
- includeIds = true;
- else if (expr.charAt(0) === ".")
- includeClasses = true;
- else
- includeTagNames = true;
- }
- if (preExpr.length > 0 && reSelectorChar.test(preExpr.slice(-1)))
- includeTagNames = false;
-
- var ret = [];
-
- if (includeTagNames || includeIds || includeClasses)
- {
- // Traverse the DOM to get the used ids/classes/tag names that
- // are relevant as continuations.
- // (Tag names could be hard-coded, but finding which ones are
- // actually used hides annoying things like 'b'/'i' when they
- // are not used, and works in other contexts than HTML.)
- // This isn't actually that bad, performance-wise.
- var doc = context.window.document, els;
- if (preExpr && " >+~".indexOf(preExpr.slice(-1)) === -1)
- {
- try
- {
- var preSelector = preExpr.split(",").reverse()[0];
- els = doc.querySelectorAll(preSelector);
- }
- catch (exc)
- {
- if (FBTrace.DBG_CSS)
- FBTrace.sysout("Invalid previous selector part \"" + preSelector + "\"", exc);
- }
- }
- if (!els)
- els = doc.getElementsByTagName("*");
- els = [].slice.call(els);
-
- if (includeTagNames)
- {
- var tagMap = {};
- els.forEach(function(e)
- {
- tagMap[e.localName] = 1;
- });
- ret.push.apply(ret, Object.keys(tagMap));
- }
-
- if (includeIds)
- {
- var ids = [];
- els.forEach(function(e)
- {
- if (e.id)
- ids.push(e.id);
- });
- ids = Arr.sortUnique(ids);
- ret.push.apply(ret, ids.map(function(cl)
- {
- return "#" + cl;
- }));
- }
-
- if (includeClasses)
- {
- var clCombinationMap = {}, classes = [];
- els.forEach(function(e)
- {
- var cl = e.className;
- if (cl && !((","+cl) in clCombinationMap))
- {
- clCombinationMap[","+cl] = 1;
- classes.push.apply(classes, e.classList);
- }
- });
- classes = Arr.sortUnique(classes);
- ret.push.apply(ret, classes.map(function(cl)
- {
- return "." + cl;
- }));
- }
- }
-
- if (includePseudoClasses)
- {
- // Add the pseudo-class-looking :before, :after.
- ret.push(
- ":after",
- ":before"
- );
-
- ret.push.apply(ret, stripCompletedParens(Css.pseudoClasses, postExpr));
- }
-
- if (includePseudoElements)
- {
- ret.push.apply(ret, Css.pseudoElements);
- }
-
- // Don't suggest things that are already included (by way of totally-
- // incorrect-but-probably-good-enough logic).
- var rev = Str.reverseString(preExpr);
- var partInd = rev.search(/[, >+~]/);
- var lastPart = (partInd === -1 ? rev : rev.substr(0, partInd));
- lastPart = Str.reverseString(lastPart);
- if (lastPart !== "")
- {
- ret = ret.filter(function(str)
- {
- var ind = lastPart.indexOf(str);
- if (ind === -1)
- return true;
- var before = ind-1, after = ind+str.length;
- var re = reSelectorChar;
- if (before >= 0 && re.test(str.charAt(0)) && re.test(lastPart.charAt(before)))
- return true;
- if (after < lastPart.length && re.test(lastPart.charAt(after)))
- return true;
- return false;
- });
- }
-
- // Don't suggest internal Firebug things.
- var reInternal = /^[.#]firebug[A-Z]/;
- ret = ret.filter(function(str)
- {
- return !reInternal.test(str);
- });
-
- if (ret.indexOf(":hover") !== -1)
- out.suggestion = ":hover";
-
- return ret.sort();
+ return SelectorEditor.prototype.getAutoCompleteList.apply(this, arguments);
},
getAutoCompletePropSeparator: function(range, expr, prefixOf)
{
if (!Css.hasClass(this.target, "cssSelector"))
return null;
-
- // For e.g. 'd|span', expand to a descendant selector; otherwise assume
- // that this is part of the same selector part.
- return (reSelectorChar.test(prefixOf.charAt(0)) ? " " : "");
- },
-
- autoCompleteAdjustSelection: function(value, offset)
- {
- if (offset >= 2 && value.substr(offset-2, 2) === "()")
- return offset-1;
- return offset;
+ return SelectorEditor.prototype.getAutoCompletePropSeparator.apply(this, arguments);
},
advanceToNext: function(target, charCode)
@@ -2542,7 +2453,7 @@ CSSRuleEditor.prototype = domplate(Firebug.InlineEditor.prototype,
// StyleSheetEditor
/**
- * StyleSheetEditor represents an inline editor and is used when editing CSS
+ * StyleSheetEditor represents the full-sized editor used for Source/Live Edit
* within the CSS panel.
*/
function StyleSheetEditor(doc)
@@ -2700,23 +2611,6 @@ Firebug.CSSDirtyListener.prototype =
// ********************************************************************************************* //
// Local Helpers
-// Transform completions so that they don't add additional parentheses when
-// ones already exist.
-function stripCompletedParens(list, postExpr)
-{
- var c = postExpr.charAt(0), rem = 0;
- if (c === "(")
- rem = 2;
- else if (c === ")")
- rem = 1;
- else
- return list;
- return list.map(function(cl)
- {
- return (cl.slice(-2) === "()" ? cl.slice(0, -rem) : cl);
- });
-}
-
function parsePriority(value)
{
var rePriority = /(.*?)\s*(!important)?$/;
@@ -2726,6 +2620,23 @@ function parsePriority(value)
return {value: propValue, priority: priority};
}
+function formatColor(color)
+{
+ var colorDisplay = Options.get("colorDisplay");
+
+ switch (colorDisplay)
+ {
+ case "hex":
+ return Css.rgbToHex(color);
+
+ case "hsl":
+ return Css.rgbToHSL(color);
+
+ default:
+ return color;
+ }
+}
+
function getRuleLine(rule)
{
// TODO return closest guess if rule isn't CSSStyleRule
diff --git a/trace/FBTrace/chrome/firebug/content/css/cssReps.js b/trace/FBTrace/chrome/firebug/content/css/cssReps.js
index 0aa34a8..81ef9c9 100644
--- a/trace/FBTrace/chrome/firebug/content/css/cssReps.js
+++ b/trace/FBTrace/chrome/firebug/content/css/cssReps.js
@@ -115,7 +115,7 @@ var CSSInfoTip = Obj.extend(InfoTip,
}
}
- caption.innerHTML = Locale.$STRF("Dimensions", [w, h]);
+ caption.textContent = Locale.$STRF("Dimensions", [w, h]);
Css.removeClass(innerBox, "infoTipLoading");
},
@@ -131,9 +131,9 @@ var CSSInfoTip = Obj.extend(InfoTip,
// Display an error in the caption (instead of dimensions).
if (Str.hasPrefix(img.src, "moz-filedata"))
- caption.innerHTML = Locale.$STR("firebug.failedToPreviewObjectURL");
+ caption.textContent = Locale.$STR("firebug.failedToPreviewObjectURL");
else
- caption.innerHTML = Locale.$STR("firebug.failedToPreviewImageURL");
+ caption.textContent = Locale.$STR("firebug.failedToPreviewImageURL");
var innerBox = img.parentNode;
Css.removeClass(innerBox, "infoTipLoading");
@@ -162,7 +162,7 @@ var CSSInfoTip = Obj.extend(InfoTip,
fontObject: fontObject}, infoTip);
var styleNode = node.getElementsByClassName("infoTipFontFamilyStyle").item(0);
- styleNode.innerHTML = getFontFaceCSS(fontObject ? fontObject : fontName);
+ styleNode.textContent = getFontFaceCSS(fontObject ? fontObject : fontName);
return true;
},
diff --git a/trace/FBTrace/chrome/firebug/content/css/selectorEditor.js b/trace/FBTrace/chrome/firebug/content/css/selectorEditor.js
new file mode 100644
index 0000000..27fc5c1
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/css/selectorEditor.js
@@ -0,0 +1,252 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/firebug",
+ "firebug/lib/domplate",
+ "firebug/lib/locale",
+ "firebug/lib/css",
+ "firebug/lib/string",
+ "firebug/lib/array",
+],
+function(Firebug, Domplate, Locale, Css, Str, Arr) {
+with (Domplate) {
+
+// ********************************************************************************************* //
+// Constants
+
+const reSelectorChar = /[-_0-9a-zA-Z]/;
+
+// ********************************************************************************************* //
+// CSS Selector Editor
+
+function SelectorEditor() {}
+
+SelectorEditor.prototype = domplate(Firebug.InlineEditor.prototype,
+{
+ getAutoCompleteRange: function(value, offset)
+ {
+ // Find the word part of an identifier.
+ var reIdent = /[-_a-zA-Z0-9]*/;
+ var rbefore = Str.reverseString(value.substr(0, offset));
+ var after = value.substr(offset);
+ var start = offset - reIdent.exec(rbefore)[0].length;
+ var end = offset + reIdent.exec(after)[0].length;
+
+ // Expand it to include '.', '#', ':', or '::'.
+ if (start > 0 && ".#:".indexOf(value.charAt(start-1)) !== -1)
+ {
+ --start;
+ if (start > 0 && value.substr(start-1, 2) === "::")
+ --start;
+ }
+ return {start: start, end: end};
+ },
+
+ getAutoCompleteList: function(preExpr, expr, postExpr, range, cycle, context, out)
+ {
+ // Don't support attribute selectors, for now.
+ if (preExpr.lastIndexOf("[") > preExpr.lastIndexOf("]"))
+ return [];
+
+ if (preExpr.lastIndexOf("(") > preExpr.lastIndexOf(")"))
+ {
+ // We are in an parenthesized expression, where we can only complete
+ // for a few particular pseudo-classes that take selector-like arguments.
+ var par = preExpr.lastIndexOf("("), colon = preExpr.lastIndexOf(":", par);
+ if (colon === -1)
+ return;
+ var allowed = ["-moz-any", "not", "-moz-empty-except-children-with-localname"];
+ var name = preExpr.substring(colon+1, par);
+ if (allowed.indexOf(name) === -1)
+ return [];
+ }
+
+ var includeTagNames = true;
+ var includeIds = true;
+ var includeClasses = true;
+ var includePseudoClasses = true;
+ var includePseudoElements = true;
+
+ if (expr.length > 0)
+ {
+ includeTagNames = includeClasses = includeIds =
+ includePseudoClasses = includePseudoElements = false;
+ if (Str.hasPrefix(expr, "::"))
+ includePseudoElements = true;
+ else if (expr.charAt(0) === ":")
+ includePseudoClasses = true;
+ else if (expr.charAt(0) === "#")
+ includeIds = true;
+ else if (expr.charAt(0) === ".")
+ includeClasses = true;
+ else
+ includeTagNames = true;
+ }
+ if (preExpr.length > 0 && reSelectorChar.test(preExpr.slice(-1)))
+ includeTagNames = false;
+
+ var ret = [];
+
+ if (includeTagNames || includeIds || includeClasses)
+ {
+ // Traverse the DOM to get the used ids/classes/tag names that
+ // are relevant as continuations.
+ // (Tag names could be hard-coded, but finding which ones are
+ // actually used hides annoying things like 'b'/'i' when they
+ // are not used, and works in other contexts than HTML.)
+ // This isn't actually that bad, performance-wise.
+ var doc = context.window.document, els;
+ if (preExpr && " >+~".indexOf(preExpr.slice(-1)) === -1)
+ {
+ try
+ {
+ var preSelector = preExpr.split(",").reverse()[0];
+ els = doc.querySelectorAll(preSelector);
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_CSS)
+ FBTrace.sysout("Invalid previous selector part \"" + preSelector + "\"", exc);
+ }
+ }
+ if (!els)
+ els = doc.getElementsByTagName("*");
+ els = [].slice.call(els);
+
+ if (includeTagNames)
+ {
+ var tagMap = {};
+ els.forEach(function(e)
+ {
+ tagMap[e.localName] = 1;
+ });
+ ret.push.apply(ret, Object.keys(tagMap));
+ }
+
+ if (includeIds)
+ {
+ var ids = [];
+ els.forEach(function(e)
+ {
+ if (e.id)
+ ids.push(e.id);
+ });
+ ids = Arr.sortUnique(ids);
+ ret.push.apply(ret, ids.map(function(cl)
+ {
+ return "#" + cl;
+ }));
+ }
+
+ if (includeClasses)
+ {
+ var clCombinationMap = Object.create(null), classes = [];
+ els.forEach(function(e)
+ {
+ var cl = e.className;
+ if (cl && !(cl in clCombinationMap))
+ {
+ clCombinationMap[cl] = 1;
+ classes.push.apply(classes, e.classList);
+ }
+ });
+ classes = Arr.sortUnique(classes);
+ ret.push.apply(ret, classes.map(function(cl)
+ {
+ return "." + cl;
+ }));
+ }
+ }
+
+ if (includePseudoClasses)
+ {
+ // Add the pseudo-class-looking :before, :after.
+ ret.push(
+ ":after",
+ ":before"
+ );
+
+ ret.push.apply(ret, SelectorEditor.stripCompletedParens(Css.pseudoClasses, postExpr));
+ }
+
+ if (includePseudoElements)
+ {
+ ret.push.apply(ret, Css.pseudoElements);
+ }
+
+ // Don't suggest things that are already included (by way of totally-
+ // incorrect-but-probably-good-enough logic).
+ var rev = Str.reverseString(preExpr);
+ var partInd = rev.search(/[, >+~]/);
+ var lastPart = (partInd === -1 ? rev : rev.substr(0, partInd));
+ lastPart = Str.reverseString(lastPart);
+ if (lastPart !== "")
+ {
+ ret = ret.filter(function(str)
+ {
+ var ind = lastPart.indexOf(str);
+ if (ind === -1)
+ return true;
+ var before = ind-1, after = ind+str.length;
+ var re = reSelectorChar;
+ if (before >= 0 && re.test(str.charAt(0)) && re.test(lastPart.charAt(before)))
+ return true;
+ if (after < lastPart.length && re.test(lastPart.charAt(after)))
+ return true;
+ return false;
+ });
+ }
+
+ // Don't suggest internal Firebug things.
+ var reInternal = /^[.#]firebug[A-Z]/;
+ ret = ret.filter(function(str)
+ {
+ return !reInternal.test(str);
+ });
+
+ if (ret.indexOf(":hover") !== -1)
+ out.suggestion = ":hover";
+
+ return ret.sort();
+ },
+
+ getAutoCompletePropSeparator: function(range, expr, prefixOf)
+ {
+ // For e.g. 'd|span', expand to a descendant selector; otherwise assume
+ // that this is part of the same selector part.
+ return (reSelectorChar.test(prefixOf.charAt(0)) ? " " : "");
+ },
+
+ autoCompleteAdjustSelection: function(value, offset)
+ {
+ if (offset >= 2 && value.substr(offset-2, 2) === "()")
+ return offset-1;
+ return offset;
+ }
+});
+
+
+// Transform completions so that they don't add additional parentheses when
+// ones already exist.
+SelectorEditor.stripCompletedParens = function(list, postExpr)
+{
+ var c = postExpr.charAt(0), rem = 0;
+ if (c === "(")
+ rem = 2;
+ else if (c === ")")
+ rem = 1;
+ else
+ return list;
+ return list.map(function(cl)
+ {
+ return (cl.slice(-2) === "()" ? cl.slice(0, -rem) : cl);
+ });
+};
+
+// ********************************************************************************************* //
+// Registration
+
+return SelectorEditor;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/css/selectorModule.js b/trace/FBTrace/chrome/firebug/content/css/selectorModule.js
new file mode 100644
index 0000000..f238322
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/css/selectorModule.js
@@ -0,0 +1,74 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/firebug",
+ "firebug/lib/trace",
+ "firebug/lib/object",
+ "firebug/lib/dom",
+ "firebug/lib/locale",
+ "firebug/chrome/menu"
+],
+function(Firebug, FBTrace, Obj, Dom, Locale, Menu) {
+
+// ********************************************************************************************* //
+// Model implementation
+
+var SelectorModule = Obj.extend(Firebug.Module,
+{
+ dispatchName: "selectorModule",
+
+ initialize: function()
+ {
+ Firebug.NetMonitor.NetInfoBody.addListener(this);
+ Firebug.registerUIListener(this);
+ },
+
+ shutdown: function()
+ {
+ Firebug.NetMonitor.NetInfoBody.removeListener(this);
+ Firebug.unregisterUIListener(this);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Context Menu
+
+ onContextMenu: function(items, object, target, context, panel, popup)
+ {
+ if (panel.name != "stylesheet")
+ return;
+
+ var cssRule = Dom.getAncestorByClass(target, "cssRule");
+ if (!cssRule)
+ return;
+
+ var rule = cssRule.repObject;
+ if (!rule)
+ return;
+
+ var panel = context.getPanel("selector");
+ if (!panel)
+ return;
+
+ var item = {
+ id: "fbGetMatchingElements",
+ nol10n: true,
+ label: Locale.$STR("css.selector.cmd.getMatchingElements"),
+ command: Obj.bindFixed(panel.getMatchingElements, panel, rule)
+ };
+
+ var refreshMenuItem = popup.querySelector("#fbRefresh");
+ Menu.createMenuItem(popup, item, refreshMenuItem);
+
+ return [];
+ },
+});
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerModule(SelectorModule);
+
+return SelectorModule;
+
+// ********************************************************************************************* //
+});
diff --git a/trace/FBTrace/chrome/firebug/content/css/selectorPanel.js b/trace/FBTrace/chrome/firebug/content/css/selectorPanel.js
new file mode 100644
index 0000000..56182e2
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/css/selectorPanel.js
@@ -0,0 +1,460 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/firebug",
+ "firebug/lib/object",
+ "firebug/lib/locale",
+ "firebug/lib/events",
+ "firebug/lib/dom",
+ "firebug/lib/domplate",
+ "firebug/chrome/menu",
+ "firebug/css/selectorEditor",
+ "firebug/css/selectorModule",
+],
+function(Firebug, Obj, Locale, Events, Dom, Domplate, Menu, SelectorEditor) {
+with (Domplate) {
+
+// ********************************************************************************************* //
+// Constants
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+
+// ********************************************************************************************* //
+// CSS Selector Panel
+
+/**
+ * @panel Selector side panel displaying HTML elements for the current selector,
+ * either from the CSS main panel or user entry
+ */
+function SelectorPanel() {}
+SelectorPanel.prototype = Obj.extend(Firebug.Panel,
+/** @lends SelectorPanel */
+{
+ name: "selector",
+ parentPanel: "stylesheet",
+ title: Locale.$STR("css.selector.Selection"),
+ editable: true,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Initialization
+
+ initialize: function(context, doc)
+ {
+ Firebug.Panel.initialize.apply(this, arguments);
+ },
+
+ shutdown: function(context, doc)
+ {
+ Firebug.Panel.shutdown.apply(this, arguments);
+ },
+
+ initializeNode: function(oldPanelNode)
+ {
+ Firebug.Panel.initializeNode.apply(this, arguments);
+
+ this.setSelection = Obj.bind(this.setSelection, this);
+ this.clearSelection = Obj.bind(this.clearSelection, this);
+ this.lockSelection = Obj.bind(this.lockSelection, this);
+
+ var panelNode = this.mainPanel.panelNode;
+ // See: http://code.google.com/p/fbug/issues/detail?id=5931
+ //Events.addEventListener(panelNode, "mouseover", this.setSelection, false);
+ //Events.addEventListener(panelNode, "mouseout", this.clearSelection, false);
+ //Events.addEventListener(panelNode, "mousedown", this.lockSelection, false);
+ },
+
+ destroyNode: function()
+ {
+ var panelNode = this.mainPanel.panelNode;
+ //Events.removeEventListener(panelNode, "mouseover", this.setSelection, false);
+ //Events.removeEventListener(panelNode, "mouseout", this.clearSelection, false);
+ //Events.removeEventListener(panelNode, "mousedown", this.lockSelection, false);
+
+ Firebug.Panel.destroyNode.apply(this, arguments);
+ },
+
+ show: function(state)
+ {
+ Firebug.Panel.show.apply(this, arguments);
+
+ this.refresh();
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ getCSSStyleRule: function(event)
+ {
+ var object = Firebug.getRepObject(event.target);
+
+ if (object && (object instanceof window.CSSStyleRule))
+ return object;
+ },
+
+ getCSSRuleElement: function(element)
+ {
+ while (element && !element.classList.contains("cssRule"))
+ element = element.parentNode;
+
+ return element;
+ },
+
+ getMatchingElements: function(rule)
+ {
+ this.trialSelector = rule.selectorText;
+ this.selection = rule;
+ this.rebuild();
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Selection
+
+ setSelection: function(event)
+ {
+ var rule = this.getCSSStyleRule(event);
+
+ if (rule)
+ {
+ // then we have entered a rule element
+ var ruleElement = this.getCSSRuleElement(event.target);
+ if (ruleElement && ruleElement !== this.lockedElement)
+ ruleElement.classList.add("selectedSelectorRule");
+
+ this.selection = rule;
+ this.rebuild();
+ }
+ },
+
+ clearSelection: function(event)
+ {
+ if (this.selection !== this.lockedSelection)
+ {
+ this.selection = this.lockedSelection;
+ this.rebuild();
+ }
+
+ var rule = this.getCSSStyleRule(event);
+ if (rule)
+ {
+ // then we are leaving a rule element that we may have highlighted.
+ var ruleElement = this.getCSSRuleElement(event.target);
+ if (ruleElement)
+ ruleElement.classList.remove("selectedSelectorRule");
+ }
+ },
+
+ lockSelection: function(event)
+ {
+ var rule = this.getCSSStyleRule(event);
+ if (rule)
+ {
+ if (this.lockedElement)
+ this.lockedElement.classList.remove("lockedSelectorRule");
+
+ this.lockedElement = this.getCSSRuleElement(event.target);
+
+ if (this.lockedElement)
+ {
+ this.lockedElement.classList.add("lockedSelectorRule");
+ this.lockedElement.classList.remove("selectedSelectorRule");
+ }
+
+ this.lockedSelection = rule;
+ }
+ },
+
+ hide: function()
+ {
+ Firebug.Panel.hide.apply(this, arguments);
+ },
+
+ refresh: function()
+ {
+ var root = this.context.window.document.documentElement;
+ this.selection = this.mainPanel.selection;
+
+ // Use trial selector if there is no selection in the CSS panel.
+ if (!this.selection)
+ this.selection = this.trialSelector;
+
+ this.rebuild(true);
+ },
+
+ /**
+ * returns an array of Elements matched from selector
+ */
+ getSelectedElements: function(selectorText)
+ {
+ var elements = [];
+
+ // Execute the query also in all iframes (see issue 5962)
+ var windows = this.context.windows;
+ for (var i=0; i<windows.length; i++)
+ {
+ var win = windows[i];
+ var selections = win.document.querySelectorAll(selectorText);
+
+ // For some reason the return value of querySelectorAll()
+ // is not recognized as a NodeList anymore since Firefox 10.0.
+ // See issue 5442.
+ // But since there can be more iframes we need to collect all matching
+ // elements in an extra array anyway.
+ if (selections)
+ {
+ for (var j=0; j<selections.length; j++)
+ elements.push(selections[j]);
+ }
+ else
+ {
+ throw new Error("Selection Failed: " + selections);
+ }
+ }
+
+ return elements;
+ },
+
+ /**
+ * Build content of the panel. The basic layout of the panel is generated by
+ * {@link SelectorTemplate} template.
+ */
+ rebuild: function()
+ {
+ if (this.selection)
+ {
+ try
+ {
+ var selectorText;
+
+ if (this.selection instanceof window.CSSStyleRule)
+ selectorText = this.selection.selectorText;
+ else
+ selectorText = this.selection;
+
+ var elements = this.getSelectedElements(selectorText);
+ if (elements && elements.length != 0)
+ {
+ SelectorTemplate.tag.replace({object: elements}, this.panelNode);
+ this.showTrialSelector(this.trialSelector);
+ return;
+ }
+ }
+ catch (e)
+ {
+ var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
+ var tbody = table.lastChild;
+
+ WarningTemplate.selectErrorTag.insertRows({object: e}, tbody.lastChild);
+ WarningTemplate.selectErrorTextTag.insertRows({object: e}, tbody.lastChild);
+
+ this.showTrialSelector(this.trialSelector);
+ return;
+ }
+ }
+
+ var table = SelectorTemplate.tag.replace({object: []}, this.panelNode);
+ var tbody = table.lastChild;
+
+ if (this.trialSelector)
+ {
+ WarningTemplate.noSelectionResultsTag.insertRows(
+ {object: this.selection}, tbody.lastChild)
+ }
+ else
+ {
+ WarningTemplate.noSelectionTag.insertRows(
+ {object: this.selection}, tbody.lastChild);
+ }
+
+ this.showTrialSelector(this.trialSelector);
+ },
+
+ getObjectPath: function(object)
+ {
+ if (FBTrace.DBG_SELECTOR)
+ FBTrace.sysout("css.selector.getObjectPath NOOP", object);
+ },
+
+ supportsObject: function(object)
+ {
+ return 0;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ tryASelector: function(element)
+ {
+ if (!this.trialSelector)
+ this.trialSelector = this.selection ? this.selection.selectorText : "";
+
+ this.editProperty(element, this.trialSelector);
+ },
+
+ editProperty: function(row, editValue)
+ {
+ Firebug.Editor.startEditing(row, editValue);
+ },
+
+ getEditor: function(target, value)
+ {
+ if (!this.editor)
+ this.editor = new SelectorPanelEditor(this.document);
+
+ return this.editor;
+ },
+
+ setTrialSelector: function(target, value)
+ {
+ if (this.lockedElement)
+ this.lockedElement.classList.remove("lockedSelectorRule");
+
+ this.trialSelector = value;
+ this.selection = this.trialSelector;
+ this.lockedElement = target;
+ this.lockedSelection = this.selection;
+ this.rebuild();
+ },
+
+ showTrialSelector: function(trialSelector)
+ {
+ var show = trialSelector ? true : false;
+ Dom.collapse(this.document.getElementById("trialHint"), show);
+
+ var trialSelectorDiv = this.document.getElementById("trialSelector");
+ trialSelectorDiv.textContent = trialSelector;
+ Dom.collapse(trialSelectorDiv, !show);
+ },
+});
+
+function SelectorPanelEditor(doc)
+{
+ this.box = this.tag.replace({}, doc, this);
+ this.input = this.box;
+
+ Firebug.InlineEditor.prototype.initialize.call(this);
+ this.tabNavigation = false;
+ this.fixedWidth = true;
+}
+
+SelectorPanelEditor.prototype = domplate(SelectorEditor.prototype,
+{
+ tag:
+ INPUT({"class": "fixedWidthEditor a11yFocusNoTab",
+ type: "text",
+ title: Locale.$STR("Selector"),
+ oninput: "$onInput",
+ onkeypress: "$onKeyPress"}
+ ),
+
+ endEditing: function(target, value, cancel)
+ {
+ if (cancel)
+ return;
+
+ this.panel.setTrialSelector(target, value);
+ }
+});
+
+// ********************************************************************************************* //
+
+var BaseRep = domplate(Firebug.Rep,
+{
+ // xxxHonza: shouldn't this be in Firebug.Rep?
+ getNaturalTag: function(value)
+ {
+ var rep = Firebug.getRep(value);
+ var tag = rep.shortTag ? rep.shortTag : rep.tag;
+ return tag;
+ }
+});
+
+// ********************************************************************************************* //
+
+var TrialRow =
+ TR({"class": "watchNewRow", level: 0, onclick: "$onClickEditor"},
+ TD({"class": "watchEditCell", colspan: 3},
+ DIV({"class": "watchEditBox a11yFocusNoTab", "id": "trialHint",
+ role: "button", "tabindex" : "0",
+ "aria-label": Locale.$STR("a11y.labels.press enter to add new selector")},
+ Locale.$STR("css.selector.TryASelector")
+ ),
+ DIV({"class": "trialSelector", "id": "trialSelector"}, "")
+ )
+ );
+
+// ********************************************************************************************* //
+
+/**
+ * @domplate: Template for basic layout of the {@link SelectorPanel} panel.
+ */
+var SelectorTemplate = domplate(BaseRep,
+{
+ // object will be array of elements CSSStyleRule
+ tag:
+ TABLE({"class": "cssSelectionTable", cellpadding: 0, cellspacing: 0},
+ TBODY({"class": "cssSelectionTBody"},
+ TrialRow,
+ FOR("element", "$object",
+ TR({"class": "selectionElementRow", _repObject: "$element"},
+ TD({"class": "selectionElement"},
+ TAG( "$element|getNaturalTag", {object: "$element"})
+ )
+ )
+ )
+ )
+ ),
+
+ onClickEditor: function(event)
+ {
+ var tr = event.currentTarget;
+ var panel = Firebug.getElementPanel(tr);
+ panel.tryASelector(tr);
+ },
+});
+
+// ********************************************************************************************* //
+
+var WarningTemplate = domplate(Firebug.Rep,
+{
+ noSelectionTag:
+ TR({"class": "selectorWarning"},
+ TD({"class": "selectionElement"}, Locale.$STR("css.selector.noSelection"))
+ ),
+
+ noSelectionResultsTag:
+ TR({"class": "selectorWarning"},
+ TD({"class": "selectionElement"}, Locale.$STR("css.selector.noSelectionResults"))
+ ),
+
+ selectErrorTag:
+ TR({"class": "selectorWarning"},
+ TD({"class": "selectionElement"}, Locale.$STR("css.selector.selectorError"))
+ ),
+
+ selectErrorTextTag:
+ TR({"class": "selectorWarning"},
+ TD({"class": "selectionErrorText selectionElement"},
+ SPAN("$object|getErrorMessage")
+ )
+ ),
+
+ getErrorMessage: function(object)
+ {
+ if (object.message)
+ return object.message;
+
+ return Locale.$STR("css.selector.unknownErrorMessage");
+ }
+});
+
+// ********************************************************************************************* //
+// Registration
+
+Firebug.registerStylesheet("chrome://firebug/skin/selector.css");
+Firebug.registerPanel(SelectorPanel);
+
+return SelectorPanel;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/css/stylePanel.js b/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
index 6f5ef01..f18b80d 100644
--- a/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
+++ b/trace/FBTrace/chrome/firebug/content/css/stylePanel.js
@@ -15,7 +15,6 @@ define([
"firebug/lib/dom",
"firebug/lib/css",
"firebug/lib/xpath",
- "firebug/lib/array",
"firebug/lib/fonts",
"firebug/lib/options",
"firebug/css/cssModule",
@@ -23,7 +22,7 @@ define([
"firebug/chrome/menu"
],
function(Obj, Firebug, Firefox, Domplate, FirebugReps, Xpcom, Locale, Events, Url, Arr,
- SourceLink, Dom, Css, Xpath, Arr, Fonts, Options, CSSModule, CSSStyleSheetPanel, Menu) {
+ SourceLink, Dom, Css, Xpath, Fonts, Options, CSSModule, CSSStyleSheetPanel, Menu) {
with (Domplate) {
@@ -95,12 +94,12 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
getSeparator: function(part)
{
- if (part.type == "otherProps")
- return " ";
-
if (part.lastFont || part.type == "important")
return "";
+ if (part.type == "otherProps")
+ return " ";
+
return ",";
},
@@ -257,11 +256,9 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
if (!isPseudoElementSheet)
this.markOverriddenProps(element, props, usedProps, inheritMode);
- var ruleId = this.getRuleId(rule);
- rules.unshift({rule: rule, id: ruleId,
- // Show universal selectors with pseudo-class
- // (http://code.google.com/p/fbug/issues/detail?id=3683)
- selector: rule.selectorText.replace(/ :/g, " *:"),
+ rules.unshift({
+ rule: rule,
+ selector: rule.selectorText.replace(/ :/g, " *:"), // (issue 3683)
sourceLink: sourceLink,
props: props, inherited: inheritMode,
isSystemSheet: isSystemSheet,
@@ -443,7 +440,7 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
getStyleProperties: function(element, rules, usedProps, inheritMode)
{
var props = this.parseCSSProps(element.style, inheritMode);
- this.addOldProperties(this.context, Xpath.getElementXPath(element), inheritMode, props);
+ this.addDisabledProperties(this.context, element, inheritMode, props);
this.sortProperties(props);
@@ -451,8 +448,8 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
if (props.length)
{
- rules.unshift({rule: element, id: Xpath.getElementXPath(element),
- selector: "element.style", props: props, inherited: inheritMode});
+ rules.unshift({rule: element, selector: "element.style",
+ props: props, inherited: inheritMode});
}
},
@@ -511,8 +508,18 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
updateView: function(element)
{
- CSSModule.cleanupSheets(element.ownerDocument, Firebug.currentContext);
+ var result = CSSModule.cleanupSheets(element.ownerDocument, Firebug.currentContext);
+ // If cleanupSheets returns false there was an exception thrown when accessing
+ // a styleshet (probably since it isn't fully loaded yet). So, delay the panel
+ // update and try it again a bit later (issue 5654).
+ if (!result)
+ {
+ this.context.setTimeout(Obj.bindFixed(this.updateView, this, element), 200);
+ return;
+ }
+
+ // All stylesheets should be ready now, update the view.
this.updateCascadeView(element);
if (Dom.domUtils)
@@ -531,7 +538,7 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
if (sothinkInstalled)
{
var div = FirebugReps.Warning.tag.replace({object: "SothinkWarning"}, this.panelNode);
- div.innerHTML = Locale.$STR("SothinkWarning");
+ div.textContent = Locale.$STR("SothinkWarning");
return;
}
@@ -591,6 +598,7 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
}
}
);
+
if (Dom.domUtils.hasPseudoClassLock)
{
items.push(
@@ -633,7 +641,7 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
},
{
label: "AddRule",
- tooltiptext: "style.tip.Add_Rule",
+ tooltiptext: "css.tip.AddRule",
command: Obj.bindFixed(this.addRelatedRule, this)
});
@@ -658,7 +666,7 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
var prop = Dom.getAncestorByClass(target, "cssProp");
if (prop)
var propNameNode = prop.getElementsByClassName("cssPropName").item(0);
-
+
if (propNameNode && (propNameNode.textContent.toLowerCase() == "font" ||
propNameNode.textContent.toLowerCase() == "font-family"))
{
@@ -670,9 +678,27 @@ CSSStylePanel.prototype = Obj.extend(CSSStyleSheetPanel.prototype,
}
}
- return CSSStyleSheetPanel.prototype.showInfoTip.call(this, infoTip, target, x, y, rangeParent, rangeOffset);
+ return CSSStyleSheetPanel.prototype.showInfoTip.call(
+ this, infoTip, target, x, y, rangeParent, rangeOffset);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Extends stylesheet (CSS Panel)
+
+ deleteRuleDeclaration: function(cssSelector)
+ {
+ var repObject = Firebug.getRepObject(cssSelector);
+
+ if (repObject instanceof window.Element)
+ CSSModule.deleteRule(repObject);
+ else
+ CSSStyleSheetPanel.prototype.deleteRuleDeclaration(cssSelector);
+
+ this.refresh();
},
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
hasPseudoClassLock: function(pseudoClass)
{
if (Dom.domUtils.hasPseudoClassLock)
@@ -813,7 +839,7 @@ function getFontPropValueParts(element, value, propName)
"monospace": 1,
};
- var parts = [];
+ var parts = [], origValue = value;
// (Mirroring CSSModule.parseCSSFontFamilyValue)
if (propName === "font")
@@ -827,7 +853,11 @@ function getFontPropValueParts(element, value, propName)
);
var matches = rePreFont.exec(value);
if (!matches)
- return;
+ {
+ // Non-simple font value, like "inherit", "status-bar" or
+ // "calc(12px) Arial" - just return the whole text.
+ return [{type: "otherProps", value: value, lastFont: true}];
+ }
var preProps = matches[0].slice(0, -1);
parts.push({type: "otherProps", value: preProps});
value = value.substr(matches[0].length);
@@ -836,13 +866,23 @@ function getFontPropValueParts(element, value, propName)
var matches = /^(.*?)( !important)?$/.exec(value);
var fonts = matches[1].split(",");
- // Clone the element to just get the fonts used in it and not its descendants
- var clonedElement = element.cloneNode(false);
- clonedElement.textContent = element.textContent;
- Firebug.setIgnored(clonedElement);
- element.parentNode.appendChild(clonedElement);
- var usedFonts = Fonts.getFonts(clonedElement).slice();
- clonedElement.parentNode.removeChild(clonedElement);
+ // What we want to know is what the specified "font-family" property means
+ // for the selected element's text, not what the element actually uses (that
+ // depends on font styles of its descendants). Thus, we just check the direct
+ // child text nodes of the element.
+ // Do not create a temporary element for testing to avoid problems like in
+ // issue 5905 and 6048
+ var usedFonts = [];
+ var child = element.firstChild;
+ do
+ {
+ if (!child)
+ break;
+
+ if (child.nodeType == Node.TEXT_NODE)
+ usedFonts = Arr.extendArray(usedFonts, Fonts.getFonts(child));
+ }
+ while (child = child.nextSibling);
var genericFontUsed = false;
for (var i = 0; i < fonts.length; ++i)
diff --git a/trace/FBTrace/chrome/firebug/content/dom/domPanel.js b/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
index 7e642c8..d9eee6f 100644
--- a/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/dom/domPanel.js
@@ -126,9 +126,9 @@ const DirTablePlate = domplate(Firebug.Rep,
TAG("$memberRowTag", {member: "$member"})
),
- memberIterator: function(object, level)
+ memberIterator: function(object)
{
- var members = Firebug.DOMBasePanel.prototype.getMembers(object, level, this.context);
+ var members = Firebug.DOMBasePanel.prototype.getMembers(object, 0, null);
if (members.length)
return members;
@@ -422,16 +422,23 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
/**
* @param object a user-level object wrapped in security blanket
* @param level for a.b.c, level is 2
- * @param context
+ * @param optional context
*/
getMembers: function(object, level, context)
{
if (!level)
level = 0;
- var ordinals = [], userProps = [], userClasses = [], userFuncs = [],
- domProps = [], domFuncs = [], domConstants = [], proto = [],
- domHandlers = [];
+ var ordinals = [];
+ var userProps = [];
+ var userClasses = [];
+ var userFuncs = [];
+ var domProps = [];
+ var domClasses = [];
+ var domFuncs = [];
+ var domConstants = [];
+ var proto = [];
+ var domHandlers = [];
try
{
@@ -439,12 +446,6 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (isArguments(object))
object = Arr.cloneArray(object);
- if ("StorageList" in window && object instanceof window.StorageList)
- {
- var domain = context.window.location.hostname;
- object = object.namedItem(domain);
- }
-
try
{
var contentView = this.getObjectView(object);
@@ -537,13 +538,24 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
else if (typeof(val) == "function")
{
if (isClassFunction(val))
- this.addMember(object, "userClass", userClasses, name, val, level, 0, context);
+ {
+ if (Dom.isDOMMember(object, name))
+ this.addMember(object, "domClass", domClasses, name, val, level, domMembers[name], context);
+ else
+ this.addMember(object, "userClass", userClasses, name, val, level, 0, context);
+ }
else if (Dom.isDOMMember(object, name))
+ {
this.addMember(object, "domFunction", domFuncs, name, val, level, domMembers[name], context);
+ }
else if (!Firebug.showUserFuncs && Firebug.showInlineEventHandlers)
+ {
this.addMember(object, "userFunction", domHandlers, name, val, level, 0, context);
+ }
else
+ {
this.addMember(object, "userFunction", userFuncs, name, val, level, 0, context);
+ }
}
else
{
@@ -600,6 +612,9 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
if (Firebug.showDOMFuncs)
{
+ domClasses.sort(sortName);
+ members.push.apply(members, domClasses);
+
domFuncs.sort(sortName);
members.push.apply(members, domFuncs);
}
@@ -682,12 +697,6 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
}
}
- if ("StorageList" in window && value instanceof window.StorageList)
- {
- var domain = context.window.location.hostname;
- hasChildren = value.namedItem(domain).length > 0;
- }
-
var member = {
object: object,
name: name,
@@ -1589,6 +1598,7 @@ Firebug.DOMBasePanel.prototype = Obj.extend(Firebug.Panel,
items.push(
{
label: isWatch ? "DeleteWatch" : "DeleteProperty",
+ id: "DeleteProperty",
tooltiptext: isWatch ? "watch.tip.Delete_Watch" :
"dom.tip.Delete_Property",
command: Obj.bindFixed(this.deleteProperty, this, row)
diff --git a/trace/FBTrace/chrome/firebug/content/editor/editor.js b/trace/FBTrace/chrome/firebug/content/editor/editor.js
index 0fd9cb8..9e08249 100644
--- a/trace/FBTrace/chrome/firebug/content/editor/editor.js
+++ b/trace/FBTrace/chrome/firebug/content/editor/editor.js
@@ -164,6 +164,8 @@ Firebug.Editor = Obj.extend(Firebug.Module,
if (value != originalValue)
this.saveEditAndNotifyListeners(currentTarget, originalValue, previousValue);
+ currentEditor.cancelEditing(currentTarget, originalValue);
+
if (removeGroup && !originalValue && currentGroup)
currentGroup.parentNode.removeChild(currentGroup);
}
@@ -548,6 +550,10 @@ Firebug.BaseEditor = Obj.extend(Firebug.MeasureBox,
return true;
},
+ cancelEditing: function(target, value)
+ {
+ },
+
insertNewRow: function(target, insertWhere)
{
},
@@ -924,8 +930,9 @@ Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
Events.cancelEvent(event);
}
else if (this.numeric && event.charCode &&
- (event.charCode < KeyEvent.DOM_VK_0 || event.charCode > KeyEvent.DOM_VK_9) &&
- event.charCode != KeyEvent.DOM_VK_INSERT && event.charCode != KeyEvent.DOM_VK_DELETE)
+ !(event.ctrlKey || event.metaKey || event.altKey) &&
+ !(KeyEvent.DOM_VK_0 <= event.charCode && event.charCode <= KeyEvent.DOM_VK_9) &&
+ event.charCode !== KeyEvent.DOM_VK_INSERT && event.charCode !== KeyEvent.DOM_VK_DELETE)
{
Events.cancelEvent(event);
}
@@ -965,12 +972,9 @@ Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
Dom.eraseNode(popup);
var target = event.target;
- var menu = this.getContextMenuItems(target);
- if (menu)
- {
- for (var i = 0; i < menu.length; ++i)
- Menu.createMenuItem(popup, menu[i]);
- }
+ var items = this.getContextMenuItems(target);
+ if (items)
+ Menu.createMenuItems(popup, items);
if (!popup.firstChild)
return false;
@@ -1028,7 +1032,7 @@ Firebug.InlineEditor.prototype = domplate(Firebug.BaseEditor,
if(this.wrapped)
{
- var fixupL = clR[1].left - clR[0].left,
+ var fixupL = clR[1].left - clR[0].left;
fixupT = clR[1].top - clR[0].top;
}
else
diff --git a/trace/FBTrace/chrome/firebug/content/firebug.css b/trace/FBTrace/chrome/firebug/content/firebug.css
index 5c134bb..296d49b 100644
--- a/trace/FBTrace/chrome/firebug/content/firebug.css
+++ b/trace/FBTrace/chrome/firebug/content/firebug.css
@@ -19,7 +19,7 @@ window[chromehidden~="toolbar"] #fbToolbar {
/* Firebug Splitter */
#fbContentSplitter[dir=reverse]{
- -moz-transform: scale(-1, -1);
+ transform: scale(-1, -1);
}
#fbContentSplitter[orient=vertical] {
@@ -79,6 +79,7 @@ textbox#fbCommandEditor {
.completionText {
color: #666666;
+ margin-right: 1px;
}
[selected="true"] > .completionText {
background-color: highlight;
@@ -261,7 +262,8 @@ panelTab > panelTabMenu .menuPopup:-moz-locale-dir(rtl) {
height: 20px;
}
-#fbLocationList.noTabStop> menupopup > arrowscrollbox> scrollbox {
+#fbLocationList.noTabStop > menupopup > arrowscrollbox > scrollbox,
+#fbCommandHistory > arrowscrollbox > scrollbox {
overflow-y: auto;
}
@@ -345,7 +347,7 @@ panelTab > panelTabMenu .menuPopup:-moz-locale-dir(rtl) {
panelTab[breakOnNextArmed="true"] > .panelTab-text {
text-shadow: 1px 1px 2px darkGray, 0 0 1em orange, 0 0 0.2em orange !important;
- /* -moz-animation: armedBlinking 0.8s ease-out infinite alternate; see issue 5618 */
+ /* animation: armedBlinking 0.8s ease-out infinite alternate; see issue 5618 */
}
/* see issue 5618
diff --git a/trace/FBTrace/chrome/firebug/content/firebug.js b/trace/FBTrace/chrome/firebug/content/firebug.js
index df69413..e1d93e2 100644
--- a/trace/FBTrace/chrome/firebug/content/firebug.js
+++ b/trace/FBTrace/chrome/firebug/content/firebug.js
@@ -21,11 +21,11 @@ define([
"firebug/lib/array",
"firebug/lib/dom",
"firebug/lib/http",
- "firebug/js/fbs",
"firebug/trace/traceListener",
+ "firebug/console/commandLineExposed",
],
function(FBL, Obj, Firefox, ChromeFactory, Domplate, Options, Locale, Events,
- Wrapper, Url, Css, Win, Str, Arr, Dom, Http, FBS, TraceListener) {
+ Wrapper, Url, Css, Win, Str, Arr, Dom, Http, TraceListener, CommandLineExposed) {
// ********************************************************************************************* //
// Constants
@@ -65,6 +65,7 @@ var panelTypeMap = {};
// ********************************************************************************************* //
+//xxxHonza: we should use the existing Firebug object.
if (window.Firebug)
{
// Stow the pre-load properties, add them back at the end
@@ -147,7 +148,9 @@ window.Firebug =
// Append early registered panels at the end.
panelTypes.push.apply(panelTypes, tempPanelTypes);
- Firebug.Options.addListener(this);
+ // Firebug is getting option-updates from the connection so,
+ // do not register it again here (see issue 6035)
+ //Firebug.Options.addListener(this);
this.isInitialized = true;
@@ -253,10 +256,6 @@ window.Firebug =
if (Firebug.PanelActivation)
Firebug.PanelActivation.activatePanelTypes(panelTypes);
- // bug712289
- if (Firebug.PanelActivation && !FBS.isJSDAvailable())
- Firebug.PanelActivation.disablePanel(this.getPanelType("script"));
-
// Tell the modules the UI is up.
Events.dispatch(modules, "initializeUI", [detachArgs]);
},
@@ -397,23 +396,29 @@ window.Firebug =
var contextURLSet = [];
// create a list of all unique activeContexts
- Firebug.connection.eachContext( function createActiveContextList(context)
+ Firebug.connection.eachContext(function createActiveContextList(context)
{
if (FBTrace.DBG_WINDOWS)
- FBTrace.sysout("context "+context.getName());
+ FBTrace.sysout("context " + context.getName());
try
{
var cw = context.window;
if (cw)
{
+ var url;
if (cw.closed)
+ {
url = "about:closed";
+ }
else
- if ('location' in cw)
- var url = cw.location.toString();
+ {
+ if ("location" in cw)
+ url = cw.location.toString();
else
- var url = context.getName();
+ url = context.getName();
+ }
+
if (url)
{
if (contextURLSet.indexOf(url) == -1)
@@ -657,6 +662,16 @@ window.Firebug =
Firebug.TraceModule.removeListener(listener);
},
+ registerCommand: function(name, config)
+ {
+ return CommandLineExposed.registerCommand(name, config);
+ },
+
+ unregistereCommand: function(name)
+ {
+ return CommandLineExposed.unregisterCommand(name);
+ },
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Options
@@ -861,11 +876,11 @@ window.Firebug =
// TODO reattach
// window is closing in detached mode
- if (Firebug.chrome.window.top)
+ var parent = this.getFirebugFrameParent();
+ if (parent)
{
- topWindow = Firebug.chrome.window.top;
- topWindow.exportFirebug();
- topWindow.close();
+ parent.exportFirebug();
+ parent.close();
}
Firebug.setPlacement("minimized");
@@ -906,9 +921,9 @@ window.Firebug =
//detached -> inbrowser
if (!forceOpen && Firebug.isDetached())
{
- var topWin = Firebug.chrome.window.top;
- topWin.exportFirebug();
- topWin.close();
+ var parent = this.getFirebugFrameParent();
+ parent.exportFirebug();
+ parent.close();
if (reopenInBrowser)
{
@@ -953,7 +968,6 @@ window.Firebug =
Firebug.StartButton.resetTooltip();
},
-
detachBar: function()
{
if (Firebug.isDetached()) // can be set true attachBrowser
@@ -964,8 +978,8 @@ window.Firebug =
if (Firebug.chrome.waitingForDetach)
return null;
- Firebug.chrome.waitingForDetach = true;
+ Firebug.chrome.waitingForDetach = true;
Firebug.chrome.toggleOpen(false); // don't show in browser.xul now
if (FBTrace.DBG_ACTIVATION)
@@ -996,6 +1010,22 @@ window.Firebug =
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+ /**
+ * Returns parent of the firebugFrame.xul frame. The actual parent depends on whether
+ * Firebug is attached or detached.
+ *
+ * attached -> browser.xul
+ * detached -> firebug.xul
+ */
+ getFirebugFrameParent: function()
+ {
+ // We need firebug.xul in case of detached state. So, don't use 'top' since
+ // it references browser.xul
+ return Firebug.chrome.window.parent;
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// deprecated
resetAllOptions: function(confirm)
@@ -1240,7 +1270,7 @@ window.Firebug =
if (Css.hasClass(child, "repTarget"))
target = child;
- if (child.repObject)
+ if (child.repObject != null)
{
if (!target && Css.hasClass(child, "repIgnore"))
break;
@@ -1257,7 +1287,7 @@ window.Firebug =
{
for (var child = node; child; child = child.parentNode)
{
- if (child.repObject)
+ if (child.repObject != null)
return child;
}
},
@@ -1266,7 +1296,7 @@ window.Firebug =
{
for (var child = element.firstChild; child; child = child.nextSibling)
{
- if (child.repObject == object)
+ if (child.repObject === object)
return child;
}
},
@@ -1394,7 +1424,7 @@ window.Firebug =
{
testLists.push({
extension: "Firebug",
- testListURL: "http://getfirebug.com/tests/head/firebug.html"
+ testListURL: "https://getfirebug.com/tests/1.11/firebug.html"
});
}
};
@@ -1719,9 +1749,11 @@ Firebug.Panel = Obj.extend(new Firebug.Listener(),
if (this.panelNode)
{
+ var scrollTop = this.panelNode.scrollTop;
this.panelNode = doc.adoptNode(this.panelNode, true);
this.panelNode.ownerPanel = this;
doc.body.appendChild(this.panelNode);
+ this.panelNode.scrollTop = scrollTop;
}
},
@@ -2507,6 +2539,11 @@ Firebug.Rep = domplate(
return m ? m[1] : label;
},
+ showInfoTip: function(infoTip, target, x, y)
+ {
+ return false;
+ },
+
getTooltip: function(object)
{
return null;
diff --git a/trace/FBTrace/chrome/firebug/content/firebugOverlay.xul b/trace/FBTrace/chrome/firebug/content/firebugOverlay.xul
index daba10f..a7963c1 100644
--- a/trace/FBTrace/chrome/firebug/content/firebugOverlay.xul
+++ b/trace/FBTrace/chrome/firebug/content/firebugOverlay.xul
@@ -4,8 +4,6 @@
<?xul-overlay href="firefox/firebugMenuOverlay.xul"?>
<?xul-overlay href="chrome://firebug/content/cookies/cookiePanel.xul"?>
-<?xml-stylesheet href="firebug.css"?>
-
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml">
@@ -36,8 +34,8 @@
noautofocus="true">
</panel>
- <panel id="fbCommandHistory" noautofocus="true">
- </panel>
+ <menupopup id="fbCommandHistory" noautofocus="true" ignorekeys="true">
+ </menupopup>
<!-- Context menu for the Command Editor -->
<menupopup id="fbCommandEditorPopup" />
@@ -62,8 +60,8 @@
<image src="chrome://firebug/skin/firebug.png"/>
<menupopup id="menu_firebug_iconMenu" class="fbFirebugMenuPopup"
- onpopupshowing="return Firebug.GlobalUI.onMenuShowing(this);"
- onpopuphiding="return Firebug.GlobalUI.onMenuHiding(this);">
+ onpopupshowing="return Firebug.browserOverlay.onMenuShowing(this, event);"
+ onpopuphiding="return Firebug.browserOverlay.onMenuHiding(this, event);">
<!-- Content comes from firebugMenuContent -->
</menupopup>
</toolbarbutton>
@@ -117,7 +115,7 @@
<!-- Open In New Window & Minimize & Close -->
<hbox id="fbWindowButtons" role="toolbar" class="innerToolbar"
aria-label="firebug window" context="_child">
- <menupopup onpopupshowing="Firebug.GlobalUI.onPositionPopupShowing(this)"/>
+ <menupopup onpopupshowing="Firebug.browserOverlay.onPositionPopupShowing(this)"/>
<toolbarbutton id="fbMinimizeButton"
class="toolbarbutton-iconic fbInternational"
tooltiptext="Minimize Firebug" command="cmd_firebug_minimizeFirebug"/>
@@ -489,10 +487,11 @@
<!-- completion text -->
<html:input id="fbCommandLineCompletion" class="fbCommandLine"
type="text" maxlength="2048" autocomplete="off" tabindex="-1" />
- <!-- holds the misspelling and a red squiggly line -->
- <html:div id="misspell" class="lst"></html:div>
<textbox id="fbCommandLine" class="fbCommandLine" flex="1"
aria-autocomplete="inline" multiline="false" newlines="pasteintact"/>
+ <!-- font width measurer, contains 60 arbitrary characters -->
+ <html:span id="fbCommandLineMeasurer" class="fbCommandLine"
+ >aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</html:span>
</html:div>
</vbox>
</hbox>
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/bindings.xml b/trace/FBTrace/chrome/firebug/content/firefox/bindings.xml
index 239acd7..96a4cb0 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/bindings.xml
+++ b/trace/FBTrace/chrome/firebug/content/firefox/bindings.xml
@@ -1258,8 +1258,9 @@
for (var j = 0; j < urls.length; ++j)
{
+ var label = urls[j].fileName != path ? urls[j].fileName : "Inline";
var menuInfo = {
- label: urls[j].fileName != path ? urls[j].fileName : "Inline",
+ label: FBL.cropString(label, Firebug.Options.get("stringCropLength")),
tooltiptext: path + urls[j].fileName,
nol10n: true
};
@@ -1293,14 +1294,14 @@
this.filter.filterString = "";
this.onkeypress = FBL.bind(this.onKeyPress, this);
- window.top.addEventListener("keypress", this.onkeypress, true);
+ window.parent.addEventListener("keypress", this.onkeypress, true);
this.onclick = FBL.bind(this.onClick, this);
this.popup.addEventListener("click", this.onclick, true);
]]></handler>
<handler event="popuphidden"><![CDATA[
- window.top.removeEventListener("keypress", this.onkeypress, true);
+ window.parent.removeEventListener("keypress", this.onkeypress, true);
this.popup.removeEventListener("click", this.onclick, true);
delete this.onkeypress;
@@ -1340,7 +1341,7 @@
{
if (child.localName == "menuitem")
{
- var label = child.getAttribute("label").toLowerCase();
+ var label = child.getAttribute("tooltiptext").toLowerCase();
child._searchMatch = label.indexOf(substring) != -1;
if (child._searchMatch)
{
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserCommands.js b/trace/FBTrace/chrome/firebug/content/firefox/browserCommands.js
new file mode 100644
index 0000000..8f8d6d2
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserCommands.js
@@ -0,0 +1,107 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/lib/trace",
+ "firebug/lib/options",
+ "firebug/lib/locale",
+ "firebug/firefox/browserOverlayLib",
+],
+function(FBTrace, Options, Locale, BrowserOverlayLib) {
+with (BrowserOverlayLib) {
+
+// ********************************************************************************************* //
+// Constants
+
+var shortcuts = [
+ "toggleFirebug",
+ "toggleInspecting",
+ "focusCommandLine",
+ "detachFirebug",
+ "closeFirebug",
+ "toggleBreakOn"
+]
+
+/* Used by the browser menu, but should be really global shortcuts?
+key_increaseTextSize
+key_decreaseTextSize
+key_normalTextSize
+key_help
+key_toggleProfiling
+key_focusFirebugSearch
+key_customizeFBKeys
+*/
+
+// ********************************************************************************************* //
+// BrowserCommands Implementation
+
+var BrowserCommands =
+{
+ overlay: function(doc)
+ {
+ this.overlayCommands(doc);
+ this.overlayShortcuts(doc);
+ },
+
+ overlayCommands: function(doc)
+ {
+ $command(doc, "cmd_firebug_closeFirebug", "Firebug.closeFirebug(true);");
+ $command(doc, "cmd_firebug_toggleInspecting", "if (!Firebug.currentContext) Firebug.toggleBar(true); Firebug.Inspector.toggleInspecting(Firebug.currentContext);");
+ $command(doc, "cmd_firebug_focusCommandLine", "if (!Firebug.currentContext) Firebug.toggleBar(true); Firebug.CommandLine.focus(Firebug.currentContext);");
+ $command(doc, "cmd_firebug_toggleFirebug", "Firebug.toggleBar();");
+ $command(doc, "cmd_firebug_detachFirebug", "Firebug.toggleDetachBar(false, true);");
+ $command(doc, "cmd_firebug_inspect", "Firebug.Inspector.inspectFromContextMenu(arg);", "document.popupNode");
+ $command(doc, "cmd_firebug_toggleBreakOn", "if (Firebug.currentContext) Firebug.chrome.breakOnNext(Firebug.currentContext, event);");
+ $command(doc, "cmd_firebug_toggleDetachFirebug", "Firebug.toggleDetachBar(false, true);");
+ $command(doc, "cmd_firebug_increaseTextSize", "Firebug.Options.changeTextSize(1);");
+ $command(doc, "cmd_firebug_decreaseTextSize", "Firebug.Options.changeTextSize(-1);");
+ $command(doc, "cmd_firebug_normalTextSize", "Firebug.Options.setTextSize(0);");
+ $command(doc, "cmd_firebug_focusFirebugSearch", "if (Firebug.currentContext) Firebug.Search.onSearchCommand(document);");
+ $command(doc, "cmd_firebug_customizeFBKeys", "Firebug.ShortcutsModel.customizeShortcuts();");
+ $command(doc, "cmd_firebug_enablePanels", "Firebug.PanelActivation.enableAllPanels();");
+ $command(doc, "cmd_firebug_disablePanels", "Firebug.PanelActivation.disableAllPanels();");
+ $command(doc, "cmd_firebug_clearActivationList", "Firebug.PanelActivation.clearAnnotations();");
+ $command(doc, "cmd_firebug_clearConsole", "Firebug.Console.clear(Firebug.currentContext);");
+ $command(doc, "cmd_firebug_allOn", "Firebug.PanelActivation.toggleAll('on');");
+ $command(doc, "cmd_firebug_toggleOrient", "Firebug.chrome.toggleOrient();");
+ $command(doc, "cmd_firebug_resetAllOptions", "Firebug.resetAllOptions(true);");
+ $command(doc, "cmd_firebug_toggleProfiling", ""); //todo
+ $command(doc, "cmd_firebug_openInEditor", "Firebug.ExternalEditors.onContextMenuCommand(event)");
+ },
+
+ overlayShortcuts: function(doc)
+ {
+ var keyset = $(doc, "mainKeyset");
+
+ for (var i=0; i<shortcuts.length ; i++)
+ {
+ var id = shortcuts[i];
+ var shortcut = Options.get("key.shortcut." + id);
+ var tokens = shortcut.split(" ");
+ var key = tokens.pop();
+
+ var keyProps = {
+ id: "key_firebug_" + id,
+ modifiers: tokens.join(","),
+ command: "cmd_firebug_" + id,
+ position: 1
+ };
+
+ if (key.length <= 1)
+ keyProps.key = key;
+ else if (doc.defaultView.KeyEvent["DOM_"+key])
+ keyProps.keycode = key;
+
+ $el(doc, "key", keyProps, keyset);
+ }
+
+ keyset.parentNode.insertBefore(keyset, keyset.nextSibling);
+ }
+}
+
+// ********************************************************************************************* //
+// Registration
+
+return BrowserCommands;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserMenu.js b/trace/FBTrace/chrome/firebug/content/firefox/browserMenu.js
new file mode 100644
index 0000000..d1ce9ec
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserMenu.js
@@ -0,0 +1,522 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/lib/trace",
+ "firebug/lib/options",
+ "firebug/lib/locale",
+ "firebug/firefox/browserOverlayLib",
+],
+function(FBTrace, Options, Locale, BrowserOverlayLib) {
+with (BrowserOverlayLib) {
+
+// ********************************************************************************************* //
+// GlobalCommands Implementation
+
+var BrowserMenu =
+{
+ overlay: function(doc)
+ {
+ this.overlayStartButtonMenu(doc);
+ this.overlayFirebugMenu(doc);
+ this.overlayFirefoxMenu(doc);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug Start Button Popup Menu
+
+ overlayStartButtonMenu: function(doc)
+ {
+ $menupopupOverlay(doc, $(doc, "mainPopupSet"), [
+ $menupopup(doc,
+ {
+ id: "fbStatusContextMenu",
+ onpopupshowing: "Firebug.browserOverlay.onOptionsShowing(this)"
+ },
+ [
+ $menu(doc,
+ {
+ label: "firebug.uiLocation",
+ tooltiptext: "firebug.menu.tip.UI_Location",
+ "class": "fbInternational"
+ },
+ [
+ $menupopup(doc, {
+ onpopupshowing: "Firebug.browserOverlay.onPositionPopupShowing(this)"
+ })
+ ]),
+ $menuseparator(doc),
+ $menuitem(doc, {
+ id: "menu_firebug_ClearConsole",
+ label: "firebug.ClearConsole",
+ tooltiptext: "firebug.ClearTooltip",
+ command: "cmd_firebug_clearConsole",
+ key: "key_firebug_clearConsole"
+ }),
+ $menuitem(doc, {
+ id: "menu_firebug_showErrorCount",
+ type: "checkbox",
+ label: "firebug.Show_Error_Count",
+ tooltiptext: "firebug.menu.tip.Show_Error_Count",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "showErrorCount"
+ }),
+ $menuseparator(doc),
+ $menuitem(doc, {
+ id: "menu_firebug_enablePanels",
+ label: "firebug.menu.Enable_All_Panels",
+ tooltiptext: "firebug.menu.tip.Enable_All_Panels",
+ command: "cmd_firebug_enablePanels"
+ }),
+ $menuitem(doc, {
+ id: "menu_firebug_disablePanels",
+ label: "firebug.menu.Disable_All_Panels",
+ tooltiptext: "firebug.menu.tip.Disable_All_Panels",
+ command: "cmd_firebug_disablePanels"
+ }),
+ $menuseparator(doc),
+ $menuitem(doc, {
+ id: "menu_firebug_AllOn",
+ type: "checkbox",
+ label: "On_for_all_web_pages",
+ tooltiptext: "firebug.menu.tip.On_for_all_Web_Sites",
+ command: "cmd_firebug_allOn",
+ option: "allPagesActivation"
+ }),
+ $menuitem(doc, {
+ id: "menu_firebug_clearActivationList",
+ label: "firebug.menu.Clear_Activation_List",
+ tooltiptext: "firebug.menu.tip.Clear_Activation_List",
+ command: "cmd_firebug_clearActivationList"
+ })
+ ])
+ ])
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug Global Menu
+
+ /**
+ * There are more instances of Firebug Menu (e.g. one in Firefox -> Tools -> Web Developer
+ * and one in Firefox 4 (top-left orange button menu) -> Web Developer
+ *
+ * If extensions want to override the menu thay need to iterate all existing instance
+ * using document.querySelectorAll(".fbFirebugMenuPopup") and append new menu items to all
+ * of them. Iteration must be done in the global space (browser.xul)
+ *
+ * The same menu is also used for Firebug Icon Menu (Firebug's toolbar). This menu is cloned
+ * and initialized as soon as Firebug UI is actually loaded. Since it's cloned from the original
+ * (global scope) extensions don't have to extend it (possible new menu items are already there).
+ */
+ overlayFirebugMenu: function(doc)
+ {
+ this.firebugMenuContent =
+ [
+ // Open/close Firebug
+ $menuitem(doc,
+ {
+ id: "menu_firebug_toggleFirebug",
+ label: "firebug.ShowFirebug",
+ tooltiptext: "firebug.menu.tip.Open_Firebug",
+ command: "cmd_firebug_toggleFirebug",
+ key: "key_firebug_toggleFirebug",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_closeFirebug",
+ label: "firebug.Deactivate_Firebug",
+ tooltiptext: "firebug.tip.Deactivate_Firebug",
+ command: "cmd_firebug_closeFirebug",
+ key: "key_firebug_closeFirebug",
+ "class": "fbInternational"
+ }),
+
+ // Firebug UI position
+ $menu(doc,
+ {
+ label: "firebug.uiLocation",
+ tooltiptext: "firebug.menu.tip.UI_Location",
+ "class": "fbInternational"
+ },
+ [
+ $menupopup(doc, {
+ onpopupshowing: "Firebug.browserOverlay.onPositionPopupShowing(this)"
+ })
+ ]),
+
+ $menuseparator(doc),
+
+ // External Editors
+ $menu(doc,
+ {
+ id: "FirebugMenu_OpenWith",
+ label:"firebug.OpenWith",
+ tooltiptext:"firebug.menu.tip.Open_With",
+ "class": "fbInternational",
+ insertafter: "menu_firebug_openActionsSeparator",
+ openFromContext: "true",
+ command: "cmd_firebug_openInEditor"
+ },
+ [
+ $menupopup(doc,{id:"fbFirebugMenu_OpenWith",
+ onpopupshowing: "return Firebug.browserOverlay.onEditorsShowing(this);"})
+ ]),
+
+ // Text Size
+ $menu(doc,
+ {
+ id: "FirebugMenu_TextSize",
+ label: "firebug.TextSize",
+ tooltiptext: "firebug.menu.tip.Text_Size",
+ "class": "fbInternational"
+ },
+ [
+ $menupopup(doc,{},
+ [
+ $menuitem(doc,
+ {
+ id: "menu_firebug_increaseTextSize",
+ label: "firebug.IncreaseTextSize",
+ tooltiptext: "firebug.menu.tip.Increase_Text_Size",
+ command: "cmd_firebug_increaseTextSize",
+ key: "key_firebug_increaseTextSize",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_decreaseTextSize",
+ label: "firebug.DecreaseTextSize",
+ tooltiptext: "firebug.menu.tip.Decrease_Text_Size",
+ command: "cmd_firebug_decreaseTextSize",
+ key: "key_firebug_decreaseTextSize",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_normalTextSize",
+ label: "firebug.NormalTextSize",
+ tooltiptext: "firebug.menu.tip.Normal_Text_Size",
+ command: "cmd_firebug_normalTextSize",
+ key: "key_firebug_normalTextSize",
+ "class": "fbInternational"
+ }),
+ ])
+ ]),
+
+ // Options
+ $menu(doc,
+ {
+ id: "FirebugMenu_Options",
+ label: "firebug.Options",
+ tooltiptext: "firebug.menu.tip.Options",
+ "class": "fbInternational"
+ },
+ [
+ $menupopup(doc,
+ {
+ id: "FirebugMenu_OptionsPopup",
+ onpopupshowing: "return Firebug.browserOverlay.onOptionsShowing(this);"
+ },
+ [
+ $menuitem(doc,
+ {
+ id: "menu_firebug_toggleShowErrorCount",
+ type: "checkbox",
+ label: "firebug.Show_Error_Count",
+ tooltiptext: "firebug.menu.tip.Show_Error_Count",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "showErrorCount",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_showTooltips",
+ type: "checkbox",
+ label: "firebug.menu.Show_Info_Tips",
+ tooltiptext: "firebug.menu.tip.Show_Info_Tips",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "showInfoTips",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_shadeBoxModel",
+ type: "checkbox",
+ label: "ShadeBoxModel",
+ tooltiptext: "inspect.option.tip.Shade_Box_Model",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "shadeBoxModel",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_showQuickInfoBox",
+ type: "checkbox",
+ label: "ShowQuickInfoBox",
+ tooltiptext: "inspect.option.tip.Show_Quick_Info_Box",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "showQuickInfoBox",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_enableA11y",
+ type: "checkbox",
+ label: "firebug.menu.Enable_Accessibility_Enhancements",
+ tooltiptext: "firebug.menu.tip.Enable_Accessibility_Enhancements",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "a11y.enable",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_activateSameOrigin",
+ type: "checkbox",
+ label: "firebug.menu.Activate_Same_Origin_URLs2",
+ tooltiptext: "firebug.menu.tip.Activate_Same_Origin_URLs",
+ oncommand: "Firebug.browserOverlay.onToggleOption(this)",
+ option: "activateSameOrigin",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_toggleOrient",
+ type: "checkbox",
+ label: "firebug.menu.Vertical_Panels",
+ tooltiptext: "firebug.menu.tip.Vertical_Panels",
+ command: "cmd_firebug_toggleOrient",
+ option: "viewPanelOrient",
+ "class": "fbInternational"
+ }),
+ $menuseparator(doc, {id: "menu_firebug_optionsSeparator"}),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_resetAllOptions",
+ label: "firebug.menu.Reset_All_Firebug_Options",
+ tooltiptext: "firebug.menu.tip.Reset_All_Firebug_Options",
+ command: "cmd_firebug_resetAllOptions",
+ "class": "fbInternational"
+ }),
+ ])
+ ]),
+
+ $menuseparator(doc,{id: "FirebugBetweenOptionsAndSites", collapsed: "true"}),
+
+ // Sites
+ $menu(doc,
+ {
+ id: "FirebugMenu_Sites",
+ label: "firebug.menu.Firebug_Online",
+ tooltiptext: "firebug.menu.tip.Firebug_Online",
+ "class": "fbInternational"
+ },
+ [
+ $menupopup(doc,{},
+ [
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugUrlWebsite",
+ label: "firebug.Website",
+ tooltiptext: "firebug.menu.tip.Website",
+ oncommand: "Firebug.chrome.visitWebsite('main')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugUrlExtensions",
+ label: "firebug.menu.Extensions",
+ tooltiptext: "firebug.menu.tip.Extensions",
+ oncommand: "Firebug.chrome.visitWebsite('extensions')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugHelp",
+ label: "firebug.help",
+ tooltiptext: "firebug.menu.tip.help",
+ command: "cmd_firebug_openHelp",
+ key: "key_firebug_help",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugDoc",
+ label: "firebug.Documentation",
+ tooltiptext: "firebug.menu.tip.Documentation",
+ oncommand: "Firebug.chrome.visitWebsite('docs')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugKeyboard",
+ label: "firebug.KeyShortcuts",
+ tooltiptext: "firebug.menu.tip.Key_Shortcuts",
+ oncommand: "Firebug.chrome.visitWebsite('keyboard')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugForums",
+ label: "firebug.Forums",
+ tooltiptext: "firebug.menu.tip.Forums",
+ oncommand: "Firebug.chrome.visitWebsite('discuss')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugIssues",
+ label: "firebug.Issues",
+ tooltiptext: "firebug.menu.tip.Issues",
+ oncommand: "Firebug.chrome.visitWebsite('issues')",
+ "class": "fbInternational"
+ }),
+ $menuitem(doc,
+ {
+ id: "menu_firebug_firebugDonate",
+ label: "firebug.Donate",
+ tooltiptext: "firebug.menu.tip.Donate",
+ oncommand: "Firebug.chrome.visitWebsite('donate')",
+ "class": "fbInternational"
+ }),
+ ])
+ ]),
+
+ $menuseparator(doc, {id: "menu_firebug_miscActionsSeparator", collapsed: "true"}),
+
+ $menuseparator(doc, {id: "menu_firebug_toolsSeparator", collapsed: "true"}),
+
+ $menuitem(doc,
+ {
+ id: "menu_firebug_customizeShortcuts",
+ label: "firebug.menu.Customize_shortcuts",
+ tooltiptext: "firebug.menu.tip.Customize_Shortcuts",
+ command: "cmd_firebug_customizeFBKeys",
+ key: "key_firebug_customizeFBKeys",
+ "class": "fbInternational"
+ }),
+
+ $menuseparator(doc, {id: "menu_firebug_aboutSeparator"}),
+
+ $menuitem(doc, {
+ id: "menu_firebug_about",
+ label: "firebug.About",
+ tooltiptext: "firebug.menu.tip.About",
+ oncommand: "Firebug.browserOverlay.openAboutDialog()",
+ "class": "firebugAbout fbInternational"
+ }),
+ ];
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Global Menu Overlays
+
+ overlayFirefoxMenu: function(doc)
+ {
+ // Firefox page context menu
+ $menupopupOverlay(doc, $(doc, "contentAreaContextMenu"), [
+ $menuseparator(doc),
+ $menuitem(doc,{
+ id: "menu_firebug_firebugInspect",
+ label: "firebug.InspectElementWithFirebug",
+ command: "cmd_firebug_inspect",
+ "class": "menuitem-iconic fbInternational"
+ })
+ ]);
+
+ // Firefox view menu
+ $menupopupOverlay(doc, $(doc, "menu_viewPopup"), [
+ $menuitem(doc, {
+ id: "menu_firebug_viewToggleFirebug",
+ insertbefore: "toggle_taskbar",
+ label: "firebug.Firebug",
+ type: "checkbox",
+ key: "key_firebug_toggleFirebug",
+ command: "cmd_firebug_toggleFirebug",
+ "class": "fbInternational"
+ })
+ ]);
+
+ // SeaMonkey view menu
+ $menupopupOverlay(doc, $(doc, "menu_View_Popup"), [
+ $menuitem(doc, {
+ id: "menu_firebug_viewToggleFirebug",
+ insertafter: "menuitem_fullScreen",
+ label: "firebug.Firebug",
+ type: "checkbox",
+ key: "key_firebug_toggleFirebug",
+ command: "cmd_firebug_toggleFirebug",
+ "class": "menuitem-iconic fbInternational"
+ })
+ ]);
+
+ // Firefox Tools -> Web Developer Menu
+ $menupopupOverlay(doc, $(doc, "menuWebDeveloperPopup"), [
+ $menu(doc, {
+ id: "menu_webDeveloper_firebug",
+ position: 1,
+ label: "firebug.Firebug",
+ "class": "menu-iconic fbInternational"
+ }, [
+ $menupopup(doc, {
+ id: "menu_firebug_firebugMenuPopup",
+ "class": "fbFirebugMenuPopup",
+ onpopupshowing: "return Firebug.browserOverlay.onMenuShowing(this, event);",
+ onpopuphiding: "return Firebug.browserOverlay.onMenuHiding(this, event);"
+ })
+ ]),
+ $menuseparator(doc, {
+ insertafter: "menu_webDeveloper_firebug"
+ })
+ ]);
+
+ // Firefox Button -> Web Developer Menu
+ $menupopupOverlay(doc, $(doc, "appmenu_webDeveloper_popup"), [
+ $splitmenu(doc, {
+ id: "appmenu_firebug",
+ position: 1,
+ command: "cmd_firebug_toggleFirebug",
+ key: "key_firebug_toggleFirebug",
+ label: "firebug.Firebug",
+ iconic: "true",
+ "class": "fbInternational"
+ }, [
+ $menupopup(doc, {
+ id: "appmenu_firebugMenuPopup",
+ "class": "fbFirebugMenuPopup",
+ onpopupshowing: "return Firebug.browserOverlay.onMenuShowing(this, event);",
+ onpopuphiding: "return Firebug.browserOverlay.onMenuHiding(this, event);"
+ })
+ ]),
+ $menuseparator(doc, {
+ insertafter: "appmenu_firebug"
+ })
+ ]);
+
+ // Sea Monkey Tools Menu
+ $menupopupOverlay(doc, $(doc, "toolsPopup"), [
+ $menu(doc, {
+ id: "menu_firebug",
+ insertbefore: "appmenu_webConsole",
+ command: "cmd_firebug_toggleFirebug",
+ key: "key_firebug_toggleFirebug",
+ label: "firebug.Firebug",
+ "class": "menuitem-iconic fbInternational"
+ }, [
+ $menupopup(doc, {
+ id: "toolsmenu_firebugMenuPopup",
+ "class": "fbFirebugMenuPopup",
+ onpopupshowing: "return Firebug.browserOverlay.onMenuShowing(this, event);",
+ onpopupshowing: "return Firebug.browserOverlay.onMenuHiding(this, event);"
+ })
+ ])
+ ]);
+ }
+}
+
+// ********************************************************************************************* //
+// Registration
+
+return BrowserMenu;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.css b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.css
index ef4552c..630971c 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.css
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.css
@@ -44,8 +44,8 @@
border-radius: 3px;
background-color: rgba(255, 0, 0, 0.9);
box-shadow: inset 0px 0px 1px white;
- background-image: -moz-linear-gradient(
- center bottom,
+ background-image: linear-gradient(
+ to top,
#DBE1EB 0%,
#DEE4EB 80%,
#E7EBF3 81%
@@ -125,7 +125,7 @@
}
#fbContentSplitter[dir=reverse]{
- -moz-transform: scale(-1, -1);
+ transform: scale(-1, -1);
}
#fbContentSplitter[orient=vertical] {
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
index 5cebf44..82da56a 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlay.js
@@ -1,296 +1,111 @@
/* See license.txt for terms of usage */
-(function() {
+define([
+ "firebug/lib/trace",
+ "firebug/lib/options",
+ "firebug/lib/locale",
+ "firebug/lib/array",
+ "firebug/firefox/browserOverlayLib",
+ "firebug/firefox/browserCommands",
+ "firebug/firefox/browserMenu",
+ "firebug/firefox/browserToolbar",
+],
+function(FBTrace, Options, Locale, Arr, BrowserOverlayLib, BrowserCommands, BrowserMenu,
+ BrowserToolbar) {
+
+with (BrowserOverlayLib) {
// ********************************************************************************************* //
// Constants
-var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
-Cu.import("resource://firebug/fbtrace.js");
-Cu.import("resource://firebug/loader.js");
+Locale.registerStringBundle("chrome://firebug/locale/firebug.properties");
+Locale.registerStringBundle("chrome://firebug/locale/cookies.properties");
-// Make sure PrefLoader variable doesn't leak into the global scope.
-var prefLoaderScope = {};
-Cu.import("resource://firebug/prefLoader.js", prefLoaderScope);
-var PrefLoader = prefLoaderScope.PrefLoader;
+Cu.import("resource://firebug/loader.js");
+Cu.import("resource://firebug/fbtrace.js");
const firstRunPage = "https://getfirebug.com/firstrun#Firebug ";
-var Locale = Cu.import("resource://firebug/locale.js").Locale;
-
// ********************************************************************************************* //
-// String Bundles
+// BrowserOverlay Implementation
-// Register bundle yet before any Locale.$STR* API is used.
-Locale.registerStringBundle("chrome://firebug/locale/firebug.properties");
-
-// xxxHonza: this needs to be done befor firebug/cookies modules are loaded
-// and it should be part of the cookies directory.
-Locale.registerStringBundle("chrome://firebug/locale/cookies.properties");
-
-// ********************************************************************************************* //
-// Overlay Helpers
-
-function $(id)
+function BrowserOverlay(win)
{
- return document.getElementById(id);
+ this.win = win;
+ this.doc = win.document;
}
-function $$(selector)
+BrowserOverlay.prototype =
{
- return document.querySelectorAll(selector);
-}
+ // When Firebug is disabled or unistalled this elements must be removed from
+ // chrome UI (XUL).
+ nodesToRemove: [],
-function $el(name, attributes, children, parent)
-{
- attributes = attributes || {};
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Initialization
- if (!Array.isArray(children) && !parent)
+ initialize: function(reason)
{
- parent = children;
- children = null;
- }
-
- // localize
- if (attributes.label)
- attributes.label = Locale.$STR(attributes.label);
+ // Expose BrowserOverlayLib object to extensions.
+ this.win.Firebug.BrowserOverlayLib = BrowserOverlayLib;
- if (attributes.tooltiptext)
- attributes.tooltiptext = Locale.$STR(attributes.tooltiptext);
+ // This element (a broadcaster) is storing Firebug state information. Other elements
+ // (like for example the Firebug start button) can watch it and display the info to
+ // the user.
+ $el(this.doc, "broadcaster", {id: "firebugStatus", suspended: true},
+ $(this.doc, "mainBroadcasterSet"));
- // persist
- if (attributes.persist)
- updatePersistedValues(attributes);
+ var node = $stylesheet(this.doc, "chrome://firebug/content/firefox/browserOverlay.css");
+ this.nodesToRemove.push(node);
- var el = document.createElement(name);
- for (var a in attributes)
- el.setAttribute(a, attributes[a]);
-
- for each (var a in children)
- el.appendChild(a);
-
- if (parent)
- {
- if (attributes.position)
- parent.insertBefore(el, parent.children[attributes.position - 1]);
- else
- parent.appendChild(el);
+ this.loadContextMenuOverlay();
+ this.loadFirstRunPage(reason);
- // Mark to remove when Firebug is uninstalled.
- el.setAttribute("firebugRootNode", true);
- }
+ var version = this.getVersion();
- return el;
-}
+ BrowserCommands.overlay(this.doc);
+ BrowserMenu.overlay(this.doc);
+ BrowserToolbar.overlay(this.doc, version);
-function $command(id, oncommand, arg)
-{
- // Wrap the command within a startFirebug call. If Firebug isn't yet loaded
- // this will force it to load.
- oncommand = "Firebug.GlobalUI.startFirebug(function(){" + oncommand + "})";
- if (arg)
- oncommand = "void function(arg){" + oncommand + "}(" + arg + ")";
-
- return $el("command", {
- id: id,
- oncommand: oncommand
- }, $("mainCommandSet"))
-}
+ this.internationalize();
+ this.allPagesActivation();
+ },
-function $key(id, key, modifiers, command, position)
-{
- var attributes =
+ internationalize: function()
{
- id: id,
- modifiers: modifiers,
- command: command,
- position: position
- };
-
- attributes[KeyEvent["DOM_"+key] ? "keycode" : "key"] = key;
-
- return $el("key", attributes, $("mainKeyset"));
-}
-
-function $menupopup(attributes, children, parent)
-{
- return $el("menupopup", attributes, children, parent);
-}
-
-function $menu(attrs, children)
-{
- return $el("menu", attrs, children);
-}
-
-function $menuseparator(attrs)
-{
- return $el("menuseparator", attrs);
-}
-
-function $menuitem(attrs)
-{
- return $el("menuitem", attrs);
-}
-
-function $splitmenu(attrs, children)
-{
- return $el("splitmenu", attrs, children);
-}
-
-function $menupopupOverlay(parent, children)
-{
- if (!parent)
- return;
+ // Internationalize all elements with 'fbInternational' class. Clone
+ // before internationalizing.
+ var elements = Arr.cloneArray(this.doc.getElementsByClassName("fbInternational"));
+ Locale.internationalizeElements(this.doc, elements, ["label", "tooltiptext", "aria-label"]);
+ },
- for (var i=0; i<children.length; ++i)
+ allPagesActivation: function()
{
- var child = children[i];
- var beforeEl;
-
- if (child.getAttribute("position"))
- {
- var pos = child.getAttribute("position");
- beforeEl = parent.children[pos - 1];
- }
- else if (child.getAttribute("insertbefore"))
- {
- var ids = child.getAttribute("insertbefore").split(",");
- for (var j=0; j < ids.length; ++j)
- {
- beforeEl = parent.querySelector("#" + ids[j]);
- if (beforeEl)
- break;
- }
- }
- else if (child.getAttribute("insertafter"))
+ // Load Firebug by default if activation is on for all pages (see issue 5522)
+ if (Options.get("allPagesActivation") == "on" || !Options.get("delayLoad"))
{
- var ids = child.getAttribute("insertafter").split(",");
- for (var j=0; j < ids.length; ++j)
+ var self = this;
+ this.startFirebug(function(Firebug)
{
- beforeEl = parent.querySelector("#" + ids[j]);
- if (beforeEl)
- break;
- }
- if (beforeEl)
- beforeEl = beforeEl.nextSibling;
- }
-
- if (beforeEl)
- parent.insertBefore(child, beforeEl);
- else
- parent.appendChild(child);
+ var browser = Firebug.Firefox.getBrowserForWindow(self.win);
+ var uri = Firebug.Firefox.getCurrentURI();
- // Mark the inserted node to remove it when Firebug is uninstalled.
- child.setAttribute("firebugRootNode", true);
- }
-}
-
-function $toolbarButton(id, attrs, children, defaultPos)
-{
- attrs["class"] = "toolbarbutton-1";
- attrs.firebugRootNode = true;
- attrs.id = id;
+ // Open Firebug UI (e.g. if the annotations say so, issue 5623)
+ if (uri && Firebug.TabWatcher.shouldCreateContext(browser, uri.spec, null))
+ Firebug.toggleBar(true);
- // in seamonkey gNavToolbox is null onload
- var button = $el("toolbarbutton", attrs, children, (gNavToolbox || $("navigator-toolbox")).palette);
-
- var selector = "[currentset^='" + id + ",'],[currentset*='," + id + ",'],[currentset$='," + id + "']";
- var toolbar = document.querySelector(selector);
- if (!toolbar)
- return; // todo defaultPos
-
- var currentset = toolbar.getAttribute("currentset").split(",");
- var i = currentset.indexOf(id) + 1;
-
- var len = currentset.length, beforeEl;
- while (i < len && !(beforeEl = $(currentset[i])))
- i++;
-
- return toolbar.insertItem(id, beforeEl);
-}
-
-function $tooltip(attrs, children)
-{
- return $el("tooltip", attrs, children);
-}
-
-function $label(attrs)
-{
- return $el("label", attrs);
-}
-
-// ********************************************************************************************* //
-// Other Helpers
-
-function updatePersistedValues(options)
-{
- var persist = options.persist.split(",");
- var id = options.id;
- var RDF = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
- var store = PlacesUIUtils.localStore; //this.RDF.GetDataSource("rdf:local-store");
- var root = RDF.GetResource("chrome://browser/content/browser.xul#" + id);
-
- var getPersist = function getPersist(aProperty)
- {
- var property = RDF.GetResource(aProperty);
- var target = store.GetTarget(root, property, true);
-
- if (target instanceof Ci.nsIRDFLiteral)
- return target.Value;
- }
-
- for each(var attr in persist)
- {
- var val = getPersist(attr);
- if (val)
- options[attr] = val;
- }
-}
-
-function cloneArray(arr)
-{
- var newArr = [];
- for (var i=0; i<arr.length; i++)
- newArr.push(arr[i]);
- return newArr;
-}
-
-// ********************************************************************************************* //
-
-Firebug.GlobalUI =
-{
- nodesToRemove: [],
-
- $: $,
- $$: $$,
- $el: $el,
- $menupopupOverlay: $menupopupOverlay,
- $menuitem: $menuitem,
- $menuseparator: $menuseparator,
- $command: $command,
- $key: $key,
- $splitmenu: $splitmenu,
- $tooltip: $tooltip,
- $label: $label,
-
- $stylesheet: function(href)
- {
- var s = document.createProcessingInstruction("xml-stylesheet", 'href="' + href + '"');
- document.insertBefore(s, document.documentElement);
- this.nodesToRemove.push(s);
- },
-
- $script: function(src)
- {
- var script = document.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
- script.src = src;
- script.type = "text/javascript";
- script.setAttribute("firebugRootNode", true);
- document.documentElement.appendChild(script);
+ FBTrace.sysout("Firebug loaded by default since 'allPagesActivation' is on " +
+ "or 'delayLoad' is false");
+ });
+ }
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Load Rest of Firebug
/**
* This method is called by the Fremework to load entire Firebug. It's executed when
@@ -300,35 +115,39 @@ Firebug.GlobalUI =
*/
startFirebug: function(callback)
{
- if (Firebug.waitingForFirstLoad)
+ if (this.win.Firebug.waitingForFirstLoad)
return;
- if (Firebug.isInitialized)
- return callback && callback(Firebug);
+ if (this.win.Firebug.isInitialized)
+ return callback && callback(this.win.Firebug);
if (FBTrace.DBG_INITIALIZE)
FBTrace.sysout("overlay; Load Firebug...", (callback ? callback.toString() : ""));
- Firebug.waitingForFirstLoad = true;
+ this.win.Firebug.waitingForFirstLoad = true;
- var container = $("appcontent");
+ var container = $(this.doc, "appcontent");
// List of Firebug scripts that must be loaded into the global scope (browser.xul)
+ // FBTrace is no longer loaded into the global space.
var scriptSources = [
- "chrome://firebug/content/trace.js",
"chrome://firebug/content/legacy.js",
"chrome://firebug/content/moduleConfig.js"
]
// Create script elements.
- scriptSources.forEach(this.$script);
+ var self = this;
+ scriptSources.forEach(function(url)
+ {
+ $script(self.doc, url);
+ });
// Create Firebug splitter element.
- $el("splitter", {id: "fbContentSplitter", collapsed: "true"}, container);
+ $el(this.doc, "splitter", {id: "fbContentSplitter", collapsed: "true"}, container);
// Create Firebug main frame and container.
- $el("vbox", {id: "fbMainFrame", collapsed: "true", persist: "height,width"}, [
- $el("browser", {
+ $el(this.doc, "vbox", {id: "fbMainFrame", collapsed: "true", persist: "height,width"}, [
+ $el(this.doc, "browser", {
id: "fbMainContainer",
flex: "2",
src: "chrome://firebug/content/firefox/firebugFrame.xul",
@@ -338,17 +157,20 @@ Firebug.GlobalUI =
// When Firebug is fully loaded and initialized it fires a "FirebugLoaded"
// event to the browser document (browser.xul scope). Wait for that to happen.
- document.addEventListener("FirebugLoaded", function onLoad()
+ this.doc.addEventListener("FirebugLoaded", function onLoad()
{
- document.removeEventListener("FirebugLoaded", onLoad, false);
- Firebug.waitingForFirstLoad = false;
+ self.doc.removeEventListener("FirebugLoaded", onLoad, false);
+ self.win.Firebug.waitingForFirstLoad = false;
// xxxHonza: TODO find a better place for notifying extensions
- FirebugLoader.dispatchToScopes("firebugFrameLoad", [Firebug]);
- callback && callback(Firebug);
+ FirebugLoader.dispatchToScopes("firebugFrameLoad", [self.win.Firebug]);
+ callback && callback(self.win.Firebug);
}, false);
},
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug Menu Handlers
+
onOptionsShowing: function(popup)
{
for (var child = popup.firstChild; child; child = child.nextSibling)
@@ -358,7 +180,7 @@ Firebug.GlobalUI =
var option = child.getAttribute("option");
if (option)
{
- var checked = PrefLoader.getPref(option);
+ var checked = Options.get(option);
// xxxHonza: I belive that allPagesActivation could be simple boolean option.
if (option == "allPagesActivation")
@@ -375,31 +197,31 @@ Firebug.GlobalUI =
var option = menuItem.getAttribute("option");
var checked = menuItem.getAttribute("checked") == "true";
- PrefLoader.setPref(option, checked);
+ Options.set(option, checked);
},
- onMenuShowing: function(popup)
+ onMenuShowing: function(popup, event)
{
- // If this popup is already open the event comes from a sub menu, just ignore it.
- if (popup.state == "open")
+ // If the event comes from a sub menu, just ignore it.
+ if (popup != event.target)
return;
while (popup.lastChild)
popup.removeChild(popup.lastChild);
// Generate dynamic content.
- for (var i=0; i<firebugMenuContent.length; i++)
- popup.appendChild(firebugMenuContent[i].cloneNode(true));
+ for (var i=0; i<BrowserMenu.firebugMenuContent.length; i++)
+ popup.appendChild(BrowserMenu.firebugMenuContent[i].cloneNode(true));
var collapsed = "true";
- if (Firebug.chrome)
+ if (this.win.Firebug.chrome)
{
- var fbContentBox = Firebug.chrome.$("fbContentBox");
+ var fbContentBox = this.win.Firebug.chrome.$("fbContentBox");
collapsed = fbContentBox.getAttribute("collapsed");
}
- var currPos = PrefLoader.getPref("framePosition");
- var placement = Firebug.getPlacement ? Firebug.getPlacement() : "";
+ var currPos = Options.get("framePosition");
+ var placement = this.win.Firebug.getPlacement ? this.win.Firebug.getPlacement() : "";
// Switch between "Open Firebug" and "Hide Firebug" label in the popup menu.
var toggleFirebug = popup.querySelector("#menu_firebug_toggleFirebug");
@@ -422,7 +244,7 @@ Firebug.GlobalUI =
// to ensure Firebug isn't closed with close button of detached window
// and 'inDetachedWindow' variable is also used to ensure the menu is
// opened from within the detached window.
- if (currPos == "detached" && Firebug.currentContext &&
+ if (currPos == "detached" && this.win.Firebug.currentContext &&
placement != "minimized" && !inDetachedWindow)
{
toggleFirebug.setAttribute("label", Locale.$STR("firebug.FocusFirebug"));
@@ -435,11 +257,12 @@ Firebug.GlobalUI =
var closeFirebug = popup.querySelector("#menu_firebug_closeFirebug");
if (closeFirebug)
{
- closeFirebug.setAttribute("collapsed", (Firebug.currentContext ? "false" : "true"));
+ closeFirebug.setAttribute("collapsed",
+ (this.win.Firebug.currentContext ? "false" : "true"));
}
// Update About Menu
- var version = Firebug.GlobalUI.getVersion();
+ var version = this.getVersion();
if (version)
{
var node = popup.getElementsByClassName("firebugAbout")[0];
@@ -449,18 +272,18 @@ Firebug.GlobalUI =
}
// Allow Firebug menu customization (see FBTest and FBTrace as an example).
- var event = new CustomEvent("firebugMenuShowing", {detail: popup});
- document.dispatchEvent(event);
+ var event = new this.win.CustomEvent("firebugMenuShowing", {detail: popup});
+ this.doc.dispatchEvent(event);
},
- onMenuHiding: function(popup)
+ onMenuHiding: function(popup, event)
{
- if (popup.state == "open")
+ if (popup != event.target)
return;
// xxxHonza: I don't know why the timeout must be here, but if it isn't
// the icon menu is broken (see issue 5427)
- setTimeout(function()
+ this.win.setTimeout(function()
{
while (popup.lastChild)
popup.removeChild(popup.lastChild);
@@ -473,15 +296,15 @@ Firebug.GlobalUI =
popup.removeChild(popup.lastChild);
// Load Firebug before the position is changed.
- var oncommand = "Firebug.GlobalUI.startFirebug(function(){" +
+ var oncommand = "Firebug.browserOverlay.startFirebug(function(){" +
"Firebug.chrome.setPosition('%pos%')" + "})";
var items = [];
- var currPos = PrefLoader.getPref("framePosition");
+ var currPos = Options.get("framePosition");
for each (var pos in ["detached", "top", "bottom", "left", "right"])
{
var label = pos.charAt(0).toUpperCase() + pos.slice(1);
- var item = $menuitem({
+ var item = $menuitem(this.doc, {
label: Locale.$STR("firebug.menu." + label),
tooltiptext: Locale.$STR("firebug.menu.tip." + label),
type: "radio",
@@ -500,27 +323,25 @@ Firebug.GlobalUI =
openAboutDialog: function()
{
+ var self = this;
+
// Firefox 4.0+
- Components.utils["import"]("resource://gre/modules/AddonManager.jsm");
- AddonManager.getAddonByID("firebug at software.joehewitt.com", function(addon)
+ Cu["import"]("resource://gre/modules/AddonManager.jsm");
+ this.win.AddonManager.getAddonByID("firebug at software.joehewitt.com", function(addon)
{
- openDialog("chrome://mozapps/content/extensions/about.xul", "",
+ self.win.openDialog("chrome://mozapps/content/extensions/about.xul", "",
"chrome,centerscreen,modal", addon);
});
},
- openFirstRunPage: function()
- {
- var version = Firebug.GlobalUI.getVersion();
- url = firstRunPage + version;
- gBrowser.selectedTab = gBrowser.addTab(url, null, null, null);
- },
-
setPosition: function(newPosition)
{
// todo
},
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug Version
+
getVersion: function()
{
var versionURL = "chrome://firebug/content/branch.properties";
@@ -555,772 +376,151 @@ Firebug.GlobalUI =
onEditorsShowing: function(popup)
{
- Firebug.GlobalUI.startFirebug(function()
+ var self = this;
+ this.startFirebug(function()
{
- Firebug.ExternalEditors.onEditorsShowing(popup);
+ self.win.Firebug.ExternalEditors.onEditorsShowing(popup);
});
return true;
- }
-}
-
-// ********************************************************************************************* //
-// Global Firebug CSS
-
-Firebug.GlobalUI.$stylesheet("chrome://firebug/content/firefox/browserOverlay.css");
-
-// ********************************************************************************************* //
-// Broadcasters
-
-/**
- * This element (a broadcaster) is storing Firebug state information. Other elements
- * (like for example the Firebug start button) can watch it and display the info to
- * the user.
- */
-$el("broadcaster", {id: "firebugStatus", suspended: true}, $("mainBroadcasterSet"));
-
-// ********************************************************************************************* //
-// Global Commands
-
-$command("cmd_firebug_closeFirebug", "Firebug.closeFirebug(true);");
-$command("cmd_firebug_toggleInspecting", "if (!Firebug.currentContext) Firebug.toggleBar(true); Firebug.Inspector.toggleInspecting(Firebug.currentContext);");
-$command("cmd_firebug_focusCommandLine", "if (!Firebug.currentContext) Firebug.toggleBar(true); Firebug.CommandLine.focus(Firebug.currentContext);");
-$command("cmd_firebug_toggleFirebug", "Firebug.toggleBar();");
-$command("cmd_firebug_detachFirebug", "Firebug.toggleDetachBar(false, true);");
-$command("cmd_firebug_inspect", "Firebug.Inspector.inspectFromContextMenu(arg);", "document.popupNode");
-$command("cmd_firebug_toggleBreakOn", "if (Firebug.currentContext) Firebug.chrome.breakOnNext(Firebug.currentContext, event);");
-$command("cmd_firebug_toggleDetachFirebug", "Firebug.toggleDetachBar(false, true);");
-$command("cmd_firebug_increaseTextSize", "Firebug.Options.changeTextSize(1);");
-$command("cmd_firebug_decreaseTextSize", "Firebug.Options.changeTextSize(-1);");
-$command("cmd_firebug_normalTextSize", "Firebug.Options.setTextSize(0);");
-$command("cmd_firebug_focusFirebugSearch", "if (Firebug.currentContext) Firebug.Search.onSearchCommand(document);");
-$command("cmd_firebug_customizeFBKeys", "Firebug.ShortcutsModel.customizeShortcuts();");
-$command("cmd_firebug_enablePanels", "Firebug.PanelActivation.enableAllPanels();");
-$command("cmd_firebug_disablePanels", "Firebug.PanelActivation.disableAllPanels();");
-$command("cmd_firebug_clearActivationList", "Firebug.PanelActivation.clearAnnotations();");
-$command("cmd_firebug_clearConsole", "Firebug.Console.clear(Firebug.currentContext);");
-$command("cmd_firebug_allOn", "Firebug.PanelActivation.toggleAll('on');");
-$command("cmd_firebug_toggleOrient", "Firebug.chrome.toggleOrient();");
-$command("cmd_firebug_resetAllOptions", "Firebug.resetAllOptions(true);");
-$command("cmd_firebug_toggleProfiling", ""); //todo
-
-$command("cmd_firebug_openInEditor", "Firebug.ExternalEditors.onContextMenuCommand(event)");
-
-// ********************************************************************************************* //
-// Global Shortcuts
+ },
-(function(globalShortcuts)
-{
- var keyset = $("mainKeyset");
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Page Context Menu Overlay
- globalShortcuts.forEach(function(id)
+ loadContextMenuOverlay: function()
{
- var shortcut = PrefLoader.getPref("key.shortcut." + id);
- var tokens = shortcut.split(" ");
- var key = tokens.pop();
-
- var keyProps = {
- id: "key_firebug_" + id,
- modifiers: tokens.join(","),
- command: "cmd_firebug_" + id,
- position: 1
- };
-
- if (key.length <= 1)
- keyProps.key = key;
- else if (KeyEvent["DOM_"+key])
- keyProps.keycode = key;
-
- $el("key", keyProps, keyset);
- });
-
- keyset.parentNode.insertBefore(keyset, keyset.nextSibling);
-})(["toggleFirebug", "toggleInspecting", "focusCommandLine",
- "detachFirebug", "closeFirebug", "toggleBreakOn"]);
-
-
-/* Used by the global menu, but should be really global shortcuts?
-key_increaseTextSize
-key_decreaseTextSize
-key_normalTextSize
-key_help
-key_toggleProfiling
-key_focusFirebugSearch
-key_customizeFBKeys
-*/
-
-// ********************************************************************************************* //
-// Firebug Start Button Popup Menu
+ var contextMenu = this.win.nsContextMenu;
+ if (typeof(contextMenu) == "undefined")
+ return;
-$menupopupOverlay($("mainPopupSet"), [
- $menupopup(
- {
- id: "fbStatusContextMenu",
- onpopupshowing: "Firebug.GlobalUI.onOptionsShowing(this)"
- },
- [
- $menu(
+ // isTargetAFormControl is removed, see:
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=433168
+ if (typeof(contextMenu.prototype.isTargetAFormControl) != "undefined")
{
- label: "firebug.uiLocation",
- tooltiptext: "firebug.menu.tip.UI_Location",
- "class": "fbInternational"
- },
- [
- $menupopup({onpopupshowing: "Firebug.GlobalUI.onPositionPopupShowing(this)"})
- ]),
- $menuseparator(),
- $menuitem({
- id: "menu_firebug_ClearConsole",
- label: "firebug.ClearConsole",
- tooltiptext: "firebug.ClearTooltip",
- command: "cmd_firebug_clearConsole",
- key: "key_firebug_clearConsole"
- }),
- $menuitem({
- id: "menu_firebug_showErrorCount",
- type: "checkbox",
- label: "firebug.Show_Error_Count",
- tooltiptext: "firebug.menu.tip.Show_Error_Count",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "showErrorCount"
- }),
- $menuseparator(),
- $menuitem({
- id: "menu_firebug_enablePanels",
- label: "firebug.menu.Enable_All_Panels",
- tooltiptext: "firebug.menu.tip.Enable_All_Panels",
- command: "cmd_firebug_enablePanels"
- }),
- $menuitem({
- id: "menu_firebug_disablePanels",
- label: "firebug.menu.Disable_All_Panels",
- tooltiptext: "firebug.menu.tip.Disable_All_Panels",
- command: "cmd_firebug_disablePanels"
- }),
- $menuseparator(),
- $menuitem({
- id: "menu_firebug_AllOn",
- type: "checkbox",
- label: "On_for_all_web_pages",
- tooltiptext: "firebug.menu.tip.On_for_all_Web_Sites",
- command: "cmd_firebug_allOn",
- option: "allPagesActivation"
- }),
- $menuitem({
- id: "menu_firebug_clearActivationList",
- label: "firebug.menu.Clear_Activation_List",
- tooltiptext: "firebug.menu.tip.Clear_Activation_List",
- command: "cmd_firebug_clearActivationList"
- })
- ])
-])
-
-// ********************************************************************************************* //
-// Firebug Global Menu
-
-/**
- * There are more instances of Firebug Menu (e.g. one in Firefox -> Tools -> Web Developer
- * and one in Firefox 4 (top-left orange button menu) -> Web Developer
- *
- * If extensions want to override the menu thay need to iterate all existing instance
- * using document.querySelectorAll(".fbFirebugMenuPopup") and append new menu items to all
- * of them. Iteration must be done in the global space (browser.xul)
- *
- * The same menu is also used for Firebug Icon Menu (Firebug's toolbar). This menu is cloned
- * and initialized as soon as Firebug UI is actually loaded. Since it's cloned from the original
- * (global scope) extensions don't have to extend it (possible new menu items are already there).
- */
-var firebugMenuContent = [
-
- // Open/close Firebug
- $menuitem(
- {
- id: "menu_firebug_toggleFirebug",
- label: "firebug.ShowFirebug",
- tooltiptext: "firebug.menu.tip.Open_Firebug",
- command: "cmd_firebug_toggleFirebug",
- key: "key_firebug_toggleFirebug",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_closeFirebug",
- label: "firebug.Deactivate_Firebug",
- tooltiptext: "firebug.tip.Deactivate_Firebug",
- command: "cmd_firebug_closeFirebug",
- key: "key_firebug_closeFirebug",
- "class": "fbInternational"
- }),
-
- // Firebug UI position
- $menu(
- {
- label: "firebug.uiLocation",
- tooltiptext: "firebug.menu.tip.UI_Location",
- "class": "fbInternational"
- },
- [
- $menupopup({onpopupshowing: "Firebug.GlobalUI.onPositionPopupShowing(this)"})
- ]),
-
- $menuseparator(),
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=433168
+ var setTargetOriginal = this.setTargetOriginal = contextMenu.prototype.setTarget;
+ contextMenu.prototype.setTarget = function(aNode, aRangeParent, aRangeOffset)
+ {
+ setTargetOriginal.apply(this, arguments);
- // External Editors
- $menu(
- {
- id: "FirebugMenu_OpenWith",
- label:"firebug.OpenWith",
- tooltiptext:"firebug.menu.tip.Open_With",
- "class": "fbInternational",
- insertafter: "menu_firebug_openActionsSeparator",
- openFromContext: "true",
- command: "cmd_firebug_openInEditor"
- },
- [
- $menupopup({id:"fbFirebugMenu_OpenWith",
- onpopupshowing: "return Firebug.GlobalUI.onEditorsShowing(this);"})
- ]),
+ if (this.isTargetAFormControl(aNode))
+ this.shouldDisplay = true;
+ };
+ }
- // Text Size
- $menu(
- {
- id: "FirebugMenu_TextSize",
- label: "firebug.TextSize",
- tooltiptext: "firebug.menu.tip.Text_Size",
- "class": "fbInternational"
- },
- [
- $menupopup({},
- [
- $menuitem(
- {
- id: "menu_firebug_increaseTextSize",
- label: "firebug.IncreaseTextSize",
- tooltiptext: "firebug.menu.tip.Increase_Text_Size",
- command: "cmd_firebug_increaseTextSize",
- key: "key_firebug_increaseTextSize",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_decreaseTextSize",
- label: "firebug.DecreaseTextSize",
- tooltiptext: "firebug.menu.tip.Decrease_Text_Size",
- command: "cmd_firebug_decreaseTextSize",
- key: "key_firebug_decreaseTextSize",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_normalTextSize",
- label: "firebug.NormalTextSize",
- tooltiptext: "firebug.menu.tip.Normal_Text_Size",
- command: "cmd_firebug_normalTextSize",
- key: "key_firebug_normalTextSize",
- "class": "fbInternational"
- }),
- ])
- ]),
-
- // Options
- $menu(
- {
- id: "FirebugMenu_Options",
- label: "firebug.Options",
- tooltiptext: "firebug.menu.tip.Options",
- "class": "fbInternational"
- },
- [
- $menupopup(
+ // Hide built-in inspector if the pref says so.
+ var initItemsOriginal = this.initItemsOriginal = contextMenu.prototype.initItems;
+ contextMenu.prototype.initItems = function()
{
- id: "FirebugMenu_OptionsPopup",
- onpopupshowing: "return Firebug.GlobalUI.onOptionsShowing(this);"
- },
- [
- $menuitem(
- {
- id: "menu_firebug_toggleShowErrorCount",
- type: "checkbox",
- label: "firebug.Show_Error_Count",
- tooltiptext: "firebug.menu.tip.Show_Error_Count",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "showErrorCount",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_showTooltips",
- type: "checkbox",
- label: "firebug.menu.Show_Info_Tips",
- tooltiptext: "firebug.menu.tip.Show_Info_Tips",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "showInfoTips",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_shadeBoxModel",
- type: "checkbox",
- label: "ShadeBoxModel",
- tooltiptext: "inspect.option.tip.Shade_Box_Model",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "shadeBoxModel",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_showQuickInfoBox",
- type: "checkbox",
- label: "ShowQuickInfoBox",
- tooltiptext: "inspect.option.tip.Show_Quick_Info_Box",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "showQuickInfoBox",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_enableA11y",
- type: "checkbox",
- label: "firebug.menu.Enable_Accessibility_Enhancements",
- tooltiptext: "firebug.menu.tip.Enable_Accessibility_Enhancements",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "a11y.enable",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_activateSameOrigin",
- type: "checkbox",
- label: "firebug.menu.Activate_Same_Origin_URLs2",
- tooltiptext: "firebug.menu.tip.Activate_Same_Origin_URLs",
- oncommand: "Firebug.GlobalUI.onToggleOption(this)",
- option: "activateSameOrigin",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_toggleOrient",
- type: "checkbox",
- label: "firebug.menu.Vertical_Panels",
- tooltiptext: "firebug.menu.tip.Vertical_Panels",
- command: "cmd_firebug_toggleOrient",
- option: "viewPanelOrient",
- "class": "fbInternational"
- }),
- $menuseparator({id: "menu_firebug_optionsSeparator"}),
- $menuitem(
+ initItemsOriginal.apply(this, arguments);
+
+ // Hide built-in inspector menu item if the pref "extensions.firebug.hideDefaultInspector"
+ // says so. Note that there is also built-in preference "devtools.inspector.enable" that
+ // can be used for the same purpose.
+ var hideInspect = Options.get("hideDefaultInspector");
+ if (hideInspect)
{
- id: "menu_firebug_resetAllOptions",
- label: "firebug.menu.Reset_All_Firebug_Options",
- tooltiptext: "firebug.menu.tip.Reset_All_Firebug_Options",
- command: "cmd_firebug_resetAllOptions",
- "class": "fbInternational"
- }),
- ])
- ]),
-
- $menuseparator({id: "FirebugBetweenOptionsAndSites", collapsed: "true"}),
-
- // Sites
- $menu(
- {
- id: "FirebugMenu_Sites",
- label: "firebug.menu.Firebug_Online",
- tooltiptext: "firebug.menu.tip.Firebug_Online",
- "class": "fbInternational"
+ this.showItem("inspect-separator", false);
+ this.showItem("context-inspect", false);
+ }
+ }
},
- [
- $menupopup({},
- [
- $menuitem(
- {
- id: "menu_firebug_firebugUrlWebsite",
- label: "firebug.Website",
- tooltiptext: "firebug.menu.tip.Website",
- oncommand: "Firebug.chrome.visitWebsite('main')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugUrlExtensions",
- label: "firebug.menu.Extensions",
- tooltiptext: "firebug.menu.tip.Extensions",
- oncommand: "Firebug.chrome.visitWebsite('extensions')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugHelp",
- label: "firebug.help",
- tooltiptext: "firebug.menu.tip.help",
- command: "cmd_firebug_openHelp",
- key: "key_firebug_help",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugDoc",
- label: "firebug.Documentation",
- tooltiptext: "firebug.menu.tip.Documentation",
- oncommand: "Firebug.chrome.visitWebsite('docs')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugKeyboard",
- label: "firebug.KeyShortcuts",
- tooltiptext: "firebug.menu.tip.Key_Shortcuts",
- oncommand: "Firebug.chrome.visitWebsite('keyboard')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugForums",
- label: "firebug.Forums",
- tooltiptext: "firebug.menu.tip.Forums",
- oncommand: "Firebug.chrome.visitWebsite('discuss')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugIssues",
- label: "firebug.Issues",
- tooltiptext: "firebug.menu.tip.Issues",
- oncommand: "Firebug.chrome.visitWebsite('issues')",
- "class": "fbInternational"
- }),
- $menuitem(
- {
- id: "menu_firebug_firebugDonate",
- label: "firebug.Donate",
- tooltiptext: "firebug.menu.tip.Donate",
- oncommand: "Firebug.chrome.visitWebsite('donate')",
- "class": "fbInternational"
- }),
- ])
- ]),
- $menuseparator({id: "menu_firebug_miscActionsSeparator", collapsed: "true"}),
-
- $menuseparator({id: "menu_firebug_toolsSeparator", collapsed: "true"}),
-
- $menuitem(
+ unloadContextMenuOverlay: function()
{
- id: "menu_firebug_customizeShortcuts",
- label: "firebug.menu.Customize_shortcuts",
- tooltiptext: "firebug.menu.tip.Customize_Shortcuts",
- command: "cmd_firebug_customizeFBKeys",
- key: "key_firebug_customizeFBKeys",
- "class": "fbInternational"
- }),
-
- $menuseparator({id: "menu_firebug_aboutSeparator"}),
-
- $menuitem({
- id: "menu_firebug_about",
- label: "firebug.About",
- tooltiptext: "firebug.menu.tip.About",
- oncommand: "Firebug.GlobalUI.openAboutDialog()",
- "class": "firebugAbout fbInternational"
- }),
-];
-
-// ********************************************************************************************* //
-// Global Menu Overlays
-
-// Firefox page context menu
-$menupopupOverlay($("contentAreaContextMenu"), [
- $menuseparator(),
- $menuitem({
- id: "menu_firebug_firebugInspect",
- label: "firebug.InspectElementWithFirebug",
- command: "cmd_firebug_inspect",
- "class": "menuitem-iconic fbInternational"
- })
-]);
-
-// Firefox view menu
-$menupopupOverlay($("menu_viewPopup"), [
- $menuitem({
- id: "menu_firebug_viewToggleFirebug",
- insertbefore: "toggle_taskbar",
- label: "firebug.Firebug",
- type: "checkbox",
- key: "key_firebug_toggleFirebug",
- command: "cmd_firebug_toggleFirebug",
- "class": "fbInternational"
- })
-]);
-
-// SeaMonkey view menu
-$menupopupOverlay($("menu_View_Popup"), [
- $menuitem({
- id: "menu_firebug_viewToggleFirebug",
- insertafter: "menuitem_fullScreen",
- label: "firebug.Firebug",
- type: "checkbox",
- key: "key_firebug_toggleFirebug",
- command: "cmd_firebug_toggleFirebug",
- "class": "menuitem-iconic fbInternational"
- })
-]);
-
-// Firefox Tools -> Web Developer Menu
-$menupopupOverlay($("menuWebDeveloperPopup"), [
- $menu({
- id: "menu_webDeveloper_firebug",
- position: 1,
- label: "firebug.Firebug",
- "class": "menu-iconic fbInternational"
- }, [
- $menupopup({
- id: "menu_firebug_firebugMenuPopup",
- "class": "fbFirebugMenuPopup",
- onpopupshowing: "return Firebug.GlobalUI.onMenuShowing(this);",
- onpopuphiding: "return Firebug.GlobalUI.onMenuHiding(this);"
- })
- ]),
- $menuseparator({
- insertafter: "menu_webDeveloper_firebug"
- })
-]);
-
-// Firefox Button -> Web Developer Menu
-$menupopupOverlay($("appmenu_webDeveloper_popup"), [
- $splitmenu({
- id: "appmenu_firebug",
- position: 1,
- command: "cmd_firebug_toggleFirebug",
- key: "key_firebug_toggleFirebug",
- label: "firebug.Firebug",
- iconic: "true",
- "class": "fbInternational"
- }, [
- $menupopup({
- id: "appmenu_firebugMenuPopup",
- "class": "fbFirebugMenuPopup",
- onpopupshowing: "return Firebug.GlobalUI.onMenuShowing(this);",
- onpopuphiding: "return Firebug.GlobalUI.onMenuHiding(this);"
- })
- ]),
- $menuseparator({
- insertafter: "appmenu_firebug"
- })
-]);
-
-// Sea Monkey Tools Menu
-$menupopupOverlay($("toolsPopup"), [
- $menu({
- id: "menu_firebug",
- insertbefore: "appmenu_webConsole",
- command: "cmd_firebug_toggleFirebug",
- key: "key_firebug_toggleFirebug",
- label: "firebug.Firebug",
- "class": "menuitem-iconic fbInternational"
- }, [
- $menupopup({
- id: "toolsmenu_firebugMenuPopup",
- "class": "fbFirebugMenuPopup",
- onpopupshowing: "return Firebug.GlobalUI.onMenuShowing(this);",
- onpopupshowing: "return Firebug.GlobalUI.onMenuHiding(this);"
- })
- ])
-]);
-
-// ********************************************************************************************* //
-// Firefox Toolbar Buttons
-
-$toolbarButton("firebug-inspectorButton", {
- label: "firebug.Inspect",
- tooltiptext: "firebug.InspectElement",
- observes: "cmd_firebug_toggleInspecting",
- style: "list-style-image: url(chrome://firebug/skin/inspect.png);" +
- "-moz-image-region: rect(0, 16px, 16px, 0);"
-});
-
-// Start Button Tooltip. As soon as Firebug is fully loaded, the tooltip content will be
-// generated by firebug/firefox/start-button/startButtonOverlay module.
-$menupopupOverlay($("mainPopupSet"), [
- $tooltip({
- "class": "firebugButtonTooltip",
- id: "firebug-buttonTooltip",
- orient: "vertical",
- }, [
- $label({
- "class": "version",
- "value": "Firebug " + Firebug.GlobalUI.getVersion()
- }),
- $label({
- "class": "status",
- "value": Locale.$STR("startbutton.tip.deactivated")
- })
- ])
-]);
-
-// TODO: why contextmenu doesn't work without cloning
-$toolbarButton("firebug-button", {
- label: "firebug.Firebug",
- tooltip: "firebug-buttonTooltip",
- type: "menu-button",
- command: "cmd_firebug_toggleFirebug",
- contextmenu: "fbStatusContextMenu",
- observes: "firebugStatus",
- style: "list-style-image: url(chrome://firebug/skin/firebug16.png)"
-}, [$("fbStatusContextMenu").cloneNode(true)]);
-
-// Appends Firebug start button into Firefox toolbar automatically after installation.
-// The button is appended only once - if the user removes it, it isn't appended again.
-// TODO: merge into $toolbarButton?
-// toolbarpalette check is for seamonkey, where it is in the document
-if ((!$("firebug-button") || $("firebug-button").parentNode.tagName == "toolbarpalette")
- && !PrefLoader.getPref("toolbarCustomizationDone"))
-{
- PrefLoader.setPref("toolbarCustomizationDone", true);
+ var contextMenu = this.win.nsContextMenu;
+ if (typeof(contextMenu) == "undefined")
+ return;
- // Get the current navigation bar button set (a string of button IDs) and append
- // ID of the Firebug start button into it.
- var startButtonId = "firebug-button";
- var navBarId = "nav-bar";
- var navBar = $(navBarId);
- var currentSet = navBar.currentSet;
+ contextMenu.prototype.setTarget = this.setTargetOriginal;
+ contextMenu.prototype.initItems = this.initItemsOriginal;
+ },
- if (FBTrace.DBG_INITIALIZE)
- FBTrace.sysout("Startbutton; curSet (before modification): " + currentSet);
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // First Run Page
- // Append only if the button is not already there.
- var curSet = currentSet.split(",");
- if (curSet.indexOf(startButtonId) == -1)
+ loadFirstRunPage: function(reason)
{
- navBar.insertItem(startButtonId);
- navBar.setAttribute("currentset", navBar.currentSet);
- navBar.ownerDocument.persist("nav-bar", "currentset");
-
- // Check whether insertItem really works
- var curSet = navBar.currentSet.split(",");
- if (curSet.indexOf(startButtonId) == -1)
- FBTrace.sysout("Startbutton; navBar.insertItem doesn't work", curSet);
+ if (this.checkFirebugVersion(Options.get("currentVersion")) <= 0)
+ return;
- if (FBTrace.DBG_INITIALIZE)
- FBTrace.sysout("Startbutton; curSet (after modification): " + navBar.currentSet);
+ // Do not show the first run page when Firebug is being updated. It'll be displayed
+ // the next time the browser is restarted
+ // # ADDON_UPGRADE == 7
+ if (reason == 7)
+ return;
- try
+ // Open the page in the top most window, so the user can see it immediately.
+ var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+ if (wm.getMostRecentWindow("navigator:browser") == this.win.top)
{
- // The current global scope is browser.xul.
- BrowserToolboxCustomizeDone(true);
- }
- catch (e)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("startButton; appendToToolbar EXCEPTION " + e, e);
- }
- }
-
- // Don't forget to show the navigation bar - just in case it's hidden.
- navBar.removeAttribute("collapsed");
- document.persist(navBarId, "collapsed");
-}
-
-// ********************************************************************************************* //
-// Localization
-
-// Internationalize all elements with 'fbInternational' class. Clone before internationalizing.
-var elements = cloneArray(document.getElementsByClassName("fbInternational"));
-Locale.internationalizeElements(document, elements, ["label", "tooltiptext", "aria-label"]);
-
-// ********************************************************************************************* //
-// First Run Page
+ // Update the preference to make sure the page is not displayed again.
+ // To avoid being annoying when Firefox crashes, forcibly save it, too.
+ var version = this.getVersion();
+ Options.set("currentVersion", version);
-var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
-
-function checkFirebugVersion(currentVersion)
-{
- if (!currentVersion)
- return 1;
+ if (Options.get("showFirstRunPage"))
+ {
+ var self = this;
+ var timeout = this.win.setTimeout(function()
+ {
+ if (self.win.closed)
+ return;
- var version = Firebug.GlobalUI.getVersion();
+ self.openFirstRunPage(self.win);
+ }, 1000);
- // Use Firefox comparator service.
- var versionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].
- getService(Ci.nsIVersionComparator);
- return versionChecker.compare(version, currentVersion);
-}
+ this.win.addEventListener("unload", function()
+ {
+ clearTimeout(timeout);
+ }, false);
+ }
+ }
+ },
-if (checkFirebugVersion(PrefLoader.getPref("currentVersion")) > 0)
-{
- // Open the page in the top most window, so the user can see it immediately.
- if (wm.getMostRecentWindow("navigator:browser") == window.top)
+ openFirstRunPage: function(win)
{
- // Don't forget to update the preference, so the page is not displayed again
- var version = Firebug.GlobalUI.getVersion();
- PrefLoader.setPref("currentVersion", version);
+ var version = this.getVersion();
+ var url = firstRunPage + version;
- if (PrefLoader.getPref("showFirstRunPage"))
+ var browser = win.gBrowser;
+ if (!browser)
{
- var timeout = setTimeout(function()
- {
- if (window.closed)
- return;
-
- Firebug.GlobalUI.openFirstRunPage();
- }, 1000);
-
- window.addEventListener("unload", function()
- {
- clearTimeout(timeout);
- }, false);
+ FBTrace.sysout("browserOverlay.openFirstRunPage; ERROR there is no gBrowser!");
+ return;
}
- }
-}
-// ********************************************************************************************* //
-// Firefox Page Context Menu
+ // Open the firstRunPage in background
+ /*gBrowser.selectedTab = */browser.addTab(url, null, null, null);
-if (typeof(nsContextMenu) != "undefined")
-{
- // https://bugzilla.mozilla.org/show_bug.cgi?id=433168
- var setTargetOriginal = nsContextMenu.prototype.setTarget;
- nsContextMenu.prototype.setTarget = function(aNode, aRangeParent, aRangeOffset)
- {
- setTargetOriginal.apply(this, arguments);
- if (this.isTargetAFormControl(aNode))
- this.shouldDisplay = true;
- };
-
- // Hide built-in inspector if the pref says so.
- var initItemsOriginal = nsContextMenu.prototype.initItems;
- nsContextMenu.prototype.initItems = function()
+ // Make sure prefs are stored, otherwise the firstRunPage would be displayed
+ // again if Firefox crashes.
+ this.win.setTimeout(function()
+ {
+ Options.forceSave();
+ }, 400);
+ },
+
+ checkFirebugVersion: function(currentVersion)
{
- initItemsOriginal.apply(this, arguments);
+ if (!currentVersion)
+ return 1;
- // Hide built-in inspector menu item if the pref "extensions.firebug.hideDefaultInspector"
- // says so. Note that there is also built-in preference "devtools.inspector.enable" that
- // can be used for the same purpose.
- var hideInspect = PrefLoader.getPref("hideDefaultInspector");
- if (hideInspect)
- {
- this.showItem("inspect-separator", false);
- this.showItem("context-inspect", false);
- }
- }
-}
+ var version = this.getVersion();
-// ********************************************************************************************* //
-// All Pages Activation" is on
+ // Use Firefox comparator service.
+ var versionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
-// Load Firebug by default if activation is on for all pages (see issue 5522)
-if (PrefLoader.getPref("allPagesActivation") == "on" || !PrefLoader.getPref("delayLoad"))
-{
- Firebug.GlobalUI.startFirebug(function()
- {
- FBTrace.sysout("Firebug loaded by default since 'allPagesActivation' is on " +
- "or 'delayLoad' is false");
- });
+ return versionChecker.compare(version, currentVersion);
+ }
}
// ********************************************************************************************* //
+// Registration
-if (FBTrace.DBG_INITIALIZE)
- FBTrace.sysout("Firebug global overlay applied");
+return BrowserOverlay;
// ********************************************************************************************* //
-})();
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js
new file mode 100644
index 0000000..e5e967e
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserOverlayLib.js
@@ -0,0 +1,272 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/lib/trace",
+ "firebug/lib/locale",
+],
+function(FBTrace, Locale) {
+
+// ********************************************************************************************* //
+// Constants
+
+var Cc = Components.classes;
+var Ci = Components.interfaces;
+var Cu = Components.utils;
+
+// ********************************************************************************************* //
+// Overlay Helpers
+
+var BrowserOverlayLib =
+{
+ $: function(doc, id)
+ {
+ return doc.getElementById(id);
+ },
+
+ $$: function(doc, selector)
+ {
+ return doc.querySelectorAll(selector);
+ },
+
+ $el: function(doc, name, attributes, children, parent)
+ {
+ if (!(doc instanceof Ci.nsIDOMDocument))
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("browserOvelayLib.$el; No document!")
+ return;
+ }
+
+ attributes = attributes || {};
+
+ if (!Array.isArray(children) && !parent)
+ {
+ parent = children;
+ children = null;
+ }
+
+ // localize
+ if (attributes.label)
+ attributes.label = Locale.$STR(attributes.label);
+
+ if (attributes.tooltiptext)
+ attributes.tooltiptext = Locale.$STR(attributes.tooltiptext);
+
+ // persist
+ if (attributes.persist)
+ updatePersistedValues(doc, attributes);
+
+ var el = doc.createElement(name);
+ for (var a in attributes)
+ el.setAttribute(a, attributes[a]);
+
+ for each (var a in children)
+ el.appendChild(a);
+
+ if (parent)
+ {
+ if (attributes.position)
+ parent.insertBefore(el, parent.children[attributes.position - 1]);
+ else
+ parent.appendChild(el);
+
+ // Mark to remove when Firebug is uninstalled.
+ el.setAttribute("firebugRootNode", true);
+ }
+
+ return el;
+ },
+
+ $command: function(doc, id, oncommand, arg)
+ {
+ // Wrap the command within a startFirebug call. If Firebug isn't yet loaded
+ // this will force it to load.
+ oncommand = "Firebug.browserOverlay.startFirebug(function(){" + oncommand + "})";
+ if (arg)
+ oncommand = "void function(arg){" + oncommand + "}(" + arg + ")";
+
+ return this.$el(doc, "command", {
+ id: id,
+ oncommand: oncommand
+ }, this.$(doc, "mainCommandSet"))
+ },
+
+ $key: function(doc, id, key, modifiers, command, position)
+ {
+ var attributes = {
+ id: id,
+ modifiers: modifiers,
+ command: command,
+ position: position
+ };
+
+ attributes[KeyEvent["DOM_" + key] ? "keycode" : "key"] = key;
+
+ return this.$el(doc, "key", attributes, $(doc, "mainKeyset"));
+ },
+
+ $menupopup: function(doc, attributes, children, parent)
+ {
+ return this.$el(doc, "menupopup", attributes, children, parent);
+ },
+
+ $menu: function(doc, attrs, children)
+ {
+ return this.$el(doc, "menu", attrs, children);
+ },
+
+ $menuseparator: function(doc, attrs)
+ {
+ return this.$el(doc, "menuseparator", attrs);
+ },
+
+ $menuitem: function(doc, attrs)
+ {
+ return this.$el(doc, "menuitem", attrs);
+ },
+
+ $splitmenu: function(doc, attrs, children)
+ {
+ return this.$el(doc, "splitmenu", attrs, children);
+ },
+
+ $menupopupOverlay: function(doc, parent, children)
+ {
+ if (!parent)
+ return;
+
+ for (var i=0; i<children.length; ++i)
+ {
+ var child = children[i];
+ var beforeEl;
+
+ if (child.getAttribute("position"))
+ {
+ var pos = child.getAttribute("position");
+ beforeEl = parent.children[pos - 1];
+ }
+ else if (child.getAttribute("insertbefore"))
+ {
+ var ids = child.getAttribute("insertbefore").split(",");
+ for (var j=0; j < ids.length; ++j)
+ {
+ beforeEl = parent.querySelector("#" + ids[j]);
+ if (beforeEl)
+ break;
+ }
+ }
+ else if (child.getAttribute("insertafter"))
+ {
+ var ids = child.getAttribute("insertafter").split(",");
+ for (var j=0; j < ids.length; ++j)
+ {
+ beforeEl = parent.querySelector("#" + ids[j]);
+ if (beforeEl)
+ break;
+ }
+ if (beforeEl)
+ beforeEl = beforeEl.nextSibling;
+ }
+
+ if (beforeEl)
+ parent.insertBefore(child, beforeEl);
+ else
+ parent.appendChild(child);
+
+ // Mark the inserted node to remove it when Firebug is uninstalled.
+ child.setAttribute("firebugRootNode", true);
+ }
+ },
+
+ $toolbarButton: function(doc, id, attrs, children, defaultPos)
+ {
+ attrs["class"] = "toolbarbutton-1";
+ attrs.firebugRootNode = true;
+ attrs.id = id;
+
+ // in seamonkey gNavToolbox is null onload
+ var button = this.$el(doc, "toolbarbutton", attrs, children,
+ (doc.defaultView.gNavToolbox || this.$(doc, "navigator-toolbox")).palette);
+
+ var selector = "[currentset^='" + id + ",'],[currentset*='," + id +
+ ",'],[currentset$='," + id + "']";
+
+ var toolbar = doc.querySelector(selector);
+ if (!toolbar)
+ return; // todo defaultPos
+
+ var currentset = toolbar.getAttribute("currentset").split(",");
+ var i = currentset.indexOf(id) + 1;
+
+ var len = currentset.length, beforeEl;
+ while (i < len && !(beforeEl = this.$(doc, currentset[i])))
+ i++;
+
+ return toolbar.insertItem(id, beforeEl);
+ },
+
+ $tooltip: function(doc, attrs, children)
+ {
+ return this.$el(doc, "tooltip", attrs, children);
+ },
+
+ $label: function(doc, attrs)
+ {
+ return this.$el(doc, "label", attrs);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Stylesheets & Scripts
+
+ $stylesheet: function(doc, href)
+ {
+ var s = doc.createProcessingInstruction("xml-stylesheet", 'href="' + href + '"');
+ doc.insertBefore(s, doc.documentElement);
+ return s;
+ },
+
+ $script: function(doc, src)
+ {
+ var script = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
+ script.src = src;
+ script.type = "text/javascript";
+ script.setAttribute("firebugRootNode", true);
+ doc.documentElement.appendChild(script);
+ },
+}
+
+// ********************************************************************************************* //
+// Helpers
+
+function updatePersistedValues(doc, options)
+{
+ var persist = options.persist.split(",");
+ var id = options.id;
+ var RDF = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ var store = doc.defaultView.PlacesUIUtils.localStore; //this.RDF.GetDataSource("rdf:local-store");
+ var root = RDF.GetResource("chrome://browser/content/browser.xul#" + id);
+
+ var getPersist = function getPersist(aProperty)
+ {
+ var property = RDF.GetResource(aProperty);
+ var target = store.GetTarget(root, property, true);
+
+ if (target instanceof Ci.nsIRDFLiteral)
+ return target.Value;
+ }
+
+ for each(var attr in persist)
+ {
+ var val = getPersist(attr);
+ if (val)
+ options[attr] = val;
+ }
+}
+
+// ********************************************************************************************* //
+// Registration
+
+return BrowserOverlayLib;
+
+// ********************************************************************************************* //
+});
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/browserToolbar.js b/trace/FBTrace/chrome/firebug/content/firefox/browserToolbar.js
new file mode 100644
index 0000000..ebd7c87
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/content/firefox/browserToolbar.js
@@ -0,0 +1,136 @@
+/* See license.txt for terms of usage */
+
+define([
+ "firebug/lib/trace",
+ "firebug/lib/options",
+ "firebug/lib/locale",
+ "firebug/firefox/browserOverlayLib",
+],
+function(FBTrace, Options, Locale, BrowserOverlayLib) {
+with (BrowserOverlayLib) {
+
+// ********************************************************************************************* //
+// Constants
+
+// ********************************************************************************************* //
+// Firefox Toolbar Buttons
+
+var BrowserToolbar =
+{
+ overlay: function(doc, version)
+ {
+ this.overlayToolbarButtons(doc, version);
+ this.customizeToolbar(doc);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Firebug Start Button Popup Menu
+
+ overlayToolbarButtons: function(doc, version)
+ {
+ $toolbarButton(doc, "firebug-inspectorButton", {
+ label: "firebug.Inspect",
+ tooltiptext: "firebug.InspectElement",
+ observes: "cmd_firebug_toggleInspecting",
+ style: "list-style-image: url(chrome://firebug/skin/inspect.png);" +
+ "-moz-image-region: rect(0, 16px, 16px, 0);"
+ });
+
+ // Start Button Tooltip. As soon as Firebug is fully loaded, the tooltip content will be
+ // generated by firebug/firefox/start-button/startButtonOverlay module.
+ $menupopupOverlay(doc, $(doc, "mainPopupSet"), [
+ $tooltip(doc, {
+ "class": "firebugButtonTooltip",
+ id: "firebug-buttonTooltip",
+ orient: "vertical",
+ }, [
+ $label(doc, {
+ "class": "version",
+ "value": "Firebug " + version
+ }),
+ $label(doc, {
+ "class": "status",
+ "value": Locale.$STR("startbutton.tip.deactivated")
+ })
+ ])
+ ]);
+
+ // TODO: why contextmenu doesn't work without cloning
+ $toolbarButton(doc, "firebug-button", {
+ label: "firebug.Firebug",
+ tooltip: "firebug-buttonTooltip",
+ type: "menu-button",
+ command: "cmd_firebug_toggleFirebug",
+ contextmenu: "fbStatusContextMenu",
+ observes: "firebugStatus",
+ style: "list-style-image: url(chrome://firebug/skin/firebug16.png)"
+ }, [$(doc, "fbStatusContextMenu").cloneNode(true)]);
+ },
+
+ customizeToolbar: function(doc)
+ {
+ // Appends Firebug start button into Firefox toolbar automatically after installation.
+ // The button is appended only once - if the user removes it, it isn't appended again.
+ // TODO: merge into $toolbarButton?
+ // toolbarpalette check is for seamonkey, where it is in the document
+ if ((!$(doc, "firebug-button") ||
+ $(doc, "firebug-button").parentNode.tagName == "toolbarpalette")
+ && !Options.get("toolbarCustomizationDone"))
+ {
+ Options.set("toolbarCustomizationDone", true);
+
+ // Get the current navigation bar button set (a string of button IDs) and append
+ // ID of the Firebug start button into it.
+ var startButtonId = "firebug-button";
+ var navBarId = "nav-bar";
+ var navBar = $(doc, navBarId);
+ var currentSet = navBar.currentSet;
+
+ if (FBTrace.DBG_INITIALIZE)
+ FBTrace.sysout("Startbutton; curSet (before modification): " + currentSet);
+
+ // Append only if the button is not already there.
+ var curSet = currentSet.split(",");
+ if (curSet.indexOf(startButtonId) == -1)
+ {
+ navBar.insertItem(startButtonId);
+ navBar.setAttribute("currentset", navBar.currentSet);
+ navBar.ownerDocument.persist("nav-bar", "currentset");
+
+ // Check whether insertItem really works
+ var curSet = navBar.currentSet.split(",");
+ if (curSet.indexOf(startButtonId) == -1)
+ FBTrace.sysout("Startbutton; navBar.insertItem doesn't work", curSet);
+
+ if (FBTrace.DBG_INITIALIZE)
+ {
+ FBTrace.sysout("Startbutton; curSet (after modification): " +
+ navBar.currentSet);
+ }
+
+ try
+ {
+ // The current global scope is browser.xul.
+ BrowserToolboxCustomizeDone(true);
+ }
+ catch (e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("startButton; appendToToolbar EXCEPTION " + e, e);
+ }
+ }
+
+ // Don't forget to show the navigation bar - just in case it's hidden.
+ navBar.removeAttribute("collapsed");
+ doc.persist(navBarId, "collapsed");
+ }
+ },
+}
+
+// ********************************************************************************************* //
+// Registration
+
+return BrowserToolbar;
+
+// ********************************************************************************************* //
+}});
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/changeeditor.js b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/changeeditor.js
index 6ca76f0..06e1322 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/changeeditor.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/changeeditor.js
@@ -29,7 +29,7 @@ function onLoad()
origImage = FBL.getIconURLForFile(item.executable);
try
{
- var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(item.executable);
document.getElementById("executable").file = file;
origLabel = file.leafName.replace(".exe","");
@@ -123,7 +123,7 @@ function onAccept()
try
{
- var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(item.executable);
if (!file.isExecutable())
throw "NotAnExecutable";
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/editors.xul b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/editors.xul
index 0c1b6aa..8da86d3 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/editors.xul
+++ b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/editors.xul
@@ -9,13 +9,15 @@
id="firebug-external-editors"
width="600" height="300"
title="firebug.Configure_Editors"
- onload="gEditorManager.init();gUrlMappingManager.init()"
- onunload="gEditorManager.uninit();gUrlMappingManager.uninit()"
+ onload="gEditorManager.init();/*gUrlMappingManager.init()*/"
+ onunload="gEditorManager.uninit();/*gUrlMappingManager.uninit()*/"
persist="screenX screenY width height">
- <script src="chrome://firebug/content/xpcom.js"/>
- <script src="chrome://firebug/content/firefox/external-editors/editors.js"/>
+ <script type="application/x-javascript" src="chrome://firebug/content/xpcom.js"/>
+ <script type="application/x-javascript"
+ src="chrome://firebug/content/firefox/external-editors/editors.js"/>
+ <!--
<tabbox flex="1" class="contentPane">
<tabs>
<tab label="editors.Configured_Firebug_Editors" class="fbInternational"/>
@@ -23,49 +25,56 @@
</tabs>
<tabpanels flex="1">
<tabpanel flex="1" orient="vertical">
- <tree id="editorsList" flex="1" seltype="single"
- lastSelected="0" persist="lastSelected"
- onselect="gEditorManager.onSelectionChanged();"
- ondblclick="gEditorManager.changeEditorHandler();">
- <treecols>
- <treecol id="editorName" ignoreincolumnpicker="true" flex="1"
- persist="width" class="fbInternational"
- label="editors.Editor"/>
- <splitter class="tree-splitter" />
- <treecol id="editorExecutable" flex="1"
- persist="width" class="fbInternational"
- label="editors.Executable"/>
- <splitter class="tree-splitter" />
- <treecol id="editorParams" flex="1"
- persist="width" class="fbInternational"
- label="editors.Launch_Arguments"/>
- </treecols>
- <treechildren/>
- </tree>
+ -->
+ <vbox flex="1" class="contentPane">
+ <label id="actionsIntro" control="editorsList"
+ value="editors.Configured_Firebug_Editors" class="fbInternational"/>
+ <separator class="thin"/>
+ <tree id="editorsList" flex="1" seltype="single"
+ lastSelected="0" persist="lastSelected"
+ onselect="gEditorManager.onSelectionChanged();"
+ ondblclick="gEditorManager.changeEditorHandler();">
+ <treecols>
+ <treecol id="editorName" ignoreincolumnpicker="true" flex="1"
+ persist="width" class="fbInternational"
+ label="editors.Editor"/>
+ <splitter class="tree-splitter" />
+ <treecol id="editorExecutable" flex="1"
+ persist="width" class="fbInternational"
+ label="editors.Executable"/>
+ <splitter class="tree-splitter" />
+ <treecol id="editorParams" flex="1"
+ persist="width" class="fbInternational"
+ label="editors.Launch_Arguments"/>
+ </treecols>
+ <treechildren/>
+ </tree>
+ </vbox>
- <separator class="thin"/>
+ <separator class="thin"/>
- <hbox>
- <hbox flex="1" class="actionButtons">
- <button id="addEditor" icon="add"
- label="editors.Add" class="fbInternational"
- oncommand="gEditorManager.addEditorHandler();"/>
- <button id="removeEditor" icon="remove"
- label="editors.Remove" class="fbInternational"
- oncommand="gEditorManager.removeEditorHandler();"/>
- <button id="changeEditor"
- label="editors.Change" class="fbInternational"
- oncommand="gEditorManager.changeEditorHandler();"/>
- <button id="moveUpEditor"
- label="editors.Move_Up" class="fbInternational"
- oncommand="gEditorManager.moveUpEditorHandler();"/>
- <spacer flex="1"/>
- <button id="closeDialogButton"
- oncommand="close();" icon="close"
- label="editors.Close" class="fbInternational"/>
- </hbox>
- <resizer dir="bottomright"/>
- </hbox>
+ <hbox>
+ <hbox flex="1" class="actionButtons">
+ <button id="addEditor" icon="add"
+ label="editors.Add" class="fbInternational"
+ oncommand="gEditorManager.addEditorHandler();"/>
+ <button id="removeEditor" icon="remove"
+ label="editors.Remove" class="fbInternational"
+ oncommand="gEditorManager.removeEditorHandler();"/>
+ <button id="changeEditor"
+ label="editors.Change" class="fbInternational"
+ oncommand="gEditorManager.changeEditorHandler();"/>
+ <button id="moveUpEditor"
+ label="editors.Move_Up" class="fbInternational"
+ oncommand="gEditorManager.moveUpEditorHandler();"/>
+ <spacer flex="1"/>
+ <button id="closeDialogButton"
+ oncommand="close();" icon="close"
+ label="editors.Close" class="fbInternational"/>
+ </hbox>
+ <resizer dir="bottomright"/>
+ </hbox>
+ <!--
</tabpanel>
<tabpanel flex="1" orient="vertical">
<textbox id="urlMappings" multiline="true" flex="1" wrap="off"
@@ -79,5 +88,6 @@
</tabpanel>
</tabpanels>
</tabbox>
+ -->
</window>
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/externalEditors.js b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/externalEditors.js
index 3fe7775..d287134 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/external-editors/externalEditors.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/external-editors/externalEditors.js
@@ -30,7 +30,6 @@ const DirService = Xpcom.CCSV("@mozilla.org/file/directory_service;1",
"nsIDirectoryServiceProvider");
const NS_OS_TEMP_DIR = "TmpD"
const nsIFile = Ci.nsIFile;
-const nsILocalFile = Ci.nsILocalFile;
const nsISafeOutputStream = Ci.nsISafeOutputStream;
const nsIURI = Ci.nsIURI;
@@ -237,11 +236,17 @@ Firebug.ExternalEditors = Obj.extend(Firebug.Module,
var item = doc.createElement("menu");
item.setAttribute("type", "splitmenu");
item.setAttribute("iconic", "true");
- item.setAttribute("oncommand", "Firebug.ExternalEditors.onContextMenuCommand(event)");
+
+ item.addEventListener("command", function(event)
+ {
+ Firebug.ExternalEditors.onContextMenuCommand(event);
+ });
var menupopup = doc.createElement("menupopup");
- menupopup.setAttribute("onpopupshowing",
- "return Firebug.ExternalEditors.onEditorsShowing(this)");
+ menupopup.addEventListener("popupshowing", function(event)
+ {
+ return Firebug.ExternalEditors.onEditorsShowing(this)
+ });
item.appendChild(menupopup);
return item;
@@ -535,7 +540,7 @@ Firebug.ExternalEditors = Obj.extend(Firebug.Module,
if (System.getPlatformName() == "WINNT")
lpath = lpath.replace(/\//g, "\\");
- var file = Xpcom.QI(temporaryDirectory.clone(), nsILocalFile);
+ var file = Xpcom.QI(temporaryDirectory.clone(), nsIFile);
file.appendRelativePath(lpath);
if (!file.exists())
file.create(nsIFile.NORMAL_FILE_TYPE, 0664);
@@ -561,7 +566,7 @@ Firebug.ExternalEditors = Obj.extend(Firebug.Module,
{
try
{
- var file = Xpcom.CCIN("@mozilla.org/file/local;1", "nsILocalFile");
+ var file = Xpcom.CCIN("@mozilla.org/file/local;1", "nsIFile");
for (var i = 0; i < temporaryFiles.length; ++i)
{
file.initWithPath(temporaryFiles[i]);
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/firebug.xul b/trace/FBTrace/chrome/firebug/content/firefox/firebug.xul
index 47476b8..dc35fa6 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/firebug.xul
+++ b/trace/FBTrace/chrome/firebug/content/firefox/firebug.xul
@@ -10,7 +10,6 @@
persist="screenX,screenY,width,height,sizemode"
onload="importFirebug()" onunload="" onclose="return exportFirebug();">
-
<vbox flex="2" id="fbMainFrame" collapsed="false">
<browser id="fbMainContainer" flex="2" src="" disablehistory="true" />
</vbox>
@@ -23,6 +22,8 @@
<key oncommand="doFirefoxCommand('Browser:ReloadSkipCache')" key='r' modifiers='accel,shift'/>
</keyset>
+ <script type="application/x-javascript" src="chrome://firebug/content/trace.js"/>
+
<script type="application/x-javascript">
doFirefoxCommand = function(id)
{
@@ -31,8 +32,9 @@
importFirebug = function()
{
- var Firebug = opener.Firebug, fbc = Firebug.chrome;
+ FBTrace.sysout("firebug.xul; importFirebug");
+ var Firebug = opener.Firebug, fbc = Firebug.chrome;
if (fbc.inDetachedScope)
{
exportFirebug = null;
@@ -51,8 +53,7 @@
fbc.originalBrowser.contentWindow.onunload = function()
{
- fbc.shutdown();
- fbc.window.top.close();
+ window.close();
}
fbc.onDetach();
@@ -61,6 +62,8 @@
exportFirebug = function()
{
+ FBTrace.sysout("firebug.xul; exportFirebug");
+
exportFirebug = null;
var Firebug = opener.Firebug, fbc = Firebug.chrome;
diff --git a/trace/FBTrace/chrome/firebug/content/firefox/start-button/startButtonOverlay.js b/trace/FBTrace/chrome/firebug/content/firefox/start-button/startButtonOverlay.js
index 75c0290..0ae7c0f 100644
--- a/trace/FBTrace/chrome/firebug/content/firefox/start-button/startButtonOverlay.js
+++ b/trace/FBTrace/chrome/firebug/content/firefox/start-button/startButtonOverlay.js
@@ -7,9 +7,10 @@ define([
"firebug/lib/locale",
"firebug/lib/events",
"firebug/lib/dom",
- "firebug/lib/options"
+ "firebug/lib/options",
+ "firebug/firefox/browserOverlayLib",
],
-function(Obj, Firebug, Firefox, Locale, Events, Dom, Options) {
+function(Obj, Firebug, Firefox, Locale, Events, Dom, Options, BrowserOverlayLib) {
// ********************************************************************************************* //
// Constants
@@ -58,20 +59,22 @@ Firebug.StartButton = Obj.extend(Firebug.Module,
onTooltipShowing: function(event)
{
var tooltip = event.target;
+ var doc = tooltip.ownerDocument;
+
Dom.eraseNode(tooltip);
- with (Firebug.GlobalUI)
+ with (BrowserOverlayLib)
{
- tooltip.appendChild($label({
+ tooltip.appendChild($label(doc, {
"class": "version",
value: "Firebug " + Firebug.getVersion()
}));
- var status = $el("hbox");
+ var status = $el(doc, "hbox");
tooltip.appendChild(status);
var suspended = Firebug.getSuspended();
- status.appendChild($label({
+ status.appendChild($label(doc, {
"class": "status",
value: suspended ? Locale.$STR("startbutton.tip.deactivated") :
Locale.$STRP("plural.Total_Firebugs2", [Firebug.TabWatcher.contexts.length])
@@ -80,14 +83,14 @@ Firebug.StartButton = Obj.extend(Firebug.Module,
if (suspended)
return;
- status.appendChild($label({
+ status.appendChild($label(doc, {
"class": "placement",
value: "(" + Locale.$STR(Firebug.getPlacement()) + ")"
}));
if (Firebug.allPagesActivation == "on")
{
- tooltip.appendChild($label({
+ tooltip.appendChild($label(doc, {
"class": "alwaysOn",
value: Locale.$STR("enablement.on") + " " +
Locale.$STR("enablement.for_all_pages")
@@ -95,7 +98,7 @@ Firebug.StartButton = Obj.extend(Firebug.Module,
}
// Panel enablement status info
- tooltip.appendChild($label({
+ tooltip.appendChild($label(doc, {
"class": "enablement",
value: Locale.$STR("enablement.Panel_activation_status")
}));
@@ -104,15 +107,15 @@ Firebug.StartButton = Obj.extend(Firebug.Module,
for (var i=0; i<statuses.length; i++)
{
var status = statuses[i];
- var parent = $el("hbox");
+ var parent = $el(doc, "hbox");
tooltip.appendChild(parent);
- parent.appendChild($label({
+ parent.appendChild($label(doc, {
"class": "panelName " + status.status,
value: status.name + ":"
}));
- parent.appendChild($label({
+ parent.appendChild($label(doc, {
"class": "panelStatus " + status.status,
value: status.statusLabel
}));
diff --git a/trace/FBTrace/chrome/firebug/content/html/highlighter.css b/trace/FBTrace/chrome/firebug/content/html/highlighter.css
index cd9a93d..a8aad6c 100644
--- a/trace/FBTrace/chrome/firebug/content/html/highlighter.css
+++ b/trace/FBTrace/chrome/firebug/content/html/highlighter.css
@@ -14,8 +14,8 @@
min-height: 0 !important;
max-height: none !important;
position: fixed !important;
- -moz-transform: rotate(0deg) !important;
- -moz-transform-origin: 50% 50% !important;
+ transform: rotate(0deg) !important;
+ transform-origin: 50% 50% !important;
border-radius: 0 !important;
box-shadow: none !important;
background: transparent none !important;
@@ -126,4 +126,4 @@
.fbProxyElement {
position: fixed !important;
pointer-events: auto !important;
-}
\ No newline at end of file
+}
diff --git a/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js b/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
index 0318c9f..1d71977 100644
--- a/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/html/htmlPanel.js
@@ -20,6 +20,7 @@ define([
"firebug/lib/persist",
"firebug/chrome/menu",
"firebug/lib/url",
+ "firebug/css/cssModule",
"firebug/css/cssReps",
"firebug/js/breakpoint",
"firebug/editor/editor",
@@ -30,7 +31,7 @@ define([
],
function(Obj, Firebug, Domplate, FirebugReps, Locale, HTMLLib, Events,
SourceLink, Css, Dom, Win, Options, Xpath, Str, Xml, Arr, Persist, Menu,
- Url, CSSInfoTip) {
+ Url, CSSModule, CSSInfoTip) {
with (Domplate) {
@@ -346,6 +347,30 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
null : ["link", "script", "style"]);
},
+ updateNodeVisibility: function(node)
+ {
+ var wasHidden = node.classList.contains("nodeHidden");
+ if (!Xml.isVisible(node.repObject))
+ {
+ // Hide this node and, through CSS, every descendant.
+ node.classList.add("nodeHidden");
+ }
+ else if (wasHidden)
+ {
+ // The node has changed state from hidden to shown. While in the
+ // hidden state, some descendants may have been explicitly marked
+ // with .nodeHidden (not just through CSS inheritance), so we need
+ // to recheck the visibility of those.
+ node.classList.remove("nodeHidden");
+ var desc = Arr.cloneArray(node.getElementsByClassName("nodeHidden"));
+ for (var i = 0; i < desc.length; ++i)
+ {
+ if (Xml.isVisible(desc[i].repObject))
+ desc[i].classList.remove("nodeHidden");
+ }
+ }
+ },
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
getElementSourceText: function(node)
@@ -479,10 +504,7 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
if (!objectNodeBox)
return;
- if (Xml.isVisible(objectNodeBox.repObject))
- Css.removeClass(objectNodeBox, "nodeHidden");
- else
- Css.setClass(objectNodeBox, "nodeHidden");
+ this.updateNodeVisibility(objectNodeBox);
if (attrChange == MODIFICATION || attrChange == ADDITION)
{
@@ -667,6 +689,10 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
{
this.ioBox.removeChildBox(parentNodeBox, target);
+ // Special case for docType.
+ if (target instanceof HTMLHtmlElement)
+ this.ioBox.removeChildBox(parentNodeBox, target.parentNode.doctype);
+
this.highlightMutation(parentNodeBox, parentNodeBox, "mutated");
}
else
@@ -694,6 +720,13 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
this.ioBox.insertChildBoxBefore(parentNodeBox, target, nextSibling) :
this.ioBox.appendChildBox(parentNodeBox, target);
+ // Special case for docType.
+ if (target instanceof HTMLHtmlElement)
+ {
+ this.ioBox.insertChildBoxBefore(parentNodeBox,
+ target.parentNode.doctype, target);
+ }
+
this.highlightMutation(objectBox, objectBox, "mutated");
}
}
@@ -1161,6 +1194,74 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
},
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // CSS Listener
+
+ updateVisibilitiesForSelectorInSheet: function(sheet, selector)
+ {
+ if (!selector)
+ return;
+ var doc = (sheet && sheet.ownerNode && sheet.ownerNode.ownerDocument);
+ if (!doc)
+ return;
+
+ var affected = doc.querySelectorAll(selector);
+ if (!affected.length || !this.ioBox.isInExistingRoot(affected[0]))
+ return;
+
+ for (var i = 0; i < affected.length; ++i)
+ {
+ var node = this.ioBox.findObjectBox(affected[i]);
+ if (node)
+ this.updateNodeVisibility(node);
+ }
+ },
+
+ updateVisibilitiesForRule: function(rule)
+ {
+ this.updateVisibilitiesForSelectorInSheet(rule.parentStyleSheet, rule.selectorText);
+ },
+
+ cssPropAffectsVisibility: function(propName)
+ {
+ // Pretend that "display" is the only property which affects visibility,
+ // which is a half-truth. We could make this more technically correct
+ // by unconditionally returning true, but forcing a synchronous reflow
+ // and computing offsetWidth/Height on up to every element on the page
+ // isn't worth it.
+ return (propName === "display");
+ },
+
+ cssTextAffectsVisibility: function(cssText)
+ {
+ return (cssText.indexOf("display:") !== -1);
+ },
+
+ onAfterCSSDeleteRule: function(styleSheet, cssText, selector)
+ {
+ if (this.cssTextAffectsVisibility(cssText))
+ this.updateVisibilitiesForSelectorInSheet(styleSheet, selector);
+ },
+
+ onCSSInsertRule: function(styleSheet, cssText, ruleIndex)
+ {
+ if (this.cssTextAffectsVisibility(cssText))
+ this.updateVisibilitiesForRule(styleSheet.cssRules[ruleIndex]);
+ },
+
+ onCSSSetProperty: function(style, propName, propValue, propPriority, prevValue,
+ prevPriority, rule, baseText)
+ {
+ if (this.cssPropAffectsVisibility(propName))
+ this.updateVisibilitiesForRule(rule);
+ },
+
+ onCSSRemoveProperty: function(style, propName, prevValue, prevPriority, rule, baseText)
+ {
+ if (this.cssPropAffectsVisibility(propName))
+ this.updateVisibilitiesForRule(rule);
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// extends Panel
name: "html",
@@ -1181,6 +1282,7 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
this.onKeyPress = Obj.bind(this.onKeyPress, this);
Firebug.Panel.initialize.apply(this, arguments);
+ Firebug.CSSModule.addListener(this);
},
destroy: function(state)
@@ -1199,6 +1301,7 @@ Firebug.HTMLPanel.prototype = Obj.extend(WalkingPanel,
delete this.inspectorHistory[i];
delete this.inspectorHistory;
+ Firebug.CSSModule.removeListener(this);
this.unregisterMutationListeners();
},
@@ -2262,6 +2365,25 @@ AttributeEditor.prototype = domplate(Firebug.InlineEditor.prototype,
var emptyAttr = {name: "", value: ""};
var sibling = insertWhere == "before" ? target.previousSibling : target;
return AttrTag.insertAfter({attr: emptyAttr}, sibling);
+ },
+
+ getInitialValue: function(target, value)
+ {
+ if (value == "")
+ return value;
+
+ var element = Firebug.getRepObject(target);
+ if (element && element instanceof window.Element)
+ {
+ // If object that was clicked to edit was
+ // attribute value, not attribute name.
+ if (Css.hasClass(target, "nodeValue"))
+ {
+ var attributeName = Dom.getPreviousByClass(target, "nodeName").textContent;
+ return element.getAttribute(attributeName);
+ }
+ }
+ return value;
}
});
diff --git a/trace/FBTrace/chrome/firebug/content/html/insideOutBox.js b/trace/FBTrace/chrome/firebug/content/html/insideOutBox.js
index a3ab406..51b5ab2 100644
--- a/trace/FBTrace/chrome/firebug/content/html/insideOutBox.js
+++ b/trace/FBTrace/chrome/firebug/content/html/insideOutBox.js
@@ -96,6 +96,7 @@ Firebug.InsideOutBox.prototype =
{
if (FBTrace.DBG_HTML)
FBTrace.sysout("insideOutBox.select object:"+object, object);
+
var objectBox = this.createObjectBox(object);
this.selectObjectBox(objectBox, forceOpen);
diff --git a/trace/FBTrace/chrome/firebug/content/html/inspector.js b/trace/FBTrace/chrome/firebug/content/html/inspector.js
index 55e15ba..4b21ca1 100644
--- a/trace/FBTrace/chrome/firebug/content/html/inspector.js
+++ b/trace/FBTrace/chrome/firebug/content/html/inspector.js
@@ -8,6 +8,7 @@ define([
"firebug/lib/locale",
"firebug/lib/events",
"firebug/lib/wrapper",
+ "firebug/lib/array",
"firebug/lib/css",
"firebug/lib/dom",
"firebug/lib/xml",
@@ -15,7 +16,7 @@ define([
"firebug/lib/system",
"firebug/html/highlighterCache"
],
-function(Obj, Firebug, Firefox, FirebugReps, Locale, Events, Wrapper, Css, Dom, Xml,
+function(Obj, Firebug, Firefox, FirebugReps, Locale, Events, Wrapper, Arr, Css, Dom, Xml,
Win, System, HighlighterCache) {
// ********************************************************************************************* //
@@ -24,6 +25,7 @@ function(Obj, Firebug, Firefox, FirebugReps, Locale, Events, Wrapper, Css, Dom,
const inspectDelay = 200;
const highlightCSS = "chrome://firebug/content/html/highlighter.css";
const ident = HighlighterCache.ident;
+const Cu = Components.utils;
// ********************************************************************************************* //
// Globals
@@ -70,7 +72,7 @@ Firebug.Inspector = Obj.extend(Firebug.Module,
var i, elt, elementLen, oldContext, usingColorArray;
var highlighter = highlightType ? getHighlighter(highlightType) : this.defaultHighlighter;
- if (!elementArr || !FirebugReps.Arr.isArray(elementArr, context.window))
+ if (!elementArr || !Arr.isArrayLike(elementArr))
{
// highlight a single element
if (!elementArr || !Dom.isElement(elementArr) ||
@@ -124,12 +126,6 @@ Firebug.Inspector = Obj.extend(Firebug.Module,
if (oldContext.window && oldContext.window.document)
{
highlighter.unhighlight(oldContext);
-
- if (oldContext.inspectorMouseMove)
- {
- Events.removeEventListener(oldContext.window.document, "mousemove",
- oldContext.inspectorMouseMove, true);
- }
}
}, inspectDelay);
}
@@ -144,7 +140,7 @@ Firebug.Inspector = Obj.extend(Firebug.Module,
}
this.clearAllHighlights();
- usingColorArray = FirebugReps.Arr.isArray(colorObj, context.window);
+ usingColorArray = Arr.isArray(colorObj);
if (context && context.window && context.window.document)
{
@@ -1244,19 +1240,19 @@ Firebug.Inspector.FrameHighlighter.prototype =
{
cs = body.ownerDocument.defaultView.getComputedStyle(element, null);
- if (cs.MozTransform && cs.MozTransform != "none")
- css += "-moz-transform: "+cs.MozTransform+"!important;" +
- "-moz-transform-origin: "+cs.MozTransformOrigin+"!important;";
+ if (cs.transform && cs.transform != "none")
+ css += "transform: " + cs.transform + " !important;" +
+ "transform-origin: " + cs.transformOrigin + " !important;";
if (cs.borderRadius)
- css += "border-radius: "+cs.borderRadius+"!important;";
+ css += "border-radius: " + cs.borderRadius + " !important;";
if (cs.borderTopLeftRadius)
- css += "border-top-left-radius: "+cs.borderTopLeftRadius+"!important;";
+ css += "border-top-left-radius: " + cs.borderTopLeftRadius + " !important;";
if (cs.borderTopRightRadius)
- css += "border-top-right-radius: "+cs.borderTopRightRadius+"!important;";
+ css += "border-top-right-radius: " + cs.borderTopRightRadius + " !important;";
if (cs.borderBottomRightRadius)
- css += "border-bottom-right-radius: "+cs.borderBottomRightRadius+"!important;";
+ css += "border-bottom-right-radius: " + cs.borderBottomRightRadius + " !important;";
if (cs.borderBottomLeftRadius)
- css += "border-bottom-left-radius: "+cs.borderBottomLeftRadius+"!important;";
+ css += "border-bottom-left-radius: " + cs.borderBottomLeftRadius + " !important;";
}
css += "box-shadow: 0 0 2px 2px "+
(colorObj && colorObj.border ? colorObj.border : "highlight")+"!important;";
@@ -1640,12 +1636,25 @@ function getNonFrameBody(elt)
function attachStyles(context, body)
{
+ if (FBTrace.DBG_ERRORS && context.highlightStyle && Cu.isDeadWrapper(context.highlightStyle))
+ FBTrace.sysout("inspector.attachStyles; ERROR can't access dead object");
+
var doc = body.ownerDocument;
+
if (!context.highlightStyle)
context.highlightStyle = Css.createStyleSheet(doc, highlightCSS);
- if (!context.highlightStyle.parentNode || context.highlightStyle.ownerDocument != doc)
- Css.addStyleSheet(body.ownerDocument, context.highlightStyle);
+ var parentNode = context.highlightStyle.parentNode;
+ if (!parentNode || context.highlightStyle.ownerDocument != doc)
+ {
+ // Clone the <style> element so, it doesn't adopt the new document as parent.
+ // The other doc (except of the original one that is always the top doc) comes
+ // from an iframe, which can be reloaded (within the context life-time) and
+ // consequent access to context.highlightStyle would fire "can't access dead object"
+ // exception (see issue 6013).
+ var style = parentNode ? context.highlightStyle.cloneNode(true) : context.highlightStyle;
+ Css.addStyleSheet(body.ownerDocument, style);
+ }
}
function createProxiesForDisabledElements(body)
@@ -1669,9 +1678,9 @@ function createProxiesForDisabledElements(body)
div.className = "firebugResetStyles fbProxyElement";
css = moveImp(null, rect.left, rect.top + body.scrollTop) + resizeImp(null, rect.width, rect.height);
- if (cs.MozTransform && cs.MozTransform != "none")
- css += "-moz-transform:" + cs.MozTransform + "!important;" +
- "-moz-transform-origin:" + cs.MozTransformOrigin + "!important;";
+ if (cs.transform && cs.transform != "none")
+ css += "transform:" + cs.transform + " !important;" +
+ "transform-origin:" + cs.transformOrigin + " !important;";
if (cs.borderRadius)
css += "border-radius:" + cs.borderRadius + " !important;";
if (cs.borderTopLeftRadius)
diff --git a/trace/FBTrace/chrome/firebug/content/html/layout.js b/trace/FBTrace/chrome/firebug/content/html/layout.js
index df2246f..b13a3c5 100644
--- a/trace/FBTrace/chrome/firebug/content/html/layout.js
+++ b/trace/FBTrace/chrome/firebug/content/html/layout.js
@@ -25,90 +25,170 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
{
tag:
DIV({"class": "outerLayoutBox"},
- DIV({"class": "positionLayoutBox $outerTopMode $outerRightMode $outerBottomMode $outerLeftMode focusGroup"},
+ DIV({"class": "positionLayoutBox $outerTopMode $outerRightMode $outerBottomMode "+
+ "$outerLeftMode focusGroup"},
DIV({"class": "layoutEdgeTop layoutEdge"}),
DIV({"class": "layoutEdgeRight layoutEdge"}),
DIV({"class": "layoutEdgeBottom layoutEdge"}),
DIV({"class": "layoutEdgeLeft layoutEdge"}),
DIV({"class": "layoutLabelBottom layoutLabel layoutLabelPosition"},
- SPAN({"class": "layoutPosition layoutCaption",
- "aria-label": Locale.$STR("a11y.layout.position")},
- Locale.$STR("position") + ": " + "$position"),
- SPAN({"class": "layoutBoxSizing layoutCaption",
- "aria-label": Locale.$STR("a11y.layout.box-sizing")},
- Locale.$STR("a11y.layout.box-sizing") + ": " + "$boxSizing"),
- SPAN({"class": "layoutZIndex v$zIndex",
- "aria-label": Locale.$STR("a11y.layout.z-index")},
- "z: " + "$zIndex")
+ SPAN({"class": "layoutPosition layoutCaption",
+ "aria-label": Locale.$STR("a11y.layout.position")},
+ Locale.$STR("position") + ": " + "$position"),
+ SPAN({"class": "layoutBoxSizing layoutCaption",
+ "aria-label": Locale.$STR("a11y.layout.box-sizing")},
+ Locale.$STR("a11y.layout.box-sizing") + ": " + "$boxSizing"),
+ SPAN({"class": "layoutZIndex", $invisible: "$zIndex|isInvisible",
+ "aria-label": Locale.$STR("a11y.layout.z-index")},
+ "z: " + "$zIndex")
),
- DIV({"class": "layoutLabelTop layoutLabel v$outerTop"},
- SPAN({"class": "editable focusStart", 'aria-label' : Locale.$STR('a11y.layout.position top')}, '$outerTop')
+ DIV({"class": "layoutLabelTop layoutLabel",
+ $invisible: "$outerTop|isInvisible"},
+ SPAN({"class": "layoutLabelOuterTop editable focusStart",
+ "aria-label": Locale.$STR("a11y.layout.position top")},
+ "$outerTop"
+ )
),
- DIV({"class": "layoutLabelRight layoutLabel v$outerRight"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.position right')}, '$outerRight')
+ DIV({"class": "layoutLabelRight layoutLabel",
+ $invisible: "$outerRight|isInvisible"},
+ SPAN({"class": "layoutLabelOuterRight editable",
+ "aria-label": Locale.$STR("a11y.layout.position right")},
+ "$outerRight"
+ )
),
- DIV({"class": "layoutLabelBottom layoutLabel v$outerBottom"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.position bottom')}, '$outerBottom')
+ DIV({"class": "layoutLabelBottom layoutLabel",
+ $invisible: "$outerBottom|isInvisible"},
+ SPAN({"class": "layoutLabelOuterBottom editable",
+ "aria-label": Locale.$STR("a11y.layout.position bottom")},
+ "$outerBottom"
+ )
),
- DIV({"class": "layoutLabelLeft layoutLabel v$outerLeft"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.position left')}, '$outerLeft')
+ DIV({"class": "layoutLabelLeft layoutLabel",
+ $invisible: "$outerLeft|isInvisible"},
+ SPAN({"class": "layoutLabelOuterLeft editable",
+ "aria-label": Locale.$STR("a11y.layout.position left")},
+ "$outerLeft"
+ )
),
- DIV({"class": "layoutCaption"}, '$outerLabel'),
+ DIV({"class": "outerLabel layoutCaption"}, "$outerLabel"),
DIV({"class": "marginLayoutBox layoutBox editGroup focusGroup"},
DIV({"class": "layoutCaption"}, Locale.$STR("LayoutMargin")),
- DIV({"class": "layoutLabelTop layoutLabel v$marginTop"},
- SPAN({"class": "editable focusStart", 'aria-label' : Locale.$STR('a11y.layout.margin top')}, '$marginTop')
+ DIV({"class": "layoutLabelTop layoutLabel",
+ $invisible: "$marginTop|isInvisible"},
+ SPAN({"class": "layoutLabelMarginTop editable focusStart",
+ "aria-label": Locale.$STR("a11y.layout.margin top")},
+ "$marginTop"
+ )
),
- DIV({"class": "layoutLabelRight layoutLabel v$marginRight"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout..margin right')}, '$marginRight')
+ DIV({"class": "layoutLabelRight layoutLabel",
+ $invisible: "$marginRight|isInvisible"},
+ SPAN({"class": "layoutLabelMarginRight editable",
+ "aria-label": Locale.$STR("a11y.layout.margin right")},
+ "$marginRight"
+ )
),
- DIV({"class": "layoutLabelBottom layoutLabel v$marginBottom"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.margin bottom')}, '$marginBottom')
+ DIV({"class": "layoutLabelBottom layoutLabel",
+ $invisible: "$marginBottom|isInvisible"},
+ SPAN({"class": "layoutLabelMarginBottom editable",
+ "aria-label": Locale.$STR("a11y.layout.margin bottom")},
+ "$marginBottom"
+ )
),
- DIV({"class": "layoutLabelLeft layoutLabel v$marginLeft"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.margin left')}, '$marginLeft')
+ DIV({"class": "layoutLabelLeft layoutLabel",
+ $invisible: "$marginLeft|isInvisible"},
+ SPAN({"class": "layoutLabelMarginLeft editable",
+ "aria-label": Locale.$STR("a11y.layout.margin left")},
+ "$marginLeft"
+ )
),
DIV({"class": "borderLayoutBox layoutBox editGroup focusGroup"},
DIV({"class": "layoutCaption"}, Locale.$STR("LayoutBorder")),
- DIV({"class": "layoutLabelTop layoutLabel v$borderTop"},
- SPAN({"class": "editable focusStart", 'aria-label' : Locale.$STR('a11y.layout.border top')}, '$borderTop')
+ DIV({"class": "layoutLabelTop layoutLabel",
+ $invisible: "$borderTop|isInvisible"},
+ SPAN({"class": "layoutLabelBorderTop editable focusStart",
+ "aria-label": Locale.$STR("a11y.layout.border top")},
+ "$borderTop"
+ )
),
- DIV({"class": "layoutLabelRight layoutLabel v$borderRight"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.border right')}, '$borderRight')
+ DIV({"class": "layoutLabelRight layoutLabel",
+ $invisible: "$borderRight|isInvisible"},
+ SPAN({"class": "layoutLabelBorderRight editable",
+ "aria-label": Locale.$STR("a11y.layout.border right")},
+ "$borderRight"
+ )
),
- DIV({"class": "layoutLabelBottom layoutLabel v$borderBottom"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.border bottom')}, '$borderBottom')
+ DIV({"class": "layoutLabelBottom layoutLabel",
+ $invisible: "$borderBottom|isInvisible"},
+ SPAN({"class": "layoutLabelBorderBottom editable",
+ "aria-label": Locale.$STR("a11y.layout.border bottom")},
+ "$borderBottom"
+ )
),
- DIV({"class": "layoutLabelLeft layoutLabel v$borderLeft"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.border left')}, '$borderLeft')
+ DIV({"class": "layoutLabelLeft layoutLabel",
+ $invisible: "$borderLeft|isInvisible"},
+ SPAN({"class": "layoutLabelBorderLeft editable",
+ "aria-label": Locale.$STR("a11y.layout.border left")},
+ "$borderLeft"
+ )
),
DIV({"class": "paddingLayoutBox layoutBox editGroup focusGroup"},
DIV({"class": "layoutCaption"}, Locale.$STR("LayoutPadding")),
- DIV({"class": "layoutLabelTop layoutLabel v$paddingTop"},
- SPAN({"class": "editable focusStart", 'aria-label' : Locale.$STR('a11y.layout.padding top')}, '$paddingTop')
+ DIV({"class": "layoutLabelTop layoutLabel",
+ $invisible: "$paddingTop|isInvisible"},
+ SPAN({"class": "layoutLabelPaddingTop editable focusStart",
+ "aria-label": Locale.$STR("a11y.layout.padding top")},
+ "$paddingTop"
+ )
),
- DIV({"class": "layoutLabelRight layoutLabel v$paddingRight"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.padding right')}, '$paddingRight')
+ DIV({"class": "layoutLabelRight layoutLabel",
+ $invisible: "$paddingRight|isInvisible"},
+ SPAN(
+ {
+ "class": "layoutLabelPaddingRight editable",
+ "aria-label":
+ Locale.$STR("a11y.layout.padding right")
+ },
+ "$paddingRight"
+ )
),
- DIV({"class": "layoutLabelBottom layoutLabel v$paddingBottom"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.padding bottom')}, '$paddingBottom')
+ DIV({"class": "layoutLabelBottom layoutLabel",
+ $invisible: "$paddingBottom|isInvisible"},
+ SPAN(
+ {
+ "class": "layoutLabelPaddingBottom editable",
+ "aria-label":
+ Locale.$STR("a11y.layout.padding bottom")
+ },
+ "$paddingBottom"
+ )
),
- DIV({"class": "layoutLabelLeft layoutLabel v$paddingLeft"},
- SPAN({"class": "editable", 'aria-label' : Locale.$STR('a11y.layout.padding left')}, '$paddingLeft')
+ DIV({"class": "layoutLabelLeft layoutLabel",
+ $invisible: "$paddingLeft|isInvisible"},
+ SPAN({"class": "layoutLabelPaddingLeft editable",
+ "aria-label": Locale.$STR("a11y.layout.padding left")},
+ "$paddingLeft"
+ )
),
DIV({"class": "contentLayoutBox layoutBox editGroup focusGroup"},
DIV({"class": "layoutLabelCenter layoutLabel"},
- SPAN({"class": "layoutLabelWidth layoutLabel editable focusStart", 'aria-label' : Locale.$STR('a11y.layout.width')}, '$width'),
+ SPAN({"class": "layoutLabelWidth layoutLabel editable "+
+ "focusStart",
+ "aria-label": Locale.$STR("a11y.layout.width")},
+ "$width"
+ ),
" x ",
- SPAN({"class": "layoutLabelHeight layoutLabel editable", 'aria-label' : Locale.$STR('a11y.layout.height')}, '$height')
+ SPAN({"class": "layoutLabelHeight layoutLabel editable",
+ "aria-label": Locale.$STR("a11y.layout.height")},
+ "$height"
+ )
)
)
)
@@ -117,6 +197,11 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
)
),
+ isInvisible: function(value)
+ {
+ return value == 0;
+ },
+
getVerticalText: function(n)
{
return getVerticalText(n);
@@ -167,6 +252,7 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
{
this.onMouseOver = Obj.bind(this.onMouseOver, this);
this.onMouseOut = Obj.bind(this.onMouseOut, this);
+ this.onAfterPaint = Obj.bindFixed(this.refresh, this);
Firebug.Panel.initialize.apply(this, arguments);
},
@@ -187,6 +273,16 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
Firebug.Panel.destroyNode.apply(this, arguments);
},
+ show: function(state)
+ {
+ Events.addEventListener(this.context.browser, "MozAfterPaint", this.onAfterPaint, true);
+ },
+
+ hide: function()
+ {
+ Events.removeEventListener(this.context.browser, "MozAfterPaint", this.onAfterPaint, true);
+ },
+
supportsObject: function(object, type)
{
return object instanceof window.Element ? 1 : 0;
@@ -201,14 +297,12 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
{
var view = element ? element.ownerDocument.defaultView : null;
if (!view)
- return this.panelNode.innerHTML = "";
+ return this.panelNode.textContent = "";
var prev = Dom.getPreviousElement(element.previousSibling);
var next = Dom.getNextElement(element.nextSibling);
var style = view.getComputedStyle(element, "");
- var prevStyle = prev ? view.getComputedStyle(prev, "") : null;
- var nextStyle = next ? view.getComputedStyle(next, "") : null;
var args = Css.getBoxFromStyles(style, element);
@@ -222,7 +316,7 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
var position = style.getPropertyCSSValue("position").cssText;
args.position = position;
- args.outerLabel = '';
+ args.outerLabel = "";
if (Xml.isElementSVG(element) || Xml.isElementMathML(element) || Xml.isElementXUL(element))
{
@@ -236,28 +330,86 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
}
// these Modes are classes on the domplate
- args.outerLeftMode = args.outerRightMode = args.outerTopMode
- = args.outerBottomMode = "blankEdge";
+ args.outerLeftMode = args.outerRightMode = args.outerTopMode = args.outerBottomMode =
+ "blankEdge";
if (position == "absolute" || position == "fixed" || position == "relative")
{
- function getStyle(style, name) { var v = style.getPropertyCSSValue(name); return (v && v.cssText) ? parseInt(v.cssText) : ' '; }
+ function getStyle(style, name)
+ {
+ var value = style.getPropertyCSSValue(name);
+ return value && value.cssText ? parseInt(value.cssText) : " ";
+ }
args.outerLabel = Locale.$STR("LayoutPosition");
- args.outerLeft = getStyle(style,'left');
- args.outerTop = getStyle(style,'top');
- args.outerRight = getStyle(style,'right');
- args.outerBottom = getStyle(style,'bottom');
+ args.outerLeft = getStyle(style, "left");
+ args.outerTop = getStyle(style, "top");
+ args.outerRight = getStyle(style, "right");
+ args.outerBottom = getStyle(style, "bottom");
- args.outerLeftMode = args.outerRightMode = args.outerTopMode
- = args.outerBottomMode = "absoluteEdge";
+ args.outerLeftMode = args.outerRightMode = args.outerTopMode = args.outerBottomMode =
+ "absoluteEdge";
+ }
+
+ var node;
+ // If the layout panel content was already created, just fill in the new values
+ if (this.panelNode.getElementsByClassName("outerLayoutBox").item(0))
+ {
+ // The styles for the positionLayoutBox need to be set manually
+ var positionLayoutBox = this.panelNode.getElementsByClassName("positionLayoutBox").
+ item(0);
+ positionLayoutBox.className = "positionLayoutBox "+args.outerTopMode+" "+
+ args.outerRightMode+" "+args.outerBottomMode+" "+args.outerLeftMode+" focusGroup";
+
+ var values =
+ {
+ layoutPosition: {label: Locale.$STR("position"), value: "position"},
+ layoutBoxSizing: {label: Locale.$STR("a11y.layout.box-sizing"),
+ value: "boxSizing"},
+ layoutZIndex: {label: "z", value: "zIndex"},
+ layoutLabelOuterTop: {value: "outerTop"},
+ layoutLabelOuterRight: {value: "outerRight"},
+ layoutLabelOuterBottom: {value: "outerBottom"},
+ layoutLabelOuterLeft: {value: "outerLeft"},
+ layoutLabelMarginTop: {value: "marginTop"},
+ layoutLabelMarginRight: {value: "marginRight"},
+ layoutLabelMarginBottom: {value: "marginBottom"},
+ layoutLabelMarginLeft: {value: "marginLeft"},
+ layoutLabelBorderTop: {value: "borderTop"},
+ layoutLabelBorderRight: {value: "borderRight"},
+ layoutLabelBorderBottom: {value: "borderBottom"},
+ layoutLabelBorderLeft: {value: "borderLeft"},
+ layoutLabelPaddingTop: {value: "paddingTop"},
+ layoutLabelPaddingRight: {value: "paddingRight"},
+ layoutLabelPaddingBottom: {value: "paddingBottom"},
+ layoutLabelPaddingLeft: {value: "paddingLeft"},
+ layoutLabelWidth: {value: "width"},
+ layoutLabelHeight: {value: "height"},
+ outerLabel: {value: "outerLabel"},
+ }
+
+ for (val in values)
+ {
+ var element = this.panelNode.getElementsByClassName(val).item(0);
+
+ element.textContent = values[val].label ?
+ values[val].label+": "+args[values[val].value] : args[values[val].value];
+
+ if (this.template.isInvisible(args[values[val].value]))
+ Css.setClass(element.parentNode, "invisible");
+ else
+ Css.removeClass(element.parentNode, "invisible");
+ }
+ }
+ else
+ {
+ node = this.template.tag.replace(args, this.panelNode);
}
- var node = this.template.tag.replace(args, this.panelNode);
this.adjustCharWidth(this.getMaxCharWidth(args, node), this.panelNode);
- Events.dispatch(this.fbListeners, 'onLayoutBoxCreated', [this, node, args]);
+ Events.dispatch(this.fbListeners, "onLayoutBoxCreated", [this, node, args]);
},
/*
@@ -295,7 +447,7 @@ LayoutPanel.prototype = Obj.extend(Firebug.Panel,
adjustBoxWidth: function(node, boxName, width)
{
var box = node.getElementsByClassName(boxName).item(0);
- box.style.cssText = "right: "+width + 'px;'+" left: "+width + 'px;';
+ box.style.cssText = "right: "+width + 'px;'+" left: "+width + "px;";
},
getMaxCharWidth: function(args, node)
@@ -374,12 +526,7 @@ LayoutEditor.prototype = domplate(Firebug.InlineEditor.prototype,
if (Css.hasClass(target, "layoutVerticalText"))
target.innerHTML = getVerticalText(intValue);
else
- target.innerHTML = intValue;
-
- if (previousValue == "0" && !!value)
- Css.removeClass(target.parentNode, "v0");
- else if (!value)
- Css.setClass(target.parentNode, "v0");
+ target.textContent = intValue;
},
endEditing: function(target, value, cancel)
diff --git a/trace/FBTrace/chrome/firebug/content/js/breakpoint.js b/trace/FBTrace/chrome/firebug/content/js/breakpoint.js
index 86630fa..1e0473b 100644
--- a/trace/FBTrace/chrome/firebug/content/js/breakpoint.js
+++ b/trace/FBTrace/chrome/firebug/content/js/breakpoint.js
@@ -108,8 +108,7 @@ Firebug.Breakpoint = Obj.extend(Firebug.Module,
var menuPopup = Firebug.chrome.$("fbBreakOnNextOptions");
Dom.eraseNode(menuPopup);
- for (var i=0; i<menuItems.length; ++i)
- Menu.createMenuItem(menuPopup, menuItems[i]);
+ Menu.createMenuItems(menuPopup, menuItems);
},
/* see issue 5618
diff --git a/trace/FBTrace/chrome/firebug/content/js/debugger.js b/trace/FBTrace/chrome/firebug/content/js/debugger.js
index 1190364..810c673 100644
--- a/trace/FBTrace/chrome/firebug/content/js/debugger.js
+++ b/trace/FBTrace/chrome/firebug/content/js/debugger.js
@@ -124,7 +124,7 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
/**
* Used by autocomplete in commandLine
- * @return array of global property names
+ * @return array of locally visible property names for each scope we are in
*/
getCurrentFrameKeys: function(context) // TODO remote, on bti
{
@@ -151,11 +151,6 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
{
var prop = listValue.value[i];
var name = Wrapper.unwrapIValue(prop.name);
-
- // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=712289.
- if (typeof name !== "string")
- break;
-
names.push(name);
}
@@ -2561,58 +2556,11 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
}
*/
- // context.watchScriptAdditions = Obj.bind(this.watchScriptAdditions, this, context);
- // context.window.document.addEventListener("DOMNodeInserted", context.watchScriptAdditions, false);
-
if (FBTrace.DBG_SOURCEFILES)
FBTrace.sysout("debugger("+this.debuggerName+").loadedContext enabled on load: "+
context.onLoadWindowContent+" context.sourceFileMap", context.sourceFileMap);
},
- /*
- * A DOM Mutation Event handler for script tag additions
- * FAILS see http://code.google.com/p/fbug/issues/detail?id=2912
- */
- watchScriptAdditions: function(event, context)
- {
- if (event.type !== "DOMNodeInserted")
- return;
-
- if (event.target.tagName.toLowerCase() !== "script")
- return;
-
- FBTrace.sysout("debugger.watchScriptAdditions ", event.target.innerHTML);
- var location = Win.safeGetWindowLocation(context.window);
-
- jsd.enumerateScripts({enumerateScript: function(script)
- {
- if (Url.normalizeURL(script.fileName) === location)
- {
- var sourceFile = Firebug.SourceFile.getSourceFileByScript(context, script);
- FBTrace.sysout('debugger.watchScriptAdditions '+script.tag+" in "+
- (sourceFile?sourceFile.href:"NONE")+" "+script.functionSource,
- script.functionSource);
- // The dynamically added script tags via element.appendChild do not show up.
- }
- }});
-
- if (context.pendingScriptTagSourceFile)
- {
- var sourceFile = context.pendingScriptTagSourceFile;
- sourceFile.scriptTag = event.target;
- sourceFile.source = Str.splitLines(event.target.innerHTML);
-
- var panel = context.getPanel("script", true);
- if (panel)
- panel.removeSourceBoxBySourceFile(sourceFile);
-
- FBTrace.sysout("debugger.watchScriptAdditions connected tag to sourcefile",
- sourceFile);
-
- delete context.pendingScriptTagSourceFile;
- }
- },
-
// clean up the source file map in case the frame is being reloaded.
unwatchWindow: function(context, win)
{
@@ -2639,9 +2587,6 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
{
Firebug.ActivableModule.destroyContext.apply(this, arguments);
- Events.removeEventListener(context.window.document, "DOMNodeInserted",
- context.watchScriptAdditions, false);
-
if (context.stopped)
{
// the abort will call resume, but the nestedEventLoop would continue the load...
@@ -2728,11 +2673,6 @@ Firebug.Debugger = Obj.extend(Firebug.ActivableModule,
if (this.hasObservers())
{
this.activateDebugger();
-
- // bug712289, do not display the activation message if JSD is not available
- if (!FBS.isJSDAvailable())
- return;
-
if (Firebug.currentContext)
{
var name = observer.name || observer.dispatchName || observer.toolName;
diff --git a/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js b/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
index 96ee531..d27112a 100644
--- a/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/js/scriptPanel.js
@@ -22,7 +22,6 @@ define([
"firebug/chrome/menu",
"firebug/trace/debug",
"firebug/lib/keywords",
- "firebug/js/fbs", // bug712289
"firebug/editor/editorSelector",
"firebug/chrome/infotip",
"firebug/chrome/searchBox",
@@ -31,7 +30,7 @@ define([
],
function (Obj, Firebug, Firefox, FirebugReps, Domplate, JavaScriptTool, CompilationUnit,
Locale, Events, Url, SourceLink, StackFrame, Css, Dom, Win, Search, Persist,
- System, Menu, Debug, Keywords, FBS) {
+ System, Menu, Debug, Keywords) {
// ********************************************************************************************* //
// Script panel
@@ -170,7 +169,13 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
// Front side UI mark
var firebugStatus = Firefox.getElementById("firebugStatus");
if (firebugStatus)
- firebugStatus.setAttribute("script", active ? "on" : "off");
+ {
+ // Use enabled state for the status flag. JSD can be active even if
+ // the Script panel itself is deactivated (i.e. because the Console
+ // panel is enabled). See issue 2582 for more details.
+ var enabled = this.isEnabled();
+ firebugStatus.setAttribute("script", (enabled && active) ? "on" : "off");
+ }
if (Firebug.StartButton)
Firebug.StartButton.resetTooltip();
@@ -182,8 +187,8 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
if (FBTrace.DBG_ACTIVATION)
{
- FBTrace.sysout("script.onJavaScriptDebugging "+active+" icon attribute: "+
- Firefox.getElementById('firebugStatus').getAttribute("script"));
+ FBTrace.sysout("script.onJavaScriptDebugging " + active + " icon attribute: " +
+ Firefox.getElementById("firebugStatus").getAttribute("script"));
}
},
@@ -908,6 +913,7 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
this.showToolbarButtons("fbLocationButtons", active);
this.showToolbarButtons("fbScriptButtons", active);
this.showToolbarButtons("fbStatusButtons", active);
+ this.showToolbarButtons("fbLocationList", active);
Firebug.chrome.$("fbRerunButton").setAttribute("tooltiptext",
Locale.$STRF("firebug.labelWithShortcut", [Locale.$STR("script.Rerun"), "Shift+F8"]));
@@ -1377,8 +1383,14 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
optionMenu: function(label, option)
{
var checked = Firebug.Options.get(option);
- return {label: label, type: "checkbox", checked: checked,
- command: Obj.bindFixed(Firebug.Options.set, Firebug, option, !checked) };
+ return {
+ label: label, type: "checkbox", checked: checked,
+ command: function()
+ {
+ var checked = this.hasAttribute("checked");
+ Firebug.Options.set(option, checked)
+ }
+ };
},
getContextMenuItems: function(fn, target)
@@ -1569,27 +1581,6 @@ Firebug.ScriptPanel.prototype = Obj.extend(Firebug.SourceBoxPanel,
this.onJavaScriptDebugging(isActive, "onActiveTool");
},
- setEnabled: function(enable)
- {
- // bug712289
- if (!FBS.isJSDAvailable())
- {
- Firebug.SourceBoxPanel.setEnabled.apply(this, [false]);
- return;
- }
-
- Firebug.SourceBoxPanel.setEnabled.apply(this, arguments);
- },
-
- isPanelEnabled: function(panelType)
- {
- // bug712289
- if (!FBS.isJSDAvailable())
- return false;
-
- return Firebug.SourceBoxPanel.isPanelEnabled.apply(this, arguments);
- },
-
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Toolbar functions
@@ -1992,4 +1983,4 @@ Firebug.registerPanel(Firebug.ScriptPanel);
return Firebug.ScriptPanel;
// ********************************************************************************************* //
-});
\ No newline at end of file
+});
diff --git a/trace/FBTrace/chrome/firebug/content/js/sourceCache.js b/trace/FBTrace/chrome/firebug/content/js/sourceCache.js
index a32d943..2f22f25 100644
--- a/trace/FBTrace/chrome/firebug/content/js/sourceCache.js
+++ b/trace/FBTrace/chrome/firebug/content/js/sourceCache.js
@@ -170,7 +170,10 @@ Firebug.SourceCache.prototype = Obj.extend(new Firebug.Listener(),
removeAnchor: function(url)
{
- var index = url.indexOf("#");
+ if (FBTrace.DBG_ERRORS && !url)
+ FBTrace.sysout("sourceCache.removeAnchor; ERROR url must not be null");
+
+ var index = url ? url.indexOf("#") : -1;
if (index < 0)
return url;
diff --git a/trace/FBTrace/chrome/firebug/content/js/tabCache.js b/trace/FBTrace/chrome/firebug/content/js/tabCache.js
index a9ddd37..b7df9da 100644
--- a/trace/FBTrace/chrome/firebug/content/js/tabCache.js
+++ b/trace/FBTrace/chrome/firebug/content/js/tabCache.js
@@ -27,7 +27,7 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
-const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+const prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
const versionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator);
const appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
@@ -64,6 +64,8 @@ var contentTypes =
"application/xhtml+xml": 1,
"application/atom+xml": 1,
"application/rss+xml": 1,
+ "application/mathml+xml": 1,
+ "application/rdf+xml": 1,
"application/vnd.mozilla.maybe.feed": 1,
"application/vnd.mozilla.xul+xml": 1,
"application/javascript": 1,
diff --git a/trace/FBTrace/chrome/firebug/content/js/watchPanel.js b/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
index 2b535f3..b9d0a2a 100644
--- a/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/js/watchPanel.js
@@ -2,6 +2,7 @@
define([
"firebug/lib/object",
+ "firebug/chrome/firefox",
"firebug/firebug",
"firebug/dom/toggleBranch",
"firebug/lib/events",
@@ -12,7 +13,7 @@ define([
"firebug/lib/string",
"firebug/dom/domPanel", // Firebug.DOMBasePanel, Firebug.DOMPanel.DirTable
],
-function(Obj, Firebug, ToggleBranch, Events, Dom, Css, StackFrame, Locale, Str) {
+function(Obj, Firefox, Firebug, ToggleBranch, Events, Dom, Css, StackFrame, Locale, Str) {
// ********************************************************************************************* //
// Watch Panel
@@ -188,8 +189,17 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
showEmptyMembers: function()
{
- this.tag.replace({domPanel: this, toggles: new ToggleBranch.ToggleBranch()},
+ var domTable = this.tag.replace({domPanel: this, toggles: new ToggleBranch.ToggleBranch()},
this.panelNode);
+
+ // The direction needs to be adjusted according to the direction
+ // of the user agent. See issue 5073.
+ // TODO: Set the direction at the <body> to allow correct formatting of all relevant parts.
+ // This requires more adjustments related for rtl user agents.
+ var mainFrame = Firefox.getElementById("fbMainFrame");
+ var cs = mainFrame.ownerDocument.defaultView.getComputedStyle(mainFrame);
+ var watchRow = domTable.getElementsByClassName("watchNewRow").item(0);
+ watchRow.style.direction = cs.direction;
},
addWatch: function(expression)
@@ -260,6 +270,19 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
}, this));
},
+ // deletes all the watches
+ deleteAllWatches: function()
+ {
+ if (FBTrace.DBG_WATCH)
+ FBTrace.sysout("Firebug.WatchPanel.deleteAllWatches");
+ this.watches = [];
+ this.rebuild(true);
+ this.context.setTimeout(Obj.bindFixed(function()
+ {
+ this.showToolbox(null);
+ }, this));
+ },
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
showToolbox: function(row)
@@ -348,6 +371,7 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
if (!path || !path.length)
return;
+
// Ignore top level variables in the Watch panel.
if (panel.name == "watches" && path.length == 1)
return;
@@ -359,6 +383,37 @@ Firebug.WatchPanel.prototype = Obj.extend(Firebug.DOMBasePanel.prototype,
command: Obj.bindFixed(this.addWatch, this, path.join(""))
});
},
+
+ getContextMenuItems: function(object, target)
+ {
+ var items = Firebug.DOMBasePanel.prototype.getContextMenuItems.apply(this, arguments);
+
+ if (!this.watches || this.watches.length == 0)
+ return items;
+
+ // find the index of "DeletePropery" in the items:
+ var deleteWatchIndex = items.map(function(item)
+ {
+ return item.id;
+ }).indexOf("DeleteProperty");
+
+ // if DeleteWatch was found, we insert DeleteAllWatches after it
+ // otherwise, we insert the item at the beginning of the menu
+ var deleteAllWatchesIndex = (deleteWatchIndex >= 0) ? deleteWatchIndex + 1 : 0;
+
+ if (FBTrace.DBG_WATCH)
+ FBTrace.sysout("insert DeleteAllWatches at: "+ deleteAllWatchesIndex);
+
+ // insert DeleteAllWatches after DeleteWatch
+ items.splice(deleteAllWatchesIndex, 0, {
+ id: "fbDeleteAllWatches",
+ label: "DeleteAllWatches",
+ tooltiptext: "watch.tip.Delete_All_Watches",
+ command: Obj.bindFixed(this.deleteAllWatches, this)
+ });
+
+ return items;
+ }
});
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/lib/array.js b/trace/FBTrace/chrome/firebug/content/lib/array.js
index b93d865..724683d 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/array.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/array.js
@@ -8,18 +8,41 @@ function(FBTrace) {
// ********************************************************************************************* //
// Constants
+const Ci = Components.interfaces;
var Arr = {};
// ********************************************************************************************* //
// Arrays
-Arr.isArray = function(obj)
+Arr.isArray = Array.isArray || function(obj)
{
- if (Array.isArray)
- return Array.isArray(obj);
-
return Object.prototype.toString.call(obj) === "[object Array]";
-}
+};
+
+Arr.isArrayLike = function(obj)
+{
+ try
+ {
+ if (typeof obj !== "object")
+ return false;
+ if (!isFinite(obj.length))
+ return false;
+ if (Arr.isArray(obj))
+ return true;
+ if (typeof obj.callee === "function") // arguments
+ return true;
+ if (typeof obj.splice === "function") // jQuery etc.
+ return true;
+ if (obj instanceof Ci.nsIDOMHTMLCollection)
+ return true;
+ if (obj instanceof Ci.nsIDOMNodeList)
+ return true;
+ if (obj instanceof Ci.nsIDOMDOMTokenList)
+ return true;
+ }
+ catch (exc) {}
+ return false;
+};
// At least sometimes the keys will be on user-level window objects
Arr.keys = function(map)
@@ -91,13 +114,13 @@ Arr.sliceArray = function(array, index)
Arr.cloneArray = function(array, fn)
{
- var newArray = [];
+ var newArray = [], len = array.length;
if (fn)
- for (var i = 0; i < array.length; ++i)
+ for (var i = 0; i < len; ++i)
newArray.push(fn(array[i]));
else
- for (var i = 0; i < array.length; ++i)
+ for (var i = 0; i < len; ++i)
newArray.push(array[i]);
return newArray;
diff --git a/trace/FBTrace/chrome/firebug/content/lib/css.js b/trace/FBTrace/chrome/firebug/content/lib/css.js
index c1c1794..d1f449c 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/css.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/css.js
@@ -113,6 +113,68 @@ Css.getCSSShorthandCategory = function(nodeType, shorthandProp, keyword)
return category;
};
+/**
+ * Parses the CSS properties of a CSSStyleRule
+ * @param {Object} style CSSStyleRule to get the properties of
+ * @param {Object} element Element to which the style applies. Needed for parsing shorthand properties correctly.
+ * @returns {Array} Properties represented by {name, value, priority, longhandProps}
+ */
+Css.parseCSSProps = function(style, element)
+{
+ var props = [];
+
+ if (!element)
+ {
+ for (var i = 0, len = style.length; i < len; ++i)
+ {
+ var prop = style.item(i);
+ props.push({name: prop,
+ value: style.getPropertyValue(prop),
+ priority: style.getPropertyPriority(longhandProp)});
+ }
+ }
+ else
+ {
+ var lineRE = /(?:[^;\(]*(?:\([^\)]*?\))?[^;\(]*)*;?/g;
+ var propRE = /\s*([^:\s]*)\s*:\s*(.*?)\s*(?:! (important))?;?$/;
+ var lines = style.cssText.match(lineRE);
+ for (var i = 0, len = lines.length; i < len; ++i)
+ {
+ var match = propRE.exec(lines[i]);
+ if (!match)
+ continue;
+
+ if (match[2])
+ {
+ var prop = {name: match[1], value: match[2], priority: match[3] || ""};
+
+ // Add longhand properties to shorthand property
+ var doc = element.ownerDocument;
+ var dummyElement = doc.createElementNS(element.namespaceURI, element.tagName);
+ var dummyStyle = dummyElement.style;
+ dummyStyle.cssText = "";
+ dummyStyle.setProperty(prop.name, prop.value, prop.priority);
+
+ if (dummyStyle.length > 1)
+ {
+ prop.longhandProps = [];
+ for (var j = 0, propLen = dummyStyle.length; j < propLen; ++j)
+ {
+ var longhandProp = dummyStyle.item(j);
+ prop.longhandProps.push({name: longhandProp,
+ value: dummyStyle.getPropertyValue(longhandProp),
+ priority: dummyStyle.getPropertyPriority(longhandProp)});
+ }
+ }
+
+ props.push(prop);
+ }
+ }
+ }
+
+ return props;
+};
+
Css.isColorKeyword = function(keyword)
{
if (keyword == "transparent")
@@ -150,16 +212,20 @@ Css.isImageRule = function(nodeType,rule)
Css.copyTextStyles = function(fromNode, toNode, style)
{
- var view = fromNode.ownerDocument.defaultView;
+ var view = fromNode ? fromNode.ownerDocument.defaultView : null;
if (view)
{
if (!style)
style = view.getComputedStyle(fromNode, "");
- toNode.style.fontFamily = style.getPropertyCSSValue("font-family").cssText;
- toNode.style.fontSize = style.getPropertyCSSValue("font-size").cssText;
- toNode.style.fontWeight = style.getPropertyCSSValue("font-weight").cssText;
- toNode.style.fontStyle = style.getPropertyCSSValue("font-style").cssText;
+ toNode.style.fontFamily = style.fontFamily;
+ toNode.style.fontSize = style.fontSize;
+ toNode.style.fontWeight = style.fontWeight;
+ toNode.style.fontStyle = style.fontStyle;
+ toNode.style.fontSizeAdjust = style.fontSizeAdjust;
+ toNode.style.fontStretch = style.fontStretch;
+ toNode.style.fontVariant = style.fontVariant;
+ toNode.style.MozFontFeatureSettings = style.MozFontFeatureSettings;
return style;
}
@@ -469,7 +535,7 @@ Css.createStyleSheet = function(doc, url)
var expr = /url\(([\'"]?)(?![\'"]?(?:[a-z]+:|\/))/gi;
cssText = cssText.replace(expr, "url($1" + absURL);
- style.innerHTML = cssText;
+ style.textContent = cssText;
}
Firebug.setIgnored(style);
@@ -775,6 +841,16 @@ Css.rgbToHSL = function(value)
Css.cssInfo = {};
Css.cssInfo.html =
{
+ "animation": [],
+ "animation-delay": [],
+ "animation-direction": ["normal", "alternate", "reverse", "alternate-reverse"],
+ "animation-duration": [],
+ "animation-iteration-count": ["infinite"],
+ "animation-name" : ["none"],
+ "animation-play-state": ["running", "paused"],
+ "animation-timing-function": [],
+ "animation-fill-mode": ["none", "forwards", "backwards", "both"],
+
"background": ["bgRepeat", "bgAttachment", "position", "color", "image", "none", "boxModels"],
"background-attachment": ["bgAttachment"],
"background-color": ["color"],
@@ -812,10 +888,10 @@ Css.cssInfo.html =
"border-top-right-radius": ["length"], // FF 4.0
"border-bottom-right-radius": ["length"], // FF 4.0
"border-bottom-left-radius": ["length"], // FF 4.0
- "-moz-border-image": ["mozBorderImageRepeat", "thickness", "url()", "none"],
- "border-image": ["mozBorderImageRepeat", "thickness", "url()", "none"], // FF 15.0
+ "-moz-border-image": ["borderImageRepeat", "thickness", "url()", "none"],
+ "border-image": ["borderImageRepeat", "thickness", "url()", "none"], // FF 15.0
"border-image-outset": ["length"], // FF 15.0
- "border-image-repeat": ["mozBorderImageRepeat"], // FF 15.0
+ "border-image-repeat": ["borderImageRepeat"], // FF 15.0
"border-image-slice": ["fill"],
"border-image-source": ["image", "none"],
"border-image-width": ["auto", "length"], // FF 15.0
@@ -888,6 +964,8 @@ Css.cssInfo.html =
"padding-bottom": ["length"],
"padding-left": ["length"],
+ "page-break-after": ["pageBreak"],
+ "page-break-before": ["pageBreak"],
"pointer-events": ["auto", "none"],
"position": ["elPosition"],
"quotes": ["none"],
@@ -901,6 +979,14 @@ Css.cssInfo.html =
"text-rendering": ["textRendering"],
"text-shadow": ["color", "length"],
"text-transform": ["textTransform"],
+ "transition": ["transitionProperty", "timingFunction"],
+ "transition-property": ["transitionProperty"],
+ "transition-duration": [],
+ "transition-timing-function": ["timingFunction"],
+ "transition-delay": [],
+ "transform": ["transformFunction", "none", "length"],
+ "transform-origin": ["position", "length"],
+ "transform-style": ["transformStyle"],
"unicode-bidi": ["unicodeBidi"],
"vertical-align": ["verticalAlign", "length"],
"visibility": ["visibility"],
@@ -909,8 +995,6 @@ Css.cssInfo.html =
"word-spacing": ["normal", "length"],
"word-wrap": ["wordWrap"], // FF 3.5
"z-index": ["auto"],
- "page-break-after": ["pageBreak"],
- "page-break-before": ["pageBreak"],
"-moz-appearance": ["mozAppearance"],
"-moz-backface-visibility": ["mozBackfaceVisibility"], // FF 10.0
@@ -948,26 +1032,9 @@ Css.cssInfo.html =
"-moz-column-rule-color": ["color"],
"-moz-column-width": ["auto", "length"],
"-moz-image-region": [],
- "-moz-transform": ["mozTransformFunction", "none", "length"],
- "-moz-transform-origin": ["position", "length"],
- "-moz-transform-style": ["mozTransformStyle"], // FF 10.0
"-moz-font-feature-settings": ["mozFontFeatureSettings"], // FF 4.0
"-moz-font-language-override": ["normal"],
"-moz-tab-size": [], // FF 4.0,
- "-moz-transition": ["mozTransitionProperty", "mozTimingFunction"], // FF 4.0
- "-moz-transition-property": ["mozTransitionProperty"], // FF 4.0
- "-moz-transition-duration": [], // FF 4.0
- "-moz-transition-timing-function": ["mozTimingFunction"], // FF 4.0
- "-moz-transition-delay": [], // FF 4.0
- "-moz-animation": [], // FF 5.0
- "-moz-animation-delay": [], // FF 5.0
- "-moz-animation-direction": ["normal", "alternate"], // FF 5.0
- "-moz-animation-duration": [], // FF 5.0
- "-moz-animation-iteration-count": ["infinite"], // FF 5.0
- "-moz-animation-name" : ["none"], // FF 5.0
- "-moz-animation-play-state": ["running", "paused"], // FF 5.0
- "-moz-animation-timing-function": [], // FF 5.0
- "-moz-animation-fill-mode": ["none", "forwards", "backwards", "both"], // FF 5.0
"orient": ["horizontal", "vertical"], // FF 6.0
"-moz-text-blink": ["none", "blink"], // FF 6.0
"-moz-text-decoration-color": ["color"], // FF 6.0
@@ -1044,43 +1111,9 @@ Css.cssInfo.svg =
"writing-mode": ["writingMode"]
};
-Css.inheritedStyleNames =
-{
- "border-collapse": 1,
- "border-spacing": 1,
- "border-style": 1,
- "caption-side": 1,
- "color": 1,
- "cursor": 1,
- "direction": 1,
- "empty-cells": 1,
- "font": 1,
- "font-family": 1,
- "font-size-adjust": 1,
- "font-size": 1,
- "font-style": 1,
- "font-variant": 1,
- "font-weight": 1,
- "letter-spacing": 1,
- "line-height": 1,
- "list-style": 1,
- "list-style-image": 1,
- "list-style-position": 1,
- "list-style-type": 1,
- "opacity": 1,
- "quotes": 1,
- "text-align": 1,
- "text-decoration": 1,
- "text-indent": 1,
- "text-shadow": 1,
- "text-transform": 1,
- "white-space": 1,
- "word-spacing": 1,
- "word-wrap": 1
-};
-
Css.multiValuedProperties =
{
+ "animation": 1,
"background": 1,
"background-position": 1,
"border": 1,
@@ -1092,8 +1125,7 @@ Css.multiValuedProperties =
"font": 1,
"font-family": 1,
"margin": 1,
- "padding": 1,
- "-moz-animation": 1
+ "padding": 1
};
Css.unitlessProperties =
@@ -1144,6 +1176,8 @@ Css.cssKeywords =
"menupopup",
"menuradio",
"menuseparator",
+ "meterbar",
+ "meterchunk",
"progressbar",
"progressbar-vertical",
"progresschunk",
@@ -2019,7 +2053,7 @@ Css.cssKeywords =
"inset"
],
- "mozBorderImageRepeat":
+ "borderImageRepeat":
[
"stretch",
"round",
@@ -2030,20 +2064,24 @@ Css.cssKeywords =
"image":
[
"url()",
- "-moz-linear-gradient()", // FF 3.6
- "-moz-radial-gradient()", // FF 3.6
- "-moz-repeating-linear-gradient()", // FF 3.6
- "-moz-repeating-radial-gradient()", // FF 3.6
- "-moz-image-rect()", // FF 4.0
- "-moz-element()", // FF 4.0
+ "linear-gradient()",
+ "radial-gradient()",
+ "repeating-linear-gradient()",
+ "repeating-radial-gradient()",
+ "-moz-linear-gradient()",
+ "-moz-radial-gradient()",
+ "-moz-repeating-linear-gradient()",
+ "-moz-repeating-radial-gradient()",
+ "-moz-image-rect()",
+ "-moz-element()",
],
"length":
[
- "-moz-calc()"
+ "calc()"
],
- "mozTransformFunction":
+ "transformFunction":
[
"matrix()",
"matrix3d()",
@@ -2209,14 +2247,14 @@ Css.cssKeywords =
],
// FF 10.0
- "mozTransformStyle":
+ "transformStyle":
[
"preserve-3d",
"flat"
],
// FF 4.0
- "mozTransitionProperty":
+ "transitionProperty":
[
"none",
"all",
@@ -2267,6 +2305,8 @@ Css.cssKeywords =
"text-indent",
"text-shadow",
"top",
+ "transform-origin",
+ "transform",
"vertical-align",
"visibility",
"width",
@@ -2279,12 +2319,10 @@ Css.cssKeywords =
"-moz-column-rule-width",
"-moz-column-width",
"-moz-image-region",
- "-moz-outline-radius",
- "-moz-transform-origin",
- "-moz-transform"
+ "-moz-outline-radius"
],
- "mozTimingFunction": // FF 4.0
+ "timingFunction": // FF 4.0
[
"cubic-bezier()",
"ease",
@@ -2628,6 +2666,9 @@ Css.pseudoClasses =
":-moz-lwtheme-brighttext",
":-moz-lwtheme-darktext",
":-moz-math-increment-script-level",
+ ":-moz-meter-optimum",
+ ":-moz-meter-sub-optimum",
+ ":-moz-meter-sub-sub-optimum",
":-moz-only-whitespace",
":-moz-placeholder",
":-moz-read-only",
diff --git a/trace/FBTrace/chrome/firebug/content/lib/deprecated.js b/trace/FBTrace/chrome/firebug/content/lib/deprecated.js
index aed9992..8508846 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/deprecated.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/deprecated.js
@@ -17,7 +17,7 @@ var consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConso
// Module implementation
var Deprecated = {};
-Deprecated.deprecated = function(msg, fnc)
+Deprecated.deprecated = function(msg, fnc, args)
{
return function deprecationWrapper()
{
@@ -43,9 +43,9 @@ Deprecated.deprecated = function(msg, fnc)
this.nagged = true;
}
- return fnc.apply(this, arguments);
+ return fnc.apply(this, args || arguments);
}
-}
+};
// ********************************************************************************************* //
// Local helpers
diff --git a/trace/FBTrace/chrome/firebug/content/lib/dom.js b/trace/FBTrace/chrome/firebug/content/lib/dom.js
index bc084eb..81e2f17 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/dom.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/dom.js
@@ -145,6 +145,12 @@ Dom.getBody = function(doc)
// ********************************************************************************************* //
// DOM Modification
+Dom.insertAfter = function(newNode, referenceNode)
+{
+ if (referenceNode.parentNode)
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+}
+
Dom.addScript = function(doc, id, src)
{
var element = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script");
@@ -154,7 +160,7 @@ Dom.addScript = function(doc, id, src)
if (!FBTrace.DBG_CONSOLE)
Firebug.setIgnored(element);
- element.innerHTML = src;
+ element.textContent = src;
if (doc.documentElement)
{
@@ -175,11 +181,8 @@ Dom.setOuterHTML = function(element, html)
{
try
{
- var doc = element.ownerDocument;
- var range = doc.createRange();
- range.selectNode(element || doc.documentElement);
+ var fragment = DOM.markupToDocFragment(html, element);
- var fragment = range.createContextualFragment(html);
var first = fragment.firstChild;
var last = fragment.lastChild;
element.parentNode.replaceChild(fragment, element);
@@ -191,6 +194,15 @@ Dom.setOuterHTML = function(element, html)
}
};
+Dom.markupToDocFragment = function(markup, parent)
+{
+ var doc = parent.ownerDocument;
+ var range = doc.createRange();
+ range.selectNode(parent || doc.documentElement);
+
+ return range.createContextualFragment(markup);
+};
+
Dom.appendInnerHTML = function(element, html, referenceElement)
{
var doc = element.ownerDocument;
@@ -244,7 +256,7 @@ Dom.hide = function(elt, hidden)
Dom.clearNode = function(node)
{
- node.innerHTML = "";
+ node.textContent = "";
};
Dom.eraseNode = function(node)
@@ -402,7 +414,7 @@ Dom.findPrevious = function(node, criteria, downOnly, maxRoot)
}
};
-// ************************************************************************************************
+// ********************************************************************************************* //
// Graphics
Dom.getClientOffset = function(elt)
@@ -424,7 +436,10 @@ Dom.getClientOffset = function(elt)
addOffset(p, coords, view);
}
else if (elt.ownerDocument.defaultView.frameElement)
- addOffset(elt.ownerDocument.defaultView.frameElement, coords, elt.ownerDocument.defaultView);
+ {
+ addOffset(elt.ownerDocument.defaultView.frameElement, coords,
+ elt.ownerDocument.defaultView);
+ }
}
var coords = {x: 0, y: 0};
@@ -445,8 +460,8 @@ Dom.getClientOffset = function(elt)
*/
Dom.getLTRBWH = function(elt)
{
- var bcrect,
- dims = {"left": 0, "top": 0, "right": 0, "bottom": 0, "width": 0, "height": 0};
+ var bcrect;
+ var dims = {"left": 0, "top": 0, "right": 0, "bottom": 0, "width": 0, "height": 0};
if (elt)
{
@@ -487,7 +502,8 @@ Dom.getOffsetSize = function(elt)
*/
Dom.getOverflowParent = function(element)
{
- for (var scrollParent = element.parentNode; scrollParent; scrollParent = scrollParent.offsetParent)
+ for (var scrollParent = element.parentNode; scrollParent;
+ scrollParent = scrollParent.offsetParent)
{
if (scrollParent.scrollHeight > scrollParent.offsetHeight)
return scrollParent;
@@ -504,9 +520,11 @@ Dom.isScrolledToBottom = function(element)
var onBottom = (element.scrollTop + element.offsetHeight) == element.scrollHeight;
if (FBTrace.DBG_CONSOLE)
+ {
FBTrace.sysout("Dom.isScrolledToBottom offsetHeight: " + element.offsetHeight +
", scrollTop: " + element.scrollTop + ", scrollHeight: " + element.scrollHeight +
", onBottom: " + onBottom);
+ }
return onBottom;
};
@@ -522,9 +540,14 @@ Dom.scrollToBottom = function(element)
if (FBTrace.DBG_CONSOLE)
{
- FBTrace.sysout("scrollToBottom reset scrollTop "+element.scrollTop+" = "+element.scrollHeight);
+ FBTrace.sysout("scrollToBottom reset scrollTop " + element.scrollTop + " = " +
+ element.scrollHeight);
+
if (element.scrollHeight == element.offsetHeight)
- FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element "+element, element);
+ {
+ FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element " +
+ element, element);
+ }
}
return (element.scrollTop == element.scrollHeight);
@@ -565,8 +588,8 @@ Dom.linesIntoCenterView = function(element, scrollBox) // {before: int, after:
var offset = Dom.getClientOffset(element);
var topSpace = offset.y - scrollBox.scrollTop;
- var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight)
- - (offset.y + element.offsetHeight);
+ var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight) -
+ (offset.y + element.offsetHeight);
if (topSpace < 0 || bottomSpace < 0)
{
@@ -574,7 +597,7 @@ Dom.linesIntoCenterView = function(element, scrollBox) // {before: int, after:
var centerY = offset.y - split;
scrollBox.scrollTop = centerY;
topSpace = split;
- bottomSpace = split - element.offsetHeight;
+ bottomSpace = split - element.offsetHeight;
}
return {
@@ -692,9 +715,40 @@ Dom.scrollTo = function(element, scrollBox, alignmentX, alignmentY, scrollWhenVi
*/
Dom.scrollIntoCenterView = function(element, scrollBox, notX, notY)
{
- Dom.scrollTo(element, scrollBox, notX ? "none" : "centerOrLeft", notY ? "none" : "centerOrTop");
+ Dom.scrollTo(element, scrollBox, notX ? "none" : "centerOrLeft",
+ notY ? "none" : "centerOrTop");
};
+Dom.scrollMenupopup = function(popup, item)
+{
+ var doc = popup.ownerDocument;
+ var box = doc.getAnonymousNodes(popup)[0];
+ var scrollBox = doc.getAnonymousNodes(box)[1];
+
+ if (item == undefined)
+ {
+ scrollBox.scrollTop = scrollBox.scrollHeight + 100;
+ }
+ else if (item == 0)
+ {
+ scrollBox.scrollTop = 0;
+ }
+ else
+ {
+ var popupRect = popup.getBoundingClientRect();
+ var itemRect = item.getBoundingClientRect();
+
+ if (itemRect.top < popupRect.top + itemRect.height)
+ {
+ scrollBox.scrollTop += itemRect.top - popupRect.top - itemRect.height;
+ }
+ else if (itemRect.bottom + itemRect.height > popupRect.bottom)
+ {
+ scrollBox.scrollTop -= popupRect.bottom - itemRect.bottom - itemRect.height;
+ }
+ }
+}
+
// ********************************************************************************************* //
// DOM Members
@@ -758,6 +812,8 @@ Dom.getDOMMembers = function(object)
{ return domMemberCache.Node; }
else if (object instanceof Event || object instanceof Dom.EventCopy)
{ return domMemberCache.Event; }
+ else if (object instanceof Object)
+ { return domMemberCache.Object; }
return null;
};
@@ -777,12 +833,27 @@ Dom.isDOMConstant = function(object, name)
if (name == "__proto__")
return false;
- if (!(object instanceof Window ||
- object instanceof Node ||
- object instanceof Location ||
- object instanceof Event ||
- object instanceof Dom.EventCopy))
+ // object isn't recognized as such when using ===,
+ // so use this as workaround
+ var str = Object.prototype.toString.call(object);
+ var isDOMProperty = ["[object Window]", "[object Node]", "[object Location]",
+ "[object Event]"].indexOf(str) !== -1;
+
+ if (!(object === window.Window ||
+ object === window.Object ||
+ object === window.Node ||
+ object === window.Location ||
+ object === window.Event ||
+ object === Dom.EventCopy ||
+ object instanceof window.Window ||
+ object instanceof window.Node ||
+ object instanceof window.Location ||
+ object instanceof window.Event ||
+ object instanceof Dom.EventCopy ||
+ isDOMProperty))
+ {
return false;
+ }
return Dom.domConstantMap.hasOwnProperty(name);
}
@@ -834,7 +905,12 @@ domMemberMap.Window =
"mozAnimationStartTime", //FF4.0
"mozPaintCount", //FF4.0
"mozRequestAnimationFrame", //FF4.0
- "mozIndexedDB", //FF4.0
+ "mozCancelAnimationFrame",
+ "mozCancelRequestAnimationFrame",
+
+ "mozCancelAnimationFrame",
+ "mozCancelRequestAnimationFrame",
+ "indexedDB",
"status",
"defaultStatus",
@@ -860,7 +936,6 @@ domMemberMap.Window =
"scrollbars",
"fullScreen",
"netscape",
- "java",
"console",
"Components",
"controllers",
@@ -873,7 +948,6 @@ domMemberMap.Window =
"length",
"sessionStorage",
- "globalStorage",
"setTimeout",
"setInterval",
@@ -933,6 +1007,195 @@ domMemberMap.Window =
"matchMedia", // https://developer.mozilla.org/en/DOM/window.matchMedia
"getInterface",
+
+ "BarProp",
+ "Controllers",
+ "Crypto",
+ "DOMException",
+ "DOMStringList",
+ "EventTarget",
+ "History",
+ "MimeTypeArray",
+ "MozURLProperty",
+ "Navigator",
+ "NodeList",
+ "OfflineResourceList",
+ "Screen",
+ "Storage",
+ "XULControllers",
+ "Document",
+ "Element",
+ "Attr",
+ "CharacterData",
+ "DOMTokenList",
+ "Text",
+
+ "HTMLAnchorElement",
+ "HTMLAudioElement",
+ "HTMLBaseElement",
+ "HTMLButtonElement",
+ "HTMLCollection",
+ "HTMLCanvasElement",
+ "HTMLDataListElement",
+ "HTMLDListElement",
+ "HTMLDocument",
+ "HTMLElement",
+ "HTMLEmbedElement",
+ "HTMLHtmlElement",
+ "HTMLBRElement",
+ "HTMLBodyElement",
+ "HTMLCollection",
+ "HTMLDivElement",
+ "HTMLDocument",
+ "HTMLElement",
+ "HTMLFormElement",
+ "HTMLHRElement",
+ "HTMLHeadElement",
+ "HTMLHeadingElement",
+ "HTMLHtmlElement",
+ "HTMLIFrameElement",
+ "HTMLImageElement",
+ "HTMLInputElement",
+ "HTMLLabelElement",
+ "HTMLLegendElement",
+ "HTMLLinkElement",
+ "HTMLMapElement",
+ "HTMLMediaElement",
+ "HTMLMenuElement",
+ "HTMLMetaElement",
+ "HTMLMeterElement",
+ "HTMLModElement",
+ "HTMLObjectElement",
+ "HTMLOListElement",
+ "HTMLOptionElement",
+ "HTMLOptionsCollection",
+ "HTMLOutputElement",
+ "HTMLPreElement",
+ "HTMLProgressElement",
+ "HTMLQuoteElement",
+ "HTMLScriptElement",
+ "HTMLSelectElement",
+ "HTMLSourceElement",
+ "HTMLSpanElement",
+ "HTMLStyleElement",
+ "HTMLTableCellElement",
+ "HTMLTableElement",
+ "HTMLTableRowElement",
+ "HTMLTableSectionElement",
+ "HTMLTextAreaElement",
+ "HTMLTitleElement",
+ "HTMLUListElement",
+ "HTMLUnknownElement",
+ "HTMLVideoElement",
+
+ "Infinity",
+ "JSON",
+ "Location",
+ "Math",
+ "NaN",
+ "Node",
+ "StopIteration",
+ "Window",
+ "XULElement",
+ "undefined",
+ "CSS2Properties",
+ "CSSStyleDeclaration",
+ "Error",
+ "EvalError",
+ "InternalError",
+ "Namespace",
+ "QName",
+ "RangeError",
+ "ReferenceError",
+ "SyntaxError",
+ "TypeError",
+ "URIError",
+ "Array",
+ "ArrayBuffer",
+ "Boolean",
+ "DataView",
+ "Date",
+ "Float32Array",
+ "Float64Array",
+ "Function",
+ "Int16Array",
+ "Int32Array",
+ "Int8Array",
+ "Iterator",
+ "Map",
+ "Number",
+ "Object",
+ "ParallelArray",
+ "QueryInterface",
+ "RegExp",
+ "Set",
+ "String",
+ "Uint16Array",
+ "Uint32Array",
+ "Uint8Array",
+ "Uint8ClampedArray",
+ "WeakMap",
+ "XML",
+ "XMLList",
+ "decodeURI",
+ "decodeURIComponent",
+ "dumpProfile",
+ "encodeURI",
+ "encodeURIComponent",
+ "escape",
+ "isFinite",
+ "isNaN",
+ "isXMLName",
+ "parseFloat",
+ "parseInt",
+ "pauseProfilers",
+ "resumeProfilers",
+ "startProfiling",
+ "stopProfiling",
+ "unescape",
+ "uneval",
+ "Performance",
+ "PerformanceNavigation",
+ "PerformanceTiming"
+];
+
+domMemberMap.Object =
+[
+ "arguments",
+ "caller",
+ "length",
+ "name",
+ "__defineGetter__",
+ "__defineSetter__",
+ "__lookupGetter__",
+ "__lookupSetter__",
+ "apply",
+ "bind",
+ "call",
+ "constructor",
+ "create",
+ "defineProperties",
+ "defineProperty",
+ "freeze",
+ "getOwnPropertyDescriptor",
+ "getOwnPropertyNames",
+ "getPrototypeOf",
+ "hasOwnProperty",
+ "isExtensible",
+ "isFrozen",
+ "isGenerator",
+ "isPrototypeOf",
+ "isSealed",
+ "keys",
+ "preventExtensions",
+ "propertyIsEnumerable",
+ "seal",
+ "toLocaleString",
+ "toSource",
+ "toString",
+ "unwatch",
+ "valueOf",
+ "watch"
];
domMemberMap.Location =
@@ -948,7 +1211,9 @@ domMemberMap.Location =
"assign",
"reload",
- "replace"
+ "replace",
+
+ "QueryInterface"
];
domMemberMap.Node =
@@ -999,7 +1264,9 @@ domMemberMap.Node =
"isSupported",
"getFeature",
"getUserData",
- "setUserData"
+ "setUserData",
+
+ "QueryInterface"
];
domMemberMap.Document = Arr.extendArray(domMemberMap.Node,
@@ -1877,6 +2144,15 @@ Dom.domInlineEventHandlersMap =
"onvolumechange": 1,
"onwaiting": 1,
"onmozfullscreenchange": 1,
+ "ondevicelight": 1,
+ "ondeviceproximity": 1,
+ "onmouseenter": 1,
+ "onmouseleave": 1,
+ "onmozfullscreenerror": 1,
+ "onmozpointerlockchange": 1,
+ "onmozpointerlockerror": 1,
+ "onuserproximity": 1,
+ "onwheel": 1
}
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/lib/domplate.js b/trace/FBTrace/chrome/firebug/content/lib/domplate.js
index 5131b9f..c2ba7f3 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/domplate.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/domplate.js
@@ -295,9 +295,9 @@ DomplateTag.prototype =
{
for (var i = 0; i < child.parts.length; ++i)
{
- if (child.parts[i] instanceof Variable)
+ if (child.parts[i] instanceof Variables)
{
- var name = child.parts[i].name;
+ var name = child.parts[i].names[0];
var names = name.split(".");
args.push(names[0]);
}
@@ -422,10 +422,8 @@ DomplateTag.prototype =
var nodeCount = this.generateDOM(path, blocks, this.domArgs);
var fnBlock = ['(function (root, context, o'];
-
for (var i = 0; i < path.staticIndex; ++i)
fnBlock.push(', ', 's'+i);
-
for (var i = 0; i < path.renderIndex; ++i)
fnBlock.push(', ', 'd'+i);
@@ -442,10 +440,10 @@ DomplateTag.prototype =
fnBlock.push(blocks.join(""));
- if (this.subject)
- fnBlock.push('}\n');
if (this.context)
fnBlock.push('}\n');
+ if (this.subject)
+ fnBlock.push('}\n');
fnBlock.push('return ', nodeCount, ';\n');
fnBlock.push('})\n');
@@ -499,6 +497,7 @@ DomplateTag.prototype =
for (var i = 2; i < arguments.length; ++i)
{
var index = arguments[i];
+
if (i == 3)
index += offset;
@@ -534,7 +533,6 @@ DomplateTag.prototype =
chained.cause = {exc:exc, js: js};
throw chained;
}
-
},
generateDOM: function(path, blocks, args)
@@ -735,12 +733,25 @@ DomplateLoop.prototype = copyObject(DomplateTag.prototype,
{
this.addCode(topBlock, topOuts, blocks);
+ // We are in a FOR loop and our this.iter property contains
+ // either a simple function name as a string or a Parts object
+ // with only ONE Variables object. There is only one variables object
+ // as the FOR argument can contain only ONE valid function callback
+ // with optional arguments or just one variable. Allowed arguments are
+ // func or $var or $var.sub or $var|func or $var1,$var2|func or $var|func1|func2 or $var1,$var2|func1|func2
var iterName;
if (this.iter instanceof Parts)
{
+ // We have a function with optional aruments or just one variable
var part = this.iter.parts[0];
- iterName = part.name;
-
+
+ // Join our function arguments or variables
+ // If the user has supplied multiple variables without a function
+ // this will create an invalid result and we should probably add an
+ // error message here or just take the first variable
+ iterName = part.names.join(",");
+
+ // Nest our functions
if (part.format)
{
for (var i = 0; i < part.format.length; ++i)
@@ -749,12 +760,12 @@ DomplateLoop.prototype = copyObject(DomplateTag.prototype,
}
else
{
+ // We have just a simple function name without any arguments
iterName = this.iter;
}
blocks.push('__loop__.apply(this, [', iterName, ', __out__, function(',
this.varName, ', __out__) {\n');
-
this.generateChildMarkup(topBlock, topOuts, blocks, info);
this.addCode(topBlock, topOuts, blocks);
@@ -809,9 +820,9 @@ DomplateLoop.prototype = copyObject(DomplateTag.prototype,
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-function Variable(name, format)
+function Variables(names, format)
{
- this.name = name;
+ this.names = names;
this.format = format;
}
@@ -824,7 +835,8 @@ function Parts(parts)
function parseParts(str)
{
- var re = /\$([_A-Za-z][_A-Za-z0-9.|]*)/g;
+ // Match $var or $var.sub or $var|func or $var1,$var2|func or $var|func1|func2 or $var1,$var2|func1|func2
+ var re = /\$([_A-Za-z][_A-Za-z0-9.]*(,\$[_A-Za-z][_A-Za-z0-9.]*)*([_A-Za-z0-9.|]*))/g;
var index = 0;
var parts = [];
@@ -835,14 +847,20 @@ function parseParts(str)
if (pre)
parts.push(pre);
- var expr = m[1].split("|");
- parts.push(new Variable(expr[0], expr.slice(1)));
+ var segs = m[1].split("|");
+ var vars = segs[0].split(",$");
+
+ // Assemble the variables object and append to buffer
+ parts.push(new Variables(vars, segs.slice(1)));
+
index = re.lastIndex;
}
+ // No matches found at all so we return the whole string
if (!index)
return str;
+ // If we have data after our last matched index we append it here as the final step
var post = str.substr(index);
if (post)
parts.push(post);
@@ -872,8 +890,8 @@ function readPartNames(val, vars)
for (var i = 0; i < val.parts.length; ++i)
{
var part = val.parts[i];
- if (part instanceof Variable)
- vars.push(part.name);
+ if (part instanceof Variables)
+ vars.push(part.names[0]);
}
}
}
@@ -886,7 +904,7 @@ function generateArg(val, path, args)
for (var i = 0; i < val.parts.length; ++i)
{
var part = val.parts[i];
- if (part instanceof Variable)
+ if (part instanceof Variables)
{
var varName = 'd'+path.renderIndex++;
if (part.format)
@@ -918,9 +936,9 @@ function addParts(val, delim, block, info, escapeIt)
for (var i = 0; i < val.parts.length; ++i)
{
var part = val.parts[i];
- if (part instanceof Variable)
+ if (part instanceof Variables)
{
- var partName = part.name;
+ var partName = part.names.join(",");
if (part.format)
{
for (var j = 0; j < part.format.length; ++j)
diff --git a/trace/FBTrace/chrome/firebug/content/lib/events.js b/trace/FBTrace/chrome/firebug/content/lib/events.js
index 35b09a4..5254f5f 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/events.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/events.js
@@ -326,6 +326,15 @@ const eventTypes =
"cut",
"copy",
"paste"
+ ],
+
+ touch: [
+ "touchstart",
+ "touchend",
+ "touchmove",
+ "touchenter",
+ "touchleave",
+ "touchcancel"
]
};
diff --git a/trace/FBTrace/chrome/firebug/content/lib/fonts.js b/trace/FBTrace/chrome/firebug/content/lib/fonts.js
index cc43de1..0e58257 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/fonts.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/fonts.js
@@ -78,7 +78,7 @@ Fonts.getFontsUsedInContext = function(context)
* Retrieves the information about a font
* @context: Context of the font
* @win: Window the font is used in
- * @identifier: Either a URL in case of a Fonts font or the font name
+ * @identifier: Either a URL in case of a web font or the font name
* @return Object with information about the font
*/
Fonts.getFontInfo = function(context, win, identifier)
@@ -94,15 +94,15 @@ Fonts.getFontInfo = function(context, win, identifier)
}
var fonts = Fonts.getFonts(doc.documentElement);
- var url = Url.splitURLBase(identifier);
if (FBTrace.DBG_FONTS)
- FBTrace.sysout("Fonts.getFontInfo;", {fonts:fonts, url:url});
+ FBTrace.sysout("Fonts.getFontInfo;", {fonts:fonts, identifier: identifier});
for (var i=0; i<fonts.length; i++)
{
- if ((fonts[i].rule && url && identifier == fonts[i].URI) ||
- identifier == fonts[i].CSSFamilyName || identifier == fonts[i].name)
+ if (identifier == fonts[i].URI ||
+ identifier.toLowerCase() == fonts[i].CSSFamilyName.toLowerCase() ||
+ identifier.toLowerCase() == fonts[i].name.toLowerCase())
{
return fonts[i];
}
diff --git a/trace/FBTrace/chrome/firebug/content/lib/object.js b/trace/FBTrace/chrome/firebug/content/lib/object.js
index 1d367e1..5656d57 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/object.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/object.js
@@ -25,19 +25,21 @@ Obj.bindFixed = function() // fn, thisObject, args => thisObject.fn(args);
return function() { return fn.apply(object, args); }
};
-Obj.extend = function(l, r)
+Obj.extend = function()
{
- if (!l || !r)
+ if (arguments.length < 2)
{
- FBTrace.sysout("object.extend; ERROR", [l, r]);
+ FBTrace.sysout("object.extend; ERROR", arguments);
throw new Error("Obj.extend on undefined object");
}
var newOb = {};
- for (var n in l)
- newOb[n] = l[n];
- for (var n in r)
- newOb[n] = r[n];
+ for (var i = 0, len = arguments.length; i < len; ++i)
+ {
+ for (var prop in arguments[i])
+ newOb[prop] = arguments[i][prop];
+ }
+
return newOb;
};
@@ -68,8 +70,7 @@ Obj.hasProperties = function(ob, nonEnumProps, ownPropsOnly)
return false;
var obString = Str.safeToString(ob);
- if (obString === "[object StorageList]" ||
- obString === "[xpconnect wrapped native prototype]")
+ if (obString === "[xpconnect wrapped native prototype]")
{
return true;
}
diff --git a/trace/FBTrace/chrome/firebug/content/lib/options.js b/trace/FBTrace/chrome/firebug/content/lib/options.js
index 0f9b1aa..f1155f8 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/options.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/options.js
@@ -13,12 +13,11 @@ const Cc = Components.classes;
const Ci = Components.interfaces;
const nsIPrefBranch = Ci.nsIPrefBranch;
-const nsIPrefBranch2 = Ci.nsIPrefBranch2;
const PrefService = Cc["@mozilla.org/preferences-service;1"];
const nsIPrefService = Ci.nsIPrefService;
const prefService = PrefService.getService(nsIPrefService);
-const prefs = PrefService.getService(nsIPrefBranch2);
+const prefs = PrefService.getService(nsIPrefBranch);
const prefNames = // XXXjjb TODO distribute to modules
[
@@ -97,6 +96,8 @@ var optionUpdateMap = {};
var Options =
/** @lends Options */
{
+ prefDomain: "extensions.firebug",
+
getPrefDomain: function()
{
return this.prefDomain;
@@ -347,7 +348,7 @@ var Options =
if (prefs.prefHasUserValue(prefName))
prefs.clearUserPref(prefName);
},
-
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Firebug UI text zoom
@@ -412,6 +413,11 @@ var Options =
}
}
},
+
+ forceSave: function()
+ {
+ prefs.savePrefFile(null);
+ }
};
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/lib/string.js b/trace/FBTrace/chrome/firebug/content/lib/string.js
index f9e98c1..c638a18 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/string.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/string.js
@@ -22,7 +22,7 @@ const reNotWhitespace = /[^\s]/;
var Str = {};
-// ************************************************************************************************
+// ********************************************************************************************* //
// Whitespace and Entity conversions
var entityConversionLists = Str.entityConversionLists =
@@ -111,7 +111,7 @@ e(0x200d, "zwj", attr, text, white, editor);
e(0x200e, "lrm", attr, text, white, editor);
e(0x200f, "rlm", attr, text, white, editor);
-//************************************************************************************************
+// ********************************************************************************************* //
// Entity escaping
var entityConversionRegexes =
@@ -356,7 +356,7 @@ function unescapeEntities(str, lists)
return results.join('') || '';
}
-// ************************************************************************************************
+// ********************************************************************************************* //
// String escaping
var escapeForTextNode = Str.escapeForTextNode = createSimpleEscape("text", "normal");
@@ -386,7 +386,7 @@ Str.unescapeForTextNode = function(str)
str = escapeForElementAttribute(str);
return str;
-}
+};
Str.unescapeForURL = createSimpleEscape('text', 'reverse');
@@ -532,20 +532,29 @@ Str.splitLines = function(text)
Str.trim = function(text)
{
return text.replace(/^\s*|\s*$/g, "");
-}
+};
Str.trimLeft = function(text)
{
return text.replace(/^\s+/, "");
-}
+};
Str.trimRight = function(text)
{
return text.replace(/\s+$/, "");
-}
+};
Str.hasPrefix = function(hay, needle)
{
+ // Passing empty string is ok, but null or undefined is not.
+ if (hay == null)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("Str.hasPrefix; string must not be null", {hay: hay, needle: needle});
+
+ return false;
+ }
+
// This is the fastest way of testing for prefixes - (hay.indexOf(needle) === 0)
// can be O(|hay|) in the worst case, and (hay.substr(0, needle.length) === needle)
// unnecessarily creates a new string and might be O(|needle|) in some JavaScript
@@ -553,6 +562,14 @@ Str.hasPrefix = function(hay, needle)
return hay.lastIndexOf(needle, 0) === 0;
};
+Str.endsWith = function(str, suffix)
+{
+ return str.indexOf(suffix, str.length - suffix.length) !== -1;
+}
+
+// ********************************************************************************************* //
+// HTML Wrap
+
Str.wrapText = function(text, noEscapeHTML)
{
var reNonAlphaNumeric = /[^A-Za-z_$0-9'"-]/;
@@ -591,15 +608,15 @@ Str.wrapText = function(text, noEscapeHTML)
}
return html;
-}
+};
Str.insertWrappedText = function(text, textBox, noEscapeHTML)
{
var html = Str.wrapText(text, noEscapeHTML);
textBox.innerHTML = "<pre role=\"list\">" + html.join("") + "</pre>";
-}
+};
-// ************************************************************************************************
+// ********************************************************************************************* //
// Indent
const reIndent = /^(\s+)/;
@@ -625,22 +642,16 @@ Str.cleanIndentation = function(text)
lines[i] = line.substr(minIndent);
}
return lines.join("");
-}
+};
-// ************************************************************************************************
+// ********************************************************************************************* //
// Formatting
-Str.formatNumber = function(number)
-{
- number += "";
- var x = number.split(".");
- var x1 = x[0];
- var x2 = x.length > 1 ? "." + x[1] : "";
- var rgx = /(\d+)(\d{3})/;
- while (rgx.test(x1))
- x1 = x1.replace(rgx, "$1" + "," + "$2");
- return x1 + x2;
-}
+//deprecated compatibility functions
+Str.deprecateEscapeHTML = createSimpleEscape("text", "normal");
+
+Str.formatNumber = Deprecated.deprecated("use <number>.toLocaleString() instead",
+ function(number) { return number.toLocaleString(); });
Str.formatSize = function(bytes)
{
@@ -670,16 +681,16 @@ Str.formatSize = function(bytes)
if (bytes == -1 || bytes == undefined)
return "?";
else if (bytes == 0)
- return "0";
+ return "0 B";
else if (bytes < 1024)
- result = bytes + " B";
+ result = bytes.toLocaleString() + " B";
else if (bytes < (1024*1024))
- result = Math.round((bytes/1024)*a)/a + " KB";
+ result = (Math.round((bytes/1024)*a)/a).toLocaleString() + " KB";
else
- result = Math.round((bytes/(1024*1024))*a)/a + " MB";
+ result = (Math.round((bytes/(1024*1024))*a)/a).toLocaleString() + " MB";
return negative ? "-" + result : result;
-}
+};
Str.formatTime = function(elapsed)
{
@@ -697,10 +708,32 @@ Str.formatTime = function(elapsed)
var sec = (elapsed % 60000);
return min + "m " + (Math.round((elapsed/1000)%60)) + "s";
}
-}
+};
+
+/**
+ * Formats an IPv4 or IPv6 address incl. port
+ * @param {String} address IP address to format
+ * @param {String} [port] IP port to format
+ * @returns {String} Formatted IP address
+ */
+Str.formatIP = function(address, port)
+{
+ if (!address || address == "")
+ return "";
-//********************************************************************************************* //
-//Conversions
+ var result = address;
+ var isIPv6Address = address.indexOf(":") != -1;
+ if (isIPv6Address)
+ result = "["+result+"]";
+
+ if (port && port != "")
+ result += ":"+port;
+
+ return result;
+};
+
+// ********************************************************************************************* //
+// Conversions
Str.convertToUnicode = function(text, charset)
{
diff --git a/trace/FBTrace/chrome/firebug/content/lib/system.js b/trace/FBTrace/chrome/firebug/content/lib/system.js
index e2e9686..8a3e075 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/system.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/system.js
@@ -37,7 +37,7 @@ System.launchProgram = function(exePath, args)
{
try
{
- var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(exePath);
if (System.getPlatformName() == "Darwin" && file.isDirectory())
{
@@ -62,19 +62,23 @@ System.launchProgram = function(exePath, args)
System.getIconURLForFile = function(path)
{
- var fileHandler = ioService.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
+ var fileHandler = ioService.getProtocolHandler("file")
+ .QueryInterface(Ci.nsIFileProtocolHandler);
+
try
{
- var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
file.initWithPath(path);
- if ((System.getPlatformName() == "Darwin") && !file.isDirectory() && (path.indexOf(".app/") != -1))
+ if ((System.getPlatformName() == "Darwin") && !file.isDirectory() &&
+ (path.indexOf(".app/") != -1))
{
path = path.substr(0,path.lastIndexOf(".app/")+4);
file.initWithPath(path);
}
+
return "moz-icon://" + fileHandler.getURLSpecFromFile(file) + "?size=16";
}
- catch(exc)
+ catch (exc)
{
if (FBTrace.DBG_ERRORS)
FBTrace.sysout("getIconURLForFile ERROR "+exc+" for "+path, exc);
@@ -92,6 +96,44 @@ System.copyToClipboard = function(string)
FBTrace.sysout("system.copyToClipboard; " + string, string);
};
+System.getStringDataFromClipboard = function()
+{
+ // https://developer.mozilla.org/en-US/docs/Using_the_Clipboard#Pasting_Clipboard_Contents
+ var clip = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+ if (!clip)
+ return false;
+
+ var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
+ if (!trans)
+ return false;
+
+ if ("init" in trans)
+ trans.init(null);
+
+ trans.addDataFlavor("text/unicode");
+
+ clip.getData(trans, clip.kGlobalClipboard);
+
+ var str = {};
+ var strLength = {};
+
+ try
+ {
+ trans.getTransferData("text/unicode", str, strLength);
+
+ if (str)
+ {
+ str = str.value.QueryInterface(Ci.nsISupportsString);
+ return str.data.substring(0, strLength.value / 2);
+ }
+ }
+ catch (ex)
+ {
+ }
+
+ return false;
+}
+
// ********************************************************************************************* //
// Firebug Version Comparator
diff --git a/trace/FBTrace/chrome/firebug/content/lib/trace.js b/trace/FBTrace/chrome/firebug/content/lib/trace.js
index d34e2fa..e2e4322 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/trace.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/trace.js
@@ -2,38 +2,61 @@
define([], function() {
-//********************************************************************************************* //
-//Constants
+// ********************************************************************************************* //
+// Constants
const Cu = Components.utils;
-// ********************************************************************************************* //
-// Firebug Trace - FBTrace
-
var scope = {};
+Cu["import"]("resource://firebug/fbtrace.js", scope);
-try
-{
- Cu["import"]("resource://fbtrace/firebug-trace-service.js", scope);
-}
-catch (err)
+// ********************************************************************************************* //
+// Wrapper
+
+/**
+ * Wraps tracer for given option. Logs made through the wrapper will automatically
+ * be checked against the option and only displayed if the option is true.
+ * If FBTrace console isn't installed all options are false and there is no
+ * additional performance penalty.
+ */
+function TraceWrapper(tracer, option)
{
- scope.traceConsoleService =
+ function createMethodWrapper(method)
{
- getTracer: function(prefDomain)
+ return function()
{
- var TraceAPI = ["dump", "sysout", "setScope", "matchesNode", "time", "timeEnd"];
- var TraceObj = {};
- for (var i=0; i<TraceAPI.length; i++)
- TraceObj[TraceAPI[i]] = function() {};
- return TraceObj;
+ // Check the option before the log is passed to the tracing console.
+ if (tracer[option])
+ tracer[method].apply(tracer, arguments);
}
- };
+ }
+
+ for (var i=0; i<TraceAPI.length; i++)
+ {
+ var method = TraceAPI[i];
+ this[method] = createMethodWrapper(method);
+ }
}
// ********************************************************************************************* //
-return scope.traceConsoleService.getTracer("extensions.firebug");
+var tracer = scope.FBTrace;
+
+/**
+ * Support for scoped logging.
+ *
+ * Example:
+ * FBTrace = FBTrace.to("DBG_NET");
+ *
+ * // This log will be displayed only if DBG_NET option is on
+ * FBTrace.sysout("net.initialiaze");
+ */
+tracer.to = function(option)
+{
+ return new TraceWrapper(this, option);
+}
+
+return tracer;
// ********************************************************************************************* //
-});
\ No newline at end of file
+});
diff --git a/trace/FBTrace/chrome/firebug/content/lib/url.js b/trace/FBTrace/chrome/firebug/content/lib/url.js
index 0878656..4ac4ef3 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/url.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/url.js
@@ -313,6 +313,20 @@ Url.getPrettyDomain = function(url)
return m ? m[2] : "";
};
+/**
+ * Returns the base URL for a given window
+ * @param {Object} win DOM window
+ * @returns {String} Base URL
+ */
+Url.getBaseURL = function(win)
+{
+ if (!win)
+ return;
+
+ var base = win.document.getElementsByTagName("base").item(0);
+ return base ? base.href : win.location.href;
+};
+
Url.absoluteURL = function(url, baseURL)
{
// Replace "/./" with "/" using regular expressions (don't use string since /./
@@ -508,6 +522,17 @@ Url.reEncodeURL = function(file, text, noLimit)
return url;
};
+/**
+ * Extracts the URL from a CSS URL definition.
+ * Example: url(../path/to/file) => ../path/to/file
+ * @param {String} url CSS URL definition
+ * @returns {String} Extracted URL
+ */
+Url.extractFromCSS = function(url)
+{
+ return url.replace(/^url\(["']?(.*?)["']?\)$/, "$1");
+};
+
Url.makeURI = function(urlString)
{
try
diff --git a/trace/FBTrace/chrome/firebug/content/lib/wrapper.js b/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
index b4e71f1..232365a 100644
--- a/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
+++ b/trace/FBTrace/chrome/firebug/content/lib/wrapper.js
@@ -19,11 +19,6 @@ Wrapper.getContentView = function(object)
if (typeof(object) === "undefined" || object == null)
return false;
- // There is an exception when accessing StorageList.wrappedJSObject (which is
- // instance of StorageObsolete)
- if ("StorageList" in window && object instanceof window.StorageList)
- return false;
-
return (object.wrappedJSObject);
}
@@ -33,11 +28,6 @@ Wrapper.unwrapObject = function(object)
if (typeof(object) === 'undefined' || object == null)
return object;
- // There is an exception when accessing StorageList.wrappedJSObject (which is
- // instance of StorageObsolete)
- if ("StorageList" in window && object instanceof window.StorageList)
- return object;
-
if (object.wrappedJSObject)
return object.wrappedJSObject;
@@ -88,10 +78,6 @@ Wrapper.unwrapIValueObject = function(scope, viewChrome)
var prop = listValue.value[i];
var name = Wrapper.unwrapIValue(prop.name);
- // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=712289.
- if (typeof name !== "string")
- break;
-
if (prop.value.jsType === prop.value.TYPE_NULL) // null is an object (!)
{
scopeVars[name] = null;
@@ -115,7 +101,6 @@ Wrapper.ignoreVars =
// We are forced to ignore Java-related variables, because
// trying to access them causes browser freeze
- "java": 1,
"sun": 1,
"Packages": 1,
"JavaArray": 1,
@@ -123,6 +108,7 @@ Wrapper.ignoreVars =
"JavaObject": 1,
"JavaClass": 1,
"JavaPackage": 1,
+
// internal firebug things XXXjjb todo we should privatize these
"_firebug": 1,
"_createFirebugConsole": 1,
diff --git a/trace/FBTrace/chrome/firebug/content/main.js b/trace/FBTrace/chrome/firebug/content/main.js
index d73ee9d..649450a 100644
--- a/trace/FBTrace/chrome/firebug/content/main.js
+++ b/trace/FBTrace/chrome/firebug/content/main.js
@@ -24,7 +24,7 @@ if (FBTrace.DBG_INITIALIZE || FBTrace.DBG_MODULES)
try
{
// xxxHonza: temporary hack for Crossfire to provide custom set of modules.
- var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+ var prefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
var value = prefService.getCharPref("extensions.firebug.defaultModuleList");
if (value)
{
diff --git a/trace/FBTrace/chrome/firebug/content/moduleConfig.js b/trace/FBTrace/chrome/firebug/content/moduleConfig.js
index 6eb690c..2a28b70 100644
--- a/trace/FBTrace/chrome/firebug/content/moduleConfig.js
+++ b/trace/FBTrace/chrome/firebug/content/moduleConfig.js
@@ -59,6 +59,7 @@ Firebug.getModuleLoaderConfig = function(baseConfig)
"firebug/css/computedPanel",
"firebug/cookies/cookieModule",
"firebug/cookies/cookiePanel",
+ "firebug/css/selectorPanel",
];
return config;
@@ -84,14 +85,11 @@ Firebug.registerExtension = function(extName, extConfig)
var tempConfig = this.getExtensionConfig(extName);
if (tempConfig)
{
- FBTrace.sysout("firebug.registerExtension; ERROR An extension with the same ID " +
- "already exists! - " + extName, tempConfig);
+ Components.utils.reportError("firebug.registerExtension; ERROR An extension " +
+ "with the same ID already exists! - " + extName, tempConfig);
return;
}
- if (FBTrace.DBG_REGISTRATION)
- FBTrace.sysout("Extension registered: " + extName);
-
this.extensions[extName] = extConfig;
var config = Firebug.getModuleLoaderConfig();
@@ -128,8 +126,8 @@ Firebug.registerExtension = function(extName, extConfig)
}
catch (err)
{
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_REGISTRATION)
- FBTrace.sysout("firebug.main; Extension: " + extName + " EXCEPTION " + err, err);
+ Components.utils.reportError("firebug.main; Extension: " + extName +
+ " EXCEPTION " + err, err);
}
});
}
@@ -153,14 +151,11 @@ Firebug.unregisterExtension = function(extName)
extConfig.app.shutdown();
delete this.extensions[extName];
-
- if (FBTrace.DBG_REGISTRATION)
- FBTrace.sysout("Extension unregistered: " + extName);
}
catch (err)
{
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_REGISTRATION)
- FBTrace.sysout("unregisterExtension: " + extName + " EXCEPTION " + err, err);
+ Components.utils.reportError("unregisterExtension: " + extName +
+ " EXCEPTION " + err, err);
}
}
diff --git a/trace/FBTrace/chrome/firebug/content/net/fontViewer.js b/trace/FBTrace/chrome/firebug/content/net/fontViewer.js
index 2df5d16..0a8c47f 100644
--- a/trace/FBTrace/chrome/firebug/content/net/fontViewer.js
+++ b/trace/FBTrace/chrome/firebug/content/net/fontViewer.js
@@ -283,12 +283,12 @@ Firebug.FontViewerModel.Preview = domplate(
if (target.sourceDisplayed)
{
this.insertMetaDataFormatted(fontInfo, fontObject.metadata);
- target.innerHTML = Locale.$STR("fontviewer.view source");
+ target.textContent = Locale.$STR("fontviewer.view source");
}
else
{
this.insertMetaDataSource(fontInfo, fontObject.metadata);
- target.innerHTML = Locale.$STR("fontviewer.pretty print");
+ target.textContent = Locale.$STR("fontviewer.pretty print");
}
target.sourceDisplayed = !target.sourceDisplayed;
break;
@@ -300,13 +300,13 @@ Firebug.FontViewerModel.Preview = domplate(
{
sample.style.display = "block";
chars.style.display = "none";
- target.innerHTML = Locale.$STR("fontviewer.view characters");
+ target.textContent = Locale.$STR("fontviewer.view characters");
}
else
{
sample.style.display = "none";
chars.style.display = "block";
- target.innerHTML = Locale.$STR("fontviewer.view sample");
+ target.textContent = Locale.$STR("fontviewer.view sample");
}
target.lettersDisplayed = !target.lettersDisplayed;
break;
@@ -539,6 +539,7 @@ Firebug.FontViewerModel.Preview = domplate(
var propValueTemplates = {
vendor: Firebug.FontViewerModel.Preview.vendorTag,
credits: Firebug.FontViewerModel.Preview.creditsTag,
+ description: Firebug.FontViewerModel.Preview.translatedInfoTag,
copyright: Firebug.FontViewerModel.Preview.translatedInfoTag,
trademark: Firebug.FontViewerModel.Preview.translatedInfoTag,
license: Firebug.FontViewerModel.Preview.licenseTag
diff --git a/trace/FBTrace/chrome/firebug/content/net/netMonitor.js b/trace/FBTrace/chrome/firebug/content/net/netMonitor.js
index b22cb8b..de99f1a 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netMonitor.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netMonitor.js
@@ -32,6 +32,7 @@ const Cr = Components.results;
var panelName = "net";
var startFile = NetProgress.prototype.startFile;
+var openingFile = NetProgress.prototype.openingFile;
var requestedFile = NetProgress.prototype.requestedFile;
var respondedFile = NetProgress.prototype.respondedFile;
var respondedCacheFile = NetProgress.prototype.respondedCacheFile;
@@ -399,6 +400,8 @@ var NetHttpObserver =
this.onExamineResponse(subject, win, tabId, context);
else if (topic == "http-on-examine-cached-response")
this.onExamineCachedResponse(subject, win, tabId, context);
+ else if (topic == "http-on-opening-request")
+ this.openingFile(subject, win, tabId, context);
}
catch (err)
{
@@ -517,6 +520,18 @@ var NetHttpObserver =
networkContext.post(respondedCacheFile, [request, NetUtils.now(), info]);
},
+ openingFile: function(request, win, tabId, context)
+ {
+ var networkContext = Firebug.NetMonitor.contexts[tabId];
+ if (!networkContext)
+ networkContext = context ? context.netProgress : null;
+
+ if (!networkContext)
+ return;
+
+ networkContext.post(openingFile, [request, win]);
+ },
+
/* nsISupports */
QueryInterface: function(iid)
{
diff --git a/trace/FBTrace/chrome/firebug/content/net/netPanel.js b/trace/FBTrace/chrome/firebug/content/net/netPanel.js
index bbfd20c..6af088d 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netPanel.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netPanel.js
@@ -312,7 +312,7 @@ NetPanel.prototype = Obj.extend(Firebug.ActivablePanel,
tooltiptext: "net.option.tip.Disable_Browser_Cache",
command: function()
{
- BrowserCache.toggle(!this.getAttribute("checked"));
+ BrowserCache.toggle(!this.hasAttribute("checked"));
}
};
},
@@ -963,10 +963,10 @@ NetPanel.prototype = Obj.extend(Firebug.ActivablePanel,
}
var remoteIPLabel = row.querySelector(".netRemoteAddressCol .netAddressLabel");
- remoteIPLabel.innerHTML = NetRequestEntry.getRemoteAddress(file);
+ remoteIPLabel.textContent = NetRequestEntry.getRemoteAddress(file);
var localIPLabel = row.querySelector(".netLocalAddressCol .netAddressLabel");
- localIPLabel.innerHTML = NetRequestEntry.getLocalAddress(file);
+ localIPLabel.textContent = NetRequestEntry.getLocalAddress(file);
if (file.requestHeaders)
Css.setClass(row, "hasHeaders");
@@ -988,7 +988,7 @@ NetPanel.prototype = Obj.extend(Firebug.ActivablePanel,
var netBar = Dom.getChildByClass(row, "netTimeCol").childNodes[1];
var timeLabel = Dom.getChildByClass(netBar, "netReceivingBar").firstChild;
- timeLabel.innerHTML = NetRequestEntry.getElapsedTime({elapsed: this.elapsed});
+ timeLabel.textContent = NetRequestEntry.getElapsedTime({elapsed: this.elapsed});
if (file.loaded)
Css.setClass(row, "loaded");
@@ -1189,7 +1189,7 @@ NetPanel.prototype = Obj.extend(Firebug.ActivablePanel,
timeText += " (onload: " + NetRequestEntry.formatTime(loadTime) + ")";
}
- timeLabel.innerHTML = timeText;
+ timeLabel.textContent = timeText;
},
summarizePhase: function(phase, rightNow)
diff --git a/trace/FBTrace/chrome/firebug/content/net/netProgress.js b/trace/FBTrace/chrome/firebug/content/net/netProgress.js
index 8b1a22e..849f279 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netProgress.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netProgress.js
@@ -13,10 +13,11 @@ define([
"firebug/lib/string",
"firebug/lib/array",
"firebug/lib/system",
- "firebug/net/netUtils"
+ "firebug/net/netUtils",
+ "firebug/lib/xpcom"
],
function(Obj, Firebug, Locale, Events, Url, SourceLink, Http, Css, Win, Str,
- Arr, System, NetUtils) {
+ Arr, System, NetUtils, Xpcom) {
// ********************************************************************************************* //
// Constants
@@ -27,6 +28,10 @@ const Cr = Components.results;
const CacheService = Cc["@mozilla.org/network/cache-service;1"];
+var versionChecker = Xpcom.CCSV("@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator");
+var appInfo = Xpcom.CCSV("@mozilla.org/xre/app-info;1", "nsIXULAppInfo");
+var fx18 = versionChecker.compare(appInfo.version, "18") >= 0;
+
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const reIgnore = /about:|javascript:|resource:|chrome:|jar:/;
@@ -120,8 +125,28 @@ NetProgress.prototype =
requestNumber: 1,
+ openingFile: function openingFile(request, win)
+ {
+ if (!fx18)
+ return;
+
+ var file = this.getRequestFile(request, win);
+ if (file)
+ {
+ // Parse URL params so, they are available for conditional breakpoints.
+ file.urlParams = Url.parseURLParams(file.href);
+ this.breakOnXHR(file);
+ }
+ },
+
startFile: function startFile(request, win)
{
+ // Called asynchronously since Fx17 so, can't be use for Break on XHR
+ // since JS stack is not available at the moment.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=800799
+ if (fx18)
+ return;
+
var file = this.getRequestFile(request, win);
if (file)
{
@@ -375,6 +400,20 @@ NetProgress.prototype =
file.fromCache = true;
file.aborted = false;
+ try
+ {
+ if (request instanceof Ci.nsIApplicationCacheChannel)
+ {
+ if (request.loadedFromApplicationCache)
+ file.fromAppCache = true;
+ }
+ }
+ catch (e)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("net.respondedCacheFile ERROR " + e, e);
+ }
+
if (request.contentLength >= 0)
file.size = request.contentLength;
diff --git a/trace/FBTrace/chrome/firebug/content/net/netReps.js b/trace/FBTrace/chrome/firebug/content/net/netReps.js
index 6a594ab..c0fd470 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netReps.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netReps.js
@@ -491,14 +491,14 @@ Firebug.NetMonitor.NetRequestEntry = domplate(Firebug.Rep, new Firebug.Listener(
TD({"class": "netCol netProtocolCol a11yFocus", "role" : "gridcell"}),
TD({"class": "netCol netDomainCol a11yFocus", "role" : "gridcell"}),
TD({"class": "netTotalSizeCol netCol netSizeCol a11yFocus", "role": "gridcell"},
- DIV({"class": "netTotalSizeLabel netSummaryLabel"}, "0KB")
+ DIV({"class": "netTotalSizeLabel netSummaryLabel"}, "0 B")
),
TD({"class": "netTotalTimeCol netCol netTimeCol a11yFocus", "role":
"gridcell", colspan: "3"},
DIV({"class": "netSummaryBar", style: "width: 100%"},
DIV({"class": "netCacheSizeLabel netSummaryLabel", collapsed: "true"},
"(",
- SPAN("0KB"),
+ SPAN("0 B"),
SPAN(" " + Locale.$STR("FromCache")),
")"
),
@@ -641,8 +641,11 @@ Firebug.NetMonitor.NetRequestEntry = domplate(Firebug.Rep, new Firebug.Listener(
getHref: function(file)
{
- return (file.method ? file.method.toUpperCase() : "?") + " " +
- Str.cropString(Url.getFileName(file.href), 40);
+ var fileName = Url.getFileName(file.href);
+ var limit = Options.get("stringCropLength");
+ if (limit > 0)
+ fileName = Str.cropString(fileName, limit);
+ return (file.method ? file.method.toUpperCase() : "?") + " " + fileName;
},
getProtocol: function(file)
@@ -665,10 +668,12 @@ Firebug.NetMonitor.NetRequestEntry = domplate(Firebug.Rep, new Firebug.Listener(
text = text ? Str.cropString(text) : " ";
- if (file.fromBFCache)
+ if (file.fromAppCache)
+ text += " (AppCache)";
+ else if (file.fromBFCache)
text += " (BFCache)";
- return text;
+ return text
},
getDomain: function(file)
@@ -684,24 +689,12 @@ Firebug.NetMonitor.NetRequestEntry = domplate(Firebug.Rep, new Firebug.Listener(
getLocalAddress: function(file)
{
- var address = file.localAddress ? file.localAddress : "";
- var port = file.localPort ? file.localPort : "";
-
- var result = address;
- result += result ? ":" : "";
- result += port;
- return result;
+ return Str.formatIP(file.localAddress, file.localPort);
},
getRemoteAddress: function(file)
{
- var address = file.remoteAddress ? file.remoteAddress : "";
- var port = file.remotePort ? file.remotePort : "";
-
- var result = address;
- result += result ? ":" : "";
- result += port;
- return result;
+ return Str.formatIP(file.remoteAddress, file.remotePort);
},
getElapsedTime: function(file)
@@ -1240,8 +1233,7 @@ Firebug.NetMonitor.NetInfoBody = domplate(Firebug.Rep, new Firebug.Listener(),
var object = {
text: Locale.$STR("net.responseSizeLimitMessage"),
onClickLink: function() {
- var panel = context.getPanel("net", true);
- panel.openResponseInTab(file);
+ NetUtils.openResponseInTab(file);
}
};
Firebug.NetMonitor.ResponseSizeLimit.append(object, responseTextBox);
@@ -1641,13 +1633,13 @@ Firebug.NetMonitor.NetInfoHeaders = domplate(Firebug.Rep, new Firebug.Listener()
{
var headers = requestHeaders ? file.requestHeaders : file.responseHeaders;
this.insertHeaderRows(netInfoBox, headers, target.rowName);
- target.innerHTML = Locale.$STR("net.headers.view source");
+ target.textContent = Locale.$STR("net.headers.view source");
}
else
{
var source = requestHeaders ? file.requestHeadersText : file.responseHeadersText;
- this.insertSource(netInfoBox, source, target.rowName);
- target.innerHTML = Locale.$STR("net.headers.pretty print");
+ this.insertSource(netInfoBox, Str.escapeForTextNode(source), target.rowName);
+ target.textContent = Locale.$STR("net.headers.pretty print");
}
target.sourceDisplayed = !target.sourceDisplayed;
@@ -1965,7 +1957,7 @@ Firebug.NetMonitor.SizeInfoTip = domplate(Firebug.Rep,
formatNumber: function(size)
{
- return size.size ? ("(" + Str.formatNumber(size.size) + ")") : "";
+ return size.size && size.size >= 1024 ? "(" + size.size.toLocaleString() + " B)" : "";
},
render: function(file, parentNode)
diff --git a/trace/FBTrace/chrome/firebug/content/net/netUtils.js b/trace/FBTrace/chrome/firebug/content/net/netUtils.js
index 2045d01..64a2f19 100644
--- a/trace/FBTrace/chrome/firebug/content/net/netUtils.js
+++ b/trace/FBTrace/chrome/firebug/content/net/netUtils.js
@@ -51,6 +51,8 @@ const mimeCategoryMap =
"application/rss+xml": "html",
"application/atom+xml": "html",
"application/xhtml+xml": "html",
+ "application/mathml+xml": "html",
+ "application/rdf+xml": "html",
"text/css": "css",
"application/x-javascript": "js",
"text/javascript": "js",
diff --git a/trace/FBTrace/chrome/firebug/content/net/requestObserver.js b/trace/FBTrace/chrome/firebug/content/net/requestObserver.js
index c6d3125..e885554 100644
--- a/trace/FBTrace/chrome/firebug/content/net/requestObserver.js
+++ b/trace/FBTrace/chrome/firebug/content/net/requestObserver.js
@@ -46,6 +46,7 @@ var HttpRequestObserver =
if (!this.observing)
{
+ observerService.addObserver(this, "http-on-opening-request", false);
observerService.addObserver(this, "http-on-modify-request", false);
observerService.addObserver(this, "http-on-examine-response", false);
observerService.addObserver(this, "http-on-examine-cached-response", false);
@@ -62,6 +63,7 @@ var HttpRequestObserver =
if (this.observing)
{
+ observerService.removeObserver(this, "http-on-opening-request");
observerService.removeObserver(this, "http-on-modify-request");
observerService.removeObserver(this, "http-on-examine-response");
observerService.removeObserver(this, "http-on-examine-cached-response");
@@ -83,7 +85,8 @@ var HttpRequestObserver =
// Notify all registered observers.
if (topic == "http-on-modify-request" ||
topic == "http-on-examine-response" ||
- topic == "http-on-examine-cached-response")
+ topic == "http-on-examine-cached-response" ||
+ topic == "http-on-opening-request")
{
this.notifyObservers(subject, topic, data);
}
diff --git a/trace/FBTrace/chrome/firebug/content/net/responseObserver.js b/trace/FBTrace/chrome/firebug/content/net/responseObserver.js
index f742b83..9d3556c 100644
--- a/trace/FBTrace/chrome/firebug/content/net/responseObserver.js
+++ b/trace/FBTrace/chrome/firebug/content/net/responseObserver.js
@@ -15,7 +15,7 @@ const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
-const PrefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch2);
+const PrefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
var redirectionLimit = PrefService.getIntPref("network.http.redirection-limit");
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/content/net/spy.js b/trace/FBTrace/chrome/firebug/content/net/spy.js
index b6bc9c8..7387922 100644
--- a/trace/FBTrace/chrome/firebug/content/net/spy.js
+++ b/trace/FBTrace/chrome/firebug/content/net/spy.js
@@ -22,12 +22,13 @@ define([
"firebug/trace/traceListener",
"firebug/trace/traceModule",
"firebug/lib/wrapper",
+ "firebug/lib/xpcom",
"firebug/net/netPanel",
- "firebug/console/errors"
+ "firebug/console/errors",
],
function(Obj, Firebug, Domplate, FirebugReps, Events, HttpRequestObserver, StackFrame,
Http, Css, Dom, Win, System, Str, Url, Arr, Debug, NetHttpActivityObserver, NetUtils,
- TraceListener, TraceModule, Wrapper) {
+ TraceListener, TraceModule, Wrapper, Xpcom) {
// ********************************************************************************************* //
// Constants
@@ -35,9 +36,16 @@ function(Obj, Firebug, Domplate, FirebugReps, Events, HttpRequestObserver, Stack
const Cc = Components.classes;
const Ci = Components.interfaces;
+var eventListenerService = Cc["@mozilla.org/eventlistenerservice;1"].
+ getService(Ci.nsIEventListenerService);
+
// List of contexts with XHR spy attached.
var contexts = [];
+var versionChecker = Xpcom.CCSV("@mozilla.org/xpcom/version-comparator;1", "nsIVersionComparator");
+var appInfo = Xpcom.CCSV("@mozilla.org/xre/app-info;1", "nsIXULAppInfo");
+var fx18 = versionChecker.compare(appInfo.version, "18") >= 0;
+
// ********************************************************************************************* //
// Spy Module
@@ -86,14 +94,16 @@ Firebug.Spy = Obj.extend(Firebug.Module,
// For any spies that are in progress, remove our listeners so that they don't leak
this.detachObserver(context, null);
- if (FBTrace.DBG_SPY && context.spies.length)
+ if (FBTrace.DBG_SPY && context.spies && context.spies.length)
+ {
FBTrace.sysout("spy.destroyContext; ERROR There are spies in progress ("
+ context.spies.length + ") " + context.getName());
+ }
// Make sure that all Spies in progress are detached at this moment.
// Clone the array beforehand since the spy object is removed from the
// original array within detach.
- var spies = Arr.cloneArray(context.spies);
+ var spies = context.spies ? Arr.cloneArray(context.spies) : [];
for (var i=0; i<spies.length; i++)
spies[i].detach(true);
@@ -276,16 +286,13 @@ var SpyHttpObserver =
{
try
{
- if (topic != "http-on-modify-request" &&
- topic != "http-on-examine-response" &&
- topic != "http-on-examine-cached-response")
+ if ((topic == "http-on-modify-request" && !fx18) ||
+ topic == "http-on-opening-request" ||
+ topic == "http-on-examine-response" ||
+ topic == "http-on-examine-cached-response")
{
- if (FBTrace.DBG_ERRORS || FBTrace.DBG_SPY)
- FBTrace.sysout("spy.SpyHttpObserver.observe; ERROR Unknown topic: " + topic);
- return;
+ this.observeRequest(request, topic);
}
-
- this.observeRequest(request, topic);
}
catch (exc)
{
@@ -313,7 +320,9 @@ var SpyHttpObserver =
var requestName = request.URI.asciiSpec;
var requestMethod = request.requestMethod;
- if (topic == "http-on-modify-request")
+ if (topic == "http-on-modify-request" && !fx18)
+ this.requestStarted(request, xhr, spyContext, requestMethod, requestName);
+ if (topic == "http-on-opening-request")
this.requestStarted(request, xhr, spyContext, requestMethod, requestName);
else if (topic == "http-on-examine-response")
this.requestStopped(request, xhr, spyContext, requestMethod, requestName);
@@ -526,6 +535,16 @@ function getSpyForXHR(request, xhrRequest, context, noCreate)
{
var spy = null;
+ if (!context.spies)
+ {
+ if (FBTrace.DBG_ERRORS)
+ {
+ FBTrace.sysout("spy.getSpyForXHR; ERROR no spies array " +
+ Http.safeGetRequestName(request));
+ }
+ return;
+ }
+
// Iterate all existing spy objects in this context and look for one that is
// already created for this request.
var length = context.spies.length;
@@ -587,26 +606,45 @@ Firebug.Spy.XMLHttpRequestSpy.prototype =
attach: function()
{
var spy = this;
+
this.onReadyStateChange = function(event) { onHTTPSpyReadyStateChange(spy, event); };
this.onLoad = function() { onHTTPSpyLoad(spy); };
this.onError = function() { onHTTPSpyError(spy); };
this.onAbort = function() { onHTTPSpyAbort(spy); };
- // xxxHonza: #502959 is still failing on Fx 3.5
- // Use activity distributor to identify 3.6
- if (SpyHttpActivityObserver.getActivityDistributor())
+ this.onEventListener = function(event)
+ {
+ switch (event.type)
+ {
+ case "readystatechange":
+ onHTTPSpyReadyStateChange(spy, event);
+ break;
+ case "load":
+ onHTTPSpyLoad(spy);
+ break;
+ case "error":
+ onHTTPSpyError(spy);
+ break;
+ case "abort":
+ onHTTPSpyAbort(spy);
+ break;
+ }
+ };
+
+ if (typeof(eventListenerService.addListenerForAllEvents) == "function")
+ {
+ eventListenerService.addListenerForAllEvents(this.xhrRequest,
+ this.onEventListener, true, false, false);
+ }
+ else
{
this.onreadystatechange = this.xhrRequest.onreadystatechange;
this.xhrRequest.onreadystatechange = this.onReadyStateChange;
- }
- this.xhrRequest.addEventListener("load", this.onLoad, false);
- this.xhrRequest.addEventListener("error", this.onError, false);
- this.xhrRequest.addEventListener("abort", this.onAbort, false);
-
- // xxxHonza: should be removed from FB 3.6
- if (!SpyHttpActivityObserver.getActivityDistributor())
- this.context.sourceCache.addListener(this);
+ this.xhrRequest.addEventListener("load", this.onLoad, false);
+ this.xhrRequest.addEventListener("error", this.onError, false);
+ this.xhrRequest.addEventListener("abort", this.onAbort, false);
+ }
if (FBTrace.DBG_SPY)
FBTrace.sysout("spy.attach; " + Http.safeGetRequestName(this.request));
@@ -615,7 +653,7 @@ Firebug.Spy.XMLHttpRequestSpy.prototype =
detach: function(force)
{
// Bubble out if already detached.
- if (!this.onLoad)
+ if (!this.onEventListener)
return;
// If the activity distributor is available, let's detach it when the XHR
@@ -637,21 +675,27 @@ Firebug.Spy.XMLHttpRequestSpy.prototype =
// Remove itself from the list of active spies.
Arr.remove(this.context.spies, this);
- if (this.onreadystatechange)
- this.xhrRequest.onreadystatechange = this.onreadystatechange;
+ if (typeof(eventListenerService.addListenerForAllEvents) == "function")
+ {
+ eventListenerService.removeListenerForAllEvents(this.xhrRequest,
+ this.onEventListener, true, false);
+ }
+ else
+ {
+ if (this.onreadystatechange)
+ this.xhrRequest.onreadystatechange = this.onreadystatechange;
- try { this.xhrRequest.removeEventListener("load", this.onLoad, false); } catch (e) {}
- try { this.xhrRequest.removeEventListener("error", this.onError, false); } catch (e) {}
- try { this.xhrRequest.removeEventListener("abort", this.onAbort, false); } catch (e) {}
+ try { this.xhrRequest.removeEventListener("load", this.onLoad, false); } catch (e) {}
+ try { this.xhrRequest.removeEventListener("error", this.onError, false); } catch (e) {}
+ try { this.xhrRequest.removeEventListener("abort", this.onAbort, false); } catch (e) {}
+ }
this.onreadystatechange = null;
this.onLoad = null;
this.onError = null;
this.onAbort = null;
- // xxxHonza: shouuld be removed from FB 1.6
- if (!SpyHttpActivityObserver.getActivityDistributor())
- this.context.sourceCache.removeListener(this);
+ this.onEventListener = null;
},
getURL: function()
@@ -680,8 +724,10 @@ Firebug.Spy.XMLHttpRequestSpy.prototype =
function onHTTPSpyReadyStateChange(spy, event)
{
if (FBTrace.DBG_SPY)
+ {
FBTrace.sysout("spy.onHTTPSpyReadyStateChange " + spy.xhrRequest.readyState +
" (multipart: " + spy.xhrRequest.multipart + ")");
+ }
// Remember just in case spy is detached (readyState == 4).
var originalHandler = spy.onreadystatechange;
@@ -710,16 +756,7 @@ function onHTTPSpyReadyStateChange(spy, event)
if (spy.xhrRequest.readyState == 4)
{
// Cumulate response so that multipart response content is properly displayed.
- if (SpyHttpActivityObserver.getActivityDistributor())
- {
- spy.responseText += Http.safeGetXHRResponseText(spy.xhrRequest);
- }
- else
- {
- // xxxHonza: remove from FB 1.6
- if (!spy.responseText)
- spy.responseText = Http.safeGetXHRResponseText(spy.xhrRequest);
- }
+ spy.responseText += Http.safeGetXHRResponseText(spy.xhrRequest);
// The XHR is loaded now (used also by the activity observer).
spy.loaded = true;
@@ -740,7 +777,44 @@ function onHTTPSpyReadyStateChange(spy, event)
}
// Pass the event to the original page handler.
- callPageHandler(spy, event, originalHandler);
+ if (typeof(eventListenerService.addListenerForAllEvents) == "undefined")
+ callPageHandler(spy, event, originalHandler);
+}
+
+function callPageHandler(spy, event, originalHandler)
+{
+ try
+ {
+ // Calling the page handler throwed an exception (see #502959)
+ // This should be fixed in Firefox 3.5
+ if (originalHandler && event)
+ {
+ if (originalHandler.handleEvent)
+ originalHandler.handleEvent(event);
+ else
+ originalHandler.call(spy.xhrRequest, event);
+ }
+ }
+ catch (exc)
+ {
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("spy.onHTTPSpyReadyStateChange: EXCEPTION " + exc, [exc, event]);
+
+ var xpcError = Firebug.Errors.reparseXPC(exc, spy.context);
+ if (xpcError)
+ {
+ // TODO attach trace
+ if (FBTrace.DBG_ERRORS)
+ FBTrace.sysout("spy.onHTTPSpyReadyStateChange: reparseXPC", xpcError);
+
+ // Make sure the exception is displayed in both Firefox & Firebug console.
+ throw new Error(xpcError.message, xpcError.href, xpcError.lineNo);
+ }
+ else
+ {
+ throw exc;
+ }
+ }
}
function onHTTPSpyLoad(spy)
@@ -752,10 +826,6 @@ function onHTTPSpyLoad(spy)
// onAbort would not be handled.
spy.detach(false);
- // xxxHonza: Still needed for Fx 3.5 (#502959)
- if (!SpyHttpActivityObserver.getActivityDistributor())
- onHTTPSpyReadyStateChange(spy, null);
-
// If the spy is not loaded yet (and so, the response was not cached), do it now.
// This can happen since synchronous XHRs don't fire onReadyStateChange event (issue 2868).
if (!spy.loaded)
@@ -812,44 +882,6 @@ function onHTTPSpyAbort(spy)
// ********************************************************************************************* //
-function callPageHandler(spy, event, originalHandler)
-{
- try
- {
- // Calling the page handler throwed an exception (see #502959)
- // This should be fixed in Firefox 3.5
- if (originalHandler && event)
- {
- if (originalHandler.handleEvent)
- originalHandler.handleEvent(event);
- else
- originalHandler.call(spy.xhrRequest, event);
- }
- }
- catch (exc)
- {
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("spy.onHTTPSpyReadyStateChange: EXCEPTION " + exc, [exc, event]);
-
- var xpcError = Firebug.Errors.reparseXPC(exc, spy.context);
- if (xpcError) //
- {
- // TODO attach trace
- if (FBTrace.DBG_ERRORS)
- FBTrace.sysout("spy.onHTTPSpyReadyStateChange: reparseXPC", xpcError);
-
- // Make sure the exception is displayed in both Firefox & Firebug console.
- throw new Error(xpcError.message, xpcError.href, xpcError.lineNo);
- }
- else
- {
- throw exc;
- }
- }
-}
-
-// ********************************************************************************************* //
-
/**
* @domplate Represents a template for XHRs logged in the Console panel. The body of the
* log (displayed when expanded) is rendered using {@link Firebug.NetMonitor.NetInfoBody}.
diff --git a/trace/FBTrace/chrome/firebug/content/net/xmlViewer.js b/trace/FBTrace/chrome/firebug/content/net/xmlViewer.js
index 499b32b..d6664e7 100644
--- a/trace/FBTrace/chrome/firebug/content/net/xmlViewer.js
+++ b/trace/FBTrace/chrome/firebug/content/net/xmlViewer.js
@@ -24,6 +24,7 @@ var xmlContentTypes =
"application/rss+xml",
"application/atom+xml",,
"application/vnd.mozilla.maybe.feed",
+ "application/mathml+xml",
"application/rdf+xml",
"application/vnd.mozilla.xul+xml"
];
diff --git a/trace/FBTrace/chrome/firebug/content/trace.js b/trace/FBTrace/chrome/firebug/content/trace.js
index b9c12f9..494fdae 100644
--- a/trace/FBTrace/chrome/firebug/content/trace.js
+++ b/trace/FBTrace/chrome/firebug/content/trace.js
@@ -14,22 +14,22 @@ var FBTrace = {};
try
{
var scope = {};
- Components.utils["import"]("resource://firebug/firebug-trace-service.js", scope);
- FBTrace = scope.traceConsoleService.getTracer("extensions.firebug");
+ Components.utils["import"]("resource://firebug/fbtrace.js", scope);
+ FBTrace = scope.FBTrace;
FBTrace.setScope(window);
function clearFBTraceScope()
{
- window.removeEventListener('unload', clearFBTraceScope, true);
+ window.removeEventListener("unload", clearFBTraceScope, true);
FBTrace.setScope(null);
}
- window.addEventListener('unload', clearFBTraceScope, true);
+ window.addEventListener("unload", clearFBTraceScope, true);
FBTrace.time("SCRIPTTAG_TIME");
}
catch (err)
{
- dump("FBTrace; " + err);
+ Components.utils.reportError(err);
}
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/firebug-http-observer.js b/trace/FBTrace/chrome/firebug/modules/firebug-http-observer.js
index 9e7aee6..304b629 100644
--- a/trace/FBTrace/chrome/firebug/modules/firebug-http-observer.js
+++ b/trace/FBTrace/chrome/firebug/modules/firebug-http-observer.js
@@ -1,21 +1,22 @@
/* See license.txt for terms of usage */
-// ************************************************************************************************
+// ********************************************************************************************* //
// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
+const Cu = Components.utils;
var EXPORTED_SYMBOLS = ["httpRequestObserver"];
var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
var categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
-// ************************************************************************************************
-// HTTP Request Observer implementation
+Cu["import"]("resource://firebug/fbtrace.js");
-var FBTrace = null;
+// ********************************************************************************************* //
+// HTTP Request Observer implementation
/**
* @service This service is intended as the only HTTP observer registered by Firebug.
@@ -33,12 +34,6 @@ var httpRequestObserver =
{
this.observers = [];
this.observing = 0;
-
- // Get firebug-trace service for logging (the service should be already
- // registered at this moment).
- Components.utils["import"]("resource://firebug/firebug-trace-service.js");
- FBTrace = traceConsoleService.getTracer("extensions.firebug");
-
this.initialize();
},
@@ -66,6 +61,7 @@ var httpRequestObserver =
if (!this.observing)
{
+ observerService.addObserver(this, "http-on-opening-request", false);
observerService.addObserver(this, "http-on-modify-request", false);
observerService.addObserver(this, "http-on-examine-response", false);
observerService.addObserver(this, "http-on-examine-cached-response", false);
@@ -82,6 +78,7 @@ var httpRequestObserver =
if (this.observing)
{
+ observerService.removeObserver(this, "http-on-opening-request");
observerService.removeObserver(this, "http-on-modify-request");
observerService.removeObserver(this, "http-on-examine-response");
observerService.removeObserver(this, "http-on-examine-cached-response");
@@ -109,7 +106,8 @@ var httpRequestObserver =
", " + safeGetName(subject));
// Notify all registered observers.
- if (topic == "http-on-modify-request" ||
+ if (topic == "http-on-opening-request" ||
+ topic == "http-on-modify-request" ||
topic == "http-on-examine-response" ||
topic == "http-on-examine-cached-response")
{
@@ -185,7 +183,7 @@ var httpRequestObserver =
}
}
-// ************************************************************************************************
+// ********************************************************************************************* //
// Request helpers
function safeGetName(request)
@@ -201,9 +199,9 @@ function safeGetName(request)
return null;
}
-// ************************************************************************************************
+// ********************************************************************************************* //
+// Debugging Helpers
-// Debugging helper.
function dumpStack(message)
{
dump(message + "\n");
@@ -220,7 +218,9 @@ function dumpStack(message)
}
}
-// ************************************************************************************************
+// ********************************************************************************************* //
// Initialization
httpRequestObserver.preInitialize();
+
+// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/firebug-service.js b/trace/FBTrace/chrome/firebug/modules/firebug-service.js
index 4299987..3ecc89f 100644
--- a/trace/FBTrace/chrome/firebug/modules/firebug-service.js
+++ b/trace/FBTrace/chrome/firebug/modules/firebug-service.js
@@ -30,7 +30,6 @@ const jsdIErrorHook = Ci.jsdIErrorHook;
const jsdIFilter = Components.interfaces.jsdIFilter;
const nsISupports = Ci.nsISupports;
const nsIPrefBranch = Ci.nsIPrefBranch;
-const nsIPrefBranch2 = Ci.nsIPrefBranch2;
const nsIComponentRegistrar = Ci.nsIComponentRegistrar;
const nsIFactory = Ci.nsIFactory;
const nsIConsoleService = Ci.nsIConsoleService;
@@ -147,7 +146,7 @@ var errorInfo = null;
var timer = Timer.createInstance(nsITimer);
var waitingForTimer = false;
-var FBTrace = null;
+Cu.import("resource://firebug/fbtrace.js");
// ********************************************************************************************* //
@@ -729,10 +728,6 @@ var fbs =
{
initialize: function()
{
- Components.utils.import("resource://firebug/firebug-trace-service.js");
-
- FBTrace = traceConsoleService.getTracer("extensions.firebug");
-
if (FBTrace.DBG_FBS_ERRORS)
FBTrace.sysout("fbs.FirebugService Starting");
@@ -754,7 +749,7 @@ var fbs =
this.profiling = false;
- prefs = PrefService.getService(nsIPrefBranch2);
+ prefs = PrefService.getService(nsIPrefBranch);
fbs.prefDomain = "extensions.firebug";
prefs.addObserver(fbs.prefDomain, fbs, false);
@@ -1576,61 +1571,8 @@ var fbs =
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
- /**
- * Do not activate JSD, which is broken in Firefox 9 on Mac and Linux 32 bit
- * This method is checking the current platform & browser configuration and
- * return false for Mac/Linux 32 bit
- *
- * See: https://bugzilla.mozilla.org/show_bug.cgi?id=712289
- *
- * Can be removed when the min Firefox version is 10
- *
- * Search for 'bug712289' within the source code to remove all find all related
- * parts of this workaround.
- */
- isJSDAvailable: function()
- {
- if (typeof(this._isJSDAvailable) == "undefined")
- {
- var systemInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
-
- // Check the current OS, must not be Mac or Linux 32 bit
- var os = systemInfo.XPCOMABI == "x86-gcc3";
-
- // Check the current Firefox version, must not be 9
- systemInfo = systemInfo.QueryInterface(Ci.nsIXULAppInfo);
- var ff = systemInfo.version.indexOf("9.") == 0;
-
- // If one or another is false, JSD is available.
- this._isJSDAvailable = !(os && ff);
-
- if (!this._isJSDAvailable)
- {
- try
- {
- consoleService = ConsoleService.getService(nsIConsoleService);
- consoleService.logStringMessage(
- "WARNING: Firebug Script panel is disabled in Firefox " +
- systemInfo.version + " running on 32 bit Mac or Linux (" +
- systemInfo.XPCOMABI + ")");
- }
- catch (err)
- {
- }
- }
- }
-
- return this._isJSDAvailable;
- },
-
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
-
enableDebugger: function()
{
- // bug712289
- if (!this.isJSDAvailable())
- return;
-
if (waitingForTimer)
{
timer.cancel();
@@ -3816,7 +3758,7 @@ var fbs =
var bps = breakpointStore.getItem(url);
// Do not restore "Run unit this line" breakpoints. This should solve complaints
- // about Firebug braking in the sourece even if there are no breakpoints in
+ // about Firebug breaking in the source even if there are no breakpoints in
// Firebug UI.
if (bps.type == BP_UNTIL)
continue;
@@ -4096,7 +4038,7 @@ var fbs =
// stack empty
if (unhookAtBottom && hookFrameCount == 0)
- this.unhookFunctions();
+ fbs.unhookFunctions();
contextCached = callBack(contextCached, frame, hookFrameCount, false);
break;
diff --git a/trace/FBTrace/chrome/firebug/modules/firebug-trace-service.js b/trace/FBTrace/chrome/firebug/modules/firebug-trace-service.js
index 830dd61..413f63f 100644
--- a/trace/FBTrace/chrome/firebug/modules/firebug-trace-service.js
+++ b/trace/FBTrace/chrome/firebug/modules/firebug-trace-service.js
@@ -1,37 +1,290 @@
/* See license.txt for terms of usage */
-// ************************************************************************************************
+// ********************************************************************************************* //
// Constants
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
+const Cu = Components.utils;
var EXPORTED_SYMBOLS = ["traceConsoleService"];
-// ************************************************************************************************
-// Service implementation
+const PrefService = Cc["@mozilla.org/preferences-service;1"];
+const prefs = PrefService.getService(Ci.nsIPrefBranch);
+const prefService = PrefService.getService(Ci.nsIPrefService);
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/AddonManager.jsm");
+
+// xxxHonza: could we remove some of them?
+var TraceAPI = ["dump", "sysout", "setScope", "matchesNode", "time", "timeEnd"];
+
+// ********************************************************************************************* //
+// Service Implementation
-/**
- * This implementation serves as a proxy to the FBTrace extension. All logs are forwarded
- * to the FBTrace service.
- */
try
{
- Components.utils["import"]("resource://fbtrace/firebug-trace-service.js");
+ Cu["import"]("resource://fbtrace/firebug-trace-service.js");
}
catch (err)
{
+ // Tracing Console is not available yet, let's use a fake one.
var traceConsoleService =
{
+ tracers: {},
+
getTracer: function(prefDomain)
{
- var TraceAPI = ["dump", "sysout", "setScope", "matchesNode", "time", "timeEnd"];
- var TraceObj = {};
- for (var i=0; i<TraceAPI.length; i++)
- TraceObj[TraceAPI[i]] = function() {};
- return TraceObj;
+ var tracer = this.tracers[prefDomain];
+ if (tracer)
+ return tracer;
+
+ var enabledAddons = decodeURIComponent(getCharPref("extensions", "enabledAddons"));
+ if (enabledAddons.indexOf("fbtrace at getfirebug.com:") >= 0)
+ {
+ // Solution with built-in buffer for logs created before console is ready.
+ var wrapper = new TracerWrapper(prefDomain);
+ tracer = wrapper.createTracer();
+ }
+ else
+ {
+ // Simple empty implementation for cases where Firebug Tracing Console
+ // is not even installed or 'alwaysOpenTraceConsole' is set to false.
+ tracer = {};
+ for (var i=0; i<TraceAPI.length; i++)
+ tracer[TraceAPI[i]] = function() {};
+ }
+
+ this.tracers[prefDomain] = tracer;
+ return tracer;
+ },
+ }
+}
+
+// ********************************************************************************************* //
+// Tracer Wrapper
+
+/**
+ * Trace Wrapper represents a temporary Trace object that is used till the real Tracing
+ * Console is opened and available to use. Trace Wrapper implements a buffer that
+ * collects all logs and flushes them as intot the real console as soon as it's ready.
+ *
+ * In order to use this functionality, you need to set:
+ * 'extensions.firebug.alwaysOpenTraceConsole' to true
+ *
+ * @param {Object} prefDomain Associated pref domain. Usually 'extensions.firebug'
+ */
+function TracerWrapper(prefDomain)
+{
+ this.prefDomain = prefDomain;
+}
+
+TracerWrapper.prototype =
+{
+ // Temporary trace object
+ tracer: null,
+
+ // Buffer with logs used till the Tracing Console UI is available
+ queue: [],
+
+ // The real tracing console tracer object.
+ FBTrace: null,
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Tracer
+
+ createTracer: function()
+ {
+ var self = this;
+
+ this.addObserver();
+
+ // Default FBTrace implementation puts all calls in a buffer.
+ // It'll be used as soon as the console is ready.
+ function createHandler(method)
+ {
+ return function() {
+ self.push(method, arguments);
+ }
+ };
+
+ // Fake FBTrace object
+ this.tracer = {};
+
+ // Dynamically create APIs.
+ for (var i=0; i<TraceAPI.length; i++)
+ {
+ var method = TraceAPI[i];
+ this.tracer[method] = createHandler(method);
+ }
+
+ var branch = prefService.getBranch(this.prefDomain);
+ var arrayDesc = {};
+
+ // Set options from preferences.
+ var children = branch.getChildList("", arrayDesc);
+ for (var i=0; i<children.length; i++)
+ {
+ var name = children[i];
+ var m = name.indexOf("DBG_");
+ if (m != -1)
+ {
+ var optionName = name.substr(1); // drop leading .
+ this.tracer[optionName] = getBoolPref(this.prefDomain, optionName);
+ }
+ }
+
+ // Create FBTrace proxy. As soon as FBTrace console is available it'll forward
+ // all calls to it.
+ return Proxy.create(
+ {
+ get: function(target, name)
+ {
+ if (self.FBTrace)
+ return self.FBTrace[name];
+
+ return self.FBTrace ? self.FBTrace[name] : self.tracer[name];
+ },
+
+ set: function(target, name, value)
+ {
+ if (self.FBTrace)
+ self.FBTrace[name] = value;
+
+ return true;
+ },
+ });
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // Buffer
+
+ push: function(method, args)
+ {
+ if (!this.queue)
+ return;
+
+ this.queue.push({
+ method: method,
+ args: args,
+ });
+
+ // Size of the buffer is limited.
+ while (this.queue.length > 1000)
+ this.queue.pop();
+ },
+
+ clearBuffer: function()
+ {
+ this.queue = null;
+ },
+
+ flush: function()
+ {
+ if (!this.FBTrace || !this.queue)
+ return;
+
+ if (this.queue.length > 0)
+ this.FBTrace.sysout("FBTrace: flush " + this.queue.length + " buffered logs:");
+
+ for (var i=0; i<this.queue.length; i++)
+ {
+ var call = this.queue[i];
+ this.FBTrace[call.method].apply(this.FBTrace, call.args);
+ }
+
+ this.clearBuffer();
+ },
+
+ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+ // FBTrace Console Observer
+
+ addObserver: function()
+ {
+ // Listen for new windows, Firebug must be loaded into them too.
+ Services.obs.addObserver(this, "chrome-document-global-created", false);
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+ observe: function windowWatcher(win, topic, data)
+ {
+ // xxxHonza: the window should be associated with the same prefDomain.
+ if (win.location.href == "chrome://fbtrace/content/traceLogFrame.html")
+ {
+ var self = this;
+
+ // https://bugzil.la/795961 ?
+ win.addEventListener("load", function onLoad(evt)
+ {
+ // load listener not necessary once https://bugzil.la/800677 is fixed
+ var win = evt.currentTarget;
+ win.removeEventListener("load", onLoad, false);
+
+ self.initFBTrace(self.prefDomain);
+ }, false);
+ }
+ },
+
+ initFBTrace: function()
+ {
+ if (this.FBTrace)
+ return this.FBTrace;
+
+ try
+ {
+ var scope = {};
+ Cu.import("resource://fbtrace/firebug-trace-service.js", scope);
+ this.FBTrace = scope.traceConsoleService.getTracer(this.prefDomain);
+
+ // FBTrace Console is ready let's flush the log buffer.
+ this.flush();
+ }
+ catch (err)
+ {
}
- };
+ }
+}
+
+// ********************************************************************************************* //
+// Helpers
+
+function getStackDump()
+{
+ var lines = [];
+ for (var frame = Components.stack; frame; frame = frame.caller)
+ lines.push(frame.filename + " (" + frame.lineNumber + ")");
+
+ return lines.join("\n");
+};
+
+function getBoolPref(prefDomain, name)
+{
+ try
+ {
+ var prefName = prefDomain + "." + name;
+ return prefs.getBoolPref(prefName);
+ }
+ catch (err)
+ {
+ }
+
+ return false;
+}
+
+function getCharPref(prefDomain, name)
+{
+ try
+ {
+ var prefName = prefDomain + "." + name;
+ return prefs.getCharPref(prefName);
+ }
+ catch (err)
+ {
+ }
+
+ return false;
}
+// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/gcli.js b/trace/FBTrace/chrome/firebug/modules/gcli.js
index c8210af..ac06469 100644
--- a/trace/FBTrace/chrome/firebug/modules/gcli.js
+++ b/trace/FBTrace/chrome/firebug/modules/gcli.js
@@ -7,7 +7,7 @@ var Cc = Components.classes;
var Ci = Components.interfaces;
var Cu = Components.utils;
-var EXPORTED_SYMBOLS = [];
+var EXPORTED_SYMBOLS = ["FirebugGCLICommands"];
// ********************************************************************************************* //
// GCLI
@@ -24,12 +24,28 @@ catch (err)
FBTrace.sysout("GCLI not available");
}
+// Load the Locale module and make sure Firebug string bundle is registered
+// (GCLI commands needs to be localized)
+var Locale = Cu.import("resource://firebug/locale.js").Locale;
+Locale.registerStringBundle("chrome://firebug/locale/firebug.properties");
+
if (scope.gcli) {
// ********************************************************************************************* //
-// Services
+// FirebugGCLICommands
-var Locale = Cu.import("resource://firebug/locale.js").Locale;
+var FirebugGCLICommands =
+{
+ startup: function()
+ {
+ registerCommands();
+ },
+
+ shutdown: function()
+ {
+ unregisterCommands();
+ }
+}
// ********************************************************************************************* //
// Command Implementation
@@ -90,7 +106,7 @@ var FirebugController =
if (!Firebug)
return;
- Firebug.GlobalUI.startFirebug(function(Firebug) {
+ Firebug.browserOverlay.startFirebug(function(Firebug) {
callback(Firebug);
});
},
@@ -99,40 +115,59 @@ var FirebugController =
// ********************************************************************************************* //
// Registration
-scope.gcli.addCommand({
- name: "firebug",
- description: "Web Development Evolved"
-});
-
-scope.gcli.addCommand({
- name: "firebug open",
- description: Locale.$STR("firebug.menu.tip.Open_Firebug"),
- exec: FirebugController.openFirebug.bind(FirebugController)
-});
-
-scope.gcli.addCommand({
- name: "firebug hide",
- description: Locale.$STR("firebug.menu.tip.Minimize_Firebug"),
- exec: FirebugController.hideFirebug.bind(FirebugController)
-});
-
-scope.gcli.addCommand({
- name: "firebug close",
- description: Locale.$STR("firebug.shortcut.tip.closeFirebug"),
- exec: FirebugController.closeFirebug.bind(FirebugController)
-});
-
-scope.gcli.addCommand({
- name: "firebug detach",
- description: Locale.$STR("firebug.DetachFirebug"),
- exec: FirebugController.detachFirebug.bind(FirebugController)
-});
-
-scope.gcli.addCommand({
- name: "firebug attach",
- description: Locale.$STR("firebug.AttachFirebug"),
- exec: FirebugController.attachFirebug.bind(FirebugController)
-});
+var commands = [];
+
+function addCommand(command)
+{
+ scope.gcli.addCommand(command);
+ commands.push(command);
+}
+
+function registerCommands()
+{
+ addCommand({
+ name: "firebug",
+ description: "Web Development Evolved"
+ });
+
+ addCommand({
+ name: "firebug open",
+ description: Locale.$STR("firebug.menu.tip.Open_Firebug"),
+ exec: FirebugController.openFirebug.bind(FirebugController)
+ });
+
+ addCommand({
+ name: "firebug hide",
+ description: Locale.$STR("firebug.menu.tip.Minimize_Firebug"),
+ exec: FirebugController.hideFirebug.bind(FirebugController)
+ });
+
+ addCommand({
+ name: "firebug close",
+ description: Locale.$STR("firebug.shortcut.tip.closeFirebug"),
+ exec: FirebugController.closeFirebug.bind(FirebugController)
+ });
+
+ addCommand({
+ name: "firebug detach",
+ description: Locale.$STR("firebug.DetachFirebug"),
+ exec: FirebugController.detachFirebug.bind(FirebugController)
+ });
+
+ addCommand({
+ name: "firebug attach",
+ description: Locale.$STR("firebug.AttachFirebug"),
+ exec: FirebugController.attachFirebug.bind(FirebugController)
+ });
+}
+
+function unregisterCommands()
+{
+ for (var i=0; i<commands.length; i++)
+ scope.gcli.removeCommand(commands[i]);
+
+ commands = [];
+}
// ********************************************************************************************* //
}
diff --git a/trace/FBTrace/chrome/firebug/modules/loader.js b/trace/FBTrace/chrome/firebug/modules/loader.js
index 0e0653a..7b9fd9e 100644
--- a/trace/FBTrace/chrome/firebug/modules/loader.js
+++ b/trace/FBTrace/chrome/firebug/modules/loader.js
@@ -10,10 +10,7 @@ var Ci = Components.interfaces;
var Cu = Components.utils;
Cu.import("resource://gre/modules/Services.jsm");
-
-// xxxHonza: this breaks tracing, needs to be fixed.
-//Components.utils.import("resource://firebug/fbtrace.js");
-var FBTrace = {};
+Cu.import("resource://firebug/fbtrace.js");
// ********************************************************************************************* //
@@ -118,28 +115,50 @@ var FirebugLoader =
}
[getRoots(win.document), getRoots(win.gNavToolbox.palette),
- fbug.GlobalUI.nodesToRemove].forEach(function(list)
+ fbug.browserOverlay.nodesToRemove].forEach(function(list)
{
for each(var el in list)
if (el && el.parentNode)
el.parentNode.removeChild(el);
});
+ win.Firebug.browserOverlay.unloadContextMenuOverlay(win);
+
delete win.Firebug;
delete win.FBTrace;
delete win.FBL;
},
- loadIntoWindow: function(win)
+ loadIntoWindow: function(win, reason)
{
// This is the place where the global Firebug object is created. This object represents
// the entire application and all consequently created namespaces and variables should be
// injected into it.
// In the future, there should *not* be any other globals except of the Firebug object.
+ // xxxHonza: properties from this object are copied into the new Firebug obect that is
+ // created within "firebug/firebug" module (a hack).
win.Firebug = {};
- // Apply all Firefox/SeaMonkey overlays to the browser window.
- loadSubscript("chrome://firebug/content/firefox/browserOverlay.js", win);
+ var requireScope = {};
+ Cu.import("resource://firebug/mini-require.js", requireScope);
+ var require = requireScope.require;
+
+ var config = {
+ baseUrl: "resource://",
+ paths: {"firebug": "chrome://firebug/content"}
+ };
+
+ require(config, [
+ "firebug/firefox/browserOverlay"
+ ],
+ function(BrowserOverlay)
+ {
+ var overlay = win.Firebug.browserOverlay = new BrowserOverlay(win);
+ overlay.initialize(reason);
+ });
+
+ if (FBTrace.DBG_MODULES)
+ FBTrace.sysout("Basic loader dependencies: " + require.Loader.getDepDesc());
// Firebug extensions should initialize here.
this.dispatchToScopes("topWindowLoad", [win]);
diff --git a/trace/FBTrace/chrome/firebug/modules/locale.js b/trace/FBTrace/chrome/firebug/modules/locale.js
index 751e914..d3baede 100644
--- a/trace/FBTrace/chrome/firebug/modules/locale.js
+++ b/trace/FBTrace/chrome/firebug/modules/locale.js
@@ -14,23 +14,9 @@ var EXPORTED_SYMBOLS = [];
// ********************************************************************************************* //
// Services
-// xxxHonza: FBTrace console doesn't have to exist at this point (Firebug is bootstrapped).
-// In such case an empty object is created and all consequent logs are not visible in the
-// console window.
-// Cu.import("resource://firebug/fbtrace.js");
-
-var consoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
-
-// Just workaround for this module.
-var FBTrace = {sysout: function(msg)
-{
- consoleService.logStringMessage(msg);
-}};
-
+Cu.import("resource://firebug/fbtrace.js");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://firebug/prefLoader.js");
-
-// Import of PluralForm object.
Cu.import("resource://gre/modules/PluralForm.jsm");
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/mini-require.js b/trace/FBTrace/chrome/firebug/modules/mini-require.js
index e05c73c..318da68 100644
--- a/trace/FBTrace/chrome/firebug/modules/mini-require.js
+++ b/trace/FBTrace/chrome/firebug/modules/mini-require.js
@@ -3,6 +3,8 @@
// ********************************************************************************************* //
// Module Loader Implementation
+var EXPORTED_SYMBOLS = ["require", "define"];
+
var require, define;
(function() {
@@ -15,6 +17,7 @@ var Cc = Components.classes;
var Ci = Components.interfaces;
Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://firebug/fbtrace.js");
// ********************************************************************************************* //
// Module Loader implementation
@@ -196,7 +199,16 @@ var Loader =
}
return deps;
- }
+ },
+
+ getDepDesc: function()
+ {
+ var desc = "";
+ var deps = this.getDeps();
+ for (var p in deps)
+ desc += p + "\n";
+ return desc;
+ },
}
// ********************************************************************************************* //
@@ -205,6 +217,7 @@ var Loader =
require = Loader.require.bind(Loader);
define = Loader.define.bind(Loader);
require.load = Loader.load.bind(Loader);
+require.Loader = Loader;
// ********************************************************************************************* //
})();
diff --git a/trace/FBTrace/chrome/firebug/modules/observer-service.js b/trace/FBTrace/chrome/firebug/modules/observer-service.js
index 58881d7..64f8bad 100644
--- a/trace/FBTrace/chrome/firebug/modules/observer-service.js
+++ b/trace/FBTrace/chrome/firebug/modules/observer-service.js
@@ -6,11 +6,11 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
+const Cu = Components.utils;
var EXPORTED_SYMBOLS = ["fbObserverService"];
-Components.utils.import("resource://firebug/firebug-trace-service.js");
-var FBTrace = traceConsoleService.getTracer("extensions.firebug");
+Cu.import("resource://firebug/fbtrace.js");
// ********************************************************************************************* //
// Observer implementation
diff --git a/trace/FBTrace/chrome/firebug/modules/prefLoader.js b/trace/FBTrace/chrome/firebug/modules/prefLoader.js
index 01238f2..e40ff59 100644
--- a/trace/FBTrace/chrome/firebug/modules/prefLoader.js
+++ b/trace/FBTrace/chrome/firebug/modules/prefLoader.js
@@ -144,6 +144,11 @@ function setPref(name, value)
return value;
}
+function forceSave()
+{
+ Services.prefs.savePrefFile(null);
+}
+
// ********************************************************************************************* //
// Registration
@@ -151,5 +156,6 @@ PrefLoader.loadDefaultPrefs = loadDefaultPrefs;
PrefLoader.clearDefaultPrefs = clearDefaultPrefs;
PrefLoader.getPref = getPref;
PrefLoader.setPref = setPref;
+PrefLoader.forceSave = forceSave;
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/require-debug.js b/trace/FBTrace/chrome/firebug/modules/require-debug.js
index 91c7169..10efe4f 100644
--- a/trace/FBTrace/chrome/firebug/modules/require-debug.js
+++ b/trace/FBTrace/chrome/firebug/modules/require-debug.js
@@ -1,37 +1,7 @@
-/*Software License Agreement (BSD License)
-
-Copyright (c) 2007, Parakey Inc.
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of Parakey Inc. nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of Parakey Inc.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
-IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*/
-// johnjbarton at johnjbarton.com May 2011 IBM Corp.
+/* See license.txt for terms of usage */
+// ********************************************************************************************* //
+// johnjbarton at johnjbarton.com May 2011 IBM Corp.
// Extend require.js to add debugging information
// Include this file immediately after require.js
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/modules/storageService.js b/trace/FBTrace/chrome/firebug/modules/storageService.js
index 9f98065..1465b3d 100644
--- a/trace/FBTrace/chrome/firebug/modules/storageService.js
+++ b/trace/FBTrace/chrome/firebug/modules/storageService.js
@@ -6,14 +6,15 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
+const Cu = Components.utils;
const dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
// https://developer.mozilla.org/en/Using_JavaScript_code_modules
var EXPORTED_SYMBOLS = ["Storage", "StorageService", "TextService"];
-Components.utils["import"]("resource://firebug/firebug-trace-service.js");
-var FBTrace = traceConsoleService.getTracer("extensions.firebug");
+Cu.import("resource://firebug/fbtrace.js");
+Cu.import("resource://gre/modules/FileUtils.jsm");
// ********************************************************************************************* //
// Implementation
@@ -92,7 +93,7 @@ Storage.prototype =
{
this.objectTable = {};
StorageService.setStorage(this, now);
- },
+ }
};
// ********************************************************************************************* //
@@ -139,7 +140,7 @@ var StorageService =
removeStorage: function(leafName)
{
ObjectPersister.deleteObject(leafname);
- },
+ }
};
// ********************************************************************************************* //
@@ -150,39 +151,12 @@ var StorageService =
*/
var ObjectPersister =
{
- getProfileDirectory: function()
- {
- var file = dirService.get("ProfD", Ci.nsIFile);
- return file;
- },
-
- getFileInDirectory: function(file, path) // forward slash separated
- {
- var segs = path.split('/');
- for (var i = 0; i < segs.length; i++)
- {
- file.append(segs[i]);
- }
- return file;
- },
-
- getFileInProfileDirectory: function(path)
- {
- // Get persistence file stored within the profile directory.
- var file = ObjectPersister.getProfileDirectory();
- file = ObjectPersister.getFileInDirectory(file, path);
- if (FBTrace.DBG_STORAGE)
- FBTrace.sysout("ObjectPersister getFileInProfileDirectory("+path+")="+file.path);
-
- return file;
- },
-
readObject: function(leafName)
{
if (FBTrace.DBG_STORAGE)
FBTrace.sysout("ObjectPersister read from leafName "+leafName);
- var file = ObjectPersister.getFileInProfileDirectory("firebug/"+leafName);
+ var file = FileUtils.getFile("ProfD", ["firebug", leafName]);
if (!file.exists())
{
@@ -283,7 +257,7 @@ var ObjectPersister =
{
// Convert data to JSON.
var jsonString = JSON.stringify(obj);
- var file = ObjectPersister.getFileInProfileDirectory("firebug/"+leafName);
+ var file = FileUtils.getFile("ProfD", ["firebug", leafName]);
ObjectPersister.writeTextToFile(file, jsonString);
}
catch(exc)
@@ -345,9 +319,7 @@ var ObjectPersister =
var TextService =
{
readText: ObjectPersister.readTextFromFile,
- writeText: ObjectPersister.writeTextToFile,
- getProfileDirectory: ObjectPersister.getProfileDirectory,
- getFileInDirectory: ObjectPersister.getFileInDirectory,
+ writeText: ObjectPersister.writeTextToFile
};
// ********************************************************************************************* //
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/callstack.css b/trace/FBTrace/chrome/firebug/skin/classic/callstack.css
index 159e388..46633dd 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/callstack.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/callstack.css
@@ -69,3 +69,11 @@
display: none;
}
+/*************************************************************************************************/
+/* FunctionCall log */
+
+.objectBox-functionCall {
+ padding-left: 17px;
+ cursor: default;
+ position: relative;
+}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/console.css b/trace/FBTrace/chrome/firebug/skin/classic/console.css
index ed9cd04..289cfaf 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/console.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/console.css
@@ -1,4 +1,3 @@
-/* See license.txt for terms of usage */
.panelNode-console {
overflow-x: hidden;
@@ -18,7 +17,7 @@
}
.logGroup {
- background: #FFFFFF -moz-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1) 18px, transparent 51px) repeat-x;
+ background: #FFFFFF linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1) 18px, transparent 51px) repeat-x;
padding: 0;
border: none;
}
@@ -57,6 +56,7 @@
.logRow-error,
.logRow-assert,
.logRow-warningMessage,
+.logRow-loading,
.logRow-errorMessage {
padding-left: 22px;
background-repeat: no-repeat;
@@ -100,6 +100,10 @@
background-image: url(chrome://firebug/skin/info.svg);
}
+.logRow-loading {
+ background-image: url(chrome://firebug/skin/loading.svg);
+}
+
.logRow-warn,
.logRow-warningMessage {
background-image: url(chrome://firebug/skin/warning.svg);
@@ -156,6 +160,7 @@
.objectBox-null,
.objectBox-undefined,
+.objectBox-hint,
.logRowHint {
font-style: italic;
color: #787878;
@@ -349,7 +354,7 @@
border-bottom: 1px solid #9C9C9C;
padding: 0 !important;
font-weight: bold;
- background: #C8C8C8 -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
+ background: #C8C8C8 linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
}
.headerCellBox {
@@ -448,9 +453,9 @@
/*************************************************************************************************/
+.objectLink-event,
+.objectLink-eventLog,
.objectLink-regexp,
-.objectLink-Storage,
-.objectLink-StorageList,
.objectLink-object,
.objectLink-Date {
font-family: Lucida Grande, sans-serif;
@@ -643,11 +648,16 @@
padding-left: 18px;
}
+.objectBox-array > .objectTitle {
+ font-weight: bold;
+ color: DarkGreen;
+}
+
/*****************************************************************************************/
.logRow-spy,
.logRow-spy .objectLink-sourceLink {
- background: #FFFFFF -moz-linear-gradient(top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1) 18px, transparent 51px) repeat-x;
+ background: #FFFFFF linear-gradient(to bottom, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0.1) 18px, transparent 51px) repeat-x;
padding-right: 4px;
right: 0;
}
@@ -783,3 +793,28 @@
color: gray;
padding-left: 5px;
}
+
+
+/************************************************************************************************/
+/* include */
+.tableCommandLineInclude td{
+ height: 17px;
+}
+.tableCommandLineInclude .closeButton{
+ display: none;
+}
+
+.tableCommandLineInclude tr:hover .closeButton{
+ display: block;
+}
+.tableCommandLineInclude .url{ float: left; }
+
+.tableCommandLineInclude .commands{
+ float: right;
+ height:100%;
+}
+.tableCommandLineInclude td:last-child
+{
+ width: 75%;
+ padding-right: 0 !important;
+}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/cookies/cookies.css b/trace/FBTrace/chrome/firebug/skin/classic/cookies/cookies.css
index 06dc2bc..5caf3f8 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/cookies/cookies.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/cookies/cookies.css
@@ -87,7 +87,7 @@
border-bottom: 1px solid #9C9C9C;
padding: 0 !important;
font-weight: bold;
- background: #C8C8C8 -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2)) repeat-x;
+ background: #C8C8C8 linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2)) repeat-x;
white-space: nowrap;
}
@@ -345,7 +345,7 @@
.cookieInfoCol {
border-top: 1px solid #EEEEEE;
- background: #FFFFFF -moz-linear-gradient(top, rgba(0, 0, 0, 0.1), transparent 33px) repeat-x;
+ background: #FFFFFF linear-gradient(to bottom, rgba(0, 0, 0, 0.1), transparent 33px) repeat-x;
}
.cookieInfoBody {
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/css.css b/trace/FBTrace/chrome/firebug/skin/classic/css.css
index 661d75e..d84e34f 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/css.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/css.css
@@ -128,15 +128,13 @@
padding-bottom: 2px;
}
-.computedStyleRow > td:first-child {
- width: 160px;
-}
-
.selectorName {
+ width: 160px;
-moz-padding-start: 24px;
}
.stylePropName {
+ width: 160px;
vertical-align: top;
font-weight: bold;
padding: 0 4px 0 24px;
@@ -146,11 +144,7 @@
padding-left: 3px;
}
-.styleSelector > td:first-child {
- width: 160px;
-}
-
-.styleSelector > td:n-th-child(2) {
+.propValue {
width: 140px;
}
@@ -170,7 +164,7 @@
text-align: right;
}
-.cssRule .objectLink-sourceLink {
+.cssElementRuleContainer > .objectLink-sourceLink {
top: 0;
}
@@ -200,10 +194,6 @@
display: none;
}
-.cssPropValue.editing {
- white-space: nowrap;
-}
-
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.useA11y .a11yCSSView .focusRow:focus {
@@ -228,10 +218,10 @@
.infoTipColorBox {
background-color: #C8C8C8;
background-image:
- -moz-linear-gradient(45deg, #A0A0A0 25%, transparent 25%),
- -moz-linear-gradient(-45deg, #A0A0A0 25%, transparent 25%),
- -moz-linear-gradient(45deg, transparent 75%, #A0A0A0 75%),
- -moz-linear-gradient(-45deg, transparent 75%, #A0A0A0 75%);
+ linear-gradient(45deg, #A0A0A0 25%, transparent 25%),
+ linear-gradient(135deg, #A0A0A0 25%, transparent 25%),
+ linear-gradient(45deg, transparent 75%, #A0A0A0 75%),
+ linear-gradient(135deg, transparent 75%, #A0A0A0 75%);
background-size: 16px 16px;
background-position:0 0, 8px 0, 8px -8px, 0px 8px;
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/debugger.css b/trace/FBTrace/chrome/firebug/skin/classic/debugger.css
index d4b9ac1..8ea158c 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/debugger.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/debugger.css
@@ -136,7 +136,7 @@
margin-top: 0;
left: 5px;
width: 90%;
- background: -moz-linear-gradient(top, #00CEFD, #00BAF6) no-repeat;
+ background: linear-gradient(to bottom, #00CEFD, #00BAF6) no-repeat;
border-style: solid;
border-width: 19px 25px 33px 33px;
-moz-border-image: url(condCorners.png) 19 25 33 33 stretch;
@@ -164,7 +164,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.upsideDown {
- background: -moz-linear-gradient(top, #00D1FE, #00ADE6) no-repeat;
+ background: linear-gradient(to bottom, #00D1FE, #00ADE6) no-repeat;
border-style: solid;
border-width: 28px 25px 19px 33px;
-moz-border-image: url(condCornersUps.png) 28 25 19 33 stretch;
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/dom.css b/trace/FBTrace/chrome/firebug/skin/classic/dom.css
index 12f2a0e..406e45c 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/dom.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/dom.css
@@ -94,25 +94,32 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+.userLabel,
+.userClassLabel,
+.userFunctionLabel {
+ font-weight: bold;
+}
+
.userLabel {
color: #000000;
- font-weight: bold;
}
.userClassLabel {
color: #E90000;
- font-weight: bold;
}
.userFunctionLabel {
color: #025E2A;
- font-weight: bold;
}
.domLabel {
color: #000000;
}
+.domClassLabel {
+ color: #E90000;
+}
+
.domFunctionLabel {
color: #025E2A;
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/firebug.css b/trace/FBTrace/chrome/firebug/skin/classic/firebug.css
index b7496e9..783fd15 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/firebug.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/firebug.css
@@ -75,7 +75,7 @@
.fbCommandLine {
-moz-appearance: none;
- margin: 4px 0 0 0;
+ margin: 2px 0 0 0;
padding: 0 4px;
border: none;
font-family: monospace;
@@ -87,6 +87,16 @@
z-index: 3;
}
+#fbCommandLineMeasurer {
+ margin: 0;
+ padding: 0;
+ border: none;
+ position: absolute;
+ z-index: -1;
+ visibility: hidden;
+ width: auto;
+}
+
#fbCommandEditor {
margin: 0;
font-family: monospace;
@@ -123,10 +133,6 @@
width: auto;
}
-#misspell {
- display: none !important;
-}
-
/*************************************************************************************************/
/* Toolbar */
@@ -154,7 +160,7 @@
.fbsearch-textbox[status="wraparound"] {
background-image: url(chrome://global/skin/icons/wrap.png);
- background-position: -moz-calc(100% - 5px) center;
+ background-position: calc(100% - 5px) center;
background-repeat: no-repeat;
}
@@ -365,6 +371,24 @@ textbox[type="fbSearchBox"] > panel {
list-style-image: url(chrome://firebug/skin/commandLineDisabled.png);
}
+/************************************************************************************************/
+/* Command History panel */
+
+#fbCommandHistory {
+ min-width: 200px;
+ max-height: 400px;
+ cursor: default;
+ font-family: monospace;
+ white-space: pre;
+ -moz-appearance: none;
+ background-color: -moz-dialog;
+}
+
+.commandHistoryItem.selected {
+ background-color: highlight;
+ color: highlighttext;
+}
+
/*************************************************************************************************/
#fbBreakOnErrors {
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/html.css b/trace/FBTrace/chrome/firebug/skin/classic/html.css
index 70b17ed..3daed71 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/html.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/html.css
@@ -58,6 +58,7 @@
.nodeComment {
margin: 0 2px;
vertical-align: top;
+ unicode-bidi: embed;
}
.nodeText {
@@ -165,7 +166,11 @@
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
-.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText {
+.nodeBox.nodeHidden.selected > .nodeLabel > .nodeLabelBox > .nodeText,
+.nodeBox.nodeHidden .nodeBox.selected > .nodeLabel > .nodeLabelBox,
+.nodeBox.nodeHidden .nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeTag,
+.nodeBox.nodeHidden .nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeAttr > .nodeValue,
+.nodeBox.nodeHidden .nodeBox.selected > .nodeLabel > .nodeLabelBox > .nodeText {
color: SkyBlue !important;
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/layout.css b/trace/FBTrace/chrome/firebug/skin/classic/layout.css
index 63ba9fc..4a4a3d2 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/layout.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/layout.css
@@ -82,7 +82,7 @@
position: absolute;
}
-.layoutLabel.v0 {
+.layoutLabel.invisible {
opacity: 0.2;
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/linux/firebug.css b/trace/FBTrace/chrome/firebug/skin/classic/linux/firebug.css
new file mode 100644
index 0000000..1b30596
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/skin/classic/linux/firebug.css
@@ -0,0 +1,6 @@
+ at import "chrome://firebug/skin/win/firebug.css";
+
+/* Add some basic padding to the completion popup (missing on Linux). */
+.userTypedText {
+ margin-left: 1px;
+}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/mac/debugger.css b/trace/FBTrace/chrome/firebug/skin/classic/mac/debugger.css
index 7ac6313..b9b47bf 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/mac/debugger.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/mac/debugger.css
@@ -135,7 +135,7 @@
margin-top: 0;
left: 5px;
width: 90%;
- background: -moz-linear-gradient(top, #00CEFD, #00BAF6) no-repeat;
+ background: linear-gradient(to bottom, #00CEFD, #00BAF6) no-repeat;
border-style: solid;
border-width: 19px 25px 33px 33px;
-moz-border-image: url(condCorners.png) 19 25 33 33 stretch;
@@ -163,7 +163,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
.upsideDown {
- background: -moz-linear-gradient(top, #00D1FE, #00ADE6) no-repeat;
+ background: linear-gradient(to bottom, #00D1FE, #00ADE6) no-repeat;
border-style: solid;
border-width: 28px 25px 19px 33px;
-moz-border-image: url(condCornersUps.png) 28 25 19 33 stretch;
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/mac/firebug.css b/trace/FBTrace/chrome/firebug/skin/classic/mac/firebug.css
index 19ba75f..fc50f76 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/mac/firebug.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/mac/firebug.css
@@ -10,17 +10,23 @@
#fbCommandToolbar {
border-top: 1px solid #BBB9BA;
border-bottom: 1px solid #BBB9BA;
- background: #F6F6F6 -moz-linear-gradient(bottom, #FFFFFF, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
+ background: #F6F6F6 linear-gradient(to top, #FFFFFF, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
}
#fbCommandArrow,
#fbCommandLine,
#fbCommandEditor,
#fbCommandLineCompletion,
+#fbCommandLineMeasurer,
.fbCommandLineCompletions {
font-family: Monaco, monospace;
}
+/* Add some more padding to the completion popup */
+.userTypedText {
+ margin-left: 1px;
+}
+
#fbCommandEditor {
-moz-appearance: none;
border: none;
@@ -53,7 +59,7 @@
#fbToolbar {
padding-left: 4px;
- background: #F6F6F6 -moz-linear-gradient(bottom, #FFFFFF, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
+ background: #F6F6F6 linear-gradient(to top, #FFFFFF, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
border-bottom: none;
}
@@ -107,8 +113,8 @@
.fbsearch-options-buttons {
-moz-appearance: none;
- background: #464646 -moz-linear-gradient(
- bottom,
+ background: #464646 linear-gradient(
+ to top,
rgba(255, 255, 255, 0.3),
rgba(255, 255, 255, 0) 55%,
rgba(255, 255, 255, 0.1) 55%,
@@ -235,10 +241,17 @@
font-family: Monaco, monospace;
}
+/************************************************************************************************/
+/* Command History panel */
+
+#fbCommandHistory {
+ font-family: Monaco, monospace;
+}
+
/********************************************************************************************/
.panelTabBox {
- background: #e0e0e0 -moz-linear-gradient(bottom, #D7D7D7, #EDEDED) repeat-x;
+ background: #e0e0e0 linear-gradient(to top, #D7D7D7, #EDEDED) repeat-x;
border-bottom: 1px solid #BBB9BA;
padding: 0;
overflow: hidden;
@@ -263,14 +276,14 @@ panelTab {
panelTab[selected="true"] {
border: 1px solid #A0A0A0;
border-bottom: none;
- background: -moz-linear-gradient(top, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.7)) no-repeat 0 0;
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0.7)) no-repeat 0 0;
color: inherit;
}
panelTab:not([selected="true"]):hover {
border: 1px solid #C8C8C8;
border-bottom: none;
- background: -moz-linear-gradient(top, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.2)) no-repeat 0 0;
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.2)) no-repeat 0 0;
}
.panelTab-text {
@@ -441,7 +454,7 @@ panelTab[selected="true"] > panelTabMenu {
/* ensure the inner toolbar background looks the same as the other toolbars */
#fbToolbarInner.innerToolbar {
- background: #F6F6F6 -moz-linear-gradient(bottom, #DCDCDC 1px, #FFFFFF 1px, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
+ background: #F6F6F6 linear-gradient(to top, #DCDCDC 1px, #FFFFFF 1px, #E9E9E9 55%, #F2F2F2 55%, #FAFAFA) repeat-x;
margin-left: -5px;
margin-right: 0px;
}
@@ -507,4 +520,4 @@ panelTab[selected="true"] > panelTabMenu {
#fbMigrationOk {
font-family: Monaco, monospace;
-}
\ No newline at end of file
+}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/mac/panel.css b/trace/FBTrace/chrome/firebug/skin/classic/mac/panel.css
index 9cbf3c2..8834637 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/mac/panel.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/mac/panel.css
@@ -19,6 +19,7 @@ body {
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.hasHeaders .netHrefLabel,
.objectBox-stackFrame.hasTwisty,
+.objectBox-functionCall.hasTwisty,
.netPageRow > .netCol > .netPageTitle,
.computedStyle.hasSelectors > .stylePropName,
.cookieRow > .cookieNameCol > .cookieNameLabel {
@@ -36,6 +37,8 @@ body {
.nodeBox.open > .nodeLabel > .twisty,
.netRow.opened > .netCol > .netHrefLabel,
.objectBox-stackFrame.hasTwisty.opened,
+.objectBox-functionCall.hasTwisty.opened,
+.computedStylesGroup.opened > .cssComputedHeader > .twisty,
.netPageRow.opened > .netCol > .netPageTitle,
.computedStyle.hasSelectors.opened > .stylePropName,
.cookieRow.opened > .cookieNameCol > .cookieNameLabel {
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/net.css b/trace/FBTrace/chrome/firebug/skin/classic/net.css
index e86b21f..91e0e8c 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/net.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/net.css
@@ -32,7 +32,7 @@
border-bottom: 1px solid #9C9C9C;
padding: 0 !important;
font-weight: bold;
- background: #C4C4C4 -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
+ background: #C4C4C4 linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
color: #000000;
white-space: nowrap;
}
@@ -311,7 +311,7 @@
left: 0;
top: 1px;
bottom: 1px;
- background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
}
.netBlockingBar {
@@ -397,7 +397,7 @@
*/
.fromCache .netReceivingBar,
.fromCache.netReceivingBar {
- background-image: -moz-linear-gradient(top, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.1));
}
.netSummaryRow .netTimeLabel,
@@ -414,7 +414,7 @@
.netTable.showBFCacheResponses .netRow.fromBFCache {
display: table-row;
- background-image: -moz-repeating-linear-gradient(-45deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05) 5px, transparent 5px, transparent 10px);
+ background-image: repeating-linear-gradient(135deg, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.05) 5px, transparent 5px, transparent 10px);
background-repeat: repeat;
}
@@ -492,10 +492,6 @@
font-size: 11px;
}
-.sizeInfoSizeCol {
- font-weight: bold;
-}
-
.sizeInfoDetailCol {
color: gray;
text-align: right;
@@ -595,7 +591,7 @@
.netInfoCol {
border-top: 1px solid #EEEEEE;
- background: #FFFFFF -moz-linear-gradient(top, rgba(0, 0, 0, 0.1), transparent 33px) repeat-x;
+ background: #FFFFFF linear-gradient(to bottom, rgba(0, 0, 0, 0.1), transparent 33px) repeat-x;
}
.netInfoBody {
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/panel.css b/trace/FBTrace/chrome/firebug/skin/classic/panel.css
index 1e56f16..6a28118 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/panel.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/panel.css
@@ -13,5 +13,6 @@
@import "chrome://firebug/skin/callstack.css";
@import "chrome://firebug/skin/layout.css";
@import "chrome://firebug/skin/dom.css";
+ at import "chrome://firebug/skin/performanceTiming.css";
@import "chrome://firebug/skin/tableRep.css";
- at import "chrome://firebug-os/skin/panel.css";
\ No newline at end of file
+ at import "chrome://firebug-os/skin/panel.css";
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/panelbase.css b/trace/FBTrace/chrome/firebug/skin/classic/panelbase.css
index 2179837..f714ca5 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/panelbase.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/panelbase.css
@@ -252,7 +252,7 @@ h1.groupHeader {
margin: 0 0 4px 0;
border-top: 1px solid #CCCCCC;
border-bottom: 1px solid #CCCCCC;
- background: #FFFFFF -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.1) 60%, rgba(0, 0, 0, 0.05) 60%, transparent) repeat-x;
+ background: #FFFFFF linear-gradient(to top, rgba(0, 0, 0, 0.05), rgba(0, 0, 0, 0.1) 60%, rgba(0, 0, 0, 0.05) 60%, transparent) repeat-x;
font-size: inherit;
}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/performanceTiming.css b/trace/FBTrace/chrome/firebug/skin/classic/performanceTiming.css
new file mode 100644
index 0000000..8ccf0d3
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/skin/classic/performanceTiming.css
@@ -0,0 +1,192 @@
+/* See license.txt for terms of usage */
+
+/*************************************************************************************************/
+
+.logRow-perfTiming {
+}
+
+/*************************************************************************************************/
+
+.perfTimingBox {
+ position: relative;
+ height: 17px;
+ border-right: 130px solid transparent;
+}
+
+.perfTimingBar {
+ position: absolute;
+ top: 1px;
+ bottom: 1px;
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
+ min-width: 2px;
+ z-index: 10;
+}
+
+.perfTimingBarLabel {
+ -moz-box-sizing: padding-box;
+ position: absolute;
+ top: 1px;
+ left: 100%;
+ padding-left: 6px;
+ color: #808080;
+ min-width: 16px;
+ white-space: nowrap;
+ z-index: 30;
+}
+
+/*************************************************************************************************/
+/* Info Tip */
+
+.timeInfoTipRow .timeInfoTipBar {
+ background-image: linear-gradient(to bottom, rgba(255, 255, 255, 0.3), rgba(0, 0, 0, 0.2));
+}
+
+/*************************************************************************************************/
+/* Bars */
+
+.perfTimingBar.pageLoad,
+.timeInfoTipBar.pageLoad {
+ background-color: rgb(217, 179, 147);
+}
+
+.perfTimingBar.redirect,
+.timeInfoTipBar.redirect {
+ background-color: rgb(0, 148, 87);
+}
+
+.perfTimingBar.dns,
+.timeInfoTipBar.dns {
+ background-color: #91D2DC;
+}
+
+.perfTimingBar.connecting,
+.timeInfoTipBar.connecting {
+ background-color: #B9E164;
+}
+
+.perfTimingBar.waiting,
+.timeInfoTipBar.waiting {
+ background-color: #B4A5D2;
+}
+
+.perfTimingBar.response,
+.timeInfoTipBar.response {
+ background-color: #78E17D;
+}
+
+.perfTimingBar.processing,
+.timeInfoTipBar.processing {
+ background-color: rgb(202, 206, 168);
+}
+
+.perfTimingBar.DOMContentLoaded,
+.timeInfoTipBar.DOMContentLoaded {
+ background-color: rgb(179, 184, 118);
+}
+
+.perfTimingBar.onLoad,
+.timeInfoTipBar.onLoad {
+ background-color: rgb(168, 194, 196);
+}
+
+/*************************************************************************************************/
+/* DOM Events */
+
+.perfTimingBar.event {
+ width: 1px;
+}
+
+.perfTimingEvent {
+ position: absolute;
+ width: 1px;
+ z-index: 20;
+ top: 0;
+ bottom: 0;
+}
+
+.perfTimingTable TR:first-child .perfTimingEvent {
+ top: 1px;
+}
+
+.perfTimingTable TR:last-child .perfTimingEvent {
+ bottom: 1px;
+}
+
+.perfTimingEvent.domInteractive,
+.timeInfoTipEventBar.domInteractive {
+ background-color: rgb(126, 146, 126);
+}
+
+.perfTimingEvent.domLoading,
+.timeInfoTipEventBar.domLoading {
+ background-color: rgb(155, 133, 155);
+}
+
+.perfTimingEvent.domContentLoaded,
+.timeInfoTipEventBar.domContentLoaded {
+ background-color: rgb(152, 152, 255);
+}
+
+.perfTimingEvent.onLoad,
+.timeInfoTipEventBar.onLoad {
+ background-color: rgb(255, 152, 152);
+}
+
+/*************************************************************************************************/
+/* Details */
+
+.logRow-perfTimingDetails .logGroupBody {
+ border-bottom: 1px solid #D7D7D7;
+ overflow-y: auto;
+ height: 200px;
+}
+
+.logRow-perfTimingDetails .logGroupLabel {
+ text-decoration: none !important;
+}
+
+.logRow-perfTimingDetails > .logRow {
+ background-position: 2px 3px !important;
+}
+
+.logRow-perfTimingDetails .timingCaptionDesc {
+ color: gray;
+ font-weight: normal;
+ padding-left: 10px;
+}
+
+.logRow-perfTimingDetails .timingTable {
+ margin-bottom: 4px;
+ cursor: pointer;
+}
+
+.logRow-perfTimingDetails .timingCell {
+ padding: 2px 4px 2px 4px;
+}
+
+.logRow-perfTimingDetails .timingTable tr:nth-child(even) {
+ background-color: #EFEFEF;
+}
+
+.logRow-perfTimingDetails .timingName {
+ color: green;
+ font-family: monospace;
+}
+
+.logRow-perfTimingDetails .timingRow:hover .timingName {
+ text-decoration: underline;
+}
+
+.logRow-perfTimingDetails .timingDesc {
+ color: gray
+}
+
+/*************************************************************************************************/
+/* Cursor */
+
+.perfTimingEvent.cursor {
+ background-color: gray;
+ visibility: hidden;
+ width: 2px;
+ z-index: 40;
+}
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/selector.css b/trace/FBTrace/chrome/firebug/skin/classic/selector.css
new file mode 100644
index 0000000..bbfb3b0
--- /dev/null
+++ b/trace/FBTrace/chrome/firebug/skin/classic/selector.css
@@ -0,0 +1,42 @@
+/* Rules for Selector panel elements */
+
+.cssSelectionTable {
+ width: 100%;
+}
+.selectionElement {
+ padding: 0 0 0 1ex;
+}
+
+.selectorWarning {
+ font-size: 11px;
+ color: gray;
+ padding: 2px 0 0 1ex;
+}
+
+.selectionErrorText {
+ color: black;
+ padding: 1em;
+ background-color: #FFEBEB;
+}
+
+/* Rules for select panel's effect on CSS stylesheet panel */
+.selectedSelectorRule {
+ border-color: Highlight !important;
+ background-color: #EBF5FF !important;
+ color: #000000 !important;
+ cursor: pointer;
+}
+
+.cssSelector,
+.cssPropName,
+.cssPropValue {
+ cursor: text;
+}
+
+.lockedSelectorRule {
+ background-color: Highlight;
+}
+
+.lockedSelectorRule * {
+ color: HighlightText !important;
+}
\ No newline at end of file
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/tableRep.css b/trace/FBTrace/chrome/firebug/skin/classic/tableRep.css
index b93fcda..719097e 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/tableRep.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/tableRep.css
@@ -14,6 +14,7 @@
.dataTableSizer {
width: 100%;
+ overflow-x: auto;
}
.dataTableSizer:focus {
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/win/firebug.css b/trace/FBTrace/chrome/firebug/skin/classic/win/firebug.css
index 96106de..8a17cb7 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/win/firebug.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/win/firebug.css
@@ -144,18 +144,6 @@
/************************************************************************************************/
-#fbCommandHistory {
- min-width: 200px;
- cursor: default;
- font-family: monospace;
- white-space: pre;
-}
-
-.commandHistoryItem.selected {
- background-color: highlight;
- color: highlighttext;
-}
-
#fbCommandEditor {
-moz-appearance: none;
border: none;
@@ -182,8 +170,8 @@
/************************************************************************************************/
.panelTabBox {
- background: -moz-linear-gradient(
- bottom,
+ background: linear-gradient(
+ to top,
rgba(0, 0, 0, 0.25) 1px,
rgba(0, 0, 0, 0.15) 1px,
rgba(0, 0, 0, 0));
@@ -211,8 +199,8 @@ panelTab {
panelTab[selected="true"] {
border: 1px solid #A0A0A0;
border-bottom: none;
- background: -moz-linear-gradient(
- top,
+ background: linear-gradient(
+ to bottom,
rgba(255, 255, 255, 0.7),
rgba(255, 255, 255, 0.9) 40%,
rgba(255, 255, 255, 0.4) 40%,
@@ -223,8 +211,8 @@ panelTab[selected="true"] {
panelTab:not([selected="true"]):hover {
border: 1px solid #C8C8C8;
border-bottom: none;
- background: -moz-linear-gradient(
- top,
+ background: linear-gradient(
+ to bottom,
rgba(255, 255, 255, 0.2),
rgba(255, 255, 255, 0.4) 40%,
rgba(255, 255, 255, 0) 40%,
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/win/linux.css b/trace/FBTrace/chrome/firebug/skin/classic/win/linux.css
new file mode 100644
index 0000000..e69de29
diff --git a/trace/FBTrace/chrome/firebug/skin/classic/win/panel.css b/trace/FBTrace/chrome/firebug/skin/classic/win/panel.css
index 03adec6..238de0e 100644
--- a/trace/FBTrace/chrome/firebug/skin/classic/win/panel.css
+++ b/trace/FBTrace/chrome/firebug/skin/classic/win/panel.css
@@ -11,6 +11,7 @@
.memberRow.hasChildren > .memberLabelCell > .memberLabel,
.hasHeaders .netHrefLabel,
.objectBox-stackFrame.hasTwisty,
+.objectBox-functionCall.hasTwisty,
.netPageRow > .netCol > .netPageTitle,
.cssComputedHeader > .twisty,
.breakpointHeader > .twisty,
@@ -32,6 +33,7 @@
.netRow.opened > .netCol > .netHrefLabel,
.netPageRow.opened > .netCol > .netPageTitle,
.objectBox-stackFrame.hasTwisty.opened,
+.objectBox-functionCall.hasTwisty.opened,
.computedStylesGroup.opened > .cssComputedHeader > .twisty,
.breakpointBlock.opened > .breakpointHeader > .twisty,
.computedStyle.hasSelectors.opened > .stylePropName,
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/firebug.git
More information about the Pkg-mozext-commits
mailing list