Backed out 8 changesets (bug 1563350, bug 1563351, bug 1563349, bug 1567939) on suspicion of causing OS X crashes https://bugzilla.mozilla.org/show_bug.cgi?id=1587351 CLOSED TREE a=backout

Backed out changeset 86ed8b9bee5f (bug 1563351)
Backed out changeset 355b0329bd95 (bug 1563350)
Backed out changeset 653caa0c494a (bug 1567939)
Backed out changeset 4b4a71e170bd (bug 1563349)
Backed out changeset 81b93962243b (bug 1563349)
Backed out changeset cff2050ff540 (bug 1563349)
Backed out changeset db50ea44f0b1 (bug 1563349)
Backed out changeset dcbddc5738c3 (bug 1563349)
This commit is contained in:
shindli 2019-10-09 13:33:05 +03:00
Родитель 05a22d8648
Коммит 083cbd8b40
16 изменённых файлов: 188 добавлений и 969 удалений

Просмотреть файл

@ -7,29 +7,13 @@ const { XPCOMUtils } = ChromeUtils.import(
);
XPCOMUtils.defineLazyModuleGetters(this, {
AppConstants: "resource://gre/modules/AppConstants.jsm",
BrowserWindowTracker: "resource:///modules/BrowserWindowTracker.jsm",
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
Services: "resource://gre/modules/Services.jsm",
UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
AppConstants: "resource://gre/modules/AppConstants.jsm",
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
});
XPCOMUtils.defineLazyServiceGetter(
this,
"gTouchBarUpdater",
"@mozilla.org/widget/touchbarupdater;1",
"nsITouchBarUpdater"
);
// For accessing TouchBarHelper methods from static contexts in this file.
XPCOMUtils.defineLazyServiceGetter(
this,
"gTouchBarHelper",
"@mozilla.org/widget/touchbarhelper;1",
"nsITouchBarHelper"
);
/**
* Executes a XUL command on the top window. Called by the callbacks in each
* TouchBarInput.
@ -40,7 +24,8 @@ XPCOMUtils.defineLazyServiceGetter(
* Intended to be shorter and more readable than the XUL command.
*/
function execCommand(commandName, telemetryKey) {
let command = TouchBarHelper.window.document.getElementById(commandName);
let win = BrowserWindowTracker.getTopWindow();
let command = win.document.getElementById(commandName);
if (command) {
command.doCommand();
}
@ -67,15 +52,6 @@ function hexToInt(hexString) {
return isNaN(val) ? null : val;
}
const kInputTypes = {
BUTTON: "button",
LABEL: "label",
MAIN_BUTTON: "mainButton",
POPOVER: "popover",
SCROLLVIEW: "scrollView",
SCRUBBER: "scrubber",
};
/**
* An object containing all implemented TouchBarInput objects.
*/
@ -83,25 +59,25 @@ const kBuiltInInputs = {
Back: {
title: "back",
image: "chrome://browser/skin/back.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("Browser:Back", "Back"),
},
Forward: {
title: "forward",
image: "chrome://browser/skin/forward.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("Browser:Forward", "Forward"),
},
Reload: {
title: "reload",
image: "chrome://browser/skin/reload.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("Browser:Reload", "Reload"),
},
Home: {
title: "home",
image: "chrome://browser/skin/home.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => {
let win = BrowserWindowTracker.getTopWindow();
win.BrowserHome();
@ -114,25 +90,25 @@ const kBuiltInInputs = {
Fullscreen: {
title: "fullscreen",
image: "chrome://browser/skin/fullscreen.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("View:FullScreen", "Fullscreen"),
},
Find: {
title: "find",
image: "chrome://browser/skin/search-glass.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("cmd_find", "Find"),
},
NewTab: {
title: "new-tab",
image: "chrome://browser/skin/add.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("cmd_newNavigatorTabNoEvent", "NewTab"),
},
Sidebar: {
title: "open-sidebar",
image: "chrome://browser/skin/sidebars.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => {
let win = BrowserWindowTracker.getTopWindow();
win.SidebarUI.toggle();
@ -145,88 +121,31 @@ const kBuiltInInputs = {
AddBookmark: {
title: "add-bookmark",
image: "chrome://browser/skin/bookmark-hollow.svg",
type: kInputTypes.BUTTON,
type: "button",
callback: () => execCommand("Browser:AddBookmarkAs", "AddBookmark"),
},
ReaderView: {
title: "reader-view",
image: "chrome://browser/skin/readerMode.svg",
type: kInputTypes.BUTTON,
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: "chrome://browser/skin/search-glass.svg",
type: kInputTypes.MAIN_BUTTON,
type: "mainButton",
callback: () => execCommand("Browser:OpenLocation", "OpenLocation"),
},
// This is a special-case `type: kInputTypes.SCRUBBER` element.
// 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: "chrome://browser/skin/share.svg",
type: kInputTypes.SCRUBBER,
callback: () => execCommand("cmd_share", "Share"),
},
SearchPopover: {
title: "search-popover",
image: "chrome://browser/skin/search-glass.svg",
type: kInputTypes.POPOVER,
children: {
SearchScrollViewLabel: {
title: "search-search-in",
type: kInputTypes.LABEL,
},
SearchScrollView: {
key: "search-scrollview",
type: kInputTypes.SCROLLVIEW,
children: {
Bookmarks: {
title: "search-bookmarks",
type: kInputTypes.BUTTON,
callback: () =>
gTouchBarHelper.insertRestrictionInUrlbar(
UrlbarTokenizer.RESTRICT.BOOKMARK
),
},
History: {
title: "search-history",
type: kInputTypes.BUTTON,
callback: () =>
gTouchBarHelper.insertRestrictionInUrlbar(
UrlbarTokenizer.RESTRICT.HISTORY
),
},
OpenTabs: {
title: "search-opentabs",
type: kInputTypes.BUTTON,
callback: () =>
gTouchBarHelper.insertRestrictionInUrlbar(
UrlbarTokenizer.RESTRICT.OPENPAGE
),
},
Tags: {
title: "search-tags",
type: kInputTypes.BUTTON,
callback: () =>
gTouchBarHelper.insertRestrictionInUrlbar(
UrlbarTokenizer.RESTRICT.TAG
),
},
Titles: {
title: "search-titles",
type: kInputTypes.BUTTON,
callback: () =>
gTouchBarHelper.insertRestrictionInUrlbar(
UrlbarTokenizer.RESTRICT.TITLE
),
},
},
},
},
},
};
const kHelperObservers = new Set([
@ -235,8 +154,6 @@ const kHelperObservers = new Set([
"touchbar-location-change",
"quit-application",
"intl:app-locales-changed",
"urlbar-focus",
"urlbar-blur",
]);
/**
@ -248,20 +165,16 @@ class TouchBarHelper {
for (let topic of kHelperObservers) {
Services.obs.addObserver(this, topic);
}
// We cache our search popover since otherwise it is frequently
// created/destroyed for the urlbar-focus/blur events.
this._searchPopover = this.getTouchBarInput("SearchPopover");
}
destructor() {
this._searchPopover = null;
for (let topic of kHelperObservers) {
Services.obs.removeObserver(this, topic);
}
}
get activeTitle() {
let tabbrowser = TouchBarHelper.window.ownerGlobal.gBrowser;
let tabbrowser = this.window.ownerGlobal.gBrowser;
let activeTitle;
if (tabbrowser) {
activeTitle = tabbrowser.selectedBrowser.contentTitle;
@ -288,25 +201,15 @@ class TouchBarHelper {
return layoutItems;
}
static get window() {
get window() {
return BrowserWindowTracker.getTopWindow();
}
get isUrlbarFocused() {
return TouchBarHelper.window.gURLBar.focused;
}
static get baseWindow() {
return TouchBarHelper.window.docShell.treeOwner.QueryInterface(
Ci.nsIBaseWindow
);
get bookmarkingUI() {
return this.window.BookmarkingUI;
}
getTouchBarInput(inputName) {
if (inputName == "SearchPopover" && this._searchPopover) {
return this._searchPopover;
}
// inputName might be undefined if an input's context() returns undefined.
if (!inputName || !kBuiltInInputs.hasOwnProperty(inputName)) {
return null;
@ -324,13 +227,8 @@ class TouchBarHelper {
let inputData = kBuiltInInputs[inputName];
let item = new TouchBarInput(inputData);
// Skip localization if there is already a cached localized title or if
// no title is needed.
if (
kBuiltInInputs[inputName].hasOwnProperty("localTitle") ||
!kBuiltInInputs[inputName].hasOwnProperty("title")
) {
// Skip localization if there is already a cached localized title.
if (kBuiltInInputs[inputName].hasOwnProperty("localTitle")) {
return item;
}
@ -338,11 +236,15 @@ class TouchBarHelper {
this._l10n.formatValue(item.key).then(result => {
item.title = result;
kBuiltInInputs[inputName].localTitle = result; // Cache result.
// Checking TouchBarHelper.window since this callback can fire after all windows are closed.
if (TouchBarHelper.window) {
gTouchBarUpdater.updateTouchBarInputs(TouchBarHelper.baseWindow, [
item,
]);
// 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.updateTouchBarInputs(baseWindow, [item]);
}
});
@ -357,7 +259,7 @@ class TouchBarHelper {
* Additional keys to values in the kBuiltInInputs object in this file.
*/
_updateTouchBarInputs(...inputNames) {
if (!TouchBarHelper.window) {
if (!this.window) {
return;
}
@ -370,23 +272,13 @@ class TouchBarHelper {
inputs.push(input);
}
gTouchBarUpdater.updateTouchBarInputs(TouchBarHelper.baseWindow, inputs);
}
/**
* Inserts a restriction token into the Urlbar ahead of the current typed
* search term.
* @param {string} restrictionToken
* The restriction token to be inserted into the Urlbar. Preferably
* sourced from UrlbarTokenizer.RESTRICT.
*/
insertRestrictionInUrlbar(restrictionToken) {
let searchString = TouchBarHelper.window.gURLBar.lastSearchString.trimStart();
if (Object.values(UrlbarTokenizer.RESTRICT).includes(searchString[0])) {
searchString = searchString.substring(1).trimStart();
}
TouchBarHelper.window.gURLBar.search(`${restrictionToken} ${searchString}`);
let baseWindow = this.window.docShell.treeOwner.QueryInterface(
Ci.nsIBaseWindow
);
let updater = Cc["@mozilla.org/widget/touchbarupdater;1"].getService(
Ci.nsITouchBarUpdater
);
updater.updateTouchBarInputs(baseWindow, inputs);
}
observe(subject, topic, data) {
@ -396,10 +288,8 @@ class TouchBarHelper {
// ReaderView button is disabled on every location change since
// Reader View must determine if the new page can be Reader Viewed.
kBuiltInInputs.ReaderView.disabled = !data.startsWith("about:reader");
kBuiltInInputs.Back.disabled = !TouchBarHelper.window.gBrowser
.canGoBack;
kBuiltInInputs.Forward.disabled = !TouchBarHelper.window.gBrowser
.canGoForward;
kBuiltInInputs.Back.disabled = !this.window.gBrowser.canGoBack;
kBuiltInInputs.Forward.disabled = !this.window.gBrowser.canGoForward;
this._updateTouchBarInputs("ReaderView", "Back", "Forward");
break;
case "bookmark-icon-updated":
@ -414,29 +304,8 @@ class TouchBarHelper {
kBuiltInInputs.ReaderView.disabled = false;
this._updateTouchBarInputs("ReaderView");
break;
case "urlbar-focus":
if (!this._searchPopover) {
this._searchPopover = this.getTouchBarInput("SearchPopover");
}
gTouchBarUpdater.showPopover(
TouchBarHelper.baseWindow,
this._searchPopover,
true
);
break;
case "urlbar-blur":
if (!this._searchPopover) {
this._searchPopover = this.getTouchBarInput("SearchPopover");
}
gTouchBarUpdater.showPopover(
TouchBarHelper.baseWindow,
this._searchPopover,
false
);
break;
case "intl:app-locales-changed":
// On locale change, refresh all inputs after loading new localTitle.
this._searchPopover = null;
for (let input in kBuiltInInputs) {
delete input.localTitle;
}
@ -458,6 +327,7 @@ 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.
@ -471,46 +341,21 @@ helperProto._l10n = new Localization(["browser/touchbar/touchbar.ftl"]);
* One of `button`, `mainButton`.
* @param {Function} input.callback
* A callback invoked when a touchbar item is touched.
* @param {string} [input.color]
* @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]
* @param {bool} input.disabled (optional)
* If `true`, the Touch Bar input is greyed out and inoperable.
* @param {Array} [input.children]
* An array of input objects that will be displayed as children of
* this input. Available only for types KInputTypes.POPOVER and
* kInputTypes.SCROLLVIEW.
*/
class TouchBarInput {
constructor(input) {
this._key = input.key || input.title;
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;
if (input.children) {
this._children = [];
let toLocalize = [];
for (let childData of Object.values(input.children)) {
let initializedChild = new TouchBarInput(childData);
if (!initializedChild) {
continue;
}
// Children's types are prepended by the parent's type. This is so we
// can uniquely identify a child input from a standalone input with
// the same name. (e.g. a button called "back" in a popover would be a
// "popover-button.back" vs. a "button.back").
initializedChild.type = input.type + "-" + initializedChild.type;
this._children.push(initializedChild);
// Skip l10n for inputs without a title or those already localized.
if (childData.title && childData.title != "") {
toLocalize.push(initializedChild);
}
}
this._localizeChildren(toLocalize);
}
}
get key() {
@ -523,7 +368,7 @@ class TouchBarInput {
this._title = title;
}
get image() {
return this._image ? PlacesUtils.toURI(this._image) : null;
return PlacesUtils.toURI(this._image);
}
set image(image) {
this._image = image;
@ -556,35 +401,6 @@ class TouchBarInput {
set disabled(disabled) {
this._disabled = disabled;
}
get children() {
if (!this._children) {
return null;
}
let children = Cc["@mozilla.org/array;1"].createInstance(
Ci.nsIMutableArray
);
for (let child of this._children) {
children.appendElement(child);
}
return children;
}
/**
* Apply Fluent l10n to child inputs.
* @param {Array} children An array of initialized TouchBarInputs.
*/
async _localizeChildren(children) {
let titles = await helperProto._l10n.formatValues(
children.map(child => ({ id: child.key }))
);
// In the TouchBarInput constuctor, we filtered so children contains only
// those inputs with titles to be localized. We can be confident that the
// results in titles match up with the inputs to be localized.
children.forEach(function(child, index) {
child.title = titles[index];
});
gTouchBarUpdater.updateTouchBarInputs(TouchBarHelper.baseWindow, children);
}
}
const inputProto = TouchBarInput.prototype;

Просмотреть файл

@ -2,5 +2,4 @@
support-files =
readerModeArticle.html
[browser_touchbar_searchrestrictions.js]
[browser_touchbar_tests.js]
[browser_touchbar_tests.js]

Просмотреть файл

@ -1,129 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
XPCOMUtils.defineLazyModuleGetters(this, {
UrlbarTokenizer: "resource:///modules/UrlbarTokenizer.jsm",
});
XPCOMUtils.defineLazyServiceGetter(
this,
"TouchBarHelper",
"@mozilla.org/widget/touchbarhelper;1",
"nsITouchBarHelper"
);
add_task(async function insertTokens() {
const tests = [
{
input: "",
token: UrlbarTokenizer.RESTRICT.HISTORY,
expected: "^ ",
},
{
input: "mozilla",
token: UrlbarTokenizer.RESTRICT.HISTORY,
expected: "^ mozilla",
},
{
input: "mozilla",
token: UrlbarTokenizer.RESTRICT.BOOKMARK,
expected: "* mozilla",
},
{
input: "mozilla",
token: UrlbarTokenizer.RESTRICT.TAG,
expected: "+ mozilla",
},
{
input: "mozilla",
token: UrlbarTokenizer.RESTRICT.OPENPAGE,
expected: "% mozilla",
},
{
input: "mozilla",
token: UrlbarTokenizer.RESTRICT.TITLE,
expected: "# mozilla",
},
];
let win = BrowserWindowTracker.getTopWindow();
for (let { input, token, expected } of tests) {
win.gURLBar.search(input);
TouchBarHelper.insertRestrictionInUrlbar(token);
Assert.equal(
win.gURLBar.value,
expected,
"The search restriction token should have been entered."
);
}
});
add_task(async function existingTokens() {
const tests = [
{
input: "* mozilla",
token: UrlbarTokenizer.RESTRICT.HISTORY,
expected: "^ mozilla",
},
{
input: "+ mozilla",
token: UrlbarTokenizer.RESTRICT.BOOKMARK,
expected: "* mozilla",
},
{
input: "( $ ^ mozilla",
token: UrlbarTokenizer.RESTRICT.TAG,
expected: "+ ( $ ^ mozilla",
},
{
input: "^*+%?#$ mozilla",
token: UrlbarTokenizer.RESTRICT.TAG,
expected: "+ *+%?#$ mozilla",
},
];
let win = BrowserWindowTracker.getTopWindow();
for (let { input, token, expected } of tests) {
win.gURLBar.search(input);
TouchBarHelper.insertRestrictionInUrlbar(token);
Assert.equal(
win.gURLBar.value,
expected,
"The search restriction token should have been replaced."
);
}
});
add_task(async function stripSpaces() {
const tests = [
{
input: " ^ mozilla",
token: UrlbarTokenizer.RESTRICT.HISTORY,
expected: "^ mozilla",
},
{
input: " + mozilla ",
token: UrlbarTokenizer.RESTRICT.BOOKMARK,
expected: "* mozilla ",
},
{
input: " moz illa ",
token: UrlbarTokenizer.RESTRICT.TAG,
expected: "+ moz illa ",
},
];
let win = BrowserWindowTracker.getTopWindow();
for (let { input, token, expected } of tests) {
win.gURLBar.search(input);
TouchBarHelper.insertRestrictionInUrlbar(token);
Assert.equal(
win.gURLBar.value,
expected,
"The search restriction token should have been entered " +
"with stripped whitespace."
);
}
});

Просмотреть файл

@ -983,14 +983,6 @@ class UrlbarInput {
return this._setValue(val, true);
}
get lastSearchString() {
return this._lastSearchString;
}
get openViewOnFocus() {
return this._openViewOnFocus;
}
get openViewOnFocusForCurrentTab() {
return (
this._openViewOnFocusAndSearchString ||
@ -1782,8 +1774,6 @@ class UrlbarInput {
if (this.getAttribute("pageproxystate") != "valid") {
this.window.UpdatePopupNotificationsVisibility();
}
Services.obs.notifyObservers(null, "urlbar-blur");
}
_on_click(event) {
@ -1824,8 +1814,6 @@ class UrlbarInput {
if (this.getAttribute("pageproxystate") != "valid") {
this.window.UpdatePopupNotificationsVisibility();
}
Services.obs.notifyObservers(null, "urlbar-focus");
}
_on_mouseover(event) {

Просмотреть файл

@ -18,17 +18,3 @@ open-location = Search or enter address
share = Share
close-window = Close Window
open-sidebar = Sidebars
# This string describes shortcuts for search.
search-popover = Search shortcuts
# Describes searches limited to a specific scope
# (e.g. searching only in history).
search-search-in = Search in:
## Various categories of shortcuts for search.
search-bookmarks = Bookmarks
search-history = History
search-opentabs = Open Tabs
search-tags = Tags
search-titles = Titles
##

Просмотреть файл

@ -74,7 +74,6 @@ def Libxul(name, output_category=None):
LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSSharingServicePickerTouchBarItem']
LDFLAGS += ['-Wl,-U,_OBJC_METACLASS_$_NSTouchBar']
LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSCustomTouchBarItem']
LDFLAGS += ['-Wl,-U,_OBJC_CLASS_$_NSPopoverTouchBarItem']
LDFLAGS += ['-lresolv']
if CONFIG['MOZ_DEBUG_SYMBOLS'] and CONFIG['CC_TYPE'] == 'clang-cl':

Просмотреть файл

@ -25,10 +25,10 @@ using namespace mozilla::dom;
NSString* mType;
NSColor* mColor;
BOOL mDisabled;
NSTouchBarItemIdentifier mNativeIdentifier;
nsCOMPtr<nsITouchBarInputCallback> mCallback;
RefPtr<Document> mDocument;
BOOL mIsIconPositionSet;
NSMutableArray<TouchBarInput*>* mChildren;
}
- (NSString*)key;
@ -42,7 +42,6 @@ using namespace mozilla::dom;
- (nsCOMPtr<nsITouchBarInputCallback>)callback;
- (RefPtr<Document>)document;
- (BOOL)isIconPositionSet;
- (NSMutableArray<TouchBarInput*>*)children;
- (void)setKey:(NSString*)aKey;
- (void)setTitle:(NSString*)aTitle;
- (void)setImageURI:(nsCOMPtr<nsIURI>)aImageURI;
@ -50,10 +49,10 @@ using namespace mozilla::dom;
- (void)setType:(NSString*)aType;
- (void)setColor:(NSColor*)aColor;
- (void)setDisabled:(BOOL)aDisabled;
- (void)setNativeIdentifier:(NSString*)aNativeIdentifier;
- (void)setCallback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback;
- (void)setDocument:(RefPtr<Document>)aDocument;
- (void)setIconPositionSet:(BOOL)aIsIconPositionSet;
- (void)setChildren:(NSMutableArray<TouchBarInput*>*)aChildren;
- (id)initWithKey:(NSString*)aKey
title:(NSString*)aTitle
@ -62,22 +61,12 @@ using namespace mozilla::dom;
callback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback
color:(uint32_t)aColor
disabled:(BOOL)aDisabled
document:(RefPtr<Document>)aDocument
children:(nsCOMPtr<nsIArray>)aChildren;
document:(RefPtr<Document>)aDocument;
- (TouchBarInput*)initWithXPCOM:(nsCOMPtr<nsITouchBarInput>)aInput;
- (void)releaseJSObjects;
- (void)dealloc;
/**
* We make this helper method static so that other classes can query a
* TouchBarInput's nativeIdentifier (e.g. nsTouchBarUpdater looking up a
* popover in mappedLayoutItems).
*/
+ (NSTouchBarItemIdentifier)nativeIdentifierWithType:(NSString*)aType withKey:(NSString*)aKey;
@end
/**
@ -103,26 +92,12 @@ using namespace mozilla::dom;
*/
@property(strong) NSMutableDictionary<NSTouchBarItemIdentifier, TouchBarInput*>* mappedLayoutItems;
/**
* Stores buttons displayed in a NSScrollView. They must be stored separately
* because they are generic NSButtons and not NSTouchBarItems. As such, they
* cannot be retrieved with [NSTouchBar itemForIdentifier].
*/
@property(strong) NSMutableDictionary<NSTouchBarItemIdentifier, NSButton*>* scrollViewButtons;
/**
* Returns an instance of nsTouchBar based on implementation details
* fetched from the frontend through nsTouchBarHelper.
*/
- (instancetype)init;
/**
* If aInputs is not nil, a nsTouchBar containing the inputs specified is
* initialized. Otherwise, a nsTouchBar is initialized containing a default set
* of inputs.
*/
- (instancetype)initWithInputs:(NSMutableArray<TouchBarInput*>*)aInputs;
- (void)dealloc;
/**
@ -137,45 +112,18 @@ using namespace mozilla::dom;
/**
* Updates an input on the Touch Bar by redirecting to one of the specific
* TouchBarItem types updaters.
* Returns true if the input was successfully updated.
*/
- (bool)updateItem:(TouchBarInput*)aInput;
/**
* Helper function for updateItem. Checks to see if a given input exists within
* any of this Touch Bar's popovers and updates it if it exists.
*/
- (bool)maybeUpdatePopoverChild:(TouchBarInput*)aInput;
/**
* Helper function for updateItem. Checks to see if a given input exists within
* any of this Touch Bar's scroll views and updates it if it exists.
*/
- (bool)maybeUpdateScrollViewChild:(TouchBarInput*)aInput;
/**
* Helper function for updateItem. Replaces an item in the
* self.mappedLayoutItems dictionary.
*/
- (void)replaceMappedLayoutItem:(TouchBarInput*)aItem;
- (void)updateItem:(TouchBarInput*)aInput;
/**
* Update or create various subclasses of TouchBarItem.
*/
- (void)updateButton:(NSButton*)aButton input:(TouchBarInput*)aInput;
- (void)updateMainButton:(NSButton*)aMainButton input:(TouchBarInput*)aInput;
- (void)updatePopover:(NSPopoverTouchBarItem*)aPopoverItem input:(TouchBarInput*)aInput;
- (void)updateScrollView:(NSCustomTouchBarItem*)aScrollViewItem input:(TouchBarInput*)aInput;
- (void)updateLabel:(NSTextField*)aLabel input:(TouchBarInput*)aInput;
- (NSTouchBarItem*)updateButton:(NSCustomTouchBarItem*)aButton input:(TouchBarInput*)aInput;
- (NSTouchBarItem*)updateMainButton:(NSCustomTouchBarItem*)aMainButton input:(TouchBarInput*)aInput;
- (NSTouchBarItem*)makeShareScrubberForIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
/**
* If aShowing is true, aPopover is shown. Otherwise, it is hidden.
*/
- (void)showPopover:(TouchBarInput*)aPopover showing:(bool)aShowing;
/**
* Redirects button actions to the appropriate handler.
* Redirects button actions to the appropriate handler and handles telemetry.
*/
- (void)touchBarAction:(id)aSender;

Просмотреть файл

@ -12,108 +12,72 @@
@implementation nsTouchBar
static const NSTouchBarItemIdentifier BaseIdentifier = @"com.mozilla.firefox.touchbar";
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 =
[TouchBarInput nativeIdentifierWithType:@"scrubber" withKey:@"share"];
// The search popover needs to show/hide depending on if the Urlbar is focused
// when it is created. We keep track of its identifier to accomodate this
// special handling.
static NSTouchBarItemIdentifier SearchPopoverIdentifier =
[TouchBarInput nativeIdentifierWithType:@"popover" withKey:@"search-popover"];
[ScrubberIdentifier stringByAppendingPathExtension:@"share"];
// Used to tie action strings to buttons.
static char sIdentifierAssociationKey;
static const NSArray<NSString*>* kAllowedInputTypes = @[
@"button",
@"mainButton",
@"scrubber",
@"popover",
@"scrollView",
@"label",
];
// The default space between inputs, used where layout is not automatic.
static const uint32_t kInputSpacing = 8;
// The width of buttons in Apple's Share ScrollView. We use this in our
// ScrollViews to give them a native appearance.
static const uint32_t kScrollViewButtonWidth = 144;
static const uint32_t kInputIconSize = 16;
// The system default width for Touch Bar inputs is 128px. This is double.
#define MAIN_BUTTON_WIDTH 256
#pragma mark - NSTouchBarDelegate
- (instancetype)init {
return [self initWithInputs:nil];
}
- (instancetype)initWithInputs:(NSMutableArray<TouchBarInput*>*)aInputs {
if ((self = [super init])) {
mTouchBarHelper = do_GetService(NS_TOUCHBARHELPER_CID);
if (!mTouchBarHelper) {
NS_ERROR("Unable to create Touch Bar Helper.");
return nil;
}
self.delegate = self;
// This customization identifier is how users' custom layouts are saved by macOS.
// If this changes, all users' layouts would be reset to the default layout.
self.customizationIdentifier = @"com.mozilla.firefox.touchbar.defaultbar";
self.mappedLayoutItems = [NSMutableDictionary dictionary];
self.customizationAllowedItemIdentifiers = nil;
nsCOMPtr<nsIArray> allItems;
if (!aInputs) {
// This customization identifier is how users' custom layouts are saved by macOS.
// If this changes, all users' layouts would be reset to the default layout.
self.customizationIdentifier = [BaseIdentifier stringByAppendingPathExtension:@"defaultbar"];
nsCOMPtr<nsIArray> allItems;
nsresult rv = mTouchBarHelper->GetAllItems(getter_AddRefs(allItems));
if (NS_FAILED(rv) || !allItems) {
return nil;
}
uint32_t itemCount = 0;
allItems->GetLength(&itemCount);
// This is copied to self.customizationAllowedItemIdentifiers.
// Required since [self.mappedItems allKeys] does not preserve order.
// One slot is added for the spacer item.
NSMutableArray* orderedIdentifiers = [NSMutableArray arrayWithCapacity:itemCount + 1];
for (uint32_t i = 0; i < itemCount; ++i) {
nsCOMPtr<nsITouchBarInput> input = do_QueryElementAt(allItems, 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;
orderedIdentifiers[i] = [convertedInput nativeIdentifier];
}
[orderedIdentifiers addObject:@"NSTouchBarItemIdentifierFlexibleSpace"];
self.customizationAllowedItemIdentifiers = [orderedIdentifiers copy];
NSArray* defaultItemIdentifiers = @[
[TouchBarInput nativeIdentifierWithType:@"button" withKey:@"back"],
[TouchBarInput nativeIdentifierWithType:@"button" withKey:@"forward"],
[TouchBarInput nativeIdentifierWithType:@"button" withKey:@"reload"],
[TouchBarInput nativeIdentifierWithType:@"mainButton" withKey:@"open-location"],
[TouchBarInput nativeIdentifierWithType:@"button" withKey:@"new-tab"],
ShareScrubberIdentifier, SearchPopoverIdentifier
];
self.defaultItemIdentifiers = [defaultItemIdentifiers copy];
} else {
NSMutableArray* defaultItemIdentifiers = [NSMutableArray arrayWithCapacity:[aInputs count]];
for (TouchBarInput* input in aInputs) {
self.mappedLayoutItems[[input nativeIdentifier]] = input;
[defaultItemIdentifiers addObject:[input nativeIdentifier]];
}
self.defaultItemIdentifiers = [defaultItemIdentifiers copy];
nsresult rv = mTouchBarHelper->GetAllItems(getter_AddRefs(allItems));
if (NS_FAILED(rv) || !allItems) {
return nil;
}
uint32_t itemCount = 0;
allItems->GetLength(&itemCount);
// This is copied to self.customizationAllowedItemIdentifiers. Required since
// [self.mappedItems allKeys] does not preserve order.
// One slot is added for the spacer item.
NSMutableArray* orderedIdentifiers = [NSMutableArray arrayWithCapacity:itemCount + 1];
for (uint32_t i = 0; i < itemCount; ++i) {
nsCOMPtr<nsITouchBarInput> input = do_QueryElementAt(allItems, 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;
orderedIdentifiers[i] = [convertedInput nativeIdentifier];
}
[orderedIdentifiers addObject:@"NSTouchBarItemIdentifierFlexibleSpace"];
NSArray* defaultItemIdentifiers = @[
[CustomButtonIdentifier stringByAppendingPathExtension:@"back"],
[CustomButtonIdentifier stringByAppendingPathExtension:@"forward"],
[CustomButtonIdentifier stringByAppendingPathExtension:@"reload"],
[CustomMainButtonIdentifier stringByAppendingPathExtension:@"open-location"],
[CustomButtonIdentifier stringByAppendingPathExtension:@"new-tab"], ShareScrubberIdentifier
];
self.defaultItemIdentifiers = [defaultItemIdentifiers copy];
self.customizationAllowedItemIdentifiers = [orderedIdentifiers copy];
}
return self;
@ -122,25 +86,11 @@ static const uint32_t kInputIconSize = 16;
- (void)dealloc {
for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) {
NSTouchBarItem* item = [self itemForIdentifier:identifier];
if (!item) {
continue;
}
if ([item isKindOfClass:[NSPopoverTouchBarItem class]]) {
[(NSPopoverTouchBarItem*)item setCollapsedRepresentation:nil];
[(NSPopoverTouchBarItem*)item setCollapsedRepresentationImage:nil];
[(nsTouchBar*)[(NSPopoverTouchBarItem*)item popoverTouchBar] release];
} else if ([[item view] isKindOfClass:[NSScrollView class]]) {
[[(NSScrollView*)[item view] documentView] release];
}
[[item view] release];
[item release];
}
[self.defaultItemIdentifiers release];
[self.customizationAllowedItemIdentifiers release];
[self.scrollViewButtons removeAllObjects];
[self.scrollViewButtons release];
[self.mappedLayoutItems removeAllObjects];
[self.mappedLayoutItems release];
[super dealloc];
@ -148,20 +98,7 @@ static const uint32_t kInputIconSize = 16;
- (NSTouchBarItem*)touchBar:(NSTouchBar*)aTouchBar
makeItemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier {
TouchBarInput* input = self.mappedLayoutItems[aIdentifier];
if (!input) {
return nil;
}
// Checking to see if our new item is of an accepted type.
if (![kAllowedInputTypes
containsObject:[[[input type] componentsSeparatedByString:@"-"] lastObject]]) {
return nil;
}
if ([[input type] hasSuffix:@"scrubber"]) {
// We check the identifier rather than the type here as a special case.
if ([aIdentifier hasPrefix:ScrubberIdentifier]) {
if (![aIdentifier isEqualToString:ShareScrubberIdentifier]) {
// We're only supporting the Share scrubber for now.
return nil;
@ -169,253 +106,86 @@ static const uint32_t kInputIconSize = 16;
return [self makeShareScrubberForIdentifier:aIdentifier];
}
if ([[input type] hasSuffix:@"popover"]) {
NSPopoverTouchBarItem* newPopoverItem =
[[NSPopoverTouchBarItem alloc] initWithIdentifier:aIdentifier];
// We initialize popoverTouchBar here because we only allow setting this
// property on popover creation. Updating popoverTouchBar for every update
// of the popover item would be very expensive.
newPopoverItem.popoverTouchBar = [[nsTouchBar alloc] initWithInputs:[input children]];
[self updatePopover:newPopoverItem input:input];
return newPopoverItem;
}
// Our new item, which will be initialized depending on aIdentifier.
NSCustomTouchBarItem* newItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:aIdentifier];
if ([[input type] hasSuffix:@"scrollView"]) {
[self updateScrollView:newItem input:input];
return newItem;
} else if ([[input type] hasSuffix:@"label"]) {
NSTextField* label = [NSTextField labelWithString:@""];
[self updateLabel:label input:input];
newItem.view = label;
return newItem;
}
// The cases of a button or main button require the same setup.
NSButton* button = [NSButton buttonWithTitle:@"" target:self action:@selector(touchBarAction:)];
newItem.view = button;
NSCustomTouchBarItem* item = [[NSCustomTouchBarItem alloc] initWithIdentifier:aIdentifier];
item.view = button;
if ([[input type] hasSuffix:@"button"] && ![[input type] hasPrefix:@"scrollView"]) {
[self updateButton:button input:input];
} else if ([[input type] hasSuffix:@"mainButton"]) {
[self updateMainButton:button input:input];
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 newItem;
return nil;
}
- (bool)updateItem:(TouchBarInput*)aInput {
- (void)updateItem:(TouchBarInput*)aInput {
NSTouchBarItem* item = [self itemForIdentifier:[aInput nativeIdentifier]];
// If we can't immediately find item, there are three possibilities:
// * It is a button in a ScrollView, which can't be found with itemForIdentifier; or
// * It is contained within a popover; or
// * It simply does not exist.
// We check for each possibility here.
if (!item) {
if ([self maybeUpdateScrollViewChild:aInput]) {
[self replaceMappedLayoutItem:aInput];
return true;
}
if ([self maybeUpdatePopoverChild:aInput]) {
[self replaceMappedLayoutItem:aInput];
return true;
}
return false;
}
item.customizationLabel = [aInput title];
if ([[aInput type] hasSuffix:@"button"]) {
[self updateButton:(NSButton*)item.view input:aInput];
} else if ([[aInput type] hasSuffix:@"mainButton"]) {
[self updateMainButton:(NSButton*)item.view input:aInput];
} else if ([[aInput type] hasSuffix:@"scrollView"]) {
[self updateScrollView:(NSCustomTouchBarItem*)item input:aInput];
} else if ([[aInput type] hasSuffix:@"popover"]) {
[self updatePopover:(NSPopoverTouchBarItem*)item input:aInput];
} else if ([[aInput type] hasSuffix:@"label"]) {
[self updateLabel:(NSTextField*)item.view input:aInput];
}
[self replaceMappedLayoutItem:aInput];
return true;
}
- (bool)maybeUpdatePopoverChild:(TouchBarInput*)aInput {
for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) {
TouchBarInput* potentialPopover = self.mappedLayoutItems[identifier];
if (![[potentialPopover type] hasSuffix:@"popover"]) {
continue;
}
NSTouchBarItem* popover = [self itemForIdentifier:[potentialPopover nativeIdentifier]];
if (popover) {
if ([(nsTouchBar*)[(NSPopoverTouchBarItem*)popover popoverTouchBar] updateItem:aInput]) {
return true;
}
}
}
return false;
}
- (bool)maybeUpdateScrollViewChild:(TouchBarInput*)aInput {
NSButton* scrollViewButton = self.scrollViewButtons[[aInput nativeIdentifier]];
if (scrollViewButton) {
// ScrollView buttons are similar to mainButtons except for their width.
[self updateMainButton:scrollViewButton input:aInput];
uint32_t buttonSize =
MAX(scrollViewButton.attributedTitle.size.width + kInputIconSize + kInputSpacing,
kScrollViewButtonWidth);
[[scrollViewButton widthAnchor] constraintGreaterThanOrEqualToConstant:buttonSize].active = YES;
}
// Updating the TouchBarInput* in the ScrollView's mChildren array.
for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) {
TouchBarInput* potentialScrollView = self.mappedLayoutItems[identifier];
if (![[potentialScrollView type] hasSuffix:@"scrollView"]) {
continue;
}
for (uint32_t i = 0; i < [[potentialScrollView children] count]; ++i) {
TouchBarInput* child = [potentialScrollView children][i];
if (![[child nativeIdentifier] isEqualToString:[aInput nativeIdentifier]]) {
continue;
}
[[potentialScrollView children] replaceObjectAtIndex:i withObject:aInput];
[child release];
return true;
}
}
return false;
}
- (void)replaceMappedLayoutItem:(TouchBarInput*)aItem {
[self.mappedLayoutItems[[aItem nativeIdentifier]] release];
self.mappedLayoutItems[[aItem nativeIdentifier]] = aItem;
}
- (void)updateButton:(NSButton*)aButton input:(TouchBarInput*)aInput {
if (!aButton || !aInput) {
return;
}
if ([[aInput nativeIdentifier] hasPrefix:CustomButtonIdentifier]) {
[self updateButton:(NSCustomTouchBarItem*)item input:aInput];
} else if ([[aInput nativeIdentifier] hasPrefix:CustomMainButtonIdentifier]) {
[self updateMainButton:(NSCustomTouchBarItem*)item input:aInput];
}
aButton.title = [aInput title];
[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 isIconPositionSet]) {
[aButton setImagePosition:NSImageOnly];
[button setImagePosition:NSImageOnly];
[aInput setIconPositionSet:true];
}
if ([aInput imageURI]) {
RefPtr<nsTouchBarInputIcon> icon = [aInput icon];
if (!icon) {
icon = new nsTouchBarInputIcon([aInput document], aButton);
icon = new nsTouchBarInputIcon([aInput document], button);
[aInput setIcon:icon];
}
icon->SetupIcon([aInput imageURI]);
}
[aButton setEnabled:![aInput isDisabled]];
[button setEnabled:![aInput isDisabled]];
if ([aInput color]) {
aButton.bezelColor = [aInput color];
button.bezelColor = [aInput color];
}
objc_setAssociatedObject(aButton, &sIdentifierAssociationKey, [aInput nativeIdentifier],
objc_setAssociatedObject(button, &sIdentifierAssociationKey, [aInput nativeIdentifier],
OBJC_ASSOCIATION_RETAIN);
aButton.customizationLabel = [aInput title];
return aButton;
}
- (void)updateMainButton:(NSButton*)aMainButton input:(TouchBarInput*)aInput {
if (!aMainButton || !aInput) {
return;
}
- (NSTouchBarItem*)updateMainButton:(NSCustomTouchBarItem*)aMainButton
input:(TouchBarInput*)aInput {
NSButton* button = (NSButton*)aMainButton.view;
// If empty, string is still being localized. Display a blank input instead.
if ([[aInput title] isEqualToString:@""]) {
[aMainButton setImagePosition:NSNoImage];
[button setImagePosition:NSNoImage];
} else {
[aMainButton setImagePosition:NSImageLeft];
[button setImagePosition:NSImageLeft];
}
aMainButton.imageHugsTitle = YES;
button.imageHugsTitle = YES;
[aInput setIconPositionSet:true];
[self updateButton:aMainButton input:aInput];
[aMainButton.widthAnchor constraintGreaterThanOrEqualToConstant:MAIN_BUTTON_WIDTH].active = YES;
[aMainButton setContentHuggingPriority:1.0
forOrientation:NSLayoutConstraintOrientationHorizontal];
}
- (void)updatePopover:(NSPopoverTouchBarItem*)aPopoverItem input:(TouchBarInput*)aInput {
if (!aPopoverItem || !aInput) {
return;
}
aPopoverItem.showsCloseButton = YES;
if ([aInput imageURI]) {
RefPtr<nsTouchBarInputIcon> icon = [aInput icon];
if (!icon) {
icon = new nsTouchBarInputIcon([aInput document], nil, nil, aPopoverItem);
[aInput setIcon:icon];
}
icon->SetupIcon([aInput imageURI]);
} else if ([aInput title]) {
aPopoverItem.collapsedRepresentationLabel = [aInput title];
} else {
aPopoverItem.collapsedRepresentation = nil;
}
}
- (void)updateScrollView:(NSCustomTouchBarItem*)aScrollViewItem input:(TouchBarInput*)aInput {
if (!aScrollViewItem || ![aInput children]) {
return;
}
NSMutableDictionary* constraintViews = [NSMutableDictionary dictionary];
NSView* documentView = [[NSView alloc] initWithFrame:NSZeroRect];
NSString* layoutFormat = @"H:|-8-";
NSSize size = NSMakeSize(kInputSpacing, 30);
// Layout strings allow only alphanumeric characters. We will use this
// NSCharacterSet to strip illegal characters.
NSCharacterSet* charactersToRemove = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
for (TouchBarInput* childInput in [aInput children]) {
if (![[childInput type] hasSuffix:@"button"]) {
continue;
}
NSButton* button = [NSButton buttonWithTitle:[childInput title]
target:self
action:@selector(touchBarAction:)];
// ScrollView buttons are similar to mainButtons except for their width.
[self updateMainButton:button input:childInput];
uint32_t buttonSize = MAX(button.attributedTitle.size.width + kInputIconSize + kInputSpacing,
kScrollViewButtonWidth);
[[button widthAnchor] constraintGreaterThanOrEqualToConstant:buttonSize].active = YES;
self.scrollViewButtons[[childInput nativeIdentifier]] = button;
button.translatesAutoresizingMaskIntoConstraints = NO;
[documentView addSubview:button];
NSString* layoutKey = [[[childInput nativeIdentifier]
componentsSeparatedByCharactersInSet:charactersToRemove] componentsJoinedByString:@""];
// Iteratively create our layout string.
layoutFormat =
[layoutFormat stringByAppendingString:[NSString stringWithFormat:@"[%@]-8-", layoutKey]];
[constraintViews setObject:button forKey:layoutKey];
size.width += kInputSpacing + buttonSize;
}
layoutFormat = [layoutFormat stringByAppendingString:[NSString stringWithFormat:@"|"]];
NSArray* hConstraints =
[NSLayoutConstraint constraintsWithVisualFormat:layoutFormat
options:NSLayoutFormatAlignAllCenterY
metrics:nil
views:constraintViews];
NSScrollView* scrollView =
[[NSScrollView alloc] initWithFrame:CGRectMake(0, 0, size.width, size.height)];
[documentView setFrame:NSMakeRect(0, 0, size.width, size.height)];
[NSLayoutConstraint activateConstraints:hConstraints];
scrollView.documentView = documentView;
aScrollViewItem.view = scrollView;
}
- (void)updateLabel:(NSTextField*)aLabel input:aInput {
if (!aLabel || ![aInput title]) {
return;
}
[aLabel setStringValue:[aInput title]];
aMainButton = (NSCustomTouchBarItem*)[self updateButton:aMainButton input:aInput];
[button.widthAnchor constraintGreaterThanOrEqualToConstant:MAIN_BUTTON_WIDTH].active = YES;
[button setContentHuggingPriority:1.0 forOrientation:NSLayoutConstraintOrientationHorizontal];
return aMainButton;
}
- (NSTouchBarItem*)makeShareScrubberForIdentifier:(NSTouchBarItemIdentifier)aIdentifier {
@ -440,22 +210,6 @@ static const uint32_t kInputIconSize = 16;
return servicesItem;
}
- (void)showPopover:(TouchBarInput*)aPopover showing:(bool)aShowing {
if (!aPopover) {
return;
}
NSPopoverTouchBarItem* popoverItem =
(NSPopoverTouchBarItem*)[self itemForIdentifier:[aPopover nativeIdentifier]];
if (!popoverItem) {
return;
}
if (aShowing) {
[popoverItem showPopover:self];
} else {
[popoverItem dismissPopover:self];
}
}
- (void)touchBarAction:(id)aSender {
NSTouchBarItemIdentifier identifier =
objc_getAssociatedObject(aSender, &sIdentifierAssociationKey);
@ -482,23 +236,13 @@ static const uint32_t kInputIconSize = 16;
for (NSTouchBarItemIdentifier identifier in self.mappedLayoutItems) {
TouchBarInput* input = self.mappedLayoutItems[identifier];
if (!input) {
continue;
RefPtr<nsTouchBarInputIcon> icon = [input icon];
if (icon) {
icon->ReleaseJSObjects();
}
// Childless popovers contain the default Touch Bar as its popoverTouchBar.
// We check for [input children] since the default Touch Bar contains a
// popover (search-popover), so this would infinitely loop if there was no check.
if ([[input type] hasSuffix:@"popover"] && [input children]) {
NSTouchBarItem* item = [self itemForIdentifier:identifier];
[(nsTouchBar*)[(NSPopoverTouchBarItem*)item popoverTouchBar] releaseJSObjects];
}
[input setCallback:nil];
[input setDocument:nil];
[input setImageURI:nil];
[input releaseJSObjects];
}
}
@ -575,7 +319,7 @@ static const uint32_t kInputIconSize = 16;
return mDisabled;
}
- (NSTouchBarItemIdentifier)nativeIdentifier {
return [TouchBarInput nativeIdentifierWithType:mType withKey:mKey];
return mNativeIdentifier;
}
- (nsCOMPtr<nsITouchBarInputCallback>)callback {
return mCallback;
@ -586,9 +330,6 @@ static const uint32_t kInputIconSize = 16;
- (BOOL)isIconPositionSet {
return mIsIconPositionSet;
}
- (NSMutableArray<TouchBarInput*>*)children {
return mChildren;
}
- (void)setKey:(NSString*)aKey {
[aKey retain];
[mKey release];
@ -625,6 +366,12 @@ static const uint32_t kInputIconSize = 16;
mDisabled = aDisabled;
}
- (void)setNativeIdentifier:(NSTouchBarItemIdentifier)aNativeIdentifier {
[aNativeIdentifier retain];
[mNativeIdentifier release];
mNativeIdentifier = aNativeIdentifier;
}
- (void)setCallback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback {
mCallback = aCallback;
}
@ -641,16 +388,6 @@ static const uint32_t kInputIconSize = 16;
mIsIconPositionSet = aIsIconPositionSet;
}
- (void)setChildren:(NSMutableArray<TouchBarInput*>*)aChildren {
[aChildren retain];
for (TouchBarInput* child in mChildren) {
[child releaseJSObjects];
}
[mChildren removeAllObjects];
[mChildren release];
mChildren = aChildren;
}
- (id)initWithKey:(NSString*)aKey
title:(NSString*)aTitle
imageURI:(nsCOMPtr<nsIURI>)aImageURI
@ -658,8 +395,7 @@ static const uint32_t kInputIconSize = 16;
callback:(nsCOMPtr<nsITouchBarInputCallback>)aCallback
color:(uint32_t)aColor
disabled:(BOOL)aDisabled
document:(RefPtr<Document>)aDocument
children:(nsCOMPtr<nsIArray>)aChildren {
document:(RefPtr<Document>)aDocument {
if (self = [super init]) {
[self setKey:aKey];
[self setTitle:aTitle];
@ -668,28 +404,29 @@ static const uint32_t kInputIconSize = 16;
[self setCallback:aCallback];
[self setDocument:aDocument];
[self setIconPositionSet:false];
[self setDisabled:aDisabled];
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]];
}
if (aChildren) {
uint32_t itemCount = 0;
aChildren->GetLength(&itemCount);
NSMutableArray* orderedChildren = [NSMutableArray arrayWithCapacity:itemCount];
for (uint32_t i = 0; i < itemCount; ++i) {
nsCOMPtr<nsITouchBarInput> child = do_QueryElementAt(aChildren, i);
if (!child) {
continue;
}
TouchBarInput* convertedChild = [[TouchBarInput alloc] initWithXPCOM:child];
if (convertedChild) {
orderedChildren[i] = convertedChild;
}
}
[self setChildren:orderedChildren];
[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]];
}
}
@ -745,12 +482,6 @@ static const uint32_t kInputIconSize = 16;
return nil;
}
nsCOMPtr<nsIArray> children;
rv = aInput->GetChildren(getter_AddRefs(children));
if (NS_FAILED(rv)) {
return nil;
}
return [self initWithKey:nsCocoaUtils::ToNSString(keyStr)
title:nsCocoaUtils::ToNSString(titleStr)
imageURI:imageURI
@ -758,20 +489,7 @@ static const uint32_t kInputIconSize = 16;
callback:callback
color:colorInt
disabled:(BOOL)disabled
document:document
children:children];
}
- (void)releaseJSObjects {
if (mIcon) {
mIcon->ReleaseJSObjects();
}
mCallback = nil;
mImageURI = nil;
mDocument = nil;
for (TouchBarInput* child in mChildren) {
[child releaseJSObjects];
}
document:document];
}
- (void)dealloc {
@ -783,18 +501,8 @@ static const uint32_t kInputIconSize = 16;
[mTitle release];
[mType release];
[mColor release];
[mChildren removeAllObjects];
[mChildren release];
[mNativeIdentifier release];
[super dealloc];
}
+ (NSTouchBarItemIdentifier)nativeIdentifierWithType:(NSString*)aType withKey:(NSString*)aKey {
NSTouchBarItemIdentifier identifier;
identifier = [BaseIdentifier stringByAppendingPathExtension:aType];
if (aKey) {
identifier = [identifier stringByAppendingPathExtension:aKey];
}
return identifier;
}
@end

Просмотреть файл

@ -26,9 +26,9 @@ class imgRequestProxy;
class nsTouchBarInputIcon : public nsIconLoaderObserver {
public:
explicit nsTouchBarInputIcon(
RefPtr<Document> aDocument, NSButton* aButton,
NSSharingServicePickerTouchBarItem* aShareScrubber = nil,
NSPopoverTouchBarItem* aPopoverItem = nil);
RefPtr<Document> aDocument,
NSButton* aButton,
NSSharingServicePickerTouchBarItem* aShareScrubber = nil);
private:
virtual ~nsTouchBarInputIcon();
@ -59,8 +59,6 @@ class nsTouchBarInputIcon : public nsIconLoaderObserver {
// NSSharingServicePickerTouchBarItem does not expose an NSButton* on which we
// can set the `image` property.
NSSharingServicePickerTouchBarItem* mShareScrubber;
// We accept a popover only as a special case.
NSPopoverTouchBarItem* mPopoverItem;
// The icon loader object should never outlive its creating
// nsTouchBarInputIcon object.
RefPtr<nsIconLoaderService> mIconLoader;

Просмотреть файл

@ -22,14 +22,10 @@ using namespace mozilla;
static const uint32_t kIconSize = 16;
static const CGFloat kHiDPIScalingFactor = 2.0f;
nsTouchBarInputIcon::nsTouchBarInputIcon(RefPtr<Document> aDocument, NSButton* aButton,
NSSharingServicePickerTouchBarItem* aShareScrubber,
NSPopoverTouchBarItem* aPopoverItem)
: mDocument(aDocument),
mSetIcon(false),
mButton(aButton),
mShareScrubber(aShareScrubber),
mPopoverItem(aPopoverItem) {
nsTouchBarInputIcon::nsTouchBarInputIcon(RefPtr<Document> aDocument,
NSButton* aButton,
NSSharingServicePickerTouchBarItem* aShareScrubber)
: mDocument(aDocument), mSetIcon(false), mButton(aButton), mShareScrubber(aShareScrubber) {
MOZ_COUNT_CTOR(nsTouchBarInputIcon);
}
@ -49,14 +45,13 @@ void nsTouchBarInputIcon::Destroy() {
mButton = nil;
mShareScrubber = nil;
mPopoverItem = nil;
}
nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
// Still don't have one, then something is wrong, get out of here.
if (!(mButton || mShareScrubber || mPopoverItem)) {
if (!(mButton || mShareScrubber)) {
NS_ERROR("No Touch Bar button");
return NS_ERROR_FAILURE;
}
@ -75,7 +70,6 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) {
// Load placeholder icon.
[mButton setImage:mIconLoader->GetNativeIconImage()];
[mShareScrubber setButtonImage:mIconLoader->GetNativeIconImage()];
[mPopoverItem setCollapsedRepresentationImage:mIconLoader->GetNativeIconImage()];
}
nsresult rv = mIconLoader->LoadIcon(aIconURI);
@ -85,7 +79,6 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) {
// been set. Clear it.
[mButton setImage:nil];
[mShareScrubber setButtonImage:nil];
[mPopoverItem setCollapsedRepresentationImage:nil];
}
mSetIcon = true;
@ -102,7 +95,6 @@ nsresult nsTouchBarInputIcon::SetupIcon(nsCOMPtr<nsIURI> aIconURI) {
nsresult nsTouchBarInputIcon::OnComplete(NSImage* aImage) {
[mButton setImage:aImage];
[mShareScrubber setButtonImage:aImage];
[mPopoverItem setCollapsedRepresentationImage:aImage];
[aImage release];
return NS_OK;

Просмотреть файл

@ -19,10 +19,6 @@
blue:(CGFloat)blue
alpha:(CGFloat)alpha;
@end
@interface NSTextField (NewConstructors)
+ (NSTextField*)labelWithString:(NSString*)stringValue;
@end
#endif // !defined(MAC_OS_X_VERSION_10_12)
#if !defined(MAC_OS_X_VERSION_10_12_2) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12_2
@ -32,8 +28,6 @@
typedef NSString* NSTouchBarItemIdentifier;
__attribute__((weak_import)) @interface NSTouchBarItem : NSObject
@property(readonly) NSView* view;
@property(strong) NSString* customizationLabel;
- (instancetype)initWithIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
@end
@ -47,6 +41,7 @@ __attribute__((weak_import)) @interface NSSharingServicePickerTouchBarItem : NST
__attribute__((weak_import)) @interface NSCustomTouchBarItem : NSTouchBarItem
@property(strong) NSView* view;
@property(strong) NSString* customizationLabel;
@end
@protocol NSTouchBarDelegate
@ -61,16 +56,6 @@ __attribute__((weak_import)) @interface NSTouchBar : NSObject
- (NSTouchBarItem*)itemForIdentifier:(NSTouchBarItemIdentifier)aIdentifier;
@end
__attribute__((weak_import)) @interface NSPopoverTouchBarItem : NSTouchBarItem
@property(strong) NSView* collapsedRepresentation;
@property(strong) NSImage* collapsedRepresentationImage;
@property(strong) NSString* collapsedRepresentationLabel;
@property(strong) NSTouchBar* popoverTouchBar;
@property BOOL showsCloseButton;
- (void)showPopover:(id)sender;
- (void)dismissPopover:(id)sender;
@end
@interface NSButton (TouchBarButton)
@property(strong) NSColor* bezelColor;
@end

Просмотреть файл

@ -6,7 +6,6 @@
#define nsTouchBarUpdater_h_
#include "nsITouchBarUpdater.h"
#include "nsCocoaWindow.h"
class nsTouchBarUpdater : public nsITouchBarUpdater {
public:
@ -17,7 +16,6 @@ class nsTouchBarUpdater : public nsITouchBarUpdater {
protected:
virtual ~nsTouchBarUpdater() {}
BaseWindow* GetCocoaWindow(nsIBaseWindow* aWindow);
};
#endif // nsTouchBarUpdater_h_

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsTouchBarUpdater.h"
#include "nsTouchBarNativeAPIDefines.h"
#include "nsCocoaWindow.h"
#include "nsIArray.h"
#include "nsIBaseWindow.h"
#include "nsIWidget.h"
@ -27,11 +28,12 @@ NS_IMPL_ISUPPORTS(nsTouchBarUpdater, nsITouchBarUpdater);
NS_IMETHODIMP
nsTouchBarUpdater::UpdateTouchBarInputs(nsIBaseWindow* aWindow,
const nsTArray<RefPtr<nsITouchBarInput>>& aInputs) {
if (!sTouchBarIsInitialized) {
return NS_OK;
nsCOMPtr<nsIWidget> widget = nullptr;
aWindow->GetMainWidget(getter_AddRefs(widget));
if (!widget) {
return NS_ERROR_FAILURE;
}
BaseWindow* cocoaWin = nsTouchBarUpdater::GetCocoaWindow(aWindow);
BaseWindow* cocoaWin = (BaseWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
if (!cocoaWin) {
return NS_ERROR_FAILURE;
}
@ -52,42 +54,6 @@ nsTouchBarUpdater::UpdateTouchBarInputs(nsIBaseWindow* aWindow,
return NS_OK;
}
NS_IMETHODIMP
nsTouchBarUpdater::ShowPopover(nsIBaseWindow* aWindow, nsITouchBarInput* aPopover, bool aShowing) {
if (!sTouchBarIsInitialized || !aPopover) {
return NS_OK;
}
BaseWindow* cocoaWin = nsTouchBarUpdater::GetCocoaWindow(aWindow);
if (!cocoaWin) {
return NS_ERROR_FAILURE;
}
if ([cocoaWin respondsToSelector:@selector(touchBar)]) {
// We don't need to completely reinitialize the popover. We only need its
// identifier to look it up in [nsTouchBar mappedLayoutItems].
nsAutoString keyStr;
nsresult rv = aPopover->GetKey(keyStr);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
NSString* key = nsCocoaUtils::ToNSString(keyStr);
nsAutoString typeStr;
rv = aPopover->GetType(typeStr);
if (NS_FAILED(rv)) {
return NS_ERROR_FAILURE;
}
NSString* type = nsCocoaUtils::ToNSString(typeStr);
TouchBarInput* popoverItem = [[(nsTouchBar*)cocoaWin.touchBar mappedLayoutItems]
objectForKey:[TouchBarInput nativeIdentifierWithType:type withKey:key]];
[(nsTouchBar*)cocoaWin.touchBar showPopover:popoverItem showing:aShowing];
}
return NS_OK;
}
NS_IMETHODIMP
nsTouchBarUpdater::EnterCustomizeMode() {
[NSApp toggleTouchBarCustomizationPalette:(id)this];
@ -100,19 +66,6 @@ nsTouchBarUpdater::IsTouchBarInitialized(bool* aResult) {
return NS_OK;
}
BaseWindow* nsTouchBarUpdater::GetCocoaWindow(nsIBaseWindow* aWindow) {
nsCOMPtr<nsIWidget> widget = nullptr;
aWindow->GetMainWidget(getter_AddRefs(widget));
if (!widget) {
return nil;
}
BaseWindow* cocoaWin = (BaseWindow*)widget->GetNativeData(NS_NATIVE_WINDOW);
if (!cocoaWin) {
return nil;
}
return cocoaWin;
}
// NOTE: This method is for internal unit tests only.
NS_IMETHODIMP
nsTouchBarUpdater::SetTouchBarInitialized(bool aIsInitialized) {

Просмотреть файл

@ -22,11 +22,6 @@ interface nsITouchBarHelper : nsISupports
*/
readonly attribute AString activeTitle;
/**
* Return true if the Urlbar has focus.
*/
readonly attribute boolean isUrlbarFocused;
/**
* Returns all available Touch Bar Inputs in an nsIArray
* of nsITouchBarInput objects.
@ -38,10 +33,4 @@ interface nsITouchBarHelper : nsISupports
* Exposed for testing.
*/
nsITouchBarInput getTouchBarInput(in string aInputName);
/**
* Inserts a search restriction string in the Urlbar.
* Exposed for testing.
*/
void insertRestrictionInUrlbar(in string aToken);
};

Просмотреть файл

@ -65,10 +65,4 @@ interface nsITouchBarInput : nsISupports
* an imgLoader to load our SVG icons.
*/
readonly attribute Document document;
/**
* An array containing an input's children.
* Available for type = ("scrollView" || "popover").
*/
attribute nsIArray children;
};

Просмотреть файл

@ -34,9 +34,4 @@ interface nsITouchBarUpdater : nsISupports
* sets this value after a Touch Bar is initialized on compatible Macs.
*/
void setTouchBarInitialized(in boolean aIsInitialized);
/**
* If aShowing is true, aPopover is shown. Otherwise, it is hidden.
*/
void showPopover(in nsIBaseWindow aWindow, in nsITouchBarInput aPopover, in boolean aShowing);
};