Cleaned up card.js

This commit is contained in:
Severin Opel 2019-10-15 10:07:29 +02:00
parent 66da13aed6
commit e50ea6af31
1 changed files with 70 additions and 45 deletions

View File

@ -1,8 +1,15 @@
'use strict'
/* globals Logging Power2 Points InteractionMapper mainController Popup saved popup Rect ExpoScaleEase*/
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. */
// eslint-disable-next-line no-unused-vars
const closeIconDataURI = `data:image/svg+xml;utf8,
<?xml version="1.0" encoding="utf-8" ?>
<!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" />
</svg>
`
// eslint-disable-next-line no-unused-vars
const resizeIconDataURI = `data:image/svg+xml;utf8,
<?xml version="1.0" encoding="utf-8" ?>
<!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" />
</svg>
`
// TODO: @ue Is this constant necessary?
const enableNearestNeighborTaps = false
/**
@ -33,7 +40,7 @@ const enableNearestNeighborTaps = false
*/
export default class Card {
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.
@ -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) {
//Remove all modules that are registered to the context.
for (let module of Object.values(context.module)) {
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) {
let context = this.getContext(event.target)
@ -107,21 +146,6 @@ export default class Card {
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.
*
@ -245,7 +269,7 @@ export default class Card {
*/
return html.replace(
/<\s*(a|video|img|image|circle)\s(.*?)(xlink:href|href|src)\s*=\s*["'](\..*?)["']\s*(.*?)>/g,
function(data) {
function() {
let path = that._getRelativePath(arguments[4])
const tag = `<${arguments[1]} ${arguments[2]} ${arguments[3]}="${path}" ${arguments[5]}>`
/* if (that.debug) */ console.log('Adjusted: ', tag)
@ -379,7 +403,6 @@ export default class Card {
* @memberof Card
*/
static _openPopup(context, src, position, content, options = {}) {
let maxWidth = null
if (this.debug) console.log('Card._openPopup', position)
//logging
@ -503,7 +526,7 @@ export default class Card {
popup.placeAt(position)
InteractionMapper.on(this.interactionType, popup.element, e => {
InteractionMapper.on(this.interactionType, popup.element, () => {
this._cleanup(context)
})
@ -520,6 +543,9 @@ export default class Card {
return promise
}
/**
* LEGACY but this may be required still for the editor
*/
static _overlayCleanup(context, overlay) {
/**
* The cleanup functionality is now covered by the _cleanup function.
@ -674,7 +700,7 @@ export default class Card {
*/
static _activateCorrespondingHighlights(context, node, parent) {
let highlightId = node.getAttribute('data-highlight-id')
// console.log("Request Highlight: " + highlightId)
if (this.debug) console.log('Request Highlight: ' + highlightId)
let correspondingHighlights = []
if (highlightId) {
@ -730,7 +756,7 @@ export default class Card {
}
static _calculateCenterRelativeTo(target, image) {
console.log('_calculateCenterRelativeTo', target, image)
// console.log('_calculateCenterRelativeTo', target, image)
let bbox = image.getBBox()
let width = bbox.width
let height = bbox.height
@ -741,7 +767,7 @@ export default class Card {
let x = cx.endsWith('%') ? (parseFloat(cx) / 100) * width : 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 }
}
@ -788,8 +814,6 @@ export default class Card {
let radius = parseFloat(node.getAttribute('r'))
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
@ -820,7 +844,7 @@ export default class Card {
.then(content => {
this._openPopup(context, src, local, content, {
highlight: node,
closeCommand: (popup, callback) => {
closeCommand: popup => {
this._overlayCleanup(context, overlay)
popup.remove()
}
@ -855,7 +879,7 @@ export default class Card {
let content = { html: html.body.innerHTML, selector }
resolve(content)
} 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
// captured from the whole subcard.
InteractionMapper.on(this.interactionType, zoomedFig, event => {
InteractionMapper.on(this.interactionType, zoomedFig, () => {
this._cleanup(wrapper)
})
@ -1147,7 +1171,7 @@ export default class Card {
iconClone.src = iconClone.src.replace('info.svg', 'close.svg')
iconClone.style.zIndex = 1000
iconClone.classList.add('zoomed-icon')
iconClone.onclick = event => {
iconClone.onclick = () => {
zoomIcon.style.display = savedDisplay
iconClone.remove()
zoomIcon.setAttribute('onclick', savedOnClick)
@ -1185,7 +1209,7 @@ export default class Card {
}
}
}
zoomable.onmouseup = event => {
zoomable.onmouseup = () => {
zoomable.dragging = false
}
@ -1295,7 +1319,7 @@ export default class Card {
/* Removes the 'default' cleanup on the card */
clone.removeAttribute('onclick')
InteractionMapper.on(this.interactionType, clone, event => {
InteractionMapper.on(this.interactionType, clone, () => {
this._cleanup(context)
})
@ -1345,7 +1369,6 @@ export default class Card {
}
if (this.dynamicHeight) {
let targetHeight = subcardContent.offsetHeight
subcardContent.classList.add('dynamic-height')
/**
* Scale the content from 100% to it's target size.
@ -1353,6 +1376,8 @@ export default class Card {
// TweenLite.set(subcardContent, {
// height: "100%"
// })
//
// let targetHeight = subcardContent.offsetHeight
// TweenLite.to(subcardContent, Card.animation.articleTransition, {
// height: targetHeight + "px"
// })
@ -1425,7 +1450,6 @@ export default class Card {
if (iconClone.tagName == 'img') {
iconClone.src = iconClone.src.replace('info.svg', 'close.svg')
}
//console.log("ICON: ", iconClone)
iconClone.classList.remove('info')
iconClone.classList.add('close', 'view-button', 'transparent-background')
@ -1488,7 +1512,7 @@ export default class Card {
clonedSubcard,
clonedArticle,
{ eventElements = [], src = null } = []
{ src = null } = []
) {
let indexbox = context.querySelector('.mainview')
let padding = parseInt(this.css(indexbox, 'padding'))
@ -1511,7 +1535,7 @@ export default class Card {
let strparts = src.split('/')
let cardID = strparts[strparts.length - 2]
let cardName = strparts[strparts.length - 1]
strparts = card.className.split(' ')
strparts = context.className.split(' ')
let cardType = strparts[1]
let msg = 'Card: ' + cardID + ': closeTopic: ' + cardType + ', ' + cardName
console.log('Logging:', msg)
@ -1540,9 +1564,10 @@ export default class Card {
}
if (this.dynamicHeight) {
TweenLite.to(subcardContent, this.animation.articleTransition, {
height: '100%'
})
console.error('Dynamic height is not implemented yet.')
// TweenLite.to(subcardContent, this.animation.articleTransition, {
// height: '100%'
// })
}
let maxWidth = this.css(subcard, 'max-width')
@ -1623,14 +1648,14 @@ export default class Card {
* @memberof Card
*/
static openIndexCard(event, src) {
console.log('openIndexCard', src)
if (this.debug) console.log('openIndexCard', src)
/*
* Called by the expandIndexCard(...)
*/
let target = event.target
const saveCallback = 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.
target.setAttribute('onclick', handler)
@ -1986,7 +2011,7 @@ export default class Card {
}
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) {
module.subcardChanged(closed)
}
@ -2043,7 +2068,7 @@ export default class Card {
}
/**
* Unregisters all events on the infocard.
* Unregister all events on the infocard.
*
*
* @static
@ -2057,7 +2082,7 @@ export default class Card {
}
Card.id = 0
Card.debug = true
Card.debug = false
Card._relativePath = ''
Card.scatterContainer = null
Card.interactionType = 'tap'