Fixed closing issue with cards.
This commit is contained in:
		
							parent
							
								
									30c7113713
								
							
						
					
					
						commit
						28a7a0b6a2
					
				
							
								
								
									
										43
									
								
								dist/iwmlib.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								dist/iwmlib.js
									
									
									
									
										vendored
									
									
								
							@ -2772,7 +2772,9 @@
 | 
			
		||||
                    for (let j = 0; j < elements.length; j++) {
 | 
			
		||||
                        // if(elements[j].tagName == "svg") return false;
 | 
			
		||||
 | 
			
		||||
                        let hammer = new Hammer(elements[j], opts);
 | 
			
		||||
                        const target = elements[j];
 | 
			
		||||
 | 
			
		||||
                        let hammer = new Hammer(target, opts);
 | 
			
		||||
 | 
			
		||||
                        if (window.propagating !== 'undefined') {
 | 
			
		||||
                            hammer = propagating(hammer);
 | 
			
		||||
@ -2793,16 +2795,23 @@
 | 
			
		||||
                            hammer.get('tap').set(opts);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        console.log('APPLY HAMMER ON', type);
 | 
			
		||||
 | 
			
		||||
                        target.addEventListener("click", ()=>{
 | 
			
		||||
                            console.log("Hello");
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        hammer.on(type, event => {
 | 
			
		||||
                            console.log('FIRED');
 | 
			
		||||
                            cb(event);
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        if (Hammer.__hammers.has(elements[j])) {
 | 
			
		||||
                            const elementHammers = Hammer.__hammers.get(elements[j]);
 | 
			
		||||
                        if (Hammer.__hammers.has(target)) {
 | 
			
		||||
                            const elementHammers = Hammer.__hammers.get(target);
 | 
			
		||||
                            elementHammers.push(hammer);
 | 
			
		||||
                            Hammer.__hammers.set(elements[j], elementHammers);
 | 
			
		||||
                            Hammer.__hammers.set(target, elementHammers);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Hammer.__hammers.set(elements[j], [hammer]);
 | 
			
		||||
                            Hammer.__hammers.set(target, [hammer]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
@ -7709,8 +7718,9 @@
 | 
			
		||||
         * @memberof Card
 | 
			
		||||
         */
 | 
			
		||||
        static _replaceAttributes(context, html, attribute, replaceFunc) {
 | 
			
		||||
            let clickables = html.querySelectorAll(`[${attribute}]`);
 | 
			
		||||
            clickables.forEach(element => {
 | 
			
		||||
            let attributeCarrier = html.querySelectorAll(`[${attribute}]`);
 | 
			
		||||
            attributeCarrier.forEach(element => {
 | 
			
		||||
                console.log(element);
 | 
			
		||||
                let attributeVal = element.getAttribute(attribute);
 | 
			
		||||
                element.removeAttribute(attribute);
 | 
			
		||||
                replaceFunc.call(this, context, element, attributeVal);
 | 
			
		||||
@ -7759,10 +7769,13 @@
 | 
			
		||||
            // These are 'hardcoded' inside the convert.js.
 | 
			
		||||
            if (element.tagName == 'circle') return false
 | 
			
		||||
 | 
			
		||||
            console.log("Replace" , context, element, attributeVal);
 | 
			
		||||
 | 
			
		||||
            this.registerEvent(context, interactionType, element, event => {
 | 
			
		||||
                /**
 | 
			
		||||
                 * Replaces the strings from the listener with the cooresponding variables.
 | 
			
		||||
                 */
 | 
			
		||||
                console.log("EVENT");
 | 
			
		||||
                let args = [];
 | 
			
		||||
                argsStrings.forEach(arg => {
 | 
			
		||||
                    arg = arg.trim();
 | 
			
		||||
@ -7811,13 +7824,6 @@
 | 
			
		||||
                /<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g,
 | 
			
		||||
                function(data) {
 | 
			
		||||
                    let path = that._getRelativePath(arguments[4]);
 | 
			
		||||
 | 
			
		||||
                    console.log('REPLACE ', arguments[1]);
 | 
			
		||||
                    if (arguments[1] == 'a') {
 | 
			
		||||
                        console.error('NOT REPLACING LINKS');
 | 
			
		||||
                        return ''
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>`;
 | 
			
		||||
                    /* if (that.debug) */ console.log('Adjusted: ', tag);
 | 
			
		||||
                    return tag
 | 
			
		||||
@ -9152,7 +9158,7 @@
 | 
			
		||||
         * @memberof Card
 | 
			
		||||
         */
 | 
			
		||||
        static openIndexCard(event, src) {
 | 
			
		||||
            //console.log("openIndexCard", src)
 | 
			
		||||
            console.log("openIndexCard", src);
 | 
			
		||||
            /*
 | 
			
		||||
             *   Called by the expandIndexCard(...)
 | 
			
		||||
             */
 | 
			
		||||
@ -9324,6 +9330,7 @@
 | 
			
		||||
            let parser = new DOMParser();
 | 
			
		||||
            let html = parser.parseFromString(htmlString, 'text/html');
 | 
			
		||||
            if (!editable) {
 | 
			
		||||
                console.log("REPLACE ONCLICK");
 | 
			
		||||
                this._replaceAttributes(context, html, 'onclick', this._replaceCallback);
 | 
			
		||||
            }
 | 
			
		||||
            let zoomableWrappers = html.querySelectorAll('.svg-wrapper');
 | 
			
		||||
@ -9562,7 +9569,10 @@
 | 
			
		||||
         * @memberof Card
 | 
			
		||||
         */
 | 
			
		||||
        static registerEvent(context, types, element, callback) {
 | 
			
		||||
            InteractionMapper.on(types, element, callback);
 | 
			
		||||
            console.log("REGISTER INTERACTION EVENT",context, types, element, callback);
 | 
			
		||||
            InteractionMapper.on(types, element, ()=>{
 | 
			
		||||
                console.log("HELLO");
 | 
			
		||||
            });
 | 
			
		||||
            if (context._registeredEvents == null) context._registeredEvents = [];
 | 
			
		||||
            if (context._registeredEvents.indexOf(element) == -1) context._registeredEvents.push(element);
 | 
			
		||||
        }
 | 
			
		||||
@ -10202,6 +10212,7 @@
 | 
			
		||||
            context.classList.add('info-card');
 | 
			
		||||
 | 
			
		||||
            this.relativePath = basePath;
 | 
			
		||||
            console.log(htmlString);
 | 
			
		||||
            htmlString = this._adjustRelativeLinks(htmlString);
 | 
			
		||||
 | 
			
		||||
            let parser = new DOMParser();
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								dist/iwmlib.pixi.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								dist/iwmlib.pixi.js
									
									
									
									
										vendored
									
									
								
							@ -6396,7 +6396,9 @@
 | 
			
		||||
                    for (let j = 0; j < elements.length; j++) {
 | 
			
		||||
                        // if(elements[j].tagName == "svg") return false;
 | 
			
		||||
 | 
			
		||||
                        let hammer = new Hammer(elements[j], opts);
 | 
			
		||||
                        const target = elements[j];
 | 
			
		||||
 | 
			
		||||
                        let hammer = new Hammer(target, opts);
 | 
			
		||||
 | 
			
		||||
                        if (window.propagating !== 'undefined') {
 | 
			
		||||
                            hammer = propagating(hammer);
 | 
			
		||||
@ -6417,16 +6419,23 @@
 | 
			
		||||
                            hammer.get('tap').set(opts);
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        console.log('APPLY HAMMER ON', type);
 | 
			
		||||
 | 
			
		||||
                        target.addEventListener("click", ()=>{
 | 
			
		||||
                            console.log("Hello");
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        hammer.on(type, event => {
 | 
			
		||||
                            console.log('FIRED');
 | 
			
		||||
                            cb(event);
 | 
			
		||||
                        });
 | 
			
		||||
 | 
			
		||||
                        if (Hammer.__hammers.has(elements[j])) {
 | 
			
		||||
                            const elementHammers = Hammer.__hammers.get(elements[j]);
 | 
			
		||||
                        if (Hammer.__hammers.has(target)) {
 | 
			
		||||
                            const elementHammers = Hammer.__hammers.get(target);
 | 
			
		||||
                            elementHammers.push(hammer);
 | 
			
		||||
                            Hammer.__hammers.set(elements[j], elementHammers);
 | 
			
		||||
                            Hammer.__hammers.set(target, elementHammers);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            Hammer.__hammers.set(elements[j], [hammer]);
 | 
			
		||||
                            Hammer.__hammers.set(target, [hammer]);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										206
									
								
								lib/card/card.js
									
									
									
									
									
								
							
							
						
						
									
										206
									
								
								lib/card/card.js
									
									
									
									
									
								
							@ -1,5 +1,6 @@
 | 
			
		||||
'use strict'
 | 
			
		||||
 | 
			
		||||
'use strict';
 | 
			
		||||
import  Highlight  from './highlight.js'
 | 
			
		||||
 | 
			
		||||
/** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */
 | 
			
		||||
const closeIconDataURI = `data:image/svg+xml;utf8,
 | 
			
		||||
@ -33,10 +34,17 @@ const enableNearestNeighborTaps = false
 | 
			
		||||
export default class Card {
 | 
			
		||||
    static setup(context, modules = []) {
 | 
			
		||||
        console.log('Setup Card...', modules)
 | 
			
		||||
        context.modules = []
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * This is required for the callback functions to work properly.
 | 
			
		||||
         */
 | 
			
		||||
        window.Card = Card
 | 
			
		||||
 | 
			
		||||
        context.modules = []
 | 
			
		||||
        context.module = {}
 | 
			
		||||
 | 
			
		||||
        context.onClose = null
 | 
			
		||||
 | 
			
		||||
        context.classList.add('info-card')
 | 
			
		||||
        context.setAttribute('data-id', Card.id++)
 | 
			
		||||
 | 
			
		||||
@ -51,16 +59,57 @@ export default class Card {
 | 
			
		||||
 | 
			
		||||
    static remove(context) {
 | 
			
		||||
        for (let module of Object.values(context.module)) {
 | 
			
		||||
            module.remove()
 | 
			
		||||
            const moduleHasRemoveFunction = typeof module.remove === 'function'
 | 
			
		||||
            if (moduleHasRemoveFunction) module.remove()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static eventClose(event) {
 | 
			
		||||
    static close(event) {
 | 
			
		||||
        let context = this.getContext(event.target)
 | 
			
		||||
 | 
			
		||||
        if (context) {
 | 
			
		||||
            this.constructor.close(context)
 | 
			
		||||
        } else console.error('Could not find context!', event.target)
 | 
			
		||||
        if (context.onClose != null) {
 | 
			
		||||
            context.onClose()
 | 
			
		||||
        } else {
 | 
			
		||||
            this.remove(context)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // console.error("Remove")
 | 
			
		||||
        // let context = this.getContext(event.target)
 | 
			
		||||
 | 
			
		||||
        // if (context) {
 | 
			
		||||
        //     this.remove(context)
 | 
			
		||||
        // } else console.error('Could not find context!', event.target)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds an on close method to the provided context.
 | 
			
		||||
     * This will overwrite the default closing behaviour.
 | 
			
		||||
     * Removing the
 | 
			
		||||
     *
 | 
			
		||||
     * @static
 | 
			
		||||
     * @param {DOMElement} context - Context on which the onClose will be set.
 | 
			
		||||
     * @param {Function} callback - Callback function of the onClose.
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static setOnClose(context, callback) {
 | 
			
		||||
        if (context.onClose != null) console.error('OnClose was already set. It was overwritten by the new method.')
 | 
			
		||||
        context.onClose = callback
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *  Unsets the onClose.
 | 
			
		||||
     *
 | 
			
		||||
     * Note: This may be used in conjunction with the setOnClose method.
 | 
			
		||||
     * Using the setOnClose method to adjust behaviour before closing the card.
 | 
			
		||||
     * Then unsetting the onClose to close the Card appropriately by calling the
 | 
			
		||||
     * Card.Close again.
 | 
			
		||||
     *
 | 
			
		||||
     * @static
 | 
			
		||||
     * @param {DOMElement} context - Context on which the remove will be executed.
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static removeOnClose(context) {
 | 
			
		||||
        context.onClose = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -70,12 +119,12 @@ export default class Card {
 | 
			
		||||
     * @param {*} event
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static close(context) {
 | 
			
		||||
        console.log('CLOSE CARD!!!')
 | 
			
		||||
        this.unregisterAllEvents(context)
 | 
			
		||||
        if (context.onClose) {
 | 
			
		||||
            context.onClose(event)
 | 
			
		||||
        } else context.parentNode.removeChild(context)
 | 
			
		||||
    static remove(context) {
 | 
			
		||||
        if (context.parentNode != null) {
 | 
			
		||||
            context.parentNode.removeChild(context)
 | 
			
		||||
        } else {
 | 
			
		||||
            console.error('Tried removing card but it was already removed.')
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -88,8 +137,8 @@ export default class Card {
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static _replaceAttributes(context, html, attribute, replaceFunc) {
 | 
			
		||||
        let clickables = html.querySelectorAll(`[${attribute}]`)
 | 
			
		||||
        clickables.forEach(element => {
 | 
			
		||||
        let attributeCarrier = html.querySelectorAll(`[${attribute}]`)
 | 
			
		||||
        attributeCarrier.forEach(element => {
 | 
			
		||||
            let attributeVal = element.getAttribute(attribute)
 | 
			
		||||
            element.removeAttribute(attribute)
 | 
			
		||||
            replaceFunc.call(this, context, element, attributeVal)
 | 
			
		||||
@ -124,11 +173,23 @@ export default class Card {
 | 
			
		||||
        let argsStrings = trimmedArgs.split(',').filter(entry => {
 | 
			
		||||
            return entry.trim() != ''
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * As we determine a function by a string we must traverse from the window object to
 | 
			
		||||
         * get the associated javascript function.
 | 
			
		||||
         */
 | 
			
		||||
        let callStack = window
 | 
			
		||||
        let last = 'window'
 | 
			
		||||
        do {
 | 
			
		||||
            callStack = callStack[callParts.shift().trim()]
 | 
			
		||||
            let func = callParts.shift().trim()
 | 
			
		||||
            if (callStack[func] == null) {
 | 
			
		||||
                callStack = null
 | 
			
		||||
                console.error(
 | 
			
		||||
                    `Could not access callback function: ${attributeVal}. Member ${func} of ${last} could not be found.`
 | 
			
		||||
                )
 | 
			
		||||
                break
 | 
			
		||||
            } else callStack = callStack[func]
 | 
			
		||||
        } while (callParts.length > 0)
 | 
			
		||||
        let targetFunc = callStack
 | 
			
		||||
 | 
			
		||||
        let that = this
 | 
			
		||||
 | 
			
		||||
@ -161,8 +222,9 @@ export default class Card {
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
            event.stopPropagation()
 | 
			
		||||
            if (callStack) callStack.call(that, ...args)
 | 
			
		||||
            else {
 | 
			
		||||
            if (targetFunc) {
 | 
			
		||||
                targetFunc.call(that, ...args)
 | 
			
		||||
            } else {
 | 
			
		||||
                console.error('Could not call callback function ' + attributeVal, ...args)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
@ -190,13 +252,6 @@ export default class Card {
 | 
			
		||||
            /<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g,
 | 
			
		||||
            function(data) {
 | 
			
		||||
                let path = that._getRelativePath(arguments[4])
 | 
			
		||||
 | 
			
		||||
                console.log('REPLACE ', arguments[1])
 | 
			
		||||
                if (arguments[1] == 'a') {
 | 
			
		||||
                    console.error('NOT REPLACING LINKS')
 | 
			
		||||
                    return ''
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>`
 | 
			
		||||
                /* if (that.debug) */ console.log('Adjusted: ', tag)
 | 
			
		||||
                return tag
 | 
			
		||||
@ -751,7 +806,7 @@ export default class Card {
 | 
			
		||||
 | 
			
		||||
                    let point = svgPoint.matrixTransform(matrix)
 | 
			
		||||
                    let closestDiv = node.closest('div')
 | 
			
		||||
                    console.log('closestDiv', closestDiv, point)
 | 
			
		||||
                    // console.log('closestDiv', closestDiv, point)
 | 
			
		||||
                    let global = Points.fromNodeToPage(closestDiv, point)
 | 
			
		||||
                    let local = Points.fromPageToNode(context, global)
 | 
			
		||||
 | 
			
		||||
@ -763,7 +818,7 @@ export default class Card {
 | 
			
		||||
                    // we could load the data while the circle is animating.
 | 
			
		||||
                    // but for simplicity it's just done here for now.
 | 
			
		||||
                    // TODO: Adjust to load while animating (Problem: Unload when cancelled).
 | 
			
		||||
                    console.log('loadHighlightPopup', src, position, local)
 | 
			
		||||
                    // console.log('loadHighlightPopup', src, position, local)
 | 
			
		||||
                    this._loadPopupContent(context, src)
 | 
			
		||||
                        .then(content => {
 | 
			
		||||
                            this._openPopup(context, src, local, content, {
 | 
			
		||||
@ -1214,7 +1269,7 @@ export default class Card {
 | 
			
		||||
     *
 | 
			
		||||
     * @param {*} card - The card to expand
 | 
			
		||||
     * @param {string} html - The original HTML of the card
 | 
			
		||||
     * @param {*} tagName - The tagname of the element that is used as exanded element
 | 
			
		||||
     * @param {*} tagName - The tagname of the element that is used as expanded element
 | 
			
		||||
     * @param {*} src - The src of the expanded element
 | 
			
		||||
     * @param {*} callback - A callback that is called when the expanded element is closed
 | 
			
		||||
     */
 | 
			
		||||
@ -1257,7 +1312,6 @@ export default class Card {
 | 
			
		||||
        let scaleY = globalPreviewRect.height / globalIndexCardRect.height
 | 
			
		||||
 | 
			
		||||
        let padding = parseInt(this.css(indexbox, 'padding'))
 | 
			
		||||
        let maxWidth = this.css(card, 'max-width')
 | 
			
		||||
 | 
			
		||||
        TweenLite.set(clone, {
 | 
			
		||||
            css: {
 | 
			
		||||
@ -1295,7 +1349,6 @@ export default class Card {
 | 
			
		||||
 | 
			
		||||
        if (this.dynamicHeight) {
 | 
			
		||||
            let targetHeight = subcardContent.offsetHeight
 | 
			
		||||
            console.log(targetHeight)
 | 
			
		||||
            subcardContent.classList.add('dynamic-height')
 | 
			
		||||
            /**
 | 
			
		||||
             * Scale the content from 100% to it's target size.
 | 
			
		||||
@ -1309,7 +1362,7 @@ export default class Card {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //jquery hyphenate below
 | 
			
		||||
        if (this.constructor._jQueryIsPresent()) {
 | 
			
		||||
        if (this._isJQueryPresent()) {
 | 
			
		||||
            $('.column')
 | 
			
		||||
                .not('.overview')
 | 
			
		||||
                .children('p')
 | 
			
		||||
@ -1389,7 +1442,7 @@ export default class Card {
 | 
			
		||||
        if (enableNearestNeighborTaps) {
 | 
			
		||||
            //look for nearby popups on tap
 | 
			
		||||
            InteractionMapper.on('tap', indexbox, () => {
 | 
			
		||||
                console.log('Tap handler called', editable)
 | 
			
		||||
                // console.log('Tap handler called', editable)
 | 
			
		||||
                if (!editable) {
 | 
			
		||||
                    this.findNearbyPopups(event, card)
 | 
			
		||||
                }
 | 
			
		||||
@ -1407,24 +1460,55 @@ export default class Card {
 | 
			
		||||
                if (isDirty) {
 | 
			
		||||
                    mainController.saveNode(html.innerHTML, url => {
 | 
			
		||||
                        callback(url)
 | 
			
		||||
                        this._closeIndexCard(context, card,{
 | 
			
		||||
                        this._closeIndexCard(context, card, clone, articleClone, {
 | 
			
		||||
                            eventElements,
 | 
			
		||||
                            src
 | 
			
		||||
                        })
 | 
			
		||||
                    })
 | 
			
		||||
                } else {
 | 
			
		||||
                    this._closeIndexCard(context, card)
 | 
			
		||||
                    this._closeIndexCard(context, card, clone, articleClone)
 | 
			
		||||
                }
 | 
			
		||||
            } else {
 | 
			
		||||
                this._closeIndexCard(context, card)
 | 
			
		||||
                this._closeIndexCard(context, card, clone, articleClone)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _closeIndexCard(context, card, { 
 | 
			
		||||
        eventElements = [],
 | 
			
		||||
        src = null
 | 
			
		||||
    } = []) {
 | 
			
		||||
    /**
 | 
			
		||||
     * Closes the index card again.
 | 
			
		||||
     *
 | 
			
		||||
     * @static
 | 
			
		||||
     * @param {DOMElement} context - The Card element.
 | 
			
		||||
     * @param {DOMElement} subcard - The original subcard element visible on the main card.
 | 
			
		||||
     * @param {DOMElement} clonedSubcard - The cloned subcard that's going to be expanded.
 | 
			
		||||
     * @param {DOMElement} clonedArticle - The article part of the ClonedSubcard.
 | 
			
		||||
     * @param {Object} [{ eventElements = [], src = null }=[]]
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static _closeIndexCard(
 | 
			
		||||
        context,
 | 
			
		||||
        subcard,
 | 
			
		||||
        clonedSubcard,
 | 
			
		||||
        clonedArticle,
 | 
			
		||||
 | 
			
		||||
        { eventElements = [], src = null } = []
 | 
			
		||||
    ) {
 | 
			
		||||
        let indexbox = context.querySelector('.mainview')
 | 
			
		||||
        let padding = parseInt(this.css(indexbox, 'padding'))
 | 
			
		||||
 | 
			
		||||
        let globalPreviewRect = Card._getGlobalRect(subcard)
 | 
			
		||||
        let globalIndexCardRect = Card._getGlobalRect(indexbox)
 | 
			
		||||
 | 
			
		||||
        let scale = {
 | 
			
		||||
            x: globalPreviewRect.width / globalIndexCardRect.width,
 | 
			
		||||
            y: globalPreviewRect.height / globalIndexCardRect.height
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let titlebar = clonedSubcard.querySelector('.titlebar')
 | 
			
		||||
 | 
			
		||||
        let desiredBorderBottomWidth = parseInt(window.getComputedStyle(titlebar).borderBottomWidth)
 | 
			
		||||
        let localOrigin = Points.fromPageToNode(indexbox, Rect.getPosition(globalPreviewRect))
 | 
			
		||||
 | 
			
		||||
        //logging
 | 
			
		||||
        if (src) {
 | 
			
		||||
            let strparts = src.split('/')
 | 
			
		||||
@ -1442,15 +1526,14 @@ export default class Card {
 | 
			
		||||
        this._subcardChanged(context, true)
 | 
			
		||||
        this._enableCardCloseButton(context)
 | 
			
		||||
 | 
			
		||||
        let previewTitlebar = card.querySelector('.titlebar')
 | 
			
		||||
        let previewTitlebar = subcard.querySelector('.titlebar')
 | 
			
		||||
        let titlebarStyle = window.getComputedStyle(previewTitlebar)
 | 
			
		||||
        let titlebar = clone.querySelector('.titlebar')
 | 
			
		||||
 | 
			
		||||
        TweenLite.to(titlebar, this.animation.articleTransition, {
 | 
			
		||||
            height: parseInt(titlebarStyle.height)
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
        TweenLite.to(articleClone, this.animation.articleTransition / 2, {
 | 
			
		||||
        TweenLite.to(clonedArticle, this.animation.articleTransition / 2, {
 | 
			
		||||
            autoAlpha: 0
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
@ -1465,24 +1548,25 @@ export default class Card {
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        TweenLite.set(card, { autoAlpha: 1, css: { maxWidth } })
 | 
			
		||||
        TweenLite.to(clone, this.animation.articleTransition, {
 | 
			
		||||
        let maxWidth = this.css(subcard, 'max-width')
 | 
			
		||||
        TweenLite.set(subcard, { autoAlpha: 1, css: { maxWidth } })
 | 
			
		||||
        TweenLite.to(clonedSubcard, this.animation.articleTransition, {
 | 
			
		||||
            x: localOrigin.x - padding,
 | 
			
		||||
            y: localOrigin.y - padding,
 | 
			
		||||
            scaleX,
 | 
			
		||||
            scaleY,
 | 
			
		||||
            ease: ExpoScaleEase.config(1, scaleX),
 | 
			
		||||
            rotation: angle,
 | 
			
		||||
            scaleX: scale.x,
 | 
			
		||||
            scaleY: scale.y,
 | 
			
		||||
            ease: ExpoScaleEase.config(1, scale.x),
 | 
			
		||||
            // rotation: angle,
 | 
			
		||||
            onComplete: () => {
 | 
			
		||||
                // article.remove()
 | 
			
		||||
                TweenLite.to(clone, this.animation.fade, {
 | 
			
		||||
                TweenLite.to(clonedSubcard, this.animation.fade, {
 | 
			
		||||
                    //delay: 0.2,
 | 
			
		||||
                    autoAlpha: 0,
 | 
			
		||||
                    onComplete: () => {
 | 
			
		||||
                        if (editable) {
 | 
			
		||||
                        if (Card.isEditable()) {
 | 
			
		||||
                            mainController.popController()
 | 
			
		||||
                        }
 | 
			
		||||
                        clone.remove()
 | 
			
		||||
                        clonedSubcard.remove()
 | 
			
		||||
                    }
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
@ -1508,7 +1592,7 @@ export default class Card {
 | 
			
		||||
     * Tests if jQuery is properly included in the project.
 | 
			
		||||
     * Otherwise specific features may not work correctly (e.g. hyphenation)
 | 
			
		||||
     */
 | 
			
		||||
    _jQueryIsPresent() {
 | 
			
		||||
    static _isJQueryPresent() {
 | 
			
		||||
        let jQueryInitialized = typeof $ != 'undefined'
 | 
			
		||||
        if (!jQueryInitialized) console.error('No jQuery is provided. Specific features may fail.')
 | 
			
		||||
        return jQueryInitialized
 | 
			
		||||
@ -1542,7 +1626,7 @@ export default class Card {
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static openIndexCard(event, src) {
 | 
			
		||||
        //console.log("openIndexCard", src)
 | 
			
		||||
        console.log('openIndexCard', src)
 | 
			
		||||
        /*
 | 
			
		||||
         *   Called by the expandIndexCard(...)
 | 
			
		||||
         */
 | 
			
		||||
@ -1593,9 +1677,7 @@ export default class Card {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _enableCardCloseButton(context) {
 | 
			
		||||
        //console.log("ENABLE")
 | 
			
		||||
        let btn = this._selectCardCloseButton(context)
 | 
			
		||||
        //console.log(btn)
 | 
			
		||||
        btn.classList.remove('disabled')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -1706,11 +1788,9 @@ export default class Card {
 | 
			
		||||
     * @memberof Card
 | 
			
		||||
     */
 | 
			
		||||
    static postProcessResponseText(context, htmlString) {
 | 
			
		||||
        console.error('RUN POSTPROCESS')
 | 
			
		||||
        let editable = this.isEditable()
 | 
			
		||||
 | 
			
		||||
        htmlString = this._adjustRelativeLinks(htmlString)
 | 
			
		||||
        //console.log(htmlString)
 | 
			
		||||
        let parser = new DOMParser()
 | 
			
		||||
        let html = parser.parseFromString(htmlString, 'text/html')
 | 
			
		||||
        if (!editable) {
 | 
			
		||||
@ -1835,7 +1915,7 @@ export default class Card {
 | 
			
		||||
        this._setPopupSource(popup, source)
 | 
			
		||||
        context.popup = popup
 | 
			
		||||
 | 
			
		||||
        if (this.constructor._jQueryIsPresent()) {
 | 
			
		||||
        if (this._isJQueryPresent()) {
 | 
			
		||||
            //jquery hyphenate below
 | 
			
		||||
            console.log('hyphenated popup:', $('span').hyphenate('de'))
 | 
			
		||||
        }
 | 
			
		||||
@ -1908,6 +1988,14 @@ export default class Card {
 | 
			
		||||
        context.subcard = null
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static _subcardChanged(context, closed = false) {
 | 
			
		||||
        for (let [key, module] of Object.entries(context.module)) {
 | 
			
		||||
            if (module.subcardChanged) {
 | 
			
		||||
                module.subcardChanged(closed)
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static incrementZIndex(context) {
 | 
			
		||||
        if (!context.zIndex) context.zIndex = 0
 | 
			
		||||
        context.zIndex++
 | 
			
		||||
 | 
			
		||||
@ -2,6 +2,7 @@ export var CardPlugin = CardPlugin || {}
 | 
			
		||||
 | 
			
		||||
export class CardPluginBase {
 | 
			
		||||
    apply(context) {
 | 
			
		||||
        this.context = context
 | 
			
		||||
        if (this.verify(context)) {
 | 
			
		||||
            this.append(context)
 | 
			
		||||
            console.log('Plugin ' + this.name + ' was verified successfully.')
 | 
			
		||||
@ -91,6 +92,14 @@ export class CardPluginBase {
 | 
			
		||||
        }
 | 
			
		||||
        return requirements
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when the card is removed.
 | 
			
		||||
     * Can be used to cleanup the plugin.
 | 
			
		||||
     *
 | 
			
		||||
     * @memberof CardPluginBase
 | 
			
		||||
     */
 | 
			
		||||
    remove() {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CardPlugin.LightBox = class LightBox extends CardPluginBase {
 | 
			
		||||
@ -392,130 +401,135 @@ CardPlugin.Speech = class SpeechPlugin extends CardPluginBase {
 | 
			
		||||
        this.parentSelector = parentSelector
 | 
			
		||||
        this.interactionType = interactionType
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
        // We directly overwriting the function with a version that has a binded
 | 
			
		||||
        // reference to itself. Doing so provides an easy and reliable way to remove
 | 
			
		||||
        // the event listener using this function. -  SO
 | 
			
		||||
        this._domWasChanged = this._domWasChanged.bind(this)
 | 
			
		||||
 | 
			
		||||
     /* 
 | 
			
		||||
        /* 
 | 
			
		||||
        Speech doesn't stop when page is navigated.
 | 
			
		||||
        Therefore we do it manually here.
 | 
			
		||||
        */
 | 
			
		||||
       window.addEventListener('beforeunload', () => {
 | 
			
		||||
        window.speechSynthesis.cancel()
 | 
			
		||||
    })
 | 
			
		||||
        window.addEventListener('beforeunload', () => {
 | 
			
		||||
            window.speechSynthesis.cancel()
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
    // Binding the function beforehand ensures, that the end function is always the same.
 | 
			
		||||
    this._end = this._end.bind(this)
 | 
			
		||||
        // Binding the function beforehand ensures, that the end function is always the same.
 | 
			
		||||
        this._end = this._end.bind(this)
 | 
			
		||||
 | 
			
		||||
    this._setupUtterance()
 | 
			
		||||
    this.utterance.addEventListener('end', event => {
 | 
			
		||||
        this._end()
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get require() {
 | 
			
		||||
    return [CardPlugin.Ui]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
subcardChanged(closed) {
 | 
			
		||||
    if (this.cardActive) {
 | 
			
		||||
        this._updateText(closed)
 | 
			
		||||
        this._setupUtterance()
 | 
			
		||||
        this.utterance.addEventListener('end', event => {
 | 
			
		||||
            this._end()
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get cardActive() {
 | 
			
		||||
    return this.activeUtterance == this.utterance
 | 
			
		||||
}
 | 
			
		||||
    get require() {
 | 
			
		||||
        return [CardPlugin.Ui]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
_updateText(ignoreSubcard = false) {
 | 
			
		||||
    let node = this.context
 | 
			
		||||
    let subcard = this.context.querySelector('.mainview > .subcard')
 | 
			
		||||
    subcardChanged(closed) {
 | 
			
		||||
        if (this.cardActive) {
 | 
			
		||||
            this._updateText(closed)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ignoreSubcard) {
 | 
			
		||||
    get cardActive() {
 | 
			
		||||
        return this.activeUtterance == this.utterance
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _updateText(ignoreSubcard = false) {
 | 
			
		||||
        let node = this.context
 | 
			
		||||
        let subcard = node.querySelector('.mainview > .subcard')
 | 
			
		||||
 | 
			
		||||
        if (ignoreSubcard) {
 | 
			
		||||
            if (subcard != null) {
 | 
			
		||||
                let clone = node.cloneNode(true)
 | 
			
		||||
                let clonedSubcard = clone.querySelector('.mainview > .subcard')
 | 
			
		||||
                clonedSubcard.parentNode.removeChild(clonedSubcard)
 | 
			
		||||
                node = clone
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            if (subcard) {
 | 
			
		||||
                let clone = subcard.cloneNode(true)
 | 
			
		||||
                clone.querySelectorAll('figure').forEach(figure => {
 | 
			
		||||
                    figure.parentNode.removeChild(figure)
 | 
			
		||||
                })
 | 
			
		||||
 | 
			
		||||
                node = clone
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let id = this.context.getAttribute('data-id')
 | 
			
		||||
        let src = this.context.getAttribute('data-source')
 | 
			
		||||
        let subcardSource = null
 | 
			
		||||
        if (subcard != null) {
 | 
			
		||||
            let clone = node.cloneNode(true)
 | 
			
		||||
            let clonedSubcard = clone.querySelector('.mainview > .subcard')
 | 
			
		||||
            clonedSubcard.parentNode.removeChild(clonedSubcard)
 | 
			
		||||
            node = clone
 | 
			
		||||
            subcardSource = subcard.getAttribute('data-source')
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
        if (subcard) {
 | 
			
		||||
            let clone = subcard.cloneNode(true)
 | 
			
		||||
            clone.querySelectorAll('figure').forEach(figure => {
 | 
			
		||||
                figure.parentNode.removeChild(figure)
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            node = clone
 | 
			
		||||
        if (!window.speechSynthesis.speaking) {
 | 
			
		||||
            this._start(node)
 | 
			
		||||
            Logging.log(`Started speech on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
        } else if (this.cardActive && this._sameText(node)) {
 | 
			
		||||
            Logging.log(`Stopped speech on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
            this._stop()
 | 
			
		||||
        } else {
 | 
			
		||||
            Logging.log(`Updated Text on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
            this._stop()
 | 
			
		||||
                .then(() => {
 | 
			
		||||
                    this._start(node)
 | 
			
		||||
                })
 | 
			
		||||
                .catch(console.error)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let id = this.context.getAttribute('data-id')
 | 
			
		||||
    let src = this.context.getAttribute('data-source')
 | 
			
		||||
    let subcardSource = null
 | 
			
		||||
    if (subcard != null) {
 | 
			
		||||
        subcardSource = subcard.getAttribute('data-source')
 | 
			
		||||
    _sameText(node) {
 | 
			
		||||
        return this.utterance.text == this._cleanupText(node)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!window.speechSynthesis.speaking) {
 | 
			
		||||
        this._start(node)
 | 
			
		||||
        Logging.log(`Started speech on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
    } else if (this.cardActive && this._sameText(node)) {
 | 
			
		||||
        Logging.log(`Stopped speech on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
        this._stop()
 | 
			
		||||
    } else {
 | 
			
		||||
        Logging.log(`Updated Text on card: id:${id} - source: ${src} - subcard: ${subcardSource}`)
 | 
			
		||||
        this._stop()
 | 
			
		||||
            .then(() => {
 | 
			
		||||
                this._start(node)
 | 
			
		||||
            })
 | 
			
		||||
            .catch(console.error)
 | 
			
		||||
    _setupUtterance() {
 | 
			
		||||
        this.utterance = new SpeechSynthesisUtterance()
 | 
			
		||||
        this.utterance.lang = 'de-DE'
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_sameText(node) {
 | 
			
		||||
    return this.utterance.text == this._cleanupText(node)
 | 
			
		||||
}
 | 
			
		||||
    get require() {
 | 
			
		||||
        return [CardPlugin.Ui]
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
_setupUtterance() {
 | 
			
		||||
    this.utterance = new SpeechSynthesisUtterance()
 | 
			
		||||
    this.utterance.lang = 'de-DE'
 | 
			
		||||
}
 | 
			
		||||
    remove() {
 | 
			
		||||
        this.button = null
 | 
			
		||||
        this.context.removeEventListener('DOMNodeRemoved', this._domWasChanged)
 | 
			
		||||
        super.remove()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
 | 
			
		||||
remove() {
 | 
			
		||||
    this.button = null
 | 
			
		||||
    super.remove()
 | 
			
		||||
}
 | 
			
		||||
        InteractionMapper.on(this.interactionType, this.button, () => {
 | 
			
		||||
            this.speak()
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
append(context) {
 | 
			
		||||
    let container = context.querySelector(this.parentSelector)
 | 
			
		||||
    this.button = document.createElement('div')
 | 
			
		||||
    this.button.className = 'icon button ' + this.className
 | 
			
		||||
    container.appendChild(this.button)
 | 
			
		||||
        context.addEventListener('DOMNodeRemoved', this._domWasChanged)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    InteractionMapper.on(this.interactionType, this.button, () => {
 | 
			
		||||
        this.speak()
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    this.context.addEventListener('DOMNodeRemoved', event => {
 | 
			
		||||
        if (
 | 
			
		||||
    _domWasChanged(event) {
 | 
			
		||||
        if (this.context == null) this._stop()
 | 
			
		||||
        else if (
 | 
			
		||||
            this.context['lastSpeechNode'] == window.speechSynthesis['speechPluginNode'] &&
 | 
			
		||||
            event.target == this.context
 | 
			
		||||
        ) {
 | 
			
		||||
            this._stop()
 | 
			
		||||
        }
 | 
			
		||||
    })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ScatterCard
 | 
			
		||||
}
 | 
			
		||||
    _isSameNode(node) {
 | 
			
		||||
        return this.currentText == node.textContent
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
_isSameNode(node) {
 | 
			
		||||
    return this.currentText == node.textContent
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
speak() {
 | 
			
		||||
    /**
 | 
			
		||||
    speak() {
 | 
			
		||||
        /**
 | 
			
		||||
     * This is a little bit ugly, but imho the most elegant of all dirty solutions.
 | 
			
		||||
     *
 | 
			
		||||
5ht         * Within the plugins we have no knowledge of other cards and such. But must differentiate the
 | 
			
		||||
@ -529,63 +543,62 @@ speak() {
 | 
			
		||||
     * SO -17.07.19
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
    let activeNode = window.speechSynthesis['speechPluginNode']
 | 
			
		||||
    this._updateText()
 | 
			
		||||
}
 | 
			
		||||
        let activeNode = window.speechSynthesis['speechPluginNode']
 | 
			
		||||
        this._updateText()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
async _stop() {
 | 
			
		||||
    return new Promise(resolve => {
 | 
			
		||||
        if (this.activeUtterance) {
 | 
			
		||||
            this.activeUtterance.addEventListener('end', resolve, {
 | 
			
		||||
                once: true
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
    async _stop() {
 | 
			
		||||
        return new Promise(resolve => {
 | 
			
		||||
            if (this.activeUtterance) {
 | 
			
		||||
                this.activeUtterance.addEventListener('end', resolve, {
 | 
			
		||||
                    once: true
 | 
			
		||||
                })
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            window.speechSynthesis.cancel()
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get activeUtterance() {
 | 
			
		||||
        return window.speechSynthesis['speechPluginUtterance']
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _end() {
 | 
			
		||||
        window.speechSynthesis['speechPluginNode'] = null
 | 
			
		||||
        window.speechSynthesis['speechPluginUtterance'] = null
 | 
			
		||||
        this._deactivateButton()
 | 
			
		||||
        this.context.classList.remove('speech-plugin-is-reading')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _start(node) {
 | 
			
		||||
        window.speechSynthesis.cancel()
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
        window.speechSynthesis['speechPluginUtterance'] = this.utterance
 | 
			
		||||
        window.speechSynthesis['speechPluginNode'] = node
 | 
			
		||||
        this.context['lastSpeechNode'] = node
 | 
			
		||||
 | 
			
		||||
        let cleanText = this._cleanupText(node)
 | 
			
		||||
        this.utterance.text = cleanText
 | 
			
		||||
        window.speechSynthesis.speak(this.utterance)
 | 
			
		||||
        this._activateButton()
 | 
			
		||||
 | 
			
		||||
        this.context.classList.add('speech-plugin-is-reading')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _cleanupText(node) {
 | 
			
		||||
        let text = node.textContent
 | 
			
		||||
        text = this._removeShy(text)
 | 
			
		||||
        return text
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _removeShy(text) {
 | 
			
		||||
        return text.replace(/\u00AD/g, '')
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _activateButton() {
 | 
			
		||||
        if (this.button) this.button.classList.add('active')
 | 
			
		||||
    }
 | 
			
		||||
    _deactivateButton() {
 | 
			
		||||
        if (this.button) this.button.classList.remove('active')
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
get activeUtterance() {
 | 
			
		||||
    return window.speechSynthesis['speechPluginUtterance']
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_end() {
 | 
			
		||||
    window.speechSynthesis['speechPluginNode'] = null
 | 
			
		||||
    window.speechSynthesis['speechPluginUtterance'] = null
 | 
			
		||||
    this._deactivateButton()
 | 
			
		||||
    this.context.classList.remove('speech-plugin-is-reading')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_start(node) {
 | 
			
		||||
    window.speechSynthesis.cancel()
 | 
			
		||||
 | 
			
		||||
    window.speechSynthesis['speechPluginUtterance'] = this.utterance
 | 
			
		||||
    window.speechSynthesis['speechPluginNode'] = node
 | 
			
		||||
    this.context['lastSpeechNode'] = node
 | 
			
		||||
 | 
			
		||||
    let cleanText = this._cleanupText(node)
 | 
			
		||||
    this.utterance.text = cleanText
 | 
			
		||||
    window.speechSynthesis.speak(this.utterance)
 | 
			
		||||
    this._activateButton()
 | 
			
		||||
 | 
			
		||||
    this.context.classList.add('speech-plugin-is-reading')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_cleanupText(node) {
 | 
			
		||||
    let text = node.textContent
 | 
			
		||||
    text = this._removeShy(text)
 | 
			
		||||
    return text
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_removeShy(text) {
 | 
			
		||||
    return text.replace(/\u00AD/g, '')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
_activateButton() {
 | 
			
		||||
    if (this.button) this.button.classList.add('active')
 | 
			
		||||
}
 | 
			
		||||
_deactivateButton() {
 | 
			
		||||
    if (this.button) this.button.classList.remove('active')
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -18,6 +18,17 @@ export default class ScatterCard extends Card {
 | 
			
		||||
     * @memberof ScatterCard
 | 
			
		||||
     */
 | 
			
		||||
    static setup(context, htmlString, { basePath = './', modules = [] } = {}) {
 | 
			
		||||
        if (typeof context.scatter == 'undefined') {
 | 
			
		||||
            console.error(
 | 
			
		||||
                "You need to wrap the context inside a DOMScatter before executing the ScatterCard's setup function."
 | 
			
		||||
            )
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         *  This is required for the callback functions to work properly
 | 
			
		||||
         */
 | 
			
		||||
        window.ScatterCard = ScatterCard
 | 
			
		||||
 | 
			
		||||
        context.classList.add('info-card')
 | 
			
		||||
 | 
			
		||||
        this.relativePath = basePath
 | 
			
		||||
@ -38,29 +49,6 @@ export default class ScatterCard extends Card {
 | 
			
		||||
        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
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Removes the close listener from a card element.
 | 
			
		||||
     *
 | 
			
		||||
     * @static
 | 
			
		||||
     * @param {HTMLElement} element - Context of the Card.
 | 
			
		||||
     * @memberof ScatterCard
 | 
			
		||||
     */
 | 
			
		||||
    static removeOnCloseListener(element) {
 | 
			
		||||
        element.onClose = null
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a scatter for the card and applies the card to it,
 | 
			
		||||
     *
 | 
			
		||||
@ -95,15 +83,19 @@ export default class ScatterCard extends Card {
 | 
			
		||||
     * of the scatter.
 | 
			
		||||
     */
 | 
			
		||||
    static close(context) {
 | 
			
		||||
 | 
			
		||||
        Card.close(context)
 | 
			
		||||
 | 
			
		||||
        if (context['scatter']) {
 | 
			
		||||
            console.error('CLOSED CARD')
 | 
			
		||||
            context.scatter.close()
 | 
			
		||||
        } else {
 | 
			
		||||
        if (typeof context.scatter != 'undefined') context.scatter.close()
 | 
			
		||||
        else {
 | 
			
		||||
            console.error('Expected a scatter element to close!', this)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Card.close(context)
 | 
			
		||||
 | 
			
		||||
        // if (context['scatter']) {
 | 
			
		||||
        //     console.error('CLOSED CARD')
 | 
			
		||||
        //     context.scatter.close()
 | 
			
		||||
        // } else {
 | 
			
		||||
        //     console.error('Expected a scatter element to close!', this)
 | 
			
		||||
        // }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@ -116,14 +108,13 @@ export default class ScatterCard extends Card {
 | 
			
		||||
    static remove(context) {
 | 
			
		||||
        if (context['scatter']) {
 | 
			
		||||
            context.scatter = null
 | 
			
		||||
            console.error('REMOVED CARD')
 | 
			
		||||
        } else {
 | 
			
		||||
            console.error('Expected a scatter element to remove!', this)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Card.remove(context)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     *Utility function to create a fully functional card scatter.
 | 
			
		||||
     *
 | 
			
		||||
@ -135,7 +126,7 @@ export default class ScatterCard extends Card {
 | 
			
		||||
     * @returns
 | 
			
		||||
     * @memberof CardScatter
 | 
			
		||||
     */
 | 
			
		||||
    static loadAndCreateScatterCard(scatterContainer, item, { basePath = '../', modules = [], onClose = null } = {}) {
 | 
			
		||||
    static loadAndCreateScatterCard(scatterContainer, item, { basePath = '../', modules = [] } = {}) {
 | 
			
		||||
        console.log(basePath)
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            let url = basePath + '/' + item + '/index.html'
 | 
			
		||||
@ -147,7 +138,6 @@ export default class ScatterCard extends Card {
 | 
			
		||||
                        basePath,
 | 
			
		||||
                        modules
 | 
			
		||||
                    })
 | 
			
		||||
                    if (onClose) this.addOnCloseListener(element, onClose)
 | 
			
		||||
                    resolve(element)
 | 
			
		||||
                })
 | 
			
		||||
                .catch(e => reject(e))
 | 
			
		||||
 | 
			
		||||
@ -64,6 +64,8 @@
 | 
			
		||||
                })
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            createCard()
 | 
			
		||||
 | 
			
		||||
            function createCard() {
 | 
			
		||||
                const path = './example/01/index.html'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user