Cleaned up card.js
This commit is contained in:
parent
66da13aed6
commit
e50ea6af31
115
lib/card/card.js
115
lib/card/card.js
@ -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'
|
||||||
|
Loading…
Reference in New Issue
Block a user