mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-01-10 17:30:26 +00:00
refactor: use history mechanism for block level navigation
This commit is contained in:
parent
dfa060024e
commit
436343ce1b
@ -90,12 +90,12 @@ Story.prototype.saveStoryList = function(storyList) {
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
Story.prototype.addToHistory = function(navigateTo,navigateFromClientRect) {
|
Story.prototype.addToHistory = function(navigateTo,fromPageRect,anchor) {
|
||||||
var titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];
|
var titles = $tw.utils.isArray(navigateTo) ? navigateTo : [navigateTo];
|
||||||
// Add a new record to the top of the history stack
|
// Add a new record to the top of the history stack
|
||||||
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
|
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
|
||||||
$tw.utils.each(titles,function(title) {
|
$tw.utils.each(titles,function(title) {
|
||||||
historyList.push({title: title, fromPageRect: navigateFromClientRect});
|
historyList.push({title: title, fromPageRect: fromPageRect, anchor: anchor});
|
||||||
});
|
});
|
||||||
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
|
this.wiki.setTiddlerData(this.historyTitle,historyList,{"current-tiddler": titles[titles.length-1]});
|
||||||
};
|
};
|
||||||
|
@ -26,13 +26,26 @@ ClassicStoryView.prototype.navigateTo = function(historyInfo) {
|
|||||||
}
|
}
|
||||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||||
targetElement = listItemWidget.findFirstDomNode();
|
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;
|
||||||
|
}
|
||||||
|
foundAnchor = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
// Abandon if the list entry isn't a DOM element (it might be a text node)
|
||||||
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(duration) {
|
if(duration) {
|
||||||
// Scroll the node into view
|
// Scroll the node into view
|
||||||
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement});
|
this.listWidget.dispatchEvent({type: "tm-scroll", target: targetElement, highlight: foundAnchor});
|
||||||
} else {
|
} else {
|
||||||
targetElement.scrollIntoView();
|
targetElement.scrollIntoView();
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,9 @@ Handle an event
|
|||||||
*/
|
*/
|
||||||
PageScroller.prototype.handleEvent = function(event) {
|
PageScroller.prototype.handleEvent = function(event) {
|
||||||
if(event.type === "tm-scroll") {
|
if(event.type === "tm-scroll") {
|
||||||
var options = {};
|
var options = {
|
||||||
|
highlight: event.highlight,
|
||||||
|
};
|
||||||
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
if($tw.utils.hop(event.paramObject,"animationDuration")) {
|
||||||
options.animationDuration = event.paramObject.animationDuration;
|
options.animationDuration = event.paramObject.animationDuration;
|
||||||
}
|
}
|
||||||
@ -65,14 +67,21 @@ PageScroller.prototype.handleEvent = function(event) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Handle a scroll event hitting the page document
|
Handle a scroll event hitting the page document
|
||||||
|
|
||||||
|
options:
|
||||||
|
- animationDuration: total time of scroll animation
|
||||||
|
- highlight: highlight the element after scrolling, to make it evident. Usually to focus an anchor in the middle of the tiddler.
|
||||||
*/
|
*/
|
||||||
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
||||||
var self = this,
|
var self = this,
|
||||||
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
duration = $tw.utils.hop(options,"animationDuration") ? parseInt(options.animationDuration) : $tw.utils.getAnimationDuration(),
|
||||||
|
highlight = options.highlight || false,
|
||||||
srcWindow = element ? element.ownerDocument.defaultView : window;
|
srcWindow = element ? element.ownerDocument.defaultView : window;
|
||||||
// Now get ready to scroll the body
|
// Now get ready to scroll the body
|
||||||
this.cancelScroll(srcWindow);
|
this.cancelScroll(srcWindow);
|
||||||
this.startTime = Date.now();
|
this.startTime = Date.now();
|
||||||
|
// toggle class to allow trigger the highlight animation
|
||||||
|
$tw.utils.removeClass(element,"tc-focus-highlight");
|
||||||
// Get the height of any position:fixed toolbars
|
// Get the height of any position:fixed toolbars
|
||||||
var toolbar = srcWindow.document.querySelector(".tc-adjust-top-of-scroll"),
|
var toolbar = srcWindow.document.querySelector(".tc-adjust-top-of-scroll"),
|
||||||
offset = 0;
|
offset = 0;
|
||||||
@ -121,6 +130,15 @@ PageScroller.prototype.scrollIntoView = function(element,callback,options) {
|
|||||||
srcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);
|
srcWindow.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t);
|
||||||
if(t < 1) {
|
if(t < 1) {
|
||||||
self.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);
|
self.idRequestFrame = self.requestAnimationFrame.call(srcWindow,drawFrame);
|
||||||
|
} else {
|
||||||
|
// the animation is end.
|
||||||
|
if(highlight) {
|
||||||
|
element.focus({ focusVisible: true });
|
||||||
|
// Using setTimeout to ensure the removal takes effect before adding the class again.
|
||||||
|
setTimeout(function() {
|
||||||
|
$tw.utils.addClass(element,"tc-focus-highlight");
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
drawFrame();
|
drawFrame();
|
||||||
|
@ -23,8 +23,9 @@ AnchorWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
this.idNode = this.document.createElement("span");
|
this.idNode = this.document.createElement("span");
|
||||||
this.idNode.setAttribute("data-anchor-id",this.id);
|
this.idNode.setAttribute("data-anchor-id",this.id);
|
||||||
this.idNode.setAttribute("data-anchor-title",this.tiddlerTitle);
|
this.idNode.setAttribute("data-anchor-title",this.tiddlerTitle);
|
||||||
if(this.before) {
|
// if the actual block is before this node, we need to add a flag to the node
|
||||||
this.idNode.setAttribute("data-before","true");
|
if(this.previousSibling) {
|
||||||
|
this.idNode.setAttribute("data-anchor-previous-sibling","true");
|
||||||
}
|
}
|
||||||
this.idNode.className = "tc-anchor";
|
this.idNode.className = "tc-anchor";
|
||||||
parent.insertBefore(this.idNode,nextSibling);
|
parent.insertBefore(this.idNode,nextSibling);
|
||||||
|
@ -138,9 +138,10 @@ NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
|
|||||||
Add a new record to the top of the history stack
|
Add a new record to the top of the history stack
|
||||||
title: a title string or an array of title strings
|
title: a title string or an array of title strings
|
||||||
fromPageRect: page coordinates of the origin of the navigation
|
fromPageRect: page coordinates of the origin of the navigation
|
||||||
|
anchor:optional anchor id in this tiddler
|
||||||
*/
|
*/
|
||||||
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
|
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect,anchor) {
|
||||||
this.story.addToHistory(title,fromPageRect,this.historyTitle);
|
this.story.addToHistory(title,fromPageRect,anchor);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -150,9 +151,8 @@ NavigatorWidget.prototype.handleNavigateEvent = function(event) {
|
|||||||
event = $tw.hooks.invokeHook("th-navigating",event);
|
event = $tw.hooks.invokeHook("th-navigating",event);
|
||||||
if(event.navigateTo) {
|
if(event.navigateTo) {
|
||||||
this.addToStory(event.navigateTo,event.navigateFromTitle);
|
this.addToStory(event.navigateTo,event.navigateFromTitle);
|
||||||
event = $tw.hooks.invokeHook("th-navigating-add-history",event);
|
|
||||||
if(!event.navigateSuppressNavigation) {
|
if(!event.navigateSuppressNavigation) {
|
||||||
this.addToHistory(event.navigateTo,event.navigateFromClientRect);
|
this.addToHistory(event.navigateTo,event.navigateFromClientRect,event.toAnchor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$tw.hooks.invokeHook("th-navigated",event);
|
$tw.hooks.invokeHook("th-navigated",event);
|
||||||
|
Loading…
Reference in New Issue
Block a user