Skip to content

Commit 7e1d052

Browse files
Add url-changed to WebTelemetry (#1865)
* DRAFT: Add urlChanged to WebTelemetry Uses JK's suggestion to get at the event type. If I add this to `urlChanged` (in web-telemetry.js) I see that neither of these are true, which confuses me. It may be that we need a check here, or perhaps this is working because the WebTelemetry feature is enabled and that's by design. ```js console.log('WebTelemetry: URL changed', navigationType, this.getFeatureSettingEnabled('urlChanged'), this.getFeatureSettingEnabled('listenForUrlChanges')); ``` * Apply suggestions from code review Co-authored-by: Jonathan Kingston <[email protected]> * Apply suggestions from code review Co-authored-by: Jonathan Kingston <[email protected]> * Update injected/src/url-change.js * lint-fix --------- Co-authored-by: Jonathan Kingston <[email protected]>
1 parent ea10dbb commit 7e1d052

File tree

3 files changed

+37
-11
lines changed

3 files changed

+37
-11
lines changed

injected/src/content-scope-features.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ export async function init(args) {
7777
featureInstance.callInit(args);
7878
// Either listenForUrlChanges or urlChanged ensures the feature listens.
7979
if (featureInstance.listenForUrlChanges || featureInstance.urlChanged) {
80-
registerForURLChanges(() => {
80+
registerForURLChanges((navigationType) => {
8181
// The rationale for the two separate call here is to ensure that
8282
// extensions to the class don't need to call super.urlChanged()
8383
featureInstance.recomputeSiteObject();
8484
// Called if the feature instance has a urlChanged method
85-
featureInstance?.urlChanged();
85+
featureInstance?.urlChanged(navigationType);
8686
});
8787
}
8888
}

injected/src/features/web-telemetry.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import ContentFeature from '../content-feature.js';
22

33
const MSG_VIDEO_PLAYBACK = 'video-playback';
4+
const MSG_URL_CHANGED = 'url-changed';
45

56
export class WebTelemetry extends ContentFeature {
7+
listenForUrlChanges = true;
8+
69
constructor(featureName, importConfig, args) {
710
super(featureName, importConfig, args);
811
this.seenVideoElements = new WeakSet();
@@ -15,6 +18,12 @@ export class WebTelemetry extends ContentFeature {
1518
}
1619
}
1720

21+
urlChanged(navigationType = 'unknown') {
22+
if (this.getFeatureSettingEnabled('urlChanged')) {
23+
this.fireTelemetryForUrlChanged(navigationType);
24+
}
25+
}
26+
1827
getVideoUrl(video) {
1928
// Try to get the video URL from various sources
2029
if (video.src) {
@@ -31,6 +40,13 @@ export class WebTelemetry extends ContentFeature {
3140
return null;
3241
}
3342

43+
fireTelemetryForUrlChanged(navigationType) {
44+
this.messaging.notify(MSG_URL_CHANGED, {
45+
url: window.location.href,
46+
navigationType,
47+
});
48+
}
49+
3450
fireTelemetryForVideo(video) {
3551
const videoUrl = this.getVideoUrl(video);
3652
if (this.seenVideoUrls.has(videoUrl)) {

injected/src/url-change.js

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,30 @@ export function registerForURLChanges(listener) {
1313
urlChangeListeners.add(listener);
1414
}
1515

16-
function handleURLChange() {
16+
function handleURLChange(navigationType = 'unknown') {
1717
for (const listener of urlChangeListeners) {
18-
listener();
18+
listener(navigationType);
1919
}
2020
}
2121

2222
function listenForURLChanges() {
2323
const urlChangedInstance = new ContentFeature('urlChanged', {}, {});
24+
// if the browser supports the navigation API, use that to listen for URL changes
2425
if ('navigation' in globalThis && 'addEventListener' in globalThis.navigation) {
25-
// if the browser supports the navigation API, we can use that to listen for URL changes
26-
// Listening to navigatesuccess instead of navigate to ensure the navigation is committed.
27-
globalThis.navigation.addEventListener('navigatesuccess', () => {
28-
handleURLChange();
26+
// We listen to `navigatesuccess` instead of `navigate` to ensure the navigation is committed.
27+
// But, `navigatesuccess` does not provide the navigationType, so we capture it at `navigate` time
28+
// then look it up later. This allows consumers to filter on navigationType.
29+
// WeakMap ensures we don't hold onto the event.target longer than necessary and can be freed.
30+
const navigations = new WeakMap();
31+
globalThis.navigation.addEventListener('navigate', (event) => {
32+
navigations.set(event.target, event.navigationType);
2933
});
30-
// Exit early if the navigation API is supported
34+
globalThis.navigation.addEventListener('navigatesuccess', (event) => {
35+
const navigationType = navigations.get(event.target) || 'unknown';
36+
handleURLChange(navigationType);
37+
navigations.delete(event.target);
38+
});
39+
// Exit early if the navigation API is supported, i.e. history proxy and popState listener aren't created.
3140
return;
3241
}
3342
if (isBeingFramed()) {
@@ -39,13 +48,14 @@ function listenForURLChanges() {
3948
const historyMethodProxy = new DDGProxy(urlChangedInstance, History.prototype, 'pushState', {
4049
apply(target, thisArg, args) {
4150
const changeResult = DDGReflect.apply(target, thisArg, args);
42-
handleURLChange();
51+
console.log('pushstate event');
52+
handleURLChange('push');
4353
return changeResult;
4454
},
4555
});
4656
historyMethodProxy.overload();
4757
// listen for popstate events in order to run on back/forward navigations
4858
window.addEventListener('popstate', () => {
49-
handleURLChange();
59+
handleURLChange('popState');
5060
});
5161
}

0 commit comments

Comments
 (0)