plugins(files): Feature 10 — Navigation history
- History stack with Back/Forward (goBack/goForward) - historyIndex + navigatingHistory flag for correct stack management - Toolbar buttons: ← (back) and → (forward) before Up button - Alt+Left / Alt+Right and Ctrl+[ / Ctrl+] keyboard shortcuts - Future path trimmed on new navigation (forward state discarded) - Duplicate paths not pushed to stack - Refresh and direct loadEntries don't pollute history
This commit is contained in:
parent
4a0656cd09
commit
c3a14411ab
|
|
@ -231,6 +231,9 @@
|
|||
var createMode = '';
|
||||
var renameTarget = null;
|
||||
var disposed = false;
|
||||
var historyStack = [''];
|
||||
var historyIndex = 0;
|
||||
var navigatingHistory = false;
|
||||
|
||||
function scopedPath(local) {
|
||||
local = cleanPath(local);
|
||||
|
|
@ -246,6 +249,8 @@
|
|||
|
||||
var toolbar = el('div', { className: 'files-toolbar' });
|
||||
var breadcrumb = el('div', { className: 'files-breadcrumb' });
|
||||
var backBtn = el('button', { className: 'files-toolbar-btn', 'data-files-action': 'back', title: 'Back (Alt+Left)' }, ['\u2190']);
|
||||
var forwardBtn = el('button', { className: 'files-toolbar-btn', 'data-files-action': 'forward', title: 'Forward (Alt+Right)' }, ['\u2192']);
|
||||
var upBtn = el('button', { className: 'files-toolbar-btn', 'data-files-action': 'up', title: 'Up' }, ['Up']);
|
||||
var refreshBtn = el('button', { className: 'files-toolbar-btn', 'data-files-action': 'refresh', title: 'Refresh' }, ['Refresh']);
|
||||
var newFolderBtn = el('button', { className: 'files-toolbar-btn', 'data-files-action': 'new-folder' }, ['+ Folder']);
|
||||
|
|
@ -264,7 +269,7 @@
|
|||
el('option', { value: 'size-desc' }, ['Size'])
|
||||
]);
|
||||
toolbar.appendChild(breadcrumb);
|
||||
[upBtn, refreshBtn, newFolderBtn, newMdBtn, newTextBtn, openBtn, renameBtn, trashBtn, pasteBtn, filterInput, sortSelect].forEach(function (node) { toolbar.appendChild(node); });
|
||||
[backBtn, forwardBtn, upBtn, refreshBtn, newFolderBtn, newMdBtn, newTextBtn, openBtn, renameBtn, trashBtn, pasteBtn, filterInput, sortSelect].forEach(function (node) { toolbar.appendChild(node); });
|
||||
containerEl.appendChild(toolbar);
|
||||
|
||||
var listContainer = el('div', { className: 'files-list', 'data-files-list': '' });
|
||||
|
|
@ -307,6 +312,11 @@
|
|||
pasteBtn.disabled = !window.__filesClipboard;
|
||||
}
|
||||
|
||||
function updateHistoryButtons() {
|
||||
backBtn.disabled = historyIndex <= 0;
|
||||
forwardBtn.disabled = historyIndex >= historyStack.length - 1;
|
||||
}
|
||||
|
||||
function updateBreadcrumb() {
|
||||
breadcrumb.innerHTML = '';
|
||||
var root = el('span', { className: currentPath ? 'files-breadcrumb-item' : 'files-breadcrumb-current', onClick: function () { navigateTo(''); } }, [workspaceName]);
|
||||
|
|
@ -480,12 +490,39 @@
|
|||
}
|
||||
|
||||
function navigateTo(path) {
|
||||
currentPath = cleanPath(path);
|
||||
var newPath = cleanPath(path);
|
||||
if (!navigatingHistory) {
|
||||
if (historyIndex < historyStack.length - 1) {
|
||||
historyStack = historyStack.slice(0, historyIndex + 1);
|
||||
}
|
||||
if (historyStack[historyStack.length - 1] !== newPath) {
|
||||
historyStack.push(newPath);
|
||||
historyIndex = historyStack.length - 1;
|
||||
}
|
||||
}
|
||||
currentPath = newPath;
|
||||
cancelCreate();
|
||||
cancelRename();
|
||||
updateHistoryButtons();
|
||||
loadEntries();
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (historyIndex <= 0) return;
|
||||
historyIndex--;
|
||||
navigatingHistory = true;
|
||||
navigateTo(historyStack[historyIndex]);
|
||||
navigatingHistory = false;
|
||||
}
|
||||
|
||||
function goForward() {
|
||||
if (historyIndex >= historyStack.length - 1) return;
|
||||
historyIndex++;
|
||||
navigatingHistory = true;
|
||||
navigateTo(historyStack[historyIndex]);
|
||||
navigatingHistory = false;
|
||||
}
|
||||
|
||||
function goUp() {
|
||||
if (currentPath) navigateTo(parentPath(currentPath));
|
||||
}
|
||||
|
|
@ -608,6 +645,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
backBtn.addEventListener('click', goBack);
|
||||
forwardBtn.addEventListener('click', goForward);
|
||||
refreshBtn.addEventListener('click', loadEntries);
|
||||
upBtn.addEventListener('click', goUp);
|
||||
newFolderBtn.addEventListener('click', function () { startCreate('folder'); });
|
||||
|
|
@ -929,6 +968,11 @@
|
|||
beginRename();
|
||||
return;
|
||||
}
|
||||
if (key === 'ArrowLeft' && event.altKey) { event.preventDefault(); goBack(); return; }
|
||||
if (key === 'ArrowRight' && event.altKey) { event.preventDefault(); goForward(); return; }
|
||||
if (key === '[' && ctrl) { event.preventDefault(); goBack(); return; }
|
||||
if (key === ']' && ctrl) { event.preventDefault(); goForward(); return; }
|
||||
|
||||
if (key === 'a' && (ctrl || event.metaKey)) {
|
||||
event.preventDefault();
|
||||
var vis = visibleEntries();
|
||||
|
|
@ -970,6 +1014,7 @@
|
|||
}
|
||||
});
|
||||
|
||||
updateHistoryButtons();
|
||||
loadEntries();
|
||||
|
||||
containerEl.__filesCleanup = function () {
|
||||
|
|
|
|||
Loading…
Reference in New Issue