make script injection to add navigator.service.contacts work with both 3.6.x and 4 oauth
authormixedpuppy <mixedpuppy@gmail.com>
Wed, 10 Nov 2010 14:32:49 -0800
branchoauth
changeset 234 482b42950cac
parent 233 29418fd89b0e
child 235 2e7a8a102919
push id190
push usermixedpuppy@gmail.com
push date2010-11-10 22:46 +0000
make script injection to add navigator.service.contacts work with both 3.6.x and 4 some of this is based on work done for f1 where injection has been moved to a module and can be used more generically, we can move to that for contacts later. myk looked at the similar changes for f1.
content/injected.js
content/injector.js
deleted file mode 100755
--- a/content/injected.js
+++ /dev/null
@@ -1,48 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is People.
- *
- * The Initial Developer of the Original Code is Mozilla.
- * Portions created by the Initial Developer are Copyright (C) 2009
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Myk Melez <myk@mozilla.org>
- *   Justin Dolske <dolske@mozilla.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* The people API injected into window.navigator objects. */
-  
-  if (window && window.navigator){
-    if (!window.navigator.service)
-      window.navigator.service = {};
-    window.navigator.service.contacts = {
-      find: function(fields, successCallback, failureCallback, options) {
-        contacts_find(window, fields, successCallback, failureCallback, options);
-      }
-    };
-  }
--- a/content/injector.js
+++ b/content/injector.js
@@ -46,80 +46,96 @@ let refreshed;
 let PeopleInjector = {
   // URI module
   URI: null,
 
   // People module
   People: null,
 
   onLoad: function() {
+    dump('observe document creation\n');
     var obs = Components.classes["@mozilla.org/observer-service;1"].
                           getService(Components.interfaces.nsIObserverService);
     obs.addObserver(this, 'content-document-global-created', false);
   },
 
   onUnload: function() {
+    var obs = Components.classes["@mozilla.org/observer-service;1"].
+                          getService(Components.interfaces.nsIObserverService);
+    obs.removeObserver(this, 'content-document-global-created');
   },
 
 
   observe: function(aSubject, aTopic, aData) {
-    var win = aSubject;
-    if (win == window) return;
-    this._inject(win);
+    if (!aSubject.location.href) return;
+    // is this window a child of OUR XUL window?
+    var mainWindow = aSubject.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                   .getInterface(Components.interfaces.nsIWebNavigation)
+                   .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
+                   .rootTreeItem
+                   .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                   .getInterface(Components.interfaces.nsIDOMWindow); 
+    if (mainWindow != window) {
+      return;
+    }
+    this._inject(aSubject);
   },
 
   //**************************************************************************//
   // 
 
-  SCRIPT_TO_INJECT_URI: "resource://people/content/injected.js",
-
   get _scriptToInject() {
     delete this._scriptToInject;
 
-    let uri =
-      new this.URI(this.SCRIPT_TO_INJECT_URI).QueryInterface(Components.interfaces.nsIFileURL);
+    var scriptToInject =  (function () {
+      if (window && navigator){
+        if (!navigator.service)
+          navigator.service = {};
+        navigator.service.contacts = {
+          find: function(fields, successCallback, failureCallback, options) {
+            contacts_find(window, fields, successCallback, failureCallback, options);
+          }
+        };
+      }
+    }).toString();
 
-    // Slurp the contents of the file into a string.
-    let inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].
-                      createInstance(Components.interfaces.nsIFileInputStream);
-    inputStream.init(uri.file, 0x01, -1, null); // RD_ONLY
-    let lineStream = inputStream.QueryInterface(Components.interfaces.nsILineInputStream);
-    let line = { value: "" }, hasMore, scriptToInject = "";
-    do {
-        hasMore = lineStream.readLine(line);
-        scriptToInject += line.value + "\n";
-    } while (hasMore);
-    lineStream.close();
-
-    return this._scriptToInject = scriptToInject;
+    return this._scriptToInject = "("+scriptToInject+")();";
   },
 
   /*
    * _inject
    *
    * Injects the content API into the specified DOM window.
    */
-  _inject: function(win) {
-    let sandbox = new Components.utils.Sandbox(win);
+  _inject: function(safeWin) {
+    if (typeof(XPCNativeWrapper) != 'undefined') {
+      // ensure we do indeed have a nativewrapper
+      safeWin = new XPCNativeWrapper(safeWin);
+    }
+    // options here are ignored for 3.6
+    let sandbox = new Components.utils.Sandbox(safeWin, { sandboxProto: safeWin, wantXrays: true });
     sandbox.importFunction(this._getFindFunction(), "contacts_find");
-    sandbox.window = win.wrappedJSObject;
-    Components.utils.evalInSandbox(this._scriptToInject, sandbox, "1.8",
-                     this.SCRIPT_TO_INJECT_URI, 1);
+    sandbox.window = safeWin;
+    sandbox.navigator = safeWin.navigator.wrappedJSObject;
+    Components.utils.evalInSandbox(this._scriptToInject, sandbox, "1.8");
   },
 
   _getFindFunction: function() {
     // Make the People module accessible to the find function via a closure.
     let People = this.People;
     let URI = this.URI;
 
     return function(win, fields, successCallback, failureCallback, options) {
-      win = XPCSafeJSObjectWrapper(win);
-      options = XPCSafeJSObjectWrapper(options);
-      successCallback = XPCSafeJSObjectWrapper(successCallback);
-      failureCallback = XPCSafeJSObjectWrapper(failureCallback);
+      // fx 4 no longer has XPCSafeJSObjectWrapper, it is handled transparently
+      if (typeof(XPCSafeJSObjectWrapper) != 'undefined') {
+        win = XPCSafeJSObjectWrapper(win);
+        options = XPCSafeJSObjectWrapper(options);
+        successCallback = XPCSafeJSObjectWrapper(successCallback);
+        failureCallback = XPCSafeJSObjectWrapper(failureCallback);
+      }
 
       let permissionManager = Components.classes["@mozilla.org/permissionmanager;1"].
                               getService(Components.interfaces.nsIPermissionManager);
       let uri = new URI(win.location);
 
       function onAllow() {
         // This function is called when the user clicks "Allow..."
         // or automatically because a) they are in a built-in screen,
@@ -367,10 +383,10 @@ let PeopleInjector = {
         box.removeNotification(oldBar);
     }
   }
 };
 
 Components.utils.import("resource://people/modules/ext/URI.js", PeopleInjector);
 Components.utils.import("resource://people/modules/people.js", PeopleInjector);
 
-window.addEventListener("load",   function() PeopleInjector.onLoad(),   false);
+PeopleInjector.onLoad()
 window.addEventListener("unload", function() PeopleInjector.onUnload(), false);