Skip to content

Commit db3cdf8

Browse files
committed
fix: add content feature type
1 parent 6476ae4 commit db3cdf8

File tree

7 files changed

+46
-56
lines changed

7 files changed

+46
-56
lines changed

injected/src/content-feature.js

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,33 +26,43 @@ class ConfigParser {
2626
/** @type {import('./utils.js').RemoteConfig | undefined} */
2727
#bundledConfig;
2828

29-
/** @type {import('./content-scope-features.js').LoadArgs} */
30-
#loadArgs;
31-
32-
/** @type {Record<string, unknown> | undefined} */
33-
#featureSettings;
34-
3529
/** @type {any} */
3630
name;
3731

32+
/** @type {{ debug?: boolean, desktopModeEnabled?: boolean, forcedZoomEnabled?: boolean, featureSettings?: Record<string, unknown>, assets?: AssetConfig | undefined, site: Site, messagingConfig?: import('@duckduckgo/messaging').MessagingConfig } | null} */
33+
#args;
34+
3835
/**
3936
* @param {any} name
4037
*/
4138
constructor(name) {
4239
this.name = name;
4340
}
4441

42+
get args() {
43+
return this.#args;
44+
}
45+
46+
set args(args) {
47+
this.#args = args;
48+
}
49+
50+
get featureSettings() {
51+
return this.#args?.featureSettings;
52+
}
53+
4554
/**
4655
* @param {import('./content-scope-features.js').LoadArgs} loadArgs
4756
*/
4857
initLoadArgs(loadArgs) {
4958
const { bundledConfig, site, platform } = loadArgs;
5059
this.#bundledConfig = bundledConfig;
60+
this.#args = loadArgs;
5161
// If we have a bundled config, treat it as a regular config
5262
// This will be overriden by the remote config if it is available
53-
if (this.#bundledConfig) {
63+
if (this.#bundledConfig && this.#args) {
5464
const enabledFeatures = computeEnabledFeatures(bundledConfig, site.domain, platform.version);
55-
this.#featureSettings = parseFeatureSettings(bundledConfig, enabledFeatures);
65+
this.#args.featureSettings = parseFeatureSettings(bundledConfig, enabledFeatures);
5666
}
5767
}
5868

@@ -64,7 +74,7 @@ class ConfigParser {
6474
* @protected
6575
*/
6676
matchDomainFeatureSetting(featureKeyName) {
67-
const domain = this.#loadArgs?.site.domain;
77+
const domain = this.args?.site.domain;
6878
if (!domain) return [];
6979
const domains = this._getFeatureSettings()?.[featureKeyName] || [];
7080
return domains.filter((rule) => {
@@ -83,8 +93,8 @@ class ConfigParser {
8393
* @returns {any}
8494
*/
8595
_getFeatureSettings(featureName) {
86-
const camelFeatureName = featureName ?? camelcase(this.name);
87-
return this.#featureSettings?.[camelFeatureName];
96+
const camelFeatureName = featureName || camelcase(this.name);
97+
return this.featureSettings?.[camelFeatureName];
8898
}
8999

90100
/**
@@ -182,28 +192,26 @@ export default class ContentFeature extends ConfigParser {
182192
/** @type {boolean} */
183193
#isDebugFlagSet = false;
184194

185-
/** @type {{ debug?: boolean, desktopModeEnabled?: boolean, forcedZoomEnabled?: boolean, featureSettings?: Record<string, unknown>, assets?: AssetConfig | undefined, site: Site, messagingConfig?: import('@duckduckgo/messaging').MessagingConfig } | null} */
186-
#args;
187-
188-
/** @type {any} */
195+
/** @type {ImportMeta} */
189196
#importConfig;
197+
190198
constructor(featureName, importConfig) {
191199
super(featureName);
192-
this.#args = null;
200+
this.args = null;
193201
this.monitor = new PerformanceMonitor();
194202
this.#importConfig = importConfig;
195203
}
196204

197205
get isDebug() {
198-
return this.#args?.debug || false;
206+
return this.args?.debug || false;
199207
}
200208

201209
get desktopModeEnabled() {
202-
return this.#args?.desktopModeEnabled || false;
210+
return this.args?.desktopModeEnabled || false;
203211
}
204212

205213
get forcedZoomEnabled() {
206-
return this.#args?.forcedZoomEnabled || false;
214+
return this.args?.forcedZoomEnabled || false;
207215
}
208216

209217
/**
@@ -222,18 +230,18 @@ export default class ContentFeature extends ConfigParser {
222230
* @type {AssetConfig | undefined}
223231
*/
224232
get assetConfig() {
225-
return this.#args?.assets;
233+
return this.args?.assets;
226234
}
227235

228236
/**
229-
* @returns {object}
237+
* @returns {ImportMeta['trackerLookup']}
230238
**/
231239
get trackerLookup() {
232240
return this.#importConfig.trackerLookup || {};
233241
}
234242

235243
/**
236-
* @returns {string}
244+
* @returns {ImportMeta['injectName']}
237245
*/
238246
get injectName() {
239247
return this.#importConfig.injectName;
@@ -268,7 +276,7 @@ export default class ContentFeature extends ConfigParser {
268276
get messaging() {
269277
if (this._messaging) return this._messaging;
270278
const messagingContext = this._createMessagingContext();
271-
let messagingConfig = this.#args?.messagingConfig;
279+
let messagingConfig = this.args?.messagingConfig;
272280
if (!messagingConfig) {
273281
if (this.platform?.name !== 'extension') throw new Error('Only extension messaging supported, all others should be passed in');
274282
messagingConfig = extensionConstructMessagingConfig();
@@ -295,7 +303,7 @@ export default class ContentFeature extends ConfigParser {
295303

296304
callInit(args) {
297305
const mark = this.monitor.mark(this.name + 'CallInit');
298-
this.#args = args;
306+
this.args = args;
299307
this.platform = args.platform;
300308
this.init(args);
301309
mark.end();
@@ -345,18 +353,20 @@ export default class ContentFeature extends ConfigParser {
345353

346354
/**
347355
* @param {import('./content-scope-features.js').LoadArgs} args
356+
* @param {any} importConfig
348357
*/
349-
callLoad(args) {
358+
callLoad(args, importConfig) {
350359
const mark = this.monitor.mark(this.name + 'CallLoad');
351-
this.#args = args;
360+
this.args = args;
352361
this.platform = args.platform;
353362
this.initLoadArgs(args);
363+
this.#importConfig = importConfig;
354364
this.load(args);
355365
mark.end();
356366
}
357367

358368
measure() {
359-
if (this.#args?.debug) {
369+
if (this.args?.debug) {
360370
this.monitor.measureAll();
361371
}
362372
}

injected/src/content-scope-features.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function load(args) {
4646
for (const featureName of featureNames) {
4747
const ContentFeature = platformFeatures['ddg_feature_' + featureName];
4848
const featureInstance = new ContentFeature(featureName, importConfig);
49-
featureInstance.callLoad(args);
49+
featureInstance.callLoad(args, importConfig);
5050
features.push({ featureName, featureInstance });
5151
}
5252
mark.end();

injected/src/globals.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,6 @@ declare module '*.riv' {
4444
}
4545

4646
declare module 'ddg:platformFeatures' {
47-
const output: Record<string, new (featureName: string) => import('./content-feature').default>;
47+
const output: Record<string, new (featureName: string, importConfig: ImportConfig) => import('./content-feature').default>;
4848
export default output;
4949
}

injected/src/wrapper-utils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export function wrapMethod(object, propertyName, wrapperFn, definePropertyFn) {
193193
* @param {typeof globalThis[StandardInterfaceName]} ImplClass - the class to use as the shim implementation
194194
* @param {DefineInterfaceOptions} options - options for defining the interface
195195
* @param {DefinePropertyFn} definePropertyFn - function to use for defining the property
196+
* @param {ImportMeta['injectName']} [injectName] - the name of the inject to use for the shim
196197
*/
197198
export function shimInterface(interfaceName, ImplClass, options, definePropertyFn, injectName) {
198199
if (injectName === 'integration') {
@@ -304,6 +305,7 @@ export function shimInterface(interfaceName, ImplClass, options, definePropertyF
304305
* @param {Base[K]} implInstance - instance to use as the shim (e.g. new MyMediaSession())
305306
* @param {boolean} readOnly - whether the property should be read-only
306307
* @param {DefinePropertyFn} definePropertyFn - function to use for defining the property
308+
* @param {ImportMeta['injectName']} [injectName] - the name of the inject to use for the shim
307309
*/
308310
export function shimProperty(baseObject, propertyName, implInstance, readOnly, definePropertyFn, injectName) {
309311
// @ts-expect-error - implInstance is a class instance

injected/unit-test/utils.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ describe('Helpers checks', () => {
8989
},
9090
versionNumber: 99,
9191
sessionKey: 'testSessionKey',
92-
// import.meta.trackerLookup is undefined because we've not overloaded it
93-
trackerLookup: undefined,
9492
bundledConfig: configIn,
9593
});
9694
});
@@ -169,7 +167,6 @@ describe('Helpers checks', () => {
169167
},
170168
versionString: '0.9.9',
171169
sessionKey: 'testSessionKey',
172-
trackerLookup: undefined,
173170
bundledConfig: configIn,
174171
});
175172
});

injected/unit-test/verify-artifacts.js

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ if (process.platform === 'win32') {
1717
const checks = {
1818
android: {
1919
file: join(BUILD, 'android/contentScope.js'),
20-
tests: [
21-
{ kind: 'maxFileSize', value: CSS_OUTPUT_SIZE },
22-
{ kind: 'containsString', text: 'output.trackerLookup = {', includes: true },
23-
],
20+
tests: [{ kind: 'maxFileSize', value: CSS_OUTPUT_SIZE }],
2421
},
2522
chrome: {
2623
file: join(BUILD, 'chrome/inject.js'),
@@ -49,16 +46,12 @@ const checks = {
4946
},
5047
windows: {
5148
file: join(BUILD, 'windows/contentScope.js'),
52-
tests: [
53-
{ kind: 'maxFileSize', value: CSS_OUTPUT_SIZE },
54-
{ kind: 'containsString', text: 'output.trackerLookup = {', includes: true },
55-
],
49+
tests: [{ kind: 'maxFileSize', value: CSS_OUTPUT_SIZE }],
5650
},
5751
apple: {
5852
file: join(APPLE_BUILD, 'contentScope.js'),
5953
tests: [
6054
{ kind: 'maxFileSize', value: CSS_OUTPUT_SIZE },
61-
{ kind: 'containsString', text: 'output.trackerLookup = {', includes: true },
6255
{ kind: 'containsString', text: '#bundledConfig', includes: false },
6356
],
6457
},
@@ -77,7 +70,6 @@ describe('checks', () => {
7770
if (check.kind === 'containsString') {
7871
it(`${platformName}: '${localPath}' contains ${check.text}`, () => {
7972
const fileContents = readFileSync(platformChecks.file).toString();
80-
// @ts-expect-error - can't infer that value is a number without adding types
8173
const includes = fileContents.includes(check.text);
8274
if (check.includes) {
8375
expect(includes).toBeTrue();

injected/unit-test/wrapper-utils.js

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ describe('Shim API', () => {
4848
allowConstructorCall: false,
4949
},
5050
definePropertyFn,
51-
'integration',
5251
);
5352
expect(definePropertyFn).toHaveBeenCalledTimes(2);
5453
const NewMediaSession = globalThis.MediaSession;
@@ -78,7 +77,6 @@ describe('Shim API', () => {
7877
wrapToString: true,
7978
},
8079
definePropertyFn,
81-
'integration',
8280
);
8381
expect(() => new globalThis.MediaSession()).not.toThrow();
8482

@@ -91,7 +89,6 @@ describe('Shim API', () => {
9189
wrapToString: true,
9290
},
9391
definePropertyFn,
94-
'integration',
9592
);
9693
expect(() => new globalThis.MediaSession()).toThrowError(TypeError);
9794

@@ -105,7 +102,6 @@ describe('Shim API', () => {
105102
wrapToString: true,
106103
},
107104
definePropertyFn,
108-
'integration',
109105
);
110106
expect(() => new globalThis.MediaSession()).toThrowMatching(
111107
(err) => err instanceof TypeError && err.message === 'friendly message',
@@ -122,7 +118,6 @@ describe('Shim API', () => {
122118
disallowConstructor: false,
123119
},
124120
definePropertyFn,
125-
'integration',
126121
);
127122
// @ts-expect-error real MediaSession is not callable
128123
expect(() => globalThis.MediaSession()).not.toThrow();
@@ -140,7 +135,6 @@ describe('Shim API', () => {
140135
disallowConstructor: false,
141136
},
142137
definePropertyFn,
143-
'integration',
144138
);
145139
// @ts-expect-error real MediaSession is not callable
146140
expect(() => globalThis.MediaSession()).toThrowError(TypeError);
@@ -156,7 +150,6 @@ describe('Shim API', () => {
156150
allowConstructorCall: false,
157151
},
158152
definePropertyFn,
159-
'integration',
160153
);
161154
expect(globalThis.MediaSession.toString()).not.toContain('class');
162155
expect(globalThis.MediaSession.toString.toString())
@@ -175,7 +168,6 @@ describe('Shim API', () => {
175168
allowConstructorCall: false,
176169
},
177170
definePropertyFn,
178-
'integration',
179171
);
180172

181173
expect(globalThis.MediaSession.toString()).toBe('function MediaSession() { [native code] }');
@@ -195,10 +187,9 @@ describe('Shim API', () => {
195187
allowConstructorCall: false,
196188
},
197189
definePropertyFn,
198-
'integration',
199190
);
200191
const instance = new MyMediaSession();
201-
shimProperty(navigatorPrototype, 'mediaSession', instance, false, definePropertyFn, 'integration');
192+
shimProperty(navigatorPrototype, 'mediaSession', instance, false, definePropertyFn);
202193

203194
const NewMediaSession = globalThis.MediaSession;
204195
expect(navigator.mediaSession instanceof NewMediaSession)
@@ -219,10 +210,9 @@ describe('Shim API', () => {
219210
allowConstructorCall: false,
220211
},
221212
definePropertyFn,
222-
'integration',
223213
);
224214
const instance = new MyMediaSession();
225-
shimProperty(navigatorPrototype, 'mediaSession', instance, false, definePropertyFn, 'integration');
215+
shimProperty(navigatorPrototype, 'mediaSession', instance, false, definePropertyFn);
226216

227217
const descriptor = Object.getOwnPropertyDescriptor(navigatorPrototype, 'mediaSession');
228218
// @ts-expect-error we know it's defined
@@ -248,10 +238,9 @@ describe('Shim API', () => {
248238
allowConstructorCall: false,
249239
},
250240
definePropertyFn,
251-
'integration',
252241
);
253242
const instance = new MyMediaSession();
254-
shimProperty(navigatorPrototype, 'mediaSession', instance, true, definePropertyFn, 'integration');
243+
shimProperty(navigatorPrototype, 'mediaSession', instance, true, definePropertyFn);
255244

256245
/** @type {import('../src/wrapper-utils').StrictAccessorDescriptor} */
257246
// @ts-expect-error we know it's defined

0 commit comments

Comments
 (0)