feat: sandbox
This commit is contained in:
parent
548f7c02ba
commit
566ec96144
2 changed files with 22 additions and 7 deletions
10
src/btn.ts
10
src/btn.ts
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import { ScoreInfo } from './scoreinfo'
|
import { ScoreInfo } from './scoreinfo'
|
||||||
import { loadMscore, WebMscore } from './mscore'
|
import { loadMscore, WebMscore } from './mscore'
|
||||||
import { useTimeout, windowOpen, console, attachShadow } from './utils'
|
import { useTimeout, windowOpenAsync, console, attachShadow } from './utils'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import btnListCss from './btn.css'
|
import btnListCss from './btn.css'
|
||||||
|
@ -116,7 +116,7 @@ export class BtnList {
|
||||||
/**
|
/**
|
||||||
* replace the template button with the list of new buttons
|
* replace the template button with the list of new buttons
|
||||||
*/
|
*/
|
||||||
commit (mode: BtnListMode = BtnListMode.InPage): void {
|
async commit (mode: BtnListMode = BtnListMode.InPage): Promise<void> {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case BtnListMode.InPage: {
|
case BtnListMode.InPage: {
|
||||||
// fallback to BtnListMode.ExtWindow
|
// fallback to BtnListMode.ExtWindow
|
||||||
|
@ -148,7 +148,7 @@ export class BtnList {
|
||||||
|
|
||||||
case BtnListMode.ExtWindow: {
|
case BtnListMode.ExtWindow: {
|
||||||
const div = this._commit()
|
const div = this._commit()
|
||||||
const w = windowOpen('', undefined, 'resizable,width=230,height=270')
|
const w = await windowOpenAsync('', undefined, 'resizable,width=230,height=270')
|
||||||
// eslint-disable-next-line no-unused-expressions
|
// eslint-disable-next-line no-unused-expressions
|
||||||
w?.document.body.append(div)
|
w?.document.body.append(div)
|
||||||
window.addEventListener('unload', () => w?.close())
|
window.addEventListener('unload', () => w?.close())
|
||||||
|
@ -176,7 +176,7 @@ export namespace BtnAction {
|
||||||
|
|
||||||
export const openUrl = (url: UrlInput): BtnAction => {
|
export const openUrl = (url: UrlInput): BtnAction => {
|
||||||
return process(async (): Promise<any> => {
|
return process(async (): Promise<any> => {
|
||||||
windowOpen(await normalizeUrlInput(url))
|
return windowOpenAsync(await normalizeUrlInput(url))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,7 +195,7 @@ export namespace BtnAction {
|
||||||
btn.onclick = null
|
btn.onclick = null
|
||||||
setText(i18n('PROCESSING')())
|
setText(i18n('PROCESSING')())
|
||||||
|
|
||||||
const w = windowOpen('') as Window
|
const w = await windowOpenAsync('') as Window
|
||||||
const txt = document.createTextNode(i18n('PROCESSING')())
|
const txt = document.createTextNode(i18n('PROCESSING')())
|
||||||
w.document.body.append(txt)
|
w.document.body.append(txt)
|
||||||
|
|
||||||
|
|
19
src/utils.ts
19
src/utils.ts
|
@ -47,6 +47,21 @@ export const useTimeout = async <T> (promise: T | Promise<T>, ms: number): Promi
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getSandboxWindowAsync = async (): Promise<Window> => {
|
||||||
|
if (typeof document === 'undefined') return {} as any as Window
|
||||||
|
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
window.onmouseover = () => {
|
||||||
|
const iframe = document.createElement('iframe')
|
||||||
|
iframe.style.display = 'none'
|
||||||
|
document.body.append(iframe)
|
||||||
|
const w = iframe.contentWindow
|
||||||
|
window.onmouseover = null
|
||||||
|
resolve(w as Window)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const getUnsafeWindow = (): Window => {
|
export const getUnsafeWindow = (): Window => {
|
||||||
// eslint-disable-next-line no-eval
|
// eslint-disable-next-line no-eval
|
||||||
return window.eval('window') as Window
|
return window.eval('window') as Window
|
||||||
|
@ -54,8 +69,8 @@ export const getUnsafeWindow = (): Window => {
|
||||||
|
|
||||||
export const console: Console = (window || global).console // Object.is(window.console, unsafeWindow.console) == false
|
export const console: Console = (window || global).console // Object.is(window.console, unsafeWindow.console) == false
|
||||||
|
|
||||||
export const windowOpen: Window['open'] = (...args): Window | null => {
|
export const windowOpenAsync = (...args: Parameters<Window['open']>): Promise<Window | null> => {
|
||||||
return window.open(...args) // Object.is(window.open, unsafeWindow.open) == false
|
return getSandboxWindowAsync().then(w => w.open(...args))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const attachShadow = (el: Element): ShadowRoot => {
|
export const attachShadow = (el: Element): ShadowRoot => {
|
||||||
|
|
Loading…
Reference in a new issue