feat: modes of BtnList
able to show the buttons in a separate window
This commit is contained in:
parent
a296651c6f
commit
a5de589b6b
58
src/btn.ts
58
src/btn.ts
|
@ -35,13 +35,16 @@ interface BtnOptions {
|
||||||
readonly tooltip?: string;
|
readonly tooltip?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum BtnListMode {
|
||||||
|
InPage,
|
||||||
|
ExtWindow,
|
||||||
|
}
|
||||||
|
|
||||||
export class BtnList {
|
export class BtnList {
|
||||||
private readonly list: BtnElement[] = [];
|
private readonly list: BtnElement[] = [];
|
||||||
|
|
||||||
constructor (private getTemplateBtn: () => BtnElement) { }
|
constructor (private getTemplateBtn: () => BtnElement) { }
|
||||||
|
|
||||||
private antiDetectionText = 'Download'
|
|
||||||
|
|
||||||
add (options: BtnOptions): BtnElement {
|
add (options: BtnOptions): BtnElement {
|
||||||
const btn = this.getTemplateBtn().cloneNode(true) as HTMLButtonElement
|
const btn = this.getTemplateBtn().cloneNode(true) as HTMLButtonElement
|
||||||
|
|
||||||
|
@ -73,8 +76,11 @@ export class BtnList {
|
||||||
return btn
|
return btn
|
||||||
}
|
}
|
||||||
|
|
||||||
private _commit () {
|
private _commit (mode: BtnListMode) {
|
||||||
const parent = this.getTemplateBtn().parentElement as HTMLDivElement
|
const btnParent = this.getTemplateBtn().parentElement as HTMLDivElement
|
||||||
|
const parent = mode === BtnListMode.InPage
|
||||||
|
? btnParent
|
||||||
|
: document.createElement('div')
|
||||||
const shadow = parent.attachShadow({ mode: 'closed' })
|
const shadow = parent.attachShadow({ mode: 'closed' })
|
||||||
|
|
||||||
// style the shadow DOM from outside css
|
// style the shadow DOM from outside css
|
||||||
|
@ -83,30 +89,44 @@ export class BtnList {
|
||||||
})
|
})
|
||||||
|
|
||||||
// hide buttons using the shadow DOM
|
// hide buttons using the shadow DOM
|
||||||
const newParent = parent.cloneNode(false) as HTMLDivElement
|
const newParent = btnParent.cloneNode(false) as HTMLDivElement
|
||||||
newParent.append(...this.list)
|
newParent.append(...this.list)
|
||||||
shadow.append(newParent)
|
shadow.append(newParent)
|
||||||
|
|
||||||
return {
|
return parent
|
||||||
parent,
|
|
||||||
shadowRoot: shadow,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* replace the template button with the list of new buttons
|
* replace the template button with the list of new buttons
|
||||||
*/
|
*/
|
||||||
commit (): void {
|
commit (mode: BtnListMode = BtnListMode.InPage): void {
|
||||||
let el: Element = this._commit().parent
|
switch (mode) {
|
||||||
const observer = new MutationObserver(() => {
|
case BtnListMode.InPage: {
|
||||||
// check if the buttons are still in document when dom updates
|
let el: Element = this._commit(mode)
|
||||||
if (!document.contains(el)) {
|
const observer = new MutationObserver(() => {
|
||||||
// re-commit
|
// check if the buttons are still in document when dom updates
|
||||||
// performance issue?
|
if (!document.contains(el)) {
|
||||||
el = this._commit().parent
|
// re-commit
|
||||||
|
// performance issue?
|
||||||
|
el = this._commit(mode)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
observer.observe(document, { childList: true, subtree: true })
|
||||||
|
break
|
||||||
}
|
}
|
||||||
})
|
|
||||||
observer.observe(document, { childList: true, subtree: true })
|
case BtnListMode.ExtWindow: {
|
||||||
|
const div = this._commit(mode)
|
||||||
|
const w = window.open('', undefined, 'resizable,width=230,height=270')
|
||||||
|
// eslint-disable-next-line no-unused-expressions
|
||||||
|
w?.document.body.append(div)
|
||||||
|
window.addEventListener('unload', () => w?.close())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error('unknown BtnListMode')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { downloadPDF } from './pdf'
|
||||||
import { downloadMscz } from './mscz'
|
import { downloadMscz } from './mscz'
|
||||||
import { getFileUrl } from './file'
|
import { getFileUrl } from './file'
|
||||||
import { WebMscore, loadSoundFont } from './mscore'
|
import { WebMscore, loadSoundFont } from './mscore'
|
||||||
import { getDownloadBtn, BtnList, BtnAction } from './btn'
|
import { getDownloadBtn, BtnList, BtnAction, BtnListMode } from './btn'
|
||||||
import * as recaptcha from './recaptcha'
|
import * as recaptcha from './recaptcha'
|
||||||
import scoreinfo from './scoreinfo'
|
import scoreinfo from './scoreinfo'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
|
@ -160,7 +160,7 @@ const main = (): void => {
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
|
||||||
btnList.commit()
|
btnList.commit(BtnListMode.InPage)
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||||
|
|
Loading…
Reference in New Issue