vite-userscript-plugin 1.4.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # vite-userscript-plugin
2
2
 
3
- ![npm](https://img.shields.io/npm/v/vite-userscript-plugin)
4
- ![license](https://img.shields.io/github/license/crashmax-dev/vite-userscript-plugin)
3
+ [![npm](https://img.shields.io/npm/v/vite-userscript-plugin)](https://npmjs.com/vite-userscript-plugin)
4
+ [![license](https://img.shields.io/github/license/crashmax-dev/vite-userscript-plugin)](./LICENCE)
5
+ [![template](https://img.shields.io/github/package-json/v/crashmax-dev/vite-userscript-template?label=vite-userscript-template)](https://github.com/crashmax-dev/vite-userscript-template)
5
6
 
6
- > ⚡️ Tampermonkey userscript developing and build plugin based on [Vite](https://vitejs.dev).\
7
- > 📦 Use this [template](https://github.com/crashmax-dev/vite-userscript-template) to initialize your project.
7
+ > ⚡️ Tampermonkey userscript developing and build plugin based on [Vite](https://vitejs.dev).
8
8
 
9
9
  ## Features
10
10
 
@@ -12,7 +12,7 @@
12
12
  - 🔧 Configure Tampermonkey's Userscript header.
13
13
  - 💨 Import all `grant` by default in development mode.
14
14
  - 📝 Automatically add used `grant` when building for production.
15
- - 📦 Built-in Tampermonkey's TypeScript type difinition.
15
+ - 📦 Built-in Tampermonkey's TypeScript type definition.
16
16
 
17
17
  ## Install
18
18
 
@@ -28,9 +28,7 @@ yarn add vite-userscript-plugin -D
28
28
  pnpm add vite-userscript-plugin -D
29
29
  ```
30
30
 
31
- ## Usage
32
-
33
- ### `vite.config.ts`
31
+ ### Setup `vite.config.ts`
34
32
 
35
33
  ```js
36
34
  import { defineConfig } from 'vite'
@@ -45,11 +43,10 @@ export default defineConfig((config) => {
45
43
  header: {
46
44
  name,
47
45
  version,
48
- match: [
49
- '*://example.com',
50
- '*://example.org',
51
- '*://example.edu'
52
- ]
46
+ match: '*://example.com'
47
+ },
48
+ server: {
49
+ port: 3000
53
50
  }
54
51
  })
55
52
  ]
@@ -57,9 +54,10 @@ export default defineConfig((config) => {
57
54
  })
58
55
  ```
59
56
 
60
- ### `package.json`
57
+ ### Setup scripts
61
58
 
62
59
  ```json
60
+ // package.json
63
61
  {
64
62
  "scripts": {
65
63
  "dev": "vite build --watch --mode development",
@@ -68,13 +66,14 @@ export default defineConfig((config) => {
68
66
  }
69
67
  ```
70
68
 
71
- ### `tsconfig.json`
69
+ ### Setup TypeScript
72
70
 
73
71
  ```json
72
+ // tsconfig.json
74
73
  {
75
74
  "compilerOptions": {
76
75
  "types": [
77
- "vite-userscript-plugin/tampermonkey"
76
+ "vite-userscript-plugin/types/tampermonkey"
78
77
  ]
79
78
  }
80
79
  }
@@ -110,17 +109,10 @@ interface UserscriptPluginConfig {
110
109
  }
111
110
  ```
112
111
 
113
- ## Example
112
+ ## Examples
114
113
 
115
114
  See the [examples](https://github.com/crashmax-dev/vite-userscript-plugin/tree/master/examples) folder.
116
115
 
117
- ## Used by
118
-
119
- - [vite-userscript-template](https://github.com/crashmax-dev/vite-userscript-template)
120
- - [netangels-userscript](https://github.com/crashmax-dev/netangels-userscript)
121
- - [godev-code-highlight](https://github.com/crashmax-dev/godev-code-highlight)
122
- - [beautifier-userscript](https://github.com/crashmax-dev/beautifier-userscript)
123
-
124
116
  ## License
125
117
 
126
118
  [MIT](./LICENCE) © [crashmax](https://github.com/crashmax-dev)
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
- "use strict";var Z=Object.create;var b=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty;var oe=(e,r)=>{for(var t in r)b(e,t,{get:r[t],enumerable:!0})},T=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of te(r))!ne.call(e,s)&&s!==t&&b(e,s,{get:()=>r[s],enumerable:!(n=ee(r,s))||n.enumerable});return e};var u=(e,r,t)=>(t=e!=null?Z(re(e)):{},T(r||!e||!e.__esModule?b(t,"default",{value:e,enumerable:!0}):t,e)),se=e=>T(b({},"__esModule",{value:!0}),e);var le={};oe(le,{default:()=>N});module.exports=se(le);var V=u(require("get-port"),1),c=require("fs"),D=require("http"),a=require("path"),K=require("url"),A=u(require("open"),1),M=u(require("picocolors"),1),H=u(require("sanitize-filename"),1),W=u(require("serve-handler"),1),q=require("vite"),B=require("websocket");var g=class{constructor(r){this.config=r;this.downloadMeta(),this.configKeys=Object.keys(this.config),this.maxKeyLength=Math.max(...this.configKeys.map(t=>t.length))+1}header=[];configKeys;maxKeyLength;downloadMeta(){let{name:r,homepage:t,updateURL:n,downloadURL:s}=this.config;t&&!n&&!s&&(this.config.updateURL=new URL(`${r}.meta.js`,t).href,this.config.downloadURL=new URL(`${r}.user.js`,t).href)}addSpaces(r){return" ".repeat(this.maxKeyLength-r.length)}addMetadata(r,t){let n=typeof t=="boolean";n&&!t||(t=n?"":`${this.addSpaces(r)}${t}`,this.header.push(`// @${r}${t}`))}generate(){for(let[r,t]of Object.entries(this.config))if(Array.isArray(t))t.forEach(n=>this.addMetadata(r,n));else{if(t===void 0)continue;this.addMetadata(r,t)}return["// ==UserScript==",...this.header,"// ==/UserScript=="].join(`
2
- `)}};function E({entry:e,header:r}){return{build:{lib:{entry:e,name:r.name,formats:["iife"],fileName:()=>`${r.name}.js`},rollupOptions:{output:{extend:!0}}}}}var F=new RegExp(/.(t|j)sx?/),L=new RegExp(/\.(s?css|sass)$/),ie=["setValue","getValue","deleteValue","listValues","setClipboard","addStyle","addElement","addValueChangeListener","removeValueChangeListener","registerMenuCommand","unregisterMenuCommand","download","getTab","getTabs","saveTab","openInTab","notification","getResourceURL","getResourceText","xmlhttpRequest","log","info"],ae=["unsafeWindow","window.onurlchange","window.focus","window.close"],h=ie.map(e=>[`GM_${e}`,`GM.${e}`]).flat();h.push(...ae);var O=require("vite");function U(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function y({file:e,name:r,loader:t}){let{code:n}=await(0,O.transformWithEsbuild)(e,r,{loader:t,minify:!0,sourcemap:!1,legalComments:"none"});return n}function k(e){let r=[];for(let t of h)e.indexOf(t)!==-1&&r.push(t);return r}var _=class{styles=new Map;async add(r,t){let n=await y({file:r,name:t,loader:"css"});return this.styles.set(t,n.replace(`
3
- `,"")),""}inject(){return this.styles.size?`GM_addStyle(\`${[...this.styles.values()].join("")}\`)`:void 0}merge(r){let t=[];for(let n of r){let s=this.styles.get(n);!s||t.push([n,s])}this.styles.clear(),t.forEach(n=>this.styles.set(...n))}},j=new _;var ce={};function N(e){let r,t,n=null,s=(0,a.dirname)((0,K.fileURLToPath)(ce.url)),S=(0,q.createLogger)("info",{prefix:"[vite-userscript-plugin]",allowClearScreen:!0}),w=(0,D.createServer)((o,i)=>(0,W.default)(o,i,{public:r.build.outDir})),z=B.server;return new z({httpServer:w}).on("request",o=>{n=o.accept(null,o.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return E(e)},async configResolved(o){r=o,t=o.build.watch??!1,e.entry=(0,a.resolve)(o.root,e.entry),e.header.name=(0,H.default)(e.header.name),Array.from(["match","require","include","exclude","resource","connect"]).forEach(i=>{let p=e.header[i];e.header[i]=U(p)}),e.server={port:await(0,V.default)(),open:!1,...e.server}},async transform(o,i){let p=o;return L.test(i)&&(p=await j.add(o,i)),i.includes(e.entry)&&(p=o+"__STYLE__"),{code:p,map:null}},generateBundle(o,i){for(let[p,m]of Object.entries(i)){let f=Object.keys(m.modules).filter($=>L.test($));f.length&&j.merge(f)}},async writeBundle(o,i){let{open:p,port:m}=e.server,P=`${e.header.name}.user.js`,f=`${e.header.name}.proxy.user.js`,$=`${e.header.name}.meta.js`;for(let[d]of Object.entries(i))if(F.test(d)){let x=r.root,v=r.build.outDir,C=(0,a.resolve)(x,v,d),Y=(0,a.resolve)(x,v,P),I=(0,a.resolve)(x,v,f),J=(0,a.resolve)(x,v,$),R=(0,a.resolve)(s,`hot-reload-${e.header.name}.js`);try{let l=(0,c.readFileSync)(C,"utf8");if(l=l.replace("__STYLE__",`${j.inject()}`),l=await y({file:l,name:d,loader:"js"}),e.header.grant=U(t?h:[...k(l),...e.header.grant??[]]),t){let Q=(0,c.readFileSync)((0,a.resolve)(s,"hot-reload.js"),"utf8"),X=await y({file:Q.replace("__WS__",`ws://localhost:${m}`),name:R,loader:"js"});(0,c.writeFileSync)(R,X),(0,c.writeFileSync)(I,new g({...e.header,require:[...e.header.require,"file://"+R,"file://"+C]}).generate())}let G=new g(e.header).generate();(0,c.writeFileSync)(C,l),(0,c.writeFileSync)(J,G),(0,c.writeFileSync)(Y,`${G}
1
+ "use strict";var Z=Object.create;var b=Object.defineProperty;var ee=Object.getOwnPropertyDescriptor;var te=Object.getOwnPropertyNames;var re=Object.getPrototypeOf,ne=Object.prototype.hasOwnProperty;var se=(e,r)=>{for(var t in r)b(e,t,{get:r[t],enumerable:!0})},T=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of te(r))!ne.call(e,o)&&o!==t&&b(e,o,{get:()=>r[o],enumerable:!(n=ee(r,o))||n.enumerable});return e};var u=(e,r,t)=>(t=e!=null?Z(re(e)):{},T(r||!e||!e.__esModule?b(t,"default",{value:e,enumerable:!0}):t,e)),oe=e=>T(b({},"__esModule",{value:!0}),e);var le={};se(le,{default:()=>N});module.exports=oe(le);var V=u(require("get-port"),1),c=require("fs"),D=require("http"),a=require("path"),K=require("url"),A=u(require("open"),1),M=u(require("picocolors"),1),H=u(require("sanitize-filename"),1),W=u(require("serve-handler"),1),q=require("vite"),B=require("websocket");var g=class{constructor(r){this.config=r;this.downloadMeta(),this.configKeys=Object.keys(this.config),this.maxKeyLength=Math.max(...this.configKeys.map(t=>t.length))+1}header=[];configKeys;maxKeyLength;downloadMeta(){let{name:r,homepage:t,updateURL:n,downloadURL:o}=this.config;t&&!n&&!o&&(this.config.updateURL=new URL(`${r}.meta.js`,t).href,this.config.downloadURL=new URL(`${r}.user.js`,t).href)}addSpaces(r){return" ".repeat(this.maxKeyLength-r.length)}addMetadata(r,t){let n=typeof t=="boolean";n&&!t||(t=n?"":`${this.addSpaces(r)}${t}`,this.header.push(`// @${r}${t}`))}generate(){for(let[r,t]of Object.entries(this.config))if(Array.isArray(t))t.forEach(n=>this.addMetadata(r,n));else{if(t===void 0)continue;this.addMetadata(r,t)}return["// ==UserScript==",...this.header,"// ==/UserScript=="].join(`
2
+ `)}};function E({entry:e,header:r}){return{build:{lib:{entry:e,name:r.name,formats:["iife"],fileName:()=>`${r.name}.js`},rollupOptions:{output:{extend:!0}}}}}var F=new RegExp(/\.(t|j)sx?$/),R=new RegExp(/\.(s[ac]|c|le)ss$/),ie=["setValue","getValue","deleteValue","listValues","setClipboard","addStyle","addElement","addValueChangeListener","removeValueChangeListener","registerMenuCommand","unregisterMenuCommand","download","getTab","getTabs","saveTab","openInTab","notification","getResourceURL","getResourceText","xmlhttpRequest","log","info"],ae=["unsafeWindow","window.onurlchange","window.focus","window.close"],h=ie.map(e=>[`GM_${e}`,`GM.${e}`]).flat();h.push(...ae);var O=require("vite");function U(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function y({file:e,name:r,loader:t}){let{code:n}=await(0,O.transformWithEsbuild)(e,r,{loader:t,minify:!0,sourcemap:!1,legalComments:"none"});return n}function k(e){let r=[];for(let t of h)e.indexOf(t)!==-1&&r.push(t);return r}var _=class{styles=new Map;async add(r,t){let n=await y({file:r,name:t,loader:"css"});return this.styles.set(t,n.replace(`
3
+ `,"")),""}inject(){return this.styles.size?`GM_addStyle(\`${[...this.styles.values()].join("")}\`)`:void 0}merge(r){let t=[];for(let n of r){let o=this.styles.get(n);!o||t.push([n,o])}this.styles.clear(),t.forEach(n=>this.styles.set(...n))}},j=new _;var ce={};function N(e){let r,t,n=null,o=(0,a.dirname)((0,K.fileURLToPath)(ce.url)),$=(0,q.createLogger)("info",{prefix:"[vite-userscript-plugin]",allowClearScreen:!0}),w=(0,D.createServer)((s,i)=>(0,W.default)(s,i,{public:r.build.outDir})),z=B.server;return new z({httpServer:w}).on("request",s=>{n=s.accept(null,s.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return E(e)},async configResolved(s){r=s,t=s.build.watch??!1,e.entry=(0,a.resolve)(s.root,e.entry),e.header.name=(0,H.default)(e.header.name),Array.from(["match","require","include","exclude","resource","connect"]).forEach(i=>{let p=e.header[i];e.header[i]=U(p)}),e.server={port:await(0,V.default)(),open:!1,...e.server}},async transform(s,i){let p=s;return R.test(i)&&(p=await j.add(s,i)),i.includes(e.entry)&&(p=s+"__STYLE__"),{code:p,map:null}},generateBundle(s,i){for(let[p,d]of Object.entries(i)){let f=Object.keys(d.modules).filter(S=>R.test(S));f.length&&j.merge(f)}},async writeBundle(s,i){let{open:p,port:d}=e.server,P=`${e.header.name}.user.js`,f=`${e.header.name}.proxy.user.js`,S=`${e.header.name}.meta.js`;for(let[m]of Object.entries(i))if(F.test(m)){let x=r.root,v=r.build.outDir,C=(0,a.resolve)(x,v,m),Y=(0,a.resolve)(x,v,P),I=(0,a.resolve)(x,v,f),J=(0,a.resolve)(x,v,S),L=(0,a.resolve)(o,`ws-${e.header.name}.js`);try{let l=(0,c.readFileSync)(C,"utf8");if(l=l.replace("__STYLE__",`${j.inject()}`),l=await y({file:l,name:m,loader:"js"}),e.header.grant=U(t?h:[...k(l),...e.header.grant??[]]),t){let Q=(0,c.readFileSync)((0,a.resolve)(o,"ws.js"),"utf8"),X=await y({file:Q.replace("__WS__",`ws://localhost:${d}`),name:L,loader:"js"});(0,c.writeFileSync)(L,X),(0,c.writeFileSync)(I,new g({...e.header,require:[...e.header.require,"file://"+L,"file://"+C]}).generate())}let G=new g(e.header).generate();(0,c.writeFileSync)(C,l),(0,c.writeFileSync)(J,G),(0,c.writeFileSync)(Y,`${G}
4
4
 
5
- ${l}`)}catch(l){console.log(l)}}if(t&&!w.listening){let d=`http://localhost:${m}`;w.listen(m,()=>{S.clearScreen("info"),S.info(M.default.blue(`Running at: ${M.default.gray(d)}`))}),p&&await(0,A.default)(`${d}/${f}`)}else t||(w.close(),process.exit(0))},buildEnd(){t&&(S.clearScreen("info"),n&&n.sendUTF(JSON.stringify({message:"reload"})))}}}0&&(module.exports={});
5
+ ${l}`)}catch(l){console.log(l)}}if(t&&!w.listening){let m=`http://localhost:${d}`;w.listen(d,()=>{$.clearScreen("info"),$.info(M.default.blue(`Running at: ${M.default.gray(m)}`))}),p&&await(0,A.default)(`${m}/${f}`)}else t||(w.close(),process.exit(0))},buildEnd(){t&&($.clearScreen("info"),n&&n.sendUTF(JSON.stringify({message:"reload"})))}}}0&&(module.exports={});
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import q from"get-port";import{readFileSync as T,writeFileSync as h}from"fs";import{createServer as B}from"http";import{dirname as N,resolve as c}from"path";import{fileURLToPath as z}from"url";import Y from"open";import E from"picocolors";import I from"sanitize-filename";import J from"serve-handler";import{createLogger as Q}from"vite";import{server as X}from"websocket";var f=class{constructor(r){this.config=r;this.downloadMeta(),this.configKeys=Object.keys(this.config),this.maxKeyLength=Math.max(...this.configKeys.map(t=>t.length))+1}header=[];configKeys;maxKeyLength;downloadMeta(){let{name:r,homepage:t,updateURL:n,downloadURL:l}=this.config;t&&!n&&!l&&(this.config.updateURL=new URL(`${r}.meta.js`,t).href,this.config.downloadURL=new URL(`${r}.user.js`,t).href)}addSpaces(r){return" ".repeat(this.maxKeyLength-r.length)}addMetadata(r,t){let n=typeof t=="boolean";n&&!t||(t=n?"":`${this.addSpaces(r)}${t}`,this.header.push(`// @${r}${t}`))}generate(){for(let[r,t]of Object.entries(this.config))if(Array.isArray(t))t.forEach(n=>this.addMetadata(r,n));else{if(t===void 0)continue;this.addMetadata(r,t)}return["// ==UserScript==",...this.header,"// ==/UserScript=="].join(`
2
- `)}};function M({entry:e,header:r}){return{build:{lib:{entry:e,name:r.name,formats:["iife"],fileName:()=>`${r.name}.js`},rollupOptions:{output:{extend:!0}}}}}var P=new RegExp(/.(t|j)sx?/),C=new RegExp(/\.(s?css|sass)$/),A=["setValue","getValue","deleteValue","listValues","setClipboard","addStyle","addElement","addValueChangeListener","removeValueChangeListener","registerMenuCommand","unregisterMenuCommand","download","getTab","getTabs","saveTab","openInTab","notification","getResourceURL","getResourceText","xmlhttpRequest","log","info"],H=["unsafeWindow","window.onurlchange","window.focus","window.close"],u=A.map(e=>[`GM_${e}`,`GM.${e}`]).flat();u.push(...H);import{transformWithEsbuild as W}from"vite";function R(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function g({file:e,name:r,loader:t}){let{code:n}=await W(e,r,{loader:t,minify:!0,sourcemap:!1,legalComments:"none"});return n}function G(e){let r=[];for(let t of u)e.indexOf(t)!==-1&&r.push(t);return r}var L=class{styles=new Map;async add(r,t){let n=await g({file:r,name:t,loader:"css"});return this.styles.set(t,n.replace(`
3
- `,"")),""}inject(){return this.styles.size?`GM_addStyle(\`${[...this.styles.values()].join("")}\`)`:void 0}merge(r){let t=[];for(let n of r){let l=this.styles.get(n);!l||t.push([n,l])}this.styles.clear(),t.forEach(n=>this.styles.set(...n))}},v=new L;function Z(e){let r,t,n=null,l=N(z(import.meta.url)),b=Q("info",{prefix:"[vite-userscript-plugin]",allowClearScreen:!0}),y=B((o,s)=>J(o,s,{public:r.build.outDir})),F=X;return new F({httpServer:y}).on("request",o=>{n=o.accept(null,o.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return M(e)},async configResolved(o){r=o,t=o.build.watch??!1,e.entry=c(o.root,e.entry),e.header.name=I(e.header.name),Array.from(["match","require","include","exclude","resource","connect"]).forEach(s=>{let a=e.header[s];e.header[s]=R(a)}),e.server={port:await q(),open:!1,...e.server}},async transform(o,s){let a=o;return C.test(s)&&(a=await v.add(o,s)),s.includes(e.entry)&&(a=o+"__STYLE__"),{code:a,map:null}},generateBundle(o,s){for(let[a,d]of Object.entries(s)){let m=Object.keys(d.modules).filter(j=>C.test(j));m.length&&v.merge(m)}},async writeBundle(o,s){let{open:a,port:d}=e.server,U=`${e.header.name}.user.js`,m=`${e.header.name}.proxy.user.js`,j=`${e.header.name}.meta.js`;for(let[p]of Object.entries(s))if(P.test(p)){let w=r.root,x=r.build.outDir,S=c(w,x,p),O=c(w,x,U),k=c(w,x,m),V=c(w,x,j),$=c(l,`hot-reload-${e.header.name}.js`);try{let i=T(S,"utf8");if(i=i.replace("__STYLE__",`${v.inject()}`),i=await g({file:i,name:p,loader:"js"}),e.header.grant=R(t?u:[...G(i),...e.header.grant??[]]),t){let D=T(c(l,"hot-reload.js"),"utf8"),K=await g({file:D.replace("__WS__",`ws://localhost:${d}`),name:$,loader:"js"});h($,K),h(k,new f({...e.header,require:[...e.header.require,"file://"+$,"file://"+S]}).generate())}let _=new f(e.header).generate();h(S,i),h(V,_),h(O,`${_}
2
+ `)}};function M({entry:e,header:r}){return{build:{lib:{entry:e,name:r.name,formats:["iife"],fileName:()=>`${r.name}.js`},rollupOptions:{output:{extend:!0}}}}}var P=new RegExp(/\.(t|j)sx?$/),C=new RegExp(/\.(s[ac]|c|le)ss$/),A=["setValue","getValue","deleteValue","listValues","setClipboard","addStyle","addElement","addValueChangeListener","removeValueChangeListener","registerMenuCommand","unregisterMenuCommand","download","getTab","getTabs","saveTab","openInTab","notification","getResourceURL","getResourceText","xmlhttpRequest","log","info"],H=["unsafeWindow","window.onurlchange","window.focus","window.close"],u=A.map(e=>[`GM_${e}`,`GM.${e}`]).flat();u.push(...H);import{transformWithEsbuild as W}from"vite";function L(e){return[...new Set(Array.isArray(e)?e:e?[e]:[])]}async function g({file:e,name:r,loader:t}){let{code:n}=await W(e,r,{loader:t,minify:!0,sourcemap:!1,legalComments:"none"});return n}function G(e){let r=[];for(let t of u)e.indexOf(t)!==-1&&r.push(t);return r}var R=class{styles=new Map;async add(r,t){let n=await g({file:r,name:t,loader:"css"});return this.styles.set(t,n.replace(`
3
+ `,"")),""}inject(){return this.styles.size?`GM_addStyle(\`${[...this.styles.values()].join("")}\`)`:void 0}merge(r){let t=[];for(let n of r){let l=this.styles.get(n);!l||t.push([n,l])}this.styles.clear(),t.forEach(n=>this.styles.set(...n))}},v=new R;function Z(e){let r,t,n=null,l=N(z(import.meta.url)),b=Q("info",{prefix:"[vite-userscript-plugin]",allowClearScreen:!0}),y=B((s,o)=>J(s,o,{public:r.build.outDir})),F=X;return new F({httpServer:y}).on("request",s=>{n=s.accept(null,s.origin)}),{name:"vite-userscript-plugin",apply:"build",config(){return M(e)},async configResolved(s){r=s,t=s.build.watch??!1,e.entry=c(s.root,e.entry),e.header.name=I(e.header.name),Array.from(["match","require","include","exclude","resource","connect"]).forEach(o=>{let a=e.header[o];e.header[o]=L(a)}),e.server={port:await q(),open:!1,...e.server}},async transform(s,o){let a=s;return C.test(o)&&(a=await v.add(s,o)),o.includes(e.entry)&&(a=s+"__STYLE__"),{code:a,map:null}},generateBundle(s,o){for(let[a,m]of Object.entries(o)){let d=Object.keys(m.modules).filter(j=>C.test(j));d.length&&v.merge(d)}},async writeBundle(s,o){let{open:a,port:m}=e.server,U=`${e.header.name}.user.js`,d=`${e.header.name}.proxy.user.js`,j=`${e.header.name}.meta.js`;for(let[p]of Object.entries(o))if(P.test(p)){let w=r.root,x=r.build.outDir,$=c(w,x,p),O=c(w,x,U),k=c(w,x,d),V=c(w,x,j),S=c(l,`ws-${e.header.name}.js`);try{let i=T($,"utf8");if(i=i.replace("__STYLE__",`${v.inject()}`),i=await g({file:i,name:p,loader:"js"}),e.header.grant=L(t?u:[...G(i),...e.header.grant??[]]),t){let D=T(c(l,"ws.js"),"utf8"),K=await g({file:D.replace("__WS__",`ws://localhost:${m}`),name:S,loader:"js"});h(S,K),h(k,new f({...e.header,require:[...e.header.require,"file://"+S,"file://"+$]}).generate())}let _=new f(e.header).generate();h($,i),h(V,_),h(O,`${_}
4
4
 
5
- ${i}`)}catch(i){console.log(i)}}if(t&&!y.listening){let p=`http://localhost:${d}`;y.listen(d,()=>{b.clearScreen("info"),b.info(E.blue(`Running at: ${E.gray(p)}`))}),a&&await Y(`${p}/${m}`)}else t||(y.close(),process.exit(0))},buildEnd(){t&&(b.clearScreen("info"),n&&n.sendUTF(JSON.stringify({message:"reload"})))}}}export{Z as default};
5
+ ${i}`)}catch(i){console.log(i)}}if(t&&!y.listening){let p=`http://localhost:${m}`;y.listen(m,()=>{b.clearScreen("info"),b.info(E.blue(`Running at: ${E.gray(p)}`))}),a&&await Y(`${p}/${d}`)}else t||(y.close(),process.exit(0))},buildEnd(){t&&(b.clearScreen("info"),n&&n.sendUTF(JSON.stringify({message:"reload"})))}}}export{Z as default};
package/dist/ws.js ADDED
@@ -0,0 +1 @@
1
+ function n(){let e=new WebSocket("__WS__");e.addEventListener("close",()=>{setTimeout(n,1e3)}),e.addEventListener("error",()=>{e.close()}),e.addEventListener("message",()=>{location.reload()})}n();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vite-userscript-plugin",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.cjs",
@@ -11,7 +11,7 @@
11
11
  },
12
12
  "files": [
13
13
  "dist",
14
- "tampermonkey.d.ts"
14
+ "types"
15
15
  ],
16
16
  "repository": {
17
17
  "type": "git",
@@ -48,13 +48,13 @@
48
48
  "@types/node": "^18.7.18",
49
49
  "@types/serve-handler": "^6.1.1",
50
50
  "@types/websocket": "^1.0.5",
51
- "@vitest/ui": "^0.23.2",
51
+ "@vitest/ui": "^0.23.4",
52
52
  "tsup": "^6.2.3",
53
53
  "turbo": "^1.4.7",
54
54
  "typescript": "^4.8.3",
55
55
  "vite": "^3.1.2",
56
56
  "vite-plugin-dts": "^1.5.0",
57
- "vitest": "^0.23.2"
57
+ "vitest": "^0.23.4"
58
58
  },
59
59
  "peerDependencies": {
60
60
  "vite": ">=2.9.0"
@@ -0,0 +1,21 @@
1
+ # Userscript type definitions
2
+
3
+ [![tampermonkey](https://img.shields.io/npm/v/@types/tampermonkey?label=%40types%2Ftampermonkey)](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/tampermonkey)
4
+ [![greasemonkey](https://img.shields.io/npm/v/@types/greasemonkey?label=%40types%2Fgreasemonkey)](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/greasemonkey)
5
+ [![violentmonkey](https://img.shields.io/npm/v/@violentmonkey/types?label=%40violentmonkey%2Ftypes)](https://github.com/violentmonkey/types)
6
+
7
+ > Type declaration for `GM_*`, `GM.*` APIs in Tampermonkey, Greasemonkey and Violentmonkey.
8
+
9
+ ## Installation
10
+
11
+ ```sh
12
+ npm install --save @types/tampermonkey
13
+ ```
14
+
15
+ ```sh
16
+ npm install --save @types/greasemonkey
17
+ ```
18
+
19
+ ```sh
20
+ npm install --save @violentmonkey/types
21
+ ```
@@ -0,0 +1,314 @@
1
+ // Type definitions for Greasemonkey 4.x
2
+ // Project: http://www.greasespot.net/
3
+ // Definitions by: Kota Saito <https://github.com/kotas>
4
+ // Nikolay Borzov <https://github.com/nikolay-borzov>
5
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
6
+
7
+ // This definition is based on the API reference of Greasemonkey
8
+ // https://wiki.greasespot.net/Greasemonkey_Manual:API
9
+ // TypeScript Version: 3.2
10
+
11
+ declare namespace GM {
12
+ interface ScriptInfo {
13
+ /** Possibly empty string. */
14
+ description: string
15
+ excludes: string[]
16
+ includes: string[]
17
+ matches: string[]
18
+ name: string
19
+ /** Possibly empty string. */
20
+ namespace: string
21
+ /**
22
+ * An object keyed by resource name.
23
+ * Each value is an object with keys `name` and `mimetype` and `url`
24
+ * with string values.
25
+ */
26
+ resources: {
27
+ [resourceName: string]: {
28
+ name: string
29
+ mimetype: string
30
+ url: string
31
+ }
32
+ }
33
+ /** @default 'end' */
34
+ runAt: 'start' | 'end' | 'idle'
35
+ uuid: string
36
+ /** Possibly empty string. */
37
+ version: string
38
+ }
39
+
40
+ type Value = string | boolean | number
41
+
42
+ interface Response<TContext> {
43
+ readonly responseHeaders: string
44
+ readonly finalUrl: string
45
+ /** The same object passed into the original request */
46
+ readonly context?: TContext | undefined
47
+
48
+ readonly readyState: 1 | 2 | 3 | 4
49
+ readonly response: any
50
+ readonly responseText: string
51
+ readonly responseXML: Document | false
52
+ readonly status: number
53
+ readonly statusText: string
54
+ }
55
+
56
+ interface ProgressResponse<TContext> extends Response<TContext> {
57
+ lengthComputable: boolean
58
+ loaded: number
59
+ total: number
60
+ }
61
+
62
+ interface Request<TContext = any> {
63
+ // Fields
64
+
65
+ /**
66
+ * The URL to make the request to. Must be an absolute URL, beginning
67
+ * with the scheme. May be relative to the current page.
68
+ */
69
+ url: string
70
+ /** String type of HTTP request to make (E.G. "GET", "POST") */
71
+ method:
72
+ | 'GET'
73
+ | 'POST'
74
+ | 'PUT'
75
+ | 'DELETE'
76
+ | 'PATCH'
77
+ | 'HEAD'
78
+ | 'TRACE'
79
+ | 'OPTIONS'
80
+ | 'CONNECT'
81
+ /**
82
+ * When true, the data is sent as a Blob
83
+ * @default false
84
+ */
85
+ binary?: boolean | undefined
86
+ /**
87
+ * Any object (Compatibility: 1.10+). This object will also be the
88
+ * context property of the Response Object.
89
+ */
90
+ context?: TContext | undefined
91
+ /**
92
+ * Data to send in the request body. Usually for POST method requests.
93
+ * If the data field contains form-encoded data, you usually must also
94
+ * set the header `'Content-Type': 'application/x-www-form-urlencoded'`
95
+ * in the `headers` field.
96
+ */
97
+ data?: string | undefined
98
+ /** A set of headers to include in the request */
99
+ headers?:
100
+ | {
101
+ [header: string]: string
102
+ }
103
+ | undefined
104
+ /**
105
+ * A MIME type to specify with the request (e.g.
106
+ * "text/html; charset=ISO-8859-1")
107
+ */
108
+ overrideMimeType?: string | undefined
109
+ /** User name to use for authentication purposes. */
110
+ user?: string | undefined
111
+ /** Password to use for authentication purposes */
112
+ password?: string | undefined
113
+ /** Decode the response as specified type. Default value is "text" */
114
+ responseType?: XMLHttpRequestResponseType | undefined
115
+ /**
116
+ * When `true`, this is a synchronous request.
117
+ * Be careful: The entire Firefox UI will be locked and frozen until the
118
+ * request completes.In this mode, more data will be available in the
119
+ * return value.
120
+ */
121
+ synchronous?: boolean | undefined
122
+ /**
123
+ * The number of milliseconds to wait before terminating the call. Zero
124
+ * (the default) means wait forever.
125
+ */
126
+ timeout?: number | undefined
127
+ /**
128
+ * Object containing optional function callbacks to monitor the upload
129
+ * of data.
130
+ */
131
+ upload?:
132
+ | {
133
+ onabort?(response: Response<TContext>): void
134
+ onerror?(response: Response<TContext>): void
135
+ onload?(response: Response<TContext>): void
136
+ onprogress?(response: ProgressResponse<TContext>): void
137
+ }
138
+ | undefined
139
+
140
+ // Event handlers
141
+
142
+ /** Will be called when the request is aborted */
143
+ onabort?(response: Response<TContext>): void
144
+ /** Will be called if an error occurs while processing the request */
145
+ onerror?(response: Response<TContext>): void
146
+ /** Will be called when the request has completed successfully */
147
+ onload?(response: Response<TContext>): void
148
+ /** Will be called when the request progress changes */
149
+ onprogress?(response: ProgressResponse<TContext>): void
150
+ /** Will be called repeatedly while the request is in progress */
151
+ onreadystatechange?(response: Response<TContext>): void
152
+ /** Will be called if/when the request times out */
153
+ ontimeout?(response: Response<TContext>): void
154
+ }
155
+ }
156
+
157
+ /**
158
+ * Window object of the content page where the user script is running on.
159
+ * @see {@link http://wiki.greasespot.net/UnsafeWindow}
160
+ */
161
+ declare var unsafeWindow: Window
162
+
163
+ declare var GM: {
164
+ // Headers
165
+
166
+ /**
167
+ * Meta data about the running user script.
168
+ * @see {@link https://wiki.greasespot.net/GM.info}
169
+ */
170
+ info: {
171
+ /** An object containing data about the currently running script */
172
+ script: GM.ScriptInfo
173
+ /**
174
+ * A string, the entire literal Metadata Block (without the delimiters)
175
+ * for the currently running script
176
+ */
177
+ scriptMetaStr: string
178
+ /**
179
+ * The name of the user script engine handling this script's execution.
180
+ * The string `Greasemonkey`
181
+ */
182
+ scriptHandler: string
183
+ /** The version of Greasemonkey, a string e.g. `4.0` */
184
+ version: string
185
+ }
186
+
187
+ // Values
188
+
189
+ /**
190
+ * Allows user script authors to persist simple values across page loads and
191
+ * across origins.
192
+ * Strings, booleans, and integers are currently the only allowed data types.
193
+ * @see {@link https://wiki.greasespot.net/GM.setValue}
194
+ * @param name The unique (within this script) name for this value.
195
+ * Should be restricted to valid Javascript identifier characters.
196
+ * @param value Any valid value of these types. Any other type may cause
197
+ * undefined behavior, including crashes
198
+ * @returns A Promise, resolved successfully with no value on success,
199
+ * rejected with no value on failure
200
+ */
201
+ setValue(name: string, value: GM.Value): Promise<void>
202
+
203
+ /**
204
+ * Retrieves a value that was set with `GM.setValue`
205
+ * @see {@link https://wiki.greasespot.net/GM.getValue}
206
+ * @param name The property name to get
207
+ * @param defaultValue The default value to be returned when none has
208
+ * previously been set
209
+ * @returns A Promise, rejected in case of error and otherwise resolved with:
210
+ * - When this name has been set - `string`, `integer` or `boolean` as
211
+ * previously set
212
+ * - When this name has not been set, and default is provided - The value
213
+ * passed as default
214
+ * - When this name has not been set, and default is not provided -
215
+ * `undefined`
216
+ * @example
217
+ * // Retrieving the value associated with the name 'timezoneOffset' with a default value defined:
218
+ * const timezoneOffset = await GM.getValue("timezoneOffset", -5)
219
+ * @example
220
+ * // For structured data used `JSON.stringify()` to place an object into storage and then `JSON.parse()` to convert it back
221
+ * const storedObject = JSON.parse(await GM.getValue('foo', '{}'));
222
+ */
223
+ getValue(name: string): Promise<GM.Value | undefined>
224
+ getValue<TValue = GM.Value>(
225
+ name: string,
226
+ defaultValue: TValue
227
+ ): Promise<TValue>
228
+
229
+ /**
230
+ * Deletes an existing name / value pair from storage.
231
+ * @see {@link https://wiki.greasespot.net/GM.deleteValue}
232
+ * @param name Property name to delete
233
+ * @returns A Promise, resolved successfully with no value on success,
234
+ * rejected with no value on failure.
235
+ */
236
+ deleteValue(name: string): Promise<void>
237
+
238
+ /**
239
+ * Retrieves an array of preference names that this script has stored
240
+ * @see {@link https://wiki.greasespot.net/GM.listValues}
241
+ * @returns A Promise, rejected in case of error and otherwise resolved with
242
+ * an string[] for previously set values
243
+ */
244
+ listValues(): Promise<string[]>
245
+
246
+ // Resources
247
+
248
+ /**
249
+ * Given a defined `@resource`, this method returns it as a URL
250
+ * @see {@link https://wiki.greasespot.net/GM.getResourceUrl}
251
+ * @param resourceName The name provided when the `@resource` was defined
252
+ * @returns A Promise, rejected on failure and resolved with a string URL on
253
+ * success.
254
+ * Treat the result as opaque string. It will work where you need a URL
255
+ * (for a `<link>` or `<style>` for CSS, for an `<img>` tag, or similar).
256
+ */
257
+ getResourceUrl(resourceName: string): Promise<string>
258
+
259
+ // Other
260
+
261
+ /**
262
+ * Displays a notification to the user, using the underlying operating
263
+ * system's notification mechanism
264
+ * @see {@link https://wiki.greasespot.net/GM.notification}
265
+ * @param text The main notification text
266
+ * @param title The title of the notification
267
+ * @param image The URL for an image to display in the dialog. If not
268
+ * provided, the Greasemonkey logo by default.
269
+ * @param onClick Callback, triggered when the notification's button is
270
+ * clicked.
271
+ */
272
+ notification(
273
+ text: string,
274
+ title: string,
275
+ image?: string,
276
+ onClick?: () => void
277
+ ): void
278
+
279
+ /**
280
+ * Opens the specified URL in a new tab.
281
+ * @see {@link https://wiki.greasespot.net/GM.openInTab}
282
+ * @param url The URL to navigate the new tab to
283
+ * @param openInBackground Force tab to/to not open in a background tab.
284
+ * Default (unspecified) behavior honors Firefox configuration.
285
+ */
286
+ openInTab(url: string, openInBackground?: boolean): void
287
+
288
+ /**
289
+ * Adds an item to the User Script Commands menu.
290
+ * @param caption The caption to display on the menu item.
291
+ * @param commandFunc The function to call when the menu item is selected.
292
+ * @param accessKey A single character that can be used to select the
293
+ * item when the menu is open. It should be a letter in the caption.
294
+ * @see {@link https://wiki.greasespot.net/GM.registerMenuCommand}
295
+ */
296
+ registerMenuCommand(
297
+ caption: string,
298
+ commandFunc: () => void,
299
+ accessKey?: string
300
+ ): void
301
+
302
+ /**
303
+ * Sets the current contents of the operating system's clipboard
304
+ * @see {@link https://wiki.greasespot.net/GM.setClipboard}
305
+ */
306
+ setClipboard(text: string): void
307
+
308
+ /**
309
+ * Performs a similar function to the standard XMLHttpRequest object, but
310
+ * allows these requests to cross the [same origin policy]{@link https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy} boundaries.
311
+ * @see {@link https://wiki.greasespot.net/GM.xmlHttpRequest}
312
+ */
313
+ xmlHttpRequest(details: GM.Request): void
314
+ }
File without changes
@@ -0,0 +1,376 @@
1
+ declare const unsafeWindow: Window
2
+
3
+ declare type VMScriptRunAt =
4
+ | 'document-start'
5
+ | 'document-body'
6
+ | 'document-end'
7
+ | 'document-idle'
8
+
9
+ /** Injection mode of a script. */
10
+ declare type VMScriptInjectInto = 'auto' | 'page' | 'content'
11
+
12
+ declare interface VMScriptGMInfoPlatform {
13
+ arch: 'arm' | 'arm64' | 'x86-32' | 'x86-64' | 'mips' | 'mips64'
14
+ /** `chrome`, `firefox` or whatever was returned by the API. */
15
+ browserName: string
16
+ browserVersion: string
17
+ os: 'mac' | 'win' | 'android' | 'cros' | 'linux' | 'openbsd' | 'fuchsia'
18
+ }
19
+
20
+ declare interface VMScriptGMInfoScriptMeta {
21
+ description: string
22
+ excludes: string[]
23
+ includes: string[]
24
+ matches: string[]
25
+ name: string
26
+ namespace: string
27
+ resources: Array<{ name: string; url: string }>
28
+ runAt: VMScriptRunAt
29
+ version: string
30
+ }
31
+
32
+ declare interface VMScriptGMInfoObject {
33
+ /** Unique ID of the script. */
34
+ uuid: string
35
+ /** The meta block of the script. */
36
+ scriptMetaStr: string
37
+ /** Whether the script will be updated automatically. */
38
+ scriptWillUpdate: boolean
39
+ /** The name of userscript manager, which should be the string `Violentmonkey`. */
40
+ scriptHandler: string
41
+ /** Version of Violentmonkey. */
42
+ version: string
43
+ /**
44
+ * Unlike `navigator.userAgent`, which can be overriden by other extensions/userscripts
45
+ * or by devtools in device-emulation mode, `GM_info.platform` is more reliable as the
46
+ * data is obtained in the background page of Violentmonkey using a specialized
47
+ * extension API (`browser.runtime.getPlatformInfo` and `getBrowserInfo`).
48
+ */
49
+ platform: VMScriptGMInfoPlatform
50
+ /** Contains structured fields from the *Metadata Block*. */
51
+ script: VMScriptGMInfoScriptMeta
52
+ /** The injection mode of current script. */
53
+ injectInto: VMScriptInjectInto
54
+ }
55
+
56
+ /**
57
+ * An object that exposes information about the current userscript.
58
+ */
59
+ declare const GM_info: VMScriptGMInfoObject
60
+
61
+ /** Retrieves a value for current script from storage. */
62
+ declare function GM_getValue<T>(name: string, defaultValue?: T): T
63
+ /** Sets a key / value pair for current script to storage. */
64
+ declare function GM_setValue<T>(name: string, value: T): void
65
+ /** Deletes an existing key / value pair for current script from storage. */
66
+ declare function GM_deleteValue(name: string): void
67
+ /** Returns an array of keys of all available values within this script. */
68
+ declare function GM_listValues(): string[]
69
+
70
+ declare type VMScriptGMValueChangeCallback<T> = (
71
+ /** The name of the observed variable */
72
+ name: string,
73
+ /** The old value of the observed variable (`undefined` if it was created) */
74
+ oldValue: T,
75
+ /** The new value of the observed variable (`undefined` if it was deleted) */
76
+ newValue: T,
77
+ /** `true` if modified by the userscript instance of another tab or `false` for this script instance. Can be used by scripts of different browser tabs to communicate with each other. */
78
+ remote: boolean
79
+ ) => void
80
+
81
+ /** Adds a change listener to the storage and returns the listener ID. */
82
+ declare function GM_addValueChangeListener<T>(
83
+ name: string,
84
+ callback: VMScriptGMValueChangeCallback<T>
85
+ ): string
86
+ /** Removes a change listener by its ID. */
87
+ declare function GM_removeValueChangeListener(listenerId: string): void
88
+
89
+ /** Retrieves a text resource from the *Metadata Block*. */
90
+ declare function GM_getResourceText(
91
+ /** Name of a resource defined in the *Metadata Block*. */
92
+ name: string
93
+ ): string
94
+ /**
95
+ * Retrieves a `blob:` or `data:` URL of a resource from the *Metadata Block*.
96
+ *
97
+ * Note: when setting this URL as `src` or `href` of a DOM element, it may fail on some sites with a particularly strict CSP that forbids `blob:` or `data:` URLs. Such sites are rare though. The workaround in Chrome is to use `GM_addElement`, whereas in Firefox you'll have to disable CSP either globally via `about:config` or by using an additional extension that modifies HTTP headers selectively.
98
+ */
99
+ declare function GM_getResourceURL(
100
+ /** Name of a resource defined in the *Metadata Block*. */
101
+ name: string,
102
+ /**
103
+ * - If `true`, returns a `blob:` URL. It's short and cacheable, so it's good for reusing in multiple DOM elements.
104
+ * - If `false`, returns a `data:` URL. It's long so reusing it in DOM may be less performant due to the lack of caching, but it's particularly handy for direct synchronous decoding of the data on sites that forbid fetching `blob:` in their CSP.
105
+ */
106
+ isBlobUrl?: boolean
107
+ ): string
108
+
109
+ /**
110
+ * Appends and returns an element with the specified attributes.
111
+ *
112
+ * Examples:
113
+ *
114
+ * ```js
115
+ * // using a private function in `onload`
116
+ * let el = GM_addElement('script', { src: 'https://....' });
117
+ * el.onload = () => console.log('loaded', el);
118
+ *
119
+ * // same as GM_addStyle('a { color:red }')
120
+ * let el = GM_addElement('style', { textContent: 'a { color:red }' });
121
+ *
122
+ * // appending to an arbitrary node
123
+ * let el = GM_addElement(parentElement.shadowRoot, 'iframe', { src: url });
124
+ * ```
125
+ */
126
+ declare function GM_addElement(
127
+ /** A tag name like `script`. Any valid HTML tag can be used, but the only motivation for this API was to add `script`, `link`, `style` elements when they are disallowed by a strict `Content-Security-Policy` of the site e.g. github.com, twitter.com. */
128
+ tagName: string,
129
+ /** The keys are HTML attributes, not DOM properties, except `textContent` which sets DOM property `textContent`. The values are strings so if you want to assign a private function to `onload` you can do it after the element is created. */
130
+ attributes?: Record<string, string>
131
+ ): HTMLElement
132
+ declare function GM_addElement(
133
+ /**
134
+ * The parent node to which the new node will be appended.
135
+ * It can be inside ShadowDOM: `someElement.shadowRoot`.
136
+ * When omitted, it'll be determined automatically:
137
+ *
138
+ * - `document.head` (`<head>`) for `script`, `link`, `style`, `meta` tags.
139
+ * - `document.body` (`<body>`) for other tags or when there's no `<head>`.
140
+ * - `document.documentElement` (`<html>` or an XML root node) otherwise.
141
+ */
142
+ parentNode: HTMLElement,
143
+ /** A tag name like `script`. Any valid HTML tag can be used, but the only motivation for this API was to add `script`, `link`, `style` elements when they are disallowed by a strict `Content-Security-Policy` of the site e.g. github.com, twitter.com. */
144
+ tagName: string,
145
+ /** The keys are HTML attributes, not DOM properties, except `textContent` which sets DOM property `textContent`. The values are strings so if you want to assign a private function to `onload` you can do it after the element is created. */
146
+ attributes?: Record<string, string>
147
+ ): HTMLElement
148
+
149
+ /** Appends and returns a `<style>` element with the specified CSS. */
150
+ declare function GM_addStyle(css: string): HTMLStyleElement
151
+
152
+ declare interface VMScriptGMTabControl {
153
+ /** Сan be assigned to a function. If provided, it will be called when the opened tab is closed. */
154
+ onclose?: () => void
155
+ /** Whether the opened tab is closed. */
156
+ closed: boolean
157
+ /** A function to explicitly close the opened tab. */
158
+ close: () => void
159
+ }
160
+
161
+ declare interface VMScriptGMTabOptions {
162
+ /** Make the new tab active (i.e. open in foreground). Default as `true`. */
163
+ active?: boolean
164
+ /**
165
+ * Firefox only.
166
+ *
167
+ * - not specified = reuse script's tab container
168
+ * - `0` = default (main) container
169
+ * - `1`, `2`, etc. = internal container index
170
+ */
171
+ container?: number
172
+ /** Insert the new tab next to the current tab and set its `openerTab` so when it's closed the original tab will be focused automatically. When `false` or not specified, the usual browser behavior is to open the tab at the end of the tab list. Default as `true`. */
173
+ insert?: boolean
174
+ /** Pin the tab (i.e. show without a title at the beginning of the tab list). Default as `false`. */
175
+ pinned?: boolean
176
+ }
177
+
178
+ /** Opens URL in a new tab. */
179
+ declare function GM_openInTab(
180
+ /** The URL to open in a new tab. URL relative to current page is also allowed. Note: Firefox does not support data URLs. */
181
+ url: string,
182
+ options?: VMScriptGMTabOptions
183
+ ): VMScriptGMTabControl
184
+ declare function GM_openInTab(
185
+ /** The URL to open in a new tab. URL relative to current page is also allowed. Note: Firefox does not support data URLs. */
186
+ url: string,
187
+ /** Open the tab in background. Note, this is a reverse of the first usage method so for example `true` is the same as `{ active: false }`. */
188
+ openInBackground?: boolean
189
+ ): VMScriptGMTabControl
190
+
191
+ /**
192
+ * Registers a command in Violentmonkey popup menu.
193
+ * If you want to add a shortcut, please see `@violentmonkey/shortcut`.
194
+ */
195
+ declare function GM_registerMenuCommand(
196
+ /** The name to show in the popup menu. */
197
+ caption: string,
198
+ /** Callback function when the command is clicked in the menu. */
199
+ onClick: (event: MouseEvent) => void
200
+ ): string
201
+ /** Unregisters a command which has been registered to Violentmonkey popup menu. */
202
+ declare function GM_unregisterMenuCommand(
203
+ /** The name of command to unregister. */
204
+ caption: string
205
+ ): void
206
+
207
+ /**
208
+ * A control object returned by `GM_notification`.
209
+ * `control.remove()` can be used to remove the notification.
210
+ */
211
+ declare interface VMScriptGMNotificationControl {
212
+ /** Remove the notification immediately. */
213
+ remove: () => Promise<void>
214
+ }
215
+
216
+ declare interface VMScriptGMNotificationOptions {
217
+ /** Main text of the notification. */
218
+ text: string
219
+ /** Title of the notification. */
220
+ title?: string
221
+ /** URL of an image to show in the notification. */
222
+ image?: string
223
+ /** Callback when the notification is clicked by user. */
224
+ onclick?: () => void
225
+ /** Callback when the notification is closed, either by user or by system. */
226
+ ondone?: () => void
227
+ }
228
+
229
+ /** Shows an HTML5 desktop notification. */
230
+ declare function GM_notification(
231
+ options: VMScriptGMNotificationOptions
232
+ ): VMScriptGMNotificationControl
233
+ declare function GM_notification(
234
+ /** Main text of the notification. */
235
+ text: string,
236
+ /** Title of the notification. */
237
+ title?: string,
238
+ /** URL of an image to show in the notification. */
239
+ image?: string,
240
+ /** Callback when the notification is clicked by user. */
241
+ onclick?: () => void
242
+ ): VMScriptGMNotificationControl
243
+
244
+ /** Sets data to system clipboard. */
245
+ declare function GM_setClipboard(
246
+ /** The data to be copied to system clipboard. */
247
+ data: string,
248
+ /** The MIME type of data to copy. Default as `text/plain`. */
249
+ type?: string
250
+ ): void
251
+
252
+ /**
253
+ * A control object returned by `GM_xmlhttpRequest`.
254
+ * `control.abort()` can be used to abort the request.
255
+ */
256
+ declare interface VMScriptXHRControl {
257
+ abort: () => void
258
+ }
259
+
260
+ declare type VMScriptResponseType =
261
+ | 'text'
262
+ | 'json'
263
+ | 'blob'
264
+ | 'arraybuffer'
265
+ | 'document'
266
+
267
+ declare interface VMScriptResponseObject<T> {
268
+ status: number
269
+ statusText: string
270
+ readyState: number
271
+ responseHeaders: string
272
+ response: T
273
+ responseText: string | null
274
+ /** The final URL after redirection. */
275
+ finalUrl: string
276
+ /** The same `context` object you specified in `details`. */
277
+ context?: unknown
278
+ }
279
+
280
+ declare interface VMScriptGMXHRDetails<T> {
281
+ /** URL relative to current page is also allowed. */
282
+ url: string
283
+ /** HTTP method, default as `GET`. */
284
+ method?: string
285
+ /** User for authentication. */
286
+ user?: string
287
+ /** Password for authentication. */
288
+ password?: string
289
+ /** A MIME type to specify with the request. */
290
+ overrideMimeType?: string
291
+ /**
292
+ * Some special headers are also allowed:
293
+ *
294
+ * - `Cookie`
295
+ * - `Host`
296
+ * - `Origin`
297
+ * - `Referer`
298
+ * - `User-Agent`
299
+ */
300
+ headers?: Record<string, string>
301
+ /**
302
+ * One of the following:
303
+ *
304
+ * - `text` (default value)
305
+ * - `json`
306
+ * - `blob`
307
+ * - `arraybuffer`
308
+ * - `document`
309
+ */
310
+ responseType?: VMScriptResponseType
311
+ /** Time to wait for the request, none by default. */
312
+ timeout?: number
313
+ /** Data to send with the request, usually for `POST` and `PUT` requests. */
314
+ data?: string | FormData | Blob
315
+ /** Send the `data` string as a `blob`. This is for compatibility with Tampermonkey/Greasemonkey, where only `string` type is allowed in `data`. */
316
+ binary?: boolean
317
+ /** Can be an object and will be assigned to context of the response object. */
318
+ context?: unknown
319
+ /** When set to `true`, no cookie will be sent with the request and the response cookies will be ignored. The default value is `false`. */
320
+ anonymous?: boolean
321
+ onabort?: (resp: VMScriptResponseObject<T>) => void
322
+ onerror?: (resp: VMScriptResponseObject<T>) => void
323
+ onload?: (resp: VMScriptResponseObject<T>) => void
324
+ onloadend?: (resp: VMScriptResponseObject<T>) => void
325
+ onloadstart?: (resp: VMScriptResponseObject<T>) => void
326
+ onprogress?: (resp: VMScriptResponseObject<T>) => void
327
+ onreadystatechange?: (resp: VMScriptResponseObject<T>) => void
328
+ ontimeout?: (resp: VMScriptResponseObject<T>) => void
329
+ }
330
+
331
+ /** Makes a request like XMLHttpRequest, with some special capabilities, not restricted by same-origin policy. */
332
+ declare function GM_xmlhttpRequest<T>(
333
+ details: VMScriptGMXHRDetails<T>
334
+ ): VMScriptXHRControl
335
+
336
+ declare interface VMScriptGMDownloadOptions {
337
+ /** The URL to download. */
338
+ url: string
339
+ /** The filename to save as. */
340
+ name?: string
341
+ /** The function to call when download starts successfully. */
342
+ onload?: () => void
343
+ headers?: Record<string, string>
344
+ timeout?: number
345
+ onerror?: (resp: VMScriptResponseObject<Blob>) => void
346
+ onprogress?: (resp: VMScriptResponseObject<Blob>) => void
347
+ ontimeout?: (resp: VMScriptResponseObject<Blob>) => void
348
+ }
349
+
350
+ /** Downloads a URL to a local file. */
351
+ declare function GM_download(options: VMScriptGMDownloadOptions): void
352
+ declare function GM_download(
353
+ /** The URL to download. */
354
+ url: string,
355
+ /** The filename to save as. */
356
+ name?: string
357
+ ): void
358
+
359
+ declare interface VMScriptGMObject {
360
+ unsafeWindow: Window
361
+ info: typeof GM_info
362
+ getValue: <T>(name: string, defaultValue?: T) => Promise<T>
363
+ setValue: <T>(name: string, value: T) => Promise<void>
364
+ deleteValue: (name: string) => Promise<void>
365
+ listValues: () => Promise<string[]>
366
+ addStyle: typeof GM_addStyle
367
+ addElement: typeof GM_addElement
368
+ registerMenuCommand: typeof GM_registerMenuCommand
369
+ getResourceUrl: (name: string, isBlobUrl?: boolean) => Promise<string>
370
+ notification: typeof GM_notification
371
+ openInTab: typeof GM_openInTab
372
+ setClipboard: typeof GM_setClipboard
373
+ xmlHttpRequest: typeof GM_xmlhttpRequest
374
+ }
375
+
376
+ declare const GM: VMScriptGMObject
@@ -1 +0,0 @@
1
- function n(){let e=new WebSocket("__WS__");e.addEventListener("open",()=>{let{script:o}=GM_info;console.group(`${o.name}@${o.version}`),console.log(GM_info),console.groupEnd()}),e.addEventListener("close",()=>{setTimeout(n,1e3)}),e.addEventListener("error",()=>{e.close()}),e.addEventListener("message",()=>{location.reload()})}n();