diff --git a/dist/iwmlib.js b/dist/iwmlib.js index 865b1ff..45d7992 100644 --- a/dist/iwmlib.js +++ b/dist/iwmlib.js @@ -4021,7 +4021,7 @@ - class DOMScatter extends AbstractScatter { + class DOMScatter$1 extends AbstractScatter { constructor( element, container, @@ -4308,7 +4308,7 @@ bringToFront() { // this.element.parentNode.appendChild(this.element) // uo: On Chome and Electon appendChild leads to flicker - TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ }); + TweenLite.set(this.element, { zIndex: DOMScatter$1.zIndex++ }); } onTap(event, interaction, point) { @@ -4438,7 +4438,7 @@ } } - DOMScatter.zIndex = 1000; + DOMScatter$1.zIndex = 1000; class CardLoader { constructor( @@ -4696,7 +4696,7 @@ frontLoaded(loader) { return new Promise((resolve, reject) => { - let scatter = new DOMScatter( + let scatter = new DOMScatter$1( this.cardWrapper, this.domScatterContainer, { @@ -4920,7 +4920,7 @@ bringToFront() { this.scatter.bringToFront(); - TweenLite.set(this.element, { zIndex: DOMScatter.zIndex++ }); + TweenLite.set(this.element, { zIndex: DOMScatter$1.zIndex++ }); } clickInfo() { @@ -7942,7 +7942,7 @@ zIndex: this.zIndices.popup }); - TweenMax.to(popup.element, this.animation.popup, { + TweenLite.to(popup.element, this.animation.popup, { autoAlpha: 1, ease: Power2.easeIn }); @@ -7962,7 +7962,7 @@ * TEST if this intereferes with the editor. */ if (overlay) { - TweenMax.to(overlay, 0.2, { + TweenLite.to(overlay, 0.2, { autoAlpha: 0, onComplete: () => { popup.remove(); //this._cleanup(context) @@ -8018,9 +8018,9 @@ if (editable) { if (this.debug) console.log("Append overlay.", context); overlay.classList.add('overlay'); - TweenMax.set(overlay, { autoAlpha: 0 }); + TweenLite.set(overlay, { autoAlpha: 0 }); context.appendChild(overlay); - TweenMax.to(overlay, 0.5, { autoAlpha: 0.25 }); + TweenLite.to(overlay, 0.5, { autoAlpha: 0.25 }); } // Extract the body from the Popup site. @@ -8460,17 +8460,17 @@ const scaleFactor = 2; const transformOrigin = 'bottom right'; - TweenMax.set(zoomedFig, { + TweenLite.set(zoomedFig, { x: current.x, y: current.y, width: current.width + borderX, height: current.height + borderY, transformOrigin }); - TweenMax.set(zoomable, { opacity: 0 }); + TweenLite.set(zoomable, { opacity: 0 }); let icon = zoomedFig.querySelector(".icon"); - TweenMax.set(icon, { + TweenLite.set(icon, { transformOrigin }); zoomedFig.style.transformOrigin = "calc(100% - " + parseFloat(zoomedFigStyle.borderRightWidth) + "px) calc(100% - " + parseFloat(zoomedFigStyle.borderBottomWidth) + "px)"; @@ -8540,7 +8540,7 @@ zoomParent.appendChild(zoomedFig); zoomedFig.style.opacity = 0.5; zoomContainer.appendChild(zoomable); - TweenMax.set(zoomable, { x: current.x, y: current.y, width: current.width, height: current.height }); + TweenLite.set(zoomable, { x: current.x, y: current.y, width: current.width, height: current.height }); let editor = mainController.topController().ensureEditor(img); let savedDisplay = zoomIcon.style.display; let iconClone = zoomIcon.cloneNode(true); @@ -8557,14 +8557,14 @@ zoomedFig.remove(); zoomContainer.remove(); zoomParent.appendChild(zoomable); - TweenMax.set(zoomable, { x: 0, y: 0 }); + TweenLite.set(zoomable, { x: 0, y: 0 }); zoomable.onmousedown = null; zoomable.onmousemove = null; zoomable.onmouseup = null; zoomable.onmousewheel = null; }; wrapper.appendChild(iconClone); - TweenMax.set(iconClone, { x: current.iconPos.x, y: current.iconPos.y }); + TweenLite.set(iconClone, { x: current.iconPos.x, y: current.iconPos.y }); zoomable.onmousedown = event => { if (this.debug) console.log('mousedown', event.target); @@ -8578,7 +8578,7 @@ event.preventDefault(); let dx = event.pageX - zoomable.dragStartPos.x; let dy = event.pageY - zoomable.dragStartPos.y; - TweenMax.set([zoomable, iconClone], { x: '+=' + dx, y: '+=' + dy }); + TweenLite.set([zoomable, iconClone], { x: '+=' + dx, y: '+=' + dy }); zoomable.dragStartPos = { x: event.pageX, y: event.pageY }; if (editor) { editor.showControls(); @@ -8597,7 +8597,7 @@ let zoom = direction ? zoomFactor : 1 / zoomFactor; startZoom *= zoom; - TweenMax.set(zoomable, { scale: startZoom }); + TweenLite.set(zoomable, { scale: startZoom }); if (editor) { editor.showControls(); } @@ -8628,17 +8628,17 @@ let zoomedCaption = zoomedFig.querySelector("figcaption.zoomcap"); - TweenMax.to(zoomedCaption, this.animation.fade, { + TweenLite.to(zoomedCaption, this.animation.fade, { autoAlpha: 0, }); - TweenMax.to(zoomedFig, this.animation.zoomable, { + TweenLite.to(zoomedFig, this.animation.zoomable, { css: { scaleX: 1, scaleY: 1 }, onComplete: () => { - TweenMax.set(zoomable, { + TweenLite.set(zoomable, { opacity: 1 }); let div = zoomedFig.parentNode; @@ -8715,7 +8715,7 @@ let padding = parseInt(this.css(indexbox, 'padding')); let maxWidth = this.css(card, 'max-width'); - TweenMax.set(clone, { + TweenLite.set(clone, { css: { position: 'absolute', width: globalIndexCardRect.width, @@ -8726,12 +8726,12 @@ } }); - TweenMax.set(articleClone, { + TweenLite.set(articleClone, { autoAlpha: 0 }); - TweenMax.set(card, { css: { maxWidth: '100%' } }); - TweenMax.set(clone, { + TweenLite.set(card, { css: { maxWidth: '100%' } }); + TweenLite.set(clone, { x: localOrigin.x - padding, y: localOrigin.y - padding, scaleX, @@ -8755,10 +8755,10 @@ /** * Scale the content from 100% to it's target size. */ - // TweenMax.set(subcardContent, { + // TweenLite.set(subcardContent, { // height: "100%" // }) - // TweenMax.to(subcardContent, Card.animation.articleTransition, { + // TweenLite.to(subcardContent, Card.animation.articleTransition, { // height: targetHeight + "px" // }) } @@ -8781,7 +8781,7 @@ } let desiredBorderBottomWidth = parseInt(window.getComputedStyle(titlebar).borderBottomWidth); - TweenMax.to(clone, Card.animation.articleTransition, { + TweenLite.to(clone, Card.animation.articleTransition, { x: -padding, y: -padding, ease: ExpoScaleEase.config(scaleX, 1), @@ -8793,10 +8793,10 @@ onUpdateParams: ['{self}'], onUpdate: (self) => { let transform = self.target._gsTransform; - TweenMax.set(title, { + TweenLite.set(title, { scale: 1 / transform.scaleX }); - TweenMax.set(titlebar, { + TweenLite.set(titlebar, { height: start.height * 1 / transform.scaleY }); @@ -8805,7 +8805,7 @@ } }); - TweenMax.to([articleClone], this.animation.articleTransition / 2, { + TweenLite.to([articleClone], this.animation.articleTransition / 2, { delay: this.animation.articleTransition / 2, autoAlpha: 1 }); @@ -8838,11 +8838,11 @@ let titlebarStyle = window.getComputedStyle(previewTitlebar); let titlebar = clone.querySelector(".titlebar"); - TweenMax.to(titlebar, this.animation.articleTransition, { + TweenLite.to(titlebar, this.animation.articleTransition, { height: parseInt(titlebarStyle.height) }); - TweenMax.to(articleClone, this.animation.articleTransition / 2, { + TweenLite.to(articleClone, this.animation.articleTransition / 2, { autoAlpha: 0 }); @@ -8852,13 +8852,13 @@ }; if (this.dynamicHeight) { - TweenMax.to(subcardContent, this.animation.articleTransition, { + TweenLite.to(subcardContent, this.animation.articleTransition, { height: "100%" }); } - TweenMax.set(card, { autoAlpha: 1, css: { maxWidth } }); - TweenMax.to(clone, this.animation.articleTransition, { + TweenLite.set(card, { autoAlpha: 1, css: { maxWidth } }); + TweenLite.to(clone, this.animation.articleTransition, { x: localOrigin.x - padding, y: localOrigin.y - padding, scaleX, @@ -8867,7 +8867,7 @@ rotation: angle, onComplete: () => { // article.remove() - TweenMax.to(clone, this.animation.fade, + TweenLite.to(clone, this.animation.fade, { //delay: 0.2, autoAlpha: 0, @@ -8884,11 +8884,11 @@ onUpdate: function (self) { let transform = self.target._gsTransform; - TweenMax.set(title, { + TweenLite.set(title, { scale: 1 / transform.scaleX }); - TweenMax.set(titlebar, { + TweenLite.set(titlebar, { height: original.height * 1 / transform.scaleY }); @@ -9009,7 +9009,7 @@ // TODO: What is this good for? // let article = parsedHTML.querySelector('article') // card.insertAdjacentElement('afterbegin', article) - // TweenMax.set(article, { autoAlpha: 0 }) + // TweenLite.set(article, { autoAlpha: 0 }) Card.expandIndexCard(card, parsedHTML, 'article', relativeSource, saveCallback); } @@ -9951,6 +9951,682 @@ Highlight$1.expandedClass = 'expanded'; + /** + * Extends the card with scatter functionality. + * + * @class ScatterCard + */ + class ScatterCard extends Card { + + + /** + * TODO: Find a more suitable name. + * Adjusts the HTML to work in the new context. + * + * @static + * @param {*} domElement + * @param {*} htmlString + * @param {*} basePath + * @param {*} [opts={}] + * @memberof Card + */ + static setup(context, htmlString, { + basePath = "./", + modules = [] + } = {}) { + context.classList.add("info-card"); + + this.relativePath = basePath; + htmlString = this._adjustRelativeLinks(htmlString); + + let parser = new DOMParser(); + let html = parser.parseFromString(htmlString, "text/html"); + + /** + * Conflicts with the FindTarget method of the Abstract scatter. + */ + this._replaceAttributes(html, "onclick", this._replaceCallback); + + + let content = html.querySelector(".mainview"); + context.appendChild(content); + + super.setup(context, modules); + return context + } + + + /** + * Appends a close listener to the scatter element. + * + * @static + * @param {*} element + * @param {*} callback + * @memberof Card + */ + static addOnCloseListener(element, callback) { + if (callback) { + element.onClose = callback; + } + } + + + /** + * Creates a scatter for the card and applies the card to it, + * + * @static + * @param {*} html + * @param {*} scatterContainer + * @param {string} [basePath=""] + * @param {*} [opts={}] + * @returns + * @memberof Card + */ + static createCardScatter(html, scatterContainer, { + basePath = "./", + modules = [] + } = {}) { + let element = document.createElement("div"); + + scatterContainer.element.appendChild(element); + new DOMScatter(element, scatterContainer, { + width: 1400, + height: 1200 + }); + + this.setup(element, html, { + basePath, + modules + }); + return element + } + + + + /** + *Utility function to create a fully functional card scatter. + * + * @static + * @param {*} scatterContainer + * @param {*} path + * @param {string} [basePath="."] + * @param {*} opts + * @returns + * @memberof CardScatter + */ + static loadAndCreateScatterCard(scatterContainer, item, { + basePath = "../", + modules = [], + onClose = null + } = {}) { + console.log(basePath); + return new Promise((resolve, reject) => { + let url = basePath + "/" + item + "/index.html"; + console.log("Loading", url); + this.loadHTML(url) + .then(html => { + console.log("Received", html); + let element = this.createCardScatter(html, scatterContainer, { + basePath, + modules + }); + if (onClose) + this.addOnCloseListener(element, onClose); + resolve(element); + }) + .catch(e => reject(e)); + }) + } + + static _setLanguage(context, language) { + context.language = language; + } + + static _getLanguage(context) { + return context.language + } + + } + + ScatterCard.selectedLanguage = 0; + ScatterCard.languages = ["Deutsch", "English"]; + ScatterCard.languageTags = { + Deutsch: "de", + English: "en" + }; + ScatterCard.scatterContainer = null; + + var CardPlugin = CardPlugin || {}; + + class CardPluginBase { + + apply(context) { + if (this.verify(context)) { + this.append(context); + console.log("Plugin " + this.name + " was verified successfully."); + return true + } else console.error("Could not verify module " + this.name + "."); + return false + } + + get name() { + return this.constructor.name + } + + verify(context) { + let funcs = this._getVerificationFunctions(context); + for (let func of funcs) { + if (!func()) return false + } + return true + } + + _verifyElementsExist(context, ...selectors) { + let missing = []; + + for (let selector of selectors) { + let requiredElement = context.querySelector(selector); + if (requiredElement == null) { + missing.push(selector); + } + } + const valid = (missing.length == 0); + if (!valid) console.error("Elements were missing: ", missing.join(", ")); + return valid + } + + + /** + * Appends the Plugin to the context. + * + * @memberof CardPlugin + */ + append(context) { + console.error("Call of abstract method CardPlugin.prototype.append(context). Plugins need to overwrite the append method!"); + } + + _getVerificationFunctions(context) { + return [ + this._verifyContext.bind(this, context), + this._verifyRequirements.bind(this, context) + ] + } + + _verifyContext(context) { + if (!(context instanceof HTMLElement)) { + console.error("Context is not of type HTML Element.", context); + return false + } else return true + } + + _verifyRequirements(context) { + let requirements = this._collectAllRequirements(); + let missing = []; + + requirements.forEach(module => { + if (context.modules.indexOf(module.name) == -1) { + missing.push(module.name); + } + }); + + const valid = (missing.length == 0); + if (!valid) console.error("Could not apply module '" + this.name + "'. Following modules are required but were missing: " + missing.join(",")); + else console.log("All requirements were met! Well done!"); + return valid + } + + + _collectAllRequirements() { + let requirements = []; + let klass = this.__proto__; + while (klass) { + if (klass.require != null) { + requirements = requirements.concat(klass.require); + } + klass = klass.__proto__; + } + return requirements + } + } + + + + + CardPlugin.LightBox = class LightBox extends CardPluginBase { + constructor(className, style = {}) { + super(); + this.className = className; + this.style = style; + } + + append(context) { + let wrapper = document.createElement("div"); + wrapper.className = this.className; + + Object.assign(wrapper.style, { + zIndex: 1000, + // backgroundColor: "black", + top: 0, + left: 0, + width: "100%", + height: "100%" + }, this.style, { + display: "none", + position: "absolute", + }); + + context.appendChild(wrapper); + } + + }; + + + /** + * The Enlargeable Overlay module allows the user to click on the thumbnail image, + * and the images gets enlarged inside the card. + * + * @class EnlargeableThumbnail + * @extends {CardPlugin} + */ + CardPlugin.EnlargeableThumbnail = class EnlargeableThumbnail extends CardPluginBase { + + constructor(wrapperSelector, overlaySelector = null, { + zoomAnimationDuration = 0.4, + fadeAnimationDuration = 0.4, + interactionType = "tap" + } = {}) { + super(); + this.wrapperSelector = wrapperSelector; + this.overlaySelector = overlaySelector; + + this.zoomAnimationDuration = zoomAnimationDuration; + this.fadeAnimationDuration = fadeAnimationDuration; + this.interactionType = interactionType; + } + + get require() { + return [ + CardPlugin.LightBox + ] + } + + _getVerificationFunctions(context) { + let arr = super._getVerificationFunctions(context); + let funcs = [ + this._verifyElementsExist.bind(this, context, this.wrapperSelector, this.overlaySelector) + ]; + return arr.concat(funcs) + } + + append(context) { + let source = this._retrieveSource(context); + this.setupEnlargeableThumbnail(context, source); + } + + + /** + * Get the preview image. + * + * It depends on the fact, that the thumbnail image is in the same directory + * + * + * @param {*} context + * @returns + * @memberof EnlargeableThumbnail + */ + _retrieveSource(context) { + let img = context.querySelector(this.wrapperSelector + " img"); + let src = img.getAttribute("src"); + let parts = src.split("/"); + parts.pop(); + parts.push(parts[parts.length - 1]); + let imagePath = parts.join("/") + ".jpg"; + return imagePath + } + + + setupEnlargeableThumbnail(context, src) { + let wrapper = context.querySelector(this.wrapperSelector); + let overlay = context.querySelector(this.overlaySelector); + + let icon = document.createElement("div"); + icon.className = "button corner-button bottom-right icon zoom"; + wrapper.appendChild(icon); + + Object.assign(wrapper.style, { + cursor: "pointer" + }); + + InteractionMapper.on(this.interactionType, wrapper, () => { + this.openThumbnailDetail(context, src); + }); + + InteractionMapper.on(this.interactionType, overlay, () => { + this.closeThumnailDetail(context); + }); + } + + openThumbnailDetail(context, src) { + let overlay = context.querySelector(".img-overlay"); + overlay.innerHTML = ""; + let source = context.querySelector(this.wrapperSelector); + let sourceStyle = window.getComputedStyle(source); + let imageWrapper = source.cloneNode(true); + let image = imageWrapper.querySelector("img"); + + Object.assign(imageWrapper.style, { + maxWidth: "none", + maxHeight: "none" + }); + + Object.assign(image.style, { + width: "100%", + height: "100%", + objectFit: "cover" + }); + + this._replaceIcon(imageWrapper); + + image.onload = () => { + let header = context.querySelector("header"); + let headerStlye = window.getComputedStyle(header); + + /** + * First the maxFillRatio is considered. + * It describes how much the image is allowed to exceed the context element. + */ + const maxFillRatio = 1.5; + + /** + * The minor side should not exceed the height of the context window. + */ + const maxMinorSize = context.offsetHeight - 2 * parseInt(headerStlye.paddingTop) - 2 * parseInt(headerStlye.marginTop); + + + + const max = { + width: context.offsetWidth * maxFillRatio, + height: context.offsetHeight * maxFillRatio + }; + + + let majorSide; + let minorSide; + const _width = { name: "width", axis: "x" }; + const _height = { name: "height", axis: "y" }; + if (image.naturalHeight > image.naturalWidth) { + majorSide = _height; + minorSide = _width; + } else { + majorSide = _width; + minorSide = _height; + } + + function capitalize(string) { + return string.charAt(0).toUpperCase() + string.slice(1) + } + function getImageSize(side) { + return image["natural" + capitalize(side.name)] + } + + const majorImageSize = getImageSize(majorSide); + // const minorImageSize = getImageSize(minorSide) + + let ratio = getImageSize(minorSide) / getImageSize(majorSide); + let size = (majorImageSize > max[majorSide.name]) ? max[majorSide.name] : majorImageSize; + + if (size * ratio > maxMinorSize) { + size = maxMinorSize / ratio; + } + + let targetDimensions = { + width: 0, + height: 0 + }; + + + let position = Points.fromPageToNode(context, Points.fromNodeToPage(source, { x: 0, y: 0 })); + + let targetOffset = { + x: 0, + y: 0 + }; + + targetDimensions[majorSide.name] = size; + targetDimensions[minorSide.name] = size * ratio; + + targetOffset[majorSide.axis] = (context["offset" + capitalize(majorSide.name)] - targetDimensions[majorSide.name]) / 2; + targetOffset[minorSide.axis] = (context["offset" + capitalize(minorSide.name)] - targetDimensions[minorSide.name]) / 2; + + overlay.appendChild(imageWrapper); + + TweenMax.set(imageWrapper, { + left: 0, + top: 0, + x: position.x, + y: position.y, + position: "absolute", + width: parseInt(sourceStyle.width), + height: parseInt(sourceStyle.height) + }); + + + TweenMax.set(overlay, { + display: "flex", + autoAlpha: 0 + }); + + TweenMax.to(imageWrapper, this.zoomAnimationDuration, { + x: targetOffset.x, + y: targetOffset.y, + width: targetDimensions.width, + height: targetDimensions.height, + }); + TweenMax.to(overlay, this.fadeAnimationTime, { + autoAlpha: 1 + }); + }; + + image.src = src; + } + + _replaceIcon(clone) { + let zoomIcon = clone.querySelector(".icon.zoom"); + zoomIcon.classList.remove("zoom"); + zoomIcon.classList.add("close"); + } + + getBorderHeight(style) { + const borderWidth = parseInt(style.borderTopWidth) + parseInt(style.borderBottomWidth); + const padding = parseInt(style.paddingTop) + parseInt(style.paddingBottom); + return parseInt(style.width) + borderWidth + padding + } + + getBorderWidth(style) { + const borderWidth = parseInt(style.borderLeftWidth) + parseInt(style.borderRightWidth); + const padding = parseInt(style.paddingLeft) + parseInt(style.paddingRight); + return parseInt(style.width) + borderWidth + padding + } + + closeThumnailDetail(context) { + let overlay = context.querySelector(".img-overlay"); + + let timeline = new TimelineLite(); + + timeline.to(overlay, this.fadeAnimationDuration, { + autoAlpha: 0 + }).set(overlay, { + display: "none" + }); + } + + }; + + CardPlugin.Ui = class UiPlugin extends CardPluginBase { + constructor(className, parent = null) { + super(); + this.parent = parent; + this.className = className; + } + + _getVerificationFunctions(context) { + let arr = super._getVerificationFunctions(context); + let func = [ + this._doesParentExist.bind(this, context, this.parent) + ]; + return arr.concat(func) + } + + _doesParentExist(context, parent) { + if (parent == null) return true + let valid = (context.querySelector(parent) != null); + if (!valid) console.error("Could not find parent on context.", context, parent); + return valid + } + + append(context) { + parent = (this.parent == null) ? context : context.querySelector(this.parent).appendChild(container); + let container = document.createElement("div"); + container.className = this.className; + parent.appendChild(container); + } + + }; + + CardPlugin.Speech = class SpeechPlugin extends CardPluginBase { + + constructor(parentSelector, className, interactionType = "tap") { + super(); + this.className = className; + this.parentSelector = parentSelector; + this.interactionType = interactionType; + + } + + get require() { + return [ + CardPlugin.Ui + ] + } + + append(context) { + let container = context.querySelector(this.parentSelector); + this.button = document.createElement("div"); + this.button.className = "icon button " + this.className; + container.appendChild(this.button); + + InteractionMapper.on(this.interactionType, this.button, () => { + let subcard = context.querySelector(".mainview > .subcard"); + let target = (subcard) ? subcard : context; + + this.speak(target); + + }); + } + + _activate() { + this._disableActive(); + this.active = this; + this._activateButton(); + } + + _activateButton() { + if (this.button) + this.button.classList.add("active"); + } + + _deactivate() { + this._deactivateButton(); + } + + _deactivateButton() { + if (this.button) + this.button.classList.remove("active"); + } + + _isSameNode(node) { + //console.log(this.currentText, node.innerText) + return (this.currentText == node.innerText) + } + + speak(node) { + + console.log(this._isSameNode(node)); + + if (!window.speechSynthesis.speaking) { + console.log("Noone talking!"); + this._start(node); + } else if (this._isSameNode(node)) { + console.log("Requested same!"); + this._stop(); + + } else { + console.log("Requested Different!"); + this._stop(); + this._start(node); + } + + } + + _disableActive() { + console.log("disableActive:", this.active); + if (this.active) { + this.active._deactivate(); + } + } + + _start(node) { + this.currentText = node.innerText; + let utterance = new SpeechSynthesisUtterance(node.innerText); + + let voices = window.speechSynthesis.getVoices(); + console.log(voices); + let voice = voices.filter((val) => { + //console.log(val) + return val.name == "Microsoft Hedda Desktop - German" + })[0]; + + //console.log(voice) + + utterance.voice = voice; + console.log("TALK: ", utterance); + window.speechSynthesis.speak(utterance); + this._activate(); + window.speechSynthesis.resume(); + + + utterance.onboundary = () => { console.log("onboundary", node.innerText); if (this.currentText.substring(0, 5) != node.innerText.substring(0, 5)) { console.log("text for speech synth changed!", this.currentText, node.innerText); this._stop(); } }; + utterance.onend = () => console.log("onend", node.innerText); + utterance.onerror = () => console.log("onerror", node.innerText); + utterance.onmark = () => console.log("onmark", node.innerText); + utterance.onpause = () => console.log("onpause", node.innerText); + utterance.onresume = () => console.log("onresume", node.innerText); + utterance.onstart = () => console.log("onstart", node.innerText); + utterance.onerror = () => console.log("onerror", node.innerText); + } + + _stop() { + window.speechSynthesis.cancel(); + this.currentText = null; + this._deactivate(); + } + + get active() { + return this.constructor.active + } + + set active(val) { this.constructor.active = val; } + + get currentText() { + return this.constructor.text + } + + set currentText(val) { + this.constructor.text = val; + } + + }; + /* eslint-disable no-unused-vars */ /** @@ -10019,7 +10695,7 @@ window.ImageLoader = ImageLoader; window.FrameLoader = FrameLoader; - window.DOMScatter = DOMScatter; + window.DOMScatter = DOMScatter$1; window.DOMScatterContainer = DOMScatterContainer; window.Dates = Dates; window.Doctest = Doctest; @@ -10064,7 +10740,9 @@ window.CardWrapper = CardWrapper; window.Card = Card; - window.ScatterCard = Card; + window.CardPlugin = CardPlugin; + window.CardPluginBase = CardPluginBase; + window.ScatterCard = ScatterCard; window.Highlight = Highlight$1; window.Theme = Theme; diff --git a/lib/bundle.js b/lib/bundle.js index 5c708c5..7521534 100755 --- a/lib/bundle.js +++ b/lib/bundle.js @@ -22,7 +22,7 @@ import UITest from './uitest.js' import Card from './card/card.js' import CardWrapper from './card/wrapper.js' import Highlight from './card/highlight.js' -import ScatterCard from './card/card.js' +import ScatterCard from './card/scatter.js' import { CardPlugin, CardPluginBase } from './card/plugin.js' import Theme from './card/theme.js' @@ -92,6 +92,8 @@ window.randomFloat = randomFloat window.CardWrapper = CardWrapper window.Card = Card +window.CardPlugin = CardPlugin +window.CardPluginBase = CardPluginBase window.ScatterCard = ScatterCard window.Highlight = Highlight window.Theme = Theme diff --git a/lib/card/scatter.js b/lib/card/scatter.js index 885649b..184761e 100644 --- a/lib/card/scatter.js +++ b/lib/card/scatter.js @@ -1,3 +1,5 @@ +import Card from './card.js' + /** * Extends the card with scatter functionality. *