1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-01-26 08:56:52 +00:00

feat: redirect tm-focus-selector event to check parent or sibling

This commit is contained in:
linonetwo 2023-09-16 04:45:07 +08:00
parent b956e72536
commit 3d8ade3ebe
6 changed files with 65 additions and 3 deletions

View File

@ -2674,6 +2674,20 @@ $tw.hooks.addHook = function(hookName,definition) {
} }
}; };
/*
Delete hooks from the hashmap
*/
$tw.hooks.removeHook = function(hookName,definition) {
if($tw.utils.hop($tw.hooks.names,hookName)) {
var index = $tw.hooks.names[hookName].findIndex(function(hook) {
return hook === definition;
});
if(index !== -1) {
$tw.hooks.names[hookName].splice(index, 1);
}
}
};
/* /*
Invoke the hook by key Invoke the hook by key
*/ */

View File

@ -39,7 +39,7 @@ exports.parse = function() {
id: {type: "string", value: blockId || blockBeforeId}, id: {type: "string", value: blockId || blockBeforeId},
// `true` means the block is before this node, in parent node's children list. // `true` means the block is before this node, in parent node's children list.
// `false` means the block is this node's parent node. // `false` means the block is this node's parent node.
before: {type: "boolean", value: Boolean(blockBeforeId)}, previousSibling: {type: "boolean", value: Boolean(blockBeforeId)},
}, },
children: [] children: []
}]; }];

View File

@ -72,6 +72,8 @@ exports.startup = function() {
}); });
// Install the tm-focus-selector message // Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) { $tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
event = $tw.hooks.invokeHook("th-focus-selector",event);
if (!event) return;
var selector = event.param || "", var selector = event.param || "",
element, element,
baseElement = event.event && event.event.target ? event.event.target.ownerDocument : document; baseElement = event.event && event.event.target ? event.event.target.ownerDocument : document;

View File

@ -18,9 +18,13 @@ BlockIdWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes(); this.computeAttributes();
// Execute our logic // Execute our logic
this.execute(); this.execute();
$tw.hooks.removeHook("th-focus-selector",this.hookFocusElementEvent);
this.hookFocusElementEvent = this.hookFocusElementEvent.bind(this);
$tw.hooks.addHook("th-focus-selector",this.hookFocusElementEvent);
// Create an invisible DOM element with data that can be accessed from JS or CSS // Create an invisible DOM element with data that can be accessed from JS or CSS
this.spanDomNode = this.document.createElement("span"); this.spanDomNode = this.document.createElement("span");
this.spanDomNode.setAttribute("data-id",this.id); this.spanDomNode.id = this.id;
this.spanDomNode.setAttribute("data-block-id",this.id);
if(this.before) { if(this.before) {
this.spanDomNode.setAttribute("data-before","true"); this.spanDomNode.setAttribute("data-before","true");
} }
@ -29,13 +33,34 @@ BlockIdWidget.prototype.render = function(parent,nextSibling) {
this.domNodes.push(this.spanDomNode); this.domNodes.push(this.spanDomNode);
}; };
BlockIdWidget.prototype.hookFocusElementEvent = function(event) {
var id = event.param.replace('#','');
if(id !== this.id) {
return event;
}
var element = this.parentDomNode;
// need to check if the block is before this node
if(this.previousSibling) {
element = element.previousSibling;
}
element.focus({ focusVisible: true });
// toggle class to trigger highlight animation
$tw.utils.removeClass(element,"tc-focus-highlight");
$tw.utils.addClass(element,"tc-focus-highlight");
return false;
};
BlockIdWidget.prototype.removeChildDomNodes = function() {
$tw.hooks.removeHook("th-focus-selector",this.hookFocusElementEvent);
};
/* /*
Compute the internal state of the widget Compute the internal state of the widget
*/ */
BlockIdWidget.prototype.execute = function() { BlockIdWidget.prototype.execute = function() {
// Get the id from the parse tree node or manually assigned attributes // Get the id from the parse tree node or manually assigned attributes
this.id = this.getAttribute("id"); this.id = this.getAttribute("id");
this.before = this.getAttribute("before"); this.previousSibling = this.getAttribute("previousSibling");
// Make the child widgets // Make the child widgets
this.makeChildWidgets(); this.makeChildWidgets();
}; };

View File

@ -167,6 +167,13 @@ LinkWidget.prototype.handleClickEvent = function(event) {
shiftKey: event.shiftKey, shiftKey: event.shiftKey,
event: event event: event
}); });
if(this.toBlockId) {
this.dispatchEvent({
type: "tm-focus-selector",
param: "#" + this.toBlockId,
event: event,
});
}
if(this.domNodes[0].hasAttribute("href")) { if(this.domNodes[0].hasAttribute("href")) {
event.preventDefault(); event.preventDefault();
} }
@ -180,6 +187,7 @@ Compute the internal state of the widget
LinkWidget.prototype.execute = function() { LinkWidget.prototype.execute = function() {
// Pick up our attributes // Pick up our attributes
this.to = this.getAttribute("to",this.getVariable("currentTiddler")); this.to = this.getAttribute("to",this.getVariable("currentTiddler"));
this.toBlockId = this.getAttribute("toBlockId");
this.tooltip = this.getAttribute("tooltip"); this.tooltip = this.getAttribute("tooltip");
this["aria-label"] = this.getAttribute("aria-label"); this["aria-label"] = this.getAttribute("aria-label");
this.linkClasses = this.getAttribute("class"); this.linkClasses = this.getAttribute("class");

View File

@ -2413,6 +2413,19 @@ html body.tc-body.tc-single-tiddler-window {
color: <<colour alert-highlight>>; color: <<colour alert-highlight>>;
} }
@keyframes fadeHighlight {
0% {
background-color: <<colour highlight-background>>;
}
100% {
background-color: transparent;
}
}
.tc-focus-highlight {
animation: fadeHighlight 2s forwards;
}
@media (min-width: <<sidebarbreakpoint>>) { @media (min-width: <<sidebarbreakpoint>>) {
.tc-static-alert { .tc-static-alert {