Make Webcomponent

This commit is contained in:
Alfred Melch 2019-10-18 22:17:12 +09:00
parent bfc7524d1b
commit e1679d94c8
5 changed files with 155 additions and 99 deletions

View File

@ -0,0 +1,54 @@
// class RSVPControlButton extends HTMLElement {
// constructor() {
// super()
// const shadow = this.attachShadow({mode: 'open'})
// const button = document.createElement()
// }
// }
class RSVPControls extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({ mode: 'open' })
// const shadow = document.createElement('div')
shadow.innerHTML = `
<button action="prevSentence">&lt;&lt;</button>
<button action="prevWord">&lt;</button>
<button action="stop">stop</button>
<button action="playpause">start</button>
<button action="nextWord">&gt;</button>
<button action="nextSentence">&gt;&gt;</button>
`
this._root = shadow
// this.appendChild(shadow)
}
connectedCallback() {
for (let button of this._root.querySelectorAll('button')) {
button.addEventListener('click', e => {
let action = e.target.getAttribute('action')
let evt = new CustomEvent('control-event', { detail: { action } })
this.dispatchEvent(evt)
})
}
}
updateUI(chapter, player) {
this.getButton('prevSentence').disabled = !chapter.hasPrevSentence()
this.getButton('prevWord').disabled = !chapter.hasPrevWord()
this.getButton('nextWord').disabled = !chapter.hasNextWord()
this.getButton('nextSentence').disabled = !chapter.hasNextSentence()
this.getButton('playpause').innerText = player.playing ? 'pause' : 'start'
}
getButton(name) {
for (let btn of this._root.querySelectorAll('button')) {
if (btn.getAttribute('action') === name) {
return btn
}
}
return null
}
}
window.customElements.define('rsvp-controls', RSVPControls)

View File

@ -0,0 +1,76 @@
import './rsvp-word.js'
import './rsvp-controls.js'
import { Chapter } from '../src/Chapter.js'
import { Player } from '../src/Player.js'
class RSVPReader extends HTMLElement {
constructor() {
super()
const shadow = this.attachShadow({ mode: 'open' })
const word = document.createElement('rsvp-word')
const controls = document.createElement('rsvp-controls')
shadow.appendChild(word)
shadow.appendChild(controls)
this._root = shadow
this._rsvpWord = word
this._rsvpControls = controls
this.player = new Player()
this.player.subscribe('main', this.tick.bind(this))
this.setText('Sample Text. Easy there.')
this._rsvpControls.addEventListener(
'control-event',
this.handleControlEvent.bind(this)
)
}
setText(text) {
this.chapter = new Chapter(text, 10)
this.updateChildrenUI()
}
tick() {
if (!this.chapter.hasNext()) {
this.player.stop()
} else {
this.chapter.next()
}
this.updateChildrenUI()
}
updateChildrenUI() {
this._rsvpWord.setAttribute('word', this.chapter.currentSegment)
this._rsvpControls.updateUI(this.chapter, this.player)
}
handleControlEvent(e) {
switch (e.detail.action) {
case 'prevSentence':
this.chapter.prevSentence()
break
case 'nextSentence':
this.chapter.nextSentence()
break
case 'prevWord':
this.chapter.prevWord()
break
case 'nextWord':
this.chapter.nextWord()
break
case 'playpause':
this.player.toggle()
break
case 'stop':
this.player.stop()
this.chapter.reset()
break
}
this.updateChildrenUI()
}
}
window.customElements.define('rsvp-reader', RSVPReader)

View File

@ -1,47 +1,24 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> <meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title> <title>Document</title>
<style> <style>
.marker {
text-align: center;
}
</style> </style>
</head> </head>
<body> <body>
<div id="root">
<textarea id="input"> <textarea id="input">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Error fuga eos odit cupiditate harum quibusdam beatae recusandae aut asperiores, molestiae provident modi quia, atque dicta et earum sunt assumenda inventore.</textarea Lorem ipsum dolor sit amet consectetur adipisicing elit. Error fuga eos odit cupiditate harum quibusdam beatae recusandae aut asperiores, molestiae provident modi quia, atque dicta et earum sunt assumenda inventore.</textarea>
>
<button class="action" action="load" id="load">Load Text</button> <button class="action" action="load" id="load">Load Text</button>
<div>
Info: <hr>
</div>
<div> <rsvp-reader></rsvp-reader>
<div>
<div class="marker">|</div>
<rsvp-word id="output"></rsvp-word>
<div class="marker">|</div>
</div>
</div>
<div>
<button class="action" action="prevSentence" id="prevSentence">
&lt;&lt;
</button>
<button class="action" action="prevWord" id="prevWord">&lt;</button>
<button class="action" action="nextWord" id="nextWord">&gt;</button>
<button class="action" action="nextSentence" id="nextSentence">
&gt;&gt;
</button>
</div>
<div>
<button class="action" action="play-pause" id="play"></button>
</div>
</div>
<script type="module" src="index.js"></script> <script type="module" src="index.js"></script>
</body> </body>
</html> </html>

View File

@ -1,67 +1,12 @@
import { Chapter } from './src/Chapter.js' import './components/rsvp-reader.js'
import { Player } from './src/Player.js'
import './components/rsvp-word.js'
const inputText = document.getElementById('input') const inputText = document.getElementById('input')
const output = document.getElementById('output') const rsvpReader = document.getElementsByTagName('rsvp-reader')[0]
const loadBtn = document.getElementById('load')
const prevSentenceButton = document.getElementById('prevSentence') function loadText() {
const prevWordButton = document.getElementById('prevWord') rsvpReader.setText(inputText.value)
const nextWordButton = document.getElementById('nextWord')
const nextSentenceButton = document.getElementById('nextSentence')
const playButton = document.getElementById('play')
let chapter = new Chapter(inputText.value, 10)
let player = new Player()
function updateUI() {
prevSentenceButton.disabled = !chapter.hasPrevSentence()
prevWordButton.disabled = !chapter.hasPrevWord()
nextWordButton.disabled = !chapter.hasNextWord()
nextSentenceButton.disabled = !chapter.hasNextSentence()
playButton.innerText = player.playing ? 'pause' : 'start'
output.setAttribute('word', chapter.currentSegment)
} }
function tick() { loadBtn.addEventListener('click', loadText)
if (!chapter.hasNext()) { loadText()
player.stop()
} else {
chapter.next()
}
updateUI()
}
function handleClick(e) {
switch (e.target.getAttribute('action')) {
case 'load':
chapter = new Chapter(inputText.value, 10)
break
case 'prevSentence':
chapter.prevSentence()
break
case 'nextSentence':
chapter.nextSentence()
break
case 'prevWord':
chapter.prevWord()
break
case 'nextWord':
chapter.nextWord()
break
case 'play-pause':
player.toggle()
break
}
updateUI()
}
for (let button of document.getElementsByClassName('action')) {
button.onclick = handleClick
}
player.subscribe('main', tick)
updateUI()

View File

@ -6,6 +6,10 @@ export class Chapter {
this.segments = segments this.segments = segments
this.words = words this.words = words
this.sentences = sentences this.sentences = sentences
this.reset()
}
reset() {
this.currentIdx = 0 this.currentIdx = 0
} }