Bug 1313429 - Add Touch Bar functionality to Firefox r=spohl,mikedeboer,flod
authorHarry Twyford <harry.a.twyford@gmail.com>
Tue, 22 Jan 2019 17:13:33 +0000
changeset 514848 099f631b90046b102aa1868455f03b7f9942eaba
parent 514847 b4f6235387606ef6fbf72556f25e46b20816903f
child 514849 3c892082191daa8abe20a3a6c96ad0b2658c3ab9
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersspohl, mikedeboer, flod
bugs1313429
milestone66.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1313429 - Add Touch Bar functionality to Firefox r=spohl,mikedeboer,flod Adds Touch Bar functionality to Firefox across eight commits. Differential Revision: https://phabricator.services.mozilla.com/D5496
browser/base/content/browser-places.js
browser/base/content/browser.js
browser/base/content/test/static/browser_all_files_referenced.js
browser/components/moz.build
browser/components/touchbar/MacTouchBar.js
browser/components/touchbar/MacTouchBar.manifest
browser/components/touchbar/moz.build
browser/components/touchbar/tests/.eslintrc.js
browser/components/touchbar/tests/browser/browser.ini
browser/components/touchbar/tests/browser/browser_touchbar_tests.js
browser/components/touchbar/tests/browser/readerModeArticle.html
browser/installer/package-manifest.in
browser/locales/en-US/browser/touchbar/touchbar.ftl
browser/modules/ReaderParent.jsm
modules/libpref/init/all.js
python/mozbuild/mozpack/packager/formats.py
toolkit/components/telemetry/Histograms.json
toolkit/library/moz.build
widget/cocoa/moz.build
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/cocoa/nsTouchBar.h
widget/cocoa/nsTouchBar.mm
widget/cocoa/nsTouchBarUpdater.h
widget/cocoa/nsTouchBarUpdater.mm
widget/cocoa/nsWidgetFactory.mm
widget/cocoa/touchbar/back.pdf
widget/cocoa/touchbar/bookmark-filled.pdf
widget/cocoa/touchbar/bookmark.pdf
widget/cocoa/touchbar/forward.pdf
widget/cocoa/touchbar/fullscreen.pdf
widget/cocoa/touchbar/home.pdf
widget/cocoa/touchbar/new.pdf
widget/cocoa/touchbar/private-browsing.pdf
widget/cocoa/touchbar/reader-mode.pdf
widget/cocoa/touchbar/refresh.pdf
widget/cocoa/touchbar/search.pdf
widget/cocoa/touchbar/share.pdf
widget/cocoa/touchbar/sidebar-left.pdf
widget/cocoa/touchbar/sidebar-right.pdf
widget/moz.build
widget/nsITouchBarHelper.idl
widget/nsITouchBarInput.idl
widget/nsITouchBarUpdater.idl
widget/nsWidgetsCID.h
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -1483,18 +1483,20 @@ var BookmarkingUI = {
       document.getElementById("pageAction-panel-bookmark"),
     ]) {
       if (!element) {
         // The page action panel element may not have been created yet.
         continue;
       }
       if (starred) {
         element.setAttribute("starred", "true");
+        Services.obs.notifyObservers(null, "bookmark-icon-updated", "starred");
       } else {
         element.removeAttribute("starred");
+        Services.obs.notifyObservers(null, "bookmark-icon-updated", "unstarred");
       }
     }
 
     // Update the tooltip for elements that require it.
     for (let element of [
       this.star,
       document.getElementById("context-bookmarkpage"),
     ]) {
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -4822,16 +4822,17 @@ var XULBrowserWindow = {
         gCustomizeMode.enter();
       } else if (CustomizationHandler.isEnteringCustomizeMode ||
                  CustomizationHandler.isCustomizing()) {
         gCustomizeMode.exit();
       }
 
       CFRPageActions.updatePageActions(gBrowser.selectedBrowser);
     }
+    Services.obs.notifyObservers(null, "touchbar-location-change", location);
     UpdateBackForwardCommands(gBrowser.webNavigation);
     ReaderParent.updateReaderButton(gBrowser.selectedBrowser);
 
     if (!gMultiProcessBrowser) // Bug 1108553 - Cannot rotate images with e10s
       gGestureSupport.restoreRotationState();
 
     // See bug 358202, when tabs are switched during a drag operation,
     // timers don't fire on windows (bug 203573)
--- a/browser/base/content/test/static/browser_all_files_referenced.js
+++ b/browser/base/content/test/static/browser_all_files_referenced.js
@@ -43,18 +43,20 @@ var gExceptionPaths = [
   "resource://search-plugins/",
 
   // This is only in Nightly, and accessed using a direct chrome URL
   "chrome://browser/content/aboutconfig/",
 ];
 
 // These are not part of the omni.ja file, so we find them only when running
 // the test on a non-packaged build.
-if (AppConstants.platform == "macosx")
+if (AppConstants.platform == "macosx") {
   gExceptionPaths.push("resource://gre/res/cursors/");
+  gExceptionPaths.push("resource://gre/res/touchbar/");
+}
 
 var whitelist = [
   // browser/extensions/pdfjs/content/PdfStreamConverter.jsm
   {file: "chrome://pdf.js/locale/chrome.properties"},
   {file: "chrome://pdf.js/locale/viewer.properties"},
 
   // security/manager/pki/resources/content/device_manager.js
   {file: "chrome://pippki/content/load_device.xul"},
--- a/browser/components/moz.build
+++ b/browser/components/moz.build
@@ -60,16 +60,19 @@ DIRS += [
 DIRS += ['build']
 
 if CONFIG['NIGHTLY_BUILD']:
     DIRS += [
         'aboutconfig',
         'payments',
     ]
 
+if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
+    DIRS += ['touchbar']
+
 XPIDL_SOURCES += [
     'nsIBrowserHandler.idl',
 ]
 
 XPIDL_MODULE = 'browsercompsbase'
 
 EXTRA_COMPONENTS += [
     'BrowserComponents.manifest',
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/MacTouchBar.js
@@ -0,0 +1,405 @@
+/* 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/. */
+
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+  BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
+  PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
+  Services: "resource://gre/modules/Services.jsm",
+  AppConstants: "resource://gre/modules/AppConstants.jsm",
+  Localization: "resource://gre/modules/Localization.jsm",
+});
+
+/**
+ * Executes a XUL command on the top window. Called by the callbacks in each
+ * TouchBarInput.
+ * @param {string} commandName
+ *        A XUL command.
+ * @param {string} telemetryKey
+ *        A string describing the command, sent for telemetry purposes.
+ *        Intended to be shorter and more readable than the XUL command.
+ */
+function execCommand(commandName, telemetryKey) {
+  let win = BrowserWindowTracker.getTopWindow();
+  let command = win.document.getElementById(commandName);
+  if (command) {
+    command.doCommand();
+  }
+  let telemetry = Services.telemetry.getHistogramById("TOUCHBAR_BUTTON_PRESSES");
+  telemetry.add(telemetryKey);
+}
+
+/**
+ * Static helper function to convert a hexadecimal string to its integer
+ * value. Used to convert colours to a format accepted by Apple's NSColor code.
+ * @param {string} hexString
+ *        A hexadecimal string, optionally beginning with '#'.
+ */
+function hexToInt(hexString) {
+  if (!hexString) {
+    return null;
+  }
+  if (hexString.charAt(0) == "#") {
+    hexString = hexString.slice(1);
+  }
+  let val = parseInt(hexString, 16);
+  return isNaN(val) ? null : val;
+}
+
+/**
+ * An object containing all implemented TouchBarInput objects.
+ */
+const kBuiltInInputs = {
+  Back: {
+    title: "back",
+    image: "back.pdf",
+    type: "button",
+    callback: () => execCommand("Browser:Back", "Back"),
+  },
+  Forward: {
+    title: "forward",
+    image: "forward.pdf",
+    type: "button",
+    callback: () => execCommand("Browser:Forward", "Forward"),
+  },
+  Reload: {
+    title: "reload",
+    image: "refresh.pdf",
+    type: "button",
+    callback: () => execCommand("Browser:Reload", "Reload"),
+  },
+  Home: {
+    title: "home",
+    image: "home.pdf",
+    type: "button",
+    callback: () => execCommand("Browser:Home", "Home"),
+  },
+  Fullscreen: {
+    title: "fullscreen",
+    image: "fullscreen.pdf",
+    type: "button",
+    callback: () => execCommand("View:FullScreen", "Fullscreen"),
+  },
+  Find: {
+    title: "find",
+    image: "search.pdf",
+    type: "button",
+    callback: () => execCommand("cmd_find", "Find"),
+  },
+  NewTab: {
+    title: "new-tab",
+    image: "new.pdf",
+    type: "button",
+    callback: () => execCommand("cmd_newNavigatorTabNoEvent", "NewTab"),
+  },
+  Sidebar: {
+    title: "open-bookmarks-sidebar",
+    image: "sidebar-left.pdf",
+    type: "button",
+    callback: () => execCommand("viewBookmarksSidebar", "Sidebar"),
+  },
+  AddBookmark: {
+    title: "add-bookmark",
+    image: "bookmark.pdf",
+    type: "button",
+    callback: () => execCommand("Browser:AddBookmarkAs", "AddBookmark"),
+  },
+  ReaderView: {
+    title: "reader-view",
+    image: "reader-mode.pdf",
+    type: "button",
+    callback: () => execCommand("View:ReaderView", "ReaderView"),
+    disabled: true,  // Updated when the page is found to be Reader View-able.
+  },
+  OpenLocation: {
+    title: "open-location",
+    image: "search.pdf",
+    type: "mainButton",
+    callback: () => execCommand("Browser:OpenLocation", "OpenLocation"),
+  },
+  Focus: {
+    title: "focus",
+    image: "private-browsing.pdf",
+    type: "mainButton",
+    callback: () => execCommand("cmd_closeWindow", "Focus"),
+    color: "#8000D7",
+    context: () => {
+      let name;
+      if (PrivateBrowsingUtils.isWindowPrivate(BrowserWindowTracker.getTopWindow())) {
+        name = "Focus";
+      }
+      return name;
+    },
+  },
+  OpenOrFocus: {
+    // This input is just a forwarder to other inputs.
+    context: () => {
+      let name;
+      if (PrivateBrowsingUtils.isWindowPrivate(BrowserWindowTracker.getTopWindow())) {
+        name = "Focus";
+      } else {
+        name = "OpenLocation";
+      }
+      return name;
+    },
+  },
+  // This is a special-case `type: "scrubber"` element.
+  // Scrubbers are not yet generally implemented.
+  // See follow-up bug 1502539.
+  Share: {
+    title: "share",
+    type: "scrubber",
+    image: "share.pdf",
+    callback: () => execCommand("cmd_share", "Share"),
+  },
+};
+
+const kHelperObservers = new Set(["bookmark-icon-updated", "reader-mode-available",
+  "touchbar-location-change", "quit-application", "intl:app-locales-changed"]);
+
+/**
+ * JS-implemented TouchBarHelper class.
+ * Provides services to the Mac Touch Bar.
+ */
+class TouchBarHelper {
+  constructor() {
+    for (let topic of kHelperObservers) {
+      Services.obs.addObserver(this, topic);
+    }
+
+    XPCOMUtils.defineLazyPreferenceGetter(this, "_touchBarLayout",
+      "ui.touchbar.layout", "Back,Reload,OpenOrFocus,AddBookmark,NewTab,Share");
+  }
+
+  destructor() {
+    for (let topic of kHelperObservers) {
+      Services.obs.removeObserver(this, topic);
+    }
+  }
+
+  get activeTitle() {
+    let tabbrowser = this.window.ownerGlobal.gBrowser;
+    let activeTitle;
+    if (tabbrowser) {
+      activeTitle = tabbrowser.selectedBrowser.contentTitle;
+    }
+    return activeTitle;
+  }
+
+  get layout() {
+    let prefArray = this.storedLayout;
+    let layoutItems = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+
+    for (let inputName of prefArray) {
+      if (typeof kBuiltInInputs[inputName].context == "function") {
+        inputName = kBuiltInInputs[inputName].context();
+      }
+      let input = this.getTouchBarInput(inputName);
+      if (!input) {
+        continue;
+      }
+      layoutItems.appendElement(input);
+    }
+
+    return layoutItems;
+  }
+
+  get window() {
+    return BrowserWindowTracker.getTopWindow();
+  }
+
+  get bookmarkingUI() {
+    return this.window.BookmarkingUI;
+  }
+
+  /**
+   * Returns a string array of the user's Touch Bar layout preference.
+   * Set by a pref ui.touchbar.layout and returned in an array.
+   */
+  get storedLayout() {
+    let prefArray = this._touchBarLayout.split(",");
+    prefArray = prefArray.map(str => str.trim());
+    // Remove duplicates.
+    prefArray = Array.from(new Set(prefArray));
+
+    // Remove unimplemented/mispelled inputs.
+    prefArray = prefArray.filter(input =>
+      Object.keys(kBuiltInInputs).includes(input));
+    this._storedLayout = prefArray;
+    return this._storedLayout;
+  }
+
+  getTouchBarInput(inputName) {
+    if (typeof kBuiltInInputs[inputName].context == "function") {
+      inputName = kBuiltInInputs[inputName].context();
+    }
+
+    let inputData = kBuiltInInputs[inputName];
+
+    if (!inputData) {
+      return null;
+    }
+
+    let item = new TouchBarInput(inputData);
+
+    // Async l10n fills in the localized input labels after the initial load.
+    this._l10n.formatValue(item.key).then((result) => {
+      item.title = result;
+      kBuiltInInputs[inputName].localTitle = result; // Cache result.
+      // Checking this.window since this callback can fire after all windows are closed.
+      if (this.window) {
+        let baseWindow = this.window.docShell.treeOwner.QueryInterface(Ci.nsIBaseWindow);
+        let updater = Cc["@mozilla.org/widget/touchbarupdater;1"]
+                        .getService(Ci.nsITouchBarUpdater);
+        updater.updateTouchBarInput(baseWindow, item);
+      }
+    });
+
+    return item;
+  }
+
+  /**
+   * Fetches a specific Touch Bar Input by name and updates it on the Touch Bar.
+   * @param {string} inputName
+   *        A key to a value in the kBuiltInInputs object in this file.
+   */
+  _updateTouchBarInput(inputName) {
+    let input = this.getTouchBarInput(inputName);
+    if (!input || !this.window) {
+      return;
+    }
+
+    let baseWindow = this.window.docShell.treeOwner.QueryInterface(Ci.nsIBaseWindow);
+    let updater = Cc["@mozilla.org/widget/touchbarupdater;1"]
+                    .getService(Ci.nsITouchBarUpdater);
+    updater.updateTouchBarInput(baseWindow, input);
+  }
+
+  observe(subject, topic, data) {
+    switch (topic) {
+      case "touchbar-location-change":
+        this.activeUrl = data;
+        if (data.startsWith("about:reader")) {
+          kBuiltInInputs.ReaderView.disabled = false;
+          this._updateTouchBarInput("ReaderView");
+        } else {
+          // ReaderView button is disabled on every location change since
+          // Reader View must determine if the new page can be Reader Viewed.
+          kBuiltInInputs.ReaderView.disabled = true;
+          this._updateTouchBarInput("ReaderView");
+        }
+        break;
+      case "bookmark-icon-updated":
+        data == "starred" ?
+          kBuiltInInputs.AddBookmark.image = "bookmark-filled.pdf"
+          : kBuiltInInputs.AddBookmark.image = "bookmark.pdf";
+        this._updateTouchBarInput("AddBookmark");
+        break;
+      case "reader-mode-available":
+        kBuiltInInputs.ReaderView.disabled = false;
+        this._updateTouchBarInput("ReaderView");
+        break;
+      case "intl:app-locales-changed":
+        // On locale change, refresh all inputs after loading new localTitle.
+        for (let inputName of this._storedLayout) {
+          delete kBuiltInInputs[inputName].localTitle;
+          this._updateTouchBarInput(inputName);
+        }
+      case "quit-application":
+        this.destructor();
+        break;
+    }
+  }
+}
+
+const helperProto = TouchBarHelper.prototype;
+helperProto.classDescription = "Services the Mac Touch Bar";
+helperProto.classID = Components.ID("{ea109912-3acc-48de-b679-c23b6a122da5}");
+helperProto.contractID = "@mozilla.org/widget/touchbarhelper;1";
+helperProto.QueryInterface = ChromeUtils.generateQI([Ci.nsITouchBarHelper]);
+helperProto._l10n = new Localization(["browser/touchbar/touchbar.ftl"]);
+
+/**
+ * A representation of a Touch Bar input.
+ * Uses async update() in lieu of a constructor to accomodate async l10n code.
+ *     @param {object} input
+ *            An object representing a Touch Bar Input.
+ *            Contains listed properties.
+ *     @param {string} input.title
+ *            The lookup key for the button's localized text title.
+ *     @param {string} input.image
+ *            The name of a icon file added to
+ *            /widget/cocoa/resources/touchbar_icons.
+ *     @param {string} input.type
+ *            The type of Touch Bar input represented by the object.
+ *            One of `button`, `mainButton`.
+ *     @param {Function} input.callback
+ *            A callback invoked when a touchbar item is touched.
+ *     @param {string} input.color (optional)
+ *            A string in hex format specifying the button's background color.
+ *            If omitted, the default background color is used.
+ *     @param {bool} input.disabled (optional)
+ *            If `true`, the Touch Bar input is greyed out and inoperable.
+ */
+class TouchBarInput {
+  constructor(input) {
+    this._key = input.title;
+    this._title = input.hasOwnProperty("localTitle") ? input.localTitle : "";
+    this._image = input.image;
+    this._type = input.type;
+    this._callback = input.callback;
+    this._color = hexToInt(input.color);
+    this._disabled = input.hasOwnProperty("disabled") ? input.disabled : false;
+  }
+
+  get key() {
+    return this._key;
+  }
+  get title() {
+    return this._title;
+  }
+  set title(title) {
+    this._title = title;
+  }
+  get image() {
+    return this._image;
+  }
+  set image(image) {
+    this._image = image;
+  }
+  get type() {
+    return this._type == "" ? "button" : this._type;
+  }
+  set type(type) {
+    this._type = type;
+  }
+  get callback() {
+    return this._callback;
+  }
+  set callback(callback) {
+    this._callback = callback;
+  }
+  get color() {
+    return this._color;
+  }
+  set color(color) {
+    this._color = this.hexToInt(color);
+  }
+  get disabled() {
+    return this._disabled || false;
+  }
+  set disabled(disabled) {
+    this._disabled = disabled;
+  }
+}
+
+const inputProto = TouchBarInput.prototype;
+inputProto.classDescription = "Represents an input on the Mac Touch Bar";
+inputProto.classID = Components.ID("{77441d17-f29c-49d7-982f-f20a5ab5a900}");
+inputProto.contractID = "@mozilla.org/widget/touchbarinput;1";
+inputProto.QueryInterface = ChromeUtils.generateQI([Ci.nsITouchBarInput]);
+
+this.NSGetFactory =
+  XPCOMUtils.generateNSGetFactory([TouchBarHelper, TouchBarInput]);
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/MacTouchBar.manifest
@@ -0,0 +1,9 @@
+# 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/. */
+
+component {ea109912-3acc-48de-b679-c23b6a122da5} MacTouchBar.js
+contract @mozilla.org/widget/touchbarhelper;1 {ea109912-3acc-48de-b679-c23b6a122da5}
+
+component {77441d17-f29c-49d7-982f-f20a5ab5a900} MacTouchBar.js
+contract @mozilla.org/widget/touchbarinput;1 {77441d17-f29c-49d7-982f-f20a5ab5a900}
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/moz.build
@@ -0,0 +1,13 @@
+# 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/.
+
+with Files('**'):
+    BUG_COMPONENT = ('Core', 'Widget: Cocoa')
+
+BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
+
+EXTRA_COMPONENTS += [
+    'MacTouchBar.js',
+    'MacTouchBar.manifest',
+]
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/tests/.eslintrc.js
@@ -0,0 +1,11 @@
+/* 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.exports = {
+  "extends": [
+    "plugin:mozilla/browser-test"
+  ]
+}
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/tests/browser/browser.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+support-files =
+  readerModeArticle.html
+
+[browser_touchbar_tests.js]
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/tests/browser/browser_touchbar_tests.js
@@ -0,0 +1,91 @@
+/* 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 PREF_NAME = "ui.touchbar.layout";
+
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "TouchBarHelper",
+                                   "@mozilla.org/widget/touchbarhelper;1",
+                                   "nsITouchBarHelper");
+XPCOMUtils.defineLazyServiceGetter(this, "TouchBarInput",
+                                   "@mozilla.org/widget/touchbarinput;1",
+                                   "nsITouchBarInput");
+
+function is_element_visible(aElement, aMsg) {
+  isnot(aElement, null, "Element should not be null when checking visibility");
+  ok(!BrowserTestUtils.is_hidden(aElement), aMsg);
+}
+
+function is_element_hidden(aElement, aMsg) {
+  isnot(aElement, null, "Element should not be null when checking visibility");
+  ok(BrowserTestUtils.is_hidden(aElement), aMsg);
+}
+
+/**
+ * Sets the pref to contain errors. .layout should contain only the
+ * non-erroneous elements.
+ */
+add_task(async function setWrongPref() {
+  registerCleanupFunction(function() {
+    Services.prefs.deleteBranch(PREF_NAME);
+  });
+
+  let wrongValue   = "Back, Back, Forwrd, NewTab, Unimplemented,";
+  let correctValue = ["back", "new-tab"];
+  let testValue = [];
+  Services.prefs.setStringPref(PREF_NAME, wrongValue);
+
+  let layoutItems = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+  layoutItems = TouchBarHelper.layout;
+  for (let i = 0; i < layoutItems.length; i++) {
+    let input = layoutItems.queryElementAt(i, Ci.nsITouchBarInput);
+    testValue.push(input.key);
+  }
+  Assert.equal(testValue.toString(),
+               correctValue.toString(),
+               "Pref should filter out incorrect inputs.");
+});
+
+/**
+ * Tests if our bookmark button updates with our event.
+ */
+add_task(async function updateBookmarkButton() {
+  Services.obs.notifyObservers(null, "bookmark-icon-updated", "starred");
+  Assert.equal(TouchBarHelper.getTouchBarInput("AddBookmark").image,
+    "bookmark-filled.pdf",
+    "AddBookmark image should be filled bookmark after event.");
+
+  Services.obs.notifyObservers(null, "bookmark-icon-updated", "unstarred");
+  Assert.equal(TouchBarHelper.getTouchBarInput("AddBookmark").image,
+    "bookmark.pdf",
+    "AddBookmark image should be unfilled bookmark after event.");
+});
+
+/**
+ * Tests if our Reader View button updates when a page can be reader viewed.
+ */
+add_task(async function updateReaderView() {
+  const PREF_READERMODE = "reader.parse-on-load.enabled";
+  await SpecialPowers.pushPrefEnv({set: [[PREF_READERMODE, true]]});
+
+  // The page actions reader mode button
+  var readerButton = document.getElementById("reader-mode-button");
+  is_element_hidden(readerButton, "Reader Mode button should be hidden.");
+
+  Assert.equal(TouchBarHelper.getTouchBarInput("ReaderView").disabled,
+    true,
+    "ReaderView Touch Bar button should be disabled by default.");
+
+  const TEST_PATH = getRootDirectory(gTestPath)
+  .replace("chrome://mochitests/content", "http://example.com");
+  let url = TEST_PATH + "readerModeArticle.html";
+  await BrowserTestUtils.withNewTab(url, async function() {
+    await BrowserTestUtils.waitForCondition(() => !readerButton.hidden);
+
+    Assert.equal(TouchBarHelper.getTouchBarInput("ReaderView").disabled, false,
+      "ReaderView Touch Bar button should be enabled on reader-able pages.");
+  });
+});
new file mode 100644
--- /dev/null
+++ b/browser/components/touchbar/tests/browser/readerModeArticle.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>Article title</title>
+<meta name="description" content="This is the article description." />
+</head>
+<body>
+<header>Site header</header>
+<div>
+<h1>Article title</h1>
+<ul>
+  <li><a id="foo-anchor" href="#foo">by John Doe</a></li>
+</ul>
+<h2 class="author">by Jane Doe</h2>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p id="foo">by John Doe</p>
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur. Donec ut libero sed arcu vehicula ultricies a non tortor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ut gravida lorem. Ut turpis felis, pulvinar a semper sed, adipiscing id dolor. Pellentesque auctor nisi id magna consequat sagittis. Curabitur dapibus enim sit amet elit pharetra tincidunt feugiat nisl imperdiet. Ut convallis libero in urna ultrices accumsan. Donec sed odio eros. Donec viverra mi quis quam pulvinar at malesuada arcu rhoncus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. In rutrum accumsan ultricies. Mauris vitae nisi at sem facilisis semper ac in est.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+<p>Vivamus fermentum semper porta. Nunc diam velit, adipiscing ut tristique vitae, sagittis vel odio. Maecenas convallis ullamcorper ultricies. Curabitur ornare, ligula semper consectetur sagittis, nisi diam iaculis velit, id fringilla sem nunc vel mi. Nam dictum, odio nec pretium volutpat, arcu ante placerat erat, non tristique elit urna et turpis. Quisque mi metus, ornare sit amet fermentum et, tincidunt et orci. Fusce eget orci a orci congue vestibulum. Ut dolor diam, elementum et vestibulum eu, porttitor vel elit. Curabitur venenatis pulvinar tellus gravida ornare. Sed et erat faucibus nunc euismod ultricies ut id justo. Nullam cursus suscipit nisi, et ultrices justo sodales nec. Fusce venenatis facilisis lectus ac semper. Aliquam at massa ipsum. Quisque bibendum purus convallis nulla ultrices ultricies. Nullam aliquam, mi eu aliquam tincidunt, purus velit laoreet tortor, viverra pretium nisi quam vitae mi. Fusce vel volutpat elit. Nam sagittis nisi dui.</p>
+</div>
+</body>
+</html>
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -272,16 +272,18 @@
 @RESPATH@/browser/components/FirefoxProfileMigrator.js
 #ifdef XP_WIN
 @RESPATH@/browser/components/360seProfileMigrator.js
 @RESPATH@/browser/components/EdgeProfileMigrator.js
 @RESPATH@/browser/components/IEProfileMigrator.js
 #endif
 #ifdef XP_MACOSX
 @RESPATH@/browser/components/SafariProfileMigrator.js
+@RESPATH@/browser/components/MacTouchBar.manifest
+@RESPATH@/browser/components/MacTouchBar.js
 #endif
 @RESPATH@/components/nsPrompter.manifest
 @RESPATH@/components/nsPrompter.js
 @RESPATH@/components/SyncComponents.manifest
 @RESPATH@/components/Weave.js
 @RESPATH@/components/FxAccountsComponents.manifest
 @RESPATH@/components/FxAccountsPush.js
 @RESPATH@/components/CaptivePortalDetectComponents.manifest
@@ -479,16 +481,17 @@
 @RESPATH@/res/table-remove-column-hover.gif
 @RESPATH@/res/table-remove-column.gif
 @RESPATH@/res/table-remove-row-active.gif
 @RESPATH@/res/table-remove-row-hover.gif
 @RESPATH@/res/table-remove-row.gif
 @RESPATH@/res/grabber.gif
 #ifdef XP_MACOSX
 @RESPATH@/res/cursors/*
+@RESPATH@/res/touchbar/*
 #endif
 @RESPATH@/res/fonts/*
 @RESPATH@/res/dtd/*
 @RESPATH@/res/language.properties
 #ifdef XP_MACOSX
 @RESPATH@/res/MainMenu.nib/
 #endif
 
new file mode 100644
--- /dev/null
+++ b/browser/locales/en-US/browser/touchbar/touchbar.ftl
@@ -0,0 +1,20 @@
+# 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/.
+
+# Strings in this file are used to localize button titles displayed on the 
+# MacBook Touch Bar.
+back = Back
+forward = Forward
+reload = Reload
+home = Home
+fullscreen = Fullscreen
+find = Find
+new-tab = New tab
+add-bookmark = Add bookmark
+open-bookmarks-sidebar = Open Bookmarks Sidebar
+reader-view = Reader View
+# Meant to match the string displayed in an empty URL bar.
+open-location = Search or enter address
+share = Share
+focus = Close
--- a/browser/modules/ReaderParent.jsm
+++ b/browser/modules/ReaderParent.jsm
@@ -73,32 +73,34 @@ var ReaderParent = {
       menuitem.setAttribute("label", closeText);
       menuitem.setAttribute("hidden", false);
       menuitem.setAttribute("accesskey",
         gStringBundle.GetStringFromName("readerView.close.accesskey"));
 
       key.setAttribute("disabled", false);
 
       browser.setAttribute("aria-reader", "active");
+      Services.obs.notifyObservers(null, "reader-mode-available");
     } else {
       let enterText = gStringBundle.GetStringFromName("readerView.enter");
 
       button.removeAttribute("readeractive");
       button.hidden = !browser.isArticle;
       button.setAttribute("aria-label", enterText);
 
       menuitem.setAttribute("label", enterText);
       menuitem.setAttribute("hidden", !browser.isArticle);
       menuitem.setAttribute("accesskey",
         gStringBundle.GetStringFromName("readerView.enter.accesskey"));
 
       key.setAttribute("disabled", !browser.isArticle);
 
       if (browser.isArticle) {
         browser.setAttribute("aria-reader", "available");
+        Services.obs.notifyObservers(null, "reader-mode-available");
       } else {
         browser.removeAttribute("aria-reader");
       }
     }
   },
 
   forceShowReaderIcon(browser) {
     browser.isArticle = true;
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -280,16 +280,20 @@ pref("ui.click_hold_context_menus", fals
 // Pop up context menu on mouseup instead of mousedown, if that's the OS default.
 // Note: ignored on Windows (context menus always use mouseup)
 pref("ui.context_menus.after_mouseup", false);
 // Duration of timeout of incremental search in menus (ms).  0 means infinite.
 pref("ui.menu.incremental_search.timeout", 1000);
 // If true, all popups won't hide automatically on blur
 pref("ui.popup.disable_autohide", false);
 
+#ifdef XP_MACOSX
+pref("ui.touchbar.layout", "Back,Reload,OpenOrFocus,AddBookmark,NewTab,Share");
+#endif
+
 pref("browser.display.use_document_fonts",  1);  // 0 = never, 1 = quick, 2 = always
 // 0 = default: always, except in high contrast mode
 // 1 = always
 // 2 = never
 pref("browser.display.document_color_use", 0);
 pref("browser.display.use_system_colors",   false);
 pref("browser.display.foreground_color",    "#000000");
 pref("browser.display.background_color",    "#FFFFFF");
--- a/python/mozbuild/mozpack/packager/formats.py
+++ b/python/mozbuild/mozpack/packager/formats.py
@@ -315,17 +315,19 @@ class OmniJarSubFormatter(PiecemealForma
             return False
         path = mozpath.split(path)
         if path[0] == 'chrome':
             return len(path) == 1 or path[1] != 'icons'
         if path[0] == 'components':
             return path[-1].endswith(('.js', '.xpt'))
         if path[0] == 'res':
             return len(path) == 1 or \
-                (path[1] != 'cursors' and path[1] != 'MainMenu.nib')
+                (path[1] != 'cursors' and \
+                 path[1] != 'touchbar' and \
+                 path[1] != 'MainMenu.nib')
         if path[0] == 'defaults':
             return len(path) != 3 or \
                 not (path[2] == 'channel-prefs.js' and
                      path[1] in ['pref', 'preferences'])
         return path[0] in [
             'modules',
             'actors',
             'dictionaries',
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -14430,16 +14430,26 @@
     "alert_emails": ["kgupta@mozilla.com"],
     "bug_numbers": [1470901],
     "expires_in_version": "never",
     "kind": "exponential",
     "high": 1000,
     "n_buckets": 50,
     "description": "WebRender render time in milliseconds"
   },
+  "TOUCHBAR_BUTTON_PRESSES": {
+    "record_in_processes": ["main"],
+    "alert_emails": ["mdeboer@mozilla.com"],
+    "bug_numbers": [1313429],
+    "expires_in_version": "71",
+    "kind": "categorical",
+    "labels": ["Back", "Forward", "Reload", "Home",  "Fullscreen", "Find", "NewTab", "ReaderView", "AddBookmark", "OpenLocation", "Focus", "Share", "Sidebar"],
+    "releaseChannelCollection": "opt-out",
+    "description": "What buttons are pressed most often on the Mac Touch Bar?"
+  },
   "AUDIO_TRACK_SILENCE_PROPORTION": {
     "record_in_processes": ["main", "content"],
     "alert_emails": [
       "alwu@mozilla.com",
       "cpearce@mozilla.com",
       "nohlmeier@mozilla.com"
     ],
     "expires_in_version": "68",
--- a/toolkit/library/moz.build
+++ b/toolkit/library/moz.build
@@ -69,20 +69,25 @@ def Libxul(name, output_category=None):
             CONFIG['LINKER_KIND'] == 'bfd':
         LDFLAGS += [TOPSRCDIR + '/toolkit/library/StaticXULComponents.ld']
 
     Libxul_defines()
 
     if CONFIG['MOZ_NEEDS_LIBATOMIC']:
         OS_LIBS += ['atomic']
 
-    # This option should go away in bug 1290972, but we need to wait until
-    # Rust 1.12 has been released.
+    # TouchBar-related classes are only available in the 10.12.2 SDK and later.
+    # We need to weak link these classes until we've upgraded our SDK to at
+    # least 10.12.2.
     # We're also linking against libresolv to solve bug 1367932.
     if CONFIG['OS_ARCH'] == 'Darwin':
+        LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSTouchBar']
+        LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSSharingServicePickerTouchBarItem']
+        LDFLAGS += ['-Wl,-U,_OBJC_METACLASS_$_NSTouchBar']
+        LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSCustomTouchBarItem']
         LDFLAGS += ['-lresolv']
 
     if CONFIG['MOZ_DEBUG_SYMBOLS'] and CONFIG['CC_TYPE'] in ('msvc', 'clang-cl'):
         LDFLAGS += ['-NATVIS:%s/toolkit/library/gecko.natvis' % TOPSRCDIR]
     if CONFIG['RUSTC_NATVIS_LDFLAGS']:
         LDFLAGS += CONFIG['RUSTC_NATVIS_LDFLAGS']
 
 Libxul('xul')
--- a/widget/cocoa/moz.build
+++ b/widget/cocoa/moz.build
@@ -49,16 +49,18 @@ UNIFIED_SOURCES += [
     'nsMenuX.mm',
     'nsPrintDialogX.mm',
     'nsPrintSettingsServiceX.mm',
     'nsPrintSettingsX.mm',
     'nsSound.mm',
     'nsStandaloneNativeMenu.mm',
     'nsSystemStatusBarCocoa.mm',
     'nsToolkit.mm',
+    'nsTouchBar.mm',
+    'nsTouchBarUpdater.mm',
     'nsWidgetFactory.mm',
     'nsWindowMap.mm',
     'OSXNotificationCenter.mm',
     'RectTextureImage.mm',
     'ScreenHelperCocoa.mm',
     'SwipeTracker.mm',
     'TextInputHandler.mm',
     'VibrancyManager.mm',
@@ -130,16 +132,33 @@ RESOURCE_FILES.cursors += [
     'cursors/vtIBeam.png',
     'cursors/vtIBeam@2x.png',
     'cursors/zoomIn.png',
     'cursors/zoomIn@2x.png',
     'cursors/zoomOut.png',
     'cursors/zoomOut@2x.png',
 ]
 
+RESOURCE_FILES.touchbar += [
+    'touchbar/back.pdf',
+    'touchbar/bookmark-filled.pdf',
+    'touchbar/bookmark.pdf',
+    'touchbar/forward.pdf',
+    'touchbar/fullscreen.pdf',
+    'touchbar/home.pdf',
+    'touchbar/new.pdf',
+    'touchbar/private-browsing.pdf',
+    'touchbar/reader-mode.pdf',
+    'touchbar/refresh.pdf',
+    'touchbar/search.pdf',
+    'touchbar/share.pdf',
+    'touchbar/sidebar-left.pdf',
+    'touchbar/sidebar-right.pdf',
+]
+
 # These resources go in $(DIST)/bin/res/MainMenu.nib, but we can't use a magic
 # RESOURCE_FILES.MainMenu.nib attribute, since that would put the files in
 # $(DIST)/bin/res/MainMenu/nib. Instead, we call __setattr__ directly to create
 # an attribute with the correct name.
 RESOURCE_FILES.__setattr__('MainMenu.nib', [
     'resources/MainMenu.nib/classes.nib',
     'resources/MainMenu.nib/info.nib',
     'resources/MainMenu.nib/keyedobjects.nib',
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -9,16 +9,17 @@
 #undef DARWIN
 
 #import <Cocoa/Cocoa.h>
 
 #include "mozilla/RefPtr.h"
 #include "nsBaseWidget.h"
 #include "nsPIWidgetCocoa.h"
 #include "nsCocoaUtils.h"
+#include "nsTouchBar.h"
 
 class nsCocoaWindow;
 class nsChildView;
 class nsMenuBarX;
 @class ChildView;
 
 typedef struct _nsCocoaWindowList {
   _nsCocoaWindowList() : prev(nullptr), window(nullptr) {}
@@ -44,16 +45,18 @@ typedef struct _nsCocoaWindowList {
   NSTrackingArea* mTrackingArea;
 
   NSRect mDirtyRect;
 
   BOOL mBeingShown;
   BOOL mDrawTitle;
   BOOL mBrightTitlebarForeground;
   BOOL mUseMenuStyle;
+
+  nsTouchBar* mTouchBar;
 }
 
 - (void)importState:(NSDictionary*)aState;
 - (NSMutableDictionary*)exportState;
 - (void)setDrawsContentsIntoWindowFrame:(BOOL)aState;
 - (BOOL)drawsContentsIntoWindowFrame;
 
 - (void)mouseEntered:(NSEvent*)aEvent;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -2998,16 +2998,23 @@ static NSMutableSet *gSwizzledFrameViewC
 @interface NSImage(ImageCreationWithDrawingHandler)
 + (NSImage *)imageWithSize:(NSSize)size
                    flipped:(BOOL)drawingHandlerShouldBeCalledWithFlippedContext
             drawingHandler:(BOOL (^)(NSRect dstRect))drawingHandler;
 @end
 
 #endif
 
+#if !defined(MAC_OS_X_VERSION_10_12_2) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_2
+@interface NSView(NSTouchBarProvider)
+- (NSTouchBar*)makeTouchBar;
+@end
+#endif
+
 @interface NSView(NSVisualEffectViewSetMaskImage)
 - (void)setMaskImage:(NSImage*)image;
 @end
 
 @interface BaseWindow(Private)
 - (void)removeTrackingArea;
 - (void)cursorUpdated:(NSEvent*)aEvent;
 - (void)updateContentViewSize;
@@ -3099,16 +3106,17 @@ static NSMutableSet *gSwizzledFrameViewC
   mState = nil;
   mDisabledNeedsDisplay = NO;
   mTrackingArea = nil;
   mDirtyRect = NSZeroRect;
   mBeingShown = NO;
   mDrawTitle = NO;
   mBrightTitlebarForeground = NO;
   mUseMenuStyle = NO;
+  mTouchBar = nil;
   [self updateTrackingArea];
 
   return self;
 }
 
 // Returns an autoreleased NSImage.
 static NSImage*
 GetMenuMaskImage()
@@ -3154,16 +3162,22 @@ GetMenuMaskImage()
     // Turn off rounded corner masking.
     NSView* wrapper = [[NSView alloc] initWithFrame:NSZeroRect];
     [self swapOutChildViewWrapper:wrapper];
     [wrapper release];
   }
   mUseMenuStyle = aValue;
 }
 
+- (NSTouchBar*)makeTouchBar
+{
+  mTouchBar = [[nsTouchBar alloc] init];
+  return mTouchBar;
+}
+
 - (void)setBeingShown:(BOOL)aValue
 {
   mBeingShown = aValue;
 }
 
 - (BOOL)isBeingShown
 {
   return mBeingShown;
@@ -3181,16 +3195,17 @@ GetMenuMaskImage()
 
 - (void)enableSetNeedsDisplay
 {
   mDisabledNeedsDisplay = NO;
 }
 
 - (void)dealloc
 {
+  [mTouchBar release];
   [self removeTrackingArea];
   ChildViewMouseTracker::OnDestroyWindow(self);
   [super dealloc];
 }
 
 static const NSString* kStateTitleKey = @"title";
 static const NSString* kStateDrawsContentsIntoWindowFrameKey = @"drawsContentsIntoWindowFrame";
 static const NSString* kStateShowsToolbarButton = @"showsToolbarButton";
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsTouchBar.h
@@ -0,0 +1,178 @@
+/* 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/. */
+
+#ifndef nsTouchBar_h_
+#define nsTouchBar_h_
+
+#import <Cocoa/Cocoa.h>
+
+#include "mozilla/RefPtr.h"
+#include "nsITouchBarHelper.h"
+#include "nsITouchBarInput.h"
+
+#if !defined(MAC_OS_X_VERSION_10_12) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
+@interface NSButton (NewConstructors)
+@property(nonatomic) BOOL imageHugsTitle;
++ (NSButton*)buttonWithTitle:(NSString*)title target:(id)target action:(SEL)action;
+@end
+
+@interface NSColor (DisplayP3Colors)
++ (NSColor*)colorWithDisplayP3Red:(CGFloat)red
+                            green:(CGFloat)green
+                             blue:(CGFloat)blue
+                            alpha:(CGFloat)alpha;
+@end
+#endif
+
+#if !defined(MAC_OS_X_VERSION_10_12_2) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_2
+typedef NSString* NSTouchBarItemIdentifier;
+__attribute__((weak_import)) @interface NSTouchBarItem : NSObject
+- (instancetype)initWithIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
+@end
+
+__attribute__((weak_import)) @interface NSCustomTouchBarItem : NSTouchBarItem
+@property(strong) NSView* view;
+@property(strong) NSString* customizationLabel;
+@end
+
+@protocol NSTouchBarDelegate
+@end
+
+__attribute__((weak_import)) @interface NSTouchBar : NSObject
+@property(strong) NSArray<NSTouchBarItemIdentifier>* defaultItemIdentifiers;
+@property(strong) id<NSTouchBarDelegate> delegate;
+- (NSTouchBarItem*)itemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
+@end
+
+@protocol NSSharingServicePickerTouchBarItemDelegate
+@end
+
+__attribute__((weak_import)) @interface NSSharingServicePickerTouchBarItem : NSTouchBarItem
+@property(strong) id<NSSharingServicePickerTouchBarItemDelegate> delegate;
+@property(strong) NSImage* buttonImage;
+@end
+
+@interface NSButton (TouchBarButton)
+@property(strong) NSColor* bezelColor;
+@end
+#endif
+
+/**
+ * NSObject representation of nsITouchBarInput.
+ */
+@interface TouchBarInput : NSObject {
+  NSString* mKey;
+  NSString* mTitle;
+  NSImage* mImage;
+  NSString* mType;
+  NSColor* mColor;
+  BOOL mDisabled;
+  NSTouchBarItemIdentifier mNativeIdentifier;
+  nsCOMPtr<nsITouchBarInputCallback> mCallback;
+}
+
+- (NSString*)key;
+- (NSString*)title;
+- (NSImage*)image;
+- (NSString*)type;
+- (NSColor*)color;
+- (BOOL)isDisabled;
+- (NSTouchBarItemIdentifier)nativeIdentifier;
+- (nsCOMPtr<nsITouchBarInputCallback>)callback;
+- (void)setKey:(NSString*)aKey;
+- (void)setTitle:(NSString*)aTitle;
+- (void)setImage:(NSImage*)aImage;
+- (void)setType:(NSString*)aType;
+- (void)setColor:(NSColor*)aColor;
+- (void)setDisabled:(BOOL)aDisabled;
+- (void)setNativeIdentifier:(NSString*)aNativeIdentifier;
+- (void)setCallback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback;
+
+- (id)initWithKey:(NSString*)aKey
+            title:(NSString*)aTitle
+            image:(NSString*)aImage
+             type:(NSString*)aType
+         callback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback
+            color:(uint32_t)aColor
+         disabled:(BOOL)aDisabled;
+
+- (TouchBarInput*)initWithXPCOM:(nsCOMPtr<nsITouchBarInput>)aInput;
+
+- (void)dealloc;
+
+@end
+
+/**
+ * Our TouchBar is its own delegate. This is adequate for our purposes,
+ * since the current implementation only defines Touch Bar buttons for the
+ * main Firefox window. If modals and other windows were to have custom
+ * Touch Bar views, each window would have to be a NSTouchBarDelegate so
+ * they could define their own custom sets of buttons.
+ */
+@interface nsTouchBar : NSTouchBar <NSTouchBarDelegate,
+                                    NSSharingServicePickerTouchBarItemDelegate,
+                                    NSSharingServiceDelegate> {
+  /**
+   * Link to the frontend API that determines which buttons appear
+   * in the Touch Bar
+   */
+  nsCOMPtr<nsITouchBarHelper> mTouchBarHelper;
+}
+
+/**
+ * Contains TouchBarInput representations of the inputs currently in
+ * the Touch Bar. Populated in `init` and updated by nsITouchBarUpdater.
+ */
+@property(strong) NSMutableDictionary<NSTouchBarItemIdentifier, TouchBarInput*>* mappedLayoutItems;
+
+/**
+ * Returns an instance of nsTouchBar based on implementation details
+ * fetched from the frontend through nsTouchBarHelper.
+ */
+- (instancetype)init;
+
+- (void)dealloc;
+
+/**
+ * Creates a new NSTouchBarItem and adds it to the Touch Bar.
+ * Reads the passed identifier and creates the
+ * appropriate item type (eg. NSCustomTouchBarItem).
+ * Required as a member of NSTouchBarDelegate.
+ */
+- (NSTouchBarItem*)touchBar:(NSTouchBar*)aTouchBar
+      makeItemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
+
+/**
+ * Updates an input on the Touch Bar by redirecting to one of the specific
+ * TouchBarItem types updaters.
+ */
+- (void)updateItem:(TouchBarInput*)aInput;
+
+/**
+ * Update or create various subclasses of TouchBarItem.
+ */
+- (NSTouchBarItem*)updateButton:(NSCustomTouchBarItem*)aButton input:(TouchBarInput*)aInput;
+- (NSTouchBarItem*)updateMainButton:(NSCustomTouchBarItem*)aMainButton input:(TouchBarInput*)aInput;
+- (NSTouchBarItem*)makeShareScrubberForIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
+
+/**
+ *  Redirects button actions to the appropriate handler and handles telemetry.
+ */
+- (void)touchBarAction:(id)aSender;
+
+- (NSArray*)itemsForSharingServicePickerTouchBarItem:
+    (NSSharingServicePickerTouchBarItem*)aPickerTouchBarItem;
+
+- (NSArray<NSSharingService*>*)sharingServicePicker:(NSSharingServicePicker*)aSharingServicePicker
+                            sharingServicesForItems:(NSArray*)aItems
+                            proposedSharingServices:(NSArray<NSSharingService*>*)aProposedServices;
+
+/**
+ * Retrieves TouchBarInput icons.
+ */
++ (NSImage*)getTouchBarIconNamed:(NSString*)aImageName;
+
+@end  // nsTouchBar
+
+#endif  // nsTouchBar_h_
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsTouchBar.mm
@@ -0,0 +1,469 @@
+/* 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/. */
+
+#include "nsTouchBar.h"
+
+#include "mozilla/MacStringHelpers.h"
+#include "mozilla/Telemetry.h"
+#include "nsArrayUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsIArray.h"
+
+@implementation nsTouchBar
+
+static NSTouchBarItemIdentifier CustomButtonIdentifier =
+    @"com.mozilla.firefox.touchbar.button";
+static NSTouchBarItemIdentifier CustomMainButtonIdentifier =
+    @"com.mozilla.firefox.touchbar.mainbutton";
+static NSTouchBarItemIdentifier ScrubberIdentifier =
+    @"com.mozilla.firefox.touchbar.scrubber";
+
+// Non-JS scrubber implemention for the Share Scrubber,
+// since it is defined by an Apple API.
+static NSTouchBarItemIdentifier ShareScrubberIdentifier =
+  [ScrubberIdentifier stringByAppendingPathExtension:@"share"];
+
+// Used to tie action strings to buttons.
+static char sIdentifierAssociationKey;
+
+// The system default width for Touch Bar inputs is 128px. This is double.
+#define MAIN_BUTTON_WIDTH 256
+
+#pragma mark - NSTouchBarDelegate
+
+- (instancetype)init
+{
+  if ((self = [super init])) {
+    mTouchBarHelper = do_GetService(NS_TOUCHBARHELPER_CID);
+    if (!mTouchBarHelper) {
+      return nil;
+    }
+
+    self.delegate = self;
+    self.mappedLayoutItems = [NSMutableDictionary dictionary];
+    nsCOMPtr<nsIArray> layoutItems;
+
+    nsresult rv = mTouchBarHelper->GetLayout(getter_AddRefs(layoutItems));
+    if (NS_FAILED(rv) || !layoutItems) {
+      return nil;
+    }
+
+    uint32_t itemCount = 0;
+    layoutItems->GetLength(&itemCount);
+    // This is copied to self.defaultItemIdentifiers. Required since 
+    // [self.mappedLayoutItems allKeys] does not preserve order.
+    NSMutableArray* orderedLayoutIdentifiers = 
+      [NSMutableArray arrayWithCapacity:itemCount];
+    for (uint32_t i = 0; i < itemCount; ++i) {
+      nsCOMPtr<nsITouchBarInput> input = do_QueryElementAt(layoutItems, i);
+      if (!input) {
+        continue;
+      }
+
+      TouchBarInput* convertedInput =
+        [[TouchBarInput alloc] initWithXPCOM:input];
+
+      // Add new input to dictionary for lookup of properties in delegate.
+      self.mappedLayoutItems[[convertedInput nativeIdentifier]] = convertedInput;
+      orderedLayoutIdentifiers[i] = [convertedInput nativeIdentifier];
+    }
+
+    self.defaultItemIdentifiers = [orderedLayoutIdentifiers copy];
+  }
+
+  return self;
+}
+
+- (void)dealloc
+{
+  for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) {
+    NSTouchBarItem* item = [self itemForIdentifier:identifier];
+    [item release];
+  }
+
+  [self.defaultItemIdentifiers release];
+
+  [self.mappedLayoutItems removeAllObjects];
+  [self.mappedLayoutItems release];
+  [super dealloc];
+}
+
+- (NSTouchBarItem*)touchBar:(NSTouchBar*)aTouchBar
+      makeItemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier
+{
+  if ([aIdentifier hasPrefix:ScrubberIdentifier]) {
+    if (![aIdentifier isEqualToString:ShareScrubberIdentifier]) {
+      // We're only supporting the Share scrubber for now.
+      return nil;
+    }
+    return [self makeShareScrubberForIdentifier:aIdentifier];
+  }
+
+  // The cases of a button or main button require the same setup.
+  NSButton* button = [NSButton buttonWithTitle:@""
+                                        target:self
+                                        action:@selector(touchBarAction:)];
+  NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc]
+                                  initWithIdentifier:aIdentifier];
+  item.view = button;
+
+  TouchBarInput* input = self.mappedLayoutItems[aIdentifier];
+  if ([aIdentifier hasPrefix:CustomButtonIdentifier]) {
+    return [self updateButton:item input:input];
+  } else if ([aIdentifier hasPrefix:CustomMainButtonIdentifier]) {
+    return [self updateMainButton:item input:input];
+  }
+
+  return nil;
+}
+
+- (void)updateItem:(TouchBarInput*)aInput
+{
+  NSTouchBarItem* item = [self itemForIdentifier:[aInput nativeIdentifier]];
+  if (!item) {
+    return;
+  }
+  if ([[aInput nativeIdentifier] hasPrefix:CustomButtonIdentifier]) {
+    [self updateButton:(NSCustomTouchBarItem*)item
+                 input:aInput];
+  } else if ([[aInput nativeIdentifier] hasPrefix:CustomMainButtonIdentifier]) {
+    [self updateMainButton:(NSCustomTouchBarItem*)item
+                     input:aInput];
+  }
+
+  [self.mappedLayoutItems[[aInput nativeIdentifier]] release];
+  self.mappedLayoutItems[[aInput nativeIdentifier]] = aInput;
+}
+
+- (NSTouchBarItem*)updateButton:(NSCustomTouchBarItem*)aButton
+                          input:(TouchBarInput*)aInput
+{
+  NSButton* button = (NSButton*)aButton.view;
+  if (!button) {
+    return nil;
+  }
+
+  button.title = [aInput title];
+  if ([aInput image]) {
+    button.image = [aInput image];
+    [button setImagePosition:NSImageOnly];
+  }
+
+  [button setEnabled:![aInput isDisabled]];
+
+  if ([aInput color]) {
+    button.bezelColor = [aInput color];
+  }
+
+  objc_setAssociatedObject(button,
+    &sIdentifierAssociationKey,
+    [aInput nativeIdentifier], OBJC_ASSOCIATION_RETAIN);
+
+  aButton.customizationLabel = [aInput title];
+
+  return aButton;
+}
+
+- (NSTouchBarItem*)updateMainButton:(NSCustomTouchBarItem*)aMainButton
+                              input:(TouchBarInput*)aInput
+{
+  aMainButton = (NSCustomTouchBarItem*)[self updateButton:aMainButton
+                                                    input:aInput];
+  NSButton* button = (NSButton*)aMainButton.view;
+  button.imageHugsTitle = YES;
+  // If empty, string is still being localized. Display a blank input instead.
+  if ([button.title isEqualToString:@""]) {
+    [button setImagePosition:NSNoImage];
+  } else {
+    [button setImagePosition:NSImageLeft];
+  }
+
+  [button.widthAnchor
+    constraintGreaterThanOrEqualToConstant:MAIN_BUTTON_WIDTH].active = YES;
+  [button setContentHuggingPriority:1.0
+                      forOrientation:NSLayoutConstraintOrientationHorizontal];
+  return aMainButton;
+}
+
+- (NSTouchBarItem*)makeShareScrubberForIdentifier:
+                        (NSTouchBarItemIdentifier)aIdentifier 
+{
+  TouchBarInput* input = self.mappedLayoutItems[aIdentifier];
+  // System-default share menu
+  NSSharingServicePickerTouchBarItem* servicesItem =
+      [[NSSharingServicePickerTouchBarItem alloc]
+        initWithIdentifier:aIdentifier];
+  servicesItem.buttonImage = [input image];
+  servicesItem.delegate = self;
+  return servicesItem;
+}
+
+- (void)touchBarAction:(id)aSender
+{
+  NSTouchBarItemIdentifier identifier =
+    objc_getAssociatedObject(aSender, &sIdentifierAssociationKey);
+  if (!identifier || [identifier isEqualToString: @""]) {
+    return;
+  }
+
+  TouchBarInput* input = self.mappedLayoutItems[identifier];
+  if (!input) {
+    return;
+  }
+
+  nsCOMPtr<nsITouchBarInputCallback> callback = [input callback];
+  callback->OnCommand();
+}
+
+#pragma mark - TouchBar Utilities
+
++ (NSImage*)getTouchBarIconNamed:(NSString*)aImageName
+{
+  nsCOMPtr<nsIFile> resDir;
+  nsAutoCString resPath;
+  NSString* pathToImage;
+
+  nsresult rv = NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(resDir));
+  resDir->AppendNative(NS_LITERAL_CSTRING("res"));
+  resDir->AppendNative(NS_LITERAL_CSTRING("touchbar"));
+
+  rv = resDir->GetNativePath(resPath);
+  
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return nil;
+  }
+
+  pathToImage = [NSString stringWithUTF8String:(const char*)resPath.get()];
+  pathToImage = [pathToImage stringByAppendingPathComponent:aImageName];
+  NSImage* image = [[[NSImage alloc]
+                      initWithContentsOfFile:pathToImage] autorelease];
+  // A nil image will fail gracefully to a labelled button
+
+  return image;
+}
+
+#pragma mark - NSSharingServicePickerTouchBarItemDelegate
+
+- (NSArray*)itemsForSharingServicePickerTouchBarItem:
+                (NSSharingServicePickerTouchBarItem*)aPickerTouchBarItem
+{
+  NSURL* urlToShare = nil;
+  NSString* titleToShare = @"";
+  nsAutoString url;
+  nsAutoString title;
+  if (mTouchBarHelper) {
+    nsresult rv = mTouchBarHelper->GetActiveUrl(url);
+    if (!NS_FAILED(rv)) {
+      urlToShare = [NSURL URLWithString:nsCocoaUtils::ToNSString(url)];
+      // NSURL URLWithString returns nil if the URL is invalid. At this point,
+      // it is too late to simply shut down the share menu, so we default to
+      // about:blank if the share button is clicked when the URL is invalid.
+      if (urlToShare == nil) {
+        urlToShare = [NSURL URLWithString:@"about:blank"];
+      }
+    }
+
+    rv = mTouchBarHelper->GetActiveTitle(title);
+    if (!NS_FAILED(rv)) {
+      titleToShare = nsCocoaUtils::ToNSString(title);
+    }
+  }
+
+  // If the user has gotten this far, they have clicked the share button so it
+  // is logged.
+  Telemetry::AccumulateCategorical(
+    Telemetry::LABELS_TOUCHBAR_BUTTON_PRESSES::Share);
+
+  return @[urlToShare, titleToShare];
+}
+
+- (NSArray<NSSharingService*>*)sharingServicePicker:
+                           (NSSharingServicePicker*)aSharingServicePicker
+                            sharingServicesForItems:
+                                          (NSArray*)aItems
+                            proposedSharingServices:
+                       (NSArray<NSSharingService*>*)aProposedServices
+{
+  // redundant services
+  NSArray* excludedServices = @[
+    @"com.apple.share.System.add-to-safari-reading-list",
+  ];
+
+  NSArray* sharingServices = [aProposedServices
+    filteredArrayUsingPredicate:
+      [NSPredicate predicateWithFormat:@"NOT (name IN %@)", excludedServices]];
+
+  return sharingServices;
+}
+
+@end
+
+@implementation TouchBarInput
+- (NSString*)key { return mKey; }
+- (NSString*)title { return mTitle; }
+- (NSImage*)image { return mImage; }
+- (NSString*)type { return mType; }
+- (NSColor*)color { return mColor; }
+- (BOOL)isDisabled { return mDisabled; }
+- (NSTouchBarItemIdentifier)nativeIdentifier { return mNativeIdentifier; }
+- (nsCOMPtr<nsITouchBarInputCallback>)callback { return mCallback; }
+- (void)setKey:(NSString*)aKey
+{
+  [aKey retain];
+  [mKey release];
+  mKey = aKey;
+}
+
+- (void)setTitle:(NSString*)aTitle
+{
+  [aTitle retain];
+  [mTitle release];
+  mTitle = aTitle;
+}
+
+- (void)setImage:(NSImage*)aImage
+{
+  [aImage retain];
+  [mImage release];
+  mImage = aImage;
+}
+
+- (void)setType:(NSString*)aType
+{
+  [aType retain];
+  [mType release];
+  mType = aType;
+}
+
+- (void)setColor:(NSColor*)aColor
+{
+  [aColor retain];
+  [mColor release];
+  mColor = aColor;
+}
+
+- (void)setDisabled:(BOOL)aDisabled { mDisabled = aDisabled; }
+
+- (void)setNativeIdentifier:(NSTouchBarItemIdentifier)aNativeIdentifier
+{
+  [aNativeIdentifier retain];
+  [mNativeIdentifier release];
+  mNativeIdentifier = aNativeIdentifier;
+}
+
+- (void)setCallback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback
+{
+  mCallback = aCallback;
+}
+
+- (id)initWithKey:(NSString*)aKey
+            title:(NSString*)aTitle
+            image:(NSString*)aImage
+            type:(NSString*)aType
+        callback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback
+           color:(uint32_t)aColor
+        disabled:(BOOL)aDisabled
+{
+  if (self = [super init]) {
+    [self setKey:aKey];
+    [self setTitle:aTitle];
+    [self setImage:[nsTouchBar getTouchBarIconNamed:aImage]];
+    [self setType:aType];
+    [self setCallback:aCallback];
+    if (aColor) {
+      [self setColor:[NSColor colorWithDisplayP3Red:((aColor>>16)&0xFF)/255.0
+                                            green:((aColor>>8)&0xFF)/255.0
+                                             blue:((aColor)&0xFF)/255.0
+                                            alpha:1.0]];
+    }
+    [self setDisabled:aDisabled];
+
+    NSTouchBarItemIdentifier TypeIdentifier = @"";
+    if ([aType isEqualToString:@"scrubber"]) {
+      TypeIdentifier = ScrubberIdentifier;
+    } else if ([aType isEqualToString:@"mainButton"]) {
+      TypeIdentifier = CustomMainButtonIdentifier;
+    } else {
+      TypeIdentifier = CustomButtonIdentifier;
+    }
+
+    if (!aKey) {
+      [self setNativeIdentifier:TypeIdentifier];
+    } else if ([aKey isEqualToString:@"share"]) {
+      [self setNativeIdentifier:
+        [TypeIdentifier stringByAppendingPathExtension:aKey]];
+    } else {
+      [self setNativeIdentifier:
+        [TypeIdentifier stringByAppendingPathExtension:aKey]];
+    }
+  }
+
+  return self;
+}
+
+- (TouchBarInput*)initWithXPCOM:(nsCOMPtr<nsITouchBarInput>)aInput
+{
+  nsAutoString keyStr;
+  nsresult rv = aInput->GetKey(keyStr);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  nsAutoString titleStr;
+  rv = aInput->GetTitle(titleStr);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  nsAutoString imageStr;
+  rv = aInput->GetImage(imageStr);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  nsAutoString typeStr;
+  rv = aInput->GetType(typeStr);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  nsCOMPtr<nsITouchBarInputCallback> callback;
+  rv = aInput->GetCallback(getter_AddRefs(callback));
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  uint32_t colorInt;
+  rv = aInput->GetColor(&colorInt);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  bool disabled = false;
+  rv = aInput->GetDisabled(&disabled);
+  if (NS_FAILED(rv)) {
+    return nil;
+  }
+
+  return [self initWithKey:nsCocoaUtils::ToNSString(keyStr)
+                     title:nsCocoaUtils::ToNSString(titleStr)
+                     image:nsCocoaUtils::ToNSString(imageStr)
+                      type:nsCocoaUtils::ToNSString(typeStr)
+                  callback:callback
+                     color:colorInt
+                  disabled:(BOOL)disabled];
+}
+
+- (void)dealloc
+{
+  [mKey release];
+  [mTitle release];
+  [mImage release];
+  [mType release];
+  [mColor release];
+  [mNativeIdentifier release];
+  [super dealloc];
+}
+
+@end
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsTouchBarUpdater.h
@@ -0,0 +1,21 @@
+/* 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/. */
+
+#ifndef nsTouchBarUpdater_h_
+#define nsTouchBarUpdater_h_
+
+#include "nsITouchBarUpdater.h"
+
+class nsTouchBarUpdater : public nsITouchBarUpdater {
+ public:
+  nsTouchBarUpdater() {}
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSITOUCHBARUPDATER
+
+ protected:
+  virtual ~nsTouchBarUpdater() {}
+};
+
+#endif  // nsTouchBarUpdater_h_
new file mode 100644
--- /dev/null
+++ b/widget/cocoa/nsTouchBarUpdater.mm
@@ -0,0 +1,45 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#import <Cocoa/Cocoa.h>
+
+#include "nsTouchBar.h"
+#include "nsITouchBarInput.h"
+#include "nsTouchBarUpdater.h"
+
+#include "nsCocoaWindow.h"
+#include "nsIBaseWindow.h"
+#include "nsIWidget.h"
+
+#if !defined(MAC_OS_X_VERSION_10_12_2) || \
+    MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_2
+@interface BaseWindow(NSTouchBarProvider)
+@property (strong) NSTouchBar* touchBar;
+@end
+#endif
+
+NS_IMPL_ISUPPORTS(nsTouchBarUpdater, nsITouchBarUpdater);
+
+NS_IMETHODIMP
+nsTouchBarUpdater::UpdateTouchBarInput(nsIBaseWindow* aWindow,
+                                       nsITouchBarInput* aInput)
+{
+  nsCOMPtr<nsIWidget> widget = nullptr;
+  aWindow->GetMainWidget(getter_AddRefs(widget));
+  if (!widget) {
+    return NS_ERROR_FAILURE;
+  }
+  BaseWindow* cocoaWin = (BaseWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
+  if (!cocoaWin) {
+    return NS_ERROR_FAILURE;
+  }
+
+  if ([cocoaWin respondsToSelector:@selector(touchBar)]) {
+    TouchBarInput* convertedInput =
+      [[TouchBarInput alloc] initWithXPCOM:aInput];
+    [(nsTouchBar*)cocoaWin.touchBar updateItem:convertedInput];
+  }
+  
+  return NS_OK;
+}
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -92,16 +92,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShar
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacWebAppUtils)
 
 #include "nsStandaloneNativeMenu.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsStandaloneNativeMenu)
 
 #include "nsSystemStatusBarCocoa.h"
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsSystemStatusBarCocoa)
 
+#include "nsTouchBarUpdater.h"
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsTouchBarUpdater)
+
 #include "GfxInfo.h"
 namespace mozilla {
 namespace widget {
 // This constructor should really be shared with all platforms.
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(GfxInfo, Init)
 } // namespace widget
 } // namespace mozilla
 
@@ -122,16 +125,17 @@ NS_DEFINE_NAMED_CID(NS_PRINTDIALOGSERVIC
 NS_DEFINE_NAMED_CID(NS_IDLE_SERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_NATIVEMENUSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_MACDOCKSUPPORT_CID);
 NS_DEFINE_NAMED_CID(NS_MACSHARINGSERVICE_CID);
 NS_DEFINE_NAMED_CID(NS_MACWEBAPPUTILS_CID);
 NS_DEFINE_NAMED_CID(NS_STANDALONENATIVEMENU_CID);
 NS_DEFINE_NAMED_CID(NS_MACSYSTEMSTATUSBAR_CID);
+NS_DEFINE_NAMED_CID(NS_TOUCHBARUPDATER_CID);
 NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
 
 static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
   { &kNS_FILEPICKER_CID, false, NULL, nsFilePickerConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_COLORPICKER_CID, false, NULL, nsColorPickerConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_APPSHELL_CID, false, NULL, nsAppShellConstructor, mozilla::Module::ALLOW_IN_GPU_VR_AND_SOCKET_PROCESS },
@@ -153,16 +157,17 @@ static const mozilla::Module::CIDEntry k
   { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
   { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor },
   { &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },
   { &kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor },
   { &kNS_MACSHARINGSERVICE_CID, false, NULL, nsMacSharingServiceConstructor },
   { &kNS_MACWEBAPPUTILS_CID, false, NULL, nsMacWebAppUtilsConstructor },
   { &kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor },
   { &kNS_MACSYSTEMSTATUSBAR_CID, false, NULL, nsSystemStatusBarCocoaConstructor },
+  { &kNS_TOUCHBARUPDATER_CID, false, NULL, nsTouchBarUpdaterConstructor },
   { &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
   { NULL }
 };
 
 static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
   { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID,
@@ -186,16 +191,17 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { "@mozilla.org/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID },
   { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
   { "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID },
   { "@mozilla.org/widget/macsharingservice;1", &kNS_MACSHARINGSERVICE_CID },
   { "@mozilla.org/widget/mac-web-app-utils;1", &kNS_MACWEBAPPUTILS_CID },
   { "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID },
   { "@mozilla.org/widget/macsystemstatusbar;1", &kNS_MACSYSTEMSTATUSBAR_CID },
+  { "@mozilla.org/widget/touchbarupdater;1", &kNS_TOUCHBARUPDATER_CID },
   { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
   { NULL }
 };
 
 static void
 nsWidgetCocoaModuleDtor()
 {
   // Shutdown all XP level widget classes.
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..16f70bc6ca0f865214f3baa8ef82e0f805bcbd67
GIT binary patch
literal 5738
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
Iq#Edd082icy#N3J
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ba0197323ae68f33d52a21a751f9478b50f41fbe
GIT binary patch
literal 5894
zc$}qJXIPWVwx)Lhm7;(U*@Rw_5K2UP2}KD-Fac=^p+hiq5GhimNfQwik)ntQqCx4s
z2vR~XB3(d=AZ62$i)`G-bJ+KuA2*rj%Y5&wS+i!|^~|&K0`=51#K7W`bijt`)#-(t
zwWpm8O>|HI2!KO7&|SU^khp?%v30itNF72300|9yCwDCV@Yl)89jk`L;H<F#1qC`c
zcRbe0na-Qk$UsiFQHf#EjV`@rtK4z(?hhlbaoUJU(%@b8=(8NznkdBOsTHTHIgPRG
zD3OF~CH`F>dQH8Y4X^`J@4N&r-6vcZii5rGb5B>z<96U$e>x)$6@Q;(TU!2!3Tdu~
zV;m82jQcdfsHUd-(P%7oQgl-m#cu3`#wUoUpi86MAIgb6aM&SOGOLN~Im>g06h{)(
z9;-<PB8MKhQ4ff7ohy-8zd~h-*+9PmQlTc=XyiI6m#IjtJRT`Aw>jxm)zWz0Va;9z
zz(cf~kgkzQRhSv5opZPw3gZum=z2;avdUuJ`u_AMB#kbu7SggJi(V7Hlo8?Z++Z?{
zSz+}iGe=ghv<5HzU9xln!J3Rp#{sF7c^$z*hGC{M;LhppwIwMm>TB|N83S(&d*i&}
zBDM&oIa8Oa2e(ER{Wv2#^D%xUgwRB>RKC8`-uq|S%4qWe-5`8pEY>^6%l8=~*z8uV
z+g?RlO;2lh_Zs`iZPKSL5kquX7wcmR4tqbDlR9QlQbzh01o@5BYd)@6fP|iv?a>pD
zb#Vts{zb3>)(z)@$6(z6(tiP}I2ZTBaW??;=>3rFV}H`W`P0MWFosxnfazgZO#@&C
zkU%2P4p@vk;OD4@GZ-LqJo`5XGAFZ4_J7Z^<CuT>l`!-`yB{GMIK1;;&z}}_V1R^*
z3eFo~3I-g0We%I!@4JHiwE`TE^Kd;1&hXGP-pa+z_2)5Qd=58k2mphATG2^p0o?H(
zhfC-HY^<Ezu*c#5o$ME)mFWUO3>3>%XkzfEUg>AH7M+GXdMuQz4hKy9z<QUrg}It9
z0D3i9yq`z<tjiocd1Jl(G#Dm^<AET_sk*mPa`*X@QCUEuzA+-mtWzT25+8|Ge@WfV
zWc7)|_av*b$0r7p`Gvs#PZCsdPB^@ws}%-&v{h9%2mlN|Ndy>jk_qr}KIk4MhJ^A@
zI$RF907$4|J?$}A1Gvh6zY9W*Oz(0Uo%@jpYoROe==szqmaSUpE>y1bo^|9|QL1TT
zkt4_3p*}WcLSmwI+ah1bm2P@};o!-ryeci_ib^q>;BMdAe(GI=Ts>p21ztggB5!5E
zb@k#ExkPJzl*1z|@z&b@*fwr9{d{K7JC(|UUDixsy|i1)i`CCvn2$A=w&yN#Wb1Q?
zzA%<gXzw_4TScT`zuHtW4gtC@u;jFS9aqXJiq`?Ij!;(_7xe<i&#DCx97c*FsKROy
zJjDxSQCwkH`DpesYo?{cV#3&mx1`{S#KxyEdeOWjmDApo-nZU_OKgsNGV0YJ5;#Bi
zUQ=J^b?nzp?YN-oR~lXl_mL^dmeC`u4F`ENzwEfs<iYT++Ca2{@(G2xK79mi93J>u
z>Rsp+>al|1F0StwwI69Q^S3CxWn5ocb3djI<Ecj3XP0fI87A!!#*2dvnviW=bBkt%
z`R9DK<Z8zXz88JP-PJUJ%B3CJ&IO`cY31>8+Und0l34O;^ZW~Ju$r9pl)lGjE1GS;
zT?6v3vg}PK(}lmS$*QTw%L}dF1@4;`6VkYl&7G3G;^;TB#gBa_!b2Ce6)3rHrno%X
z?l6CUqnq)$+zvw6M*BN@`CZvkn;@Qkt6f94_Z~8+B{)Tstlk#T8spQ22zpdBF2bC{
zA%-?;d3x1A5Uv$DX(Dj;!5RDPI}?R?5SN!(dkBG;DeN7Sdau1M)#LuRG_!maY$27I
zSCMd|3XeYd6XA90!N>)}jB`sI;~x*Ea?)C3?xk~ZT3NkkKiC}<9VR{>Vh~ys+JMT{
zOj_CwDhznB`IWIo+;RbE4-;GOHeVPabEv+{;Vf*qPZ`O9DhRJC5RH{?y4-qxjq+;c
zYSWl}Wp^QAUYLL9lJ6IDd8R$K5^iK;8TX*8zhF>08RwQM99LoD@T9T_d((hJx2Qj7
z*q6=Bh$3meqXX!!tlD0YGZSIXldK!C{gmA~Db4T4eCM+sAjYQ`qt3pSmtuPUlH}5x
z37-0Zu<P~9p^6L#;+10l!v4UtWQAn$L|(Hvacv8oF>M|li;|u4_Bg){J_x%TaFwm6
zFTb#O;2{zwj7#QuFty6Kt?$!sB(!?>GBD?hS)r2`vHcP5SuuWnS}@aN*KHO#iR!w6
zkR>16e@N0EH7G;A){M-W`fi^&h8|_OMC-hqIFNfcbdW^{m$GCJUNal3RReKH$DR3n
z;W4c)B@^vu{|9%<Eg#jUer-RsHX*ztJT0wwu}Xj?uMd%GQi>MwtD6u=qEYa_p~X4>
zrNp4qqY;dXY!P#j_PLqR;AOb@M_GznRd|*2^~)W%!|V<$yf^)qZ+_rV6JhIWp5m4X
z^O`1KK9lCB;{34vz2fS2)gN!Q{WfJct1<*fEfkAQWLCI2y`${b+Km^|H%;@~nZ^U|
zd=37=^ECaI(aB5i=q5VqfMj5QgP>#Z@UqiVRaLQa!&(E5?lA*^+22P0P{)9!{@?dn
z+5@j^hC^)O#7ddU&NI9K;5vsdEudRYla)e0LMu>@EG&fIQ;kxC<+PBo^|cyOcsMUc
zorV5RFnWM?m07Q;R$onhdL-JBb~#^aZ8UZN18Qt&ws>I3cG-WRj6`oQn4-=dNg4>v
zK(Z_?)ZRFAwzXlC>>M*GBa*ac!p4RIzNJRiyH_cnlJY{ciLkLG9%x-YELyF{@78}1
z5YH>4%11>)r`{)h`8GfMG}(PaLgRVJ0maAlBq2x`7{Zo8oB4`&s^PWMM$U{#dCS9O
z{x2CEsE+d$&?nL5dZVepiL7Xfj2jPu<F;A1sIisTv{Ff?HwAlowjN(00kNc5w9WEo
zI7L9zS<Wv-tdfz?+;4zY;2EQ~VRlbQyr0{CiKK|oLO(w}@X&txYqQPH3c+w24Hmgy
ze|6%n_Z8xL5yL$Yd*Ex_19eg$$~na@{#!oRw{NKa8N2Q3p)u~;hWql(zPm;%{ENgV
z%F$0yV@`{&Br4fRHuy{)T_98?8Icq@Qz=bPyh1DkNLDFHibfx=afdmXCp1hl2+&6@
zE;_l9raOv@e3jWv55|404ufr`v@Y!$%ROgT4EjThRT8T{{XFNnj#^tA17kALdViDo
zV5$aY-`-L$`Z&FYeI@j(k^a~Fv>_38<)N2@ka6PHbRhwK69MO>1*p&8PIF|j^ROWC
z4~6NKXi+!g<VjTjAm?*Y^d<9OFl7eQHCI*G<;TBvi-q|9nBC!_zY*y&aYdQeaAt!c
z)*27Y6g{6c7UEP(b|#M6{V5$ZNE}2aYI%w)P|}rr6hIOZsL4$JfLvUY%wCD&t+K)(
z37s-{kks>zgDXjIkZ&i2Zm_f~)eVa4HK$zZ83N%-bYZnRAkxtwdz#?y%&eKpFXPy<
znNn2xnK?~pd{mY7WLd}?RU_h<6O^_)`Cpt9zVk9eRZo8X4|k3-8nZh)PpLZrP^x`W
z|B%xU$$G3#4U)VM94eIKqJh`7j;ndIKBi``8J^HCVN+l%u4A9z{7xboYEhR+qtr}8
z-lc)0;apKui9_;{p1$Z9&znt_tDYLin9W%lqZxnm3prJIhSkG!Y)$8<!cox^Xk)8>
zv^J>kA?Bg+74{iv8)nI%?citVzBkX20<RQ3X{Ap;iV<rtwv4qjElhqxK4`Tl$Hn-e
z=KLg=>+O<rHy|!j1r)_h1JUJy3-zZa_*c9ughyGHgPCgGzN2qltfC9x3g8}#<!P!G
zh@&;3a13U;_yEA?#CMIEgJzayKjd^BR6pni!kssa*{9(KTIkKaLFEc9E`Hra7OgNo
zb^|`4l%k+(S`NHs{PO&j7ZY19S;O(?P)g>A0={&B1&}F0QSZJWKMO*eOI>A17p7gR
z<fG)H`pn?e3zuHx%ZFuYCWuNke{FvWc%o$TTJls&eqvs{W70yh9}sbWAlWO~LOfl-
z;$ndIkLP<OWcsyAwT3}ig~k~g6Ge6Mp<3#xnMvro=u~tB`p%?Oqdu@AAt<5v3?f%)
zuCN>U>>`Is&oiIylA^0cmp)-XfiA#hvUhtD=Ni{}zE-Z&Vu4uGX~Ai(X^v^aM+2%l
zkmZ)7!TD#=iP7cJv1`zoQsNYGSo*cS`9XzH(zdXR@U0}?B%37Cq}Z2NjBtG{eQ7V9
zUm|)z4*U*Q4nq#Red2jB#2lj66JnYL^x(^0_<Uhmgm1}?!=Lr@^7DxtsT@@t=Q)fx
zlA%pf=Tlu$TT-V}XQ3a8>`dt2QJ74d%)T=RC8aF2U9$laqF@>M1>bVSx)icU^5pX|
zF9=B6EL}p!S+fLjQyJyr8^wlRDhM43q=dz5{pAb={q+3w>}q(mX~4&tPQWM2DCI}B
zFES!Cs;!<_WldoIcp0D9C7flFCD$a2d4Dr<MPbU6zc3<AD?ux!<*MOe@8~tlGGY;t
z!EwfpADSms{vosQGYa)eqyH(a{&MrJET2c)BJ}c6$fz{75jG3aZ=!}`3!*$IArvLj
zxoEy{r~Xqzs-qdk|3jF=6o%08d}QWbey-S<XZ1IKxm2^l5w>#Oa^eQ#2JbHaE|^+A
z+&jFIadXh!Q?NY5zwh+I*NKvjmFOvI0Y8B^Jz6<qX{ZjNj#C|3^bG9Z*?Yy#;k#~5
zlyKqW#jVAoExcVbdX0vYrc4%g+O7`7%z8FBH;fF*5AB!iiZJOg#lxdM+|Nmz<sj0V
z-%WmfJ^uRZ;)G4~vcqzY!X<?Wg&2jiRi0IO{t{bO`(*o`J0oiY-)DCQb`cb^6t8H%
z(q&U<P#9Ay&_ig?P<l|**OJzj2lGgDTkzfJWg}DBQ}qnJOe@7;#=7HnPFxiFiht3k
z#K`-$w-<#NT3t=Gp<FYzxw{!26~m^(=B3dBZ&dGtUsd;0Pgd7SMv9^cUo@gkq5;q4
z*?2fv{rEibxtrZ1I^k1`lXO!{;*vKW5Eeh--%aPX5)0xiYEd_ZxjA_*j4>ZXoUO~9
zzEZGmQR+2KF_2guzMC-HBr+SbVz!0di>F8qc^lHDmfT<#fzc|^V%3@=Lnyx+_jqfu
z8uTUie%$>mA<5jX+;;nrqOGDH6`)mQp@^BJyg;QyJv0lXTK3VtZ^`Ivrczh@6+t(Y
zP5HxnKd$_#8O`?ycn3vKaCkdv3&*B^)NeaIv;HOZi%aW;mbI4M+fp`CULLkpo<G9&
zYNeJO8S_K?3vLXT>Ux>gmQDOwwGitJaMm39-m1|WgXJ7^i5%_Kf2v<tWobuPo@r7k
zRnecQ6zec$bZT^Bb^119L&$d+PUbc5`V-wc899jneoj~zL-}9d9%<VM`BwRC<Jqp)
zxF?O*=aIRxHDn4JWj@qdFm9GV-L{&!T3mj8vC7!W^rj_~eXMnC5#+_&O6}JU@V=b+
z?D-&$*wmTIdB5UsX`em}4^)pi2lSA}kT+5*aI<h#1T=5zIp!-nH(Gt3cvVka$eb^$
zwhgcdQ2VC25>JGO!k>Mpi}mP}>m87JA#-24E+(Pr&D6~gxc%`zRsGK9&FM*Im2OeU
zUWBboe%Rt!e!_5h$S2bO<($BN`o{ZClSq?{{?Gjp@3W=t{jT_p%?0+PUFf(VrugXK
z)_U|tN-E)_tqw81gZ1$vSi0BkRh6dDm8b~z@JrX-70Qafbf*;*7L2wACBHUbDaGdw
zSMKf^CFj`|z|7?Q)BG#Hh3&`mbC*APV6k}He(v3}bLE^XVgJEY{=F(n|Jfb0U5U|+
zGXLp&2Wgz-QB*ri;#GbJ=AY%~{73h@sB@Xj72AAe_wDvEi&L2bbO_-mFBS9m`?dyb
zax2#tpAJ|O33qK{!%9>o4wANCBkC!MxkM3-B8_=?KAaf69X;avX1(!yYjkqYRA{x(
zkN2BNU3uxZy>=^Y(Jc+%9lI7%6tzcRRKa%oH=Jj!zkccQvR{6l6FHh!rMMBapRtQs
z{}4a7h}c3TrN=0G-J;!F_2zfBnHk#*S=;@GqV|_S1Ca(p{szJSRMbNMy{MJ^M;XTr
zAaNCIZEtm?eEh79!Lo<#NCNP1aR-0_5<2$QZU9rjaf$r<zklfy9#yT}t(<VSzg!<n
z0mfLon?242AORMK{yzVgjw5*03IjkG0+0YONE|FFE(Or{u)@3h0`$~0j#MOXccH&0
z{gN^S)h<CmU|En17y^buWkDbl5J=##{mb&-6%K0;%wcT~mN^!u4$sv6FebI1H9YuO
zJ-Ujs{{8)5k$U5?Hgtza1ET}|{Q*czNl8ipYyiiY6h!v$h>k{FeqkUe4E&#%6bO3K
z4g~p!xiTj)DVY=gK+=-ZCotGQtO1h-{U-*2NS?5hI&A-mfk6=1$+_SYu|OcwC+wgw
zS?Gy1z!1rkn5@hR3<CWvW_P@my%QFHM5v*??;%exfP?`KcbKKelB1T34GsW4?yDUp
z?PXag1crq`B_Xn42*z3pEF}rCmXVQ?#mdS;Wvnrh3UvS7<gcW6b3aVUqeM8QU4{+_
JR7Ysg{SV6Q^M(Kb
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..1eace36cc3d0524330e57419736ecf7f4bbbadd0
GIT binary patch
literal 5981
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e59d485062c780085410e46c07fb46d828c82e84
GIT binary patch
literal 5768
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c0509e4f04399d2e04a1547246c53b98e27b9a7a
GIT binary patch
literal 5819
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d7aac17d464b61c6765dcca51b9a41e9adee794b
GIT binary patch
literal 5777
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8eb0188885ea03367ca231cbb4d16a266261d97f
GIT binary patch
literal 5668
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
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..62f9dbf0e2fd236dd746913a0bbbbd022bc96657
GIT binary patch
literal 5797
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
S!$c4j7K4Hz5Ji*{_<sP=G`}_g
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ea6f6993f4ed7e298e9605aabe8c9dd674ffc397
GIT binary patch
literal 5892
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
HP^9=D4PN!_
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..5e3d91477e2cf65a9b2fdd39667852dc194e0bca
GIT binary patch
literal 5934
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0547d4b480008422f1c784c14b970379d843a376
GIT binary patch
literal 5878
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..d4d3faf7ec16820f7f5d49164b68b1eada2182a7
GIT binary patch
literal 5979
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
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c231c9427cc3bf041e02c5abef715607c4dc6604
GIT binary patch
literal 5898
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
MCI<o)VM^rx1I%soo&W#<
new file mode 100755
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..cfbed6f9695817901452c2863d1f7409d3a8b07a
GIT binary patch
literal 5902
zc$}qJc|4Te+qY&7mB<ozGWKPL8BF#)q_JmbhOsjmJ4s|;vL|F0Nu(&Ev1Ey4%UZH!
z%f3E#c_)vax8KL}zV9FJ+~;%8Ip1@g>s;ICy3e^lT1qN{5Ft@YP}B7K^g`iAc6U<?
zB@_Sy7?cC0loTL*1MOn#ZU?~dkPaZMV(;XR#^V2-knU(Dv=zo04amq)y18S~NM}lK
zLd`@;7h(vtl3zv;_fYs=G3~dSkA%?#yaN=E_Zd?sbQCCG*nrk=w<cR)Q&Q~CIj_^3
z+*DH)dXgew91Bl3=(*Y=^-*c6$3at5586(wk=*;BU4Ylx+8|?uP6#!1ZYW~SG)^mG
zF0$&9?hBrNt!IUNN=Z=PZW=L>Yy4M22$_I#E&3oj#)WWysVNN+Y?ikO%oRR<?QD0C
zk*#XT2m?tu?<)5w;$Y{SHfi`PoqB5PtLd%+`{bEIwGg#_J5B+W4~@5I`_BJB?TU0j
zUm+M8BC^%`dNhzEzWGUHp|LY-gr9x;37i{Wjf}D^EZJ>hsP`>fUI)%J65oEX>W&N5
zVCnG0O+8R?-nMB3U#{#T-!8^lZoAS~BIc(>OV@|F6*>yBbS?Uy-(dmD2cDU8({6)9
zGTOtqR0NG(RR{Rz+a{sbMk#~A<=dtVaAyo*N(ck@<pc?0>b)uNL=ibL{hJhD<>()C
z%<&I!Uher8c4vdOxxHBM;O^I!;iaPWpI5hK6SK<KDA6v~Ctkt#emN6%;#5&M>^CIx
zhoAL)T+x8A7Si_kjYYe-1EPQXTnFuj@xWT4-2kz_0Y!|9JAU2`fF6(W{y*U-_6I*L
zEXGO~?GBjWyGkm686a$kKslhT+<{-SD$Wo<{ABeX48%_dp2YtgcqcOd<}0l0fpR}a
zR4`cQzu&(oC?SBbf&#`HFo6L0M;zbG{?rQo_YSI9jEC#7aJqQTSfq=a>n}4{`QR1S
z1t8#GRFuMMfIHR$zl8>1gLHC3pNRiY{PXLP>+$G;^}x_ut)%DVl86iB>FI*h;tWF-
zsvat^X*FGM=)Td=t(3!~e}$FDGTXKwt|)uO)Tt@ilzIU5RO|8cY)2vm6&rv=FSUS<
zoS<Q!@$6|=N}QNULhLsJ|6eVyh;hPTbzPBG=wtm9-9!Kg<h1o6BB#v{ISGQB_-GK8
z|K$T0yaNDXCA6o#6<SAC;s4GF84tbmbiXi!b>YNu-RC&~&?d7l1@Kw&`b84$2(^1!
zM4`c4o=T)D^yhdDto7;%Rl_)}l<BGN2cZTj*6Flb8nl&^r$?e4DOO5g8>4B5AB@Jn
z%vKJ5v0d>WtR~Pp2qJm!Zb*0!nqx@6ywG5J{z7}xHqj+ILK;KD`Ux8w64f0gqP_#1
zbZY9;>n-J5%R=|8Yla2tw7A>`jsoI2#1%Qu5Kt=ji%H$(Vw@&Q(k*Xh5;-FIxS7l=
z5(*Jv$f3x6&N12a!fC5;hQFrmQ3}^o4zp1w(>rKpbdA<%8fYRfnk2{c5op{t?+zIn
zr>B-iFul#w+q?7l1_78p)#B4ESB_JJh%!CXa>P0j0eMmr{2i7iY8P&oN#I>zI~7S1
zp@u3rH~7eY`bVqH-deftE(*e*)TlWT?tP<cvx52onDO2V%tK{Dkdbq$UHnoB>(Y|Z
zz>M8)-Ip=8ySj(ct-kyEYg~(6nex$@Mq^Hk&xLUe1Y4ZO>6goEll2KIoX^NjPdrDg
z00ir#1Qnx?H`qd*%oCcvQ*%>AEiO8_5oS3G@&6Ft&kDkPtP6#2r?xNe8%P!~$_8Fl
zyC{lQo-QaX&`|pHiJB&*%ldGe?r5?eZr{<?DDXI|o^dVYhrafYB#Ph&yP6QGK*Km8
zYs%n&{)vD~V%%g*cQYL6?K~_9{6pYcRcd6d7-<5<tHhixvc5$A3np|B%GTO<b|vvI
z++sz1f6nf)Q<+A(Ox%#?(4E<$j<v>uas`<3#)6$1h|b56xo1;C1BJju0+wf4?}@q+
zj{*e2_pZ|sKO`2qPGm1f@=9K2h=5WaGDPTk-@%ojFVMG}<YthV>lss$TlHsMsi^O%
z%29?kXn+Yv1MSI!R_QM0%0G)^$fr$J7@%V@CihX4*OH(oZdQzlqf3z6?dE!ViSPci
z97QeZ&8zOr)#PUP_p-^l0qB`SLjT}%kBEAaXNL&h-1|}{$x5#JzI|ND`{H9V#`@t2
z^(qD#n#%W#6D+F)0wEUf6UpUT$%%VZ49Qv6loa9&ISJ2Qag684Cn{1-i=)YBc^h**
z{`M5{nXnw>qe~1eOp{?o(Gw^G<N!(?-2cexk--hd88I6=(ZJoHC#e3H1%}+uWj!gx
z&ZWl)HW^sPTAGxlyd)k%E=sb}e5hyo&gy!%>XNC53#^o+l6Ek<=H5c%*$J*S?{|Eo
z^eaKM4Q{KbJ6CEc16Tvt#$wr9>bT=5j7c1WXs<j3IGs54=$Of8$q$3iy@zTCK1H~5
zgwpvmnWA`KJ{XdJr^d>4Gm%~`l#@}1lQ*>@P*2T)!;DLs3wI^4?V7bJ_L7mDIii#^
z3$OsuCdg_f@o>>2)LE4kzTAYXzm@Zm^HF@FbM~oApW(Ad)fvVJoRYt~zp!eeXv#*)
zWLrsMalB*lLW&;<ku;d%m0}^3#cgpVK>cUIK^2j9gIt4dU|yL)j><&Ed+880<+R*n
zR5&UP6@j|{9oDQ3dY2HGP<b9vBsW*~8T8}|vqJ9^pU+hlnibc+qQ8PKtBU9E_a@FY
zZ?gZuZBn2?Xp?E4Y1V1x>GF>{XWoM?cSLoVo<t``*F?u|Kxf`|O?C~7y|6bwddHi*
z%jd#(Cz&JJCYdlf_Sp@6Oh0{p#xv(<h(53bmjlw_i^G1uP;pFGVV75CSB3@jXzCzr
zzN|XJw`$Mfuf}=l`9$V4=2~VZW_{)qXbX%f%_XfZZ8~ih`k}(knCdl&@wD;mYjbdN
z>hdQ&8&G)^Jg1~|sZg*-CV!+@y2R>fxuI>|&GOC*W(h(j;_{WImAYOE2n}IFVT%{q
zD>*XSStVKdb*gnH0UztTfv=WP^63pvb0Tx<keSH539GBm;){Fu@{IE&TO_RB+>Tt6
znKa=li^xz*P>X5P)E(*@)w8Vbs_3G2oU!AA7Q<>j<d%IiGJ38ukPUB?YQ2-^lfKJO
zB^_lLmBBE=U?H$1pewi_z;48AL~7_<F<-XV__Zm`(ag&KL#V@~Re5K@$js}KBEd1w
zx+Q<fG_$f1hMJo-U0XC;9Q$1R5Hjg7?=T$A_K>?LPff6Y|G9-96IGpS(UWA{e%vp6
z)e6Tlj5>Kc&vxcfQ8TVG_6c6X_S~MRV#US_Sqnv5c)RBG=?^DQ8ZYd9(j1JL^=xu(
z8X1!Qa#*#`Ppd&2uNw6ssW5Stxr@p?Jmtl$_**Y36Sh$+4l9K+*JL7OVq`AVde#>E
z3-2Hgi4HyYMm7dlXZHs85hM~M&nbRT=98$97?8<OiBOy;^&n|%AZ(}!Vi*2w!D-sZ
zK%{V>=ounK0i!m%xaW3BNC5hrYtg4l-}|n&7l|NBSxK>}=6Y=F=T_CI7zPanFO@dc
zX61fWO=Umj6lIMRLjj}mDV1pBXrMrvft}@|AEzg_X#4YsM%d)ycgo3SAyLzZ<%?gj
zucwRJyGr9M8jNo9v9YjU9-}*oxbVJc`bO!d#apjwlEK89u>FMD7XI0oHM1S`K|D!H
z@T=e+rIaSK2rIQxwTo(#L<srU;~uXp)&r-ClH!u`ctwkPiaP9rD|RY+6+p<yGJZ2r
zX>OcwBQy`JSpCtye_8)Ru3S(24IVcmo0>-te%|=&dNgM`=)MtExx=ebTUB({N9|AN
zW;UnNrd--Dw{5iT--X%0ygY1cJ%5HCG{BY}X-Yx{N==8~-t;nSsGj(%b|KaoaK8R!
zwOyq>2F)_&5;@wZovmF~YiU=$GSi~)RzZ6LC)jC1<J9bQ(P?SKro6;qIEBN!=Py+I
z_sH)E(6@wzF(dz5yCa{rf|qblww~;JjeC-NeH)pp-Y`r>8JU0SE*&>3nf|n%yIxsy
zYq8b<X>!|=);`ucwnF6TE1dcZ2i5+<`TY4n=Ge3u+`M1qQpVR0!-I8W&H=rIF~rSe
zGHmp$?*dx4wH!<2otu&0CZ0ETE#%Hu*VzVG1Sl<CUyJWj4N-ma;eD(}zhvK__*3yD
zvG*|vEiWf;f504$|E1`6p?FS9H1F*WiNqE7+V>AT>?@hnQeS)`{h!ToA7*X6={Alu
z&KdYN5b-8o%--*Y-`L!}-i*tgmjz|hkM3+nZ>6S{f3(%;itoJmI31qlb$4B%C1fos
zf-&scEq9sfimA^TrDdg~?SUyT%-7yxi-vLg2l^?+wxw`0N&gIg+*0Ua%m7<W=0l6c
zyY_RhSDbNkuH}ahCrcjGlKRi?ne7XYZdLnFKRC)@A&xq;w=7iacVzxedd`3Ju!pRO
z)?D_Juf(C<q1EDKE;l8DFY}pf$zlJ_piL2Ob1{3+va3AYHa4_MQTQl%_XVPnw5zC#
zU!_82UbRHED|$D2#P{W9^J;r^O7CPy9q-RK+sQq}S$Dnmaki+ord7wDg;ZJf(WkZW
zy@4&~S?eEDy<YY!1%;8L#kI0qfrmN!R+}H<=N1t=h~%soS+6@32kYKk&Nee++rb<A
zr%$}c$I#;|ix@=Y9}sc^;!nD2ii!$IH?%cye2CQn%>E(zm&+^!_WwTAhUlAwv*=&?
znFw#Atm*9i+Ao-|h;!$y(Rg!l<Vi)ENn(W~^Q$lY4D#iPiPoPMIXiEBrt;?t`W{tW
zt0w;rCrBRj*|%YUY+t8H%fM@agGZ*qTb^fAxpGZ1(VEN1AsyXyXX9{e7c-m1lpFY3
z0av<zF&ES*=GOLf{acUK$NFo#b61%2wV4H;8b~K}be_Mfz+ZY;XCfPi0N>(Xc3QcG
zdCMYz)c~!JkkuMg^nu1NC<T@~j8sIN32i{IS1u4mv4(1Lk{{&OPm6`dgfb5Az*G~v
znzP|l0>#M+=e$Y1@4O5X-X8a)(W*xzuzc&&Q{Loo98gc|ysYT=Htemck9bwSxK{bb
zaG*!)v(C#c9@MYvbOf46GfB*~sUqOxs`p;NUWeQu8!H{|VO_OS`k4_ke}}|d-1V6?
z+hej&_Btc`{OX+y-Q<Jv@yfuX7Q;`hbBkuWC6|2FBpb#`S1W#C!msN<B{T4}bN7te
zDWtJ+>dI^gf>`1@^ODO9@cP2d)c(g8-nH5;>4CV`=?|t;D8pXW=hfF?rFl2QL5C)l
z<r%Dot=*y=La3J#m5+TV!a^3+Wk}g>r@Ex?cACF2{Y+CJxrgAhQC~%^yslpU#Dk^U
z=}@`Z_rNf)EhzOmQKK!;9^=!42u!aS=cg-V7DVZ{Wozp2sH#PNH|D<Z@VtHg{fROx
znAOXyBe=XPm(M#U?Lo);G>@dE46_miblDj*uL{0q1$J%XOukLBp~wZ@oJ-5h;~$SE
z3p3hd9%M1IAdznvkM@TIhPw*BQ1dSGZb2pMzgyZ4$qafi_*GwwxZ?t-4|lbPw_YA0
za;OVucILA@B#mS?Dh;bG6^IpUk!ok!Al1aJw~R^SK9`lx^KtE6^PMu6rafS&Vl!;6
zW*c(#=LyUrV%afK#k@0i$i(%cZ|gAMtQaU9_GK{BCrO^~>;$>XD|WmqoQW`JPq`Ve
zo6YE)oZ<I#zWYfp$jYbBN||w|IMsydn&|S&3HHW-&|8fwA+pp*LO4NxK7UX~icE@7
zB8OR=kh+D&m^!<LMb%zSN1WdlrwF4PXq}<Azoe{k@R1>$50k?FaB`hySKDVmpLac6
z3RE~{R_5f@)sc>QQi<K1=E?Qgcbhf*Zq#FnkRTpAd_>R@H6%{F(Q24CxoV#~h8m^5
zM&Z1YI9L=OGDNR|NnN&wY?zHTD1q6c<IaD({Fve<DJ{h}|A+T$EYlm(esrAOnBd#v
zn--J3Qp-(W+>b~zev9Jwdq2UQOfKVZs>U)uRi)GI(F`$)Y!h@5^SPbS<fXfKwK~<U
zHmuh9mQ?56P`e`w?`{8;+aH*f_!)XyC)vb9y{3s*&S&^3I6vxmBfGv^d-avN-?qed
zZ4S?<g>0p<_!=9Fca+^mhrvSDwn<3`?RdcbA3;Cav$O8#|4Ux`U6p}=#o_;e;D5_&
z(ErS9qW@aEaRY=k(bo3J<8sF@HV_GXJ1zluxVQrlKv=`x+6^!PPO{{mw|}uy92Jr7
zNGFW#Z`LQJ00T7E%^u?d2t$ORf3E*syy4MAS^)@Mzz~3dg&?9rFhJV_iFNk{w3Jki
zOGn=By#FlvUCQ85x+VgKNPxv5A`mE40t_|=gSqkTzbXH-!eQ-Ug-_2A@so-a-lpz&
znUsE|amY!@NE2iI=lH)R^~R!YDDkF&Q-c5b0b($iC=9RxPB54V9B;nk8JFJ}7zR0o
z!SK&1I<SbyDGUmSoaXm0d*J0bg~9)254f1bX<2@KCjS!?6&F8+LGb8lI@l?hMI}z_
z3x&f^(ZL|1r*wls;HUI}i9r95*&U0tcS2*29ja^Zi}w>85Z1w9@KJhFXH;{s!2pnx
zz7jrYrJxdGXfRp?4TFmzQ7|+bZ37m=51>}oFi|TB6jFxr|0el6=-u4$A$c4KFi|lW
LB?zR9P@()UVPy6#
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -59,16 +59,19 @@ if toolkit == 'windows':
 elif toolkit == 'cocoa':
     XPIDL_SOURCES += [
         'nsIMacDockSupport.idl',
         'nsIMacSharingService.idl',
         'nsIMacWebAppUtils.idl',
         'nsIStandaloneNativeMenu.idl',
         'nsISystemStatusBar.idl',
         'nsITaskbarProgress.idl',
+        'nsITouchBarHelper.idl',
+        'nsITouchBarInput.idl',
+        'nsITouchBarUpdater.idl',
     ]
     EXPORTS += [
         'nsINativeMenuService.h',
     ]
 
 TEST_DIRS += ['tests']
 
 DIRS += ['headless']
new file mode 100644
--- /dev/null
+++ b/widget/nsITouchBarHelper.idl
@@ -0,0 +1,36 @@
+/* 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/. */
+
+#include "nsIArray.idl"
+#include "nsISupports.idl"
+#include "nsITouchBarInput.idl"
+
+/**
+ * Back-to-frontend communication for the Touch Bar
+ */
+[scriptable, uuid(ea109912-3acc-48de-b679-c23b6a122da5)]
+interface nsITouchBarHelper : nsISupports
+{
+  /**
+   * Returns the active browser's URL.
+   */
+  readonly attribute AString activeUrl;
+
+  /**
+   * Return the active browser's page title.
+   */
+  readonly attribute AString activeTitle;
+
+  /**
+   * Returns the layout for the Touch Bar in an nsIArray
+   * of nsITouchBarInput objects.
+   */
+  attribute nsIArray layout;
+
+  /**
+   * Returns the requested TouchBarInput.
+   * Exposed for testing.
+   */
+  nsITouchBarInput getTouchBarInput(in string aInputName);
+};
new file mode 100644
--- /dev/null
+++ b/widget/nsITouchBarInput.idl
@@ -0,0 +1,60 @@
+/* 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/. */
+
+#include "nsIArray.idl"
+#include "nsISupports.idl"
+
+[scriptable, function, uuid(001ab07c-1b3a-4dbf-a657-fada0065ff55)]
+interface nsITouchBarInputCallback : nsISupports
+{
+  void onCommand();
+};
+
+/**
+ * Implements an input to be registered on the Mac Touch Bar.
+ */
+
+[scriptable, uuid(77441d17-f29c-49d7-982f-f20a5ab5a900)]
+interface nsITouchBarInput : nsISupports
+{
+  readonly attribute AString key;
+
+  /**
+   * The lookup key for the button's localized text title.
+   */
+  attribute AString title;
+
+  /**
+   * The name of a icon file added to
+   * /widget/cocoa/touchbar.
+   */
+  attribute AString image;
+
+  /**
+   * The type of the input.
+   * Takes one of:
+   *   `button`: A standard button.
+   *             If an image is available, only the image is displayed.
+   *   `mainButton`: An extra-wide button. Displays both the image and title.
+   *   `scrubber`: A Scrubber element. Not yet implemented, except in the
+   *               case of Apple's pre-built Share scrubber.
+   */
+  attribute AString type;
+
+  /**
+   * A callback function to be invoked when an element is touched.
+   */
+  attribute nsITouchBarInputCallback callback;
+
+  /**
+   * A hexadecimal uint32_t specifying the input's
+   * background color. If omitted, the default background color is used.
+   */
+  attribute uint32_t color;
+
+  /**
+   * If `true`, the Touch Bar input is greyed out and inoperable.
+   */
+  attribute boolean disabled;
+};
new file mode 100644
--- /dev/null
+++ b/widget/nsITouchBarUpdater.idl
@@ -0,0 +1,20 @@
+/* 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/. */
+
+#include "nsIBaseWindow.idl"
+#include "nsISupports.idl"
+#include "nsITouchBarInput.idl"
+
+/**
+ * Front-to-backend communication to keep Touch Bar updated
+ */
+[scriptable, uuid(38f396e2-93c9-4a77-aaf7-2d50b9962186)]
+interface nsITouchBarUpdater : nsISupports
+{
+  /**
+   * Updates a Touch Bar input in the specified window with the properties in
+   * aInput.
+   */
+  void updateTouchBarInput(in nsIBaseWindow aWindow, in nsITouchBarInput aInput);
+};
--- a/widget/nsWidgetsCID.h
+++ b/widget/nsWidgetsCID.h
@@ -101,16 +101,40 @@
 // {b6e1a890-b2b8-4883-a65f-9476f6185313}
 #define NS_MACSYSTEMSTATUSBAR_CID                    \
   {                                                  \
     0xb6e1a890, 0xb2b8, 0x4883, {                    \
       0xa6, 0x5f, 0x94, 0x76, 0xf6, 0x18, 0x53, 0x13 \
     }                                                \
   }
 
+// {ea109912-3acc-48de-b679-c23b6a122da5}
+#define NS_TOUCHBARHELPER_CID                        \
+  {                                                  \
+    0xea109912, 0x3acc, 0x48de, {                    \
+      0xb6, 0x79, 0xc2, 0x3b, 0x6a, 0x12, 0x2d, 0xa5 \
+    }                                                \
+  }
+
+// {38f396e2-93c9-4a77-aaf7-2d50b9962186}
+#define NS_TOUCHBARUPDATER_CID                       \
+  {                                                  \
+    0x38f396e2, 0x93c9, 0x4a77, {                    \
+      0xaa, 0xf7, 0x2d, 0x50, 0xb9, 0x96, 0x21, 0x86 \
+    }                                                \
+  }
+
+// {77441d17-f29c-49d7-982f-f20a5ab5a900}
+#define NS_TOUCHBARINPUT_CID                         \
+  {                                                  \
+    0x77441d17, 0xf29c, 0x49d7, {                    \
+      0x98, 0x2f, 0xf2, 0x0a, 0x5a, 0xb5, 0xa9, 0x00 \
+    }                                                \
+  }
+
 //-----------------------------------------------------------
 // Drag & Drop & Clipboard
 //-----------------------------------------------------------
 // {8B5314BB-DB01-11d2-96CE-0060B0FB9956}
 #define NS_DRAGSERVICE_CID                          \
   {                                                 \
     0x8b5314bb, 0xdb01, 0x11d2, {                   \
       0x96, 0xce, 0x0, 0x60, 0xb0, 0xfb, 0x99, 0x56 \