mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Dynaview: Add support for saving/restoring scroll position from local storage
This commit is contained in:
parent
348a0bc8bc
commit
a9e595c3f6
@ -0,0 +1,2 @@
|
||||
title: $:/config/DynaView/RestoreScrollPositionAtStartup
|
||||
text: yes
|
@ -13,12 +13,18 @@ The components of this plugin include:
|
||||
|
||||
! Scroll Features
|
||||
|
||||
!! Scroll Position Preservation
|
||||
!! Scroll position preservation during refresh
|
||||
|
||||
Some recent browsers have a feature called "scroll anchoring" whereby they suppress the apparent scrolling that occurs when elements are inserted or removed above the current viewport. (See https://github.com/WICG/ScrollAnchoring for more details).
|
||||
|
||||
~DynaView can optionally polyfill this behaviour for older browsers by setting the configuration tiddler $:/config/DynaView/PreserveScrollPosition to `yes`.
|
||||
|
||||
!! Startup scroll position restoration
|
||||
|
||||
Optionally, ~DynaView can store the current scroll position in local storage and restore it upon startup. Set the configuration tiddler $:/config/DynaView/RestoreScrollPositionAtStartup to `yes`.
|
||||
|
||||
Note that it is not recommended to use this setting at the same time as the "UpdateAddressBar" option.
|
||||
|
||||
!! Set tiddler field when visible
|
||||
|
||||
The background task detects when elements with the class `tc-dynaview-set-tiddler-when-visible` scroll into view. The first time that they do, the background task assigns the value in the attribute `data-dynaview-set-value` to the tiddler whose title is in the attribute `data-dynaview-set-tiddler`. This assignment can be tied to a reveal widget to cause content to be displayed when it becomes visible. If the class `tc-dynaview-expand-viewport` is set then the viewport is expanded so that the processing occurs when elements move near the viewport.
|
||||
@ -29,7 +35,9 @@ The background task detects when elements with the class `tc-dynaview-set-tiddle
|
||||
|
||||
!! Update address bar when scrolling
|
||||
|
||||
The background task detects the tiddler at the top of the viewport and sets the address bar location hash to the title of that tiddler.
|
||||
If the configuration tiddler $:/config/DynaView/UpdateAddressBar is set to `yes` the background task detects the tiddler at the top of the viewport and sets the address bar location hash to the title of that tiddler.
|
||||
|
||||
Note that it is not recommended to use this setting at the same time as the "RestoreScrollPositionAtStartup" option.
|
||||
|
||||
! Viewport Size Features
|
||||
|
||||
|
@ -15,7 +15,7 @@ Zoom everything
|
||||
// Export name and synchronous status
|
||||
exports.name = "dynaview";
|
||||
exports.platforms = ["browser"];
|
||||
exports.after = ["render"];
|
||||
exports.before = ["story"];
|
||||
exports.synchronous = true;
|
||||
|
||||
var isWaitingForAnimationFrame = 0, // Bitmask:
|
||||
@ -23,22 +23,33 @@ var isWaitingForAnimationFrame = 0, // Bitmask:
|
||||
ANIM_FRAME_CAUSED_BY_SCROLL = 2, // Animation frame was requested because of page scroll
|
||||
ANIM_FRAME_CAUSED_BY_RESIZE = 4; // Animation frame was requested because of window resize
|
||||
|
||||
var LOCAL_STORAGE_KEY_PREFIX = "tw5-dynaview-scroll-position#";
|
||||
|
||||
var hasRestoredScrollPosition = false;
|
||||
|
||||
exports.startup = function() {
|
||||
var topmost = null, lastScrollY;
|
||||
$tw.boot.disableStartupNavigation = true;
|
||||
window.addEventListener("load",onLoad,false);
|
||||
window.addEventListener("scroll",onScroll,false);
|
||||
window.addEventListener("resize",onResize,false);
|
||||
$tw.hooks.addHook("th-page-refreshing",function() {
|
||||
if(shouldPreserveScrollPosition()) {
|
||||
if(!hasRestoredScrollPosition) {
|
||||
topmost = restoreScrollPosition();
|
||||
} else if(shouldPreserveScrollPosition()) {
|
||||
topmost = findTopmostTiddler();
|
||||
}
|
||||
lastScrollY = window.scrollY;
|
||||
});
|
||||
$tw.hooks.addHook("th-page-refreshed",function() {
|
||||
if(lastScrollY === window.scrollY) { // Don't do scroll anchoring if the scroll position got changed
|
||||
scrollToTiddler(topmost);
|
||||
if(shouldPreserveScrollPosition() || !hasRestoredScrollPosition) {
|
||||
scrollToTiddler(topmost);
|
||||
hasRestoredScrollPosition = true;
|
||||
}
|
||||
}
|
||||
updateAddressBar();
|
||||
saveScrollPosition();
|
||||
checkVisibility();
|
||||
saveViewportDimensions();
|
||||
});
|
||||
@ -71,6 +82,7 @@ function worker() {
|
||||
}
|
||||
setZoomClasses();
|
||||
updateAddressBar();
|
||||
saveScrollPosition();
|
||||
checkVisibility();
|
||||
isWaitingForAnimationFrame = 0;
|
||||
}
|
||||
@ -157,11 +169,40 @@ function updateAddressBar() {
|
||||
}
|
||||
}
|
||||
|
||||
function saveScrollPosition() {
|
||||
if(hasRestoredScrollPosition && $tw.wiki.getTiddlerText("$:/config/DynaView/RestoreScrollPositionAtStartup") === "yes") {
|
||||
var top = findTopmostTiddler();
|
||||
if(top.element) {
|
||||
try {
|
||||
window.localStorage.setItem(LOCAL_STORAGE_KEY_PREFIX + window.location.pathname,JSON.stringify({
|
||||
title: top.title,
|
||||
offset: top.offset
|
||||
}));
|
||||
} catch(e) {
|
||||
console.log("Error setting local storage",e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function restoreScrollPosition() {
|
||||
var str = window.localStorage.getItem(LOCAL_STORAGE_KEY_PREFIX + window.location.pathname),
|
||||
json;
|
||||
if(str) {
|
||||
try {
|
||||
json = JSON.parse(str);
|
||||
} catch(e) {
|
||||
// Ignore errors
|
||||
};
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
/*
|
||||
tiddlerDetails: {title: <title of tiddler to scroll to>, offset: <offset in pixels from the top of the tiddler>}
|
||||
*/
|
||||
function scrollToTiddler(tiddlerDetails) {
|
||||
if(shouldPreserveScrollPosition() && !$tw.pageScroller.isScrolling() && tiddlerDetails) {
|
||||
if(!$tw.pageScroller.isScrolling() && tiddlerDetails) {
|
||||
var elements = document.querySelectorAll(".tc-tiddler-frame[data-tiddler-title]"),
|
||||
topmostTiddlerElement = null;
|
||||
$tw.utils.each(elements,function(element) {
|
||||
|
Loading…
Reference in New Issue
Block a user