UNPKG

web-barrier-free

Version:

[![LICENSE](https://img.shields.io/github/license/bubkoo/html-to-image?style=flat-square)](./LICENSE) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/karma-runner/karma-cover

240 lines (219 loc) 7.79 kB
import defaultOptions from './default' import { consoleClassName, consoleDomId, emphasizeClassName, getGather, IGather, optionsArr, showBarDomId, testReadMode } from './util' import { outHandler, overHandler } from './handlers' import './index.css' class Wbf { public opening: boolean = false public readMode: readMode = 'finger' public language: language public rate: number public pitch: number public volume: number public showBarEl: HTMLDivElement | null = null public needConsole: boolean = true public externalFn: Function | null = null private readonly overHandler private readonly outHandler constructor (options?: Options) { // options init if (options == null) options = defaultOptions options?.readMode !== undefined && (this.readMode = options.readMode) options?.needConsole !== undefined && (this.needConsole = options.needConsole) this.language = options?.language ?? defaultOptions.language this.rate = options?.rate ?? defaultOptions.rate this.pitch = options?.pitch ?? defaultOptions.pitch this.volume = options?.volume ?? defaultOptions.volume this.externalFn = options?.externalFn ?? null this.overHandler = (e: { target: HTMLElement }) => overHandler(e, this) this.outHandler = (e: { target: HTMLElement }) => outHandler(e, this) } open (): void { /** * Change mode to start wbf * And according to the options to determine whether to open the console dom */ if (this.opening) return this.changeMode(this.readMode) if (this.showBarEl == null) { const showBar = this.createShowBarDom() this.showBarEl = showBar } this.addHandler() this.opening = true this.needConsole && this.createConsole() } close (): void { /** * Remove was added emphasize elements * Cancel current speechSynthesis * Remove the corresponding listener event * Remove console and showBar * */ const emphasizeEls = document.querySelectorAll(`.${emphasizeClassName}`) emphasizeEls.forEach((el) => { this.removeEmphasize(el) }) speechSynthesis.cancel() document.removeEventListener('mouseover', this.overHandler) document.removeEventListener('mouseout', this.outHandler) this.removeShowBarDom() this.removeConsole() this.opening = false } // You can modify the properties of wbf through this method, but you cannot modify the opening state changeOptions (keyName: string, value): void { if (optionsArr.includes[keyName] === false && this[keyName] !== undefined) { throw new Error(`${keyName} options do not exist on wbf`) } if (keyName === 'opening') throw new Error(`${keyName} cannot be changed `) if (typeof value === 'number') { value >= 2 && (value = 2) } this[keyName] = value } // You can modify the wbf by this method reading mode changeMode (readMode: readMode): void { if (!testReadMode(readMode)) { throw new Error(`readMode not includes this ${readMode}`) } this.readMode = readMode if (readMode !== 'finger') { const allText = document.body.innerText this.playAudio(allText) } } addHandler (): void { document.addEventListener('mouseover', this.overHandler) document.addEventListener('mouseout', this.outHandler) } createUtterance (str): SpeechSynthesisUtterance { const msg = new SpeechSynthesisUtterance() msg.text = str msg.lang = this.language msg.pitch = this.pitch msg.rate = this.rate msg.volume = this.volume return msg } playAudio (str: string): SpeechSynthesisUtterance | undefined { if (this.externalFn != null) { this.externalFn(str) } else { speechSynthesis.cancel() const msg = this.createUtterance(str) speechSynthesis.speak(msg) return msg } } emphasize (el: HTMLElement | Element): void { el.classList.add(emphasizeClassName) } removeEmphasize (el: HTMLElement | Element): void { el.classList.remove(emphasizeClassName) } createShowBarDom (): HTMLDivElement { const prev = document.getElementById(showBarDomId) as HTMLDivElement | null if (prev != null) return prev const showBar = document.createElement('div') showBar.id = showBarDomId showBar.style.position = 'fixed' showBar.style.bottom = '0px' showBar.style.left = '0px' showBar.style.width = '100%' showBar.style.minHeight = '50px' showBar.style.maxHeight = '300px' showBar.style.fontWeight = 'bold' showBar.style.textAlign = 'center' showBar.style.wordBreak = 'break-word;' showBar.style.overflow = 'hidden' showBar.style.background = 'white' showBar.style.border = '2px solid #eee' document.body.appendChild(showBar) return showBar } createConsole (): void { const prev = document.getElementById(consoleDomId) if (prev != null) return const consoleEl = document.createElement('div') consoleEl.id = consoleDomId const gather: IGather = getGather(this.language) consoleEl.classList.add(consoleClassName) consoleEl.innerHTML = ` <div class="${consoleClassName}-main"> <div> <button id="_wbfClose">${gather.close}</button> <button id="_wbfContinuousRead">${gather.continuousRead}</button> <button id="_wbfFingerRead">${gather.fingerRead}</button> </div> | <div> ${gather.volume} <button id="_wbfAddVolume">+</button> <button id="_wbfReduceVolume">-</button> </div> | <div> ${gather.rate} <button id="_wbfAddRate">+</button> <button id="_wbfReduceRate">-</button> </div> </div>` document.body.insertBefore(consoleEl, document.body.firstChild) const closeBtn = document.getElementById('_wbfClose') const continuousReadBtn = document.getElementById('_wbfContinuousRead') const fingerReadBtn = document.getElementById('_wbfFingerRead') const addVolumeBtn = document.getElementById('_wbfAddVolume') const reduceVolumeBtn = document.getElementById('_wbfReduceVolume') const addRateBtn = document.getElementById('_wbfAddRate') const reduceRateBtn = document.getElementById('_wbfReduceRate') closeBtn != null && (closeBtn.onclick = () => this.close()) continuousReadBtn != null && (continuousReadBtn.onclick = () => this.changeMode('continuous')) fingerReadBtn != null && (fingerReadBtn.onclick = () => this.changeMode('finger')) addVolumeBtn != null && (addVolumeBtn.onclick = () => this.changeOptions('volume', ++this.volume)) reduceVolumeBtn != null && (reduceVolumeBtn.onclick = () => this.changeOptions('volume', --this.volume)) addRateBtn != null && (addRateBtn.onclick = () => this.changeOptions('rate', ++this.rate)) reduceRateBtn != null && (reduceRateBtn.onclick = () => this.changeOptions('rate', --this.rate)) } removeConsole (): void { const consoleEl = document.getElementById(consoleDomId) if (consoleEl != null) { consoleEl.remove() } } removeShowBarDom (): void { if (this.showBarEl != null) { this.showBarEl.remove() this.showBarEl = null } } } type readMode = 'finger' | 'continuous' export type language = 'en' | 'zh-CN' interface Options { readMode?: readMode language?: language rate?: number pitch?: number externalFn?: Function volume?: number needConsole?: boolean } export default Wbf