Instantly share code, notes, and snippets.
Last active
July 13, 2025 09:04
-
Star
0
(0)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
-
Save sebjwallace/fff139a7a64f118d167960b5eb0ef6a6 to your computer and use it in GitHub Desktop.
drawio navigation plugin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Navigation Plus Plugin (Standalone) | |
| * Enhances navigation: back/forward history, Command+Click page jump, and key bindings. | |
| * Fully self-contained—no reliance on ElectronApp.js or main app navigation code. | |
| */ | |
| (function() { | |
| function initPlugin() { | |
| if (typeof Draw !== 'undefined' && Draw.loadPlugin) { | |
| Draw.loadPlugin(function(ui) { | |
| var graph = ui.editor.graph; | |
| // --- Standalone navigation history --- | |
| var navHistory = []; | |
| var forwardStack = []; | |
| var isNavigating = false; | |
| // Helper to get current page | |
| function getCurrentPage() { | |
| return ui.currentPage || (ui.editor && ui.editor.currentPage); | |
| } | |
| // Helper to get all pages | |
| function getPages() { | |
| return ui.pages || (ui.editor && ui.editor.pages); | |
| } | |
| // Helper to get page id | |
| function getPageId(page) { | |
| return page && page.getId ? page.getId() : null; | |
| } | |
| // Listen for page changes to update history | |
| if (ui && ui.editor && ui.editor.addListener) { | |
| ui.editor.addListener('pageSelected', function(sender, evt) { | |
| if (isNavigating) { | |
| isNavigating = false; | |
| return; | |
| } | |
| var current = getCurrentPage(); | |
| if (current) { | |
| var currentId = getPageId(current); | |
| if (navHistory.length === 0 || navHistory[navHistory.length - 1] !== currentId) { | |
| navHistory.push(currentId); | |
| } | |
| } | |
| // Clear forward stack on new navigation | |
| forwardStack = []; | |
| }); | |
| } | |
| // --- Command+Click to navigate to page/tab links --- | |
| graph.addListener(mxEvent.CLICK, function(sender, evt) { | |
| var me = evt.getProperty('event'); // Mouse event | |
| var cell = evt.getProperty('cell'); | |
| if (!cell || !me) return; | |
| // Only trigger on Command+Click (metaKey on Mac) | |
| if (me.metaKey) { | |
| var link = graph.getLinkForCell(cell); | |
| if (link && Graph.isPageLink && Graph.isPageLink(link)) { | |
| // Find the page/tab by ID or name | |
| var pageId = null; | |
| var pageName = null; | |
| if (link.charAt(0) === '#') { | |
| pageId = link.substring(1); | |
| } else if (link.indexOf('data:page/id,') === 0) { | |
| pageId = link.substring('data:page/id,'.length); | |
| } else if (link.indexOf('data:page/name,') === 0) { | |
| pageName = decodeURIComponent(link.substring('data:page/name,'.length)); | |
| } | |
| var foundPage = null; | |
| var pages = getPages(); | |
| if (pageId && pages) { | |
| for (var i = 0; i < pages.length; i++) { | |
| if (pages[i].getId && pages[i].getId() == pageId) { | |
| foundPage = pages[i]; | |
| break; | |
| } | |
| } | |
| } else if (pageName && pages) { | |
| for (var i = 0; i < pages.length; i++) { | |
| if (pages[i].getName && pages[i].getName() == pageName) { | |
| foundPage = pages[i]; | |
| break; | |
| } | |
| } | |
| } | |
| if (foundPage) { | |
| var current = getCurrentPage(); | |
| if (current) { | |
| var currentId = getPageId(current); | |
| if (navHistory.length === 0 || navHistory[navHistory.length - 1] !== currentId) { | |
| navHistory.push(currentId); | |
| } | |
| } | |
| isNavigating = true; | |
| ui.selectPage(foundPage); | |
| // Clear forward stack on new navigation | |
| forwardStack = []; | |
| mxEvent.consume(me); | |
| console.log('Navigated to page:', foundPage.getName ? foundPage.getName() : foundPage.getId()); | |
| } else { | |
| console.log('Page not found for link:', link); | |
| } | |
| } | |
| } | |
| }); | |
| // --- Standalone back/forward navigation --- | |
| function goBack() { | |
| var current = getCurrentPage(); | |
| var currentId = getPageId(current); | |
| if (navHistory.length > 1) { | |
| // Pop current page | |
| navHistory.pop(); | |
| var prevId = navHistory[navHistory.length - 1]; | |
| var pages = getPages(); | |
| var prevPage = null; | |
| for (var i = 0; i < pages.length; i++) { | |
| if (getPageId(pages[i]) === prevId) { | |
| prevPage = pages[i]; | |
| break; | |
| } | |
| } | |
| if (prevPage) { | |
| // Push current to forward stack | |
| if (currentId) forwardStack.push(currentId); | |
| isNavigating = true; | |
| ui.selectPage(prevPage); | |
| console.log('Back navigation triggered'); | |
| } | |
| } else { | |
| console.log('Back navigation not available'); | |
| } | |
| } | |
| function goForward() { | |
| var pages = getPages(); | |
| if (forwardStack.length > 0) { | |
| var nextId = forwardStack.pop(); | |
| var nextPage = null; | |
| for (var i = 0; i < pages.length; i++) { | |
| if (getPageId(pages[i]) === nextId) { | |
| nextPage = pages[i]; | |
| break; | |
| } | |
| } | |
| if (nextPage) { | |
| var current = getCurrentPage(); | |
| var currentId = getPageId(current); | |
| if (currentId) navHistory.push(currentId); | |
| isNavigating = true; | |
| ui.selectPage(nextPage); | |
| console.log('Forward navigation triggered'); | |
| } | |
| } else { | |
| console.log('Forward navigation not available'); | |
| } | |
| } | |
| // Keydown listener for back (Alt+Left) and forward (Alt+Right) and ⌘, | |
| document.addEventListener('keydown', function(e) { | |
| // Back: Alt + Left Arrow | |
| if (e.altKey && !e.metaKey && !e.shiftKey && !e.ctrlKey && e.key === 'ArrowLeft') { | |
| e.preventDefault(); | |
| goBack(); | |
| } | |
| // Forward: Alt + Right Arrow | |
| if (e.altKey && !e.metaKey && !e.shiftKey && !e.ctrlKey && e.key === 'ArrowRight') { | |
| e.preventDefault(); | |
| goForward(); | |
| } | |
| // Command+, (⌘,) for back navigation | |
| if (e.metaKey && !e.shiftKey && !e.altKey && !e.ctrlKey && e.key === ',') { | |
| e.preventDefault(); | |
| goBack(); | |
| } | |
| }); | |
| // Log availability | |
| console.log('Navigation Plus plugin loaded! (standalone)'); | |
| console.log('Features: Command+Click page jump, Alt+Left/Right for back/forward, ⌘, for back.'); | |
| }); | |
| } else { | |
| setTimeout(initPlugin, 100); | |
| } | |
| } | |
| initPlugin(); | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment