keep scroll position and selections in tab's session
This commit is contained in:
parent
1d226aac8b
commit
3905722cdf
19
edit/edit.js
19
edit/edit.js
|
@ -56,13 +56,23 @@ lazyInit();
|
|||
.then(initTheme),
|
||||
onDOMready(),
|
||||
]);
|
||||
const scrollInfo = style.id && tryJSONparse(sessionStore['editorScrollInfo' + style.id]);
|
||||
/** @namespace EditorBase */
|
||||
Object.assign(editor, {
|
||||
style,
|
||||
dirty,
|
||||
scrollInfo,
|
||||
updateName,
|
||||
updateToc,
|
||||
toggleStyle,
|
||||
applyScrollInfo(cm, si = ((scrollInfo || {}).cms || [])[0]) {
|
||||
if (si && si.sel) {
|
||||
cm.operation(() => {
|
||||
cm.setSelections(...si.sel, {scroll: false});
|
||||
cm.scrollIntoView(cm.getCursor(), si.parentHeight / 2);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
prefs.subscribe('editor.linter', updateLinter);
|
||||
prefs.subscribe('editor.keyMap', showHotkeyInTooltip);
|
||||
|
@ -410,6 +420,15 @@ function onRuntimeMessage(request) {
|
|||
|
||||
function beforeUnload(e) {
|
||||
sessionStore.windowPos = JSON.stringify(canSaveWindowPos() && prefs.get('windowPosition'));
|
||||
sessionStore['editorScrollInfo' + editor.style.id] = JSON.stringify({
|
||||
scrollY: window.scrollY,
|
||||
cms: editor.getEditors().map(cm => /** @namespace EditorScrollInfo */({
|
||||
focus: cm.hasFocus(),
|
||||
height: cm.display.wrapper.style.height.replace('100vh', ''),
|
||||
parentHeight: cm.display.wrapper.parentElement.offsetHeight,
|
||||
sel: cm.isClean() && [cm.doc.sel.ranges, cm.doc.sel.primIndex],
|
||||
})),
|
||||
});
|
||||
const activeElement = document.activeElement;
|
||||
if (activeElement) {
|
||||
// blurring triggers 'change' or 'input' event if needed
|
||||
|
|
|
@ -17,20 +17,26 @@
|
|||
|
||||
/* exported createSection */
|
||||
|
||||
/** @returns {EditorSection} */
|
||||
function createSection(originalSection, genId) {
|
||||
/**
|
||||
* @param {StyleSection} originalSection
|
||||
* @param {function():number} genId
|
||||
* @param {EditorScrollInfo} [si]
|
||||
* @returns {EditorSection}
|
||||
*/
|
||||
function createSection(originalSection, genId, si) {
|
||||
const {dirty} = editor;
|
||||
const sectionId = genId();
|
||||
const el = template.section.cloneNode(true);
|
||||
const elLabel = $('.code-label', el);
|
||||
const cm = cmFactory.create(wrapper => {
|
||||
// making it tall during initial load so IntersectionObserver sees only one adjacent CM
|
||||
wrapper.style.height = '100vh';
|
||||
wrapper.style.height = si ? si.height : '100vh';
|
||||
elLabel.after(wrapper);
|
||||
}, {
|
||||
value: originalSection.code,
|
||||
});
|
||||
el.CodeMirror = cm; // used by getAssociatedEditor
|
||||
editor.applyScrollInfo(cm, si);
|
||||
|
||||
const changeListeners = new Set();
|
||||
|
||||
|
|
|
@ -486,7 +486,7 @@ function SectionsEditor() {
|
|||
livePreview.update(getModel());
|
||||
}
|
||||
|
||||
function initSections(originalSections, {
|
||||
function initSections(src, {
|
||||
focusOn = 0,
|
||||
replace = false,
|
||||
pristine = false,
|
||||
|
@ -497,26 +497,35 @@ function SectionsEditor() {
|
|||
container.textContent = '';
|
||||
}
|
||||
let done;
|
||||
const total = originalSections.length;
|
||||
originalSections = originalSections.slice();
|
||||
let index = 0;
|
||||
let y = 0;
|
||||
const total = src.length;
|
||||
let si = editor.scrollInfo;
|
||||
if (si && si.cms && si.cms.length === src.length) {
|
||||
si.scrollY2 = si.scrollY + window.innerHeight;
|
||||
container.style.height = si.scrollY2 + 'px';
|
||||
scrollTo(0, si.scrollY);
|
||||
} else {
|
||||
si = null;
|
||||
}
|
||||
return new Promise(resolve => {
|
||||
done = resolve;
|
||||
chunk(true);
|
||||
chunk(!si);
|
||||
});
|
||||
function chunk(forceRefresh) {
|
||||
const t0 = performance.now();
|
||||
while (originalSections.length && performance.now() - t0 < 100) {
|
||||
insertSectionAfter(originalSections.shift(), undefined, forceRefresh);
|
||||
while (index < total && performance.now() - t0 < 100) {
|
||||
if (si) forceRefresh = y < si.scrollY2 && (y += si.cms[index].parentHeight) > si.scrollY;
|
||||
insertSectionAfter(src[index], undefined, forceRefresh, si && si.cms[index]);
|
||||
if (pristine) dirty.clear();
|
||||
if (focusOn !== false && sections[focusOn]) {
|
||||
sections[focusOn].cm.focus();
|
||||
focusOn = false;
|
||||
}
|
||||
if (index === focusOn && !si) sections[index].cm.focus();
|
||||
index++;
|
||||
}
|
||||
setGlobalProgress(total - originalSections.length, total);
|
||||
if (!originalSections.length) {
|
||||
setGlobalProgress(index, total);
|
||||
if (index === total) {
|
||||
setGlobalProgress();
|
||||
requestAnimationFrame(fitToAvailableSpace);
|
||||
if (!si) requestAnimationFrame(fitToAvailableSpace);
|
||||
container.style.removeProperty('height');
|
||||
done();
|
||||
} else {
|
||||
setTimeout(chunk);
|
||||
|
@ -565,18 +574,19 @@ function SectionsEditor() {
|
|||
* @param {StyleSection} [init]
|
||||
* @param {EditorSection} [base]
|
||||
* @param {boolean} [forceRefresh]
|
||||
* @param {EditorScrollInfo} [si]
|
||||
*/
|
||||
function insertSectionAfter(init, base, forceRefresh) {
|
||||
function insertSectionAfter(init, base, forceRefresh, si) {
|
||||
if (!init) {
|
||||
init = {code: '', urlPrefixes: ['http://example.com']};
|
||||
}
|
||||
const section = createSection(init, genId);
|
||||
const section = createSection(init, genId, si);
|
||||
const {cm} = section;
|
||||
sections.splice(base ? sections.indexOf(base) + 1 : sections.length, 0, section);
|
||||
container.insertBefore(section.el, base ? base.el.nextSibling : null);
|
||||
refreshOnView(cm, forceRefresh);
|
||||
registerEvents(section);
|
||||
if (!base || init.code) {
|
||||
if ((!si || !si.height) && (!base || init.code)) {
|
||||
// Fit a) during startup or b) when the clone button is clicked on a section with some code
|
||||
fitToContent(section);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,7 @@ function SourceEditor() {
|
|||
'editor.appliesToLineWidget': (k, val) => sectionWidget.toggle(val),
|
||||
'editor.toc.expanded': (k, val) => sectionFinder.onOff(editor.updateToc, val),
|
||||
}, {now: true});
|
||||
editor.applyScrollInfo(cm);
|
||||
cm.clearHistory();
|
||||
cm.markClean();
|
||||
savedGeneration = cm.changeGeneration();
|
||||
|
|
Loading…
Reference in New Issue
Block a user