Bug 1350646: Part 6 - Remove SDK UI modules. r?Mossop draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 02 Aug 2017 14:11:00 -0700
changeset 641186 2c80406822f134a806f93b39d7a8458ef7942159
parent 641185 894a8b2af13295c4046c2a86dab68a904b89091d
child 641187 af9341bbfd7c6c882dced65b1c02ade99a8159d1
push id72469
push usermaglione.k@gmail.com
push dateSun, 06 Aug 2017 07:23:41 +0000
reviewersMossop
bugs1350646
milestone57.0a1
Bug 1350646: Part 6 - Remove SDK UI modules. r?Mossop MozReview-Commit-ID: Joln7vw9Y9r
addon-sdk/moz.build
addon-sdk/source/lib/diffpatcher/diff.js
addon-sdk/source/lib/diffpatcher/index.js
addon-sdk/source/lib/diffpatcher/patch.js
addon-sdk/source/lib/diffpatcher/rebase.js
addon-sdk/source/lib/diffpatcher/test/common.js
addon-sdk/source/lib/diffpatcher/test/diff.js
addon-sdk/source/lib/diffpatcher/test/index.js
addon-sdk/source/lib/diffpatcher/test/patch.js
addon-sdk/source/lib/diffpatcher/test/tap.js
addon-sdk/source/lib/framescript/context-menu.js
addon-sdk/source/lib/sdk/content/context-menu.js
addon-sdk/source/lib/sdk/context-menu.js
addon-sdk/source/lib/sdk/context-menu/context.js
addon-sdk/source/lib/sdk/context-menu/core.js
addon-sdk/source/lib/sdk/context-menu/readers.js
addon-sdk/source/lib/sdk/context-menu@2.js
addon-sdk/source/lib/sdk/input/browser.js
addon-sdk/source/lib/sdk/input/customizable-ui.js
addon-sdk/source/lib/sdk/input/frame.js
addon-sdk/source/lib/sdk/input/system.js
addon-sdk/source/lib/sdk/panel.js
addon-sdk/source/lib/sdk/panel/events.js
addon-sdk/source/lib/sdk/panel/utils.js
addon-sdk/source/lib/sdk/ui.js
addon-sdk/source/lib/sdk/ui/button/action.js
addon-sdk/source/lib/sdk/ui/button/contract.js
addon-sdk/source/lib/sdk/ui/button/toggle.js
addon-sdk/source/lib/sdk/ui/button/view.js
addon-sdk/source/lib/sdk/ui/button/view/events.js
addon-sdk/source/lib/sdk/ui/component.js
addon-sdk/source/lib/sdk/ui/frame.js
addon-sdk/source/lib/sdk/ui/frame/model.js
addon-sdk/source/lib/sdk/ui/frame/view.html
addon-sdk/source/lib/sdk/ui/frame/view.js
addon-sdk/source/lib/sdk/ui/id.js
addon-sdk/source/lib/sdk/ui/sidebar.js
addon-sdk/source/lib/sdk/ui/sidebar/actions.js
addon-sdk/source/lib/sdk/ui/sidebar/contract.js
addon-sdk/source/lib/sdk/ui/sidebar/namespace.js
addon-sdk/source/lib/sdk/ui/sidebar/utils.js
addon-sdk/source/lib/sdk/ui/sidebar/view.js
addon-sdk/source/lib/sdk/ui/state.js
addon-sdk/source/lib/sdk/ui/state/events.js
addon-sdk/source/lib/sdk/ui/toolbar.js
addon-sdk/source/lib/sdk/ui/toolbar/model.js
addon-sdk/source/lib/sdk/ui/toolbar/view.js
--- a/addon-sdk/moz.build
+++ b/addon-sdk/moz.build
@@ -16,28 +16,18 @@ EXTRA_JS_MODULES.sdk += [
     'source/app-extension/bootstrap.js',
 ]
 
 EXTRA_JS_MODULES.sdk.system += [
     'source/modules/system/Startup.js',
 ]
 
 modules = [
-    'diffpatcher/diff.js',
-    'diffpatcher/index.js',
-    'diffpatcher/patch.js',
-    'diffpatcher/rebase.js',
-    'diffpatcher/test/common.js',
-    'diffpatcher/test/diff.js',
-    'diffpatcher/test/index.js',
-    'diffpatcher/test/patch.js',
-    'diffpatcher/test/tap.js',
     'framescript/FrameScriptManager.jsm',
     'framescript/content.jsm',
-    'framescript/context-menu.js',
     'framescript/manager.js',
     'framescript/util.js',
     'index.js',
     'jetpack-id/index.js',
     'method/core.js',
     'method/test/browser.js',
     'method/test/common.js',
     'mozilla-toolkit-versioning/index.js',
@@ -47,34 +37,28 @@ modules = [
     'sdk/addon/window.js',
     'sdk/base64.js',
     'sdk/browser/events.js',
     'sdk/clipboard.js',
     'sdk/console/plain-text.js',
     'sdk/console/traceback.js',
     'sdk/content/content-worker.js',
     'sdk/content/content.js',
-    'sdk/content/context-menu.js',
     'sdk/content/events.js',
     'sdk/content/l10n-html.js',
     'sdk/content/loader.js',
     'sdk/content/mod.js',
     'sdk/content/page-mod.js',
     'sdk/content/sandbox.js',
     'sdk/content/sandbox/events.js',
     'sdk/content/tab-events.js',
     'sdk/content/thumbnail.js',
     'sdk/content/utils.js',
     'sdk/content/worker-child.js',
     'sdk/content/worker.js',
-    'sdk/context-menu.js',
-    'sdk/context-menu/context.js',
-    'sdk/context-menu/core.js',
-    'sdk/context-menu/readers.js',
-    'sdk/context-menu@2.js',
     'sdk/core/disposable.js',
     'sdk/core/heritage.js',
     'sdk/core/namespace.js',
     'sdk/core/observer.js',
     'sdk/core/promise.js',
     'sdk/core/reference.js',
     'sdk/deprecated/api-utils.js',
     'sdk/deprecated/events/assembler.js',
@@ -89,20 +73,16 @@ modules = [
     'sdk/event/core.js',
     'sdk/event/dom.js',
     'sdk/event/target.js',
     'sdk/event/utils.js',
     'sdk/frame/utils.js',
     'sdk/fs/path.js',
     'sdk/hotkeys.js',
     'sdk/indexed-db.js',
-    'sdk/input/browser.js',
-    'sdk/input/customizable-ui.js',
-    'sdk/input/frame.js',
-    'sdk/input/system.js',
     'sdk/io/buffer.js',
     'sdk/io/byte-streams.js',
     'sdk/io/file.js',
     'sdk/io/fs.js',
     'sdk/io/stream.js',
     'sdk/io/text-streams.js',
     'sdk/keyboard/hotkeys.js',
     'sdk/keyboard/observer.js',
@@ -126,19 +106,16 @@ modules = [
     'sdk/messaging.js',
     'sdk/model/core.js',
     'sdk/net/url.js',
     'sdk/net/xhr.js',
     'sdk/notifications.js',
     'sdk/output/system.js',
     'sdk/page-mod.js',
     'sdk/page-mod/match-pattern.js',
-    'sdk/panel.js',
-    'sdk/panel/events.js',
-    'sdk/panel/utils.js',
     'sdk/passwords.js',
     'sdk/passwords/utils.js',
     'sdk/platform/xpcom.js',
     'sdk/preferences/event-target.js',
     'sdk/preferences/native-options.js',
     'sdk/preferences/service.js',
     'sdk/preferences/utils.js',
     'sdk/private-browsing.js',
@@ -183,39 +160,16 @@ modules = [
     'sdk/test/harness.js',
     'sdk/test/httpd.js',
     'sdk/test/loader.js',
     'sdk/test/memory.js',
     'sdk/test/options.js',
     'sdk/test/runner.js',
     'sdk/test/utils.js',
     'sdk/timers.js',
-    'sdk/ui.js',
-    'sdk/ui/button/action.js',
-    'sdk/ui/button/contract.js',
-    'sdk/ui/button/toggle.js',
-    'sdk/ui/button/view.js',
-    'sdk/ui/button/view/events.js',
-    'sdk/ui/component.js',
-    'sdk/ui/frame.js',
-    'sdk/ui/frame/model.js',
-    'sdk/ui/frame/view.html',
-    'sdk/ui/frame/view.js',
-    'sdk/ui/id.js',
-    'sdk/ui/sidebar.js',
-    'sdk/ui/sidebar/actions.js',
-    'sdk/ui/sidebar/contract.js',
-    'sdk/ui/sidebar/namespace.js',
-    'sdk/ui/sidebar/utils.js',
-    'sdk/ui/sidebar/view.js',
-    'sdk/ui/state.js',
-    'sdk/ui/state/events.js',
-    'sdk/ui/toolbar.js',
-    'sdk/ui/toolbar/model.js',
-    'sdk/ui/toolbar/view.js',
     'sdk/uri/resource.js',
     'sdk/url.js',
     'sdk/url/utils.js',
     'sdk/util/array.js',
     'sdk/util/collection.js',
     'sdk/util/contract.js',
     'sdk/util/deprecate.js',
     'sdk/util/dispatcher.js',
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/diff.js
+++ /dev/null
@@ -1,45 +0,0 @@
-"use strict";
-
-var method = require("../method/core")
-
-// Method is designed to work with data structures representing application
-// state. Calling it with a state should return object representing `delta`
-// that has being applied to a previous state to get to a current state.
-//
-// Example
-//
-// diff(state) // => { "item-id-1": { title: "some title" } "item-id-2": null }
-var diff = method("diff@diffpatcher")
-
-// diff between `null` / `undefined` to any hash is a hash itself.
-diff.define(null, function(from, to) { return to })
-diff.define(undefined, function(from, to) { return to })
-diff.define(Object, function(from, to) {
-  return calculate(from, to || {}) || {}
-})
-
-function calculate(from, to) {
-  var diff = {}
-  var changes = 0
-  Object.keys(from).forEach(function(key) {
-    changes = changes + 1
-    if (!(key in to) && from[key] != null) diff[key] = null
-    else changes = changes - 1
-  })
-  Object.keys(to).forEach(function(key) {
-    changes = changes + 1
-    var previous = from[key]
-    var current = to[key]
-    if (previous === current) return (changes = changes - 1)
-    if (typeof(current) !== "object") return diff[key] = current
-    if (typeof(previous) !== "object") return diff[key] = current
-    var delta = calculate(previous, current)
-    if (delta) diff[key] = delta
-    else changes = changes - 1
-  })
-  return changes ? diff : null
-}
-
-diff.calculate = calculate
-
-module.exports = diff
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-"use strict";
-
-exports.diff = require("./diff")
-exports.patch = require("./patch")
-exports.rebase = require("./rebase")
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/patch.js
+++ /dev/null
@@ -1,21 +0,0 @@
-"use strict";
-
-var method = require("../method/core")
-var rebase = require("./rebase")
-
-// Method is designed to work with data structures representing application
-// state. Calling it with a state and delta should return object representing
-// new state, with changes in `delta` being applied to previous.
-//
-// ## Example
-//
-// patch(state, {
-//   "item-id-1": { completed: false }, // update
-//   "item-id-2": null                  // delete
-// })
-var patch = method("patch@diffpatcher")
-patch.define(Object, function patch(hash, delta) {
-  return rebase({}, hash, delta)
-})
-
-module.exports = patch
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/rebase.js
+++ /dev/null
@@ -1,36 +0,0 @@
-"use strict";
-
-var nil = {}
-var owns = ({}).hasOwnProperty
-
-function rebase(result, parent, delta) {
-  var key, current, previous, update
-  for (key in parent) {
-    if (owns.call(parent, key)) {
-      previous = parent[key]
-      update = owns.call(delta, key) ? delta[key] : nil
-      if (previous === null) continue
-      else if (previous === void(0)) continue
-      else if (update === null) continue
-      else if (update === void(0)) continue
-      else result[key] = previous
-    }
-  }
-  for (key in delta) {
-    if (owns.call(delta, key)) {
-      update = delta[key]
-      current = owns.call(result, key) ? result[key] : nil
-      if (current === update) continue
-      else if (update === null) continue
-      else if (update === void(0)) continue
-      else if (current === nil) result[key] = update
-      else if (typeof(update) !== "object") result[key] = update
-      else if (typeof(current) !== "object") result[key] = update
-      else result[key]= rebase({}, current, update)
-    }
-  }
-
-  return result
-}
-
-module.exports = rebase
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/test/common.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict";
-
-require("test").run(require("./index"))
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/test/diff.js
+++ /dev/null
@@ -1,59 +0,0 @@
-"use strict";
-
-var diff = require("../diff")
-
-exports["test diff from null"] = function(assert) {
-  var to = { a: 1, b: 2 }
-  assert.equal(diff(null, to), to, "diff null to x returns x")
-  assert.equal(diff(void(0), to), to, "diff undefined to x returns x")
-
-}
-
-exports["test diff to null"] = function(assert) {
-  var from = { a: 1, b: 2 }
-  assert.deepEqual(diff({ a: 1, b: 2 }, null),
-                   { a: null, b: null },
-                   "diff x null returns x with all properties nullified")
-}
-
-exports["test diff identical"] = function(assert) {
-  assert.deepEqual(diff({}, {}), {}, "diff on empty objects is {}")
-
-  assert.deepEqual(diff({ a: 1, b: 2 }, { a: 1, b: 2 }), {},
-                   "if properties match diff is {}")
-
-  assert.deepEqual(diff({ a: 1, b: { c: { d: 3, e: 4 } } },
-                        { a: 1, b: { c: { d: 3, e: 4 } } }), {},
-                   "diff between identical nested hashes is {}")
-
-}
-
-exports["test diff delete"] = function(assert) {
-  assert.deepEqual(diff({ a: 1, b: 2 }, { b: 2 }), { a: null },
-                   "missing property is deleted")
-  assert.deepEqual(diff({ a: 1, b: 2 }, { a: 2 }), { a: 2, b: null },
-                   "missing property is deleted another updated")
-  assert.deepEqual(diff({ a: 1, b: 2 }, {}), { a: null, b: null },
-                   "missing propertes are deleted")
-  assert.deepEqual(diff({ a: 1, b: { c: { d: 2 } } }, {}),
-                   { a: null, b: null },
-                   "missing deep propertes are deleted")
-  assert.deepEqual(diff({ a: 1, b: { c: { d: 2 } } }, { b: { c: {} } }),
-                   { a: null, b: { c: { d: null } } },
-                   "missing nested propertes are deleted")
-}
-
-exports["test add update"] = function(assert) {
-  assert.deepEqual(diff({ a: 1, b: 2 }, { b: 2, c: 3 }), { a: null, c: 3 },
-                   "delete and add")
-  assert.deepEqual(diff({ a: 1, b: 2 }, { a: 2, c: 3 }), { a: 2, b: null, c: 3 },
-                   "delete and adds")
-  assert.deepEqual(diff({}, { a: 1, b: 2 }), { a: 1, b: 2 },
-                   "diff on empty objcet returns equivalen of to")
-  assert.deepEqual(diff({ a: 1, b: { c: { d: 2 } } }, { d: 3 }),
-                   { a: null, b: null, d: 3 },
-                   "missing deep propertes are deleted")
-  assert.deepEqual(diff({ b: { c: {} }, d: null }, { a: 1, b: { c: { d: 2 } } }),
-                   { a: 1, b: { c: { d: 2 } } },
-                   "missing nested propertes are deleted")
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/test/index.js
+++ /dev/null
@@ -1,14 +0,0 @@
-"use strict";
-
-var diff = require("../diff")
-var patch = require("../patch")
-
-exports["test diff"] = require("./diff")
-exports["test patch"] = require("./patch")
-
-exports["test patch(a, diff(a, b)) => b"] = function(assert) {
-  var a = { a: { b: 1 }, c: { d: 2 } }
-  var b = { a: { e: 3 }, c: { d: 4 } }
-
-  assert.deepEqual(patch(a, diff(a, b)), b, "patch(a, diff(a, b)) => b")
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/test/patch.js
+++ /dev/null
@@ -1,83 +0,0 @@
-"use strict";
-
-var patch = require("../patch")
-
-exports["test patch delete"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, { a: null }), { b: 2 }, "null removes property")
-}
-
-exports["test patch delete with void"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, { a: void(0) }), { b: 2 },
-                   "void(0) removes property")
-}
-
-exports["test patch delete missing"] = function(assert) {
-  assert.deepEqual(patch({ a: 1, b: 2 }, { c: null }),
-                   { a: 1, b: 2 },
-                   "null removes property if exists");
-
-  assert.deepEqual(patch({ a: 1, b: 2 }, { c: void(0) }),
-                   { a: 1, b: 2 },
-                   "void removes property if exists");
-}
-
-exports["test delete deleted"] = function(assert) {
-  assert.deepEqual(patch({ a: null, b: 2, c: 3, d: void(0)},
-                         { a: void(0), b: null, d: null }),
-                   {c: 3},
-                  "removed all existing and non existing");
-}
-
-exports["test update deleted"] = function(assert) {
-  assert.deepEqual(patch({ a: null, b: void(0), c: 3},
-                         { a: { b: 2 } }),
-                   { a: { b: 2 }, c: 3 },
-                   "replace deleted");
-}
-
-exports["test patch delete with void"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, { a: void(0) }), { b: 2 },
-                   "void(0) removes property")
-}
-
-
-exports["test patch addition"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, { c: 3 }), { a: 1, b: 2, c: 3 },
-                   "new properties are added")
-}
-
-exports["test patch addition"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, { c: 3 }), { a: 1, b: 2, c: 3 },
-                   "new properties are added")
-}
-
-exports["test hash on itself"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, hash), hash,
-                   "applying hash to itself returns hash itself")
-}
-
-exports["test patch with empty delta"] = function(assert) {
-  var hash = { a: 1, b: 2 }
-
-  assert.deepEqual(patch(hash, {}), hash,
-                   "applying empty delta results in no changes")
-}
-
-exports["test patch nested data"] = function(assert) {
-  assert.deepEqual(patch({ a: { b: 1 }, c: { d: 2 } },
-                         { a: { b: null, e: 3 }, c: { d: 4 } }),
-                   { a: { e: 3 }, c: { d: 4 } },
-                   "nested structures can also be patched")
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/diffpatcher/test/tap.js
+++ /dev/null
@@ -1,3 +0,0 @@
-"use strict";
-
-require("retape")(require("./index"))
deleted file mode 100644
--- a/addon-sdk/source/lib/framescript/context-menu.js
+++ /dev/null
@@ -1,215 +0,0 @@
-/* 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 { query, constant, cache } = require("sdk/lang/functional");
-const { pairs, each, map, object } = require("sdk/util/sequence");
-const { nodeToMessageManager } = require("./util");
-
-// Decorator function that takes `f` function and returns one that attempts
-// to run `f` with given arguments. In case of exception error is logged
-// and `fallback` is returned instead.
-const Try = (fn, fallback=null) => (...args) => {
-  try {
-    return fn(...args);
-  } catch(error) {
-    console.error(error);
-    return fallback;
-  }
-};
-
-// Decorator funciton that takes `f` function and returns one that returns
-// JSON cloned result of whatever `f` returns for given arguments.
-const JSONReturn = f => (...args) => JSON.parse(JSON.stringify(f(...args)));
-
-const Null = constant(null);
-
-// Table of readers mapped to field names they're going to be reading.
-const readers = Object.create(null);
-// Read function takes "contextmenu" event target `node` and returns table of
-// read field names mapped to appropriate values. Read uses above defined read
-// table to read data for all registered readers.
-const read = node =>
-  object(...map(([id, read]) => [id, read(node, id)], pairs(readers)));
-
-// Table of built-in readers, each takes a descriptor and returns a reader:
-// descriptor -> node -> JSON
-const parsers = Object.create(null)
-// Function takes a descriptor of the remotely defined reader and parsese it
-// to construct a local reader that's going to read out data from context menu
-// target.
-const parse = descriptor => {
-  const parser = parsers[descriptor.category];
-  if (!parser) {
-    console.error("Unknown reader descriptor was received", descriptor, `"${descriptor.category}"`);
-    return Null
-  }
-  return Try(parser(descriptor));
-}
-
-// TODO: Test how chrome's mediaType behaves to try and match it's behavior.
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const SVG_NS = "http://www.w3.org/2000/svg";
-
-// Firefox always creates a HTMLVideoElement when loading an ogg file
-// directly. If the media is actually audio, be smarter and provide a
-// context menu with audio operations.
-// Source: https://github.com/mozilla/gecko-dev/blob/28c2fca3753c5371643843fc2f2f205146b083b7/browser/base/content/nsContextMenu.js#L632-L637
-const isVideoLoadingAudio = node =>
-  node.readyState >= node.HAVE_METADATA &&
-    (node.videoWidth == 0 || node.videoHeight == 0)
-
-const isVideo = node =>
-  node instanceof node.ownerGlobal.HTMLVideoElement &&
-  !isVideoLoadingAudio(node);
-
-const isAudio = node => {
-  const {HTMLVideoElement, HTMLAudioElement} = node.ownerGlobal;
-  return node instanceof HTMLAudioElement ? true :
-         node instanceof HTMLVideoElement ? isVideoLoadingAudio(node) :
-         false;
-};
-
-const isImage = ({namespaceURI, localName}) =>
-  namespaceURI === HTML_NS && localName === "img" ? true :
-  namespaceURI === XUL_NS && localName === "image" ? true :
-  namespaceURI === SVG_NS && localName === "image" ? true :
-  false;
-
-parsers["reader/MediaType()"] = constant(node =>
-  isImage(node) ? "image" :
-  isAudio(node) ? "audio" :
-  isVideo(node) ? "video" :
-  null);
-
-
-const readLink = node =>
-  node.namespaceURI === HTML_NS && node.localName === "a" ? node.href :
-  readLink(node.parentNode);
-
-parsers["reader/LinkURL()"] = constant(node =>
-  node.matches("a, a *") ? readLink(node) : null);
-
-// Reader that reads out `true` if "contextmenu" `event.target` matches
-// `descriptor.selector` and `false` if it does not.
-parsers["reader/SelectorMatch()"] = ({selector}) =>
-  node => node.matches(selector);
-
-// Accessing `selectionStart` and `selectionEnd` properties on non
-// editable input nodes throw exceptions, there for we need this util
-// function to guard us against them.
-const getInputSelection = node => {
-  try {
-    if ("selectionStart" in node && "selectionEnd" in node) {
-      const {selectionStart, selectionEnd} = node;
-      return {selectionStart, selectionEnd}
-    }
-  }
-  catch(_) {}
-
-  return null;
-}
-
-// Selection reader does not really cares about descriptor so it is
-// a constant function returning selection reader. Selection reader
-// returns string of the selected text or `null` if there is no selection.
-parsers["reader/Selection()"] = constant(node => {
-  const selection = node.ownerDocument.getSelection();
-  if (!selection.isCollapsed) {
-    return selection.toString();
-  }
-  // If target node is editable (text, input, textarea, etc..) document does
-  // not really handles selections there. There for we fallback to checking
-  // `selectionStart` `selectionEnd` properties and if they are present we
-  // extract selections manually from the `node.value`.
-  else {
-    const selection = getInputSelection(node);
-    const isSelected = selection &&
-                       Number.isInteger(selection.selectionStart) &&
-                       Number.isInteger(selection.selectionEnd) &&
-                       selection.selectionStart !== selection.selectionEnd;
-    return  isSelected ? node.value.substring(selection.selectionStart,
-                                              selection.selectionEnd) :
-            null;
-  }
-});
-
-// Query reader just reads out properties from the node, so we just use `query`
-// utility function.
-parsers["reader/Query()"] = ({path}) => JSONReturn(query(path));
-// Attribute reader just reads attribute of the event target node.
-parsers["reader/Attribute()"] = ({name}) => node => node.getAttribute(name);
-
-// Extractor reader defines generates a reader out of serialized function, who's
-// return value is JSON cloned. Note: We do know source will evaluate to function
-// as that's what we serialized on the other end, it's also ok if generated function
-// is going to throw as registered readers are wrapped in try catch to avoid breakting
-// unrelated readers.
-parsers["reader/Extractor()"] = ({source}) =>
-  JSONReturn(new Function("return (" + source + ")")());
-
-// If the context-menu target node or any of its ancestors is one of these,
-// Firefox uses a tailored context menu, and so the page context doesn't apply.
-// There for `reader/isPage()` will read `false` in that case otherwise it's going
-// to read `true`.
-const nonPageElements = ["a", "applet", "area", "button", "canvas", "object",
-                         "embed", "img", "input", "map", "video", "audio", "menu",
-                         "option", "select", "textarea", "[contenteditable=true]"];
-const nonPageSelector = nonPageElements.
-                          concat(nonPageElements.map(tag => `${tag} *`)).
-                          join(", ");
-
-// Note: isPageContext implementation could have actually used SelectorMatch reader,
-// but old implementation was also checked for collapsed selection there for to keep
-// the behavior same we end up implementing a new reader.
-parsers["reader/isPage()"] = constant(node =>
-  node.ownerGlobal.getSelection().isCollapsed &&
-  !node.matches(nonPageSelector));
-
-// Reads `true` if node is in an iframe otherwise returns true.
-parsers["reader/isFrame()"] = constant(node =>
-  !!node.ownerGlobal.frameElement);
-
-parsers["reader/isEditable()"] = constant(node => {
-  const selection = getInputSelection(node);
-  return selection ? !node.readOnly && !node.disabled : node.isContentEditable;
-});
-
-
-// TODO: Add some reader to read out tab id.
-
-const onReadersUpdate = message => {
-  each(([id, descriptor]) => {
-    if (descriptor) {
-      readers[id] = parse(descriptor);
-    }
-    else {
-      delete readers[id];
-    }
-  }, pairs(message.data));
-};
-exports.onReadersUpdate = onReadersUpdate;
-
-
-const onContextMenu = event => {
-  if (!event.defaultPrevented) {
-    const manager = nodeToMessageManager(event.target);
-    manager.sendSyncMessage("sdk/context-menu/read", read(event.target), readers);
-  }
-};
-exports.onContextMenu = onContextMenu;
-
-
-const onContentFrame = (frame) => {
-  // Listen for contextmenu events in on this frame.
-  frame.addEventListener("contextmenu", onContextMenu);
-  // Listen to registered reader changes and update registry.
-  frame.addMessageListener("sdk/context-menu/readers", onReadersUpdate);
-
-  // Request table of readers (if this is loaded in a new process some table
-  // changes may be missed, this is way to sync up).
-  frame.sendAsyncMessage("sdk/context-menu/readers?");
-};
-exports.onContentFrame = onContentFrame;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/content/context-menu.js
+++ /dev/null
@@ -1,407 +0,0 @@
-/* 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 { Class } = require("../core/heritage");
-const self = require("../self");
-const { WorkerChild } = require("./worker-child");
-const { getInnerId } = require("../window/utils");
-const { Ci } = require("chrome");
-const { Services } = require("resource://gre/modules/Services.jsm");
-const system = require('../system/events');
-const { process } = require('../remote/child');
-
-// These functions are roughly copied from sdk/selection which doesn't work
-// in the content process
-function getElementWithSelection(window) {
-  let element = Services.focus.getFocusedElementForWindow(window, false, {});
-  if (!element)
-    return null;
-
-  try {
-    // Accessing selectionStart and selectionEnd on e.g. a button
-    // results in an exception thrown as per the HTML5 spec.  See
-    // http://www.whatwg.org/specs/web-apps/current-work/multipage/association-of-controls-and-forms.html#textFieldSelection
-
-    let { value, selectionStart, selectionEnd } = element;
-
-    let hasSelection = typeof value === "string" &&
-                      !isNaN(selectionStart) &&
-                      !isNaN(selectionEnd) &&
-                      selectionStart !== selectionEnd;
-
-    return hasSelection ? element : null;
-  }
-  catch (err) {
-    console.exception(err);
-    return null;
-  }
-}
-
-function safeGetRange(selection, rangeNumber) {
-  try {
-    let { rangeCount } = selection;
-    let range = null;
-
-    for (let rangeNumber = 0; rangeNumber < rangeCount; rangeNumber++ ) {
-      range = selection.getRangeAt(rangeNumber);
-
-      if (range && range.toString())
-        break;
-
-      range = null;
-    }
-
-    return range;
-  }
-  catch (e) {
-    return null;
-  }
-}
-
-function getSelection(window) {
-  let selection = window.getSelection();
-  let range = safeGetRange(selection);
-  if (range)
-    return range.toString();
-
-  let node = getElementWithSelection(window);
-  if (!node)
-    return null;
-
-  return node.value.substring(node.selectionStart, node.selectionEnd);
-}
-
-//These are used by PageContext.isCurrent below. If the popupNode or any of
-//its ancestors is one of these, Firefox uses a tailored context menu, and so
-//the page context doesn't apply.
-const NON_PAGE_CONTEXT_ELTS = [
-  Ci.nsIDOMHTMLAnchorElement,
-  Ci.nsIDOMHTMLAreaElement,
-  Ci.nsIDOMHTMLButtonElement,
-  Ci.nsIDOMHTMLCanvasElement,
-  Ci.nsIDOMHTMLEmbedElement,
-  Ci.nsIDOMHTMLImageElement,
-  Ci.nsIDOMHTMLInputElement,
-  Ci.nsIDOMHTMLMapElement,
-  Ci.nsIDOMHTMLMediaElement,
-  Ci.nsIDOMHTMLMenuElement,
-  Ci.nsIDOMHTMLObjectElement,
-  Ci.nsIDOMHTMLOptionElement,
-  Ci.nsIDOMHTMLSelectElement,
-  Ci.nsIDOMHTMLTextAreaElement,
-];
-
-// List all editable types of inputs.  Or is it better to have a list
-// of non-editable inputs?
-var editableInputs = {
-  email: true,
-  number: true,
-  password: true,
-  search: true,
-  tel: true,
-  text: true,
-  textarea: true,
-  url: true
-};
-
-var CONTEXTS = {};
-
-var Context = Class({
-  initialize: function(id) {
-    this.id = id;
-  },
-
-  adjustPopupNode: function adjustPopupNode(popupNode) {
-    return popupNode;
-  },
-
-  // Gets state to pass through to the parent process for the node the user
-  // clicked on
-  getState: function(popupNode) {
-    return false;
-  }
-});
-
-// Matches when the context-clicked node doesn't have any of
-// NON_PAGE_CONTEXT_ELTS in its ancestors
-CONTEXTS.PageContext = Class({
-  extends: Context,
-
-  getState: function(popupNode) {
-    // If there is a selection in the window then this context does not match
-    if (!popupNode.ownerGlobal.getSelection().isCollapsed)
-      return false;
-
-    // If the clicked node or any of its ancestors is one of the blocked
-    // NON_PAGE_CONTEXT_ELTS then this context does not match
-    while (!(popupNode instanceof Ci.nsIDOMDocument)) {
-      if (NON_PAGE_CONTEXT_ELTS.some(type => popupNode instanceof type))
-        return false;
-
-      popupNode = popupNode.parentNode;
-    }
-
-    return true;
-  }
-});
-
-// Matches when there is an active selection in the window
-CONTEXTS.SelectionContext = Class({
-  extends: Context,
-
-  getState: function(popupNode) {
-    if (!popupNode.ownerGlobal.getSelection().isCollapsed)
-      return true;
-
-    try {
-      // The node may be a text box which has selectionStart and selectionEnd
-      // properties. If not this will throw.
-      let { selectionStart, selectionEnd } = popupNode;
-      return !isNaN(selectionStart) && !isNaN(selectionEnd) &&
-             selectionStart !== selectionEnd;
-    }
-    catch (e) {
-      return false;
-    }
-  }
-});
-
-// Matches when the context-clicked node or any of its ancestors matches the
-// selector given
-CONTEXTS.SelectorContext = Class({
-  extends: Context,
-
-  initialize: function initialize(id, selector) {
-    Context.prototype.initialize.call(this, id);
-    this.selector = selector;
-  },
-
-  adjustPopupNode: function adjustPopupNode(popupNode) {
-    let selector = this.selector;
-
-    while (!(popupNode instanceof Ci.nsIDOMDocument)) {
-      if (popupNode.matches(selector))
-        return popupNode;
-
-      popupNode = popupNode.parentNode;
-    }
-
-    return null;
-  },
-
-  getState: function(popupNode) {
-    return !!this.adjustPopupNode(popupNode);
-  }
-});
-
-// Matches when the page url matches any of the patterns given
-CONTEXTS.URLContext = Class({
-  extends: Context,
-
-  getState: function(popupNode) {
-    return popupNode.ownerDocument.URL;
-  }
-});
-
-// Matches when the user-supplied predicate returns true
-CONTEXTS.PredicateContext = Class({
-  extends: Context,
-
-  getState: function(node) {
-    let window = node.ownerGlobal;
-    let data = {};
-
-    data.documentType = node.ownerDocument.contentType;
-
-    data.documentURL = node.ownerDocument.location.href;
-    data.targetName = node.nodeName.toLowerCase();
-    data.targetID = node.id || null ;
-
-    if ((data.targetName === 'input' && editableInputs[node.type]) ||
-        data.targetName === 'textarea') {
-      data.isEditable = !node.readOnly && !node.disabled;
-    }
-    else {
-      data.isEditable = node.isContentEditable;
-    }
-
-    data.selectionText = getSelection(window, "TEXT");
-
-    data.srcURL = node.src || null;
-    data.value = node.value || null;
-
-    while (!data.linkURL && node) {
-      data.linkURL = node.href || null;
-      node = node.parentNode;
-    }
-
-    return data;
-  },
-});
-
-function instantiateContext({ id, type, args }) {
-  if (!(type in CONTEXTS)) {
-    console.error("Attempt to use unknown context " + type);
-    return;
-  }
-  return new CONTEXTS[type](id, ...args);
-}
-
-var ContextWorker = Class({
-  implements: [ WorkerChild ],
-
-  // Calls the context workers context listeners and returns the first result
-  // that is either a string or a value that evaluates to true. If all of the
-  // listeners returned false then returns false. If there are no listeners,
-  // returns true (show the menu item by default).
-  getMatchedContext: function getCurrentContexts(popupNode) {
-    let results = this.sandbox.emitSync("context", popupNode);
-    if (!results.length)
-      return true;
-    return results.reduce((val, result) => val || result);
-  },
-
-  // Emits a click event in the worker's port. popupNode is the node that was
-  // context-clicked, and clickedItemData is the data of the item that was
-  // clicked.
-  fireClick: function fireClick(popupNode, clickedItemData) {
-    this.sandbox.emitSync("click", popupNode, clickedItemData);
-  }
-});
-
-// Gets the item's content script worker for a window, creating one if necessary
-// Once created it will be automatically destroyed when the window unloads.
-// If there is not content scripts for the item then null will be returned.
-function getItemWorkerForWindow(item, window) {
-  if (!item.contentScript && !item.contentScriptFile)
-    return null;
-
-  let id = getInnerId(window);
-  let worker = item.workerMap.get(id);
-
-  if (worker)
-    return worker;
-
-  worker = ContextWorker({
-    id: item.id,
-    window,
-    manager: item.manager,
-    contentScript: item.contentScript,
-    contentScriptFile: item.contentScriptFile,
-    onDetach: function() {
-      item.workerMap.delete(id);
-    }
-  });
-
-  item.workerMap.set(id, worker);
-
-  return worker;
-}
-
-// A very simple remote proxy for every item. It's job is to provide data for
-// the main process to use to determine visibility state and to call into
-// content scripts when clicked.
-var RemoteItem = Class({
-  initialize: function(options, manager) {
-    this.id = options.id;
-    this.contexts = options.contexts.map(instantiateContext);
-    this.contentScript = options.contentScript;
-    this.contentScriptFile = options.contentScriptFile;
-
-    this.manager = manager;
-
-    this.workerMap = new Map();
-    keepAlive.set(this.id, this);
-  },
-
-  destroy: function() {
-    for (let worker of this.workerMap.values()) {
-      worker.destroy();
-    }
-    keepAlive.delete(this.id);
-  },
-
-  activate: function(popupNode, data) {
-    let worker = getItemWorkerForWindow(this, popupNode.ownerGlobal);
-    if (!worker)
-      return;
-
-    for (let context of this.contexts)
-      popupNode = context.adjustPopupNode(popupNode);
-
-    worker.fireClick(popupNode, data);
-  },
-
-  // Fills addonInfo with state data to send through to the main process
-  getContextState: function(popupNode, addonInfo) {
-    if (!(self.id in addonInfo)) {
-      addonInfo[self.id] = {
-        processID: process.id,
-        items: {}
-      };
-    }
-
-    let worker = getItemWorkerForWindow(this, popupNode.ownerGlobal);
-    let contextStates = {};
-    for (let context of this.contexts)
-      contextStates[context.id] = context.getState(popupNode);
-
-    addonInfo[self.id].items[this.id] = {
-      // It isn't ideal to create a PageContext for every item but there isn't
-      // a good shared place to do it.
-      pageContext: (new CONTEXTS.PageContext()).getState(popupNode),
-      contextStates,
-      hasWorker: !!worker,
-      workerContext: worker ? worker.getMatchedContext(popupNode) : true
-    }
-  }
-});
-exports.RemoteItem = RemoteItem;
-
-// Holds remote items for this frame.
-var keepAlive = new Map();
-
-// Called to create remote proxies for items. If they already exist we destroy
-// and recreate. This can happen if the item changes in some way or in odd
-// timing cases where the frame script is create around the same time as the
-// item is created in the main process
-process.port.on('sdk/contextmenu/createitems', (process, items) => {
-  for (let itemoptions of items) {
-    let oldItem = keepAlive.get(itemoptions.id);
-    if (oldItem) {
-      oldItem.destroy();
-    }
-
-    let item = new RemoteItem(itemoptions, this);
-  }
-});
-
-process.port.on('sdk/contextmenu/destroyitems', (process, items) => {
-  for (let id of items) {
-    let item = keepAlive.get(id);
-    item.destroy();
-  }
-});
-
-var lastPopupNode = null;
-
-system.on('content-contextmenu', ({ subject }) => {
-  let { event: { target: popupNode }, addonInfo } = subject.wrappedJSObject;
-  lastPopupNode = popupNode;
-
-  for (let item of keepAlive.values()) {
-    item.getContextState(popupNode, addonInfo);
-  }
-}, true);
-
-process.port.on('sdk/contextmenu/activateitems', (process, items, data) => {
-  for (let id of items) {
-    let item = keepAlive.get(id);
-    if (!item)
-      continue;
-
-    item.activate(lastPopupNode, data);
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/context-menu.js
+++ /dev/null
@@ -1,1187 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "stable",
-  "engines": {
-    // TODO Fennec support Bug 788334
-    "Firefox": "*",
-    "SeaMonkey": "*"
-  }
-};
-
-const { Class, mix } = require("./core/heritage");
-const { ns } = require("./core/namespace");
-lazyRequire(this, "./deprecated/api-utils", "validateOptions", "getTypeOf");
-lazyRequire(this, "./url", "URL", "isValidURI");
-lazyRequire(this, "./deprecated/window-utils", "WindowTracker", "browserWindowIterator");
-lazyRequire(this, "./window/utils", "isBrowser", "getInnerId");
-lazyRequire(this, "./util/match-pattern", "MatchPattern");
-const { EventTarget } = require("./event/target");
-lazyRequire(this, './event/core', "emit");
-const { when } = require('./system/unload');
-const { contract: loaderContract } = require('./content/loader');
-const { omit } = require('./util/object');
-lazyRequireModule(this, './self', "self");
-const { remoteRequire, processes } = require('./remote/parent');
-remoteRequire('sdk/content/context-menu');
-
-// All user items we add have this class.
-const ITEM_CLASS = "addon-context-menu-item";
-
-// Items in the top-level context menu also have this class.
-const TOPLEVEL_ITEM_CLASS = "addon-context-menu-item-toplevel";
-
-// Items in the overflow submenu also have this class.
-const OVERFLOW_ITEM_CLASS = "addon-context-menu-item-overflow";
-
-// The class of the menu separator that separates standard context menu items
-// from our user items.
-const SEPARATOR_CLASS = "addon-context-menu-separator";
-
-// If more than this number of items are added to the context menu, all items
-// overflow into a "Jetpack" submenu.
-const OVERFLOW_THRESH_DEFAULT = 10;
-const OVERFLOW_THRESH_PREF =
-  "extensions.addon-sdk.context-menu.overflowThreshold";
-
-// The label of the overflow sub-xul:menu.
-//
-// TODO: Localize these.
-const OVERFLOW_MENU_LABEL = "Add-ons";
-const OVERFLOW_MENU_ACCESSKEY = "A";
-
-// The class of the overflow sub-xul:menu.
-const OVERFLOW_MENU_CLASS = "addon-content-menu-overflow-menu";
-
-// The class of the overflow submenu's xul:menupopup.
-const OVERFLOW_POPUP_CLASS = "addon-content-menu-overflow-popup";
-
-// Holds private properties for API objects
-var internal = ns();
-
-// A little hacky but this is the last process ID that last opened the context
-// menu
-var lastContextProcessId = null;
-
-var uuidModule = require('./util/uuid');
-function uuid() {
-  return uuidModule.uuid().toString();
-}
-
-function getScheme(spec) {
-  try {
-    return URL(spec).scheme;
-  }
-  catch(e) {
-    return null;
-  }
-}
-
-var Context = Class({
-  initialize: function() {
-    internal(this).id = uuid();
-  },
-
-  // Returns the node that made this context current
-  adjustPopupNode: function adjustPopupNode(popupNode) {
-    return popupNode;
-  },
-
-  // Returns whether this context is current for the current node
-  isCurrent: function isCurrent(state) {
-    return state;
-  }
-});
-
-// Matches when the context-clicked node doesn't have any of
-// NON_PAGE_CONTEXT_ELTS in its ancestors
-var PageContext = Class({
-  extends: Context,
-
-  serialize: function() {
-    return {
-      id: internal(this).id,
-      type: "PageContext",
-      args: []
-    }
-  }
-});
-exports.PageContext = PageContext;
-
-// Matches when there is an active selection in the window
-var SelectionContext = Class({
-  extends: Context,
-
-  serialize: function() {
-    return {
-      id: internal(this).id,
-      type: "SelectionContext",
-      args: []
-    }
-  }
-});
-exports.SelectionContext = SelectionContext;
-
-// Matches when the context-clicked node or any of its ancestors matches the
-// selector given
-var SelectorContext = Class({
-  extends: Context,
-
-  initialize: function initialize(selector) {
-    Context.prototype.initialize.call(this);
-    let options = validateOptions({ selector: selector }, {
-      selector: {
-        is: ["string"],
-        msg: "selector must be a string."
-      }
-    });
-    internal(this).selector = options.selector;
-  },
-
-  serialize: function() {
-    return {
-      id: internal(this).id,
-      type: "SelectorContext",
-      args: [internal(this).selector]
-    }
-  }
-});
-exports.SelectorContext = SelectorContext;
-
-// Matches when the page url matches any of the patterns given
-var URLContext = Class({
-  extends: Context,
-
-  initialize: function initialize(patterns) {
-    Context.prototype.initialize.call(this);
-    patterns = Array.isArray(patterns) ? patterns : [patterns];
-
-    try {
-      internal(this).patterns = patterns.map(p => new MatchPattern(p));
-    }
-    catch (err) {
-      throw new Error("Patterns must be a string, regexp or an array of " +
-                      "strings or regexps: " + err);
-    }
-  },
-
-  isCurrent: function isCurrent(url) {
-    return internal(this).patterns.some(p => p.test(url));
-  },
-
-  serialize: function() {
-    return {
-      id: internal(this).id,
-      type: "URLContext",
-      args: []
-    }
-  }
-});
-exports.URLContext = URLContext;
-
-// Matches when the user-supplied predicate returns true
-var PredicateContext = Class({
-  extends: Context,
-
-  initialize: function initialize(predicate) {
-    Context.prototype.initialize.call(this);
-    let options = validateOptions({ predicate: predicate }, {
-      predicate: {
-        is: ["function"],
-        msg: "predicate must be a function."
-      }
-    });
-    internal(this).predicate = options.predicate;
-  },
-
-  isCurrent: function isCurrent(state) {
-    return internal(this).predicate(state);
-  },
-
-  serialize: function() {
-    return {
-      id: internal(this).id,
-      type: "PredicateContext",
-      args: []
-    }
-  }
-});
-exports.PredicateContext = PredicateContext;
-
-function removeItemFromArray(array, item) {
-  return array.filter(i => i !== item);
-}
-
-// Converts anything that isn't false, null or undefined into a string
-function stringOrNull(val) {
-  return val ? String(val) : val;
-}
-
-// Shared option validation rules for Item, Menu, and Separator
-var baseItemRules = {
-  parentMenu: {
-    is: ["object", "undefined"],
-    ok: function (v) {
-      if (!v)
-        return true;
-      return (v instanceof ItemContainer) || (v instanceof Menu);
-    },
-    msg: "parentMenu must be a Menu or not specified."
-  },
-  context: {
-    is: ["undefined", "object", "array"],
-    ok: function (v) {
-      if (!v)
-        return true;
-      let arr = Array.isArray(v) ? v : [v];
-      return arr.every(o => o instanceof Context);
-    },
-    msg: "The 'context' option must be a Context object or an array of " +
-         "Context objects."
-  },
-  onMessage: {
-    is: ["function", "undefined"]
-  },
-  contentScript: loaderContract.rules.contentScript,
-  contentScriptFile: loaderContract.rules.contentScriptFile
-};
-
-var labelledItemRules =  mix(baseItemRules, {
-  label: {
-    map: stringOrNull,
-    is: ["string"],
-    ok: v => !!v,
-    msg: "The item must have a non-empty string label."
-  },
-  accesskey: {
-    map: stringOrNull,
-    is: ["string", "undefined", "null"],
-    ok: (v) => {
-      if (!v) {
-        return true;
-      }
-      return typeof v == "string" && v.length === 1;
-    },
-    msg: "The item must have a single character accesskey, or no accesskey."
-  },
-  image: {
-    map: stringOrNull,
-    is: ["string", "undefined", "null"],
-    ok: function (url) {
-      if (!url)
-        return true;
-      return isValidURI(url);
-    },
-    msg: "Image URL validation failed"
-  }
-});
-
-// Additional validation rules for Item
-var itemRules = mix(labelledItemRules, {
-  data: {
-    map: stringOrNull,
-    is: ["string", "undefined", "null"]
-  }
-});
-
-// Additional validation rules for Menu
-var menuRules = mix(labelledItemRules, {
-  items: {
-    is: ["array", "undefined"],
-    ok: function (v) {
-      if (!v)
-        return true;
-      return v.every(function (item) {
-        return item instanceof BaseItem;
-      });
-    },
-    msg: "items must be an array, and each element in the array must be an " +
-         "Item, Menu, or Separator."
-  }
-});
-
-// Returns true if any contexts match. If there are no contexts then a
-// PageContext is tested instead
-function hasMatchingContext(contexts, addonInfo) {
-  for (let context of contexts) {
-    if (!(internal(context).id in addonInfo.contextStates)) {
-      console.error("Missing state for context " + internal(context).id + " this is an error in the SDK modules.");
-      return false;
-    }
-    if (!context.isCurrent(addonInfo.contextStates[internal(context).id]))
-      return false;
-  }
-
-  return true;
-}
-
-// Tests whether an item should be visible or not based on its contexts and
-// content scripts
-function isItemVisible(item, addonInfo, usePageWorker) {
-  if (!item.context.length) {
-    if (!addonInfo.hasWorker)
-      return usePageWorker ? addonInfo.pageContext : true;
-  }
-
-  if (!hasMatchingContext(item.context, addonInfo))
-    return false;
-
-  let context = addonInfo.workerContext;
-  if (typeof(context) === "string" && context != "")
-    item.label = context;
-
-  return !!context;
-}
-
-// Called when an item is clicked to send out click events to the content
-// scripts
-function itemActivated(item, clickedNode) {
-  let items = [internal(item).id];
-  let data = item.data;
-
-  while (item.parentMenu) {
-    item = item.parentMenu;
-    items.push(internal(item).id);
-  }
-
-  let process = processes.getById(lastContextProcessId);
-  if (process)
-    process.port.emit('sdk/contextmenu/activateitems', items, data);
-}
-
-function serializeItem(item) {
-  return {
-    id: internal(item).id,
-    contexts: item.context.map(c => c.serialize()),
-    contentScript: item.contentScript,
-    contentScriptFile: item.contentScriptFile,
-  };
-}
-
-// All things that appear in the context menu extend this
-var BaseItem = Class({
-  initialize: function initialize() {
-    internal(this).id = uuid();
-
-    internal(this).contexts = [];
-    if ("context" in internal(this).options && internal(this).options.context) {
-      let contexts = internal(this).options.context;
-      if (Array.isArray(contexts)) {
-        for (let context of contexts)
-          internal(this).contexts.push(context);
-      }
-      else {
-        internal(this).contexts.push(contexts);
-      }
-    }
-
-    let parentMenu = internal(this).options.parentMenu;
-    if (!parentMenu)
-      parentMenu = contentContextMenu;
-
-    parentMenu.addItem(this);
-
-    Object.defineProperty(this, "contentScript", {
-      enumerable: true,
-      value: internal(this).options.contentScript
-    });
-
-    // Resolve URIs here as tests may have overriden self
-    let files = internal(this).options.contentScriptFile;
-    if (files) {
-      if (!Array.isArray(files))
-        files = [files];
-      files = files.map(self.data.url);
-    }
-    internal(this).options.contentScriptFile = files;
-    Object.defineProperty(this, "contentScriptFile", {
-      enumerable: true,
-      value: internal(this).options.contentScriptFile
-    });
-
-    // Notify all frames of this new item
-    sendItems([serializeItem(this)]);
-  },
-
-  destroy: function destroy() {
-    if (internal(this).destroyed)
-      return;
-
-    // Tell all existing frames that this item has been destroyed
-    processes.port.emit("sdk/contextmenu/destroyitems", [internal(this).id]);
-
-    if (this.parentMenu)
-      this.parentMenu.removeItem(this);
-
-    internal(this).destroyed = true;
-  },
-
-  get context() {
-    let contexts = internal(this).contexts.slice(0);
-    contexts.add = (context) => {
-      internal(this).contexts.push(context);
-      // Notify all frames that this item has changed
-      sendItems([serializeItem(this)]);
-    };
-    contexts.remove = (context) => {
-      internal(this).contexts = internal(this).contexts.filter(c => {
-        return c != context;
-      });
-      // Notify all frames that this item has changed
-      sendItems([serializeItem(this)]);
-    };
-    return contexts;
-  },
-
-  set context(val) {
-    internal(this).contexts = val.slice(0);
-    // Notify all frames that this item has changed
-    sendItems([serializeItem(this)]);
-  },
-
-  get parentMenu() {
-    return internal(this).parentMenu;
-  },
-});
-
-function workerMessageReceived(process, id, args) {
-  if (internal(this).id != id)
-    return;
-
-  emit(this, ...JSON.parse(args));
-}
-
-// All things that have a label on the context menu extend this
-var LabelledItem = Class({
-  extends: BaseItem,
-  implements: [ EventTarget ],
-
-  initialize: function initialize(options) {
-    BaseItem.prototype.initialize.call(this);
-    EventTarget.prototype.initialize.call(this, options);
-
-    internal(this).messageListener = workerMessageReceived.bind(this);
-    processes.port.on('sdk/worker/event', internal(this).messageListener);
-  },
-
-  destroy: function destroy() {
-    if (internal(this).destroyed)
-      return;
-
-    processes.port.off('sdk/worker/event', internal(this).messageListener);
-
-    BaseItem.prototype.destroy.call(this);
-  },
-
-  get label() {
-    return internal(this).options.label;
-  },
-
-  set label(val) {
-    internal(this).options.label = val;
-
-    MenuManager.updateItem(this);
-  },
-
-  get accesskey() {
-    return internal(this).options.accesskey;
-  },
-
-  set accesskey(val) {
-    internal(this).options.accesskey = val;
-
-    MenuManager.updateItem(this);
-  },
-
-  get image() {
-    return internal(this).options.image;
-  },
-
-  set image(val) {
-    internal(this).options.image = val;
-
-    MenuManager.updateItem(this);
-  },
-
-  get data() {
-    return internal(this).options.data;
-  },
-
-  set data(val) {
-    internal(this).options.data = val;
-  }
-});
-
-var Item = Class({
-  extends: LabelledItem,
-
-  initialize: function initialize(options) {
-    internal(this).options = validateOptions(options, itemRules);
-
-    LabelledItem.prototype.initialize.call(this, options);
-  },
-
-  toString: function toString() {
-    return "[object Item \"" + this.label + "\"]";
-  },
-
-  get data() {
-    return internal(this).options.data;
-  },
-
-  set data(val) {
-    internal(this).options.data = val;
-
-    MenuManager.updateItem(this);
-  },
-});
-exports.Item = Item;
-
-var ItemContainer = Class({
-  initialize: function initialize() {
-    internal(this).children = [];
-  },
-
-  destroy: function destroy() {
-    // Destroys the entire hierarchy
-    for (let item of internal(this).children)
-      item.destroy();
-  },
-
-  addItem: function addItem(item) {
-    let oldParent = item.parentMenu;
-
-    // Don't just call removeItem here as that would remove the corresponding
-    // UI element which is more costly than just moving it to the right place
-    if (oldParent)
-      internal(oldParent).children = removeItemFromArray(internal(oldParent).children, item);
-
-    let after = null;
-    let children = internal(this).children;
-    if (children.length > 0)
-      after = children[children.length - 1];
-
-    children.push(item);
-    internal(item).parentMenu = this;
-
-    // If there was an old parent then we just have to move the item, otherwise
-    // it needs to be created
-    if (oldParent)
-      MenuManager.moveItem(item, after);
-    else
-      MenuManager.createItem(item, after);
-  },
-
-  removeItem: function removeItem(item) {
-    // If the item isn't a child of this menu then ignore this call
-    if (item.parentMenu !== this)
-      return;
-
-    MenuManager.removeItem(item);
-
-    internal(this).children = removeItemFromArray(internal(this).children, item);
-    internal(item).parentMenu = null;
-  },
-
-  get items() {
-    return internal(this).children.slice(0);
-  },
-
-  set items(val) {
-    // Validate the arguments before making any changes
-    if (!Array.isArray(val))
-      throw new Error(menuOptionRules.items.msg);
-
-    for (let item of val) {
-      if (!(item instanceof BaseItem))
-        throw new Error(menuOptionRules.items.msg);
-    }
-
-    // Remove the old items and add the new ones
-    for (let item of internal(this).children)
-      this.removeItem(item);
-
-    for (let item of val)
-      this.addItem(item);
-  },
-});
-
-var Menu = Class({
-  extends: LabelledItem,
-  implements: [ItemContainer],
-
-  initialize: function initialize(options) {
-    internal(this).options = validateOptions(options, menuRules);
-
-    LabelledItem.prototype.initialize.call(this, options);
-    ItemContainer.prototype.initialize.call(this);
-
-    if (internal(this).options.items) {
-      for (let item of internal(this).options.items)
-        this.addItem(item);
-    }
-  },
-
-  destroy: function destroy() {
-    ItemContainer.prototype.destroy.call(this);
-    LabelledItem.prototype.destroy.call(this);
-  },
-
-  toString: function toString() {
-    return "[object Menu \"" + this.label + "\"]";
-  },
-});
-exports.Menu = Menu;
-
-var Separator = Class({
-  extends: BaseItem,
-
-  initialize: function initialize(options) {
-    internal(this).options = validateOptions(options, baseItemRules);
-
-    BaseItem.prototype.initialize.call(this);
-  },
-
-  toString: function toString() {
-    return "[object Separator]";
-  }
-});
-exports.Separator = Separator;
-
-// Holds items for the content area context menu
-var contentContextMenu = ItemContainer();
-exports.contentContextMenu = contentContextMenu;
-
-function getContainerItems(container) {
-  let items = [];
-  for (let item of internal(container).children) {
-    items.push(serializeItem(item));
-    if (item instanceof Menu)
-      items = items.concat(getContainerItems(item));
-  }
-  return items;
-}
-
-// Notify all frames of these new or changed items
-function sendItems(items) {
-  processes.port.emit("sdk/contextmenu/createitems", items);
-}
-
-// Called when a new process is created and needs to get the current list of items
-function remoteItemRequest(process) {
-  let items = getContainerItems(contentContextMenu);
-  if (items.length == 0)
-    return;
-
-  process.port.emit("sdk/contextmenu/createitems", items);
-}
-processes.forEvery(remoteItemRequest);
-
-when(function() {
-  contentContextMenu.destroy();
-});
-
-// App specific UI code lives here, it should handle populating the context
-// menu and passing clicks etc. through to the items.
-
-function countVisibleItems(nodes) {
-  return Array.reduce(nodes, function(sum, node) {
-    return node.hidden ? sum : sum + 1;
-  }, 0);
-}
-
-var MenuWrapper = Class({
-  initialize: function initialize(winWrapper, items, contextMenu) {
-    this.winWrapper = winWrapper;
-    this.window = winWrapper.window;
-    this.items = items;
-    this.contextMenu = contextMenu;
-    this.populated = false;
-    this.menuMap = new Map();
-
-    // updateItemVisibilities will run first, updateOverflowState will run after
-    // all other instances of this module have run updateItemVisibilities
-    this._updateItemVisibilities = this.updateItemVisibilities.bind(this);
-    this.contextMenu.addEventListener("popupshowing", this._updateItemVisibilities, true);
-    this._updateOverflowState = this.updateOverflowState.bind(this);
-    this.contextMenu.addEventListener("popupshowing", this._updateOverflowState);
-  },
-
-  destroy: function destroy() {
-    this.contextMenu.removeEventListener("popupshowing", this._updateOverflowState);
-    this.contextMenu.removeEventListener("popupshowing", this._updateItemVisibilities, true);
-
-    if (!this.populated)
-      return;
-
-    // If we're getting unloaded at runtime then we must remove all the
-    // generated XUL nodes
-    let oldParent = null;
-    for (let item of internal(this.items).children) {
-      let xulNode = this.getXULNodeForItem(item);
-      oldParent = xulNode.parentNode;
-      oldParent.removeChild(xulNode);
-    }
-
-    if (oldParent)
-      this.onXULRemoved(oldParent);
-  },
-
-  get separator() {
-    return this.contextMenu.querySelector("." + SEPARATOR_CLASS);
-  },
-
-  get overflowMenu() {
-    return this.contextMenu.querySelector("." + OVERFLOW_MENU_CLASS);
-  },
-
-  get overflowPopup() {
-    return this.contextMenu.querySelector("." + OVERFLOW_POPUP_CLASS);
-  },
-
-  get topLevelItems() {
-    return this.contextMenu.querySelectorAll("." + TOPLEVEL_ITEM_CLASS);
-  },
-
-  get overflowItems() {
-    return this.contextMenu.querySelectorAll("." + OVERFLOW_ITEM_CLASS);
-  },
-
-  getXULNodeForItem: function getXULNodeForItem(item) {
-    return this.menuMap.get(item);
-  },
-
-  // Recurses through the item hierarchy creating XUL nodes for everything
-  populate: function populate(menu) {
-    for (let i = 0; i < internal(menu).children.length; i++) {
-      let item = internal(menu).children[i];
-      let after = i === 0 ? null : internal(menu).children[i - 1];
-      this.createItem(item, after);
-
-      if (item instanceof Menu)
-        this.populate(item);
-    }
-  },
-
-  // Recurses through the menu setting the visibility of items. Returns true
-  // if any of the items in this menu were visible
-  setVisibility: function setVisibility(menu, addonInfo, usePageWorker) {
-    let anyVisible = false;
-
-    for (let item of internal(menu).children) {
-      let visible = isItemVisible(item, addonInfo[internal(item).id], usePageWorker);
-
-      // Recurse through Menus, if none of the sub-items were visible then the
-      // menu is hidden too.
-      if (visible && (item instanceof Menu))
-        visible = this.setVisibility(item, addonInfo, false);
-
-      let xulNode = this.getXULNodeForItem(item);
-      xulNode.hidden = !visible;
-
-      anyVisible = anyVisible || visible;
-    }
-
-    return anyVisible;
-  },
-
-  // Works out where to insert a XUL node for an item in a browser window
-  insertIntoXUL: function insertIntoXUL(item, node, after) {
-    let menupopup = null;
-    let before = null;
-
-    let menu = item.parentMenu;
-    if (menu === this.items) {
-      // Insert into the overflow popup if it exists, otherwise the normal
-      // context menu
-      menupopup = this.overflowPopup;
-      if (!menupopup)
-        menupopup = this.contextMenu;
-    }
-    else {
-      let xulNode = this.getXULNodeForItem(menu);
-      menupopup = xulNode.firstChild;
-    }
-
-    if (after) {
-      let afterNode = this.getXULNodeForItem(after);
-      before = afterNode.nextSibling;
-    }
-    else if (menupopup === this.contextMenu) {
-      let topLevel = this.topLevelItems;
-      if (topLevel.length > 0)
-        before = topLevel[topLevel.length - 1].nextSibling;
-      else
-        before = this.separator.nextSibling;
-    }
-
-    menupopup.insertBefore(node, before);
-  },
-
-  // Sets the right class for XUL nodes
-  updateXULClass: function updateXULClass(xulNode) {
-    if (xulNode.parentNode == this.contextMenu)
-      xulNode.classList.add(TOPLEVEL_ITEM_CLASS);
-    else
-      xulNode.classList.remove(TOPLEVEL_ITEM_CLASS);
-
-    if (xulNode.parentNode == this.overflowPopup)
-      xulNode.classList.add(OVERFLOW_ITEM_CLASS);
-    else
-      xulNode.classList.remove(OVERFLOW_ITEM_CLASS);
-  },
-
-  // Creates a XUL node for an item
-  createItem: function createItem(item, after) {
-    if (!this.populated)
-      return;
-
-    // Create the separator if it doesn't already exist
-    if (!this.separator) {
-      let separator = this.window.document.createElement("menuseparator");
-      separator.setAttribute("class", SEPARATOR_CLASS);
-
-      // Insert before the separator created by the old context-menu if it
-      // exists to avoid bug 832401
-      let oldSeparator = this.window.document.getElementById("jetpack-context-menu-separator");
-      if (oldSeparator && oldSeparator.parentNode != this.contextMenu)
-        oldSeparator = null;
-      this.contextMenu.insertBefore(separator, oldSeparator);
-    }
-
-    let type = "menuitem";
-    if (item instanceof Menu)
-      type = "menu";
-    else if (item instanceof Separator)
-      type = "menuseparator";
-
-    let xulNode = this.window.document.createElement(type);
-    xulNode.setAttribute("class", ITEM_CLASS);
-    if (item instanceof LabelledItem) {
-      xulNode.setAttribute("label", item.label);
-      if (item.accesskey)
-        xulNode.setAttribute("accesskey", item.accesskey);
-      if (item.image) {
-        xulNode.setAttribute("image", item.image);
-        if (item instanceof Menu)
-          xulNode.classList.add("menu-iconic");
-        else
-          xulNode.classList.add("menuitem-iconic");
-      }
-      if (item.data)
-        xulNode.setAttribute("value", item.data);
-
-      let self = this;
-      xulNode.addEventListener("command", function(event) {
-        // Only care about clicks directly on this item
-        if (event.target !== xulNode)
-          return;
-
-        itemActivated(item, xulNode);
-      });
-    }
-
-    this.insertIntoXUL(item, xulNode, after);
-    this.updateXULClass(xulNode);
-    xulNode.data = item.data;
-
-    if (item instanceof Menu) {
-      let menupopup = this.window.document.createElement("menupopup");
-      xulNode.appendChild(menupopup);
-    }
-
-    this.menuMap.set(item, xulNode);
-  },
-
-  // Updates the XUL node for an item in this window
-  updateItem: function updateItem(item) {
-    if (!this.populated)
-      return;
-
-    let xulNode = this.getXULNodeForItem(item);
-
-    // TODO figure out why this requires setAttribute
-    xulNode.setAttribute("label", item.label);
-    xulNode.setAttribute("accesskey", item.accesskey || "");
-
-    if (item.image) {
-      xulNode.setAttribute("image", item.image);
-      if (item instanceof Menu)
-        xulNode.classList.add("menu-iconic");
-      else
-        xulNode.classList.add("menuitem-iconic");
-    }
-    else {
-      xulNode.removeAttribute("image");
-      xulNode.classList.remove("menu-iconic");
-      xulNode.classList.remove("menuitem-iconic");
-    }
-
-    if (item.data)
-      xulNode.setAttribute("value", item.data);
-    else
-      xulNode.removeAttribute("value");
-  },
-
-  // Moves the XUL node for an item in this window to its new place in the
-  // hierarchy
-  moveItem: function moveItem(item, after) {
-    if (!this.populated)
-      return;
-
-    let xulNode = this.getXULNodeForItem(item);
-    let oldParent = xulNode.parentNode;
-
-    this.insertIntoXUL(item, xulNode, after);
-    this.updateXULClass(xulNode);
-    this.onXULRemoved(oldParent);
-  },
-
-  // Removes the XUL nodes for an item in every window we've ever populated.
-  removeItem: function removeItem(item) {
-    if (!this.populated)
-      return;
-
-    let xulItem = this.getXULNodeForItem(item);
-
-    let oldParent = xulItem.parentNode;
-
-    oldParent.removeChild(xulItem);
-    this.menuMap.delete(item);
-
-    this.onXULRemoved(oldParent);
-  },
-
-  // Called when any XUL nodes have been removed from a menupopup. This handles
-  // making sure the separator and overflow are correct
-  onXULRemoved: function onXULRemoved(parent) {
-    if (parent == this.contextMenu) {
-      let toplevel = this.topLevelItems;
-
-      // If there are no more items then remove the separator
-      if (toplevel.length == 0) {
-        let separator = this.separator;
-        if (separator)
-          separator.remove();
-      }
-    }
-    else if (parent == this.overflowPopup) {
-      // If there are no more items then remove the overflow menu and separator
-      if (parent.childNodes.length == 0) {
-        let separator = this.separator;
-        separator.remove();
-        this.contextMenu.removeChild(parent.parentNode);
-      }
-    }
-  },
-
-  // Recurses through all the items owned by this module and sets their hidden
-  // state
-  updateItemVisibilities: function updateItemVisibilities(event) {
-    try {
-      if (event.type != "popupshowing")
-        return;
-      if (event.target != this.contextMenu)
-        return;
-
-      if (internal(this.items).children.length == 0)
-        return;
-
-      if (!this.populated) {
-        this.populated = true;
-        this.populate(this.items);
-      }
-
-      let mainWindow = event.target.ownerGlobal;
-      this.contextMenuContentData = mainWindow.gContextMenuContentData
-      if (!(self.id in this.contextMenuContentData.addonInfo)) {
-        console.warn("No context menu state data was provided.");
-        return;
-      }
-      let addonInfo = this.contextMenuContentData.addonInfo[self.id];
-      lastContextProcessId = addonInfo.processID;
-      this.setVisibility(this.items, addonInfo.items, true);
-    }
-    catch (e) {
-      console.exception(e);
-    }
-  },
-
-  // Counts the number of visible items across all modules and makes sure they
-  // are in the right place between the top level context menu and the overflow
-  // menu
-  updateOverflowState: function updateOverflowState(event) {
-    try {
-      if (event.type != "popupshowing")
-        return;
-      if (event.target != this.contextMenu)
-        return;
-
-      // The main items will be in either the top level context menu or the
-      // overflow menu at this point. Count the visible ones and if they are in
-      // the wrong place move them
-      let toplevel = this.topLevelItems;
-      let overflow = this.overflowItems;
-      let visibleCount = countVisibleItems(toplevel) +
-                         countVisibleItems(overflow);
-
-      if (visibleCount == 0) {
-        let separator = this.separator;
-        if (separator)
-          separator.hidden = true;
-        let overflowMenu = this.overflowMenu;
-        if (overflowMenu)
-          overflowMenu.hidden = true;
-      }
-      else if (visibleCount > MenuManager.overflowThreshold) {
-        this.separator.hidden = false;
-        let overflowPopup = this.overflowPopup;
-        if (overflowPopup)
-          overflowPopup.parentNode.hidden = false;
-
-        if (toplevel.length > 0) {
-          // The overflow menu shouldn't exist here but let's play it safe
-          if (!overflowPopup) {
-            let overflowMenu = this.window.document.createElement("menu");
-            overflowMenu.setAttribute("class", OVERFLOW_MENU_CLASS);
-            overflowMenu.setAttribute("label", OVERFLOW_MENU_LABEL);
-            overflowMenu.setAttribute("accesskey", OVERFLOW_MENU_ACCESSKEY);
-            this.contextMenu.insertBefore(overflowMenu, this.separator.nextSibling);
-
-            overflowPopup = this.window.document.createElement("menupopup");
-            overflowPopup.setAttribute("class", OVERFLOW_POPUP_CLASS);
-            overflowMenu.appendChild(overflowPopup);
-          }
-
-          for (let xulNode of toplevel) {
-            overflowPopup.appendChild(xulNode);
-            this.updateXULClass(xulNode);
-          }
-        }
-      }
-      else {
-        this.separator.hidden = false;
-
-        if (overflow.length > 0) {
-          // Move all the overflow nodes out of the overflow menu and position
-          // them immediately before it
-          for (let xulNode of overflow) {
-            this.contextMenu.insertBefore(xulNode, xulNode.parentNode.parentNode);
-            this.updateXULClass(xulNode);
-          }
-          this.contextMenu.removeChild(this.overflowMenu);
-        }
-      }
-    }
-    catch (e) {
-      console.exception(e);
-    }
-  }
-});
-
-// This wraps every window that we've seen
-var WindowWrapper = Class({
-  initialize: function initialize(window) {
-    this.window = window;
-    this.menus = [
-      new MenuWrapper(this, contentContextMenu, window.document.getElementById("contentAreaContextMenu")),
-    ];
-  },
-
-  destroy: function destroy() {
-    for (let menuWrapper of this.menus)
-      menuWrapper.destroy();
-  },
-
-  getMenuWrapperForItem: function getMenuWrapperForItem(item) {
-    let root = item.parentMenu;
-    while (root.parentMenu)
-      root = root.parentMenu;
-
-    for (let wrapper of this.menus) {
-      if (wrapper.items === root)
-        return wrapper;
-    }
-
-    return null;
-  }
-});
-
-var MenuManager = {
-  windowMap: new Map(),
-
-  get overflowThreshold() {
-    let prefs = require("./preferences/service");
-    return prefs.get(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
-  },
-
-  // When a new window is added start watching it for context menu shows
-  onTrack: function onTrack(window) {
-    if (!isBrowser(window))
-      return;
-
-    // Generally shouldn't happen, but just in case
-    if (this.windowMap.has(window)) {
-      console.warn("Already seen this window");
-      return;
-    }
-
-    let winWrapper = WindowWrapper(window);
-    this.windowMap.set(window, winWrapper);
-  },
-
-  onUntrack: function onUntrack(window) {
-    if (!isBrowser(window))
-      return;
-
-    let winWrapper = this.windowMap.get(window);
-    // This shouldn't happen but protect against it anyway
-    if (!winWrapper)
-      return;
-    winWrapper.destroy();
-
-    this.windowMap.delete(window);
-  },
-
-  // Creates a XUL node for an item in every window we've already populated
-  createItem: function createItem(item, after) {
-    for (let [window, winWrapper] of this.windowMap) {
-      let menuWrapper = winWrapper.getMenuWrapperForItem(item);
-      if (menuWrapper)
-        menuWrapper.createItem(item, after);
-    }
-  },
-
-  // Updates the XUL node for an item in every window we've already populated
-  updateItem: function updateItem(item) {
-    for (let [window, winWrapper] of this.windowMap) {
-      let menuWrapper = winWrapper.getMenuWrapperForItem(item);
-      if (menuWrapper)
-        menuWrapper.updateItem(item);
-    }
-  },
-
-  // Moves the XUL node for an item in every window we've ever populated to its
-  // new place in the hierarchy
-  moveItem: function moveItem(item, after) {
-    for (let [window, winWrapper] of this.windowMap) {
-      let menuWrapper = winWrapper.getMenuWrapperForItem(item);
-      if (menuWrapper)
-        menuWrapper.moveItem(item, after);
-    }
-  },
-
-  // Removes the XUL nodes for an item in every window we've ever populated.
-  removeItem: function removeItem(item) {
-    for (let [window, winWrapper] of this.windowMap) {
-      let menuWrapper = winWrapper.getMenuWrapperForItem(item);
-      if (menuWrapper)
-        menuWrapper.removeItem(item);
-    }
-  }
-};
-
-WindowTracker(MenuManager);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/context-menu/context.js
+++ /dev/null
@@ -1,146 +0,0 @@
-/* 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/. */
-
-const { Class } = require("../core/heritage");
-lazyRequire(this, "../util/match-pattern", "MatchPattern");
-const readers = require("./readers");
-
-// Context class is required to implement a single `isCurrent(target)` method
-// that must return boolean value indicating weather given target matches a
-// context or not. Most context implementations below will have an associated
-// reader that way context implementation can setup a reader to extract necessary
-// information to make decision if target is matching a context.
-const Context = Class({
-  isRequired: false,
-  isCurrent(target) {
-    throw Error("Context class must implement isCurrent(target) method");
-  },
-  get required() {
-    Object.defineProperty(this, "required", {
-      value: Object.assign(Object.create(Object.getPrototypeOf(this)),
-                           this,
-                           {isRequired: true})
-    });
-    return this.required;
-  }
-});
-Context.required = function(...params) {
-  return Object.assign(new this(...params), {isRequired: true});
-};
-exports.Context = Context;
-
-
-// Next few context implementations use an associated reader to extract info
-// from the context target and story it to a private symbol associtaed with
-// a context implementation. That way name collisions are avoided while required
-// information is still carried along.
-const isPage = Symbol("context/page?")
-const PageContext = Class({
-  extends: Context,
-  read: {[isPage]: new readers.isPage()},
-  isCurrent: target => target[isPage]
-});
-exports.Page = PageContext;
-
-const isFrame = Symbol("context/frame?");
-const FrameContext = Class({
-  extends: Context,
-  read: {[isFrame]: new readers.isFrame()},
-  isCurrent: target => target[isFrame]
-});
-exports.Frame = FrameContext;
-
-const selection = Symbol("context/selection")
-const SelectionContext = Class({
-  read: {[selection]: new readers.Selection()},
-  isCurrent: target => !!target[selection]
-});
-exports.Selection = SelectionContext;
-
-const link = Symbol("context/link");
-const LinkContext = Class({
-  extends: Context,
-  read: {[link]: new readers.LinkURL()},
-  isCurrent: target => !!target[link]
-});
-exports.Link = LinkContext;
-
-const isEditable = Symbol("context/editable?")
-const EditableContext = Class({
-  extends: Context,
-  read: {[isEditable]: new readers.isEditable()},
-  isCurrent: target => target[isEditable]
-});
-exports.Editable = EditableContext;
-
-
-const mediaType = Symbol("context/mediaType")
-
-const ImageContext = Class({
-  extends: Context,
-  read: {[mediaType]: new readers.MediaType()},
-  isCurrent: target => target[mediaType] === "image"
-});
-exports.Image = ImageContext;
-
-
-const VideoContext = Class({
-  extends: Context,
-  read: {[mediaType]: new readers.MediaType()},
-  isCurrent: target => target[mediaType] === "video"
-});
-exports.Video = VideoContext;
-
-
-const AudioContext = Class({
-  extends: Context,
-  read: {[mediaType]: new readers.MediaType()},
-  isCurrent: target => target[mediaType] === "audio"
-});
-exports.Audio = AudioContext;
-
-const isSelectorMatch = Symbol("context/selector/mathches?")
-const SelectorContext = Class({
-  extends: Context,
-  initialize(selector) {
-    this.selector = selector;
-    // Each instance of selector context will need to store read
-    // data into different field, so that case with multilpe selector
-    // contexts won't cause a conflicts.
-    this[isSelectorMatch] = Symbol(selector);
-    this.read = {[this[isSelectorMatch]]: new readers.SelectorMatch(selector)};
-  },
-  isCurrent(target) {
-    return target[this[isSelectorMatch]];
-  }
-});
-exports.Selector = SelectorContext;
-
-const url = Symbol("context/url");
-const URLContext = Class({
-  extends: Context,
-  initialize(pattern) {
-    this.pattern = new MatchPattern(pattern);
-  },
-  read: {[url]: new readers.PageURL()},
-  isCurrent(target) {
-    return this.pattern.test(target[url]);
-  }
-});
-exports.URL = URLContext;
-
-var PredicateContext = Class({
-  extends: Context,
-  initialize(isMatch) {
-    if (typeof(isMatch) !== "function") {
-      throw TypeError("Predicate context mus be passed a function");
-    }
-
-    this.isMatch = isMatch
-  },
-  isCurrent(target) {
-    return this.isMatch(target);
-  }
-});
-exports.Predicate = PredicateContext;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/context-menu/core.js
+++ /dev/null
@@ -1,384 +0,0 @@
-/* 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 Contexts = require("./context");
-const Readers = require("./readers");
-const Component = require("../ui/component");
-const { Class } = require("../core/heritage");
-const { map, filter, object, reduce, keys, symbols,
-        pairs, values, each, some, isEvery, count } = require("../util/sequence");
-const { loadModule } = require("framescript/manager");
-const { Cu, Cc, Ci } = require("chrome");
-const prefs = require("sdk/preferences/service");
-
-const globalMessageManager = Cc["@mozilla.org/globalmessagemanager;1"]
-                              .getService(Ci.nsIMessageListenerManager);
-const preferencesService = Cc["@mozilla.org/preferences-service;1"].
-                            getService(Ci.nsIPrefService).
-                            getBranch(null);
-
-
-const readTable = Symbol("context-menu/read-table");
-const nameTable = Symbol("context-menu/name-table");
-const onContext = Symbol("context-menu/on-context");
-const isMatching = Symbol("context-menu/matching-handler?");
-
-exports.onContext = onContext;
-exports.readTable = readTable;
-exports.nameTable = nameTable;
-
-
-const propagateOnContext = (item, data) =>
-  each(child => child[onContext](data), item.state.children);
-
-const isContextMatch = item => !item[isMatching] || item[isMatching]();
-
-// For whatever reason addWeakMessageListener does not seems to work as our
-// instance seems to dropped even though it's alive. This is simple workaround
-// to avoid dead object excetptions.
-const WeakMessageListener = function(receiver, handler="receiveMessage") {
-  this.receiver = receiver
-  this.handler = handler
-};
-WeakMessageListener.prototype = {
-  constructor: WeakMessageListener,
-  receiveMessage(message) {
-    if (Cu.isDeadWrapper(this.receiver)) {
-      message.target.messageManager.removeMessageListener(message.name, this);
-    }
-    else {
-      this.receiver[this.handler](message);
-    }
-  }
-};
-
-const OVERFLOW_THRESH = "extensions.addon-sdk.context-menu.overflowThreshold";
-const onMessage = Symbol("context-menu/message-listener");
-const onPreferceChange = Symbol("context-menu/preference-change");
-const ContextMenuExtension = Class({
-  extends: Component,
-  initialize: Component,
-  setup() {
-    const messageListener = new WeakMessageListener(this, onMessage);
-    loadModule(globalMessageManager, "framescript/context-menu", true, "onContentFrame");
-    globalMessageManager.addMessageListener("sdk/context-menu/read", messageListener);
-    globalMessageManager.addMessageListener("sdk/context-menu/readers?", messageListener);
-
-    preferencesService.addObserver(OVERFLOW_THRESH, this);
-  },
-  observe(_, __, name) {
-    if (name === OVERFLOW_THRESH) {
-      const overflowThreshold = prefs.get(OVERFLOW_THRESH, 10);
-      this[Component.patch]({overflowThreshold});
-    }
-  },
-  [onMessage]({name, data, target}) {
-    if (name === "sdk/context-menu/read")
-      this[onContext]({target, data});
-    if (name === "sdk/context-menu/readers?")
-      target.messageManager.sendAsyncMessage("sdk/context-menu/readers",
-                                             JSON.parse(JSON.stringify(this.state.readers)));
-  },
-  [Component.initial](options={}, children) {
-    const element = options.element || null;
-    const target = options.target || null;
-    const readers = Object.create(null);
-    const users = Object.create(null);
-    const registry = new WeakSet();
-    const overflowThreshold = prefs.get(OVERFLOW_THRESH, 10);
-
-    return { target, children: [], readers, users, element,
-             registry, overflowThreshold };
-  },
-  [Component.isUpdated](before, after) {
-    // Update only if target changed, since there is no point in re-rendering
-    // when children are. Also new items added won't be in sync with a latest
-    // context target so we should really just render before drawing context
-    // menu.
-    return before.target !== after.target;
-  },
-  [Component.render]({element, children, overflowThreshold}) {
-    if (!element) return null;
-
-    const items = children.filter(isContextMatch);
-    const body = items.length === 0 ? items :
-                 items.length < overflowThreshold ? [new Separator(),
-                                                     ...items] :
-                 [{tagName: "menu",
-                   className: "sdk-context-menu-overflow-menu",
-                   label: "Add-ons",
-                   accesskey: "A",
-                   children: [{tagName: "menupopup",
-                               children: items}]}];
-    return {
-      element: element,
-      tagName: "menugroup",
-      style: "-moz-box-orient: vertical;",
-      className: "sdk-context-menu-extension",
-      children: body
-    }
-  },
-  // Adds / remove child to it's own list.
-  add(item) {
-    this[Component.patch]({children: this.state.children.concat(item)});
-  },
-  remove(item) {
-    this[Component.patch]({
-      children: this.state.children.filter(x => x !== item)
-    });
-  },
-  register(item) {
-    const { users, registry } = this.state;
-    if (registry.has(item)) return;
-    registry.add(item);
-
-    // Each (ContextHandler) item has a readTable that is a
-    // map of keys to readers extracting them from the content.
-    // During the registraction we update intrnal record of unique
-    // readers and users per reader. Most context will have a reader
-    // shared across all instances there for map of users per reader
-    // is stored separately from the reader so that removing reader
-    // will occur only when no users remain.
-    const table = item[readTable];
-    // Context readers store data in private symbols so we need to
-    // collect both table keys and private symbols.
-    const names = [...keys(table), ...symbols(table)];
-    const readers = map(name => table[name], names);
-    // Create delta for registered readers that will be merged into
-    // internal readers table.
-    const added = filter(x => !users[x.id], readers);
-    const delta = object(...map(x => [x.id, x], added));
-
-    const update = reduce((update, reader) => {
-      const n = update[reader.id] || 0;
-      update[reader.id] = n + 1;
-      return update;
-    }, Object.assign({}, users), readers);
-
-    // Patch current state with a changes that registered item caused.
-    this[Component.patch]({users: update,
-                           readers: Object.assign(this.state.readers, delta)});
-
-    if (count(added)) {
-      globalMessageManager.broadcastAsyncMessage("sdk/context-menu/readers",
-                                                 JSON.parse(JSON.stringify(delta)));
-    }
-  },
-  unregister(item) {
-    const { users, registry } = this.state;
-    if (!registry.has(item)) return;
-    registry.delete(item);
-
-    const table = item[readTable];
-    const names = [...keys(table), ...symbols(table)];
-    const readers = map(name => table[name], names);
-    const update = reduce((update, reader) => {
-      update[reader.id] = update[reader.id] - 1;
-      return update;
-    }, Object.assign({}, users), readers);
-    const removed = filter(id => !update[id], keys(update));
-    const delta = object(...map(x => [x, null], removed));
-
-    this[Component.patch]({users: update,
-                           readers: Object.assign(this.state.readers, delta)});
-
-    if (count(removed)) {
-      globalMessageManager.broadcastAsyncMessage("sdk/context-menu/readers",
-                                                 JSON.parse(JSON.stringify(delta)));
-    }
-  },
-
-  [onContext]({data, target}) {
-    propagateOnContext(this, data);
-    const document = target.ownerDocument;
-    const element = document.getElementById("contentAreaContextMenu");
-
-    this[Component.patch]({target: data, element: element});
-  }
-});this,
-exports.ContextMenuExtension = ContextMenuExtension;
-
-// Takes an item options and
-const makeReadTable = ({context, read}) => {
-  // Result of this function is a tuple of all readers &
-  // name, reader id pairs.
-
-  // Filter down to contexts that have a reader associated.
-  const contexts = filter(context => context.read, context);
-  // Merge all contexts read maps to a single hash, note that there should be
-  // no name collisions as context implementations expect to use private
-  // symbols for storing it's read data.
-  return Object.assign({}, ...map(({read}) => read, contexts), read);
-}
-
-const readTarget = (nameTable, data) =>
-  object(...map(([name, id]) => [name, data[id]], nameTable))
-
-const ContextHandler = Class({
-  extends: Component,
-  initialize: Component,
-  get context() {
-    return this.state.options.context;
-  },
-  get read() {
-    return this.state.options.read;
-  },
-  [Component.initial](options) {
-    return {
-      table: makeReadTable(options),
-      requiredContext: filter(context => context.isRequired, options.context),
-      optionalContext: filter(context => !context.isRequired, options.context)
-    }
-  },
-  [isMatching]() {
-    const {target, requiredContext, optionalContext} = this.state;
-    return isEvery(context => context.isCurrent(target), requiredContext) &&
-            (count(optionalContext) === 0 ||
-             some(context => context.isCurrent(target), optionalContext));
-  },
-  setup() {
-    const table = makeReadTable(this.state.options);
-    this[readTable] = table;
-    this[nameTable] = [...map(symbol => [symbol, table[symbol].id], symbols(table)),
-                       ...map(name => [name, table[name].id], keys(table))];
-
-
-    contextMenu.register(this);
-
-    each(child => contextMenu.remove(child), this.state.children);
-    contextMenu.add(this);
-  },
-  dispose() {
-    contextMenu.remove(this);
-
-    each(child => contextMenu.unregister(child), this.state.children);
-    contextMenu.unregister(this);
-  },
-  // Internal `Symbol("onContext")` method is invoked when "contextmenu" event
-  // occurs in content process. Context handles with children delegate to each
-  // child and patch it's internal state to reflect new contextmenu target.
-  [onContext](data) {
-    propagateOnContext(this, data);
-    this[Component.patch]({target: readTarget(this[nameTable], data)});
-  }
-});
-const isContextHandler = item => item instanceof ContextHandler;
-
-exports.ContextHandler = ContextHandler;
-
-const Menu = Class({
-  extends: ContextHandler,
-  [isMatching]() {
-    return ContextHandler.prototype[isMatching].call(this) &&
-           this.state.children.filter(isContextHandler)
-                              .some(isContextMatch);
-  },
-  [Component.render]({children, options}) {
-    const items = children.filter(isContextMatch);
-    return {tagName: "menu",
-            className: "sdk-context-menu menu-iconic",
-            label: options.label,
-            accesskey: options.accesskey,
-            image: options.icon,
-            children: [{tagName: "menupopup",
-                        children: items}]};
-  }
-});
-exports.Menu = Menu;
-
-const onCommand = Symbol("context-menu/item/onCommand");
-const Item = Class({
-  extends: ContextHandler,
-  get onClick() {
-    return this.state.options.onClick;
-  },
-  [Component.render]({options}) {
-    const {label, icon, accesskey} = options;
-    return {tagName: "menuitem",
-            className: "sdk-context-menu-item menuitem-iconic",
-            label,
-            accesskey,
-            image: icon,
-            oncommand: this};
-  },
-  handleEvent(event) {
-    if (this.onClick)
-      this.onClick(this.state.target);
-  }
-});
-exports.Item = Item;
-
-var Separator = Class({
-  extends: Component,
-  initialize: Component,
-  [Component.render]() {
-    return {tagName: "menuseparator",
-            className: "sdk-context-menu-separator"}
-  },
-  [onContext]() {
-
-  }
-});
-exports.Separator = Separator;
-
-exports.Contexts = Contexts;
-exports.Readers = Readers;
-
-const createElement = (vnode, {document}) => {
-   const node = vnode.namespace ?
-              document.createElementNS(vnode.namespace, vnode.tagName) :
-              document.createElement(vnode.tagName);
-
-   node.setAttribute("data-component-path", vnode[Component.path]);
-
-   each(([key, value]) => {
-     if (key === "tagName") {
-       return;
-     }
-     if (key === "children") {
-       return;
-     }
-
-     if (key.startsWith("on")) {
-       node.addEventListener(key.substr(2), value)
-       return;
-     }
-
-     if (typeof(value) !== "object" &&
-         typeof(value) !== "function" &&
-         value !== void(0) &&
-         value !== null)
-    {
-       if (key === "className") {
-         node[key] = value;
-       }
-       else {
-         node.setAttribute(key, value);
-       }
-       return;
-     }
-   }, pairs(vnode));
-
-  each(child => node.appendChild(createElement(child, {document})), vnode.children);
-  return node;
-};
-
-const htmlWriter = tree => {
-  if (tree !== null) {
-    const root = tree.element;
-    const node = createElement(tree, {document: root.ownerDocument});
-    const before = root.querySelector("[data-component-path='/']");
-    if (before) {
-      root.replaceChild(node, before);
-    } else {
-      root.appendChild(node);
-    }
-  }
-};
-
-
-const contextMenu = ContextMenuExtension();
-exports.contextMenu = contextMenu;
-Component.mount(contextMenu, htmlWriter);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/context-menu/readers.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/* 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/. */
-const { Class } = require("../core/heritage");
-const { extend } = require("../util/object");
-const { memoize, method, identity } = require("../lang/functional");
-
-const serializeCategory = ({type}) => ({ category: `reader/${type}()` });
-
-const Reader = Class({
-  initialize() {
-    this.id = `reader/${this.type}()`
-  },
-  toJSON() {
-    return serializeCategory(this);
-  }
-});
-
-
-const MediaTypeReader = Class({ extends: Reader, type: "MediaType" });
-exports.MediaType = MediaTypeReader;
-
-const LinkURLReader = Class({ extends: Reader, type: "LinkURL" });
-exports.LinkURL = LinkURLReader;
-
-const SelectionReader = Class({ extends: Reader, type: "Selection" });
-exports.Selection = SelectionReader;
-
-const isPageReader = Class({ extends: Reader, type: "isPage" });
-exports.isPage = isPageReader;
-
-const isFrameReader = Class({ extends: Reader, type: "isFrame" });
-exports.isFrame = isFrameReader;
-
-const isEditable = Class({ extends: Reader, type: "isEditable"});
-exports.isEditable = isEditable;
-
-
-
-const ParameterizedReader = Class({
-  extends: Reader,
-  readParameter: function(value) {
-    return value;
-  },
-  toJSON: function() {
-    var json = serializeCategory(this);
-    json[this.parameter] = this[this.parameter];
-    return json;
-  },
-  initialize(...params) {
-    if (params.length) {
-      this[this.parameter] = this.readParameter(...params);
-    }
-    this.id = `reader/${this.type}(${JSON.stringify(this[this.parameter])})`;
-  }
-});
-exports.ParameterizedReader = ParameterizedReader;
-
-
-const QueryReader = Class({
-  extends: ParameterizedReader,
-  type: "Query",
-  parameter: "path"
-});
-exports.Query = QueryReader;
-
-
-const AttributeReader = Class({
-  extends: ParameterizedReader,
-  type: "Attribute",
-  parameter: "name"
-});
-exports.Attribute = AttributeReader;
-
-const SrcURLReader = Class({
-  extends: AttributeReader,
-  name: "src",
-});
-exports.SrcURL = SrcURLReader;
-
-const PageURLReader = Class({
-  extends: QueryReader,
-  path: "ownerDocument.URL",
-});
-exports.PageURL = PageURLReader;
-
-const SelectorMatchReader = Class({
-  extends: ParameterizedReader,
-  type: "SelectorMatch",
-  parameter: "selector"
-});
-exports.SelectorMatch = SelectorMatchReader;
-
-const extractors = new WeakMap();
-extractors.id = 0;
-
-
-var Extractor = Class({
-  extends: ParameterizedReader,
-  type: "Extractor",
-  parameter: "source",
-  initialize: function(f) {
-    this[this.parameter] = String(f);
-    if (!extractors.has(f)) {
-      extractors.id = extractors.id + 1;
-      extractors.set(f, extractors.id);
-    }
-
-    this.id = `reader/${this.type}.for(${extractors.get(f)})`
-  }
-});
-exports.Extractor = Extractor;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/context-menu@2.js
+++ /dev/null
@@ -1,32 +0,0 @@
-/* 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 shared = require("toolkit/require");
-const { Item, Separator, Menu, Contexts, Readers } = shared.require("sdk/context-menu/core");
-const { setupDisposable, disposeDisposable, Disposable } = require("sdk/core/disposable")
-const { Class } = require("sdk/core/heritage")
-
-const makeDisposable = Type => Class({
-  extends: Type,
-  implements: [Disposable],
-  initialize: Type.prototype.initialize,
-  setup(...params) {
-    Type.prototype.setup.call(this, ...params);
-    setupDisposable(this);
-  },
-  dispose(...params) {
-    disposeDisposable(this);
-    Type.prototype.dispose.call(this, ...params);
-  }
-});
-
-exports.Separator = Separator;
-exports.Contexts = Contexts;
-exports.Readers = Readers;
-
-// Subclass Item & Menu shared classes so their items
-// will be unloaded when add-on is unloaded.
-exports.Item = makeDisposable(Item);
-exports.Menu = makeDisposable(Menu);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/input/browser.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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 { windows, isBrowser, isInteractive, isDocumentLoaded,
-        getOuterId } = require("../window/utils");
-const { InputPort } = require("./system");
-const { lift, merges, foldp, keepIf, start, Input } = require("../event/utils");
-const { patch } = require("diffpatcher/index");
-const { Sequence, seq, filter, object, pairs } = require("../util/sequence");
-
-
-// Create lazy iterators from the regular arrays, although
-// once https://github.com/mozilla/addon-sdk/pull/1314 lands
-// `windows` will be transforme to lazy iterators.
-// When iterated over belowe sequences items will represent
-// state of windows at the time of iteration.
-const opened = seq(function*() {
-  const items = windows("navigator:browser", {includePrivate: true});
-  for (let item of items) {
-      yield [getOuterId(item), item];
-  }
-});
-const interactive = filter(([_, window]) => isInteractive(window), opened);
-const loaded = filter(([_, window]) => isDocumentLoaded(window), opened);
-
-// Helper function that converts given argument to a delta.
-const Update = window => window && object([getOuterId(window), window]);
-const Delete = window => window && object([getOuterId(window), null]);
-
-
-// Signal represents delta for last top level window close.
-const LastClosed = lift(Delete,
-                        keepIf(isBrowser, null,
-                               new InputPort({topic: "domwindowclosed"})));
-exports.LastClosed = LastClosed;
-
-const windowFor = document => document && document.defaultView;
-
-// Signal represent delta for last top level window document becoming interactive.
-const InteractiveDoc = new InputPort({topic: "chrome-document-interactive"});
-const InteractiveWin = lift(windowFor, InteractiveDoc);
-const LastInteractive = lift(Update, keepIf(isBrowser, null, InteractiveWin));
-exports.LastInteractive = LastInteractive;
-
-// Signal represent delta for last top level window loaded.
-const LoadedDoc = new InputPort({topic: "chrome-document-loaded"});
-const LoadedWin = lift(windowFor, LoadedDoc);
-const LastLoaded = lift(Update, keepIf(isBrowser, null, LoadedWin));
-exports.LastLoaded = LastLoaded;
-
-
-const initialize = input => {
-  if (!input.initialized) {
-    input.value = object(...input.value);
-    Input.start(input);
-    input.initialized = true;
-  }
-};
-
-// Signal represents set of top level interactive windows, updated any
-// time new window becomes interactive or one get's closed.
-const Interactive = foldp(patch, interactive, merges([LastInteractive,
-                                                      LastClosed]));
-Interactive[start] = initialize;
-exports.Interactive = Interactive;
-
-// Signal represents set of top level loaded window, updated any time
-// new window becomes interactive or one get's closed.
-const Loaded = foldp(patch, loaded, merges([LastLoaded, LastClosed]));
-Loaded[start] = initialize;
-exports.Loaded = Loaded;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/input/customizable-ui.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 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 { Cu } = require("chrome");
-const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
-const { receive } = require("../event/utils");
-const { InputPort } = require("./system");
-const { object} = require("../util/sequence");
-const { getOuterId } = require("../window/utils");
-
-const Input = function() {};
-Input.prototype = Object.create(InputPort.prototype);
-
-Input.prototype.onCustomizeStart = function (window) {
-  receive(this, object([getOuterId(window), true]));
-}
-
-Input.prototype.onCustomizeEnd = function (window) {
-  receive(this, object([getOuterId(window), null]));
-}
-
-Input.prototype.addListener = input => CustomizableUI.addListener(input);
-
-Input.prototype.removeListener = input => CustomizableUI.removeListener(input);
-
-exports.CustomizationInput = Input;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/input/frame.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* 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 { Ci } = require("chrome");
-const { InputPort } = require("./system");
-const { getFrameElement, getOuterId,
-        getOwnerBrowserWindow } = require("../window/utils");
-const { isnt } = require("../lang/functional");
-const { foldp, lift, merges, keepIf } = require("../event/utils");
-const { object } = require("../util/sequence");
-const { compose } = require("../lang/functional");
-const { LastClosed } = require("./browser");
-const { patch } = require("diffpatcher/index");
-
-const Document = Ci.nsIDOMDocument;
-
-const isntNull = isnt(null);
-
-const frameID = frame => frame.id;
-const browserID = compose(getOuterId, getOwnerBrowserWindow);
-
-const isInnerFrame = frame =>
-  frame && frame.hasAttribute("data-is-sdk-inner-frame");
-
-// Utility function that given content window loaded in our frame views returns
-// an actual frame. This basically takes care of fact that actual frame document
-// is loaded in the nested iframe. If content window is not loaded in the nested
-// frame of the frame view it returs null.
-const getFrame = document =>
-  document && document.defaultView && getFrameElement(document.defaultView);
-
-const FrameInput = function(options) {
-  const input = keepIf(isInnerFrame, null,
-                       lift(getFrame, new InputPort(options)));
-  return lift(frame => {
-    if (!frame) return frame;
-    const [id, owner] = [frameID(frame), browserID(frame)];
-    return object([id, {owners: object([owner, options.update])}]);
-  }, input);
-};
-
-const LastLoading = new FrameInput({topic: "document-element-inserted",
-                                    update: {readyState: "loading"}});
-exports.LastLoading = LastLoading;
-
-const LastInteractive = new FrameInput({topic: "content-document-interactive",
-                                        update: {readyState: "interactive"}});
-exports.LastInteractive = LastInteractive;
-
-const LastLoaded = new FrameInput({topic: "content-document-loaded",
-                                   update: {readyState: "complete"}});
-exports.LastLoaded = LastLoaded;
-
-const LastUnloaded = new FrameInput({topic: "content-page-hidden",
-                                    update: null});
-exports.LastUnloaded = LastUnloaded;
-
-// Represents state of SDK frames in form of data structure:
-// {"frame#1": {"id": "frame#1",
-//              "inbox": {"data": "ping",
-//                        "target": {"id": "frame#1", "owner": "outerWindowID#2"},
-//                        "source": {"id": "frame#1"}}
-//              "url": "resource://addon-1/data/index.html",
-//              "owners": {"outerWindowID#1": {"readyState": "loading"},
-//                         "outerWindowID#2": {"readyState": "complete"}}
-//
-//
-//  frame#2: {"id": "frame#2",
-//            "url": "resource://addon-1/data/main.html",
-//            "outbox": {"data": "pong",
-//                       "source": {"id": "frame#2", "owner": "outerWindowID#1"}
-//                       "target": {"id": "frame#2"}}
-//            "owners": {outerWindowID#1: {readyState: "interacitve"}}}}
-const Frames = foldp(patch, {}, merges([
-  LastLoading,
-  LastInteractive,
-  LastLoaded,
-  LastUnloaded,
-  new InputPort({ id: "frame-mailbox" }),
-  new InputPort({ id: "frame-change" }),
-  new InputPort({ id: "frame-changed" })
-]));
-exports.Frames = Frames;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/input/system.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/* 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 { Cc, Ci, Cr, Cu } = require("chrome");
-const { Input, start, stop, end, receive, outputs } = require("../event/utils");
-const { once, off } = require("../event/core");
-const { id: addonID } = require("../self");
-
-const unloadMessage = require("@loader/unload");
-const observerService = Cc['@mozilla.org/observer-service;1'].
-                          getService(Ci.nsIObserverService);
-const { ShimWaiver } = Cu.import("resource://gre/modules/ShimWaiver.jsm");
-const addObserver = ShimWaiver.getProperty(observerService, "addObserver");
-const removeObserver = ShimWaiver.getProperty(observerService, "removeObserver");
-
-
-const addonUnloadTopic = "sdk:loader:destroy";
-
-const isXrayWrapper = Cu.isXrayWrapper;
-// In the past SDK used to double-wrap notifications dispatched, which
-// made them awkward to use outside of SDK. At present they no longer
-// do that, although we still supported for legacy reasons.
-const isLegacyWrapper = x =>
-    x && x.wrappedJSObject &&
-    "observersModuleSubjectWrapper" in x.wrappedJSObject;
-
-const unwrapLegacy = x => x.wrappedJSObject.object;
-
-// `InputPort` provides a way to create a signal out of the observer
-// notification subject's for the given `topic`. If `options.initial`
-// is provided it is used as initial value otherwise `null` is used.
-// Constructor can be given `options.id` that will be used to create
-// a `topic` which is namespaced to an add-on (this avoids conflicts
-// when multiple add-on are used, although in a future host probably
-// should just be shared across add-ons). It is also possible to
-// specify a specific `topic` via `options.topic` which is used as
-// without namespacing. Created signal ends whenever add-on is
-// unloaded.
-const InputPort = function InputPort({id, topic, initial}) {
-  this.id = id || topic;
-  this.topic = topic || "sdk:" + addonID + ":" + id;
-  this.value = initial === void(0) ? null : initial;
-  this.observing = false;
-  this[outputs] = [];
-};
-
-// InputPort type implements `Input` signal interface.
-InputPort.prototype = new Input();
-InputPort.prototype.constructor = InputPort;
-
-// When port is started (which is when it's subgraph get's
-// first subscriber) actual observer is registered.
-InputPort.start = input => {
-  input.addListener(input);
-  // Also register add-on unload observer to end this signal
-  // when that happens.
-  addObserver(input, addonUnloadTopic, false);
-};
-InputPort.prototype[start] = InputPort.start;
-
-InputPort.addListener = input => addObserver(input, input.topic, false);
-InputPort.prototype.addListener = InputPort.addListener;
-
-// When port is stopped (which is when it's subgraph has no
-// no subcribers left) an actual observer unregistered.
-// Note that port stopped once it ends as well (which is when
-// add-on is unloaded).
-InputPort.stop = input => {
-  input.removeListener(input);
-  removeObserver(input, addonUnloadTopic);
-};
-InputPort.prototype[stop] = InputPort.stop;
-
-InputPort.removeListener = input => removeObserver(input, input.topic);
-InputPort.prototype.removeListener = InputPort.removeListener;
-
-// `InputPort` also implements `nsIObserver` interface and
-// `nsISupportsWeakReference` interfaces as it's going to be used as such.
-InputPort.prototype.QueryInterface = function(iid) {
-  if (!iid.equals(Ci.nsIObserver) && !iid.equals(Ci.nsISupportsWeakReference))
-    throw Cr.NS_ERROR_NO_INTERFACE;
-
-  return this;
-};
-
-// `InputPort` instances implement `observe` method, which is invoked when
-// observer notifications are dispatched. The `subject` of that notification
-// are received on this signal.
-InputPort.prototype.observe = function(subject, topic, data) {
-  // Unwrap message from the subject. SDK used to have it's own version of
-  // wrappedJSObjects which take precedence, if subject has `wrappedJSObject`
-  // and it's not an XrayWrapper use it as message. Otherwise use subject as
-  // is.
-  const message = subject === null ? null :
-        isLegacyWrapper(subject) ? unwrapLegacy(subject) :
-        isXrayWrapper(subject) ? subject :
-        subject.wrappedJSObject ? subject.wrappedJSObject :
-        subject;
-
-  // If observer topic matches topic of the input port receive a message.
-  if (topic === this.topic) {
-    receive(this, message);
-  }
-
-  // If observe topic is add-on unload topic we create an end message.
-  if (topic === addonUnloadTopic && message === unloadMessage) {
-    end(this);
-  }
-};
-
-exports.InputPort = InputPort;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/panel.js
+++ /dev/null
@@ -1,436 +0,0 @@
-/* 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";
-
-// The panel module currently supports only Firefox and SeaMonkey.
-// See: https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps
-module.metadata = {
-  "stability": "stable",
-  "engines": {
-    "Firefox": "*",
-    "SeaMonkey": "*"
-  }
-};
-
-const { Cu, Ci } = require("chrome");
-lazyRequire(this, './timers', "setTimeout");
-const { Class } = require("./core/heritage");
-const { DefaultWeakMap, merge } = require("./util/object");
-const { WorkerHost } = require("./content/utils");
-lazyRequire(this, "./deprecated/sync-worker", "Worker");
-const { Disposable } = require("./core/disposable");
-const { WeakReference } = require('./core/reference');
-const { contract: loaderContract } = require("./content/loader");
-const { contract } = require("./util/contract");
-lazyRequire(this, "./event/core", "on", "off", "emit", "setListeners");
-const { EventTarget } = require("./event/target");
-lazyRequireModule(this, "./panel/utils", "domPanel");
-lazyRequire(this, './frame/utils', "getDocShell");
-const { events } = require("./panel/events");
-const { filter, pipe, stripListeners } = require("./event/utils");
-lazyRequire(this, "./view/core", "getNodeView", "getActiveView");
-lazyRequire(this, "./lang/type", "isNil", "isObject", "isNumber");
-lazyRequire(this, "./content/utils", "getAttachEventType");
-const { number, boolean, object } = require('./deprecated/api-utils');
-lazyRequire(this, "./stylesheet/style", "Style");
-lazyRequire(this, "./content/mod", "attach", "detach");
-
-var isRect = ({top, right, bottom, left}) => [top, right, bottom, left].
-  some(value => isNumber(value) && !isNaN(value));
-
-var isSDKObj = obj => obj instanceof Class;
-
-var rectContract = contract({
-  top: number,
-  right: number,
-  bottom: number,
-  left: number
-});
-
-var position = {
-  is: object,
-  map: v => (isNil(v) || isSDKObj(v) || !isObject(v)) ? v : rectContract(v),
-  ok: v => isNil(v) || isSDKObj(v) || (isObject(v) && isRect(v)),
-  msg: 'The option "position" must be a SDK object registered as anchor; ' +
-        'or an object with one or more of the following keys set to numeric ' +
-        'values: top, right, bottom, left.'
-}
-
-var displayContract = contract({
-  width: number,
-  height: number,
-  focus: boolean,
-  position: position
-});
-
-var panelContract = contract(merge({
-  // contentStyle* / contentScript* are sharing the same validation constraints,
-  // so they can be mostly reused, except for the messages.
-  contentStyle: merge(Object.create(loaderContract.rules.contentScript), {
-    msg: 'The `contentStyle` option must be a string or an array of strings.'
-  }),
-  contentStyleFile: merge(Object.create(loaderContract.rules.contentScriptFile), {
-    msg: 'The `contentStyleFile` option must be a local URL or an array of URLs'
-  }),
-  contextMenu: boolean,
-  allow: {
-    is: ['object', 'undefined', 'null'],
-    map: function (allow) { return { script: !allow || allow.script !== false }}
-  },
-}, displayContract.rules, loaderContract.rules));
-
-function Allow(panel) {
-  return {
-    get script() { return getDocShell(viewFor(panel).backgroundFrame).allowJavascript; },
-    set script(value) { return setScriptState(panel, value); },
-  };
-}
-
-function setScriptState(panel, value) {
-  let view = viewFor(panel);
-  getDocShell(view.backgroundFrame).allowJavascript = value;
-  getDocShell(view.viewFrame).allowJavascript = value;
-  view.setAttribute("sdkscriptenabled", "" + value);
-}
-
-function isDisposed(panel) {
-  return !views.has(panel);
-}
-
-var optionsMap = new WeakMap();
-var panels = new WeakMap();
-var models = new WeakMap();
-var views = new DefaultWeakMap(panel => {
-  let model = models.get(panel);
-
-  // Setup view
-  let viewOptions = {allowJavascript: !model.allow || (model.allow.script !== false)};
-  let view = domPanel.make(null, viewOptions);
-  panels.set(view, panel);
-
-  // Load panel content.
-  domPanel.setURL(view, model.contentURL);
-
-  // Allow context menu
-  domPanel.allowContextMenu(view, model.contextMenu);
-
-  return view;
-});
-var workers = new DefaultWeakMap(panel => {
-  let options = optionsMap.get(panel);
-
-  let worker = new Worker(stripListeners(options));
-  workers.set(panel, worker);
-
-  // pipe events from worker to a panel.
-  pipe(worker, panel);
-
-  return worker;
-});
-var styles = new WeakMap();
-
-const viewFor = (panel) => views.get(panel);
-const modelFor = (panel) => models.get(panel);
-const panelFor = (view) => panels.get(view);
-const workerFor = (panel) => workers.get(panel);
-const styleFor = (panel) => styles.get(panel);
-
-function getPanelFromWeakRef(weakRef) {
-  if (!weakRef) {
-    return null;
-  }
-  let panel = weakRef.get();
-  if (!panel) {
-    return null;
-  }
-  if (isDisposed(panel)) {
-    return null;
-  }
-  return panel;
-}
-
-var SinglePanelManager = {
-  visiblePanel: null,
-  enqueuedPanel: null,
-  enqueuedPanelCallback: null,
-  // Calls |callback| with no arguments when the panel may be shown.
-  requestOpen: function(panelToOpen, callback) {
-    let currentPanel = getPanelFromWeakRef(SinglePanelManager.visiblePanel);
-    if (currentPanel || SinglePanelManager.enqueuedPanel) {
-      SinglePanelManager.enqueuedPanel = Cu.getWeakReference(panelToOpen);
-      SinglePanelManager.enqueuedPanelCallback = callback;
-      if (currentPanel && currentPanel.isShowing) {
-        currentPanel.hide();
-      }
-    } else {
-      SinglePanelManager.notifyPanelCanOpen(panelToOpen, callback);
-    }
-  },
-  notifyPanelCanOpen: function(panel, callback) {
-    let view = viewFor(panel);
-    // Can't pass an arrow function as the event handler because we need to be
-    // able to call |removeEventListener| later.
-    view.addEventListener("popuphidden", SinglePanelManager.onVisiblePanelHidden, true);
-    view.addEventListener("popupshown", SinglePanelManager.onVisiblePanelShown);
-    SinglePanelManager.enqueuedPanel = null;
-    SinglePanelManager.enqueuedPanelCallback = null;
-    SinglePanelManager.visiblePanel = Cu.getWeakReference(panel);
-    callback();
-  },
-  onVisiblePanelShown: function(event) {
-    let panel = panelFor(event.target);
-    if (SinglePanelManager.enqueuedPanel) {
-      // Another panel started waiting for |panel| to close before |panel| was
-      // even done opening.
-      panel.hide();
-    }
-  },
-  onVisiblePanelHidden: function(event) {
-    let view = event.target;
-    let panel = panelFor(view);
-    let currentPanel = getPanelFromWeakRef(SinglePanelManager.visiblePanel);
-    if (currentPanel && currentPanel != panel) {
-      return;
-    }
-    SinglePanelManager.visiblePanel = null;
-    view.removeEventListener("popuphidden", SinglePanelManager.onVisiblePanelHidden, true);
-    view.removeEventListener("popupshown", SinglePanelManager.onVisiblePanelShown);
-    let nextPanel = getPanelFromWeakRef(SinglePanelManager.enqueuedPanel);
-    let nextPanelCallback = SinglePanelManager.enqueuedPanelCallback;
-    if (nextPanel) {
-      SinglePanelManager.notifyPanelCanOpen(nextPanel, nextPanelCallback);
-    }
-  }
-};
-
-const Panel = Class({
-  implements: [
-    // Generate accessors for the validated properties that update model on
-    // set and return values from model on get.
-    panelContract.properties(modelFor),
-    EventTarget,
-    Disposable,
-    WeakReference
-  ],
-  extends: WorkerHost(workerFor),
-  setup: function setup(options) {
-    let model = merge({
-      defaultWidth: 320,
-      defaultHeight: 240,
-      focus: true,
-      position: Object.freeze({}),
-      contextMenu: false
-    }, panelContract(options));
-    model.ready = false;
-    models.set(this, model);
-
-    if (model.contentStyle || model.contentStyleFile) {
-      styles.set(this, Style({
-        uri: model.contentStyleFile,
-        source: model.contentStyle
-      }));
-    }
-
-    optionsMap.set(this, options);
-
-    // Setup listeners.
-    setListeners(this, options);
-  },
-  dispose: function dispose() {
-    if (views.has(this))
-      this.hide();
-    off(this);
-
-    workerFor(this).destroy();
-    detach(styleFor(this));
-
-    if (views.has(this))
-      domPanel.dispose(viewFor(this));
-
-    views.delete(this);
-  },
-  /* Public API: Panel.width */
-  get width() {
-    return modelFor(this).width;
-  },
-  set width(value) {
-    this.resize(value, this.height);
-  },
-  /* Public API: Panel.height */
-  get height() {
-    return modelFor(this).height;
-  },
-  set height(value) {
-    this.resize(this.width, value);
-  },
-
-  /* Public API: Panel.focus */
-  get focus() {
-    return modelFor(this).focus;
-  },
-
-  /* Public API: Panel.position */
-  get position() {
-    return modelFor(this).position;
-  },
-
-  /* Public API: Panel.contextMenu */
-  get contextMenu() {
-    return modelFor(this).contextMenu;
-  },
-  set contextMenu(allow) {
-    let model = modelFor(this);
-    model.contextMenu = panelContract({ contextMenu: allow }).contextMenu;
-    domPanel.allowContextMenu(viewFor(this), model.contextMenu);
-  },
-
-  get contentURL() {
-    return modelFor(this).contentURL;
-  },
-  set contentURL(value) {
-    let model = modelFor(this);
-    model.contentURL = panelContract({ contentURL: value }).contentURL;
-    domPanel.setURL(viewFor(this), model.contentURL);
-    // Detach worker so that messages send will be queued until it's
-    // reatached once panel content is ready.
-    workerFor(this).detach();
-  },
-
-  get allow() { return Allow(this); },
-  set allow(value) {
-    let allowJavascript = panelContract({ allow: value }).allow.script;
-    return setScriptState(this, value);
-  },
-
-  /* Public API: Panel.isShowing */
-  get isShowing() {
-    return !isDisposed(this) && domPanel.isOpen(viewFor(this));
-  },
-
-  /* Public API: Panel.show */
-  show: function show(options={}, anchor) {
-    let view = viewFor(this);
-    SinglePanelManager.requestOpen(this, () => {
-      if (options instanceof Ci.nsIDOMElement) {
-        [anchor, options] = [options, null];
-      }
-
-      if (anchor instanceof Ci.nsIDOMElement) {
-        console.warn(
-          "Passing a DOM node to Panel.show() method is an unsupported " +
-          "feature that will be soon replaced. " +
-          "See: https://bugzilla.mozilla.org/show_bug.cgi?id=878877"
-        );
-      }
-
-      let model = modelFor(this);
-      let anchorView = getNodeView(anchor || options.position || model.position);
-
-      options = merge({
-        position: model.position,
-        width: model.width,
-        height: model.height,
-        defaultWidth: model.defaultWidth,
-        defaultHeight: model.defaultHeight,
-        focus: model.focus,
-        contextMenu: model.contextMenu
-      }, displayContract(options));
-
-      if (!isDisposed(this)) {
-        domPanel.show(view, options, anchorView);
-      }
-    });
-    return this;
-  },
-
-  /* Public API: Panel.hide */
-  hide: function hide() {
-    // Quit immediately if panel is disposed or there is no state change.
-    domPanel.close(viewFor(this));
-
-    return this;
-  },
-
-  /* Public API: Panel.resize */
-  resize: function resize(width, height) {
-    let model = modelFor(this);
-    let view = viewFor(this);
-    let change = panelContract({
-      width: width || model.width || model.defaultWidth,
-      height: height || model.height || model.defaultHeight
-    });
-
-    model.width = change.width
-    model.height = change.height
-
-    domPanel.resize(view, model.width, model.height);
-
-    return this;
-  }
-});
-exports.Panel = Panel;
-
-// Note must be defined only after value to `Panel` is assigned.
-getActiveView.define(Panel, viewFor);
-
-// Filter panel events to only panels that are create by this module.
-var panelEvents = filter(events, ({target}) => panelFor(target));
-
-// Panel events emitted after panel has being shown.
-var shows = filter(panelEvents, ({type}) => type === "popupshown");
-
-// Panel events emitted after panel became hidden.
-var hides = filter(panelEvents, ({type}) => type === "popuphidden");
-
-// Panel events emitted after content inside panel is ready. For different
-// panels ready may mean different state based on `contentScriptWhen` attribute.
-// Weather given event represents readyness is detected by `getAttachEventType`
-// helper function.
-var ready = filter(panelEvents, ({type, target}) =>
-  getAttachEventType(modelFor(panelFor(target))) === type);
-
-// Panel event emitted when the contents of the panel has been loaded.
-var readyToShow = filter(panelEvents, ({type}) => type === "DOMContentLoaded");
-
-// Styles should be always added as soon as possible, and doesn't makes them
-// depends on `contentScriptWhen`
-var start = filter(panelEvents, ({type}) => type === "document-element-inserted");
-
-// Forward panel show / hide events to panel's own event listeners.
-on(shows, "data", ({target}) => {
-  let panel = panelFor(target);
-  if (modelFor(panel).ready)
-    emit(panel, "show");
-});
-
-on(hides, "data", ({target}) => {
-  let panel = panelFor(target);
-  if (modelFor(panel).ready)
-    emit(panel, "hide");
-});
-
-on(ready, "data", ({target}) => {
-  let panel = panelFor(target);
-  let window = domPanel.getContentDocument(target).defaultView;
-
-  workerFor(panel).attach(window);
-});
-
-on(readyToShow, "data", ({target}) => {
-  let panel = panelFor(target);
-
-  if (!modelFor(panel).ready) {
-    modelFor(panel).ready = true;
-
-    if (viewFor(panel).state == "open")
-      emit(panel, "show");
-  }
-});
-
-on(start, "data", ({target}) => {
-  let panel = panelFor(target);
-  let window = domPanel.getContentDocument(target).defaultView;
-
-  attach(styleFor(panel), window);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/panel/events.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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";
-
-// This module basically translates system/events to a SDK standard events
-// so that `map`, `filter` and other utilities could be used with them.
-
-module.metadata = {
-  "stability": "experimental"
-};
-
-const events = require("../system/events");
-lazyRequire(this, "../event/core", "emit");
-
-var channel = {};
-
-function forward({ subject, type, data }) {
-  return emit(channel, "data", { target: subject, type: type, data: data });
-}
-
-["popupshowing", "popuphiding", "popupshown", "popuphidden",
-"document-element-inserted", "DOMContentLoaded", "load"
-].forEach(type => events.on(type, forward));
-
-exports.events = channel;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/panel/utils.js
+++ /dev/null
@@ -1,451 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "unstable"
-};
-
-const { Cc, Ci } = require("chrome");
-const { Services } = require("resource://gre/modules/Services.jsm");
-lazyRequire(this, "../timers", "setTimeout");
-lazyRequire(this, "../system", "platform");
-lazyRequire(this, "../window/utils", "getMostRecentBrowserWindow", "getOwnerBrowserWindow",
-            "getScreenPixelsPerCSSPixel");
-
-lazyRequire(this, "../frame/utils", { "create": "createFrame" }, "swapFrameLoaders", "getDocShell");
-lazyRequire(this, "../addon/window", { "window": "addonWindow" });
-lazyRequire(this, "../lang/type", "isNil");
-lazyRequire(this, '../self', "data");
-
-lazyRequireModule(this, "../system/events", "events");
-
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-
-function calculateRegion({ position, width, height, defaultWidth, defaultHeight }, rect) {
-  position = position || {};
-
-  let x, y;
-
-  let hasTop = !isNil(position.top);
-  let hasRight = !isNil(position.right);
-  let hasBottom = !isNil(position.bottom);
-  let hasLeft = !isNil(position.left);
-  let hasWidth = !isNil(width);
-  let hasHeight = !isNil(height);
-
-  // if width is not specified by constructor or show's options, then get
-  // the default width
-  if (!hasWidth)
-    width = defaultWidth;
-
-  // if height is not specified by constructor or show's options, then get
-  // the default height
-  if (!hasHeight)
-    height = defaultHeight;
-
-  // default position is centered
-  x = (rect.right - width) / 2;
-  y = (rect.top + rect.bottom - height) / 2;
-
-  if (hasTop) {
-    y = rect.top + position.top;
-
-    if (hasBottom && !hasHeight)
-      height = rect.bottom - position.bottom - y;
-  }
-  else if (hasBottom) {
-    y = rect.bottom - position.bottom - height;
-  }
-
-  if (hasLeft) {
-    x = position.left;
-
-    if (hasRight && !hasWidth)
-      width = rect.right - position.right - x;
-  }
-  else if (hasRight) {
-    x = rect.right - width - position.right;
-  }
-
-  return {x: x, y: y, width: width, height: height};
-}
-
-function open(panel, options, anchor) {
-  // Wait for the XBL binding to be constructed
-  if (!panel.openPopup) setTimeout(open, 50, panel, options, anchor);
-  else display(panel, options, anchor);
-}
-exports.open = open;
-
-function isOpen(panel) {
-  return panel.state === "open"
-}
-exports.isOpen = isOpen;
-
-function isOpening(panel) {
-  return panel.state === "showing"
-}
-exports.isOpening = isOpening
-
-function close(panel) {
-  // Sometimes "TypeError: panel.hidePopup is not a function" is thrown
-  // when quitting the host application while a panel is visible.  To suppress
-  // these errors, check for "hidePopup" in panel before calling it.
-  // It's not clear if there's an issue or it's expected behavior.
-  // See Bug 1151796.
-
-  return panel.hidePopup && panel.hidePopup();
-}
-exports.close = close
-
-
-function resize(panel, width, height) {
-  // Resize the iframe instead of using panel.sizeTo
-  // because sizeTo doesn't work with arrow panels
-  if (panel.firstChild) {
-    panel.firstChild.style.width = width + "px";
-    panel.firstChild.style.height = height + "px";
-  }
-}
-exports.resize = resize
-
-function display(panel, options, anchor) {
-  let document = panel.ownerDocument;
-
-  let x, y;
-  let { width, height, defaultWidth, defaultHeight } = options;
-
-  let popupPosition = null;
-
-  // Panel XBL has some SDK incompatible styling decisions. We shim panel
-  // instances until proper fix for Bug 859504 is shipped.
-  shimDefaultStyle(panel);
-
-  if (!anchor) {
-    // The XUL Panel doesn't have an arrow, so the margin needs to be reset
-    // in order to, be positioned properly
-    panel.style.margin = "0";
-
-    let viewportRect = document.defaultView.gBrowser.getBoundingClientRect();
-
-    ({x, y, width, height} = calculateRegion(options, viewportRect));
-  }
-  else {
-    // The XUL Panel has an arrow, so the margin needs to be reset
-    // to the default value.
-    panel.style.margin = "";
-    let { CustomizableUI, window } = anchor.ownerGlobal;
-
-    // In Australis, widgets may be positioned in an overflow panel or the
-    // menu panel.
-    // In such cases clicking this widget will hide the overflow/menu panel,
-    // and the widget's panel will show instead.
-    // If `CustomizableUI` is not available, it means the anchor is not in a
-    // chrome browser window, and therefore there is no need for this check.
-    if (CustomizableUI) {
-      let node = anchor;
-      ({anchor} = CustomizableUI.getWidget(anchor.id).forWindow(window));
-
-      // if `node` is not the `anchor` itself, it means the widget is
-      // positioned in a panel, therefore we have to hide it before show
-      // the widget's panel in the same anchor
-      if (node !== anchor)
-        CustomizableUI.hidePanelForNode(anchor);
-    }
-
-    width = width || defaultWidth;
-    height = height || defaultHeight;
-
-    // Open the popup by the anchor.
-    let rect = anchor.getBoundingClientRect();
-
-    let zoom = getScreenPixelsPerCSSPixel(window);
-    let screenX = rect.left + window.mozInnerScreenX * zoom;
-    let screenY = rect.top + window.mozInnerScreenY * zoom;
-
-    // Set up the vertical position of the popup relative to the anchor
-    // (always display the arrow on anchor center)
-    let horizontal, vertical;
-    if (screenY > window.screen.availHeight / 2 + height)
-      vertical = "top";
-    else
-      vertical = "bottom";
-
-    if (screenY > window.screen.availWidth / 2 + width)
-      horizontal = "left";
-    else
-      horizontal = "right";
-
-    let verticalInverse = vertical == "top" ? "bottom" : "top";
-    popupPosition = vertical + "center " + verticalInverse + horizontal;
-
-    // Allow panel to flip itself if the panel can't be displayed at the
-    // specified position (useful if we compute a bad position or if the
-    // user moves the window and panel remains visible)
-    panel.setAttribute("flip", "both");
-  }
-
-  if (!panel.viewFrame) {
-    panel.viewFrame = document.importNode(panel.backgroundFrame, false);
-    panel.appendChild(panel.viewFrame);
-
-    let {privateBrowsingId} = getDocShell(panel.viewFrame).getOriginAttributes();
-    let principal = Services.scriptSecurityManager.createNullPrincipal({privateBrowsingId});
-    getDocShell(panel.viewFrame).createAboutBlankContentViewer(principal);
-  }
-
-  // Resize the iframe instead of using panel.sizeTo
-  // because sizeTo doesn't work with arrow panels
-  panel.firstChild.style.width = width + "px";
-  panel.firstChild.style.height = height + "px";
-
-  panel.openPopup(anchor, popupPosition, x, y);
-}
-exports.display = display;
-
-// This utility function is just a workaround until Bug 859504 has shipped.
-function shimDefaultStyle(panel) {
-  let document = panel.ownerDocument;
-  // Please note that `panel` needs to be part of document in order to reach
-  // it's anonymous nodes. One of the anonymous node has a big padding which
-  // doesn't work well since panel frame needs to fill all of the panel.
-  // XBL binding is a not the best option as it's applied asynchronously, and
-  // makes injected frames behave in strange way. Also this feels a lot
-  // cheaper to do.
-  ["panel-inner-arrowcontent", "panel-arrowcontent"].forEach(function(value) {
-    let node = document.getAnonymousElementByAttribute(panel, "class", value);
-      if (node) node.style.padding = 0;
-  });
-}
-
-function show(panel, options, anchor) {
-  // Prevent the panel from getting focus when showing up
-  // if focus is set to false
-  panel.setAttribute("noautofocus", !options.focus);
-
-  let window = anchor && getOwnerBrowserWindow(anchor);
-  let { document } = window ? window : getMostRecentBrowserWindow();
-  attach(panel, document);
-
-  open(panel, options, anchor);
-}
-exports.show = show
-
-function onPanelClick(event) {
-  let { target, metaKey, ctrlKey, shiftKey, button } = event;
-  let accel = platform === "darwin" ? metaKey : ctrlKey;
-  let isLeftClick = button === 0;
-  let isMiddleClick = button === 1;
-
-  if ((isLeftClick && (accel || shiftKey)) || isMiddleClick) {
-    let link = target.closest('a');
-
-    if (link && link.href)
-       getMostRecentBrowserWindow().openUILink(link.href, event)
-  }
-}
-
-function setupPanelFrame(frame) {
-  frame.setAttribute("flex", 1);
-  frame.setAttribute("transparent", "transparent");
-  frame.setAttribute("autocompleteenabled", true);
-  frame.setAttribute("tooltip", "aHTMLTooltip");
-  if (platform === "darwin") {
-    frame.style.borderRadius = "var(--arrowpanel-border-radius, 3.5px)";
-    frame.style.padding = "1px";
-  }
-}
-
-function make(document, options) {
-  document = document || getMostRecentBrowserWindow().document;
-  let panel = document.createElementNS(XUL_NS, "panel");
-  panel.setAttribute("type", "arrow");
-  panel.setAttribute("sdkscriptenabled", options.allowJavascript);
-
-  // The panel needs to be attached to a browser window in order for us
-  // to copy browser styles to the content document when it loads.
-  attach(panel, document);
-
-  let frameOptions =  {
-    allowJavascript: options.allowJavascript,
-    allowPlugins: true,
-    allowAuth: true,
-    allowWindowControl: false,
-    // Need to override `nodeName` to use `iframe` as `browsers` save session
-    // history and in consequence do not dispatch "inner-window-destroyed"
-    // notifications.
-    browser: false,
-  };
-
-  let backgroundFrame = createFrame(addonWindow, frameOptions);
-  setupPanelFrame(backgroundFrame);
-
-  getDocShell(backgroundFrame).inheritPrivateBrowsingId = false;
-
-  function onPopupShowing({type, target}) {
-    if (target === this) {
-      let attrs = getDocShell(backgroundFrame).getOriginAttributes();
-      getDocShell(panel.viewFrame).setOriginAttributes(attrs);
-
-      swapFrameLoaders(backgroundFrame, panel.viewFrame);
-    }
-  }
-
-  function onPopupHiding({type, target}) {
-    if (target === this) {
-      swapFrameLoaders(backgroundFrame, panel.viewFrame);
-
-      panel.viewFrame.remove();
-      panel.viewFrame = null;
-    }
-  }
-
-  function onContentReady({target, type}) {
-    if (target === getContentDocument(panel)) {
-      style(panel);
-      events.emit(type, { subject: panel });
-    }
-  }
-
-  function onContentLoad({target, type}) {
-    if (target === getContentDocument(panel))
-      events.emit(type, { subject: panel });
-  }
-
-  function onContentChange({subject: document, type}) {
-    if (document === getContentDocument(panel) && document.defaultView)
-      events.emit(type, { subject: panel });
-  }
-
-  function onPanelStateChange({target, type}) {
-    if (target === this)
-      events.emit(type, { subject: panel })
-  }
-
-  panel.addEventListener("popupshowing", onPopupShowing);
-  panel.addEventListener("popuphiding", onPopupHiding);
-  for (let event of ["popupshowing", "popuphiding", "popupshown", "popuphidden"])
-    panel.addEventListener(event, onPanelStateChange);
-
-  panel.addEventListener("click", onPanelClick);
-
-  // Panel content document can be either in panel `viewFrame` or in
-  // a `backgroundFrame` depending on panel state. Listeners are set
-  // on both to avoid setting and removing listeners on panel state changes.
-
-  panel.addEventListener("DOMContentLoaded", onContentReady, true);
-  backgroundFrame.addEventListener("DOMContentLoaded", onContentReady, true);
-
-  panel.addEventListener("load", onContentLoad, true);
-  backgroundFrame.addEventListener("load", onContentLoad, true);
-
-  events.on("document-element-inserted", onContentChange);
-
-  panel.backgroundFrame = backgroundFrame;
-  panel.viewFrame = null;
-
-  // Store event listener on the panel instance so that it won't be GC-ed
-  // while panel is alive.
-  panel.onContentChange = onContentChange;
-
-  return panel;
-}
-exports.make = make;
-
-function attach(panel, document) {
-  document = document || getMostRecentBrowserWindow().document;
-  let container = document.getElementById("mainPopupSet");
-  if (container !== panel.parentNode) {
-    detach(panel);
-    document.getElementById("mainPopupSet").appendChild(panel);
-  }
-}
-exports.attach = attach;
-
-function detach(panel) {
-  if (panel.parentNode) panel.remove();
-}
-exports.detach = detach;
-
-function dispose(panel) {
-  panel.backgroundFrame.remove();
-  panel.backgroundFrame = null;
-  events.off("document-element-inserted", panel.onContentChange);
-  panel.onContentChange = null;
-  detach(panel);
-}
-exports.dispose = dispose;
-
-function style(panel) {
-  /**
-  Injects default OS specific panel styles into content document that is loaded
-  into given panel. Optionally `document` of the browser window can be
-  given to inherit styles from it, by default it will use either panel owner
-  document or an active browser's document. It should not matter though unless
-  Firefox decides to style windows differently base on profile or mode like
-  chrome for example.
-  **/
-
-  try {
-    let document = panel.ownerDocument;
-    let contentDocument = getContentDocument(panel);
-    let window = document.defaultView;
-    let node = document.getAnonymousElementByAttribute(panel, "class",
-                                                       "panel-arrowcontent");
-
-    let { color, fontFamily, fontSize, fontWeight } = window.getComputedStyle(node);
-
-    let style = contentDocument.createElement("style");
-    style.id = "sdk-panel-style";
-    style.textContent = "body { " +
-      "color: " + color + ";" +
-      "font-family: " + fontFamily + ";" +
-      "font-weight: " + fontWeight + ";" +
-      "font-size: " + fontSize + ";" +
-    "}";
-
-    let container = contentDocument.head ? contentDocument.head :
-                    contentDocument.documentElement;
-
-    if (container.firstChild)
-      container.insertBefore(style, container.firstChild);
-    else
-      container.appendChild(style);
-  }
-  catch (error) {
-    console.error("Unable to apply panel style");
-    console.exception(error);
-  }
-}
-exports.style = style;
-
-var getContentFrame = panel => panel.viewFrame || panel.backgroundFrame;
-exports.getContentFrame = getContentFrame;
-
-function getContentDocument(panel) {
-  return getContentFrame(panel).contentDocument;
-}
-exports.getContentDocument = getContentDocument;
-
-function setURL(panel, url) {
-  let frame = getContentFrame(panel);
-  let webNav = getDocShell(frame).QueryInterface(Ci.nsIWebNavigation);
-
-  webNav.loadURI(url ? data.url(url) : "about:blank", 0, null, null, null);
-}
-
-exports.setURL = setURL;
-
-function allowContextMenu(panel, allow) {
-  if (allow) {
-    panel.setAttribute("context", "contentAreaContextMenu");
-  }
-  else {
-    panel.removeAttribute("context");
-  }
-}
-exports.allowContextMenu = allowContextMenu;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui.js
+++ /dev/null
@@ -1,25 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '> 28'
-  }
-};
-
-lazyRequire(this, './ui/button/action', 'ActionButton');
-lazyRequire(this, './ui/button/toggle', 'ToggleButton');
-lazyRequire(this, './ui/sidebar', 'Sidebar');
-lazyRequire(this, './ui/frame', 'Frame');
-lazyRequire(this, './ui/toolbar', 'Toolbar');
-
-module.exports = Object.freeze({
-  get ActionButton() { return ActionButton; },
-  get ToggleButton() { return ToggleButton; },
-  get Sidebar() { return Sidebar; },
-  get Frame() { return Frame; },
-  get Toolbar() { return Toolbar; },
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/button/action.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '> 28'
-  }
-};
-
-const { Class } = require('../../core/heritage');
-const { merge } = require('../../util/object');
-const { Disposable } = require('../../core/disposable');
-lazyRequire(this, '../../event/core', "on", "off", "emit", "setListeners");
-const { EventTarget } = require('../../event/target');
-lazyRequire(this, '../../view/core', "getNodeView");
-
-lazyRequireModule(this, './view', "view");
-const { buttonContract, stateContract } = require('./contract');
-lazyRequire(this, '../state', "properties", "render", "state", "register",
-            "unregister", "getDerivedStateFor");
-lazyRequire(this, '../state/events', { "events": "stateEvents" });
-lazyRequire(this, './view/events', { "events": "viewEvents" });
-lazyRequireModule(this, '../../event/utils', "events");
-
-lazyRequire(this, '../../tabs/utils', "getActiveTab");
-
-lazyRequire(this, '../../self', { "id": "addonID" });
-lazyRequire(this, '../id', "identify");
-
-const buttons = new Map();
-
-const toWidgetId = id =>
-  ('action-button--' + addonID.toLowerCase()+ '-' + id).
-    replace(/[^a-z0-9_-]/g, '');
-
-const ActionButton = Class({
-  extends: EventTarget,
-  implements: [
-    properties(stateContract),
-    state(stateContract),
-    Disposable
-  ],
-  setup: function setup(options) {
-    let state = merge({
-      disabled: false
-    }, buttonContract(options));
-
-    let id = toWidgetId(options.id);
-
-    register(this, state);
-
-    // Setup listeners.
-    setListeners(this, options);
-
-    buttons.set(id, this);
-
-    view.create(merge({}, state, { id: id }));
-  },
-
-  dispose: function dispose() {
-    let id = toWidgetId(this.id);
-    buttons.delete(id);
-
-    off(this);
-
-    view.dispose(id);
-
-    unregister(this);
-  },
-
-  get id() {
-    return this.state().id;
-  },
-
-  click: function click() { view.click(toWidgetId(this.id)) }
-});
-exports.ActionButton = ActionButton;
-
-identify.define(ActionButton, ({id}) => toWidgetId(id));
-
-getNodeView.define(ActionButton, button =>
-  view.nodeFor(toWidgetId(button.id))
-);
-
-var actionButtonStateEvents = events.filter(stateEvents,
-  e => e.target instanceof ActionButton);
-
-var actionButtonViewEvents = events.filter(viewEvents,
-  e => buttons.has(e.target));
-
-var clickEvents = events.filter(actionButtonViewEvents, e => e.type === 'click');
-var updateEvents = events.filter(actionButtonViewEvents, e => e.type === 'update');
-
-on(clickEvents, 'data', ({target: id, window}) => {
-  let button = buttons.get(id);
-  let state = getDerivedStateFor(button, getActiveTab(window));
-
-  emit(button, 'click', state);
-});
-
-on(updateEvents, 'data', ({target: id, window}) => {
-  render(buttons.get(id), window);
-});
-
-on(actionButtonStateEvents, 'data', ({target, window, state}) => {
-  let id = toWidgetId(target.id);
-  view.setIcon(id, window, state.icon);
-  view.setLabel(id, window, state.label);
-  view.setDisabled(id, window, state.disabled);
-  view.setBadge(id, window, state.badge, state.badgeColor);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/button/contract.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* 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 { contract } = require('../../util/contract');
-lazyRequire(this, '../../url', "isLocalURL");
-lazyRequire(this, '../../lang/type', "isNil", "isObject", "isString");
-const { required, either, string, boolean, object, number } = require('../../deprecated/api-utils');
-const { merge } = require('../../util/object');
-const { freeze } = Object;
-
-const isIconSet = (icons) =>
-  Object.keys(icons).
-    every(size => String(size >>> 0) === size && isLocalURL(icons[size]));
-
-var iconSet = {
-  is: either(object, string),
-  map: v => isObject(v) ? freeze(merge({}, v)) : v,
-  ok: v => (isString(v) && isLocalURL(v)) || (isObject(v) && isIconSet(v)),
-  msg: 'The option "icon" must be a local URL or an object with ' +
-    'numeric keys / local URL values pair.'
-}
-
-var id = {
-  is: string,
-  ok: v => /^[a-z-_][a-z0-9-_]*$/i.test(v),
-  msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' +
-        'underscores are allowed).'
-};
-
-var label = {
-  is: string,
-  ok: v => isNil(v) || v.trim().length > 0,
-  msg: 'The option "label" must be a non empty string'
-}
-
-var badge = {
-  is: either(string, number),
-  msg: 'The option "badge" must be a string or a number'
-}
-
-var badgeColor = {
-  is: string,
-  msg: 'The option "badgeColor" must be a string'
-}
-
-var stateContract = contract({
-  label: label,
-  icon: iconSet,
-  disabled: boolean,
-  badge: badge,
-  badgeColor: badgeColor
-});
-
-exports.stateContract = stateContract;
-
-var buttonContract = contract(merge({}, stateContract.rules, {
-  id: required(id),
-  label: required(label),
-  icon: required(iconSet)
-}));
-
-exports.buttonContract = buttonContract;
-
-exports.toggleStateContract = contract(merge({
-  checked: boolean
-}, stateContract.rules));
-
-exports.toggleButtonContract = contract(merge({
-  checked: boolean
-}, buttonContract.rules));
-
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/button/toggle.js
+++ /dev/null
@@ -1,127 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '> 28'
-  }
-};
-
-const { Class } = require('../../core/heritage');
-lazyRequire(this, '../../util/object', "merge");
-const { Disposable } = require('../../core/disposable');
-lazyRequire(this, '../../event/core', "on", "off", "emit", "setListeners");
-const { EventTarget } = require('../../event/target');
-lazyRequire(this, '../../view/core', "getNodeView");
-
-lazyRequireModule(this, "./view", "view");
-const { toggleButtonContract, toggleStateContract } = require('./contract');
-lazyRequire(this, '../state', "properties", "render", "state", "register", "unregister",
-            "setStateFor", "getStateFor", "getDerivedStateFor");
-lazyRequire(this, '../state/events', { "events": "stateEvents" });
-lazyRequire(this, './view/events', { "events": "viewEvents" });
-lazyRequireModule(this, '../../event/utils', "events");
-
-lazyRequire(this, '../../tabs/utils', "getActiveTab");
-
-lazyRequire(this, '../../self', { "id": "addonID" });
-lazyRequire(this, '../id', "identify");
-
-const buttons = new Map();
-
-const toWidgetId = id =>
-  ('toggle-button--' + addonID.toLowerCase()+ '-' + id).
-    replace(/[^a-z0-9_-]/g, '');
-
-const ToggleButton = Class({
-  extends: EventTarget,
-  implements: [
-    properties(toggleStateContract),
-    state(toggleStateContract),
-    Disposable
-  ],
-  setup: function setup(options) {
-    let state = merge({
-      disabled: false,
-      checked: false
-    }, toggleButtonContract(options));
-
-    let id = toWidgetId(options.id);
-
-    register(this, state);
-
-    // Setup listeners.
-    setListeners(this, options);
-
-    buttons.set(id, this);
-
-    view.create(merge({ type: 'checkbox' }, state, { id: id }));
-  },
-
-  dispose: function dispose() {
-    let id = toWidgetId(this.id);
-    buttons.delete(id);
-
-    off(this);
-
-    view.dispose(id);
-
-    unregister(this);
-  },
-
-  get id() {
-    return this.state().id;
-  },
-
-  click: function click() {
-    return view.click(toWidgetId(this.id));
-  }
-});
-exports.ToggleButton = ToggleButton;
-
-identify.define(ToggleButton, ({id}) => toWidgetId(id));
-
-getNodeView.define(ToggleButton, button =>
-  view.nodeFor(toWidgetId(button.id))
-);
-
-var toggleButtonStateEvents = events.filter(stateEvents,
-  e => e.target instanceof ToggleButton);
-
-var toggleButtonViewEvents = events.filter(viewEvents,
-  e => buttons.has(e.target));
-
-var clickEvents = events.filter(toggleButtonViewEvents, e => e.type === 'click');
-var updateEvents = events.filter(toggleButtonViewEvents, e => e.type === 'update');
-
-on(toggleButtonStateEvents, 'data', ({target, window, state}) => {
-  let id = toWidgetId(target.id);
-
-  view.setIcon(id, window, state.icon);
-  view.setLabel(id, window, state.label);
-  view.setDisabled(id, window, state.disabled);
-  view.setChecked(id, window, state.checked);
-  view.setBadge(id, window, state.badge, state.badgeColor);
-});
-
-on(clickEvents, 'data', ({target: id, window, checked }) => {
-  let button = buttons.get(id);
-  let windowState = getStateFor(button, window);
-
-  let newWindowState = merge({}, windowState, { checked: checked });
-
-  setStateFor(button, window, newWindowState);
-
-  let state = getDerivedStateFor(button, getActiveTab(window));
-
-  emit(button, 'click', state);
-
-  emit(button, 'change', state);
-});
-
-on(updateEvents, 'data', ({target: id, window}) => {
-  render(buttons.get(id), window);
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/button/view.js
+++ /dev/null
@@ -1,251 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '> 28'
-  }
-};
-
-const { Cu } = require('chrome');
-lazyRequire(this, '../../event/core', "on", "off", "emit");
-
-lazyRequire(this, 'sdk/self', "data");
-
-lazyRequire(this, '../../lang/type', "isObject", "isNil");
-
-lazyRequire(this, '../../window/utils', "getMostRecentBrowserWindow");
-lazyRequire(this, '../../private-browsing/utils', "ignoreWindow");
-const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
-const { AREA_PANEL, AREA_NAVBAR } = CustomizableUI;
-
-lazyRequire(this, './view/events', { "events": "viewEvents" });
-
-const XUL_NS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul';
-
-const views = new Map();
-const customizedWindows = new WeakMap();
-
-const buttonListener = {
-  onCustomizeStart: window => {
-    for (let [id, view] of views) {
-      setIcon(id, window, view.icon);
-      setLabel(id, window, view.label);
-    }
-
-    customizedWindows.set(window, true);
-  },
-  onCustomizeEnd: window => {
-    customizedWindows.delete(window);
-
-    for (let [id, ] of views) {
-      let placement = CustomizableUI.getPlacementOfWidget(id);
-
-      if (placement)
-        emit(viewEvents, 'data', { type: 'update', target: id, window: window });
-    }
-  },
-  onWidgetAfterDOMChange: (node, nextNode, container) => {
-    let { id } = node;
-    let view = views.get(id);
-    let window = node.ownerGlobal;
-
-    if (view) {
-      emit(viewEvents, 'data', { type: 'update', target: id, window: window });
-    }
-  }
-};
-
-CustomizableUI.addListener(buttonListener);
-
-require('../../system/unload').when( _ =>
-  CustomizableUI.removeListener(buttonListener)
-);
-
-function getNode(id, window) {
-  let view = views.get(id);
-  return view && view.nodes.get(window);
-};
-
-function isInToolbar(id) {
-  let placement = CustomizableUI.getPlacementOfWidget(id);
-
-  return placement && CustomizableUI.getAreaType(placement.area) === 'toolbar';
-}
-
-
-function getImage(icon, isInToolbar, pixelRatio) {
-  let targetSize = (isInToolbar ? 18 : 32) * pixelRatio;
-  let bestSize = 0;
-  let image = icon;
-
-  if (isObject(icon)) {
-    for (let size of Object.keys(icon)) {
-      size = +size;
-      let offset = targetSize - size;
-
-      if (offset === 0) {
-        bestSize = size;
-        break;
-      }
-
-      let delta = Math.abs(offset) - Math.abs(targetSize - bestSize);
-
-      if (delta < 0)
-        bestSize = size;
-    }
-
-    image = icon[bestSize];
-  }
-
-  if (image.indexOf('./') === 0)
-    return data.url(image.substr(2));
-
-  return image;
-}
-
-function nodeFor(id, window=getMostRecentBrowserWindow()) {
-  return customizedWindows.has(window) ? null : getNode(id, window);
-};
-exports.nodeFor = nodeFor;
-
-function create(options) {
-  let { id, label, icon, type, badge } = options;
-
-  if (views.has(id))
-    throw new Error('The ID "' + id + '" seems already used.');
-
-  CustomizableUI.createWidget({
-    id: id,
-    type: 'custom',
-    removable: true,
-    defaultArea: AREA_NAVBAR,
-    allowedAreas: [ AREA_PANEL, AREA_NAVBAR ],
-
-    onBuild: function(document) {
-      let window = document.defaultView;
-
-      let node = document.createElementNS(XUL_NS, 'toolbarbutton');
-
-      let image = getImage(icon, true, window.devicePixelRatio);
-
-      node.setAttribute('id', this.id);
-      node.setAttribute('class', 'toolbarbutton-1 chromeclass-toolbar-additional badged-button');
-      node.setAttribute('type', type);
-      node.setAttribute('label', label);
-      node.setAttribute('tooltiptext', label);
-      node.setAttribute('image', image);
-      node.setAttribute('constrain-size', 'true');
-
-      if (!views.get(id)) {
-        views.set(id, {
-          nodes: new WeakMap(),
-        });
-      }
-
-      let view = views.get(id);
-      Object.assign(view, {
-        area: this.currentArea,
-        icon: icon,
-        label: label
-      });
-
-      if (ignoreWindow(window))
-        node.style.display = 'none';
-      else
-        view.nodes.set(window, node);
-
-      node.addEventListener('command', function(event) {
-        if (views.has(id)) {
-          emit(viewEvents, 'data', {
-            type: 'click',
-            target: id,
-            window: event.view,
-            checked: node.checked
-          });
-        }
-      });
-
-      return node;
-    }
-  });
-};
-exports.create = create;
-
-function dispose(id) {
-  if (!views.has(id)) return;
-
-  views.delete(id);
-  CustomizableUI.destroyWidget(id);
-}
-exports.dispose = dispose;
-
-function setIcon(id, window, icon) {
-  let node = getNode(id, window);
-
-  if (node) {
-    icon = customizedWindows.has(window) ? views.get(id).icon : icon;
-    let image = getImage(icon, isInToolbar(id), window.devicePixelRatio);
-
-    node.setAttribute('image', image);
-  }
-}
-exports.setIcon = setIcon;
-
-function setLabel(id, window, label) {
-  let node = nodeFor(id, window);
-
-  if (node) {
-    node.setAttribute('label', label);
-    node.setAttribute('tooltiptext', label);
-  }
-}
-exports.setLabel = setLabel;
-
-function setDisabled(id, window, disabled) {
-  let node = nodeFor(id, window);
-
-  if (node)
-    node.disabled = disabled;
-}
-exports.setDisabled = setDisabled;
-
-function setChecked(id, window, checked) {
-  let node = nodeFor(id, window);
-
-  if (node)
-    node.checked = checked;
-}
-exports.setChecked = setChecked;
-
-function setBadge(id, window, badge, color) {
-  let node = nodeFor(id, window);
-
-  if (node) {
-    // `Array.from` is needed to handle unicode symbol properly:
-    // '𝐀𝐁'.length is 4 where Array.from('𝐀𝐁').length is 2
-    let text = badge == null
-                  ? ''
-                  : Array.from(String(badge)).slice(0, 4).join('');
-
-    node.setAttribute('badge', text);
-
-    let badgeNode = node.ownerDocument.getAnonymousElementByAttribute(node,
-                                        'class', 'toolbarbutton-badge');
-
-    if (badgeNode)
-      badgeNode.style.backgroundColor = color == null ? '' : color;
-  }
-}
-exports.setBadge = setBadge;
-
-function click(id) {
-  let node = nodeFor(id);
-
-  if (node)
-    node.click();
-}
-exports.click = click;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/button/view/events.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '*',
-    'SeaMonkey': '*',
-    'Thunderbird': '*'
-  }
-};
-
-var channel = {};
-
-exports.events = channel;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/component.js
+++ /dev/null
@@ -1,182 +0,0 @@
-/* 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";
-
-// Internal properties not exposed to the public.
-const cache = Symbol("component/cache");
-const writer = Symbol("component/writer");
-const isFirstWrite = Symbol("component/writer/first-write?");
-const currentState = Symbol("component/state/current");
-const pendingState = Symbol("component/state/pending");
-const isWriting = Symbol("component/writing?");
-
-const isntNull = x => x !== null;
-
-const Component = function(options, children) {
-  this[currentState] = null;
-  this[pendingState] = null;
-  this[writer] = null;
-  this[cache] = null;
-  this[isFirstWrite] = true;
-
-  this[Component.construct](options, children);
-}
-Component.Component = Component;
-// Constructs component.
-Component.construct = Symbol("component/construct");
-// Called with `options` and `children` and must return
-// initial state back.
-Component.initial = Symbol("component/initial");
-
-// Function patches current `state` with a given update.
-Component.patch = Symbol("component/patch");
-// Function that replaces current `state` with a passed state.
-Component.reset = Symbol("component/reset");
-
-// Function that must return render tree from passed state.
-Component.render = Symbol("component/render");
-
-// Path of the component with in the mount point.
-Component.path = Symbol("component/path");
-
-Component.isMounted = component => !!component[writer];
-Component.isWriting = component => !!component[isWriting];
-
-// Internal method that mounts component to a writer.
-// Mounts component to a writer.
-Component.mount = (component, write) => {
-  if (Component.isMounted(component)) {
-    throw Error("Can not mount already mounted component");
-  }
-
-  component[writer] = write;
-  Component.write(component);
-
-  if (component[Component.mounted]) {
-    component[Component.mounted]();
-  }
-}
-
-// Unmounts component from a writer.
-Component.unmount = (component) => {
-  if (Component.isMounted(component)) {
-    component[writer] = null;
-    if (component[Component.unmounted]) {
-      component[Component.unmounted]();
-    }
-  } else {
-    console.warn("Unmounting component that is not mounted is redundant");
-  }
-};
- // Method invoked once after inital write occurs.
-Component.mounted = Symbol("component/mounted");
-// Internal method that unmounts component from the writer.
-Component.unmounted = Symbol("component/unmounted");
-// Function that must return true if component is changed
-Component.isUpdated = Symbol("component/updated?");
-Component.update = Symbol("component/update");
-Component.updated = Symbol("component/updated");
-
-const writeChild = base => (child, index) => Component.write(child, base, index)
-Component.write = (component, base, index) => {
-  if (component === null) {
-    return component;
-  }
-
-  if (!(component instanceof Component)) {
-    const path = base ? `${base}${component.key || index}/` : `/`;
-    return Object.assign({}, component, {
-      [Component.path]: path,
-      children: component.children && component.children.
-                                        map(writeChild(path)).
-                                        filter(isntNull)
-    });
-  }
-
-  component[isWriting] = true;
-
-  try {
-
-    const current = component[currentState];
-    const pending = component[pendingState] || current;
-    const isUpdated = component[Component.isUpdated];
-    const isInitial = component[isFirstWrite];
-
-    if (isUpdated(current, pending) || isInitial) {
-      if (!isInitial && component[Component.update]) {
-        component[Component.update](pending, current)
-      }
-
-      // Note: [Component.update] could have caused more updates so can't use
-      // `pending` as `component[pendingState]` may have changed.
-      component[currentState] = component[pendingState] || current;
-      component[pendingState] = null;
-
-      const tree = component[Component.render](component[currentState]);
-      component[cache] = Component.write(tree, base, index);
-      if (component[writer]) {
-        component[writer].call(null, component[cache]);
-      }
-
-      if (!isInitial && component[Component.updated]) {
-        component[Component.updated](current, pending);
-      }
-    }
-
-    component[isFirstWrite] = false;
-
-    return component[cache];
-  } finally {
-    component[isWriting] = false;
-  }
-};
-
-Component.prototype = Object.freeze({
-  constructor: Component,
-
-  [Component.mounted]: null,
-  [Component.unmounted]: null,
-  [Component.update]: null,
-  [Component.updated]: null,
-
-  get state() {
-    return this[pendingState] || this[currentState];
-  },
-
-
-  [Component.construct](settings, items) {
-    const initial = this[Component.initial];
-    const base = initial(settings, items);
-    const options = Object.assign(Object.create(null), base.options, settings);
-    const children = base.children || items || null;
-    const state = Object.assign(Object.create(null), base, {options, children});
-    this[currentState] = state;
-
-    if (this.setup) {
-      this.setup(state);
-    }
-  },
-  [Component.initial](options, children) {
-    return Object.create(null);
-  },
-  [Component.patch](update) {
-    this[Component.reset](Object.assign({}, this.state, update));
-  },
-  [Component.reset](state) {
-    this[pendingState] = state;
-    if (Component.isMounted(this) && !Component.isWriting(this)) {
-      Component.write(this);
-    }
-  },
-
-  [Component.isUpdated](before, after) {
-    return before != after
-  },
-
-  [Component.render](state) {
-    throw Error("Component must implement [Component.render] member");
-  }
-});
-
-module.exports = Component;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/frame.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Frame } = require("./frame/model");
-
-exports.Frame = Frame;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/frame/model.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Class } = require("../../core/heritage");
-const { EventTarget } = require("../../event/target");
-lazyRequire(this, "../../event/core", "emit", "off", "setListeners");
-const { Reactor, foldp, send, merges } = require("../../event/utils");
-const { Disposable } = require("../../core/disposable");
-const { OutputPort } = require("../../output/system");
-lazyRequire(this, "../id", "identify");
-const { pairs, object, each } = require("../../util/sequence");
-lazyRequire(this, "diffpatcher/index", "patch", "diff");
-lazyRequire(this, "../../url", "isLocalURL");
-const { compose } = require("../../lang/functional");
-const { contract } = require("../../util/contract");
-const { id: addonID, data: { url: resolve }} = require("../../self");
-const { Frames } = require("../../input/frame");
-require("./view");
-
-
-const output = new OutputPort({ id: "frame-change" });
-const mailbox = new OutputPort({ id: "frame-mailbox" });
-const input = Frames;
-
-
-const makeID = url =>
-  ("frame-" + addonID + "-" + url).
-    split("/").join("-").
-    split(".").join("-").
-    replace(/[^A-Za-z0-9_\-]/g, "");
-
-const validate = contract({
-  name: {
-    is: ["string", "undefined"],
-    ok: x => /^[a-z][a-z0-9-_]+$/i.test(x),
-    msg: "The `option.name` must be a valid alphanumeric string (hyphens and " +
-         "underscores are allowed) starting with letter."
-  },
-  url: {
-    map: x => x.toString(),
-    is: ["string"],
-    ok: x => isLocalURL(x),
-    msg: "The `options.url` must be a valid local URI."
-  }
-});
-
-const Source = function({id, ownerID}) {
-  this.id = id;
-  this.ownerID = ownerID;
-};
-Source.postMessage = ({id, ownerID}, data, origin) => {
-  send(mailbox, object([id, {
-    inbox: {
-      target: {id: id, ownerID: ownerID},
-      timeStamp: Date.now(),
-      data: data,
-      origin: origin
-    }
-  }]));
-};
-Source.prototype.postMessage = function(data, origin) {
-  Source.postMessage(this, data, origin);
-};
-
-const Message = function({type, data, source, origin, timeStamp}) {
-  this.type = type;
-  this.data = data;
-  this.origin = origin;
-  this.timeStamp = timeStamp;
-  this.source = new Source(source);
-};
-
-
-const frames = new Map();
-const sources = new Map();
-
-const Frame = Class({
-  extends: EventTarget,
-  implements: [Disposable, Source],
-  initialize: function(params={}) {
-    const options = validate(params);
-    const id = makeID(options.name || options.url);
-
-    if (frames.has(id))
-      throw Error("Frame with this id already exists: " + id);
-
-    const initial = { id: id, url: resolve(options.url) };
-    this.id = id;
-
-    setListeners(this, params);
-
-    frames.set(this.id, this);
-
-    send(output, object([id, initial]));
-  },
-  get url() {
-    const state = reactor.value[this.id];
-    return state && state.url;
-  },
-  destroy: function() {
-    send(output, object([this.id, null]));
-    frames.delete(this.id);
-    off(this);
-  },
-  // `JSON.stringify` serializes objects based of the return
-  // value of this method. For convinienc we provide this method
-  // to serialize actual state data.
-  toJSON: function() {
-    return { id: this.id, url: this.url };
-  }
-});
-identify.define(Frame, frame => frame.id);
-
-exports.Frame = Frame;
-
-const reactor = new Reactor({
-  onStep: (present, past) => {
-    const delta = diff(past, present);
-
-    each(([id, update]) => {
-      const frame = frames.get(id);
-      if (update) {
-        if (!past[id])
-          emit(frame, "register");
-
-        if (update.outbox)
-          emit(frame, "message", new Message(present[id].outbox));
-
-        each(([ownerID, state]) => {
-          const readyState = state ? state.readyState : "detach";
-          const type = readyState === "loading" ? "attach" :
-                       readyState === "interactive" ? "ready" :
-                       readyState === "complete" ? "load" :
-                       readyState;
-
-          // TODO: Cache `Source` instances somewhere to preserve
-          // identity.
-          emit(frame, type, {type: type,
-                             source: new Source({id: id, ownerID: ownerID})});
-        }, pairs(update.owners));
-      }
-    }, pairs(delta));
-  }
-});
-reactor.run(input);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/frame/view.html
+++ /dev/null
@@ -1,18 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <script>
-      // HACK: This is not an ideal way to deliver chrome messages
-      // to an inner frame content but seems only way that would
-      // make `event.source` this (outer frame) window.
-      window.onmessage = function(event) {
-        var frame = document.querySelector("iframe");
-        var content = frame.contentWindow;
-        // If message is posted from chrome it has no `event.source`.
-        if (event.source === null)
-          content.postMessage(event.data, "*");
-      };
-    </script>
-  </head>
-  <body style="overflow: hidden"></body>
-</html>
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/frame/view.js
+++ /dev/null
@@ -1,145 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Cu, Ci } = require("chrome");
-const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
-const { send, Reactor } = require("../../event/utils");
-const { OutputPort } = require("../../output/system");
-lazyRequire(this, "../../util/sequence", "pairs", "keys", "object", "each");
-const { curry, compose } = require("../../lang/functional");
-lazyRequire(this, "../../window/utils", "getFrameElement", "getOuterId", "getByOuterId", "getOwnerBrowserWindow");
-lazyRequire(this, "diffpatcher/index", "patch", "diff");
-lazyRequire(this, "../../base64", "encode");
-const { Frames } = require("../../input/frame");
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-const OUTER_FRAME_URI = module.uri.replace(/\.js$/, ".html");
-
-const mailbox = new OutputPort({ id: "frame-mailbox" });
-
-const frameID = frame => frame.id.replace("outer-", "");
-const windowID = compose(getOuterId, getOwnerBrowserWindow);
-
-const getOuterFrame = (windowID, frameID) =>
-    getByOuterId(windowID).document.getElementById("outer-" + frameID);
-
-const listener = ({target, source, data, origin, timeStamp}) => {
-  // And sent received message to outbox so that frame API model
-  // will deal with it.
-  if (source && source !== target) {
-    const frame = getFrameElement(target);
-    const id = frameID(frame);
-    send(mailbox, object([id, {
-      outbox: {type: "message",
-               source: {id: id, ownerID: windowID(frame)},
-               data: data,
-               origin: origin,
-               timeStamp: timeStamp}}]));
-  }
-};
-
-// Utility function used to create frame with a given `state` and
-// inject it into given `window`.
-const registerFrame = ({id, url}) => {
-  CustomizableUI.createWidget({
-    id: id,
-    type: "custom",
-    removable: true,
-    onBuild: document => {
-      let view = document.createElementNS(XUL_NS, "toolbaritem");
-      view.setAttribute("id", id);
-      view.setAttribute("flex", 2);
-
-      let outerFrame = document.createElementNS(XUL_NS, "iframe");
-      outerFrame.setAttribute("src", OUTER_FRAME_URI);
-      outerFrame.setAttribute("id", "outer-" + id);
-      outerFrame.setAttribute("data-is-sdk-outer-frame", true);
-      outerFrame.setAttribute("type", "content");
-      outerFrame.setAttribute("transparent", true);
-      outerFrame.setAttribute("flex", 2);
-      outerFrame.setAttribute("style", "overflow: hidden;");
-      outerFrame.setAttribute("scrolling", "no");
-      outerFrame.setAttribute("disablehistory", true);
-      outerFrame.setAttribute("seamless", "seamless");
-      outerFrame.addEventListener("load", function() {
-        let doc = outerFrame.contentDocument;
-
-        let innerFrame = doc.createElementNS(HTML_NS, "iframe");
-        innerFrame.setAttribute("id", id);
-        innerFrame.setAttribute("src", url);
-        innerFrame.setAttribute("seamless", "seamless");
-        innerFrame.setAttribute("sandbox", "allow-scripts");
-        innerFrame.setAttribute("scrolling", "no");
-        innerFrame.setAttribute("data-is-sdk-inner-frame", true);
-        innerFrame.setAttribute("style", [ "border:none",
-          "position:absolute", "width:100%", "top: 0",
-          "left: 0", "overflow: hidden"].join(";"));
-
-        doc.body.appendChild(innerFrame);
-      }, {capture: true, once: true});
-
-      view.appendChild(outerFrame);
-
-      return view;
-    }
-  });
-};
-
-const unregisterFrame = CustomizableUI.destroyWidget;
-
-const deliverMessage = curry((frameID, data, windowID) => {
-  const frame = getOuterFrame(windowID, frameID);
-  const content = frame && frame.contentWindow;
-
-  if (content)
-    content.postMessage(data, content.location.origin);
-});
-
-const updateFrame = (id, {inbox, owners}, present) => {
-  if (inbox) {
-    const { data, target:{ownerID}, source } = present[id].inbox;
-    if (ownerID)
-      deliverMessage(id, data, ownerID);
-    else
-      each(deliverMessage(id, data), keys(present[id].owners));
-  }
-
-  each(setupView(id), pairs(owners));
-};
-
-const setupView = curry((frameID, [windowID, state]) => {
-  if (state && state.readyState === "loading") {
-    const frame = getOuterFrame(windowID, frameID);
-    // Setup a message listener on contentWindow.
-    frame.contentWindow.addEventListener("message", listener);
-  }
-});
-
-
-const reactor = new Reactor({
-  onStep: (present, past) => {
-    const delta = diff(past, present);
-
-    // Apply frame changes
-    each(([id, update]) => {
-      if (update === null)
-        unregisterFrame(id);
-      else if (past[id])
-        updateFrame(id, update, present);
-      else
-        registerFrame(update);
-    }, pairs(delta));
-  },
-  onEnd: state => each(unregisterFrame, keys(state))
-});
-reactor.run(Frames);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/id.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental'
-};
-
-const method = require('../../method/core');
-lazyRequire(this, '../util/uuid', "uuid");
-
-// NOTE: use lang/functional memoize when it is updated to use WeakMap
-function memoize(f) {
-  const memo = new WeakMap();
-
-  return function memoizer(o) {
-    let key = o;
-    if (!memo.has(key))
-      memo.set(key, f.apply(this, arguments));
-    return memo.get(key);
-  };
-}
-
-var identify = method('identify');
-identify.define(Object, memoize(function() { return uuid(); }));
-exports.identify = identify;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '*'
-  }
-};
-
-const { Class } = require('../core/heritage');
-const { merge } = require('../util/object');
-const { Disposable } = require('../core/disposable');
-lazyRequire(this, '../event/core', "off", "emit", "setListeners");
-const { EventTarget } = require('../event/target');
-lazyRequire(this, '../url', "URL");
-lazyRequire(this, '../self', { "id": "addonID" }, "data");
-lazyRequire(this, '../deprecated/window-utils', 'WindowTracker');
-lazyRequire(this, './sidebar/utils', "isShowing");
-lazyRequire(this, '../window/utils', "isBrowser", "getMostRecentBrowserWindow", "windows", "isWindowPrivate");
-const { ns } = require('../core/namespace');
-lazyRequire(this, '../util/array', { "remove": "removeFromArray" });
-lazyRequire(this, './sidebar/actions', "show", "hide", "toggle");
-lazyRequire(this, '../deprecated/sync-worker', "Worker");
-const { contract: sidebarContract } = require('./sidebar/contract');
-lazyRequire(this, './sidebar/view', "create", "dispose", "updateTitle", "updateURL", "isSidebarShowing", "showSidebar", "hideSidebar");
-lazyRequire(this, '../core/promise', "defer");
-lazyRequire(this, './sidebar/namespace', "models", "views", "viewsFor", "modelFor");
-lazyRequire(this, '../url', "isLocalURL");
-const { ensure } = require('../system/unload');
-lazyRequire(this, './id', "identify");
-lazyRequire(this, '../util/uuid', "uuid");
-lazyRequire(this, '../view/core', "viewFor");
-
-const resolveURL = (url) => url ? data.url(url) : url;
-
-const sidebarNS = ns();
-
-const WEB_PANEL_BROWSER_ID = 'web-panels-browser';
-
-const Sidebar = Class({
-  implements: [ Disposable ],
-  extends: EventTarget,
-  setup: function(options) {
-    // inital validation for the model information
-    let model = sidebarContract(options);
-
-    // save the model information
-    models.set(this, model);
-
-    // generate an id if one was not provided
-    model.id = model.id || addonID + '-' + uuid();
-
-    // further validation for the title and url
-    validateTitleAndURLCombo({}, this.title, this.url);
-
-    const self = this;
-    const internals = sidebarNS(self);
-    const windowNS = internals.windowNS = ns();
-
-    // see bug https://bugzilla.mozilla.org/show_bug.cgi?id=886148
-    ensure(this, 'destroy');
-
-    setListeners(this, options);
-
-    let bars = [];
-    internals.tracker = WindowTracker({
-      onTrack: function(window) {
-        if (!isBrowser(window))
-          return;
-
-        let sidebar = window.document.getElementById('sidebar');
-        let sidebarBox = window.document.getElementById('sidebar-box');
-
-        let bar = create(window, {
-          id: self.id,
-          title: self.title,
-          sidebarurl: self.url
-        });
-        bars.push(bar);
-        windowNS(window).bar = bar;
-
-        bar.addEventListener('command', function() {
-          if (isSidebarShowing(window, self)) {
-            hideSidebar(window, self).catch(() => {});
-            return;
-          }
-
-          showSidebar(window, self);
-        });
-
-        function onSidebarLoad() {
-          // check if the sidebar is ready
-          let isReady = sidebar.docShell && sidebar.contentDocument;
-          if (!isReady)
-            return;
-
-          // check if it is a web panel
-          let panelBrowser = sidebar.contentDocument.getElementById(WEB_PANEL_BROWSER_ID);
-          if (!panelBrowser) {
-            bar.removeAttribute('checked');
-            return;
-          }
-
-          let sbTitle = window.document.getElementById('sidebar-title');
-          function onWebPanelSidebarCreated() {
-            if (panelBrowser.contentWindow.location != resolveURL(model.url) ||
-                sbTitle.value != model.title) {
-              return;
-            }
-
-            let worker = windowNS(window).worker = Worker({
-              window: panelBrowser.contentWindow,
-              injectInDocument: true
-            });
-
-            function onWebPanelSidebarUnload() {
-              windowNS(window).onWebPanelSidebarUnload = null;
-
-              // uncheck the associated menuitem
-              bar.setAttribute('checked', 'false');
-
-              emit(self, 'hide', {});
-              emit(self, 'detach', worker);
-              windowNS(window).worker = null;
-            }
-            windowNS(window).onWebPanelSidebarUnload = onWebPanelSidebarUnload;
-            panelBrowser.contentWindow.addEventListener('unload', onWebPanelSidebarUnload, true);
-
-            // check the associated menuitem
-            bar.setAttribute('checked', 'true');
-
-            function onWebPanelSidebarReady() {
-              panelBrowser.contentWindow.removeEventListener('DOMContentLoaded', onWebPanelSidebarReady);
-              windowNS(window).onWebPanelSidebarReady = null;
-
-              emit(self, 'ready', worker);
-            }
-            windowNS(window).onWebPanelSidebarReady = onWebPanelSidebarReady;
-            panelBrowser.contentWindow.addEventListener('DOMContentLoaded', onWebPanelSidebarReady);
-
-            function onWebPanelSidebarLoad() {
-              panelBrowser.contentWindow.removeEventListener('load', onWebPanelSidebarLoad, true);
-              windowNS(window).onWebPanelSidebarLoad = null;
-
-              // TODO: decide if returning worker is acceptable..
-              //emit(self, 'show', { worker: worker });
-              emit(self, 'show', {});
-            }
-            windowNS(window).onWebPanelSidebarLoad = onWebPanelSidebarLoad;
-            panelBrowser.contentWindow.addEventListener('load', onWebPanelSidebarLoad, true);
-
-            emit(self, 'attach', worker);
-          }
-          windowNS(window).onWebPanelSidebarCreated = onWebPanelSidebarCreated;
-          panelBrowser.addEventListener('DOMWindowCreated', onWebPanelSidebarCreated, true);
-        }
-        windowNS(window).onSidebarLoad = onSidebarLoad;
-        sidebar.addEventListener('load', onSidebarLoad, true); // removed properly
-      },
-      onUntrack: function(window) {
-        if (!isBrowser(window))
-          return;
-
-        // hide the sidebar if it is showing
-        hideSidebar(window, self).catch(() => {});
-
-        // kill the menu item
-        let { bar } = windowNS(window);
-        if (bar) {
-          removeFromArray(viewsFor(self), bar);
-          dispose(bar);
-        }
-
-        // kill listeners
-        let sidebar = window.document.getElementById('sidebar');
-
-        if (windowNS(window).onSidebarLoad) {
-          sidebar && sidebar.removeEventListener('load', windowNS(window).onSidebarLoad, true)
-          windowNS(window).onSidebarLoad = null;
-        }
-
-        let panelBrowser = sidebar && sidebar.contentDocument.getElementById(WEB_PANEL_BROWSER_ID);
-        if (windowNS(window).onWebPanelSidebarCreated) {
-          panelBrowser && panelBrowser.removeEventListener('DOMWindowCreated', windowNS(window).onWebPanelSidebarCreated, true);
-          windowNS(window).onWebPanelSidebarCreated = null;
-        }
-
-        if (windowNS(window).onWebPanelSidebarReady) {
-          panelBrowser && panelBrowser.contentWindow.removeEventListener('DOMContentLoaded', windowNS(window).onWebPanelSidebarReady);
-          windowNS(window).onWebPanelSidebarReady = null;
-        }
-
-        if (windowNS(window).onWebPanelSidebarLoad) {
-          panelBrowser && panelBrowser.contentWindow.removeEventListener('load', windowNS(window).onWebPanelSidebarLoad, true);
-          windowNS(window).onWebPanelSidebarLoad = null;
-        }
-
-        if (windowNS(window).onWebPanelSidebarUnload) {
-          panelBrowser && panelBrowser.contentWindow.removeEventListener('unload', windowNS(window).onWebPanelSidebarUnload, true);
-          windowNS(window).onWebPanelSidebarUnload();
-        }
-      }
-    });
-
-    views.set(this, bars);
-  },
-  get id() {
-    return (modelFor(this) || {}).id;
-  },
-  get title() {
-    return (modelFor(this) || {}).title;
-  },
-  set title(v) {
-    // destroyed?
-    if (!modelFor(this))
-      return;
-    // validation
-    if (typeof v != 'string')
-      throw Error('title must be a string');
-    validateTitleAndURLCombo(this, v, this.url);
-    // do update
-    updateTitle(this, v);
-    return modelFor(this).title = v;
-  },
-  get url() {
-    return (modelFor(this) || {}).url;
-  },
-  set url(v) {
-    // destroyed?
-    if (!modelFor(this))
-      return;
-
-    // validation
-    if (!isLocalURL(v))
-      throw Error('the url must be a valid local url');
-
-    validateTitleAndURLCombo(this, this.title, v);
-
-    // do update
-    updateURL(this, v);
-    modelFor(this).url = v;
-  },
-  show: function(window) {
-    return showSidebar(viewFor(window), this);
-  },
-  hide: function(window) {
-    return hideSidebar(viewFor(window), this);
-  },
-  dispose: function() {
-    const internals = sidebarNS(this);
-
-    off(this);
-
-    // stop tracking windows
-    if (internals.tracker) {
-      internals.tracker.unload();
-    }
-
-    internals.tracker = null;
-    internals.windowNS = null;
-
-    views.delete(this);
-    models.delete(this);
-  }
-});
-exports.Sidebar = Sidebar;
-
-function validateTitleAndURLCombo(sidebar, title, url) {
-  url = resolveURL(url);
-
-  if (sidebar.title == title && sidebar.url == url) {
-    return false;
-  }
-
-  for (let window of windows(null, { includePrivate: true })) {
-    let sidebar = window.document.querySelector('menuitem[sidebarurl="' + url + '"][label="' + title + '"]');
-    if (sidebar) {
-      throw Error('The provided title and url combination is invalid (already used).');
-    }
-  }
-
-  return false;
-}
-
-isShowing.define(Sidebar, isSidebarShowing.bind(null, null));
-show.define(Sidebar, showSidebar.bind(null, null));
-hide.define(Sidebar, hideSidebar.bind(null, null));
-
-identify.define(Sidebar, function(sidebar) {
-  return sidebar.id;
-});
-
-function toggleSidebar(window, sidebar) {
-  // TODO: make sure this is not private
-  window = window || getMostRecentBrowserWindow();
-  if (isSidebarShowing(window, sidebar)) {
-    return hideSidebar(window, sidebar);
-  }
-  return showSidebar(window, sidebar);
-}
-toggle.define(Sidebar, toggleSidebar.bind(null, null));
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar/actions.js
+++ /dev/null
@@ -1,10 +0,0 @@
-/* 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 method = require('../../../method/core');
-
-exports.show = method('show');
-exports.hide = method('hide');
-exports.toggle = method('toggle');
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar/contract.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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 { contract } = require('../../util/contract');
-const { isValidURI, URL, isLocalURL } = require('../../url');
-const { isNil, isObject, isString } = require('../../lang/type');
-
-exports.contract = contract({
-  id: {
-  	is: [ 'string', 'undefined' ],
-  	ok: v => /^[a-z0-9-_]+$/i.test(v),
-    msg: 'The option "id" must be a valid alphanumeric id (hyphens and ' +
-         'underscores are allowed).'
-  },
-  title: {
-  	is: [ 'string' ],
-  	ok: v => v.length
-  },
-  url: {
-    is: [ 'string' ],
-    ok: v => isLocalURL(v),
-    map: v => v.toString(),
-    msg: 'The option "url" must be a valid local URI.'
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar/namespace.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/* 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 models = exports.models = new WeakMap();
-const views = exports.views = new WeakMap();
-exports.buttons = new WeakMap();
-
-exports.viewsFor = function viewsFor(sidebar) {
-  return views.get(sidebar);
-};
-exports.modelFor = function modelFor(sidebar) {
-  return models.get(sidebar);
-};
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar/utils.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* 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 method = require('../../../method/core');
-
-exports.isShowing = method('isShowing');
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/sidebar/view.js
+++ /dev/null
@@ -1,214 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'unstable',
-  'engines': {
-    'Firefox': '*'
-  }
-};
-
-lazyRequire(this, './namespace', "models", "buttons", "views", "viewsFor", "modelFor");
-lazyRequire(this, '../../window/utils', "isBrowser", "getMostRecentBrowserWindow", "windows", "isWindowPrivate");
-lazyRequire(this, '../state', "setStateFor");
-lazyRequire(this, '../../core/promise', "defer");
-lazyRequire(this, '../../self', "isPrivateBrowsingSupported", "data");
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const WEB_PANEL_BROWSER_ID = 'web-panels-browser';
-
-const resolveURL = (url) => url ? data.url(url) : url;
-
-function create(window, details) {
-  let id = makeID(details.id);
-  let { document } = window;
-
-  if (document.getElementById(id))
-    throw new Error('The ID "' + details.id + '" seems already used.');
-
-  let menuitem = document.createElementNS(XUL_NS, 'menuitem');
-  menuitem.setAttribute('id', id);
-  menuitem.setAttribute('label', details.title);
-  menuitem.setAttribute('sidebarurl', resolveURL(details.sidebarurl));
-  menuitem.setAttribute('checked', 'false');
-  menuitem.setAttribute('type', 'checkbox');
-  menuitem.setAttribute('group', 'sidebar');
-  menuitem.setAttribute('autoCheck', 'false');
-
-  document.getElementById('viewSidebarMenu').appendChild(menuitem);
-
-  return menuitem;
-}
-exports.create = create;
-
-function dispose(menuitem) {
-  menuitem.remove();
-}
-exports.dispose = dispose;
-
-function updateTitle(sidebar, title) {
-  let button = buttons.get(sidebar);
-
-  for (let window of windows(null, { includePrivate: true })) {
-  	let { document } = window;
-
-    // update the button
-    if (button) {
-      setStateFor(button, window, { label: title });
-    }
-
-    // update the menuitem
-    let mi = document.getElementById(makeID(sidebar.id));
-    if (mi) {
-      mi.setAttribute('label', title)
-    }
-
-    // update sidebar, if showing
-    if (isSidebarShowing(window, sidebar)) {
-      document.getElementById('sidebar-title').setAttribute('value', title);
-    }
-  }
-}
-exports.updateTitle = updateTitle;
-
-function updateURL(sidebar, url) {
-  let eleID = makeID(sidebar.id);
-
-  url = resolveURL(url);
-
-  for (let window of windows(null, { includePrivate: true })) {
-    // update the menuitem
-    let mi = window.document.getElementById(eleID);
-    if (mi) {
-      mi.setAttribute('sidebarurl', url)
-    }
-
-    // update sidebar, if showing
-    if (isSidebarShowing(window, sidebar)) {
-      showSidebar(window, sidebar, url);
-    }
-  }
-}
-exports.updateURL = updateURL;
-
-function isSidebarShowing(window, sidebar) {
-  let win = window || getMostRecentBrowserWindow();
-
-  // make sure there is a window
-  if (!win) {
-    return false;
-  }
-
-  // make sure there is a sidebar for the window
-  let sb = win.document.getElementById('sidebar');
-  let sidebarTitle = win.document.getElementById('sidebar-title');
-  if (!(sb && sidebarTitle)) {
-    return false;
-  }
-
-  // checks if the sidebar box is hidden
-  let sbb = win.document.getElementById('sidebar-box');
-  if (!sbb || sbb.hidden) {
-    return false;
-  }
-
-  if (sidebarTitle.value == modelFor(sidebar).title) {
-    let url = resolveURL(modelFor(sidebar).url);
-
-    // checks if the sidebar is loading
-    if (win.gWebPanelURI == url) {
-      return true;
-    }
-
-    // checks if the sidebar loaded already
-    let ele = sb.contentDocument && sb.contentDocument.getElementById(WEB_PANEL_BROWSER_ID);
-    if (!ele) {
-      return false;
-    }
-
-    if (ele.getAttribute('cachedurl') == url) {
-      return true;
-    }
-
-    if (ele && ele.contentWindow && ele.contentWindow.location == url) {
-      return true;
-    }
-  }
-
-  // default
-  return false;
-}
-exports.isSidebarShowing = isSidebarShowing;
-
-function showSidebar(window, sidebar, newURL) {
-  window = window || getMostRecentBrowserWindow();
-
-  let { promise, resolve, reject } = defer();
-  let model = modelFor(sidebar);
-
-  if (!newURL && isSidebarShowing(window, sidebar)) {
-    resolve({});
-  }
-  else if (!isPrivateBrowsingSupported && isWindowPrivate(window)) {
-    reject(Error('You cannot show a sidebar on private windows'));
-  }
-  else {
-    sidebar.once('show', resolve);
-
-    let menuitem = window.document.getElementById(makeID(model.id));
-    menuitem.setAttribute('checked', true);
-
-    window.openWebPanel(model.title, resolveURL(newURL || model.url));
-  }
-
-  return promise;
-}
-exports.showSidebar = showSidebar;
-
-
-function hideSidebar(window, sidebar) {
-  window = window || getMostRecentBrowserWindow();
-
-  let { promise, resolve, reject } = defer();
-
-  if (!isSidebarShowing(window, sidebar)) {
-    reject(Error('The sidebar is already hidden'));
-  }
-  else {
-    sidebar.once('hide', resolve);
-
-    // Below was taken from http://mxr.mozilla.org/mozilla-central/source/browser/base/content/browser.js#4775
-    // the code for window.todggleSideBar()..
-    let { document } = window;
-    let sidebarEle = document.getElementById('sidebar');
-    let sidebarTitle = document.getElementById('sidebar-title');
-    let sidebarBox = document.getElementById('sidebar-box');
-    let sidebarSplitter = document.getElementById('sidebar-splitter');
-    let commandID = sidebarBox.getAttribute('sidebarcommand');
-    let sidebarBroadcaster = document.getElementById(commandID);
-
-    sidebarBox.hidden = true;
-    sidebarSplitter.hidden = true;
-
-    sidebarEle.setAttribute('src', 'about:blank');
-    //sidebarEle.docShell.createAboutBlankContentViewer(null);
-
-    sidebarBroadcaster.removeAttribute('checked');
-    sidebarBox.setAttribute('sidebarcommand', '');
-    sidebarTitle.value = '';
-    sidebarBox.hidden = true;
-    sidebarSplitter.hidden = true;
-
-    // TODO: perhaps this isn't necessary if the window is not most recent?
-    window.gBrowser.selectedBrowser.focus();
-  }
-
-  return promise;
-}
-exports.hideSidebar = hideSidebar;
-
-function makeID(id) {
-  return 'jetpack-sidebar-' + id;
-}
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/state.js
+++ /dev/null
@@ -1,239 +0,0 @@
-/* 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';
-
-// The Button module currently supports only Firefox.
-// See: https://bugzilla.mozilla.org/show_bug.cgi?id=jetpack-panel-apps
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '*',
-    'SeaMonkey': '*',
-    'Thunderbird': '*'
-  }
-};
-
-const { Ci } = require('chrome');
-
-const events = require('../event/utils');
-const { events: browserEvents } = require('../browser/events');
-const { events: tabEvents } = require('../tab/events');
-const { events: stateEvents } = require('./state/events');
-
-lazyRequire(this, '../window/utils', "windows", "isInteractive", "getFocusedBrowser");
-lazyRequire(this, '../tabs/utils', "getActiveTab", "getOwnerWindow");
-
-lazyRequire(this, '../private-browsing/utils', "ignoreWindow");
-
-const { freeze } = Object;
-const { merge } = require('../util/object');
-lazyRequire(this, '../event/core', "on", "off", "emit");
-
-lazyRequire(this, '../lang/weak-set', "add", "remove", "has", "clear", "iterator");
-lazyRequire(this, '../lang/type', "isNil");
-
-lazyRequire(this, '../view/core', "viewFor");
-
-const components = new WeakMap();
-
-const ERR_UNREGISTERED = 'The state cannot be set or get. ' +
-  'The object may be not be registered, or may already have been unloaded.';
-
-const ERR_INVALID_TARGET = 'The state cannot be set or get for this target.' +
-  'Only window, tab and registered component are valid targets.';
-
-const isWindow = thing => thing instanceof Ci.nsIDOMWindow;
-const isTab = thing => thing.tagName && thing.tagName.toLowerCase() === 'tab';
-const isActiveTab = thing => isTab(thing) && thing === getActiveTab(getOwnerWindow(thing));
-const isEnumerable = window => !ignoreWindow(window);
-const browsers = _ =>
-  windows('navigator:browser', { includePrivate: true }).filter(isInteractive);
-const getMostRecentTab = _ => getActiveTab(getFocusedBrowser());
-
-function getStateFor(component, target) {
-  if (!isRegistered(component))
-    throw new Error(ERR_UNREGISTERED);
-
-  if (!components.has(component))
-    return null;
-
-  let states = components.get(component);
-
-  if (target) {
-    if (isTab(target) || isWindow(target) || target === component)
-      return states.get(target) || null;
-    else
-      throw new Error(ERR_INVALID_TARGET);
-  }
-
-  return null;
-}
-exports.getStateFor = getStateFor;
-
-function getDerivedStateFor(component, target) {
-  if (!isRegistered(component))
-    throw new Error(ERR_UNREGISTERED);
-
-  if (!components.has(component))
-    return null;
-
-  let states = components.get(component);
-
-  let componentState = states.get(component);
-  let windowState = null;
-  let tabState = null;
-
-  if (target) {
-    // has a target
-    if (isTab(target)) {
-      windowState = states.get(getOwnerWindow(target), null);
-
-      if (states.has(target)) {
-        // we have a tab state
-        tabState = states.get(target);
-      }
-    }
-    else if (isWindow(target) && states.has(target)) {
-      // we have a window state
-      windowState = states.get(target);
-    }
-  }
-
-  return freeze(merge({}, componentState, windowState, tabState));
-}
-exports.getDerivedStateFor = getDerivedStateFor;
-
-function setStateFor(component, target, state) {
-  if (!isRegistered(component))
-    throw new Error(ERR_UNREGISTERED);
-
-  let isComponentState = target === component;
-  let targetWindows = isWindow(target) ? [target] :
-                      isActiveTab(target) ? [getOwnerWindow(target)] :
-                      isComponentState ? browsers() :
-                      isTab(target) ? [] :
-                      null;
-
-  if (!targetWindows)
-    throw new Error(ERR_INVALID_TARGET);
-
-  // initialize the state's map
-  if (!components.has(component))
-    components.set(component, new WeakMap());
-
-  let states = components.get(component);
-
-  if (state === null && !isComponentState) // component state can't be deleted
-    states.delete(target);
-  else {
-    let base = isComponentState ? states.get(target) : null;
-    states.set(target, freeze(merge({}, base, state)));
-  }
-
-  render(component, targetWindows);
-}
-exports.setStateFor = setStateFor;
-
-function render(component, targetWindows) {
-  targetWindows = targetWindows ? [].concat(targetWindows) : browsers();
-
-  for (let window of targetWindows.filter(isEnumerable)) {
-    let tabState = getDerivedStateFor(component, getActiveTab(window));
-
-    emit(stateEvents, 'data', {
-      type: 'render',
-      target: component,
-      window: window,
-      state: tabState
-    });
-
-  }
-}
-exports.render = render;
-
-function properties(contract) {
-  let { rules } = contract;
-  let descriptor = Object.keys(rules).reduce(function(descriptor, name) {
-    descriptor[name] = {
-      get: function() { return getDerivedStateFor(this)[name] },
-      set: function(value) {
-        let changed = {};
-        changed[name] = value;
-
-        setStateFor(this, this, contract(changed));
-      }
-    }
-    return descriptor;
-  }, {});
-
-  return Object.create(Object.prototype, descriptor);
-}
-exports.properties = properties;
-
-function state(contract) {
-  return {
-    state: function state(target, state) {
-      let nativeTarget = target === 'window' ? getFocusedBrowser()
-                          : target === 'tab' ? getMostRecentTab()
-                          : target === this ? null
-                          : viewFor(target);
-
-      if (!nativeTarget && target !== this && !isNil(target))
-        throw new Error(ERR_INVALID_TARGET);
-
-      target = nativeTarget || target;
-
-      // jquery style
-      return arguments.length < 2
-        ? getDerivedStateFor(this, target)
-        : setStateFor(this, target, contract(state))
-    }
-  }
-}
-exports.state = state;
-
-const register = (component, state) => {
-  add(components, component);
-  setStateFor(component, component, state);
-}
-exports.register = register;
-
-const unregister = component => {
-  remove(components, component);
-}
-exports.unregister = unregister;
-
-const isRegistered = component => has(components, component);
-exports.isRegistered = isRegistered;
-
-var tabSelect = events.filter(tabEvents, e => e.type === 'TabSelect');
-var tabClose = events.filter(tabEvents, e => e.type === 'TabClose');
-var windowOpen = events.filter(browserEvents, e => e.type === 'load');
-var windowClose = events.filter(browserEvents, e => e.type === 'close');
-
-var close = events.merge([tabClose, windowClose]);
-var activate = events.merge([windowOpen, tabSelect]);
-
-on(activate, 'data', ({target}) => {
-  let [window, tab] = isWindow(target)
-                        ? [target, getActiveTab(target)]
-                        : [getOwnerWindow(target), target];
-
-  if (ignoreWindow(window)) return;
-
-  for (let component of iterator(components)) {
-    emit(stateEvents, 'data', {
-      type: 'render',
-      target: component,
-      window: window,
-      state: getDerivedStateFor(component, tab)
-    });
-  }
-});
-
-on(close, 'data', function({target}) {
-  for (let component of iterator(components)) {
-    components.get(component).delete(target);
-  }
-});
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/state/events.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* 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';
-
-module.metadata = {
-  'stability': 'experimental',
-  'engines': {
-    'Firefox': '*',
-    'SeaMonkey': '*',
-    'Thunderbird': '*'
-  }
-};
-
-var channel = {};
-
-exports.events = channel;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/toolbar.js
+++ /dev/null
@@ -1,16 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Toolbar } = require("./toolbar/model");
-require("./toolbar/view");
-
-exports.Toolbar = Toolbar;
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/toolbar/model.js
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Class } = require("../../core/heritage");
-const { EventTarget } = require("../../event/target");
-const { off, setListeners, emit } = require("../../event/core");
-const { Reactor, foldp, merges, send } = require("../../event/utils");
-const { Disposable } = require("../../core/disposable");
-const { InputPort } = require("../../input/system");
-const { OutputPort } = require("../../output/system");
-const { identify } = require("../id");
-const { pairs, object, map, each } = require("../../util/sequence");
-const { patch, diff } = require("diffpatcher/index");
-const { contract } = require("../../util/contract");
-const { id: addonID } = require("../../self");
-
-// Input state is accumulated from the input received form the toolbar
-// view code & local output. Merging local output reflects local state
-// changes without complete roundloop.
-const input = foldp(patch, {}, new InputPort({ id: "toolbar-changed" }));
-const output = new OutputPort({ id: "toolbar-change" });
-
-// Takes toolbar title and normalizes is to an
-// identifier, also prefixes with add-on id.
-const titleToId = title =>
-  ("toolbar-" + addonID + "-" + title).
-    toLowerCase().
-    replace(/\s/g, "-").
-    replace(/[^A-Za-z0-9_\-]/g, "");
-
-const validate = contract({
-  title: {
-    is: ["string"],
-    ok: x => x.length > 0,
-    msg: "The `option.title` string must be provided"
-  },
-  items: {
-    is:["undefined", "object", "array"],
-    msg: "The `options.items` must be iterable sequence of items"
-  },
-  hidden: {
-    is: ["boolean", "undefined"],
-    msg: "The `options.hidden` must be boolean"
-  }
-});
-
-// Toolbars is a mapping between `toolbar.id` & `toolbar` instances,
-// which is used to find intstance for dispatching events.
-var toolbars = new Map();
-
-const Toolbar = Class({
-  extends: EventTarget,
-  implements: [Disposable],
-  initialize: function(params={}) {
-    const options = validate(params);
-    const id = titleToId(options.title);
-
-    if (toolbars.has(id))
-      throw Error("Toolbar with this id already exists: " + id);
-
-    // Set of the items in the toolbar isn't mutable, as a matter of fact
-    // it just defines desired set of items, actual set is under users
-    // control. Conver test to an array and freeze to make sure users won't
-    // try mess with it.
-    const items = Object.freeze(options.items ? [...options.items] : []);
-
-    const initial = {
-      id: id,
-      title: options.title,
-      // By default toolbars are visible when add-on is installed, unless
-      // add-on authors decides it should be hidden. From that point on
-      // user is in control.
-      collapsed: !!options.hidden,
-      // In terms of state only identifiers of items matter.
-      items: items.map(identify)
-    };
-
-    this.id = id;
-    this.items = items;
-
-    toolbars.set(id, this);
-    setListeners(this, params);
-
-    // Send initial state to the host so it can reflect it
-    // into a user interface.
-    send(output, object([id, initial]));
-  },
-
-  get title() {
-    const state = reactor.value[this.id];
-    return state && state.title;
-  },
-  get hidden() {
-    const state = reactor.value[this.id];
-    return state && state.collapsed;
-  },
-
-  destroy: function() {
-    send(output, object([this.id, null]));
-  },
-  // `JSON.stringify` serializes objects based of the return
-  // value of this method. For convinienc we provide this method
-  // to serialize actual state data. Note: items will also be
-  // serialized so they should probably implement `toJSON`.
-  toJSON: function() {
-    return {
-      id: this.id,
-      title: this.title,
-      hidden: this.hidden,
-      items: this.items
-    };
-  }
-});
-exports.Toolbar = Toolbar;
-identify.define(Toolbar, toolbar => toolbar.id);
-
-const dispose = toolbar => {
-  toolbars.delete(toolbar.id);
-  emit(toolbar, "detach");
-  off(toolbar);
-};
-
-const reactor = new Reactor({
-  onStep: (present, past) => {
-    const delta = diff(past, present);
-
-    each(([id, update]) => {
-      const toolbar = toolbars.get(id);
-
-      // Remove
-      if (!update)
-        dispose(toolbar);
-      // Add
-      else if (!past[id])
-        emit(toolbar, "attach");
-      // Update
-      else
-        emit(toolbar, update.collapsed ? "hide" : "show", toolbar);
-    }, pairs(delta));
-  }
-});
-reactor.run(input);
deleted file mode 100644
--- a/addon-sdk/source/lib/sdk/ui/toolbar/view.js
+++ /dev/null
@@ -1,248 +0,0 @@
-/* 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";
-
-module.metadata = {
-  "stability": "experimental",
-  "engines": {
-    "Firefox": "> 28"
-  }
-};
-
-const { Cu } = require("chrome");
-const { CustomizableUI } = Cu.import('resource:///modules/CustomizableUI.jsm', {});
-const { subscribe, send, Reactor, foldp, lift, merges } = require("../../event/utils");
-const { InputPort } = require("../../input/system");
-const { OutputPort } = require("../../output/system");
-const { Interactive } = require("../../input/browser");
-const { CustomizationInput } = require("../../input/customizable-ui");
-const { pairs, map, isEmpty, object,
-        each, keys, values } = require("../../util/sequence");
-const { curry, flip } = require("../../lang/functional");
-lazyRequire(this, "diffpatcher/index", "patch", "diff");
-const prefs = require("../../preferences/service");
-lazyRequire(this, "../../window/utils", "getByOuterId");
-lazyRequire(this, '../../private-browsing/utils', "ignoreWindow");
-
-const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-const PREF_ROOT = "extensions.sdk-toolbar-collapsed.";
-
-
-// There are two output ports one for publishing changes that occured
-// and the other for change requests. Later is synchronous and is only
-// consumed here. Note: it needs to be synchronous to avoid race conditions
-// when `collapsed` attribute changes are caused by user interaction and
-// toolbar is destroyed between the ticks.
-const output = new OutputPort({ id: "toolbar-changed" });
-const syncoutput = new OutputPort({ id: "toolbar-change", sync: true });
-
-// Merge disptached changes and recevied changes from models to keep state up to
-// date.
-const Toolbars = foldp(patch, {}, merges([new InputPort({ id: "toolbar-changed" }),
-                                          new InputPort({ id: "toolbar-change" })]));
-const State = lift((toolbars, windows, customizable) =>
-  ({windows: windows, toolbars: toolbars, customizable: customizable}),
-  Toolbars, Interactive, new CustomizationInput());
-
-// Shared event handler that makes `event.target.parent` collapsed.
-// Used as toolbar's close buttons click handler.
-const collapseToolbar = event => {
-  const toolbar = event.target.parentNode;
-  toolbar.collapsed = true;
-};
-
-const parseAttribute = x =>
-  x === "true" ? true :
-  x === "false" ? false :
-  x === "" ? null :
-  x;
-
-// Shared mutation observer that is used to observe `toolbar` node's
-// attribute mutations. Mutations are aggregated in the `delta` hash
-// and send to `ToolbarStateChanged` channel to let model know state
-// has changed.
-const attributesChanged = mutations => {
-  const delta = mutations.reduce((changes, {attributeName, target}) => {
-    const id = target.id;
-    const field = attributeName === "toolbarname" ? "title" : attributeName;
-    let change = changes[id] || (changes[id] = {});
-    change[field] = parseAttribute(target.getAttribute(attributeName));
-    return changes;
-  }, {});
-
-  // Calculate what are the updates from the current state and if there are
-  // any send them.
-  const updates = diff(reactor.value, patch(reactor.value, delta));
-
-  if (!isEmpty(pairs(updates))) {
-    // TODO: Consider sending sync to make sure that there won't be a new
-    // update doing a delete in the meantime.
-    send(syncoutput, updates);
-  }
-};
-
-
-// Utility function creates `toolbar` with a "close" button and returns
-// it back. In addition it set's up a listener and observer to communicate
-// state changes.
-const addView = curry((options, {document, window}) => {
-  if (ignoreWindow(window))
-    return;
-
-  let view = document.createElementNS(XUL_NS, "toolbar");
-  view.setAttribute("id", options.id);
-  view.setAttribute("collapsed", options.collapsed);
-  view.setAttribute("toolbarname", options.title);
-  view.setAttribute("pack", "end");
-  view.setAttribute("customizable", "false");
-  view.setAttribute("style", "padding: 2px 0; max-height: 40px;");
-  view.setAttribute("mode", "icons");
-  view.setAttribute("iconsize", "small");
-  view.setAttribute("context", "toolbar-context-menu");
-  view.setAttribute("class", "chromeclass-toolbar");
-
-  let label = document.createElementNS(XUL_NS, "label");
-  label.setAttribute("value", options.title);
-  label.setAttribute("collapsed", "true");
-  view.appendChild(label);
-
-  let closeButton = document.createElementNS(XUL_NS, "toolbarbutton");
-  closeButton.setAttribute("id", "close-" + options.id);
-  closeButton.setAttribute("class", "close-icon");
-  closeButton.setAttribute("customizable", false);
-  closeButton.addEventListener("command", collapseToolbar);
-
-  view.appendChild(closeButton);
-
-  // In order to have a close button not costumizable, aligned on the right,
-  // leaving the customizable capabilities of Australis, we need to create
-  // a toolbar inside a toolbar.
-  // This is should be a temporary hack, we should have a proper XBL for toolbar
-  // instead. See:
-  // https://bugzilla.mozilla.org/show_bug.cgi?id=982005
-  let toolbar = document.createElementNS(XUL_NS, "toolbar");
-  toolbar.setAttribute("id", "inner-" + options.id);
-  toolbar.setAttribute("defaultset", options.items.join(","));
-  toolbar.setAttribute("customizable", "true");
-  toolbar.setAttribute("style", "-moz-appearance: none; overflow: hidden; border: 0;");
-  toolbar.setAttribute("mode", "icons");
-  toolbar.setAttribute("iconsize", "small");
-  toolbar.setAttribute("context", "toolbar-context-menu");
-  toolbar.setAttribute("flex", "1");
-
-  view.insertBefore(toolbar, closeButton);
-
-  const observer = new document.defaultView.MutationObserver(attributesChanged);
-  observer.observe(view, { attributes: true,
-                           attributeFilter: ["collapsed", "toolbarname"] });
-
-  const toolbox = document.getElementById("navigator-toolbox");
-  toolbox.appendChild(view);
-});
-const viewAdd = curry(flip(addView));
-
-const removeView = curry((id, {document}) => {
-  const view = document.getElementById(id);
-  if (view) view.remove();
-});
-
-const updateView = curry((id, {title, collapsed, isCustomizing}, {document}) => {
-  const view = document.getElementById(id);
-
-  if (!view)
-    return;
-
-  if (title)
-    view.setAttribute("toolbarname", title);
-
-  if (collapsed !== void(0))
-    view.setAttribute("collapsed", Boolean(collapsed));
-
-  if (isCustomizing !== void(0)) {
-    view.querySelector("label").collapsed = !isCustomizing;
-    view.querySelector("toolbar").style.visibility = isCustomizing
-                                                ? "hidden" : "visible";
-  }
-});
-
-const viewUpdate = curry(flip(updateView));
-
-// Utility function used to register toolbar into CustomizableUI.
-const registerToolbar = state => {
-  // If it's first additon register toolbar as customizableUI component.
-  CustomizableUI.registerArea("inner-" + state.id, {
-    type: CustomizableUI.TYPE_TOOLBAR,
-    legacy: true,
-    defaultPlacements: [...state.items]
-  });
-};
-// Utility function used to unregister toolbar from the CustomizableUI.
-const unregisterToolbar = CustomizableUI.unregisterArea;
-
-const reactor = new Reactor({
-  onStep: (present, past) => {
-    const delta = diff(past, present);
-
-    each(([id, update]) => {
-      // If update is `null` toolbar is removed, in such case
-      // we unregister toolbar and remove it from each window
-      // it was added to.
-      if (update === null) {
-        unregisterToolbar("inner-" + id);
-        each(removeView(id), values(past.windows));
-
-        send(output, object([id, null]));
-      }
-      else if (past.toolbars[id]) {
-        // If `collapsed` state for toolbar was updated, persist
-        // it for a future sessions.
-        if (update.collapsed !== void(0))
-          prefs.set(PREF_ROOT + id, update.collapsed);
-
-        // Reflect update in each window it was added to.
-        each(updateView(id, update), values(past.windows));
-
-        send(output, object([id, update]));
-      }
-      // Hack: Mutation observers are invoked async, which means that if
-      // client does `hide(toolbar)` & then `toolbar.destroy()` by the
-      // time we'll get update for `collapsed` toolbar will be removed.
-      // For now we check if `update.id` is present which will be undefined
-      // in such cases.
-      else if (update.id) {
-        // If it is a new toolbar we create initial state by overriding
-        // `collapsed` filed with value persisted in previous sessions.
-        const state = patch(update, {
-          collapsed: prefs.get(PREF_ROOT + id, update.collapsed),
-        });
-
-        // Register toolbar and add it each window known in the past
-        // (note that new windows if any will be handled in loop below).
-        registerToolbar(state);
-        each(addView(state), values(past.windows));
-
-        send(output, object([state.id, state]));
-      }
-    }, pairs(delta.toolbars));
-
-    // Add views to every window that was added.
-    each(window => {
-      if (window)
-        each(viewAdd(window), values(past.toolbars));
-    }, values(delta.windows));
-
-    each(([id, isCustomizing]) => {
-      each(viewUpdate(getByOuterId(id), {isCustomizing: !!isCustomizing}),
-        keys(present.toolbars));
-
-    }, pairs(delta.customizable))
-  },
-  onEnd: state => {
-    each(id => {
-      unregisterToolbar("inner-" + id);
-      each(removeView(id), values(state.windows));
-    }, keys(state.toolbars));
-  }
-});
-reactor.run(State);