Skip to content

Commit 52ce3bc

Browse files
committed
♻️ Refactor shared customizable logic and improve child capabilities on areas
1 parent 6819dec commit 52ce3bc

13 files changed

+241
-256
lines changed

components/customizableui/BrowserCustomizable.sys.mjs

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ BrowserCustomizable.prototype = {
6161
this.state = data;
6262

6363
if (permanent) {
64-
Services.prefs.setStringPref(
65-
Shared.customizableStatePref,
64+
Shared.customizablePrefs.setStringPref(
65+
"state",
6666
JSON.stringify(data)
6767
);
6868
}
@@ -74,8 +74,8 @@ BrowserCustomizable.prototype = {
7474
* Refetches and validates the customizable state
7575
*/
7676
async _updateState() {
77-
const serialized = Services.prefs.getStringPref(
78-
Shared.customizableStatePref,
77+
const serialized = Shared.customizablePrefs.getStringPref(
78+
"state",
7979
"{}"
8080
);
8181

@@ -99,23 +99,7 @@ BrowserCustomizable.prototype = {
9999
*/
100100
async _paint() {
101101
// Re-init the components singleton
102-
this.internal.initComponents();
103-
104-
const components = this.state.components || {};
105-
106-
Shared.logger.log(
107-
`Registering ${Object.keys(components).length} components...`
108-
);
109-
try {
110-
this.internal.registerCustomComponents(this.renderRoot, components);
111-
} catch (e) {
112-
throw new Error(
113-
"Failure registering custom components:\n" +
114-
e.toString().replace(/^Error: /, "") +
115-
"\n" +
116-
e.stack || ""
117-
);
118-
}
102+
await this.internal.initComponents();
119103

120104
Shared.logger.log("Registering root component...");
121105
let rootElement = null;
@@ -202,8 +186,13 @@ BrowserCustomizable.prototype = {
202186
* Initialises any observers needed for BrowserCustomizable
203187
*/
204188
_initObservers() {
205-
Services.prefs.addObserver(
206-
Shared.customizableStatePref,
189+
Shared.customizablePrefs.addObserver(
190+
"state",
191+
(() => this._update()).bind(this)
192+
);
193+
194+
Shared.customizablePrefs.addObserver(
195+
"components.",
207196
(() => this._update()).bind(this)
208197
);
209198
},
@@ -221,7 +210,6 @@ BrowserCustomizable.prototype = {
221210
this.win = this.renderRoot.ownerGlobal;
222211

223212
this.internal = new BrowserCustomizableInternal(this.win);
224-
this.internal.ensureCustomizableComponents();
225213

226214
this._initObservers();
227215

components/customizableui/BrowserCustomizableComponent.sys.mjs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
export class BrowserCustomizableComponent {
6-
static TYPE_WIDGET = 0;
7-
static TYPE_AREA = 1;
6+
static TYPE_WIDGET = Symbol("TYPE_WIDGET");
7+
static TYPE_AREA = Symbol("TYPE_AREA");
88

99
/**
1010
* The ID or type of this customizable component
@@ -15,7 +15,7 @@ export class BrowserCustomizableComponent {
1515

1616
/**
1717
* The type of this component
18-
* @type {number}
18+
* @type {symbol}
1919
*/
2020
type = null;
2121

@@ -39,7 +39,7 @@ export class BrowserCustomizableComponent {
3939
}
4040

4141
/**
42-
* @param {number} type
42+
* @param {symbol} type
4343
* @param {string} id
4444
* @param {({
4545
* doc,

components/customizableui/BrowserCustomizableComponents.sys.mjs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ const { BrowserCustomizableComponent: Component } = ChromeUtils.importESModule(
1111
);
1212

1313
export class BrowserCustomizableComponents {
14-
/** @type {Map<number, Map<string, typeof Component["prototype"]>>} */
14+
/** @type {Map<symbol, Map<string, typeof Component["prototype"]>>} */
1515
components = new Map();
1616

1717
/**
1818
* A list of all elements that can have children
1919
*/
2020
get childCapableElements() {
21-
return ["browser-customizable-area"];
21+
return ["browser-customizable-area", "menupopup"];
2222
}
2323

2424
/**
@@ -34,7 +34,9 @@ export class BrowserCustomizableComponents {
3434
);
3535

3636
if (component) {
37-
return component.render(doc, attributes);
37+
const element = component.render(doc, attributes);
38+
39+
return element;
3840
} else {
3941
return null;
4042
}
@@ -65,7 +67,7 @@ export class BrowserCustomizableComponents {
6567

6668
/**
6769
* Registers a new component to the registry
68-
* @param {number} componentType
70+
* @param {symbol} componentType
6971
* @param {string} componentId
7072
* @param {({
7173
* doc,
@@ -108,10 +110,16 @@ export class BrowserCustomizableComponents {
108110

109111
/**
110112
* Obtains a component instance by its type and ID
111-
* @param {number} componentType
113+
* @param {symbol} componentType
112114
* @param {string} componentId
113115
*/
114116
getComponentInstance(componentType, componentId) {
117+
if (!Shared.customizableComponentTagRegex.test(componentId)) {
118+
throw new Error(
119+
`Disallowed characters in component ID '${componentId}'.`
120+
);
121+
}
122+
115123
if (this.components.get(componentType).has(componentId)) {
116124
const component = this.components
117125
.get(componentType)
@@ -154,6 +162,12 @@ export class BrowserCustomizableComponents {
154162
return null;
155163
}
156164

165+
/**
166+
* Registers a custom component
167+
* @param {object} componentDeclaration
168+
*/
169+
registerCustomComponent(componentDeclaration) {}
170+
157171
/**
158172
* Registers all built-in browser areas
159173
*/
@@ -169,6 +183,10 @@ export class BrowserCustomizableComponents {
169183
this.registerComponent(Component.TYPE_AREA, "urlbar", ({ html }) =>
170184
html("browser-urlbar")
171185
);
186+
187+
this.registerComponent(Component.TYPE_AREA, "menu", ({ doc }) =>
188+
doc.createXULElement("menupopup")
189+
);
172190
}
173191

174192
/**

0 commit comments

Comments
 (0)