Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ba41691296 | |||
| 8786aa91b3 | |||
| 0623d10653 | |||
| 85174d4994 |
+13
-1
@@ -1,5 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## v0.11.1
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.11.0...v0.11.1)
|
||||
|
||||
### 🚀 Enhancements
|
||||
|
||||
- Add util for detecting URL changes in content scripts ([#264](https://github.com/wxt-dev/wxt/pull/264))
|
||||
|
||||
### 🏡 Chore
|
||||
|
||||
- Upgrade templates to `wxt@^0.11.0` ([#263](https://github.com/wxt-dev/wxt/pull/263))
|
||||
|
||||
## v0.11.0
|
||||
|
||||
[compare changes](https://github.com/wxt-dev/wxt/compare/v0.10.4...v0.11.0)
|
||||
@@ -19,7 +31,7 @@
|
||||
|
||||
#### ⚠️ Breaking Changes
|
||||
|
||||
- ⚠️ Vite 5 support ([#261](https://github.com/wxt-dev/wxt/pull/261))
|
||||
- You will need to update any other Vite plugins to a version that supports Vite 5 ([#261](https://github.com/wxt-dev/wxt/pull/261))
|
||||
|
||||
### ❤️ Contributors
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export default defineContentScript({
|
||||
// Site that uses HTML5 history
|
||||
matches: ['*://*.crunchyroll.com/*'],
|
||||
|
||||
main(ctx) {
|
||||
ctx.addEventListener(window, 'wxt:locationchange', ({ newUrl, oldUrl }) => {
|
||||
console.log('Location changed:', newUrl.href, oldUrl.href);
|
||||
});
|
||||
console.log('Watching for location change...');
|
||||
},
|
||||
});
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "wxt",
|
||||
"type": "module",
|
||||
"version": "0.11.0",
|
||||
"version": "0.11.1",
|
||||
"description": "Next gen framework for developing web extensions",
|
||||
"engines": {
|
||||
"node": ">=18",
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { ContentScriptDefinition } from '~/types';
|
||||
import { browser } from '~/browser';
|
||||
import { logger } from '~/client/utils/logger';
|
||||
import { WxtLocationChangeEvent, getUniqueEventName } from './custom-events';
|
||||
import { createLocationWatcher } from './location-watcher';
|
||||
|
||||
/**
|
||||
* Implements [`AbortController`](https://developer.mozilla.org/en-US/docs/Web/API/AbortController).
|
||||
@@ -14,6 +16,7 @@ export class ContentScriptContext implements AbortController {
|
||||
|
||||
#isTopFrame = window.self === window.top;
|
||||
#abortController: AbortController;
|
||||
#locationWatcher = createLocationWatcher(this);
|
||||
|
||||
constructor(
|
||||
private readonly contentScriptName: string,
|
||||
@@ -137,23 +140,42 @@ export class ContentScriptContext implements AbortController {
|
||||
/**
|
||||
* Call `target.addEventListener` and remove the event listener when the context is invalidated.
|
||||
*
|
||||
* Includes additional events useful for content scripts:
|
||||
*
|
||||
* - `"wxt:locationchange"` - Triggered when HTML5 history mode is used to change URL. Content
|
||||
* scripts are not reloaded when navigating this way, so this can be used to reset the content
|
||||
* script state on URL change, or run custom code.
|
||||
*
|
||||
* @example
|
||||
* ctx.addEventListener(window, "mousemove", () => {
|
||||
* // ...
|
||||
* });
|
||||
* ctx.addEventListener(document, "visibilitychange", () => {
|
||||
* // ...
|
||||
* });
|
||||
* ctx.addEventListener(document, "wxt:locationchange", () => {
|
||||
* // ...
|
||||
* });
|
||||
*/
|
||||
addEventListener(
|
||||
target: any,
|
||||
type: string,
|
||||
handler: (event: Event) => void,
|
||||
addEventListener<
|
||||
TTarget extends EventTarget,
|
||||
TType extends keyof WxtContentScriptEventMap,
|
||||
>(
|
||||
target: TTarget,
|
||||
type: TType,
|
||||
handler: (event: WxtContentScriptEventMap[TType]) => void,
|
||||
options?: AddEventListenerOptions,
|
||||
) {
|
||||
target.addEventListener?.(type, handler, options);
|
||||
this.onInvalidated(
|
||||
() => target.removeEventListener?.(type, handler, options),
|
||||
if (type === 'wxt:locationchange') {
|
||||
// Start the location watcher when adding the event for the first time
|
||||
if (this.isValid) this.#locationWatcher.run();
|
||||
}
|
||||
|
||||
target.addEventListener?.(
|
||||
type.startsWith('wxt:') ? getUniqueEventName(type) : type,
|
||||
// @ts-expect-error: Event don't match, but that's OK, EventTarget doesn't allow custom types in the callback
|
||||
handler,
|
||||
{
|
||||
...options,
|
||||
signal: this.signal,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -193,3 +215,7 @@ export class ContentScriptContext implements AbortController {
|
||||
this.onInvalidated(() => removeEventListener('message', cb));
|
||||
}
|
||||
}
|
||||
|
||||
interface WxtContentScriptEventMap extends WindowEventMap {
|
||||
'wxt:locationchange': WxtLocationChangeEvent;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { browser } from '~/browser';
|
||||
|
||||
export class WxtLocationChangeEvent extends Event {
|
||||
static EVENT_NAME = getUniqueEventName('wxt:locationchange');
|
||||
|
||||
constructor(
|
||||
readonly newUrl: URL,
|
||||
readonly oldUrl: URL,
|
||||
) {
|
||||
super(WxtLocationChangeEvent.EVENT_NAME, {});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an event name unique to the extension and content script that's running.
|
||||
*/
|
||||
export function getUniqueEventName(eventName: string): string {
|
||||
// During the build process, __ENTRYPOINT__ is not defined when importing entrypoints to get their
|
||||
// metadata.
|
||||
const entrypointName =
|
||||
typeof __ENTRYPOINT__ === 'undefined' ? 'build' : __ENTRYPOINT__;
|
||||
|
||||
return `${browser.runtime.id}:${entrypointName}:${eventName}`;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { ContentScriptContext } from '.';
|
||||
import { WxtLocationChangeEvent } from './custom-events';
|
||||
|
||||
/**
|
||||
* Create a util that watches for URL changes, dispatching the custom event when detected. Stops
|
||||
* watching when content script is invalidated.
|
||||
*/
|
||||
export function createLocationWatcher(ctx: ContentScriptContext) {
|
||||
let interval: number | undefined;
|
||||
let oldUrl: URL;
|
||||
|
||||
return {
|
||||
/**
|
||||
* Ensure the location watcher is actively looking for URL changes. If it's already watching,
|
||||
* this is a noop.
|
||||
*/
|
||||
run() {
|
||||
if (interval != null) return;
|
||||
|
||||
oldUrl = new URL(location.href);
|
||||
interval = ctx.setInterval(() => {
|
||||
let newUrl = new URL(location.href);
|
||||
if (newUrl.href !== oldUrl.href) {
|
||||
window.dispatchEvent(new WxtLocationChangeEvent(newUrl, oldUrl));
|
||||
oldUrl = newUrl;
|
||||
}
|
||||
}, 1e3);
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -23,6 +23,6 @@
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"typescript": "^5.3.2",
|
||||
"wxt": "^0.10.0"
|
||||
"wxt": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@
|
||||
"svelte-check": "^3.4.6",
|
||||
"tslib": "^2.6.0",
|
||||
"typescript": "^5.3.2",
|
||||
"wxt": "^0.10.0"
|
||||
"wxt": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5.3.2",
|
||||
"wxt": "^0.10.0"
|
||||
"wxt": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@
|
||||
"@vitejs/plugin-vue": "^4.5.1",
|
||||
"typescript": "^5.3.2",
|
||||
"vue-tsc": "^1.8.25",
|
||||
"wxt": "^0.10.0"
|
||||
"wxt": "^0.11.0"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user