Hello again everybody!
I now implemented a mechanism that allows to persist Firebug panels.
That is, a panel will survive page loads as long as it is marked
persistent. This might be useful when visualing logged information or
events etc (see also above).
The changes necessary to achieve such a behaviour are in fact minimal.
The intuition, as outlined by John, is the following. The moment we
destroy the current webpage's context, we store the panels marked
persistent in persistedState (tabContext.destroy()). Later, when the
new context is about to be created, we recover the persisted panels
from persistedState.
I will now detail the code changes.
1) Firebug.Panel
- We need to add a boolean attribute termed "persistent". If true,
the panel will not be erased when a new context is loaded.
- A method called reinitialize() (or loadedContext() ?!) is used
to handle the actions that shall be executed when a new context has
been loaded. For example, reinitialize would NOT erase the panelNode,
but add a log message.
2) Firebug.TabContext
- destroy():
We will save persistent panels in persistedState.panelMap.
First, initialize such an object:
state.panelMap = {};
Then, if a panel is marked persistent, store it in
persistedState.panelMap, otherwise destroy it as usual:
for (var panelName in this.panelMap)
{
if (panel.persistent) {
// Do not destroy persistent panel
state.panelMap[panelName] = panel;
} else {
// Destroy the panel and allow it to persist extra
info to the state object
panel.destroy(panelState);
// Remove the panel node from the DOM
var panelNode = panel.panelNode;
if (panelNode && panelNode.parentNode && !
panel.persistent)
panelNode.parentNode.removeChild(panelNode);
}
}
- TabContext constructor:
Here we need to restore the saved panels from persistedState
and put them into the new context's panelMap. In addition, we call the
panel's reinitialize() method here.
Firebug.TabContext = function(win, browser, chrome,
persistedState, persistedPanelMap)
{
this.panelMap = persistedPanelMap ? persistedPanelMap : {};
for (var panelName in this.panelMap) {
var panel = this.panelMap[panelName];
var panelType = Firebug.getPanelType(panelName);
var doc = panelType ?
this.chrome.getPanelDocument(panelType) : null;
panel.reinitialize(this, doc);
}
};
3) TabWatcher
- watchTopWindow:
Here we need to recover the panelMap from persistedState and
call TabContext constructor with the persisted panelMap. This looks as
follows:
// Restore persistent panels.
var persistedPanelMap = persistedState &&
persistedState.panelMap ? persistedState.panelMap : null;
and shortly after
context = this.owner.createTabContext(win, browser,
browser.chrome, persistedState, persistedPanelMap);
4) Firebug.createTabContext needs to become
Firebug.createTabContext: function(win, browser, chrome, state,
panelMap)
{
return new Firebug.TabContext(win, browser, chrome, state,
panelMap);
}
That's it. I will finally provide patches for tabContext.js and
tabWatcher.js (based on revision r1119 from today) and a simple panel
that logs urls to demonstrate the idea. =)
tabContext.js:
17c17
< Firebug.TabContext = function(win, browser, chrome, persistedState)
---
> Firebug.TabContext = function(win, browser, chrome, persistedState, persistedPanelMap)
32c32
< this.panelMap = {};
---
> this.panelMap = persistedPanelMap ? persistedPanelMap : {};
35a36,44
> for (var panelName in this.panelMap) {
> var panel = this.panelMap[panelName];
>
> var panelType = Firebug.getPanelType(panelName);
> var doc = panelType ? this.chrome.getPanelDocument(panelType) : null;
>
> if (panel.persistent) panel.reinitialize(this, doc);
> }
>
82a92
> state.panelMap = {};
99,105c109,120
< // Destroy the panel and allow it to persist extra info
to the state object
< panel.destroy(panelState);
<
< // Remove the panel node from the DOM
< var panelNode = panel.panelNode;
< if (panelNode && panelNode.parentNode)
< panelNode.parentNode.removeChild(panelNode);
---
> if (panel.persistent) {
> // Do not destroy persistent panel
> state.panelMap[panelName] = panel;
> } else {
> // Destroy the panel and allow it to persist extra info to the state object
> panel.destroy(panelState);
>
> // Remove the panel node from the DOM
> var panelNode = panel.panelNode;
> if (panelNode && panelNode.parentNode)
> panelNode.parentNode.removeChild(panelNode);
> }
tabWatcher.js:
125a126,129
>
> // Restore persistent panels.
> var persistedPanelMap = persistedState && persistedState.panelMap ? persistedState.panelMap : null;
>
129c133,134
< context = this.owner.createTabContext(win, browser,
browser.chrome, persistedState);
---
> context = this.owner.createTabContext(win, browser, browser.chrome, persistedState, persistedPanelMap);
>
And the panel:
FBL.ns(function() { with (FBL) {
Firebug.PersistentPanel = function() {};
Firebug.PersistentPanel.prototype = extend(Firebug.Panel,
{
name: "persistent",
title: "Persistent",
//parentPanel: "html",
persistent: true,
counter: 0,
initialize: function() {
Firebug.Panel.initialize.apply(this, arguments);
},
initializeNode: function(oldPanelNode) {
this.persistent = true;
this.counter += 1;
var newPage = this.document.createElement("p");
newPage.textContent = "["+this.counter+"] Current URL: " +
this.context.window.document.URL;
this.panelNode.appendChild(newPage);
},
reinitialize: function(context, doc) {
this.context = context;
this.document = doc;
this.counter += 1;
var newPage = this.document.createElement("p");
newPage.textContent = "["+this.counter+"] Current URL: " +
this.context.window.document.URL;
this.panelNode.appendChild(newPage);
if (this.counter == 5)
this.persistent = false;
},
clear: function() {}
});
Firebug.registerPanel(Firebug.PersistentPanel);
}});
Please note that I cannot make this work as an extension (overwriting
TabContext constructor and TabWatcher.watchTopWindow has strange side
effects). I would thus be glad if this code will somehow be included
in future versions of Firebug (in particular, given that the changes
are of minor nature).
Alright. That's it already! =)
Have a good day!
Alex
On Sep 24, 10:48 pm, John J Barton <
johnjbar...@johnjbarton.com>