Cleaned up card.js

This commit is contained in:
Severin Opel 2019-10-15 10:07:29 +02:00
parent 66da13aed6
commit e50ea6af31

View File

@ -1,8 +1,15 @@
'use strict' 'use strict'
/* globals Logging Power2 Points InteractionMapper mainController Popup saved popup Rect ExpoScaleEase*/
import Highlight from './highlight.js' import Highlight from './highlight.js'
/*
* TODO: @ue are these 2 values still necessary?
*/
/** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */ /** To avoid problems with relative URL paths, we use inline data URI to load svg icons. */
// eslint-disable-next-line no-unused-vars
const closeIconDataURI = `data:image/svg+xml;utf8, const closeIconDataURI = `data:image/svg+xml;utf8,
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
@ -12,7 +19,7 @@ const closeIconDataURI = `data:image/svg+xml;utf8,
<line x1="80" y1="20" x2="20" y2="80" stroke="black" stroke-width="8" /> <line x1="80" y1="20" x2="20" y2="80" stroke="black" stroke-width="8" />
</svg> </svg>
` `
// eslint-disable-next-line no-unused-vars
const resizeIconDataURI = `data:image/svg+xml;utf8, const resizeIconDataURI = `data:image/svg+xml;utf8,
<?xml version="1.0" encoding="utf-8" ?> <?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
@ -22,7 +29,7 @@ const resizeIconDataURI = `data:image/svg+xml;utf8,
<line x1="40" y1="80" x2="80" y2="40" stroke="lightgray" stroke-width="8" /> <line x1="40" y1="80" x2="80" y2="40" stroke="lightgray" stroke-width="8" />
</svg> </svg>
` `
// TODO: @ue Is this constant necessary?
const enableNearestNeighborTaps = false const enableNearestNeighborTaps = false
/** /**
@ -33,7 +40,7 @@ const enableNearestNeighborTaps = false
*/ */
export default class Card { export default class Card {
static setup(context, modules = []) { static setup(context, modules = []) {
console.log('Setup Card...', modules) if (this.debug) console.log('Setup Card...', modules)
/** /**
* This is required for the callback functions to work properly. * This is required for the callback functions to work properly.
@ -57,13 +64,45 @@ export default class Card {
}) })
} }
/**
* Removes the context and all registered components of the card.
*
* @static
* @param {DOMElement} context - The DOMElement representing the card.
* @memberof Card
*/
static remove(context) { static remove(context) {
//Remove all modules that are registered to the context.
for (let module of Object.values(context.module)) { for (let module of Object.values(context.module)) {
const moduleHasRemoveFunction = typeof module.remove === 'function' const moduleHasRemoveFunction = typeof module.remove === 'function'
if (moduleHasRemoveFunction) module.remove() if (moduleHasRemoveFunction) {
module.remove()
}
}
// Remove the context itself.
if (context.parentNode != null) {
context.parentNode.removeChild(context)
} else {
console.warn('Tried removing card but it has already been removed.')
} }
} }
/**
* Closes the card when an event happens on the card.
* Either the card is removed or the onClose callback is called.
*
* NOTE: Make sure to remove the card manually, when using the onClose callback!
*
* INFO: I just revisited this function and was wondering, why it takes the event as
* parameter instead of the context. The problem is that the card template defines
* the functions inside the HTML. When loaded, the HTML attributes need to be adjusted
* and the functions are overwritten. Using during the post processing step withing the postProcessResponseText function.
*
* @static
* @param {Event} event - event triggered on the car
* @memberof Card
*/
static close(event) { static close(event) {
let context = this.getContext(event.target) let context = this.getContext(event.target)
@ -107,21 +146,6 @@ export default class Card {
context.onClose = null context.onClose = null
} }
/**
*
*
* @static
* @param {*} event
* @memberof Card
*/
static remove(context) {
if (context.parentNode != null) {
context.parentNode.removeChild(context)
} else {
console.error('Tried removing card but it was already removed.')
}
}
/** /**
* Replaces a set of attributes using a provided function. * Replaces a set of attributes using a provided function.
* *
@ -245,7 +269,7 @@ export default class Card {
*/ */
return html.replace( return html.replace(
/<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g, /<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g,
function(data) { function() {
let path = that._getRelativePath(arguments[4]) let path = that._getRelativePath(arguments[4])
const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>` const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>`
/* if (that.debug) */ console.log('Adjusted: ', tag) /* if (that.debug) */ console.log('Adjusted: ', tag)
@ -379,7 +403,6 @@ export default class Card {
* @memberof Card * @memberof Card
*/ */
static _openPopup(context, src, position, content, options = {}) { static _openPopup(context, src, position, content, options = {}) {
let maxWidth = null
if (this.debug) console.log('Card._openPopup', position) if (this.debug) console.log('Card._openPopup', position)
//logging //logging
@ -503,7 +526,7 @@ export default class Card {
popup.placeAt(position) popup.placeAt(position)
InteractionMapper.on(this.interactionType, popup.element, e => { InteractionMapper.on(this.interactionType, popup.element, () => {
this._cleanup(context) this._cleanup(context)
}) })
@ -520,6 +543,9 @@ export default class Card {
return promise return promise
} }
/**
* LEGACY but this may be required still for the editor
*/
static _overlayCleanup(context, overlay) { static _overlayCleanup(context, overlay) {
/** /**
* The cleanup functionality is now covered by the _cleanup function. * The cleanup functionality is now covered by the _cleanup function.
@ -674,7 +700,7 @@ export default class Card {
*/ */
static _activateCorrespondingHighlights(context, node, parent) { static _activateCorrespondingHighlights(context, node, parent) {
let highlightId = node.getAttribute('data-highlight-id') let highlightId = node.getAttribute('data-highlight-id')
// console.log("Request Highlight: " + highlightId) if (this.debug) console.log('Request Highlight: ' + highlightId)
let correspondingHighlights = [] let correspondingHighlights = []
if (highlightId) { if (highlightId) {
@ -730,7 +756,7 @@ export default class Card {
} }
static _calculateCenterRelativeTo(target, image) { static _calculateCenterRelativeTo(target, image) {
console.log('_calculateCenterRelativeTo', target, image) // console.log('_calculateCenterRelativeTo', target, image)
let bbox = image.getBBox() let bbox = image.getBBox()
let width = bbox.width let width = bbox.width
let height = bbox.height let height = bbox.height
@ -741,7 +767,7 @@ export default class Card {
let x = cx.endsWith('%') ? (parseFloat(cx) / 100) * width : cx let x = cx.endsWith('%') ? (parseFloat(cx) / 100) * width : cx
let y = cy.endsWith('%') ? (parseFloat(cy) / 100) * height : cx let y = cy.endsWith('%') ? (parseFloat(cy) / 100) * height : cx
console.log({ x, y, width, height, radius }) // console.log({ x, y, width, height, radius })
return { x, y } return { x, y }
} }
@ -788,8 +814,6 @@ export default class Card {
let radius = parseFloat(node.getAttribute('r')) let radius = parseFloat(node.getAttribute('r'))
let svgRoot = node.closest('svg') let svgRoot = node.closest('svg')
let image = svgRoot.querySelector('image')
//let position = Card._calculateCenterRelativeTo(node, image)
/* /*
As the popup is appended directly to the card. We have to As the popup is appended directly to the card. We have to
@ -820,7 +844,7 @@ export default class Card {
.then(content => { .then(content => {
this._openPopup(context, src, local, content, { this._openPopup(context, src, local, content, {
highlight: node, highlight: node,
closeCommand: (popup, callback) => { closeCommand: popup => {
this._overlayCleanup(context, overlay) this._overlayCleanup(context, overlay)
popup.remove() popup.remove()
} }
@ -855,7 +879,7 @@ export default class Card {
let content = { html: html.body.innerHTML, selector } let content = { html: html.body.innerHTML, selector }
resolve(content) resolve(content)
} else { } else {
reject(` Popup request failed (Code: ${xhr.status}): Could not load resource: ${src}`) reject(` Popup request failed (Code: ${xhr.status}): Could not load resource: ${source}`)
} }
} }
} }
@ -1031,7 +1055,7 @@ export default class Card {
// It's just an indicator that an action is possible. The click must be // It's just an indicator that an action is possible. The click must be
// captured from the whole subcard. // captured from the whole subcard.
InteractionMapper.on(this.interactionType, zoomedFig, event => { InteractionMapper.on(this.interactionType, zoomedFig, () => {
this._cleanup(wrapper) this._cleanup(wrapper)
}) })
@ -1147,7 +1171,7 @@ export default class Card {
iconClone.src = iconClone.src.replace('info.svg', 'close.svg') iconClone.src = iconClone.src.replace('info.svg', 'close.svg')
iconClone.style.zIndex = 1000 iconClone.style.zIndex = 1000
iconClone.classList.add('zoomed-icon') iconClone.classList.add('zoomed-icon')
iconClone.onclick = event => { iconClone.onclick = () => {
zoomIcon.style.display = savedDisplay zoomIcon.style.display = savedDisplay
iconClone.remove() iconClone.remove()
zoomIcon.setAttribute('onclick', savedOnClick) zoomIcon.setAttribute('onclick', savedOnClick)
@ -1185,7 +1209,7 @@ export default class Card {
} }
} }
} }
zoomable.onmouseup = event => { zoomable.onmouseup = () => {
zoomable.dragging = false zoomable.dragging = false
} }
@ -1295,7 +1319,7 @@ export default class Card {
/* Removes the 'default' cleanup on the card */ /* Removes the 'default' cleanup on the card */
clone.removeAttribute('onclick') clone.removeAttribute('onclick')
InteractionMapper.on(this.interactionType, clone, event => { InteractionMapper.on(this.interactionType, clone, () => {
this._cleanup(context) this._cleanup(context)
}) })
@ -1345,7 +1369,6 @@ export default class Card {
} }
if (this.dynamicHeight) { if (this.dynamicHeight) {
let targetHeight = subcardContent.offsetHeight
subcardContent.classList.add('dynamic-height') subcardContent.classList.add('dynamic-height')
/** /**
* Scale the content from 100% to it's target size. * Scale the content from 100% to it's target size.
@ -1353,6 +1376,8 @@ export default class Card {
// TweenLite.set(subcardContent, { // TweenLite.set(subcardContent, {
// height: "100%" // height: "100%"
// }) // })
//
// let targetHeight = subcardContent.offsetHeight
// TweenLite.to(subcardContent, Card.animation.articleTransition, { // TweenLite.to(subcardContent, Card.animation.articleTransition, {
// height: targetHeight + "px" // height: targetHeight + "px"
// }) // })
@ -1425,7 +1450,6 @@ export default class Card {
if (iconClone.tagName == 'img') { if (iconClone.tagName == 'img') {
iconClone.src = iconClone.src.replace('info.svg', 'close.svg') iconClone.src = iconClone.src.replace('info.svg', 'close.svg')
} }
//console.log("ICON: ", iconClone)
iconClone.classList.remove('info') iconClone.classList.remove('info')
iconClone.classList.add('close', 'view-button', 'transparent-background') iconClone.classList.add('close', 'view-button', 'transparent-background')
@ -1488,7 +1512,7 @@ export default class Card {
clonedSubcard, clonedSubcard,
clonedArticle, clonedArticle,
{ eventElements = [], src = null } = [] { src = null } = []
) { ) {
let indexbox = context.querySelector('.mainview') let indexbox = context.querySelector('.mainview')
let padding = parseInt(this.css(indexbox, 'padding')) let padding = parseInt(this.css(indexbox, 'padding'))
@ -1511,7 +1535,7 @@ export default class Card {
let strparts = src.split('/') let strparts = src.split('/')
let cardID = strparts[strparts.length - 2] let cardID = strparts[strparts.length - 2]
let cardName = strparts[strparts.length - 1] let cardName = strparts[strparts.length - 1]
strparts = card.className.split(' ') strparts = context.className.split(' ')
let cardType = strparts[1] let cardType = strparts[1]
let msg = 'Card: ' + cardID + ': closeTopic: ' + cardType + ', ' + cardName let msg = 'Card: ' + cardID + ': closeTopic: ' + cardType + ', ' + cardName
console.log('Logging:', msg) console.log('Logging:', msg)
@ -1540,9 +1564,10 @@ export default class Card {
} }
if (this.dynamicHeight) { if (this.dynamicHeight) {
TweenLite.to(subcardContent, this.animation.articleTransition, { console.error('Dynamic height is not implemented yet.')
height: '100%' // TweenLite.to(subcardContent, this.animation.articleTransition, {
}) // height: '100%'
// })
} }
let maxWidth = this.css(subcard, 'max-width') let maxWidth = this.css(subcard, 'max-width')
@ -1623,14 +1648,14 @@ export default class Card {
* @memberof Card * @memberof Card
*/ */
static openIndexCard(event, src) { static openIndexCard(event, src) {
console.log('openIndexCard', src) if (this.debug) console.log('openIndexCard', src)
/* /*
* Called by the expandIndexCard(...) * Called by the expandIndexCard(...)
*/ */
let target = event.target let target = event.target
const saveCallback = url => { const saveCallback = url => {
let handler = `Card.openIndexCard(event, '${url}')` let handler = `Card.openIndexCard(event, '${url}')`
console.log('File has changed', target, handler) if (this.debug) console.log('File has changed', target, handler)
//TODO If this is required, it should be accessing the interaction type. //TODO If this is required, it should be accessing the interaction type.
target.setAttribute('onclick', handler) target.setAttribute('onclick', handler)
@ -1986,7 +2011,7 @@ export default class Card {
} }
static _subcardChanged(context, closed = false) { static _subcardChanged(context, closed = false) {
for (let [key, module] of Object.entries(context.module)) { for (let module of Object.values(context.module)) {
if (module.subcardChanged) { if (module.subcardChanged) {
module.subcardChanged(closed) module.subcardChanged(closed)
} }
@ -2043,7 +2068,7 @@ export default class Card {
} }
/** /**
* Unregisters all events on the infocard. * Unregister all events on the infocard.
* *
* *
* @static * @static
@ -2057,7 +2082,7 @@ export default class Card {
} }
Card.id = 0 Card.id = 0
Card.debug = true Card.debug = false
Card._relativePath = '' Card._relativePath = ''
Card.scatterContainer = null Card.scatterContainer = null
Card.interactionType = 'tap' Card.interactionType = 'tap'