Skip to content

Commit aa95b1f

Browse files
authored
Update FluentDOM classes to work with XPIDL (#245)
* Update FluentDOM classes to work with XPIDL * fix tests * Feedback updates * Another update
1 parent 4628a4f commit aa95b1f

File tree

3 files changed

+42
-19
lines changed

3 files changed

+42
-19
lines changed

fluent-dom/src/dom_localization.js

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ const L10N_ELEMENT_QUERY = `[${L10NID_ATTR_NAME}]`;
1616
*/
1717
export default class DOMLocalization extends Localization {
1818
/**
19-
* @param {Window} windowElement
2019
* @param {Array<String>} resourceIds - List of resource IDs
2120
* @param {Function} generateMessages - Function that returns a
2221
* generator over MessageContexts
2322
* @returns {DOMLocalization}
2423
*/
25-
constructor(windowElement, resourceIds, generateMessages) {
24+
constructor(resourceIds, generateMessages) {
2625
super(resourceIds, generateMessages);
2726

2827
// A Set of DOM trees observed by the `MutationObserver`.
@@ -31,10 +30,8 @@ export default class DOMLocalization extends Localization {
3130
this.pendingrAF = null;
3231
// list of elements pending for translation.
3332
this.pendingElements = new Set();
34-
this.windowElement = windowElement;
35-
this.mutationObserver = new windowElement.MutationObserver(
36-
mutations => this.translateMutations(mutations)
37-
);
33+
this.windowElement = null;
34+
this.mutationObserver = null;
3835

3936
this.observerConfig = {
4037
attribute: true,
@@ -132,6 +129,19 @@ export default class DOMLocalization extends Localization {
132129
}
133130
}
134131

132+
if (this.windowElement) {
133+
if (this.windowElement !== newRoot.ownerGlobal) {
134+
throw new Error(`Cannot connect a root:
135+
DOMLocalization already has a root from a different window.`);
136+
}
137+
} else {
138+
this.windowElement = newRoot.ownerGlobal;
139+
this.mutationObserver = new this.windowElement.MutationObserver(
140+
mutations => this.translateMutations(mutations)
141+
);
142+
}
143+
144+
135145
this.roots.add(newRoot);
136146
this.mutationObserver.observe(newRoot, this.observerConfig);
137147
}
@@ -150,11 +160,20 @@ export default class DOMLocalization extends Localization {
150160
*/
151161
disconnectRoot(root) {
152162
this.roots.delete(root);
153-
// Pause and resume the mutation observer to stop observing `root`.
163+
// Pause the mutation observer to stop observing `root`.
154164
this.pauseObserving();
155-
this.resumeObserving();
156165

157-
return this.roots.size === 0;
166+
if (this.roots.size === 0) {
167+
this.mutationObserver = null;
168+
this.windowElement = null;
169+
this.pendingrAF = null;
170+
this.pendingElements.clear();
171+
return true;
172+
}
173+
174+
// Resume observing all other roots.
175+
this.resumeObserving();
176+
return false;
158177
}
159178

160179
/**
@@ -175,6 +194,10 @@ export default class DOMLocalization extends Localization {
175194
* @private
176195
*/
177196
pauseObserving() {
197+
if (!this.mutationObserver) {
198+
return;
199+
}
200+
178201
this.translateMutations(this.mutationObserver.takeRecords());
179202
this.mutationObserver.disconnect();
180203
}
@@ -185,6 +208,10 @@ export default class DOMLocalization extends Localization {
185208
* @private
186209
*/
187210
resumeObserving() {
211+
if (!this.mutationObserver) {
212+
return;
213+
}
214+
188215
for (const root of this.roots) {
189216
this.mutationObserver.observe(root, this.observerConfig);
190217
}

fluent-dom/src/localization.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export default class Localization {
1717
*
1818
* @returns {Localization}
1919
*/
20-
constructor(resourceIds, generateMessages) {
20+
constructor(resourceIds = [], generateMessages) {
2121
this.resourceIds = resourceIds;
2222
this.generateMessages = generateMessages;
2323
this.ctxs =
@@ -27,11 +27,13 @@ export default class Localization {
2727
addResourceIds(resourceIds) {
2828
this.resourceIds.push(...resourceIds);
2929
this.onChange();
30+
return this.resourceIds.length;
3031
}
3132

3233
removeResourceIds(resourceIds) {
3334
this.resourceIds = this.resourceIds.filter(r => !resourceIds.includes(r));
3435
this.onChange();
36+
return this.resourceIds.length;
3537
}
3638

3739
/**
@@ -154,6 +156,7 @@ export default class Localization {
154156
onChange() {
155157
this.ctxs =
156158
new CachedAsyncIterable(this.generateMessages(this.resourceIds));
159+
this.ctxs.touchNext(2);
157160
}
158161
}
159162

fluent-dom/test/dom_localization_test.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,9 @@ async function* mockGenerateMessages(resourceIds) {
88
yield mc;
99
}
1010

11-
const mockWindow = {
12-
MutationObserver: class MutationObserver {
13-
takeRecords() {return new Set();}
14-
disconnect() {}
15-
}
16-
};
17-
1811
suite("translateFragment", function() {
1912
test("translates a node", async function() {
20-
const domLoc = new DOMLocalization(mockWindow, ["test.ftl"], mockGenerateMessages);
13+
const domLoc = new DOMLocalization(["test.ftl"], mockGenerateMessages);
2114

2215
const frag = document.createDocumentFragment();
2316
const elem = document.createElement("p");
@@ -30,7 +23,7 @@ suite("translateFragment", function() {
3023
});
3124

3225
test("does not inject content into a node with missing translation", async function() {
33-
const domLoc = new DOMLocalization(mockWindow, ["test.ftl"], mockGenerateMessages);
26+
const domLoc = new DOMLocalization(["test.ftl"], mockGenerateMessages);
3427

3528
const frag = document.createDocumentFragment();
3629
const elem = document.createElement("p");

0 commit comments

Comments
 (0)