Search code examples
javascriptfirefoxtabswindowfirefox-addon

How could a Firefox-Addon find the the tab with the window.name="mywindow"?


I'm running Firefox 30. I have some tabs open. In one is my local-html file, in which i try to set a window.id or document.id to "myhtmlpage".

...
function init() {
    document.name = 'myhtmlpage';
    document.id = 'myhtmlpage';
// or window.name ='myhtmlpage';
//    window.id = 'myhtmlpage';
}

</script></head>
<body onload="init();">
...

With the following code (from some mozilla help page) I can find the contentDocument, but it simply hasn't the .id or .name property or attribute.

function findTabPerURL(url) {
  var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                     .getService(Components.interfaces.nsIWindowMediator);
  var browserEnumerator = wm.getEnumerator("navigator:browser");

  // Check each browser instance for our URL
  var found = false;
  while (!found && browserEnumerator.hasMoreElements()) {
    var browserWin = browserEnumerator.getNext();
    var tabbrowser = browserWin.gBrowser;

    // Check each tab of this browser instance
    var numTabs = tabbrowser.browsers.length;
    for (var index = 0; index < numTabs; index++) {
      var currentBrowser = tabbrowser.getBrowserAtIndex(index);
      if (url == currentBrowser.currentURI.spec) {

        // The URL is already opened. Select this tab.
        tabbrowser.selectedTab = tabbrowser.tabContainer.childNodes[index];

        // Focus *this* browser-window
        browserWin.focus();

        found = true;
        return tabbrowser;
        break;
      }
    }
  }
}
var tab; tab = findTabPerURL("file:///F:/myfile.html");
var cd = tab.contentDocument;
alert(cd.id);  // doesn't exist. I checked the contentDocument with a for (var each in cd) loop.

With this contentDocument (cd) I can manipulate the content. (Like changing the value of an textarea.) So this would be fine.

But I want to find the right document-object by comparing the id, not by comparing the URL! How could I do that?

(There is a similiar question on here, and the answer suggest using linkedBrowser on the tab. But the tab hasn't that attribute. It throws an error and checking with for (var each in tab) doesn't show it either.)


Solution

  • First of all, your code does not actually return the browser, but tabbrowser (i.e. the gBrowser of a window).

    document.id is not a standard property of a document. As such, and since it is defined in another security context, you don't have immediate access to it. This is to prevent a website overriding the default implementation and by that making it possible to feed an add-on fake values.

    Since you know the value is website-defined (and therefore cannot be tricked into believing fake values), it is OK to to unwrap the document object by accessing the .wrappedJS property.

    Correcting both, here is some code that should work (although I didn't test it):

    function findBrowserPerURL(url) {
      var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
                         .getService(Components.interfaces.nsIWindowMediator);
      var browserEnumerator = wm.getEnumerator("navigator:browser");
    
      // Check each browser instance for our URL
      while (browserEnumerator.hasMoreElements()) {
        var browserWin = browserEnumerator.getNext();
        var tabbrowser = browserWin.gBrowser;
    
        // Check each tab of this browser instance
        var numTabs = tabbrowser.browsers.length;
        for (var index = 0; index < numTabs; index++) {
          var currentBrowser = tabbrowser.getBrowserAtIndex(index);
          if (url == currentBrowser.currentURI.spec) {
            // The URL is already opened. Select this tab.
            tabbrowser.selectedTab = tabbrowser.tabContainer.childNodes[index];
    
            // Focus *this* browser-window
            browserWin.focus();
    
            return currentBrowser;
          }
        }
      }
      return null;
    }
    
    var browser = findBrowserPerURL("file:///F:/myfile.html");
    if (browser) {
      alert(browser.contentDocument.wrappedJSObject.id + " " + browser.contentDocument.wrappedJSObject.name);
    }