1

Migrating an old Add-on from XUL to Add-ons-SDK in preparation for WebExtensions. Would still like to support some older browsers with this add-on, so that is why I am not jumping right to WebExtensions.

What I'd like to do is control minimize, maximize full screen and restore functions. These seem to be implemented right on the window object, since FF 45.0, which is great, but no help when trying to support older browsers. Not sure if that functionality existed before, or how to access it in a XUL-migration friendly context ( Step 1: use Services.jsm ). See Migrate from XUL Overlay to Restartless.

To best I could find is to use Components.interfaces.nsIDOMChromeWindow.windowState of the STATE_* attributes to detect the minimized, maximized, normal or fullscreen states, and then issue the methods minimize(), maximize() and restore() found on the same object ( nsIDOMChromeWindow ).

But I can't seem to find the precise way to load the equivalent

Components.interfaces.nsIDOMChromeWindow.windowState

using a resource:// like Services.jsm.

For example, the old add-on also used:

Components.interfaces.nsIPrefBranchInternal

which was later renamed to

Components.interfaces.nsIPrefBranch2

and later folded into

Components.interfaces.nsIPrefBranch

which can now be accessed by:

Components.utils.import( 'resource://gre/modules/Services.jsm' );
var prefsService = Services.prefs;

See Services.jsm on MDN for options.

| Service accessor  | Service interface    | Service name            |
|-------------------|----------------------|-------------------------|
| domStorageManager | nsIDOMStorageManager | DOM Storage Manager     |
| DOMRequest        | nsIDOMRequestService | DOMRequest service      |
| wm                | nsIWindowMediator    | Window mediator service |
| ww                | nsIWindowWatcher     | Window watcher service  |

There's two things that start with nsIDOM* (Request and Storage), but don't seem to be related, or have any path to the desired object. nsIWindow* (Mediator and Watcher) both have some methods that return a similarly named nsIDOMWindow object (deprecated in FF 44), including a confusingly named getChromeForWindow() method, but that is NOT THE SAME OBJECT, and indeed, doesn't have any of the desired state attributes or window management toggle methods.

I am not sure what I am missing here. Is this simply one of the things the developers decided was "low level" and thus refused to provide any high level access via Services.jsm? Or is the access there but documentation incomplete? Or is it documented but buried? Or is it blogged about somewhere? I could only find one single post on all of StackOverflow that even had nsIDOMChromeWindow in it!

As I initially stated, I know there's a simple way to do this in both the "old" style XUL/Overlay, as well as the "new" FF >= 45, but I am looking to support that in-between area, at least for another year or two, until they absolutely drop XUL. By then, I will have the Add-ons-SDK version ready to go, and the WebExtensions well underway.

  • 1
    `Components.interfaces.nsIDOMChromeWindow.windowState` doesn't make sense. The objects under `Ci` only contain abstract interface definitions (think superclass, except with multiple inheritance), not actual instances implementing them. The interface definition doesn't even have the `windowState` property an implementing class would have. That's not specific to the addon sdk, it wouldn't work in an old extension either. So your question seems sortof misleading. Maybe you should post an actual, currently working code sample you wish to modernize. – the8472 May 09 '16 at 17:32
  • 2
    `var {Cu, Ci} = require('chrome'); Cu.import('resource://gre/modules/Services.jsm'); var win = Services.wm.getMostRecentWindow('navigator:browser'); console.log(win.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED)` works for me. To get all windows you can iterate with `getEnumerator` - https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Reference/Interface/nsIWindowMediator#getEnumerator() – Noitidart May 09 '16 at 19:11
  • @the8472 The problem is, there was no code to do this in the add-on. When originally written there were probably no states, minimize, maximize or restore functions, and relied on window move and window resize. Although a clever hack at the time, it did result in some glitchy behavior that annoyed users (I read every single user review ever written for this add-on, some of which were my own). So I am trying to restore and improve code using older techniques which still work. I believe Noitidart's example may do what I wanted. Will have to try. –  May 10 '16 at 01:42
  • @Noitidart is the `require('chrome')` specific to Add-ons SDK? I know for XUL/Overlay I could use something like `var { Cu: utils, Ci: interfaces } = Components;` or `var Cu = Components.utils; var Ci = Components.interfaces;` The rest of the example shows `Services.jsm` `Windows Mediator` with the `getMostRecentWindow()` returning an nsIDOMWindow object, which doesn't have the windowState property or minimize(), maximize(), restore() methods? I am just having difficulty following the documentation to understand how these end up on nsIDOMWindow. Or I have misunderstood. –  May 10 '16 at 02:41
  • 1
    @user314159 yes thats SDK specific. To do it without SDK copy paste this: `var {Cu:utils, Ci:interfaces} = Components; Cu.import('resource://gre/modules/Services.jsm'); var win = Services.wm.getMostRecentWindow('navigator:browser'); console.log(win.windowState == Ci.nsIDOMChromeWindow.STATE_MAXIMIZED)` – Noitidart May 10 '16 at 02:49
  • @noitidart you should try to use `require` instead of `Cu.import` – humanoid May 12 '16 at 12:59
  • @humanoid Does require() work in the older XUL/Overlay based add-ons? Is it specific to Add-ons SDK? Which version Firefox introduced require()? I am presently working on an older XUL based add-on, planning to migrate to restartless -> bootstrapped -> add-ons SDK -> webextensions, etc., as I learn and have time to refactor. –  May 13 '16 at 03:30
  • @user314159 yes, require is SDK specific, though I think there is a way to get it via Cu.import. require was introduced whenever the SDK was first bundled with Firefox (long ago, would have to look up the exact time). The abilit to load JSMs directly with require was added a bit later in like Firefox 15 or something like that. If you plan to support Firefox Versions before whenever the SDK was first bundled you're in for a hard one (and supporting anything that old is nearly impossible without going insane with the SDK) – humanoid May 13 '16 at 08:06
  • Oh, and if you plan tonuse XPCOM in the SDK version it will not work after XUL is deprecated, as the two will most likely come together. Instead at that point you will have to mostly use WebExtensions. Some of the SDK APIs will probably still work, but chrome isn't one of them. – humanoid May 13 '16 at 08:23
  • @humanoid Thanks. I'm starting to use `const { Cu:utils, ... etc } = Components` in the XUL for the Services.jsm access, `const` vs `var`, just to clearly communicate that it should not be assigned to. The only thing I use the nsIDOMChromeWindow object for is the human-readable state names which are constants defined to the numeric value. Assuming those numbers are always the same everywhere, I could define then locally in add-on. But Windows Mediator is also chrome? In SDK or WebExtensions, is there any way to check the window state and trigger various actions as previously mentioned? –  May 13 '16 at 15:40
  • Ah actually, things may be ok. WebExtensions will have `windows.WindowState` with string values: normal, minimized, maximized, fullscreen and docked, so no need for the nsIDOMChromeWindow. There is no 1-to-1 state-to-method mapping. However, the single `windows.update()` method will take an updateInfo object as a parameter, with all the properties being optional. The state property, strings as above, will set a new state, so I'm good. I'll be able to completely replicate this add-on feature that used the both checking and changing states and window position. Not sure about SDK support. –  May 13 '16 at 16:14

0 Answers0