Hi Alex. This looks promising as a solution to problems many folks have. We'd like to take a look as soon as we can. Also we'll see if we can allow this kind of work in an extension.
Please open a bug report with your patch as an attachment (against branches/firebug1.3) http://code.google.com/p/fbug/issues/list Please include a testcase and procedure to see the effect of the patch. Be explicit in the report that you contribute the code under BSD and that any one employing you for coding is ok with that. John On Sep 30, 6:38 am, Alex <[EMAIL PROTECTED]> wrote: > 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 <[EMAIL PROTECTED]> > wrote: > > > Each context has a set of panels; each context corresponds to a page. > > I'd start by tracing with DBG_WINDOWS to understand the order of > > events: does the destroyContext come before the initContext for new > > page or not? My guess is yes. So then you need to decide: how to > > prevent destroyContext only in cases where I want to retain the > > panel? > > > hth, > > jjb > > > On Sep 24, 1:23 pm, Alex <[EMAIL PROTECTED]> wrote: > > > > Thanks for the quick reply! > > > > In fact, I want the "easy" feature: One panel that doesn't reload when > > > a new page is loaded into the current browser tab. Let's say I want to > > > protocol the text content of all title tags of all pages loaded into > > > the browser tab. Of course, I could just remember all title tags and > > > write them to the fresh panel, which is (obviously) not what I want to > > > do. So I guess the question is: How do I communicate to tabWatcher > > > that I do not want to delete the panel? How can I keep a panel over a > > > page reload? > > > > History-dependent panels are pretty appealing, too. But the easy > > > version would do fine for now; in particular, given that you plan to > > > drop tabWatcher. > > > > Again, I'd like to thank you for your reply. Have a good day, > > > > Alex > > > > On Sep 24, 9:07 pm, John J Barton <[EMAIL PROTECTED]> wrote: > > > > > It would be easy to for the console to show errors and warning for > > > > several pages, as long as by "several pages" you mean "all pages" ;-) > > > > > What you probably want is "when this page POSTs and gets a reply, put > > > > the new page errors in the same console as I have now". There are > > > > lots of folks who want this feature. > > > > > The problem is "how can Firebug determine that a page load event is > > > > connected in some way to a previous page?" > > > > > Here is one idea: when tabWatcher sees a new page it could look up the > > > > URL in the Net panel list of previous requests for every context. If > > > > one of the contexts did a request that matches, set the context of the > > > > new load to the match and issue "loadedContext". You also have to > > > > handle redirects. > > > > > If you succeed at that part the rest is simple. Well, I guess it > > > > depends on whether the new page events come before or after the call > > > > to destroy the old page. > > > > > By the way our plan is to eventually drop tabWatcher once we get a new > > > > API from Firefox. But that depends > > > > onhttps://bugzilla.mozilla.org/show_bug.cgi?id=342715 > > > > and it could be a ways off. > > > > > jjb > > > > > On Sep 24, 11:39 am, Alex > > ... > > read more » --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Firebug" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/firebug?hl=en -~----------~----~----~----~------~----~------~--~---
