diff --git a/rollup.config.js b/rollup.config.js index 231ec46..c033097 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -83,7 +83,7 @@ export default [ format: "iife", sourcemap: false, banner: getBannerText, - intro: "new Promise(resolve=>{const id=''+Math.random();(typeof unsafeWindow=='object'?unsafeWindow:window)[id]=resolve;setTimeout(`(function a(){window['${id}'](new Image())})()//# sourceURL=${location.href}`)}).then(d=>{d.style.display='none';d.src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';d.once=false;d.setAttribute('onload','if(this.once)return;this.once=true;this.remove();(' + function a () {", + intro: "const w=typeof unsafeWindow=='object'?unsafeWindow:window;const gmId=''+Math.random();w[gmId]=typeof GM=='object'?GM:undefined;new Promise(resolve=>{const id=''+Math.random();w[id]=resolve;setTimeout(`(function a(){window['${id}'](new Image())})()//# sourceURL=${location.href}`)}).then(d=>{d.style.display='none';d.src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';d.once=false;d.setAttribute('onload',`if(this.once)return;this.once=true;this.remove();const GM=window['${gmId}'];(` + function a () {", outro: "}.toString() + ')()');document.body.prepend(d)})" }, plugins, diff --git a/src/btn.ts b/src/btn.ts index b7c6e6a..0bd6dc9 100644 --- a/src/btn.ts +++ b/src/btn.ts @@ -2,6 +2,7 @@ import { ScoreInfo } from './scoreinfo' import { loadMscore, WebMscore } from './mscore' import { useTimeout, windowOpenAsync, console, attachShadow } from './utils' +import { isGmAvailable, registerMenuCommand } from './gm' import i18n from './i18n' // @ts-ignore import btnListCss from './btn.css' @@ -86,6 +87,13 @@ export class BtnList { btnTpl.title = options.tooltip } + // add buttons to the userscript manager menu + if (isGmAvailable()) { + registerMenuCommand(options.name, () => { + options.action(options.name, btnTpl, () => undefined) + }) + } + return btnTpl } diff --git a/src/gm.ts b/src/gm.ts new file mode 100644 index 0000000..e02e1c0 --- /dev/null +++ b/src/gm.ts @@ -0,0 +1,19 @@ + +/** + * UserScript APIs + */ +declare const GM: { + /** https://www.tampermonkey.net/documentation.php#GM_registerMenuCommand */ + registerMenuCommand (name: string, fn: () => any, accessKey?: string): Promise; +} + +type GM = typeof GM + +export const isGmAvailable = (): boolean => { + return typeof GM !== 'undefined' && + typeof GM.registerMenuCommand === 'function' +} + +export const registerMenuCommand: GM['registerMenuCommand'] = (...args) => { + return GM.registerMenuCommand(...args) +} diff --git a/src/meta.js b/src/meta.js index 7bd0120..21c6464 100644 --- a/src/meta.js +++ b/src/meta.js @@ -13,5 +13,6 @@ // @license MIT // @copyright Copyright (c) 2019-2020 Xmader // @grant unsafeWindow +// @grant GM.registerMenuCommand // @run-at document-start // ==/UserScript==