1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-08-07 14:23:53 +00:00

Eventcatcher: Fixed FF and IE bugs, added stopPropagation attribute (#5711)

This commit is contained in:
Saq Imtiaz 2021-05-21 10:43:20 +02:00 committed by GitHub
parent 1ddc3ab037
commit 270ead4701
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 22 deletions

View File

@ -22,6 +22,10 @@ exports.domContains = function(a,b) {
!!(a.compareDocumentPosition(b) & 16); !!(a.compareDocumentPosition(b) & 16);
}; };
exports.domMatchesSelector = function(node,selector) {
return node.matches ? node.matches(selector) : node.msMatchesSelector(selector);
};
exports.removeChildren = function(node) { exports.removeChildren = function(node) {
while(node.hasChildNodes()) { while(node.hasChildNodes()) {
node.removeChild(node.firstChild); node.removeChild(node.firstChild);

View File

@ -47,38 +47,46 @@ EventWidget.prototype.render = function(parent,nextSibling) {
domNode.addEventListener(type,function(event) { domNode.addEventListener(type,function(event) {
var selector = self.getAttribute("selector"), var selector = self.getAttribute("selector"),
actions = self.getAttribute("actions-"+type), actions = self.getAttribute("actions-"+type),
stopPropagation = self.getAttribute("stopPropagation","onaction"),
selectedNode = event.target, selectedNode = event.target,
selectedNodeRect, selectedNodeRect,
catcherNodeRect, catcherNodeRect,
variables = {}; variables = {};
// Firefox can fire dragover and dragenter events on text nodes instead of their parents
if(selectedNode.nodeType === 3) {
selectedNode = selectedNode.parentNode;
}
if(selector) { if(selector) {
// Search ancestors for a node that matches the selector // Search ancestors for a node that matches the selector
while(!selectedNode.matches(selector) && selectedNode !== domNode) { while(!$tw.utils.domMatchesSelector(selectedNode,selector) && selectedNode !== domNode) {
selectedNode = selectedNode.parentNode; selectedNode = selectedNode.parentNode;
} }
// If we found one, copy the attributes as variables, otherwise exit // If we found one, copy the attributes as variables, otherwise exit
if(selectedNode.matches(selector)) { if($tw.utils.domMatchesSelector(selectedNode,selector)) {
$tw.utils.each(selectedNode.attributes,function(attribute) { // Only set up variables if we have actions to invoke
variables["dom-" + attribute.name] = attribute.value.toString(); if(actions) {
}); $tw.utils.each(selectedNode.attributes,function(attribute) {
//Add a variable with a popup coordinate string for the selected node variables["dom-" + attribute.name] = attribute.value.toString();
variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")"; });
//Add a variable with a popup coordinate string for the selected node
//Add variables for offset of selected node variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
//Add variables for event X and Y position relative to selected node //Add variables for offset of selected node
selectedNodeRect = selectedNode.getBoundingClientRect(); variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();
variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString(); variables["tv-selectednode-posy"] = selectedNode.offsetTop.toString();
variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString(); variables["tv-selectednode-width"] = selectedNode.offsetWidth.toString();
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
//Add variables for event X and Y position relative to event catcher node //Add variables for event X and Y position relative to selected node
catcherNodeRect = self.domNode.getBoundingClientRect(); selectedNodeRect = selectedNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString(); variables["event-fromselected-posx"] = (event.clientX - selectedNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString(); variables["event-fromselected-posy"] = (event.clientY - selectedNodeRect.top).toString();
//Add variables for event X and Y position relative to event catcher node
catcherNodeRect = self.domNode.getBoundingClientRect();
variables["event-fromcatcher-posx"] = (event.clientX - catcherNodeRect.left).toString();
variables["event-fromcatcher-posy"] = (event.clientY - catcherNodeRect.top).toString();
}
} else { } else {
return false; return false;
} }
@ -106,6 +114,8 @@ EventWidget.prototype.render = function(parent,nextSibling) {
variables["event-detail"] = event.detail.toString(); variables["event-detail"] = event.detail.toString();
} }
self.invokeActionString(actions,self,event,variables); self.invokeActionString(actions,self,event,variables);
}
if((actions && stopPropagation === "onaction") || stopPropagation === "always") {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
return true; return true;

View File

@ -1,5 +1,5 @@
created: 20201123113532200 created: 20201123113532200
modified: 20201202200719126 modified: 20210520162813234
tags: Widgets tags: Widgets
title: EventCatcherWidget title: EventCatcherWidget
type: text/vnd.tiddlywiki type: text/vnd.tiddlywiki
@ -30,6 +30,7 @@ The content of the `<$eventcatcher>` widget is displayed normally.
|actions-* |Action strings to be invoked when a matching event is trapped. Each event is mapped to an action attribute name of the form <code>actions-<em>event</em></code> where <code><em>event</em></code> represents the type of the event. For example: `actions-click` or `actions-dblclick` | |actions-* |Action strings to be invoked when a matching event is trapped. Each event is mapped to an action attribute name of the form <code>actions-<em>event</em></code> where <code><em>event</em></code> represents the type of the event. For example: `actions-click` or `actions-dblclick` |
|tag |Optional. The HTML element the widget creates to capture the events, defaults to:<br>» `span` when parsed in inline-mode<br>» `div` when parsed in block-mode | |tag |Optional. The HTML element the widget creates to capture the events, defaults to:<br>» `span` when parsed in inline-mode<br>» `div` when parsed in block-mode |
|class |Optional. A CSS class name (or names) to be assigned to the widget HTML element | |class |Optional. A CSS class name (or names) to be assigned to the widget HTML element |
|stopPropagation |<<.from-version "5.1.24">> Optional. Set to "always" to always stop event propagation even if there are no corresponding actions to invoke, "never" to never stop event propagation, or the default value "onaction" with which event propagation is only stopped if there are corresponding actions that are invoked. |
! Variables ! Variables