feat: adapt for other story views

This commit is contained in:
linonetwo 2023-09-22 23:57:14 +08:00
parent ebf84b59e8
commit 507d004a57
5 changed files with 65 additions and 12 deletions

View File

@ -28,14 +28,12 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) {
targetElement = listItemWidget.findFirstDomNode();
// If anchor is provided, find the element the anchor pointing to
var foundAnchor = false;
if(targetElement && historyInfo.anchor) {
var anchorElement = targetElement.querySelector("[data-anchor-id='" + historyInfo.anchor + "']");
if(anchorElement) {
targetElement = anchorElement.parentNode;
var isBefore = anchorElement.dataset.anchorPreviousSibling === "true";
if(isBefore) {
targetElement = targetElement.previousSibling;
}
if(listItemWidget && historyInfo.anchor) {
var anchorWidget = $tw.utils.findChildNodeInTree(listItemWidget, function(widget) {
return widget.anchorId === historyInfo.anchor;
});
if(anchorWidget) {
targetElement = anchorWidget.findAnchorTargetDomNode()
foundAnchor = true;
}
}

View File

@ -23,12 +23,23 @@ PopStoryView.prototype.navigateTo = function(historyInfo) {
}
var listItemWidget = this.listWidget.children[listElementIndex],
targetElement = listItemWidget.findFirstDomNode();
// If anchor is provided, find the element the anchor pointing to
var foundAnchor = false;
if(listItemWidget && historyInfo.anchor) {
var anchorWidget = $tw.utils.findChildNodeInTree(listItemWidget, function(widget) {
return widget.anchorId === historyInfo.anchor;
});
if(anchorWidget) {
targetElement = anchorWidget.findAnchorTargetDomNode()
foundAnchor = true;
}
}
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
return;
}
// Scroll the node into view
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement});
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement, highlight: foundAnchor});
};
PopStoryView.prototype.insert = function(widget) {

View File

@ -51,6 +51,16 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
}
var listItemWidget = this.listWidget.children[listElementIndex],
targetElement = listItemWidget.findFirstDomNode();
// If anchor is provided, find the element the anchor pointing to
var anchorElement = null;
if(listItemWidget && historyInfo.anchor) {
var anchorWidget = $tw.utils.findChildNodeInTree(listItemWidget, function(widget) {
return widget.anchorId === historyInfo.anchor;
});
if(anchorWidget) {
anchorElement = anchorWidget.findAnchorTargetDomNode()
}
}
// Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement) {
return;
@ -119,7 +129,10 @@ ZoominListView.prototype.navigateTo = function(historyInfo) {
},duration);
}
// Scroll the target into view
// $tw.pageScroller.scrollIntoView(targetElement);
if(anchorElement) {
this.listWidget.dispatchEvent({type: "tm-scroll", target: anchorElement, highlight: true});
}
// $tw.pageScroller.scrollIntoView(targetElement);
};
/*

View File

@ -103,6 +103,21 @@ exports.findParseTreeNode = function(nodeArray,search) {
return undefined;
};
exports.findChildNodeInTree = function(root,searchFn) {
if(searchFn(root)) {
return root;
}
if(root.children && root.children.length > 0) {
for(var i=0; i<root.children.length; i++) {
var result = exports.findChildNodeInTree(root.children[i], searchFn);
if(result) {
return result;
}
}
}
return undefined;
};
/*
Helper to get the text of a parse tree node or array of nodes
*/

View File

@ -21,7 +21,7 @@ AnchorWidget.prototype.render = function(parent,nextSibling) {
this.execute();
// Create an invisible DOM element with data that can be accessed from JS or CSS
this.idNode = this.document.createElement("span");
this.idNode.setAttribute("data-anchor-id",this.id);
this.idNode.setAttribute("data-anchor-id",this.anchorId);
this.idNode.setAttribute("data-anchor-title",this.tiddlerTitle);
// if the actual block is before this node, we need to add a flag to the node
if(this.previousSibling) {
@ -37,13 +37,29 @@ Compute the internal state of the widget
*/
AnchorWidget.prototype.execute = function() {
// Get the id from the parse tree node or manually assigned attributes
this.id = this.getAttribute("id");
this.anchorId = this.getAttribute("id");
this.tiddlerTitle = this.getVariable("currentTiddler");
this.previousSibling = this.getAttribute("previousSibling") === "yes";
// Make the child widgets
this.makeChildWidgets();
};
/*
Find the DOM node pointed by this anchor
*/
Widget.prototype.findAnchorTargetDomNode = function() {
if(!this.idNode) {
return null;
}
// the actual block is always at the parent level
targetElement = this.idNode.parentNode;
// need to check if the block is before this node
if(this.previousSibling) {
targetElement = targetElement.previousSibling;
}
return targetElement;
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/