Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

sessionStore API: what does it mean?

19 views
Skip to first unread message

John J. Barton

unread,
Feb 1, 2008, 2:05:05 PM2/1/08
to
I am trying to understand and use the sessionStore api. I succeeded
once, but now I get a bizarre error:

JavaScript Error: "aWindows[i] has no properties" {file:
"file:///C:/Program%20Files/Mozilla%20Firefox/components/nsSessionStore.js"
line: 1056}];
where
// collect the cookies per window
for (var i = 0; i < aWindows.length; i++) {
aWindows[i].cookies = { count: 0 }; <<<<< FAILS Here
}


In looking at MDC http://developer.mozilla.org/en/docs/nsISessionStore
it starts to make even less sense to me:
------
getWindowState()
Returns the current state of a specified browser window.

AString getWindowState(
in nsIDOMWindow aWindow
);
------
What's a "browser window"? The nsiDOMWindow in a tab?? I want the state
of all of XUL window for firefox, that is what I am restoring.

Another choice could be:
--------
getBrowserState()
Returns the current state of the entire browser, including all tabs in
all windows.
---------

Which 'entire browser'? I'm in an extension, there could be 16 windows
open and 32 browsers in them? Which one(s) does this function work on?

Lost again,
John.

John J. Barton

unread,
Feb 2, 2008, 1:22:53 PM2/2/08
to
John J. Barton wrote:
> I am trying to understand and use the sessionStore api. I succeeded
> once, but now I get a bizarre error:
>
> JavaScript Error: "aWindows[i] has no properties" {file:
> "file:///C:/Program%20Files/Mozilla%20Firefox/components/nsSessionStore.js"
> line: 1056}];
> where
> // collect the cookies per window
> for (var i = 0; i < aWindows.length; i++) {
> aWindows[i].cookies = { count: 0 }; <<<<< FAILS Here
> }

The error message meant to say "Preference browser.sessionstore.enabled
must be set true in about:config before calling getWindowState()"


John.

Mike Shaver

unread,
Feb 3, 2008, 3:42:54 AM2/3/08
to John J. Barton, dev-pl...@lists.mozilla.org
On Feb 2, 2008 1:22 PM, John J. Barton <johnj...@johnjbarton.com> wrote:
> The error message meant to say "Preference browser.sessionstore.enabled
> must be set true in about:config before calling getWindowState()"

Bug, IMO. We should be letting extension and app code write to a
common API and providing stub data if there is no real data to be had.
If you agree, please file!

But in this case, getWindowState's live data collection appears to be
useful even if we don't intend to serialize it for use between
sessions. Should we be conditioning only the write-out on the pref,
rather than turning off all the state tracking?

Mike

Simon Bünzli

unread,
Feb 3, 2008, 9:38:22 AM2/3/08
to
Mike Shaver schrieb am 03.02.08 09:42:

> On Feb 2, 2008 1:22 PM, John J. Barton <johnj...@johnjbarton.com> wrote:
>> The error message meant to say "Preference browser.sessionstore.enabled
>> must be set true in about:config before calling getWindowState()"
>
> Bug, IMO. We should be letting extension and app code write to a
> common API and providing stub data if there is no real data to be had.

In that case we should rather remove the pref browser.sessionstore.enabled .

Its only use case was to allow extension authors disable SessionStore
when they were providing a session saving component of their own. This
should however also be possible through completely replacing the
SessionStartup and SessionStore components with different components.
Like that, there'd not only be a common API, but it would also provide
useful results in all cases.

AFAICT the only extension ever to make use of that pref is Tab Mix Plus,
so we'd just have to make sure that its authors get a month or two to
adjust to this change before Firefox 3.0 final...

> But in this case, getWindowState's live data collection appears to be
> useful even if we don't intend to serialize it for use between
> sessions. Should we be conditioning only the write-out on the pref,
> rather than turning off all the state tracking?

That's what browser.sessionstore.resume_from_crash is for. Setting that
pref to false will only write out our data when its needed for session
resuming at a restart. That's BTW the pref recommended to toggle when
you do have privacy concerns (see our Release Notes)!

Cheers,
Simon

Simon Bünzli

unread,
Feb 3, 2008, 9:42:27 AM2/3/08
to
John J. Barton schrieb am 01.02.08 20:05:

> What's a "browser window"?

That's the OS widget reading "... - Mozilla Firefox" in its title bar.
If you feel that this isn't obvious, please suggest better wording (if
possible directly in a new bug over at bugzilla.mozilla.org).


> I want the state of all of XUL window for firefox, that is what I am
restoring.

That's what getBrowserState is for:

> Which 'entire browser'?

That's everything within Firefox's current OS process (e.g. all of its
windows and all of its tabs). Again, please suggest better wording...

Cheers,
Simon

John J. Barton

unread,
Feb 3, 2008, 1:22:38 PM2/3/08
to
Simon Bünzli wrote:
> John J. Barton schrieb am 01.02.08 20:05:
>> What's a "browser window"?
>
> That's the OS widget reading "... - Mozilla Firefox" in its title bar.
> If you feel that this isn't obvious, please suggest better wording (if
> possible directly in a new bug over at bugzilla.mozilla.org).

Then:
--


Returns the current state of a specified browser window.

--
Would be:
++
Returns the current state of all of the nsIDOMWindows with in the
tabbrowser element of the specified nsIDOMWindow, assuming that the
specified window is the outermost or root nsIDOMwindow for a
nsIXULWindow. This outermost or root window object can be obtained by
applying the 'mainWindow' incantation from
http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
+++

Assuming this is correct, then this API would be much clearer if the
argument was nsIXULWindow or tabbrowser.

I put a version of this on the MDC site. Please check.

> > I want the state of all of XUL window for firefox, that is what I am
> restoring.
>
> That's what getBrowserState is for:
>
>> Which 'entire browser'?
>
> That's everything within Firefox's current OS process (e.g. all of its
> windows and all of its tabs). Again, please suggest better wording...

Rather than:
---


Returns the current state of the entire browser, including all tabs in
all windows.
---

How about:
+++
Returns the current state of every nsIDOMWindow in Firefox's current OS
process, including all of its windows and all of their tabs.
+++

>
> Cheers,
> Simon

John J. Barton

unread,
Feb 3, 2008, 1:35:47 PM2/3/08
to
Simon Bünzli wrote:
> Mike Shaver schrieb am 03.02.08 09:42:
>> On Feb 2, 2008 1:22 PM, John J. Barton <johnj...@johnjbarton.com>
>> wrote:
>>> The error message meant to say "Preference browser.sessionstore.enabled
>>> must be set true in about:config before calling getWindowState()"
>>
>> Bug, IMO. We should be letting extension and app code write to a
>> common API and providing stub data if there is no real data to be had.
>
> In that case we should rather remove the pref
> browser.sessionstore.enabled .

To clarify you mean: act as if browser.sessionstore.enabled == true always?

>
>> But in this case, getWindowState's live data collection appears to be
>> useful even if we don't intend to serialize it for use between
>> sessions. Should we be conditioning only the write-out on the pref,
>> rather than turning off all the state tracking?
>
> That's what browser.sessionstore.resume_from_crash is for. Setting that
> pref to false will only write out our data when its needed for session
> resuming at a restart. That's BTW the pref recommended to toggle when
> you do have privacy concerns (see our Release Notes)!

So nsISessionStore has two layers of function:
i) get/set window state
ii) store/retrieve window state
The usual path uses both: get+store then retrieve+set. But extensions
(like Chromebug in my case) want to use get/set without store/retrieve.

Currently
browser.sessionstore.enabled == false, means API calls will fail
browser.sessionstore.resume_from_crash == false means don't store/retieve

I suppose users could want to prevent extensions from get/set, but the
level of understanding and documentation to make this generally useful
seems too large. So in general, browser.sessionstore.enabled should be
true.

>
> Cheers,
> Simon

Simon Bünzli

unread,
Feb 3, 2008, 2:01:03 PM2/3/08
to
John J. Barton schrieb am 03.02.08 19:22:

> Then:
> --
> Returns the current state of a specified browser window.
> --
> Would be:
> ++
> Returns the current state of all of the nsIDOMWindows with in the
> tabbrowser element of the specified nsIDOMWindow, assuming that the
> specified window is the outermost or root nsIDOMwindow for a
> nsIXULWindow. This outermost or root window object can be obtained by
> applying the 'mainWindow' incantation from
> http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
> +++

While this is technically correct, it's overly complicated. The API
rather expected the simplest argument possible: |window| which in the
context of an extension will in most cases just do the right thing. And
when it doesn't, the following will:

var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var browserWindow = wm.getMostRecentWindow("navigator:browser");

So please revert your documentation change and at most include a link to
http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code#Example_3:_Using_nsIWindowMediator_when_opener_is_not_enough

> Rather than:
> ---
> Returns the current state of the entire browser, including all tabs in
> all windows.
> ---
> How about:
> +++
> Returns the current state of every nsIDOMWindow in Firefox's current OS
> process, including all of its windows and all of their tabs.
> +++

IMO you're thinking too much in technical terms. Wouldn't
s/entire browser/entire browser application (i.e. Firefox)/
be sufficient? You really don't have to know about nsIDOMWindows and
processes to understand what this API is doing...

Simon Bünzli

unread,
Feb 3, 2008, 2:06:51 PM2/3/08
to
John J. Barton schrieb am 03.02.08 19:35:

>> In that case we should rather remove the pref
>> browser.sessionstore.enabled .
>
> To clarify you mean: act as if browser.sessionstore.enabled == true always?

Yes.

> Currently
> browser.sessionstore.enabled == false, means API calls will fail

This means that the SessionStore component is disabled and won't do
anything at all. Unless you're using Tab Mix Plus, this should never be
the case, though.

> browser.sessionstore.resume_from_crash == false means don't store/retieve

Not quite. It means that we don't regularly write the application's
state to disk so that we could recover from a crash - we however still
do so at regular shutdowns when Firefox is being restarted.

> I suppose users could want to prevent extensions from get/set, but the
> level of understanding and documentation to make this generally useful
> seems too large.

Users should never want to prevent extensions from getting/setting the
application's state (because the extension could always do the same
without SessionStore's help). As I wrote: this pref was _only_ for
extension authors who wanted to completely replace SessionStore, as e.g.
Tab Mix Plus' authors have done.

John J. Barton

unread,
Feb 4, 2008, 1:09:09 AM2/4/08
to
Simon Bünzli wrote:
> John J. Barton schrieb am 03.02.08 19:35:

>> Currently


>> browser.sessionstore.enabled == false, means API calls will fail
>
> This means that the SessionStore component is disabled and won't do
> anything at all.

Well, what I found experimentally is that false causes API calls to fail
with exceptions. (So I am in favor of making this option go away).

John J. Barton

unread,
Feb 4, 2008, 1:37:18 AM2/4/08
to
Simon Bünzli wrote:
> John J. Barton schrieb am 03.02.08 19:22:
>> Then:
>> --
>> Returns the current state of a specified browser window.
>> --
>> Would be:
>> ++
>> Returns the current state of all of the nsIDOMWindows with in the
>> tabbrowser element of the specified nsIDOMWindow, assuming that the
>> specified window is the outermost or root nsIDOMwindow for a
>> nsIXULWindow. This outermost or root window object can be obtained by
>> applying the 'mainWindow' incantation from
>> http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
>> +++
>
> While this is technically correct, it's overly complicated. The API
> rather expected the simplest argument possible: |window| which in the
> context of an extension will in most cases just do the right thing. And
> when it doesn't, the following will:
>
> var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
> .getService(Components.interfaces.nsIWindowMediator);
> var browserWindow = wm.getMostRecentWindow("navigator:browser");

Sorry I still don't get it. What value to I give for |window|? If I use
browserWindow, I'll get the state of the most recent window. Why would
I want that? I want to save the state of a specific window, one I am
about to kill and reload. It may be most recent, it may not.

If I call the function with an nsIDOMWindow other than the root of the
XUL Window, what happens? By the "right thing" do you mean I'll get the
state of the XUL Window anyway?

What has me confused is 'browser' and 'window'. 'browser' can be and is
in most of the XUL documentation a XUL element. And its the very element
that whose state is being stored. 'window' has three confusingly
similar meanings that confounds new comers to Mozilla. So when you say
"a specific browser window", do you mean the nsiDOMWindow for a specific
browser element? An specific nsIDOMWindow associated with a XUL Window
within the Firefox Browser? It might be less complicated, but its not
clear to me at least.

>
> So please revert your documentation change and at most include a link to
> http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code#Example_3:_Using_nsIWindowMediator_when_opener_is_not_enough
>
>
>> Rather than:
>> ---
>> Returns the current state of the entire browser, including all tabs in
>> all windows.
>> ---
>> How about:
>> +++
>> Returns the current state of every nsIDOMWindow in Firefox's current
>> OS process, including all of its windows and all of their tabs.
>> +++
>
> IMO you're thinking too much in technical terms. Wouldn't
> s/entire browser/entire browser application (i.e. Firefox)/
> be sufficient? You really don't have to know about nsIDOMWindows and
> processes to understand what this API is doing...

How about

Returns the current state of all tabs in all windows.

Simon Bünzli

unread,
Feb 4, 2008, 6:03:41 AM2/4/08
to
John J. Barton schrieb am 04.02.08 07:09:

> Well, what I found experimentally is that false causes API calls to fail
> with exceptions. (So I am in favor of making this option go away).

And until the option goes away, just make sure not to touch it - resp.
when you're an extension author, ensure that it's enabled and when it
isn't, give your user the option to automatically do so (see e.g. what
the Session Manager extension does).

Simon Bünzli

unread,
Feb 4, 2008, 6:26:44 AM2/4/08
to
John J. Barton schrieb am 04.02.08 07:37:

> Sorry I still don't get it. What value to I give for |window|?

|window| _is_ the value to pass to the API, if you want the state of the
chrome window you're code is running in (e.g. when you call it from the
"unload" event handler to catch the state of a closing window).

> If I use browserWindow, I'll get the state of the most recent window.

If you don't want that, then don't. The window-watcher component can
e.g. also iterate over all open windows of type "navigator:browser".

See the documentation at
http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
about the windows I'm talking about, and just remember: these are
_chrome_ and not _content_ windows which the API expects.

> If I call the function with an nsIDOMWindow other than the root of the
> XUL Window, what happens? By the "right thing" do you mean I'll get the
> state of the XUL Window anyway?

No, it won't. It has to be a top-level chrome window with
chrome://browser/content/browser.xul loaded into it. That's what
"specific browser window" means.

BTW: XUL's browser elements are usually not called "browser" but rather
"XUL browser", "xul:browser" or "<browser>". Just "browser" means an
application such as Firefox, Internet Explorer, Opera, etc.

P.S.: May I suggest that you have a look at the code of an extension
which successfully uses the nsSessionStore API, such as e.g. Session
Manager from https://addons.mozilla.org/firefox/2324 ?

John J. Barton

unread,
Feb 4, 2008, 11:51:46 AM2/4/08
to
Simon Bünzli wrote:
> John J. Barton schrieb am 04.02.08 07:37:
>> Sorry I still don't get it. What value to I give for |window|?
>
> |window| _is_ the value to pass to the API, if you want the state of the
> chrome window you're code is running in (e.g. when you call it from the
> "unload" event handler to catch the state of a closing window).

I guess you expect users of the API to use the 'window' object in the
global scope of the call? That's one use case, but I think the API
documentation should be written with out that assumption.

The way you say it also points up more of the generic problems
developers of mozilla face. What is a "chrome window"? There is a
simple answer, its the 'window' object in an extension. But if an
extension developer wants to work with any other window, then suddenly
'simple' isn't 'useful'.

>
>> If I use browserWindow, I'll get the state of the most recent window.
>
> If you don't want that, then don't. The window-watcher component can
> e.g. also iterate over all open windows of type "navigator:browser".

Also not useful if the API caller wants to close and reopen a XUL
window. Or if the API users is in the sidebar browser. The window
mediator helps API users navigate the windows, but it doesn't help them
select the right object to send to the API.

>
> See the documentation at
> http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
> about the windows I'm talking about, and just remember: these are
> _chrome_ and not _content_ windows which the API expects.

As you see, more kinds of windows. That's why the API doc has to be
more precise.

>
>> If I call the function with an nsIDOMWindow other than the root of the
>> XUL Window, what happens? By the "right thing" do you mean I'll get
>> the state of the XUL Window anyway?
>
> No, it won't. It has to be a top-level chrome window with
> chrome://browser/content/browser.xul loaded into it. That's what
> "specific browser window" means.

Well, that is what "specific browser window" means to you, but what I am
trying to explain is that, as an API user, "specific browser window" is
puzzling because it is imprecise and overlaps other meaning in the same
context.

>
> BTW: XUL's browser elements are usually not called "browser" but rather
> "XUL browser", "xul:browser" or "<browser>". Just "browser" means an
> application such as Firefox, Internet Explorer, Opera, etc.

Again, it depends on your expectations.

>
> P.S.: May I suggest that you have a look at the code of an extension
> which successfully uses the nsSessionStore API, such as e.g. Session
> Manager from https://addons.mozilla.org/firefox/2324 ?

Sorry if my post wasn't clear: when I say "What kind of window to use?"
I meant "How can we make the API doc clearer without using the root or
outermost nsIDOMWindow phrase that you don't like?" My code is working
because I put the pref true and used the root nsIDOMWindow from the XUL
Window that I wanted to close.

Boris Zbarsky

unread,
Feb 4, 2008, 11:55:36 AM2/4/08
to
Simon Bünzli wrote:
> P.S.: May I suggest that you have a look at the code of an extension
> which successfully uses the nsSessionStore API, such as e.g. Session
> Manager from https://addons.mozilla.org/firefox/2324 ?

In my opinion, if writing code that uses an API is impossible without looking at
existing code that uses the API, there is a fundamental problem with the API
design or documentation (or both!).

In this case, sounds like documentation, for what it's worth.

-Boris

Mike Shaver

unread,
Feb 4, 2008, 1:04:02 PM2/4/08
to Boris Zbarsky, dev-pl...@lists.mozilla.org

That's why this thread is discussing how to fix the documentation, no?
If you have specific recommendations, I'm sure they'd be quite
welcome!

Mike

Boris Zbarsky

unread,
Feb 4, 2008, 1:06:17 PM2/4/08
to
Mike Shaver wrote:
> That's why this thread is discussing how to fix the documentation, no?

Well, John was discussing that. Simon was pushing back claiming that the
documentation is fine.

> If you have specific recommendations, I'm sure they'd be quite
> welcome!

I happen to like John's changes as a first step, for what it's worth.

-Boris

John J. Barton

unread,
Feb 5, 2008, 12:02:52 PM2/5/08
to
Simon Bünzli wrote:
> John J. Barton schrieb am 03.02.08 19:22:
>> Then:
>> --
>> Returns the current state of a specified browser window.
>> --
>> Would be:
>> ++
>> Returns the current state of all of the nsIDOMWindows with in the
>> tabbrowser element of the specified nsIDOMWindow, assuming that the
>> specified window is the outermost or root nsIDOMwindow for a
>> nsIXULWindow. This outermost or root window object can be obtained by
>> applying the 'mainWindow' incantation from
>> http://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
>> +++
>
> While this is technically correct, it's overly complicated.

Ok I re-wrote my edits to
http://developer.mozilla.org/en/docs/nsISessionStore
1) Added a 'Note on windows' to the bottom of the doc and put all the
nsI stuff and links to incantations there.
2) Cut the main body text back to
Returns the current state of one specified window in the web browser.
3) Added a couple of sentences at the beginning of the doc to point to
the Note.

I hope this is both more precise and as simple.
John.

Simon Bünzli

unread,
Feb 6, 2008, 12:09:39 PM2/6/08
to
John J. Barton schrieb am 04.02.08 17:51:

> But if an extension developer wants to work with any other window,
> then suddenly 'simple' isn't 'useful'.

In that case the question is how you'd get a reference to that other
window. One way would be through the window-mediator, which will
directly return an nsIDOMWindow you can use for the SessionStore API.

As for using a nsIXULWindow you indeed have to do the "'mainWindow'
incantation", which isn't optimal, but hasn't been needed for any of the
use cases I've seen so far. The API should remain usable, though.

Nonetheless, please enlighten me as to how you get to an nsIXULWindow in
the first place - and whether you see different use cases where the API
in your opinion currently fails.

> Or if the API users is in the sidebar browser.

In that case, window.frameElement.ownerDocument.defaultView would be the
direct (if not the obvious) way, wouldn't it?

> The window
> mediator helps API users navigate the windows, but it doesn't help them
> select the right object to send to the API.

Please explain in more detail how you'd expect to select the right
object, then.

> As you see, more kinds of windows. That's why the API doc has to be
> more precise.

Yeah, so we need a reference the the "global window object" of a
top-level with "chrome://browser/content/browser.xul" loaded - which I
see you've already done...

> Sorry if my post wasn't clear: when I say "What kind of window to use?"
> I meant "How can we make the API doc clearer without using the root or
> outermost nsIDOMWindow phrase that you don't like?"

My mistake. I appreciate your efforts and am already much happier with
your latest revision of the documentation. Thanks.

I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=415941 for
getting your clarifications into our source code as well.

Simon Bünzli

unread,
Feb 6, 2008, 12:15:52 PM2/6/08
to
Boris Zbarsky schrieb am 04.02.08 19:06:

> Well, John was discussing that. Simon was pushing back claiming that
> the documentation is fine.

FWIW: I didn't claim it was fine, I just wasn't happy with the suggested
corrections. And indeed the latest revision is both clearer and easier
to understand.

0 new messages