@mtdt.temp/browser-rum-core
Version:
Datadog browser RUM core utilities.
51 lines • 2.63 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createLocationChangeObservable = createLocationChangeObservable;
const browser_core_1 = require("@mtdt.temp/browser-core");
function createLocationChangeObservable(configuration, location) {
let currentLocation = (0, browser_core_1.shallowClone)(location);
return new browser_core_1.Observable((observable) => {
const { stop: stopHistoryTracking } = trackHistory(configuration, onLocationChange);
const { stop: stopHashTracking } = trackHash(configuration, onLocationChange);
function onLocationChange() {
if (currentLocation.href === location.href) {
return;
}
const newLocation = (0, browser_core_1.shallowClone)(location);
observable.notify({
newLocation,
oldLocation: currentLocation,
});
currentLocation = newLocation;
}
return () => {
stopHistoryTracking();
stopHashTracking();
};
});
}
function trackHistory(configuration, onHistoryChange) {
const { stop: stopInstrumentingPushState } = (0, browser_core_1.instrumentMethod)(getHistoryInstrumentationTarget('pushState'), 'pushState', ({ onPostCall }) => {
onPostCall(onHistoryChange);
});
const { stop: stopInstrumentingReplaceState } = (0, browser_core_1.instrumentMethod)(getHistoryInstrumentationTarget('replaceState'), 'replaceState', ({ onPostCall }) => {
onPostCall(onHistoryChange);
});
const { stop: removeListener } = (0, browser_core_1.addEventListener)(configuration, window, "popstate" /* DOM_EVENT.POP_STATE */, onHistoryChange);
return {
stop: () => {
stopInstrumentingPushState();
stopInstrumentingReplaceState();
removeListener();
},
};
}
function trackHash(configuration, onHashChange) {
return (0, browser_core_1.addEventListener)(configuration, window, "hashchange" /* DOM_EVENT.HASH_CHANGE */, onHashChange);
}
function getHistoryInstrumentationTarget(methodName) {
// Ideally we should always instument the method on the prototype, however some frameworks (e.g [Next.js](https://github.com/vercel/next.js/blob/d3f5532065f3e3bb84fb54bd2dfd1a16d0f03a21/packages/next/src/client/components/app-router.tsx#L429))
// are wrapping the instance method. In that case we should also wrap the instance method.
return Object.prototype.hasOwnProperty.call(history, methodName) ? history : History.prototype;
}
//# sourceMappingURL=locationChangeObservable.js.map