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
*/

View File

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

View File

@ -72,6 +72,8 @@ exports.startup = function() {
});
// Install the tm-focus-selector message
$tw.rootWidget.addEventListener("tm-focus-selector",function(event) {
event = $tw.hooks.invokeHook("th-focus-selector",event);
if (!event) return;
var selector = event.param || "",
element,
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();
// Execute our logic
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
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) {
this.spanDomNode.setAttribute("data-before","true");
}
@ -29,13 +33,34 @@ BlockIdWidget.prototype.render = function(parent,nextSibling) {
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
*/
BlockIdWidget.prototype.execute = function() {
// Get the id from the parse tree node or manually assigned attributes
this.id = this.getAttribute("id");
this.before = this.getAttribute("before");
this.previousSibling = this.getAttribute("previousSibling");
// Make the child widgets
this.makeChildWidgets();
};

View File

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

View File

@ -2413,6 +2413,19 @@ html body.tc-body.tc-single-tiddler-window {
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>>) {
.tc-static-alert {