Added support for DOM cards.
This commit is contained in:
Vendored
+12
-127
@@ -7003,6 +7003,7 @@
|
||||
}
|
||||
|
||||
|
||||
|
||||
class DOMScatter extends AbstractScatter {
|
||||
constructor(
|
||||
element,
|
||||
@@ -7028,7 +7029,7 @@
|
||||
width = null, // required
|
||||
height = null, // required
|
||||
resizable = false,
|
||||
clickOnTap = false,
|
||||
tapDelegate = null,
|
||||
triggerSVGClicks = false,
|
||||
allowClickDistance = 44,
|
||||
verbose = true,
|
||||
@@ -7085,8 +7086,7 @@
|
||||
this.height = height;
|
||||
this.throwVisibility = Math.min(width, height, throwVisibility);
|
||||
this.container = container;
|
||||
this.clickOnTap = clickOnTap;
|
||||
this.triggerSVGClicks = triggerSVGClicks;
|
||||
this.tapDelegate = tapDelegate;
|
||||
this.scale = startScale;
|
||||
this.rotationDegrees = this.startRotationDegrees;
|
||||
this.transformOrigin = transformOrigin;
|
||||
@@ -7100,8 +7100,7 @@
|
||||
transformOrigin: transformOrigin
|
||||
};
|
||||
this.tapNodes = new Map();
|
||||
this.allowClickDistance = allowClickDistance;
|
||||
|
||||
|
||||
// For tweenlite we need initial values in _gsTransform
|
||||
TweenLite.set(element, this.initialValues);
|
||||
this.onResize = onResize;
|
||||
@@ -7133,24 +7132,8 @@
|
||||
});
|
||||
this.resizeButton = button;
|
||||
}
|
||||
if (clickOnTap) {
|
||||
/* Since the tap triggers a synthetic click event
|
||||
we must prevent the original trusted click event which
|
||||
is also dispatched by the system.
|
||||
*/
|
||||
element.addEventListener('click', event => {
|
||||
/* Currently we cannot send synthesized click events to SVG elements without unwanted side effects.
|
||||
Therefore we make an exception and let the original click event through.
|
||||
*/
|
||||
if (event.target.ownerSVGElement) {
|
||||
if (this.triggerSVGClicks) {
|
||||
return
|
||||
}
|
||||
}
|
||||
else if (event.isTrusted) {
|
||||
Events$1.stop(event);
|
||||
}
|
||||
}, true);
|
||||
if (tapDelegate) {
|
||||
tapDelegate.handleClicks();
|
||||
}
|
||||
container.add(this);
|
||||
}
|
||||
@@ -7312,110 +7295,12 @@
|
||||
}
|
||||
|
||||
onTap(event, interaction, point) {
|
||||
|
||||
if (this.clickOnTap) {
|
||||
let directNode = document.elementFromPoint(event.clientX, event.clientY);
|
||||
console.log("onTap", event);
|
||||
if (this.isClickable(directNode)) {
|
||||
directNode.click();
|
||||
}
|
||||
else {
|
||||
let nearestNode = this.nearestClickable(event);
|
||||
if (this.isClickable(nearestNode)) {
|
||||
/* https://stackoverflow.com/questions/49564905/is-it-possible-to-use-click-function-on-svg-tags-i-tried-element-click-on-a
|
||||
proposes the dispatchEvent solution. But this leads to problems in flippable.html hiding the back page.
|
||||
Therefore we use the original click event (see constructor).
|
||||
*/
|
||||
if (nearestNode.tagName == 'svg') {
|
||||
let handler = this.tapNodes.get(nearestNode);
|
||||
console.log("Clicking near SVG: to be done", handler);
|
||||
if (this.triggerSVGClicks)
|
||||
nearestNode.dispatchEvent(new Event('click'));
|
||||
return
|
||||
}
|
||||
console.log("nearestNode clicked");
|
||||
nearestNode.click();
|
||||
}
|
||||
}
|
||||
if (this.tapDelegate) {
|
||||
Events$1.stop(event);
|
||||
this.tapDelegate.tap(event, "scatter");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a click or tap behavior to the node. Uses
|
||||
* either the scatter clickOnTap version which requires click handlers
|
||||
* or uses the hammer.js driven tap handler.
|
||||
*
|
||||
* @param {*} node
|
||||
* @param {*} handler
|
||||
* @memberof DOMScatter
|
||||
*/
|
||||
|
||||
addTapListener(node, handler) {
|
||||
if (this.clickOnTap) {
|
||||
node.addEventListener('click', handler);
|
||||
this.tapNodes.set(node, handler);
|
||||
}
|
||||
else {
|
||||
InteractionMapper$1.on('tap', node, handler);
|
||||
}
|
||||
}
|
||||
|
||||
isClickable(node) {
|
||||
if (node == null)
|
||||
return false
|
||||
if (node.tagName == 'A')
|
||||
return true
|
||||
if (node.hasAttribute("onclick"))
|
||||
return true
|
||||
if (this.tapNodes.has(node))
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all clickable nodes.
|
||||
* Unfortunately we cannot search for all nodes with an attached 'click' event listener
|
||||
* See https://stackoverflow.com/questions/11455515/how-to-check-whether-dynamically-attached-event-listener-exists-or-not
|
||||
* Therefore we can only detect the following standard cases:
|
||||
* I. All clickable objects like clickables
|
||||
* II. Objects that have been attached a click handler by the scatter itself via
|
||||
*/
|
||||
clickableNodes() {
|
||||
let result = [];
|
||||
for (let node of this.element.querySelectorAll("*")) {
|
||||
if (this.isClickable(node))
|
||||
result.push(node);
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
nearestClickable(event) {
|
||||
let element = this.element;
|
||||
let clickables = this.clickableNodes();
|
||||
let globalClick = (event.center) ? event.center : { x: event.x, y: event.y };
|
||||
let localClick = Points.fromPageToNode(element, globalClick);
|
||||
|
||||
let clickRects = clickables.map(link => {
|
||||
let rect = link.getBoundingClientRect();
|
||||
let topLeft = Points.fromPageToNode(element, rect);
|
||||
let center = Points.fromPageToNode(element, { x: rect.x + rect.width / 2, y: rect.y + rect.height / 2 });
|
||||
return { x: topLeft.x, y: topLeft.y, width: rect.width, height: rect.height, center, link }
|
||||
});
|
||||
|
||||
let distances = [];
|
||||
clickRects.forEach(rect => {
|
||||
let distance = Points.distanceToRect(localClick, rect);
|
||||
distances.push(parseInt(distance));
|
||||
});
|
||||
|
||||
let closestClickIndex = distances.indexOf(Math.min(...distances));
|
||||
let closestClickable = clickables[closestClickIndex];
|
||||
if (distances[closestClickIndex] < this.allowClickDistance) {
|
||||
return closestClickable
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
isDescendant(parent, child) {
|
||||
let node = child.parentNode;
|
||||
while (node != null) {
|
||||
@@ -7601,7 +7486,7 @@
|
||||
translatable = true,
|
||||
scalable = true,
|
||||
rotatable = true,
|
||||
clickOnTap = false,
|
||||
tapDelegateFactory = null,
|
||||
onFront = null,
|
||||
onBack = null,
|
||||
onClose = null,
|
||||
@@ -7621,7 +7506,7 @@
|
||||
this.translatable = translatable;
|
||||
this.scalable = scalable;
|
||||
this.rotatable = rotatable;
|
||||
this.clickOnTap = clickOnTap;
|
||||
this.tapDelegateFactory = tapDelegateFactory;
|
||||
this.onFrontFlipped = onFront;
|
||||
this.onBackFlipped = onBack;
|
||||
this.onClose = onClose;
|
||||
@@ -7677,7 +7562,7 @@
|
||||
scalable: this.scalable,
|
||||
rotatable: this.rotatable,
|
||||
overdoScaling: this.overdoScaling,
|
||||
clickOnTap: this.clickOnTap
|
||||
tapDelegate: (this.tapDelegateFactory) ? this.tapDelegateFactory(this.cardWrapper) : null
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user