diff --git a/.gitignore b/.gitignore
index aacfc57..3cf2a48 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
data.json
data.json
+changelog.txt
diff --git a/README.md b/README.md
index d128bc4..8b4f709 100644
--- a/README.md
+++ b/README.md
@@ -4,26 +4,34 @@ An Obsidian plugin that displays all open notes in a tab group as if they were a
## Features:
-#### File and Editor Contextual Menus:
- - Toggle continuous mode in active tab group.
- - Show/hide note headers in active tab group.
+#### File and Editor Contextual Menus, Command Palette:
+ - Toggle continuous mode in active tab group.
+ - Show/hide note headers in active tab group.
#### File Explorer Contextual Menu:
- - Open all files from selected folder in Continuous Mode. Currently only markdown files, images (bmp, jpg, jpeg, gif, png, svg, webp), and pdfs are opened.
- - Open or append files from selected folder in active tab group; files from the folder will not be duplicated if they are already open.
- - Replace active tab group with files from selected folder: i.e., close all open notes in active tab group and replace with folder items.
-
-#### Command Palette:
- - Toggle continuous mode in active tag group.
- - Show/hide note headers in active tab group.
+The File Explorer contextual menu provides several options for opening all the contents of the selected folder in Continuous Mode:
+ - Open files in new split (left, right, up, down).
+ - Open or append files in active tab group; files will not be duplicated if they are already open.
+ - Replace files in active tab group with files from the selected folder (i.e., close all open notes in active tab group and replace with folder items).
+Exclude/include folder files by type (e.g., markdown, images, canvas, etc.), extension, or file name in the Settings.
+Note: opening folders is not recursive—only the top level notes will be opened.
#### Other functions:
- - Navigate between notes with up and down arrow keys (and left and right arrow keys if at the beginning or end of the note).
- - Also use left and right arrow keys to scroll html notes or jump from page to page in pdfs.
+ - Automatically save and restore continuous mode tab group settings when shutting down/starting up Obsidian.
+ - Navigate between notes with up and down arrow keys (and left and right arrow keys if at the beginning or end of the note).
+ - Also use left and right arrow keys to scroll html notes or jump from page to page in pdfs.
+ - If editing a canvas file (i.e., canvas leaf is active), click the background to deselect any active node and use the up and down arrow keys to navigate to the adjacent note.
+ - Similarly use the arrow keys to navigate out of an active graph view. Use shift+arrow keys to move the graph around.
- Notes scroll into view when tab header is clicked.
- - Reorder notes via tab header drag-and-drop.
- - Save and restore continuous mode tab group settings when shutting down/starting up Obsidian.
-
+ - Reorder notes in tab group via tab header drag-and-drop.
+
+#### User Settings:
+- “Open folder in Continuous Mode” menu options: Exclude or include folder files by type (e.g., markdown, images, canvas, etc.), extension, or file name.
+- “Clear stored data”: Empty the list of stored tab groups, ignoring currently open tab groups with continuous mode active. This optional action prevents the list from getting unwieldy or cluttered with stale data, which can happen if you frequently open and close new tab groups.
+- Donate link.
+
+#### Notes:
+ - If you use the "Open folder in Continuous Mode" functions to open all the notes in a folder, the tab group will not reflect any changes you make to the folder structure in the file explorer. If you do make any changes (e.g., move, create, or delete a note), you'll have to reopen the folder to see the updated structure.
### Buy me a coffee:
diff --git a/main.js b/main.js
index c707a9a..8389518 100644
--- a/main.js
+++ b/main.js
@@ -3,13 +3,17 @@
let obsidian = require('obsidian');
let DEFAULT_SETTINGS = {
+ 'folderFileTypes':[],
+ 'extraFileTypes':[],
+ 'excludedNames':[],
'tabGroupIds': []
};
class ContinuousModePlugin extends obsidian.Plugin {
async onload() {
console.log('Loading the Continuous Mode plugin.');
- await this.loadSettings();
+ await this.loadSettings();
+ this.addSettingTab(new ContinuousModeSettings(this.app, this));
/* ----------------------- */
// HELPERS
const getAllTabGroups = (begin_node,all_tabs) => {
@@ -36,21 +40,6 @@ class ContinuousModePlugin extends obsidian.Plugin {
tab_group => { if ( tab_group ) { tab_group.containerEl.dataset.tab_group_id = this.app.appId +'_'+ tab_group.id } }
);
}
- const cleanDataTabGroupIds = () => { return; // clean up tab_group_ids in data.json
- // !! this is dangerous, as it can incorrectly remove ids when the workspace is changed; function is disabled for now.
- let all_tab_groups = getAllTabGroups(this.app.workspace.rootSplit) || [];
- let all_tab_group_ids = [];
- let data_tab_group_ids = this.settings.tabGroupIds;
- all_tab_groups.forEach( tab_group => all_tab_group_ids.push(this.app.appId +'_'+ tab_group.id) ); // get all tab group ids
- data_tab_group_ids.forEach( id => {
- if ( this.app.appId === id.split('_')[0] ) {
- if ( !all_tab_group_ids.includes(id) ) {
- this.settings.tabGroupIds.splice(this.settings.tabGroupIds.indexOf(id),1);
- this.saveSettings();
- }
- }
- })
- }
updateTabGroupDatasetIds(); // disabled
/* ----------------------- */
// TOGGLE CONTINUOUS MODE
@@ -61,7 +50,7 @@ class ContinuousModePlugin extends obsidian.Plugin {
case isFloatingWindow(): active_floating_tab_group().containerEl.classList.toggle('is_continuous_mode'); break; // if floating window, don't save tabGroupIds
case this.app.appId === tab_group_id?.split('_')[0]:
switch(true) {
- case getTabGroupById(tab_group_id)?.containerEl?.classList.contains('is_continuous_mode') && bool !== true: // if tab group is in continuous mode
+ case getTabGroupById(tab_group_id)?.containerEl?.classList.contains('is_continuous_mode') && bool !== true: // if tab group is in continuous mode, remove continuous mode
getTabGroupById(tab_group_id)?.containerEl?.classList.remove('is_continuous_mode'); // remove style
this.settings.tabGroupIds.splice(this.settings.tabGroupIds.indexOf(tab_group_id),1); // remove tabGroupdId from data.json
break;
@@ -118,8 +107,12 @@ class ContinuousModePlugin extends obsidian.Plugin {
}
// ARROW NAVIGATION between open leaves
const leafArrowNavigation = (e) => {
- if ( getActiveLeaf()?.containerEl?.closest('.workspace-split.mod-root') === null && !getActiveEditor()?.hasFocus() ) { return; } // return if not in leaf editor or editor not focussed
- if ( getActiveLeaf().containerEl.closest('.workspace-split.mod-root') === null && !getActiveEditor()?.hasFocus() ) { return; } // return if not in leaf editor or editor not focussed
+ switch(true) { // Ignore arrow navigation function in these cases:
+ case getActiveLeaf()?.containerEl?.closest('.workspace-split.mod-root') === null && !getActiveEditor()?.hasFocus(): // return if not in leaf editor or editor not focussed
+ case e.target.querySelector('.canvas-node.is-focused') && /Arrow/.test(e.key): // return if editing canvas
+ case e.target.querySelector('.workspace-leaf-content[data-set="graph"]') && /Arrow/.test(e.key) && e.shiftKey: return; // return if graph active; use shift key to move graph
+ default: e.preventDefault(); // else prevent normal arrow behavior
+ }
let cursorAnchor = getActiveEditor()?.getCursor('anchor');
let activeTabGroupChildren = getActiveLeaf().workspace.activeTabGroup.children;
switch(e.key) {
@@ -145,7 +138,7 @@ class ContinuousModePlugin extends obsidian.Plugin {
break;
}
break;
- case 'ArrowDown': case 'ArrowRight':
+ case 'ArrowDown': case 'ArrowRight':
switch(true) {
case ( /html/.test(getActiveLeaf().view.getViewType()) && e.key === 'ArrowRight' ):
getActiveLeaf().containerEl.querySelector('iframe').focus();
@@ -198,20 +191,31 @@ class ContinuousModePlugin extends obsidian.Plugin {
let folder, active_split, new_split, new_tab, pin_leaf = true, pinned_tabs = [], bool = ( direction === 'left' ? false : direction === 'right' ? true : direction);
folder = ( file instanceof obsidian.TFile ? file.parent : file instanceof obsidian.TFolder ? file : null); // allows opening from folder as well as a file items
const isEmpty = (leaf) => { return leaf.getViewState().type === 'empty' }
+ let included_extensions = [];
+ let extensions = {
+ markdown:['md'],
+ images:['avif','bmp','jpg','jpeg','gif','^png','svg','webp'],
+ canvas:['canvas'],
+ media:['aac','aif','aiff','ape','flac','m4a','mka','mp3','ogg','opus','wav','m4v','mkv','mov','mp4','mpeg','webm'],
+ pdf:['pdf'],
+ extra:this.settings.extraFileTypes
+ };
+ for (const [key, value] of Object.entries(extensions)) {
+ if ( this.settings.folderFileTypes.includes(key) ) { included_extensions.push(value); } // build array of arrays of valid file types
+ }
+ included_extensions = new RegExp(included_extensions.flat().join('|'),'im'); // flatten array and convert list of valid file types into RegExp string
switch(true) {
case folder.children.length > 99 && !window.confirm('You are about to open '+ folder.children.length +'. Are you sure you want to do this?'): return; // warn on opening > 99 notes
- case folder.children.length === 0: return alert('Folder is empty.'); // folder is empty
- case folder.children.every( child => !/md|bmp|jpg|jpeg|gif|pdf|png|svg|webp/.test(child.extension) ): return alert('No readable files in folder.'); // no readable files
+ case folder.children.length === 0: return alert('Folder is empty.'); // folder is empty
+ case folder.children.every( child => ( !included_extensions.test(child.extension) || this.settings.excludedNames.some( name => { return RegExp(name,'m').test(child.name) } ) ) ):
+ return alert('No readable files in folder.'); // no readable files
}
-
- this_workspace.iterateRootLeaves( leaf => { // pin tabs
+ this_workspace.iterateRootLeaves( leaf => { // pin tabs to prevent reuse, i.e., coerce new tab creation
if ( leaf.pinned === true ) { pinned_tabs.push(leaf.id) } else { leaf.setPinned(true) } // make list of already pinned tabs or pin all unpinned tabs
});
-
switch(true) {
-// FIX: append folder > replace folder with same folder incorrectly adds first item again
- case bool === 'append': // append items to active tab group
- this_workspace.setActiveLeaf(this_workspace.getMostRecentLeaf(),{focus:true}); // set most recent leaf to active
+ case bool === 'append': // append items to active tab group
+ this_workspace.setActiveLeaf(this_workspace.getMostRecentLeaf(),{focus:true}); // set most recent leaf to active
if ( getActiveLeaf().parent.children.length === 1 && isEmpty(getActiveLeaf()) ) { this_workspace.activeLeaf.setPinned(false); } // unpin single active empty leaf
folder.children.forEach( file => {
getActiveTabGroup().children.forEach( leaf => {
@@ -219,26 +223,26 @@ class ContinuousModePlugin extends obsidian.Plugin {
});
});
break;
- case bool === 'replace': // close all leaves
+ case bool === 'replace': // close all leaves
this_workspace.setActiveLeaf(this_workspace.getMostRecentLeaf(),{focus:true});
getActiveTabGroup().children.forEach( child => {
sleep(0).then( () => {
child.setPinned(false);
child.detach();
});
- }); // unpin & close all leaves in active tab group
+ }); // unpin & close all leaves in active tab group
break;
- default: // i.e., bool === false || bool === true:
- new_split = ( direction === 'down' ? this_workspace.createLeafBySplit(this_workspace.getMostRecentLeaf(),'horizontal',false) : direction === 'up' ? this_workspace.createLeafBySplit(this_workspace.getMostRecentLeaf(),'horizontal',true) : this_workspace.createLeafBySplit(this_workspace.rootSplit,'vertical',bool) )
- // create new split before active split; bool === false => open split on left
+ default: // create new split left/right/up/down
+ new_split = ( direction === 'down' ? this_workspace.createLeafBySplit(this_workspace.getMostRecentLeaf(),'horizontal',false) : direction === 'up' ? this_workspace.createLeafBySplit(this_workspace.getMostRecentLeaf(),'horizontal',true) : this_workspace.createLeafBySplit(this_workspace.rootSplit,'vertical',bool) );
this_workspace.setActiveLeaf(this_workspace.getLeafById(new_split.id),{focus:true}); // focus new split
active_split = new_split;
- // folder.children.sort((a,b) => a.name.localeCompare(b.name),navigator.language); // sort files by name; change to allow other sorts? or add sorting elsewhere?
break;
}
-
+ // folder.children.sort((a,b) => a.name.localeCompare(b.name),navigator.language); // sort files by name; change to allow other sorts? or add sorting elsewhere?
folder.children.forEach( child => { // open the files
- if ( child instanceof obsidian.TFile && /md|bmp|jpg|jpeg|gif|pdf|png|svg|webp/.test(child.extension) ) { // TODO: include test for plugins that allow other file types to be opened
+ if ( this.settings.excludedNames.some( name => { return RegExp(name,'m').test(child.name) } ) ) { return } // ignore excluded file names
+ else
+ if ( child instanceof obsidian.TFile && ( included_extensions.test(child.extension) || this.settings.extraFileTypes.includes(child.extension) ) ) {
active_split = this_workspace.getLeaf(); // open new tab/leaf
active_split.openFile(child); // open file
active_split.setPinned(true); // pin new tab/leaf to prevent Obsidian reusing it to open next file in loop
@@ -251,7 +255,6 @@ class ContinuousModePlugin extends obsidian.Plugin {
this_workspace.setActiveLeaf(getActiveTabGroup().children[0]); // set active leaf
scrollActiveLeafIntoView(); // scroll into view
}
-
// REGISTER EVENTS
this.registerDomEvent(document,'click', function (e) {
switch(true) {
@@ -266,23 +269,24 @@ class ContinuousModePlugin extends obsidian.Plugin {
});
this.registerDomEvent(document,'dragstart',function(e) {
if ( !e.target.closest('.workspace-tabs')?.classList.contains('is_continuous_mode')) { return; }
- if ( e.target.classList.contains('workspace-tab-header') ) { onTabHeaderDragEnd(e,getTabHeaderIndex(e)); } // get initial tab header index for onTabHeaderDragEnd()
+ if ( e.target.classList.contains('workspace-tab-header') ) { onTabHeaderDragEnd(e,getTabHeaderIndex(e)); } // get initial tab header index for onTabHeaderDragEnd()
});
// ADD CONTEXTUAL MENU ITEMS
const icons = {
- panelTopDashed: '',
- appendFolder: '',
- replaceFolder: ''
+ appendFolder: ``,
+ panelTopDashed: ``,
+ replaceFolder: ``
}
const addIcons = () => {
Object.keys(icons).forEach((key) => {
(0, obsidian.addIcon)(key, icons[key]);
});
};
- const addContinuousModeMenuItem = (item,tab_group_id) => {
- item.setTitle('Continuous mode')
+ addIcons();
+ const addContinuousModeMenuItem = (item,tab_group_id,leaf) => {
+ item.setTitle('Continuous Mode')
.setIcon('scroll-text')
- .setSection('pane')
+ .setSection( leaf ? 'pane' : 'action' )
.setSubmenu().addItem((item2) => {
item2.setTitle('Toggle Continuous Mode')
.setIcon('scroll-text')
@@ -300,10 +304,10 @@ class ContinuousModePlugin extends obsidian.Plugin {
})
})
}
- const addContinuousModeFileExplorerItem = (item,file) => {
- item.setTitle('Continuous mode')
+ const openItemsInContinuousModeMenuItems = (item,file) => {
+ item.setTitle('Continuous Mode')
.setIcon('scroll-text')
- .setSection('pane')
+ .setSection('action')
.setSubmenu().addItem((item2) => {
item2.setTitle('Open folder in new split left')
.setIcon('panel-left-close')
@@ -332,7 +336,7 @@ class ContinuousModePlugin extends obsidian.Plugin {
openFolderInContinuousMode(file,'up');
})
})
- .addItem((item0) => { item0.setTitle('').setDisabled(true); })
+ .addSeparator()
.addItem((item6) => {
item6.setTitle('Open or append folder in active tab group')
.setIcon('appendFolder')
@@ -353,12 +357,12 @@ class ContinuousModePlugin extends obsidian.Plugin {
switch(true) {
case source !== 'file-explorer-context-menu':
menu.addItem((item) => {
- addContinuousModeMenuItem(item,leaf.containerEl.closest('.workspace-tabs').dataset.tab_group_id)
+ addContinuousModeMenuItem(item,leaf.containerEl.closest('.workspace-tabs').dataset.tab_group_id,leaf)
});
break;
case source === 'file-explorer-context-menu':
menu.addItem((item) => {
- addContinuousModeFileExplorerItem(item,file)
+ openItemsInContinuousModeMenuItems(item,file)
});
break;
}
@@ -378,21 +382,21 @@ class ContinuousModePlugin extends obsidian.Plugin {
this.app.workspace.on('tab-group-menu', (menu,tab_group) => {
menu.addItem((item) => { addContinuousModeMenuItem(item,tab_group.containerEl.dataset.tab_group_id) });
})
- );
+ );
this.registerEvent( // initContinuousMode on layout change
this.app.workspace.on('layout-change', async () => {
+ updateTabGroupDatasetIds();
+ initContinuousMode();
+ scrollActiveLeafIntoView();
+ })
+ );
+ this.registerEvent(
+ this.app.workspace.on('layout-ready', async () => { // initContinuousMode on layout ready
updateTabGroupDatasetIds();
- cleanDataTabGroupIds(); // disabled
initContinuousMode();
scrollActiveLeafIntoView();
})
);
- this.app.workspace.onLayoutReady( async () => { // initContinuousMode on layout ready
- updateTabGroupDatasetIds();
- cleanDataTabGroupIds(); // disabled
- initContinuousMode();
- scrollActiveLeafIntoView();
- })
// ADD COMMAND PALETTE ITEMS
this.addCommand({ // add command: toggle continuous mode in active tab group
id: 'toggle-continuous-mode-active',
@@ -421,5 +425,85 @@ class ContinuousModePlugin extends obsidian.Plugin {
async saveSettings() {
await this.saveData(this.settings);
}
-}
+} // end class ContinuousModePlugin
+// SETTINGS
+let ContinuousModeSettings = class extends obsidian.PluginSettingTab {
+ constructor(app, plugin) {
+ super(app, plugin);
+ this.plugin = plugin;
+ }
+ display() {
+ const { containerEl } = this;
+ containerEl.empty();
+ this.containerEl.createEl("h2", { text: '“Open folder in Continuous Mode” menu: filter included file types' })
+ this.containerEl.createEl('p', { text: 'Select file types to include when using the various “Open folder in Continuous Mode” contextual menu items in the file explorer. (Note: toggling off these settings does not prevent any of these file types from being opened manually.)'});
+ new obsidian.Setting(containerEl).setName('Include markdown').setDesc('Default.').setClass("setting-indent")
+ .addToggle( A => A.setValue(this.plugin.settings.folderFileTypes.length === 0 ? true : this.plugin.settings.folderFileTypes.includes('markdown'))
+ .onChange(async (value) => {
+ (value === true || this.plugin.settings.folderFileTypes.length === 0 ? this.plugin.settings.folderFileTypes.push('markdown') : this.plugin.settings.folderFileTypes.splice(this.plugin.settings.folderFileTypes.indexOf('markdown'),1));
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Include images').setDesc('Natively supported file types: avif, bmp, gif, jpg, png, svg, webp.').setClass("setting-indent")
+ .addToggle( A => A.setValue(this.plugin.settings.folderFileTypes.includes('images'))
+ .onChange(async (value) => {
+ (value === true ? this.plugin.settings.folderFileTypes.push('images') : this.plugin.settings.folderFileTypes.splice(this.plugin.settings.folderFileTypes.indexOf('images'),1));
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Include canvas files').setClass("setting-indent")
+ .addToggle( A => A.setValue(this.plugin.settings.folderFileTypes.includes('canvas'))
+ .onChange(async (value) => {
+ (value === true ? this.plugin.settings.folderFileTypes.push('canvas') : this.plugin.settings.folderFileTypes.splice(this.plugin.settings.folderFileTypes.indexOf('canvas'),1));
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Include media').setDesc('Natively supported file types: aac, aif, aiff, ape, flac, m4a, mka, mp3, ogg, opus, wav, m4v, mkv, mov, mp4, mpeg, webm.').setClass("setting-indent")
+ .addToggle( A => A.setValue(this.plugin.settings.folderFileTypes.includes('media'))
+ .onChange(async (value) => {
+ (value === true ? this.plugin.settings.folderFileTypes.push('media') : this.plugin.settings.folderFileTypes.splice(this.plugin.settings.folderFileTypes.indexOf('media'),1));
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Include pdfs').setClass("setting-indent")
+ .addToggle( A => A.setValue(this.plugin.settings.folderFileTypes.includes('pdf'))
+ .onChange(async (value) => {
+ (value === true ? this.plugin.settings.folderFileTypes.push('pdf') : this.plugin.settings.folderFileTypes.splice(this.plugin.settings.folderFileTypes.indexOf('pdf'),1));
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Include other file extensions').setDesc('If you have installed plugins that allow Obsidian to support file types or extensions not included above, add the file extensions here, comma-separated.').setClass("setting-indent")
+ .addText((value) => value.setPlaceholder("e.g. html, js, py, etc.").setValue(this.plugin.settings.extraFileTypes.join(','))
+ .onChange(async (value) => {
+ ( !this.plugin.settings.extraFileTypes.includes(value) ? this.plugin.settings.extraFileTypes = value.split(',') : null ); // add extra file extensions
+ await this.plugin.saveSettings();
+ }));
+ new obsidian.Setting(containerEl).setName('Excluded files').setDesc('Exclude files by name (including extension). Comma-separated, case-sensitive, partial name and Regex allowed. (Note: If the file name contains a comma, use a period [wildcard character] here instead.) Extensions added here will override the settings in the above categories.').setClass("setting-indent")
+ .addText((value) => value.setPlaceholder("e.g., “index.md”").setValue(this.plugin.settings.excludedNames.join(','))
+ .onChange(async (value) => {
+ ( !this.plugin.settings.excludedNames.includes(value) ? this.plugin.settings.excludedNames = value.split(',') : null ); // add excluded name if not already used
+ this.plugin.settings.excludedNames.forEach( name => { if ( name.length === 0 ) { this.plugin.settings.excludedNames.splice(this.plugin.settings.excludedNames.indexOf(name),1) } } )
+ await this.plugin.saveSettings();
+ }));
+ this.containerEl.createEl("h2", { text: "Other" });
+ new obsidian.Setting(containerEl).setName('Clear stored data').setDesc('Empty the list of stored tab groups, ignoring currently open tab groups with continuous mode active. This optional action prevents the list from getting unwieldy or cluttered with stale data, which can happen if you frequently open and close new tab groups.')
+ .addButton((button) => {
+ button.setButtonText('Clear');
+ button.buttonEl.addEventListener("click", async (e) => {
+ if ( window.confirm('Are you sure you want to clear all stored data?') ) {
+ this.plugin.settings.tabGroupIds = []; // empty stored tabGroupIds
+ this.app.workspace.rootSplit.children.forEach( child => { ( child.containerEl.classList.contains('is_continuous_mode') ? this.plugin.settings.tabGroupIds.push(this.app.appId +'_'+ child.id) : null ) }); // add back currently active tabGroupIds
+ await this.plugin.saveSettings();
+ }
+ })
+ });
+ new obsidian.Setting(containerEl).setName('Donate').setDesc('If you like this plugin, please consider donating to support continued development.')
+ .addButton((button) => {
+ button.buttonEl.setAttr("style", "background-color: transparent; height: 30pt; padding: 0px;");
+ const div = button.buttonEl.createDiv({ attr: { "style": "width: 100%; height: 100%" } });
+ div.createEl("a", { href: "https://www.buymeacoffee.com/fiLtliTFxQ" }).createEl("img", {
+ attr: {
+ style: "width: 100%; height: 100%",
+ src: 'https://cdn.buymeacoffee.com/buttons/v2/default-violet.png',
+ alt: 'Buy Me A Coffee'
+ }
+ });
+ });
+ } // end display()
+};
module.exports = ContinuousModePlugin;
diff --git a/manifest.json b/manifest.json
index e8a5b6d..399ef49 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,9 +1,9 @@
{
"id": "continuous-mode",
"name": "Continuous Mode",
- "version": "1.3.0",
+ "version": "1.4.0",
"minAppVersion": "0.15.0",
- "description": "Displays all open notes in a tab group as if they were a continuous scrollable document (sometimes called \"Scrivenings mode\"). Features include arrow navigation between notes and the ability to reorder notes via tab header drag-and-drop. ",
+ "description": "Displays all open notes in a tab group as if they were a continuous scrollable document (sometimes called \"Scrivenings mode\"). Features include arrow navigation between notes and the ability to reorder notes via tab header drag-and-drop.",
"author": "Michael Schrauzer",
"authorURL": "https://github.com/gasparschott/",
"fundingUrl": "https://www.buymeacoffee.com/fiLtliTFxQ",
diff --git a/styles.css b/styles.css
index f7797cc..1a01126 100644
--- a/styles.css
+++ b/styles.css
@@ -8,13 +8,18 @@
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf,
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .workspace-leaf-content:not([data-type="pdf"]),
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .workspace-leaf-content:not([data-type="pdf"]) .view-content,
-.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .workspace-leaf-content[data-mode="source"]:not([data-type="pdf"]):not([data-type="image"]) .view-content > div:not([style*="display"]),
+.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .workspace-leaf-content[data-mode="source"]:not([data-type="pdf"]):not([data-type="image"]):not([data-type="graph"]) .view-content > div:not([style*="display"]),
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .workspace-leaf-content[data-mode="source"]:not([data-type="pdf"]) .view-content .markdown-preview-view,
.workspace-leaf-content[data-type="empty"] .view-content .empty-state,
.workspace-leaf-content[data-type="empty"] .view-content .empty-state-container
{
display:contents !important;
}
+.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf
+.workspace-leaf-content[data-type="graph"] .view-content {
+ display:flex !important;
+}
+
/* padding bottom */
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container,
.workspace-split.mod-vertical.mod-root .workspace-tabs.is_continuous_mode:not(.mod-stacked) .workspace-tab-container .workspace-leaf .cm-editor .cm-content
@@ -120,7 +125,13 @@
.workspace.mod-root.workspace-tab-header {
min-width:100px;
}
-/*
+/* prevent canvas scroll in continuous mode */
+.workspace-tabs.is_continuous_mode .workspace-leaf:not(.mod-active) .canvas-wrapper,
+.workspace-tabs.is_continuous_mode .workspace-leaf:not(.mod-active) .workspace-leaf-content[data-type="graph"] .view-content
+{
+ pointer-events:none !important;
+}
+/* Dropdown menu for tab-headers?
.workspace-tab-header-container-inner {
flex-direction:column;
}