Bug 1021280 - Uplift Add-on SDK to Firefox r=me
authorErik Vold <evold@mozilla.com>
Thu, 05 Jun 2014 16:22:03 -0700
changeset 207478 01332e9ad8518bc79500a9ad2aaf6277dbd972e6
parent 207477 abc445f4c32569d5d3780de3ee7eb49d51c85375
child 207479 45fd2bac9153e4d6ede9faef08a0800863f6c9ec
push id494
push userraliiev@mozilla.com
push dateMon, 25 Aug 2014 18:42:16 +0000
treeherdermozilla-release@a3cc3e46b571 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs1021280
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1021280 - Uplift Add-on SDK to Firefox r=me
addon-sdk/source/examples/toolbar-api/package.json
addon-sdk/source/lib/sdk/addon/runner.js
addon-sdk/source/lib/sdk/content/content.js
addon-sdk/source/lib/sdk/request.js
addon-sdk/source/lib/sdk/self.js
addon-sdk/source/lib/sdk/tabs/utils.js
addon-sdk/source/lib/toolkit/loader.js
addon-sdk/source/python-lib/cuddlefish/__init__.py
addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py
addon-sdk/source/test/addons/content-permissions/main.js
addon-sdk/source/test/addons/l10n-properties/main.js
addon-sdk/source/test/addons/l10n/main.js
addon-sdk/source/test/addons/layout-change/main.js
addon-sdk/source/test/addons/packed/main.js
addon-sdk/source/test/addons/require/main.js
addon-sdk/source/test/addons/simple-prefs/lib/main.js
addon-sdk/source/test/addons/unpacked/main.js
addon-sdk/source/test/test-child_process.js
addon-sdk/source/test/test-content-symbiont.js
addon-sdk/source/test/test-request.js
--- a/addon-sdk/source/examples/toolbar-api/package.json
+++ b/addon-sdk/source/examples/toolbar-api/package.json
@@ -1,9 +1,12 @@
 {
   "name": "toolbar-api",
-  "title": "toolbar-api",
-  "id": "toolbar-api",
+  "title": "Toolbar API",
+  "main": "./lib/main.js",
   "description": "a toolbar api example",
   "author": "",
   "license": "MPL 2.0",
-  "version": "0.1"
+  "version": "0.1",
+  "engines": {
+    "firefox": ">=27.0 <=30.0"
+  }
 }
--- a/addon-sdk/source/lib/sdk/addon/runner.js
+++ b/addon-sdk/source/lib/sdk/addon/runner.js
@@ -7,21 +7,22 @@ module.metadata = {
 };
 
 const { Cc, Ci } = require('chrome');
 const { descriptor, Sandbox, evaluate, main, resolveURI } = require('toolkit/loader');
 const { once } = require('../system/events');
 const { exit, env, staticArgs } = require('../system');
 const { when: unload } = require('../system/unload');
 const { loadReason } = require('../self');
-const { rootURI, metadata: { preferences } } = require("@loader/options");
+const { rootURI, metadata } = require("@loader/options");
 const globals = require('../system/globals');
 const xulApp = require('../system/xul-app');
 const appShellService = Cc['@mozilla.org/appshell/appShellService;1'].
                         getService(Ci.nsIAppShellService);
+const { preferences } = metadata;
 
 const NAME2TOPIC = {
   'Firefox': 'sessionstore-windows-restored',
   'Fennec': 'sessionstore-windows-restored',
   'SeaMonkey': 'sessionstore-windows-restored',
   'Thunderbird': 'mail-startup-done'
 };
 
@@ -129,23 +130,23 @@ function run(options) {
     catch(error) {
       console.exception(error);
     }
 
     // native-options does stuff directly with preferences key from package.json
     if (preferences && preferences.length > 0) {
       try {
         require('../preferences/native-options').enable(preferences);
-      } 
+      }
       catch (error) {
-        console.exception(error); 
+        console.exception(error);
       }
-    } 
+    }
     else {
-      // keeping support for addons packaged with older SDK versions, 
+      // keeping support for addons packaged with older SDK versions,
       // when cfx didn't include the 'preferences' key in @loader/options
 
       // Initialize inline options localization, without preventing addon to be
       // run in case of error
       try {
         require('../l10n/prefs').enable();
       }
       catch(error) {
@@ -153,17 +154,17 @@ function run(options) {
       }
 
       // TODO: When bug 564675 is implemented this will no longer be needed
       // Always set the default prefs, because they disappear on restart
       if (options.prefsURI) {
         // Only set if `prefsURI` specified
         try {
           setDefaultPrefs(options.prefsURI);
-        } 
+        }
         catch (err) {
           // cfx bootstrap always passes prefsURI, even in addons without prefs
         }
       }
     }
 
     // this is where the addon's main.js finally run.
     let program = main(options.loader, options.main);
--- a/addon-sdk/source/lib/sdk/content/content.js
+++ b/addon-sdk/source/lib/sdk/content/content.js
@@ -2,18 +2,31 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 module.metadata = {
   "stability": "deprecated"
 };
 
-const { deprecateFunction } = require('../util/deprecate');
+const { deprecateUsage } = require('../util/deprecate');
+
+Object.defineProperty(exports, "Loader", { 
+  get: function() {
+    deprecateUsage('`sdk/content/content` is deprecated. Please use `sdk/content/loader` directly.');
+    return require('./loader').Loader;
+  }
+});
 
-exports.Loader = deprecateFunction(require('./loader').Loader,
-  '`sdk/content/content` is deprecated. Please use `sdk/content/loader` directly.');
-exports.Symbiont = deprecateFunction(require('../deprecated/symbiont').Symbiont,
-  'Both `sdk/content/content` and `sdk/deprecated/symbiont` are deprecated. ' +
-  '`sdk/core/heritage` supersedes Symbiont for inheritance.');
-exports.Worker = deprecateFunction(require('./worker').Worker,
-  '`sdk/content/content` is deprecated. Please use `sdk/content/worker` directly.');
+Object.defineProperty(exports, "Symbiont", { 
+  get: function() {
+    deprecateUsage('Both `sdk/content/content` and `sdk/deprecated/symbiont` are deprecated. ' +
+                   '`sdk/core/heritage` supersedes Symbiont for inheritance.');
+    return require('../deprecated/symbiont').Symbiont;
+  }
+});
 
+Object.defineProperty(exports, "Worker", { 
+  get: function() {
+    deprecateUsage('`sdk/content/content` is deprecated. Please use `sdk/content/worker` directly.');
+    return require('./worker').Worker;
+  }
+});
--- a/addon-sdk/source/lib/sdk/request.js
+++ b/addon-sdk/source/lib/sdk/request.js
@@ -39,36 +39,42 @@ const { validateOptions, validateSingleO
   },
   contentType: {
     map: function (v) v || "application/x-www-form-urlencoded",
     is:  ["string"],
   },
   overrideMimeType: {
     map: function(v) v || null,
     is: ["string", "null"],
+  },
+  anonymous: {
+    map: function(v) v || false,
+    is: ["boolean", "null"],
   }
 });
 
 const REUSE_ERROR = "This request object has been used already. You must " +
                     "create a new one to make a new request."
 
 // Utility function to prep the request since it's the same between
 // request types
 function runRequest(mode, target) {
   let source = request(target)
-  let { xhr, url, content, contentType, headers, overrideMimeType } = source;
+  let { xhr, url, content, contentType, headers, overrideMimeType, anonymous } = source;
 
   let isGetOrHead = (mode == "GET" || mode == "HEAD");
 
   // If this request has already been used, then we can't reuse it.
   // Throw an error.
   if (xhr)
     throw new Error(REUSE_ERROR);
 
-  xhr = source.xhr = new XMLHttpRequest();
+  xhr = source.xhr = new XMLHttpRequest({
+    mozAnon: anonymous
+  });
 
   // Build the data to be set. For GET or HEAD requests, we want to append that
   // to the URL before opening the request.
   let data = stringify(content);
   // If the URL already has ? in it, then we want to just use &
   if (isGetOrHead && data)
     url = url + (/\?/.test(url) ? "&" : "?") + data;
 
@@ -124,16 +130,17 @@ const Request = Class({
   get content() { return request(this).content; },
   set content(value) {
     request(this).content = validateSingleOption('content', value);
   },
   get contentType() { return request(this).contentType; },
   set contentType(value) {
     request(this).contentType = validateSingleOption('contentType', value);
   },
+  get anonymous() { return request(this).anonymous; },
   get response() { return request(this).response; },
   delete: function() {
     runRequest('DELETE', this);
     return this;
   },
   get: function() {
     runRequest('GET', this);
     return this;
@@ -197,17 +204,18 @@ const Response = Class({
         headers[key] = val;
         lastKey = key;
       }
       else {
         headers[lastKey] += "\n" + val;
       }
     });
     return headers;
-  }
+  },
+  get anonymous() response(this).request.mozAnon
 });
 
 // apiUtils.validateOptions doesn't give the ability to easily validate single
 // options, so this is a wrapper that provides that ability.
 function OptionsValidator(rules) {
   return {
     validateOptions: function (options) {
       return apiUtils.validateOptions(options, rules);
--- a/addon-sdk/source/lib/sdk/self.js
+++ b/addon-sdk/source/lib/sdk/self.js
@@ -3,37 +3,48 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 module.metadata = {
   "stability": "stable"
 };
 
 const { CC } = require('chrome');
-const { id, name, prefixURI, rootURI, metadata,
-        version, loadReason, preferencesBranch } = require('@loader/options');
+const options = require('@loader/options');
 
+const { get } = require("./preferences/service");
 const { readURISync } = require('./net/url');
 
-const addonDataURI = prefixURI + name + '/data/';
+const id = options.id;
+
+const readPref = key => get("extensions." + id + ".sdk." + key);
+
+const name = readPref("name") || options.name;
+const version = readPref("version") || options.version;
+const loadReason = readPref("load.reason") || options.loadReason;
+const rootURI = readPref("rootURI") || options.rootURI || "";
+const baseURI = readPref("baseURI") || options.prefixURI + name + "/";
+const addonDataURI = baseURI + "data/";
+const metadata = options.metadata || {};
+const permissions = metadata.permissions || {};
+const isPacked = rootURI && rootURI.indexOf("jar:") === 0;
 
 const uri = (path="") =>
   path.contains(":") ? path : addonDataURI + path;
 
 
 // Some XPCOM APIs require valid URIs as an argument for certain operations
 // (see `nsILoginManager` for example). This property represents add-on
 // associated unique URI string that can be used for that.
 exports.uri = 'addon:' + id;
 exports.id = id;
-exports.preferencesBranch = preferencesBranch || id;
+exports.preferencesBranch = options.preferencesBranch || id;
 exports.name = name;
 exports.loadReason = loadReason;
 exports.version = version;
-// If `rootURI` is jar:file://...!/ than add-on is packed.
-exports.packed = (rootURI || '').indexOf('jar:') === 0;
+exports.packed = isPacked;
 exports.data = Object.freeze({
   url: uri,
   load: function read(path) {
     return readURISync(uri(path));
   }
 });
-exports.isPrivateBrowsingSupported = ((metadata || {}).permissions || {})['private-browsing'] === true;
+exports.isPrivateBrowsingSupported = permissions['private-browsing'] === true;
--- a/addon-sdk/source/lib/sdk/tabs/utils.js
+++ b/addon-sdk/source/lib/sdk/tabs/utils.js
@@ -56,17 +56,18 @@ function activateTab(tab, window) {
   else if (window && window.BrowserApp) {
     window.BrowserApp.selectTab(tab);
   }
   return null;
 }
 exports.activateTab = activateTab;
 
 function getTabBrowser(window) {
-  return window.gBrowser;
+  // bug 1009938 - may be null in SeaMonkey
+  return window.gBrowser || window.getBrowser();
 }
 exports.getTabBrowser = getTabBrowser;
 
 function getTabContainer(window) {
   return getTabBrowser(window).tabContainer;
 }
 exports.getTabContainer = getTabContainer;
 
@@ -235,73 +236,20 @@ exports.getTabContentWindow = getTabCont
  */
 function getAllTabContentWindows() {
   return getTabs().map(getTabContentWindow);
 }
 exports.getAllTabContentWindows = getAllTabContentWindows;
 
 // gets the tab containing the provided window
 function getTabForContentWindow(window) {
-  // Retrieve the topmost frame container. It can be either <xul:browser>,
-  // <xul:iframe/> or <html:iframe/>. But in our case, it should be xul:browser.
-  let browser;
-  try {
-    browser = window.QueryInterface(Ci.nsIInterfaceRequestor)
-                    .getInterface(Ci.nsIWebNavigation)
-                    .QueryInterface(Ci.nsIDocShell)
-                    .chromeEventHandler;
-  } catch(e) {
-    // Bug 699450: The tab may already have been detached so that `window` is
-    // in a almost destroyed state and can't be queryinterfaced anymore.
-  }
-
-  // Is null for toplevel documents
-  if (!browser) {
-    return null;
-  }
-
-  // Retrieve the owner window, should be browser.xul one
-  let chromeWindow = browser.ownerDocument.defaultView;
-
-  // Ensure that it is top-level browser window.
-  // We need extra checks because of Mac hidden window that has a broken
-  // `gBrowser` global attribute.
-  if ('gBrowser' in chromeWindow && chromeWindow.gBrowser &&
-      'browsers' in chromeWindow.gBrowser) {
-    // Looks like we are on Firefox Desktop
-    // Then search for the position in tabbrowser in order to get the tab object
-    let browsers = chromeWindow.gBrowser.browsers;
-    let i = browsers.indexOf(browser);
-    if (i !== -1)
-      return chromeWindow.gBrowser.tabs[i];
-    return null;
-  }
-  // Fennec
-  else if ('BrowserApp' in chromeWindow) {
-    return getTabForWindow(window);
-  }
-
-  return null;
+  return getTabs().find(tab => getTabContentWindow(tab) === window.top) || null;
 }
 exports.getTabForContentWindow = getTabForContentWindow;
 
-// used on fennec
-function getTabForWindow(window) {
-  for each (let { BrowserApp } in getWindows()) {
-    if (!BrowserApp)
-      continue;
-
-    for each (let tab in BrowserApp.tabs) {
-      if (tab.browser.contentWindow == window.top)
-        return tab;
-    }
-  }
-  return null;
-}
-
 function getTabURL(tab) {
   if (tab.browser) // fennec
     return String(tab.browser.currentURI.spec);
   return String(getBrowserForTab(tab).currentURI.spec);
 }
 exports.getTabURL = getTabURL;
 
 function setTabURL(tab, url) {
--- a/addon-sdk/source/lib/toolkit/loader.js
+++ b/addon-sdk/source/lib/toolkit/loader.js
@@ -379,33 +379,32 @@ const resolve = iced(function resolve(id
 });
 exports.resolve = resolve;
 
 // Node-style module lookup
 // Takes an id and path and attempts to load a file using node's resolving
 // algorithm.
 // `id` should already be resolved relatively at this point.
 // http://nodejs.org/api/modules.html#modules_all_together
-const nodeResolve = iced(function nodeResolve(id, requirer, { manifest, rootURI }) {
+const nodeResolve = iced(function nodeResolve(id, requirer, { rootURI }) {
   // Resolve again
   id = exports.resolve(id, requirer);
 
   // we assume that extensions are correct, i.e., a directory doesnt't have '.js'
   // and a js file isn't named 'file.json.js'
-
   let fullId = join(rootURI, id);
 
   let resolvedPath;
   if (resolvedPath = loadAsFile(fullId))
     return stripBase(rootURI, resolvedPath);
   else if (resolvedPath = loadAsDirectory(fullId))
     return stripBase(rootURI, resolvedPath);
   // If manifest has dependencies, attempt to look up node modules
   // in the `dependencies` list
-  else if (manifest.dependencies) {
+  else {
     let dirs = getNodeModulePaths(dirname(join(rootURI, requirer))).map(dir => join(dir, id));
     for (let i = 0; i < dirs.length; i++) {
       if (resolvedPath = loadAsFile(dirs[i]))
         return stripBase(rootURI, resolvedPath);
       if (resolvedPath = loadAsDirectory(dirs[i]))
         return stripBase(rootURI, resolvedPath);
     }
   }
@@ -528,17 +527,16 @@ const Require = iced(function Require(lo
       throw Error('you must provide a module name when calling require() from '
                   + requirer.id, requirer.uri);
 
     let requirement;
     let uri;
 
     // TODO should get native Firefox modules before doing node-style lookups
     // to save on loading time
-
     if (isNative) {
       // If a requireMap is available from `generateMap`, use that to
       // immediately resolve the node-style mapping.
       if (requireMap && requireMap[requirer.id])
         requirement = requireMap[requirer.id][id];
 
       // For native modules, we want to check if it's a module specified
       // in 'modules', like `chrome`, or `@loader` -- if it exists,
@@ -688,17 +686,18 @@ exports.unload = unload;
 //   If `resolve` does not returns `uri` string exception will be thrown by
 //   an associated `require` call.
 const Loader = iced(function Loader(options) {
   let console = new ConsoleAPI({
     consoleID: options.id ? "addon/" + options.id : ""
   });
 
   let {
-    modules, globals, resolve, paths, rootURI, manifest, requireMap, isNative
+    modules, globals, resolve, paths, rootURI,
+    manifest, requireMap, isNative, metadata
   } = override({
     paths: {},
     modules: {},
     globals: {
       console: console
     },
     resolve: options.isNative ?
       exports.nodeResolve :
@@ -743,16 +742,17 @@ const Loader = iced(function Loader(opti
   // state. We freeze it and mark make it's properties non-enumerable
   // as they are pure implementation detail that no one should rely upon.
   let returnObj = {
     destructor: { enumerable: false, value: destructor },
     globals: { enumerable: false, value: globals },
     mapping: { enumerable: false, value: mapping },
     // Map of module objects indexed by module URIs.
     modules: { enumerable: false, value: modules },
+    metadata: { enumerable: false, value: metadata },
     // Map of module sandboxes indexed by module URIs.
     sandboxes: { enumerable: false, value: {} },
     resolve: { enumerable: false, value: resolve },
     // ID of the addon, if provided.
     id: { enumerable: false, value: options.id },
     // Whether the modules loaded should be ignored by the debugger
     invisibleToDebugger: { enumerable: false,
                            value: options.invisibleToDebugger || false },
--- a/addon-sdk/source/python-lib/cuddlefish/__init__.py
+++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py
@@ -1,16 +1,15 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 import sys
 import os
 import optparse
-import webbrowser
 import time
 
 from copy import copy
 import simplejson as json
 from cuddlefish import packaging
 from cuddlefish._version import get_versions
 
 MOZRUNNER_BIN_NOT_FOUND = 'Mozrunner could not locate your binary'
--- a/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py
+++ b/addon-sdk/source/python-lib/cuddlefish/tests/test_xpi.py
@@ -143,22 +143,22 @@ class SmallXPI(unittest.TestCase):
                      ]]
 
         add_addon_sdk= lambda path: os.path.join(addon_sdk_dir, path)
         expected.extend([add_addon_sdk(module) for module in [
             os.path.join("sdk", "self.js"),
             os.path.join("sdk", "core", "promise.js"),
             os.path.join("sdk", "net", "url.js"),
             os.path.join("sdk", "util", "object.js"),
-            os.path.join("sdk", "util", "array.js")
+            os.path.join("sdk", "util", "array.js"),
+            os.path.join("sdk", "preferences", "service.js")
             ]])
 
         missing = set(expected) - set(used_files)
         extra = set(used_files) - set(expected)
-
         self.failUnlessEqual(list(missing), [])
         self.failUnlessEqual(list(extra), [])
         used_deps = m.get_used_packages()
 
         build = packaging.generate_build_for_target(pkg_cfg, target_cfg.name,
                                                     used_deps,
                                                     include_tests=False)
         options = {'main': target_cfg.main}
@@ -185,16 +185,18 @@ class SmallXPI(unittest.TestCase):
                     "resources/addon-sdk/lib/sdk/self.js",
                     "resources/addon-sdk/lib/sdk/core/",
                     "resources/addon-sdk/lib/sdk/util/",
                     "resources/addon-sdk/lib/sdk/net/",
                     "resources/addon-sdk/lib/sdk/core/promise.js",
                     "resources/addon-sdk/lib/sdk/util/object.js",
                     "resources/addon-sdk/lib/sdk/util/array.js",
                     "resources/addon-sdk/lib/sdk/net/url.js",
+                    "resources/addon-sdk/lib/sdk/preferences/",
+                    "resources/addon-sdk/lib/sdk/preferences/service.js",
                     "resources/three/",
                     "resources/three/lib/",
                     "resources/three/lib/main.js",
                     "resources/three/data/",
                     "resources/three/data/msg.txt",
                     "resources/three/data/subdir/",
                     "resources/three/data/subdir/submsg.txt",
                     "resources/three-a/",
--- a/addon-sdk/source/test/addons/content-permissions/main.js
+++ b/addon-sdk/source/test/addons/content-permissions/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const { PageMod } = require("sdk/page-mod");
 const tabs = require("sdk/tabs");
 const { startServerAsync } = require("sdk/test/httpd");
 
--- a/addon-sdk/source/test/addons/l10n-properties/main.js
+++ b/addon-sdk/source/test/addons/l10n-properties/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const prefs = require("sdk/preferences/service");
 const { Loader } = require('sdk/test/loader');
 const { resolveURI } = require('toolkit/loader');
 const { rootURI } = require("@loader/options");
--- a/addon-sdk/source/test/addons/l10n/main.js
+++ b/addon-sdk/source/test/addons/l10n/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const prefs = require("sdk/preferences/service");
 const { Loader } = require('sdk/test/loader');
 const { resolveURI } = require('toolkit/loader');
 const { rootURI } = require("@loader/options");
--- a/addon-sdk/source/test/addons/layout-change/main.js
+++ b/addon-sdk/source/test/addons/layout-change/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 const { LoaderWithHookedConsole } = require('sdk/test/loader');
 const { loader } = LoaderWithHookedConsole(module);
 const app = require("sdk/system/xul-app");
--- a/addon-sdk/source/test/addons/packed/main.js
+++ b/addon-sdk/source/test/addons/packed/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const { packed } = require("sdk/self");
 const url = require("sdk/url");
 
 exports["test self.packed"] = function (assert) {
--- a/addon-sdk/source/test/addons/require/main.js
+++ b/addon-sdk/source/test/addons/require/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 exports["test local vs sdk module"] = function (assert) {
   assert.notEqual(require("memory"),
                   require("sdk/deprecated/memory"),
                   "Local module takes the priority over sdk modules");
--- a/addon-sdk/source/test/addons/simple-prefs/lib/main.js
+++ b/addon-sdk/source/test/addons/simple-prefs/lib/main.js
@@ -129,17 +129,17 @@ if (app.is('Firefox')) {
 
               tab.close(done);
             }
           });
       	}
       });
   }
 
-  // run it again, to test against inline options document caching 
+  // run it again, to test against inline options document caching
   // and duplication of <setting> nodes upon re-entry to about:addons
   exports.testAgainstDocCaching = exports.testAOM;
 
 }
 
 exports.testDefaultPreferencesBranch = function(assert) {
   assert.equal(preferencesBranch, self.id, 'preferencesBranch default the same as self.id');
 }
--- a/addon-sdk/source/test/addons/unpacked/main.js
+++ b/addon-sdk/source/test/addons/unpacked/main.js
@@ -1,9 +1,9 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
+/* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const { packed } = require("sdk/self");
 const url = require("sdk/url");
 
 exports["test self.packed"] = function (assert) {
--- a/addon-sdk/source/test/test-child_process.js
+++ b/addon-sdk/source/test/test-child_process.js
@@ -535,8 +535,11 @@ exports.testFork = function (assert) {
   assert.throws(function () {
     fork();
   }, /not currently supported/, 'fork() correctly throws an unsupported error');
 };
 
 after(exports, cleanUp);
 
 require("test").run(exports);
+
+// Test disabled because of bug 979675
+module.exports = {};
--- a/addon-sdk/source/test/test-content-symbiont.js
+++ b/addon-sdk/source/test/test-content-symbiont.js
@@ -4,16 +4,20 @@
 "use strict";
 
 const { Cc, Ci } = require('chrome');
 const { Symbiont } = require('sdk/deprecated/symbiont');
 const self = require('sdk/self');
 const fixtures = require("./fixtures");
 const { close } = require('sdk/window/helpers');
 const app = require("sdk/system/xul-app");
+const { LoaderWithHookedConsole } = require('sdk/test/loader');
+const { set: setPref, get: getPref } = require("sdk/preferences/service");
+
+const DEPRECATE_PREF = "devtools.errorconsole.deprecation_warnings";
 
 function makeWindow() {
   let content =
     '<?xml version="1.0"?>' +
     '<window ' +
     'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' +
     '<iframe id="content" type="content"/>' +
     '</window>';
@@ -152,9 +156,30 @@ exports["test:document element present o
         assert.ok(message, "document element present on 'start'");
       else
         assert.pass("document element not necessarily present on 'start'");
       done();
     }
   });
 };
 
+exports["test:content/content deprecation"] = function(assert) {
+  let pref = getPref(DEPRECATE_PREF, false);
+  setPref(DEPRECATE_PREF, true);
+
+  const { loader, messages } = LoaderWithHookedConsole(module);
+  const { Loader, Symbiont, Worker } = loader.require("sdk/content/content");
+
+  assert.equal(messages.length, 3, "Should see three warnings");
+
+  assert.strictEqual(Loader, loader.require('sdk/content/loader').Loader,
+    "Loader from content/content is the exact same object as the one from content/loader");
+
+  assert.strictEqual(Symbiont, loader.require('sdk/deprecated/symbiont').Symbiont,
+    "Symbiont from content/content is the exact same object as the one from deprecated/symbiont");
+
+  assert.strictEqual(Worker, loader.require('sdk/content/worker').Worker,
+    "Worker from content/content is the exact same object as the one from content/worker");
+
+  setPref(DEPRECATE_PREF, pref);
+}
+
 require("test").run(exports);
--- a/addon-sdk/source/test/test-request.js
+++ b/addon-sdk/source/test/test-request.js
@@ -38,16 +38,33 @@ exports.testOptionsValidator = function(
     url: "http://playground.zpao.com/jetpack/request/text.php",
     onComplete: function () {}
   });
   assert.throws(function () {
     req.url = 'www.mozilla.org';
   }, /The option "url" is invalid/);
   // The url shouldn't have changed, so check that
   assert.equal(req.url, "http://playground.zpao.com/jetpack/request/text.php");
+
+  // Test default anonymous parameter value
+  assert.equal(req.anonymous, false);
+  // Test set anonymous parameter value
+  req = Request({
+    url: "http://playground.zpao.com/jetpack/request/text.php",
+    anonymous: true,
+    onComplete: function () {}
+  });
+  assert.equal(req.anonymous, true);
+  // Test wrong value as anonymous parameter value
+  assert.throws(function() {
+    Request({
+      url: "http://playground.zpao.com/jetpack/request/text.php",
+      anonymous: "invalidvalue"
+    });
+  }, /The option "anonymous" must be one of the following types/);
 };
 
 exports.testContentValidator = function(assert, done) {
   runMultipleURLs(null, assert, done, {
     url: "data:text/html;charset=utf-8,response",
     content: { 'key1' : null, 'key2' : 'some value' },
     onComplete: function(response) {
       assert.equal(response.text, "response?key1=null&key2=some+value");
@@ -178,16 +195,70 @@ exports.test3rdPartyCookies = function (
           assert.equal(response.headers['x-jetpack-3rd-party'], 'true');
           srv.stop(done);
         }
       }).get();
     }
   }).get();
 };
 
+// Test anonymous request behavior
+exports.testAnonymousRequest = function(assert, done) {
+  let srv = startServerAsync(port, basePath);
+  let basename = "test-anonymous-request.sjs";
+  let testUrl = "http://localhost:" + port + "/" + basename;
+  // Function to handle the requests in the server
+  let content = function handleRequest(request, response) {
+    // Request to store cookie
+    response.setHeader("Set-Cookie", "anonymousKey=anonymousValue;", "true");
+    // Set response content type
+    response.setHeader("Content-Type", "application/json");
+    // Check if cookie was send during request
+    var cookiePresent = request.hasHeader("Cookie");
+    // Create server respone content
+    response.write(JSON.stringify({ "hasCookie": cookiePresent }));
+  }.toString();
+  prepareFile(basename, content);
+  // Create request callbacks
+  var checkCookieCreated = function (response) {
+    // Check that the server created the cookie
+    assert.equal(response.headers['Set-Cookie'], 'anonymousKey=anonymousValue;');
+    // Make an other request and check that the server this time got the cookie
+    Request({
+      url: testUrl,
+      onComplete: checkCookieSend
+    }).get();
+  },
+  checkCookieSend = function (response) {
+    // Check the response sent headers and cookies
+    assert.equal(response.anonymous, false);
+    // Check the server got the created cookie
+    assert.equal(response.json.hasCookie, true);
+    // Make a anonymous request and check the server did not get the cookie
+    Request({
+      url: testUrl,
+      anonymous: true,
+      onComplete: checkCookieNotSend
+    }).get();
+  },
+  checkCookieNotSend = function (response) {
+    // Check the response is anonymous
+    assert.equal(response.anonymous, true);
+    // Check the server did not get the cookie
+    assert.equal(response.json.hasCookie, false);
+    // Stop the server
+    srv.stop(done);
+  };
+  // Make the first request to create cookie
+  Request({
+    url: testUrl,
+    onComplete: checkCookieCreated
+  }).get();
+};
+
 exports.testSimpleJSON = function (assert, done) {
   let srv = startServerAsync(port, basePath);
   let json = { foo: "bar" };
   let basename = "test-request.json";
   prepareFile(basename, JSON.stringify(json));
 
   runMultipleURLs(srv, assert, done, {
     url: "http://localhost:" + port + "/" + basename,