From 0ce9e93fd3267fc9a02c58f147c691eb42c9fe10 Mon Sep 17 00:00:00 2001 From: Mikhail Atuchin Date: Thu, 15 Aug 2024 20:25:12 +0700 Subject: [PATCH 1/2] Stop using chrome.webRequest.onSendHeaders --- .../publisher/common/XHREvents.ts | 48 +++++++++++++++++ .../publisher/common/XHRInterceptor.ts | 53 +++++++++++++++++++ .../publisher/common/webRequestHandlers.ts | 45 +++------------- .../brave_rewards/publisher/twitter/auth.ts | 41 +++++++------- .../publisher/twitter/twitterBase.ts | 23 ++++---- .../brave_rewards/publisher/twitter/types.ts | 3 +- webpack.config.js | 1 + 7 files changed, 145 insertions(+), 69 deletions(-) create mode 100644 scripts/brave_rewards/publisher/common/XHREvents.ts create mode 100644 scripts/brave_rewards/publisher/common/XHRInterceptor.ts diff --git a/scripts/brave_rewards/publisher/common/XHREvents.ts b/scripts/brave_rewards/publisher/common/XHREvents.ts new file mode 100644 index 0000000..b27c3a4 --- /dev/null +++ b/scripts/brave_rewards/publisher/common/XHREvents.ts @@ -0,0 +1,48 @@ +export class Headers {[name: string] : string} + +export function makeEvent(eventName: string, args: T) { + return new CustomEvent( + eventName, + {detail: args} + ) +} + +export function subscribe(eventName: string, callback: (args: T) => void) { + addEventListener(eventName, (e: CustomEvent) => callback(e?.detail)) +} + + +export class HeadersHandlerMessageEvent { + static eventName = 'header-handler-message' + url?: string; + headers: Headers; + + static makeEvent(args: HeadersHandlerMessageEvent) { + return new CustomEvent( + this.eventName, + {detail: args} + ) + } + + static subscribe(callback: (args: HeadersHandlerMessageEvent) => void) { + addEventListener(this.eventName, + (e: CustomEvent) => callback(e?.detail)) + } +} + +export class RegisterHeadersHandlerEvent{ + urlPattern?: string; + static eventName = 'register-header-handler' + + static makeEvent(args: RegisterHeadersHandlerEvent) { + return new CustomEvent( + this.eventName, + {detail: args} + ) + } + + static subscribe(callback: (args: RegisterHeadersHandlerEvent) => void) { + addEventListener(this.eventName, + (e: CustomEvent) => callback(e?.detail)) + } +} diff --git a/scripts/brave_rewards/publisher/common/XHRInterceptor.ts b/scripts/brave_rewards/publisher/common/XHRInterceptor.ts new file mode 100644 index 0000000..07a0a01 --- /dev/null +++ b/scripts/brave_rewards/publisher/common/XHRInterceptor.ts @@ -0,0 +1,53 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. */ + + import {HeadersHandlerMessageEvent, RegisterHeadersHandlerEvent} from '../common/XHREvents' + +let headerProcessUrlPattern: RegExp | undefined; +class CustomXMLHttpRequest extends XMLHttpRequest { + headers: {[header: string]: string} = {} + url: string | undefined; + + override open(method: string, url: string | URL): void; + override open( + method: string, url: string | URL, isAsync: boolean, + username?: any): void; + override open( + method: string, url: string | URL, isAsync?: boolean, + username?: any, + password?: any): void { + + this.url = url instanceof URL ? url.toString() : url + const realAsync = isAsync ? isAsync : true; + super.open(method, url, realAsync, username, password); + } + + override setRequestHeader(name: string, value: string): void { + this.headers[name] = value + super.setRequestHeader(name, value) + } + + override send(body?: any): void { + if (!headerProcessUrlPattern || !this.url || this.url.search(headerProcessUrlPattern) >= 0) { + window.dispatchEvent(HeadersHandlerMessageEvent.makeEvent( + {url: this.url, headers: this.headers})) + } + super.send(body) + } +} + +const initHeadersHandler = (urlPattern?: string) => { + XMLHttpRequest = CustomXMLHttpRequest + headerProcessUrlPattern = urlPattern ? new RegExp(urlPattern) : undefined +} + + +export const initScript = () => { + RegisterHeadersHandlerEvent.subscribe((e) => { + const urlPattern = e.urlPattern + initHeadersHandler(urlPattern) + }) +} + +initScript() diff --git a/scripts/brave_rewards/publisher/common/webRequestHandlers.ts b/scripts/brave_rewards/publisher/common/webRequestHandlers.ts index f145a68..26a2b6e 100644 --- a/scripts/brave_rewards/publisher/common/webRequestHandlers.ts +++ b/scripts/brave_rewards/publisher/common/webRequestHandlers.ts @@ -3,9 +3,9 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ import { getPort } from '../common/messaging' +import {HeadersHandlerMessageEvent, RegisterHeadersHandlerEvent} from '../common/XHREvents' let registeredOnCompletedWebRequestHandler = false -let registeredOnSendHeadersWebRequest = false export const registerOnCompletedWebRequestHandler = ( mediaType: string, @@ -41,41 +41,12 @@ export const registerOnCompletedWebRequestHandler = ( }) } -export const registerOnSendHeadersWebRequest = ( - mediaType: string, - urlPatterns: string[], - extra: string[], - callback: (mediaType: string, details: any) => void -) => { - if (!mediaType || registeredOnSendHeadersWebRequest) { - return - } - - registeredOnSendHeadersWebRequest = true - - const port = getPort() - if (!port) { - return - } - - port.postMessage({ - type: 'RegisterOnSendHeadersWebRequest', - mediaType, - data: { - urlPatterns, - extra - } - }) - port.onMessage.addListener(function (msg: any) { - if (!msg.data) { - return - } - switch (msg.type) { - case 'OnSendHeadersWebRequest': { - callback(msg.mediaType, msg.data.details) - break - } - } - }) +export const registerHeadersHandler = ( + urlPattern: string | undefined, + callback: (headers: any) => void +) => { + HeadersHandlerMessageEvent.subscribe((e) => callback(e.headers)) + console.log('send RegisterHeadersHandlerEvent') + dispatchEvent(RegisterHeadersHandlerEvent.makeEvent({urlPattern})) } diff --git a/scripts/brave_rewards/publisher/twitter/auth.ts b/scripts/brave_rewards/publisher/twitter/auth.ts index 5c58aee..200ba9d 100644 --- a/scripts/brave_rewards/publisher/twitter/auth.ts +++ b/scripts/brave_rewards/publisher/twitter/auth.ts @@ -16,14 +16,18 @@ const authTokenCookieRegex = /[; ]_twitter_sess=([^\s;]*)/ let lastSessionId: SessionId = null -let authHeaders: any = {} +class AuthHeaders { + [header: string]: string; +} + +let authHeaders: AuthHeaders = {} -const readSessionCookie = (cookiesString: string): SessionId => { - if (!cookiesString) { +const readSessionCookie = (): SessionId => { + if (!document.cookie) { return null } - const match = cookiesString.match(authTokenCookieRegex) + const match = document.cookie.match(authTokenCookieRegex) if (!match) { return null } @@ -41,26 +45,27 @@ export const hasRequiredAuthHeaders = () => { (authHeaders['x-csrf-token'] && authHeaders['x-guest-token'])) } -export const processRequestHeaders = (requestHeaders: any[]) => { +export const processRequestHeaders = (requestHeaders: {[header: string]: string}) => { if (!requestHeaders) { return false } - let headers = {} + let headers = new AuthHeaders() - for (const header of requestHeaders) { + const currentSessionId = readSessionCookie() + const hasAuthChanged = (currentSessionId !== lastSessionId) + if (hasAuthChanged) { + // Clear cached auth data when session changes + lastSessionId = currentSessionId + // TODO: why it was headers = {}? + authHeaders = {} + } + for (const name in requestHeaders) { + const value = requestHeaders[name] // Parse cookies for session id - if (header.name === 'Cookie') { - const currentSessionId = readSessionCookie(header.value as string) - const hasAuthChanged = (currentSessionId !== lastSessionId) - if (hasAuthChanged) { - // Clear cached auth data when session changes - lastSessionId = currentSessionId - headers = {} - } - } else if (authHeaderNames.includes(header.name) || - header.name.startsWith('x-twitter-')) { - headers[header.name] = header.value + if (authHeaderNames.includes(name) || + name.startsWith('x-twitter-')) { + headers[name] = value } } diff --git a/scripts/brave_rewards/publisher/twitter/twitterBase.ts b/scripts/brave_rewards/publisher/twitter/twitterBase.ts index d8c9faa..cb25823 100644 --- a/scripts/brave_rewards/publisher/twitter/twitterBase.ts +++ b/scripts/brave_rewards/publisher/twitter/twitterBase.ts @@ -11,12 +11,9 @@ import * as types from './types' import * as utils from '../common/utils' import * as webRequestHandlers from '../common/webRequestHandlers' -const handleOnSendHeadersWebRequest = (mediaType: string, details: any) => { - if (mediaType !== types.mediaType || !details || !details.requestHeaders) { - return - } - - if (auth.processRequestHeaders(details.requestHeaders)) { +const handleHeaders = (headers: any) => { + console.log('handleHeaders', headers) + if (auth.processRequestHeaders(headers)) { publisherInfo.send() } } @@ -59,12 +56,14 @@ const initScript = () => { } }) - webRequestHandlers.registerOnSendHeadersWebRequest( - types.mediaType, - types.sendHeadersUrls, - types.sendHeadersExtra, - handleOnSendHeadersWebRequest) - tabHandlers.registerOnUpdatedTab(types.mediaType, handleOnUpdatedTab) + // TODO: remove the timeout when XHRInterceptor is injected automatically. + setTimeout( () => { + webRequestHandlers.registerHeadersHandler( + types.sendHeadersUrl, + handleHeaders) + + tabHandlers.registerOnUpdatedTab(types.mediaType, handleOnUpdatedTab) + }, 5000); }) console.info('Greaselion script loaded: twitterBase.ts') diff --git a/scripts/brave_rewards/publisher/twitter/types.ts b/scripts/brave_rewards/publisher/twitter/types.ts index bef9cfc..f791ab6 100644 --- a/scripts/brave_rewards/publisher/twitter/types.ts +++ b/scripts/brave_rewards/publisher/twitter/types.ts @@ -6,5 +6,4 @@ export const mediaType = 'twitter' export const mediaDomain = 'twitter.com' export const baseApiUrl = 'https://api.' + location.hostname -export const sendHeadersUrls = [baseApiUrl + '/1.1/*'] -export const sendHeadersExtra = ['requestHeaders', 'extraHeaders'] +export const sendHeadersUrl = baseApiUrl + '/1.1/*' diff --git a/webpack.config.js b/webpack.config.js index 6c587b1..51d1514 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,6 +11,7 @@ const rewardsDir = 'scripts/brave_rewards' const togetherDir = 'scripts/brave_talk' const allEntries = [ + `${rewardsDir}/publisher/common/XHRInterceptor`, `${rewardsDir}/publisher/github/githubBase`, `${rewardsDir}/publisher/github/githubAutoContribution`, `${rewardsDir}/publisher/reddit/redditBase`, From 8e98ccb741fa552373b88c8de9be8c6d9b80bcc6 Mon Sep 17 00:00:00 2001 From: Mikhail Atuchin Date: Fri, 16 Aug 2024 18:03:11 +0700 Subject: [PATCH 2/2] Support youtube, remove chrome.tabs usage --- .../publisher/common/XHREvents.ts | 24 +++---- .../publisher/common/XHRInterceptor.ts | 67 ++++++++++++------- .../publisher/common/tabHandlers.ts | 27 ++------ .../publisher/common/webRequestHandlers.ts | 50 ++------------ .../publisher/twitter/twitterBase.ts | 18 +++-- .../brave_rewards/publisher/twitter/types.ts | 2 +- .../publisher/youtube/mediaDuration.ts | 1 + .../publisher/youtube/youtubeBase.ts | 49 ++++++-------- 8 files changed, 100 insertions(+), 138 deletions(-) diff --git a/scripts/brave_rewards/publisher/common/XHREvents.ts b/scripts/brave_rewards/publisher/common/XHREvents.ts index b27c3a4..7271b0f 100644 --- a/scripts/brave_rewards/publisher/common/XHREvents.ts +++ b/scripts/brave_rewards/publisher/common/XHREvents.ts @@ -12,37 +12,37 @@ export function subscribe(eventName: string, callback: (args: T) => void) { } -export class HeadersHandlerMessageEvent { - static eventName = 'header-handler-message' +export class RequestHandlerMessageEvent { + static eventName = 'request-handler-message' url?: string; headers: Headers; - static makeEvent(args: HeadersHandlerMessageEvent) { - return new CustomEvent( + static makeEvent(args: RequestHandlerMessageEvent) { + return new CustomEvent( this.eventName, {detail: args} ) } - static subscribe(callback: (args: HeadersHandlerMessageEvent) => void) { + static subscribe(callback: (args: RequestHandlerMessageEvent) => void) { addEventListener(this.eventName, - (e: CustomEvent) => callback(e?.detail)) + (e: CustomEvent) => callback(e?.detail)) } } -export class RegisterHeadersHandlerEvent{ +export class RegisterRequestHandlerEvent{ urlPattern?: string; - static eventName = 'register-header-handler' + static eventName = 'register-request-handler' - static makeEvent(args: RegisterHeadersHandlerEvent) { - return new CustomEvent( + static makeEvent(args: RegisterRequestHandlerEvent) { + return new CustomEvent( this.eventName, {detail: args} ) } - static subscribe(callback: (args: RegisterHeadersHandlerEvent) => void) { + static subscribe(callback: (args: RegisterRequestHandlerEvent) => void) { addEventListener(this.eventName, - (e: CustomEvent) => callback(e?.detail)) + (e: CustomEvent) => callback(e?.detail)) } } diff --git a/scripts/brave_rewards/publisher/common/XHRInterceptor.ts b/scripts/brave_rewards/publisher/common/XHRInterceptor.ts index 07a0a01..395d342 100644 --- a/scripts/brave_rewards/publisher/common/XHRInterceptor.ts +++ b/scripts/brave_rewards/publisher/common/XHRInterceptor.ts @@ -2,51 +2,72 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at https://mozilla.org/MPL/2.0/. */ - import {HeadersHandlerMessageEvent, RegisterHeadersHandlerEvent} from '../common/XHREvents' + import {RequestHandlerMessageEvent, RegisterRequestHandlerEvent} from '../common/XHREvents' let headerProcessUrlPattern: RegExp | undefined; class CustomXMLHttpRequest extends XMLHttpRequest { headers: {[header: string]: string} = {} - url: string | undefined; - - override open(method: string, url: string | URL): void; - override open( - method: string, url: string | URL, isAsync: boolean, - username?: any): void; - override open( - method: string, url: string | URL, isAsync?: boolean, - username?: any, - password?: any): void { - - this.url = url instanceof URL ? url.toString() : url - const realAsync = isAsync ? isAsync : true; - super.open(method, url, realAsync, username, password); - } +// url: string | undefined; + + // override open(method: string, url: string | URL): void; + // override open( + // method: string, url: string | URL, isAsync: boolean, + // username?: any): void; + // override open( + // method: string, url: string | URL, isAsync?: boolean, + // username?: any, + // password?: any): void { + + // this.url = url instanceof URL ? url.toString() : url + // const realAsync = isAsync ? isAsync : true; + // super.open(method, url, realAsync, username, password); + // } override setRequestHeader(name: string, value: string): void { this.headers[name] = value super.setRequestHeader(name, value) } - override send(body?: any): void { - if (!headerProcessUrlPattern || !this.url || this.url.search(headerProcessUrlPattern) >= 0) { - window.dispatchEvent(HeadersHandlerMessageEvent.makeEvent( - {url: this.url, headers: this.headers})) + private onLoaded() { + const match = !headerProcessUrlPattern || this.responseURL.match(headerProcessUrlPattern) + if (match) { + console.debug('process url', this.responseURL, this.headers) + window.dispatchEvent(RequestHandlerMessageEvent.makeEvent( + {url: this.responseURL, headers: this.headers})) + } else { + console.debug('skip url', this.responseURL) } + } + + override send(body?: any): void { + this.addEventListener("loadend", () => {this.onLoaded()}); super.send(body) } + + // override send(body?: any): void { + // if (!headerProcessUrlPattern || !this.url) { + // if (this.url && headerProcessUrlPattern && this.url.match(headerProcessUrlPattern)) { + // window.dispatchEvent(RequestHandlerMessageEvent.makeEvent( + // {url: this.url, headers: this.headers})) + // } else { + // console.log('skip url', this.url) + // } + // } + // super.send(body) + // } } -const initHeadersHandler = (urlPattern?: string) => { +const initRequestHandler = (urlPattern?: string) => { XMLHttpRequest = CustomXMLHttpRequest headerProcessUrlPattern = urlPattern ? new RegExp(urlPattern) : undefined + console.log('initRequestHandler', urlPattern, headerProcessUrlPattern) } export const initScript = () => { - RegisterHeadersHandlerEvent.subscribe((e) => { + RegisterRequestHandlerEvent.subscribe((e) => { const urlPattern = e.urlPattern - initHeadersHandler(urlPattern) + initRequestHandler(urlPattern) }) } diff --git a/scripts/brave_rewards/publisher/common/tabHandlers.ts b/scripts/brave_rewards/publisher/common/tabHandlers.ts index a9d15dc..1bddaff 100644 --- a/scripts/brave_rewards/publisher/common/tabHandlers.ts +++ b/scripts/brave_rewards/publisher/common/tabHandlers.ts @@ -2,8 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { getPort } from '../common/messaging' - let registeredOnUpdatedTab = false export const registerOnUpdatedTab = ( @@ -16,25 +14,12 @@ export const registerOnUpdatedTab = ( registeredOnUpdatedTab = true - const port = getPort() - if (!port) { - return + const runCallback = () => { + console.debug('OnUpdatedTab', location.href) + // Adapter for registerOnUpdatedTab consumers. + callback({status : 'complete', url: location.href}) } - port.postMessage({ - type: 'RegisterOnUpdatedTab', - mediaType: mediaType - }) - - port.onMessage.addListener(function (msg: any) { - if (!msg.data) { - return - } - switch (msg.type) { - case 'OnUpdatedTab': { - callback(msg.data.changeInfo) - break - } - } - }) + // TODO: filter events + (window as any).navigation.addEventListener('navigate', runCallback) } diff --git a/scripts/brave_rewards/publisher/common/webRequestHandlers.ts b/scripts/brave_rewards/publisher/common/webRequestHandlers.ts index 26a2b6e..739fb69 100644 --- a/scripts/brave_rewards/publisher/common/webRequestHandlers.ts +++ b/scripts/brave_rewards/publisher/common/webRequestHandlers.ts @@ -2,51 +2,13 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ -import { getPort } from '../common/messaging' -import {HeadersHandlerMessageEvent, RegisterHeadersHandlerEvent} from '../common/XHREvents' +import {RequestHandlerMessageEvent, RegisterRequestHandlerEvent} from '../common/XHREvents' -let registeredOnCompletedWebRequestHandler = false - -export const registerOnCompletedWebRequestHandler = ( - mediaType: string, - urlPattern: string, - callback: (mediaType: string, details: any) => void -) => { - if (!mediaType || registeredOnCompletedWebRequestHandler) { - return - } - - registeredOnCompletedWebRequestHandler = true - - const port = getPort() - if (!port) { - return - } - - port.postMessage({ - type: 'RegisterOnCompletedWebRequest', - mediaType, - data: { - urlPatterns: [urlPattern] - } - }) - - port.onMessage.addListener((msg: any) => { - switch (msg.type) { - case 'OnCompletedWebRequest': { - callback(msg.mediaType, msg.details) - break - } - } - }) -} - - -export const registerHeadersHandler = ( +export const registerOnBeforeRequestHandler = ( urlPattern: string | undefined, - callback: (headers: any) => void + callback: (event: RequestHandlerMessageEvent) => void ) => { - HeadersHandlerMessageEvent.subscribe((e) => callback(e.headers)) - console.log('send RegisterHeadersHandlerEvent') - dispatchEvent(RegisterHeadersHandlerEvent.makeEvent({urlPattern})) + RequestHandlerMessageEvent.subscribe((e) => callback(e)) + console.log('send RegisterRequestHandlerEvent') + dispatchEvent(RegisterRequestHandlerEvent.makeEvent({urlPattern})) } diff --git a/scripts/brave_rewards/publisher/twitter/twitterBase.ts b/scripts/brave_rewards/publisher/twitter/twitterBase.ts index cb25823..af70b52 100644 --- a/scripts/brave_rewards/publisher/twitter/twitterBase.ts +++ b/scripts/brave_rewards/publisher/twitter/twitterBase.ts @@ -11,13 +11,6 @@ import * as types from './types' import * as utils from '../common/utils' import * as webRequestHandlers from '../common/webRequestHandlers' -const handleHeaders = (headers: any) => { - console.log('handleHeaders', headers) - if (auth.processRequestHeaders(headers)) { - publisherInfo.send() - } -} - const handleOnUpdatedTab = (changeInfo: any) => { if (!changeInfo || !changeInfo.url) { return @@ -58,9 +51,14 @@ const initScript = () => { // TODO: remove the timeout when XHRInterceptor is injected automatically. setTimeout( () => { - webRequestHandlers.registerHeadersHandler( - types.sendHeadersUrl, - handleHeaders) + webRequestHandlers.registerOnBeforeRequestHandler( + '^' + types.sendHeadersUrl, + (event) => { + if (auth.processRequestHeaders(event.headers)) { + publisherInfo.send() + } + } + ) tabHandlers.registerOnUpdatedTab(types.mediaType, handleOnUpdatedTab) }, 5000); diff --git a/scripts/brave_rewards/publisher/twitter/types.ts b/scripts/brave_rewards/publisher/twitter/types.ts index f791ab6..e0ce383 100644 --- a/scripts/brave_rewards/publisher/twitter/types.ts +++ b/scripts/brave_rewards/publisher/twitter/types.ts @@ -6,4 +6,4 @@ export const mediaType = 'twitter' export const mediaDomain = 'twitter.com' export const baseApiUrl = 'https://api.' + location.hostname -export const sendHeadersUrl = baseApiUrl + '/1.1/*' +export const sendHeadersUrl = baseApiUrl + '/1.1/' diff --git a/scripts/brave_rewards/publisher/youtube/mediaDuration.ts b/scripts/brave_rewards/publisher/youtube/mediaDuration.ts index 763ac35..6ef9212 100644 --- a/scripts/brave_rewards/publisher/youtube/mediaDuration.ts +++ b/scripts/brave_rewards/publisher/youtube/mediaDuration.ts @@ -21,6 +21,7 @@ export const sendMetadataFromUrl = (url: URL) => { const mediaId = utils.getMediaIdFromParts(searchParams) const mediaKey = commonUtils.buildMediaKey(types.mediaType, mediaId) const duration = utils.getMediaDurationFromParts(searchParams) + console.debug('parsed MediaDurationMetadata', mediaKey, duration, firstVisit) const port = getPort() if (!port) { diff --git a/scripts/brave_rewards/publisher/youtube/youtubeBase.ts b/scripts/brave_rewards/publisher/youtube/youtubeBase.ts index c5a68a1..fa090ba 100644 --- a/scripts/brave_rewards/publisher/youtube/youtubeBase.ts +++ b/scripts/brave_rewards/publisher/youtube/youtubeBase.ts @@ -8,22 +8,29 @@ import * as webRequestHandlers from '../common/webRequestHandlers' import * as mediaDuration from './mediaDuration' import * as publisherInfo from './publisherInfo' -import * as types from './types' import * as utils from './utils' -const mediaDurationUrlPattern = 'https://www.youtube.com/api/stats/watchtime?*' +const mediaDurationUrlPattern = '^https://www.youtube.com/api/stats/watchtime?' -const handleOnCompletedWebRequest = (mediaType: string, details: any) => { - if (mediaType !== types.mediaType) { - return - } - - if (!details || !details.url) { - return - } +let onCompletedWebRequestHandlerRegistered = false +const registerOnCompletedWebRequestHandler = () => { + // TODO: remove timeout + setTimeout(() => { + if (onCompletedWebRequestHandlerRegistered) + return + onCompletedWebRequestHandlerRegistered = true + console.log('registerOnCompletedWebRequestHandler') - const url = new URL(details.url) - mediaDuration.sendMetadataFromUrl(url) + webRequestHandlers.registerOnBeforeRequestHandler( + mediaDurationUrlPattern, (event) => { + if (!event.url) + return + const url = new URL(event.url) + mediaDuration.sendMetadataFromUrl(url) + } + ) + publisherInfo.send() + }, 5000); } const initScript = () => { @@ -46,11 +53,7 @@ const initScript = () => { document.visibilityState === 'visible' && !utils.isVideoPath(location.pathname)) { setTimeout(() => { - webRequestHandlers.registerOnCompletedWebRequestHandler( - types.mediaType, - mediaDurationUrlPattern, - handleOnCompletedWebRequest) - publisherInfo.send() + registerOnCompletedWebRequestHandler() }, 200) } }) @@ -59,11 +62,7 @@ const initScript = () => { // on visibility change document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible') { - webRequestHandlers.registerOnCompletedWebRequestHandler( - types.mediaType, - mediaDurationUrlPattern, - handleOnCompletedWebRequest) - publisherInfo.send() + registerOnCompletedWebRequestHandler() } }) @@ -73,11 +72,7 @@ const initScript = () => { // finished loading by then document.addEventListener('yt-page-data-updated', function () { if (document.visibilityState === 'visible') { - webRequestHandlers.registerOnCompletedWebRequestHandler( - types.mediaType, - mediaDurationUrlPattern, - handleOnCompletedWebRequest) - publisherInfo.send() + registerOnCompletedWebRequestHandler() } mediaDuration.setFirstVisit(true) })