You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
620 lines
104 KiB
620 lines
104 KiB
2 years ago
|
'use strict';
|
||
|
|
||
|
var obsidian = require('obsidian');
|
||
|
|
||
|
/*! *****************************************************************************
|
||
|
Copyright (c) Microsoft Corporation.
|
||
|
|
||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||
|
purpose with or without fee is hereby granted.
|
||
|
|
||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||
|
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||
|
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||
|
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||
|
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||
|
PERFORMANCE OF THIS SOFTWARE.
|
||
|
***************************************************************************** */
|
||
|
/* global Reflect, Promise */
|
||
|
|
||
|
var extendStatics = function(d, b) {
|
||
|
extendStatics = Object.setPrototypeOf ||
|
||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||
|
return extendStatics(d, b);
|
||
|
};
|
||
|
|
||
|
function __extends(d, b) {
|
||
|
extendStatics(d, b);
|
||
|
function __() { this.constructor = d; }
|
||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||
|
}
|
||
|
|
||
|
function __awaiter(thisArg, _arguments, P, generator) {
|
||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function __generator(thisArg, body) {
|
||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||
|
function step(op) {
|
||
|
if (f) throw new TypeError("Generator is already executing.");
|
||
|
while (_) try {
|
||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||
|
switch (op[0]) {
|
||
|
case 0: case 1: t = op; break;
|
||
|
case 4: _.label++; return { value: op[1], done: false };
|
||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||
|
default:
|
||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||
|
if (t[2]) _.ops.pop();
|
||
|
_.trys.pop(); continue;
|
||
|
}
|
||
|
op = body.call(thisArg, _);
|
||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||
|
}
|
||
|
}
|
||
|
|
||
|
var SlidingPanesPlugin = /** @class */ (function (_super) {
|
||
|
__extends(SlidingPanesPlugin, _super);
|
||
|
function SlidingPanesPlugin() {
|
||
|
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||
|
// helper variables
|
||
|
_this.leavesOpenCount = 0;
|
||
|
_this.activeLeafIndex = 0;
|
||
|
// enable andy mode
|
||
|
_this.enable = function () {
|
||
|
// add the event handlers
|
||
|
_this.app.workspace.on('resize', _this.recalculateLeaves);
|
||
|
_this.app.workspace.on('file-open', _this.handleFileOpen);
|
||
|
_this.app.vault.on('delete', _this.handleDelete);
|
||
|
// wait for layout to be ready to perform the rest
|
||
|
_this.app.workspace.layoutReady ? _this.reallyEnable() : _this.app.workspace.on('layout-ready', _this.reallyEnable);
|
||
|
};
|
||
|
// really enable things (once the layout is ready)
|
||
|
_this.reallyEnable = function () {
|
||
|
// we don't need the event handler anymore
|
||
|
_this.app.workspace.off('layout-ready', _this.reallyEnable);
|
||
|
// backup the function so I can restore it
|
||
|
_this.rootSplitAny.oldOnChildResizeStart = _this.rootSplitAny.onChildResizeStart;
|
||
|
_this.rootSplitAny.onChildResizeStart = _this.onChildResizeStart;
|
||
|
// add some extra classes that can't fit in the styles.css
|
||
|
// because they use settings
|
||
|
_this.addStyle();
|
||
|
// do all the calucations necessary for the workspace leaves
|
||
|
_this.recalculateLeaves();
|
||
|
};
|
||
|
// shut down andy mode
|
||
|
_this.disable = function () {
|
||
|
// get rid of the extra style tag we added
|
||
|
_this.removeStyle();
|
||
|
// iterate through the root leaves to remove the stuff we added
|
||
|
_this.rootLeaves.forEach(function (leaf) {
|
||
|
leaf.containerEl.style.width = null;
|
||
|
leaf.containerEl.style.left = null;
|
||
|
leaf.containerEl.style.right = null;
|
||
|
});
|
||
|
// restore the default functionality
|
||
|
_this.rootSplitAny.onChildResizeStart = _this.rootSplitAny.oldOnChildResizeStart;
|
||
|
// get rid of our event handlers
|
||
|
_this.app.workspace.off('resize', _this.recalculateLeaves);
|
||
|
_this.app.workspace.off('file-open', _this.handleFileOpen);
|
||
|
_this.app.vault.off('delete', _this.handleDelete);
|
||
|
_this.suggestionContainerObserver.disconnect();
|
||
|
};
|
||
|
// refresh funcion for when we change settings
|
||
|
_this.refresh = function () {
|
||
|
// re-load the style
|
||
|
_this.updateStyle();
|
||
|
// recalculate leaf positions
|
||
|
_this.recalculateLeaves();
|
||
|
};
|
||
|
// remove the stlying elements we've created
|
||
|
_this.removeStyle = function () {
|
||
|
var el = document.getElementById('plugin-sliding-panes');
|
||
|
if (el)
|
||
|
el.remove();
|
||
|
document.body.classList.remove('plugin-sliding-panes');
|
||
|
document.body.classList.remove('plugin-sliding-panes-rotate-header');
|
||
|
document.body.classList.remove('plugin-sliding-panes-header-alt');
|
||
|
document.body.classList.remove('plugin-sliding-panes-stacking');
|
||
|
};
|
||
|
// add the styling elements we need
|
||
|
_this.addStyle = function () {
|
||
|
// add a css block for our settings-dependent styles
|
||
|
var css = document.createElement('style');
|
||
|
css.id = 'plugin-sliding-panes';
|
||
|
document.getElementsByTagName("head")[0].appendChild(css);
|
||
|
// add the main class
|
||
|
document.body.classList.add('plugin-sliding-panes');
|
||
|
// update the style with the settings-dependent styles
|
||
|
_this.updateStyle();
|
||
|
};
|
||
|
// update the styles (at the start, or as the result of a settings change)
|
||
|
_this.updateStyle = function () {
|
||
|
// if we've got rotate headers on, add the class which enables it
|
||
|
document.body.classList.toggle('plugin-sliding-panes-rotate-header', _this.settings.rotateHeaders);
|
||
|
document.body.classList.toggle('plugin-sliding-panes-header-alt', _this.settings.headerAlt);
|
||
|
// do the same for stacking
|
||
|
document.body.classList.toggle('plugin-sliding-panes-stacking', _this.settings.stackingEnabled);
|
||
|
// get the custom css element
|
||
|
var el = document.getElementById('plugin-sliding-panes');
|
||
|
if (!el)
|
||
|
throw "plugin-sliding-panes element not found!";
|
||
|
else {
|
||
|
// set the settings-dependent css
|
||
|
el.innerText = "body.plugin-sliding-panes{--header-width:" + _this.settings.headerWidth + "px;}";
|
||
|
if (!_this.settings.leafAutoWidth) {
|
||
|
el.innerText += "body.plugin-sliding-panes .mod-root>.workspace-leaf{width:" + (_this.settings.leafWidth + _this.settings.headerWidth) + "px;}";
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
// Recalculate the leaf sizing and positions
|
||
|
_this.recalculateLeaves = function () {
|
||
|
// rootSplit.children is undocumented for now, but it's easier to use for what we're doing.
|
||
|
// we only want leaves at the root of the root split
|
||
|
// (this is to fix compatibility with backlinks in document and other such plugins)
|
||
|
var rootContainerEl = _this.rootContainerEl;
|
||
|
var rootLeaves = _this.rootLeaves;
|
||
|
var leafCount = rootLeaves.length;
|
||
|
var totalWidth = 0;
|
||
|
// iterate through all the root-level leaves
|
||
|
// keep the leaf as `any` to get the undocumented containerEl
|
||
|
var widthChange = false;
|
||
|
rootLeaves.forEach(function (leaf, i) {
|
||
|
leaf.containerEl.style.flex = null;
|
||
|
var oldWidth = leaf.containerEl.clientWidth;
|
||
|
if (_this.settings.leafAutoWidth) {
|
||
|
leaf.containerEl.style.width = (rootContainerEl.clientWidth - ((leafCount - 1) * _this.settings.headerWidth)) + "px";
|
||
|
}
|
||
|
else {
|
||
|
leaf.containerEl.style.width = null;
|
||
|
}
|
||
|
if (oldWidth == leaf.containerEl.clientWidth)
|
||
|
widthChange = true;
|
||
|
leaf.containerEl.style.left = _this.settings.stackingEnabled
|
||
|
? (i * _this.settings.headerWidth) + "px"
|
||
|
: null;
|
||
|
leaf.containerEl.style.right = _this.settings.stackingEnabled
|
||
|
? (((leafCount - i) * _this.settings.headerWidth) - leaf.containerEl.clientWidth) + "px"
|
||
|
: null;
|
||
|
// keep track of the total width of all leaves
|
||
|
totalWidth += leaf.containerEl.clientWidth;
|
||
|
});
|
||
|
// if the total width of all leaves is less than the width available,
|
||
|
// add back the flex class so they fill the space
|
||
|
if (totalWidth < rootContainerEl.clientWidth) {
|
||
|
rootLeaves.forEach(function (leaf) {
|
||
|
leaf.containerEl.style.flex = '1 0 0';
|
||
|
});
|
||
|
}
|
||
|
if (widthChange)
|
||
|
_this.focusActiveLeaf(!_this.settings.leafAutoWidth);
|
||
|
};
|
||
|
// this function is called, not only when a file opens, but when the active pane is switched
|
||
|
_this.handleFileOpen = function (e) {
|
||
|
// put a small timeout on it because when a file is opened on the far right
|
||
|
// it wasn't focussing properly. The timeout fixes this
|
||
|
setTimeout(function () {
|
||
|
// check for a closed leaf and activate the adjacent leaf if it was
|
||
|
_this.activateAdjacentLeafIfClosed(e);
|
||
|
// focus on the newly selected leaf
|
||
|
_this.focusLeaf(e);
|
||
|
}, 10);
|
||
|
};
|
||
|
// check for a closed leaf and activate the adjacent leaf
|
||
|
_this.activateAdjacentLeafIfClosed = function (e) { return __awaiter(_this, void 0, void 0, function () {
|
||
|
var rootLeaves, leafCount, isActiveLeafSet_1;
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_a) {
|
||
|
// check that rootSplitAny is a thing first
|
||
|
// (it might not be if the workspace is reloading?)
|
||
|
if (this.rootSplitAny) {
|
||
|
rootLeaves = this.rootLeaves;
|
||
|
leafCount = rootLeaves.length;
|
||
|
isActiveLeafSet_1 = false;
|
||
|
// if the number of open leaves has changed
|
||
|
if (leafCount != this.leavesOpenCount) {
|
||
|
// if the number of leaves is < our last saved value, we must have closed one (or more)
|
||
|
if (leafCount < this.leavesOpenCount) {
|
||
|
// iterate through the leaves
|
||
|
this.rootLeaves.forEach(function (leaf, i) {
|
||
|
// if we haven't activated a leaf yet and this leaf is adjacent to the closed one
|
||
|
if (!isActiveLeafSet_1 && (i >= _this.activeLeafIndex - 1)) {
|
||
|
// set the active leaf (undocumented, hence `any`)
|
||
|
_this.app.workspace.setActiveLeaf(leaf);
|
||
|
isActiveLeafSet_1 = true;
|
||
|
// set the index for next time, also.
|
||
|
_this.activeLeafIndex = i;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
// set the new open count
|
||
|
this.leavesOpenCount = leafCount;
|
||
|
// recalculate leaf positions
|
||
|
this.recalculateLeaves();
|
||
|
}
|
||
|
}
|
||
|
return [2 /*return*/];
|
||
|
});
|
||
|
}); };
|
||
|
_this.focusLeaf = function (file) {
|
||
|
_this.focusActiveLeaf();
|
||
|
};
|
||
|
// hande when a file is deleted
|
||
|
_this.handleDelete = function (file) {
|
||
|
// close any leaves with the deleted file open
|
||
|
// detaching a leaf while iterating messes with the iteration
|
||
|
var leavesToDetach = [];
|
||
|
_this.app.workspace.iterateRootLeaves(function (leaf) {
|
||
|
if (leaf.view instanceof obsidian.FileView && leaf.view.file == file) {
|
||
|
leavesToDetach.push(leaf);
|
||
|
}
|
||
|
});
|
||
|
leavesToDetach.forEach(function (leaf) { return leaf.detach(); });
|
||
|
};
|
||
|
// position the suggestion container underneath the cursor for links and tags
|
||
|
_this.positionSuggestionContainer = function (scNode) {
|
||
|
var cmEditor = _this.app.workspace.activeLeaf.view.sourceMode.cmEditor;
|
||
|
// find the open bracket or hashtag to the left of or at the cursor
|
||
|
var cursorPosition = cmEditor.getCursor();
|
||
|
var currentToken = cmEditor.getTokenAt(cmEditor.getCursor());
|
||
|
var scCursorPosition;
|
||
|
// there's no text yet
|
||
|
if (currentToken.string === '[]' || currentToken.string === '#') {
|
||
|
scCursorPosition = cursorPosition;
|
||
|
}
|
||
|
// there is text
|
||
|
else {
|
||
|
// search the current line for the closest open bracket or a hashtag to the left
|
||
|
var lineTokens = cmEditor.getLineTokens(cursorPosition.line);
|
||
|
var previousTokens = lineTokens.filter(function (token) { return token.start <= currentToken.start; }).reverse();
|
||
|
var hashtagOrBracketsToken = previousTokens.find(function (token) { return token.string.contains('[') || token.string.contains('#'); });
|
||
|
if (hashtagOrBracketsToken) {
|
||
|
// position the suggestion container to just underneath the end of the open brackets
|
||
|
scCursorPosition = { line: cursorPosition.line, ch: hashtagOrBracketsToken.end };
|
||
|
}
|
||
|
else {
|
||
|
// hashtagOrBracketsToken shouldn't be undefined, so this is just to be safe
|
||
|
scCursorPosition = cursorPosition;
|
||
|
}
|
||
|
}
|
||
|
var scCoords = cmEditor.charCoords(scCursorPosition);
|
||
|
// make sure it fits within the window
|
||
|
var appContainerEl = _this.app.dom.appContainerEl;
|
||
|
var scRight = scCoords.left + scNode.offsetWidth;
|
||
|
var appWidth = appContainerEl.offsetWidth;
|
||
|
if (scRight > appWidth) {
|
||
|
scCoords.left -= scRight - appWidth;
|
||
|
}
|
||
|
// set the left coord
|
||
|
// the top coord is set by Obsidian and is correct.
|
||
|
// it's also a pain to try to recalculate so I left it out.
|
||
|
scNode.style.left = Math.max(scCoords.left, 0) + 'px';
|
||
|
};
|
||
|
// overriden function for rootSplit child resize
|
||
|
_this.onChildResizeStart = function (leaf, event) {
|
||
|
// only really apply this to vertical splits
|
||
|
if (_this.rootSplitAny.direction === "vertical") {
|
||
|
// this is the width the leaf started at before resize
|
||
|
var startWidth_1 = leaf.containerEl.clientWidth;
|
||
|
// the mousemove event to trigger while resizing
|
||
|
var mousemove_1 = function (e) {
|
||
|
// get the difference between the first position and current
|
||
|
var deltaX = e.pageX - event.pageX;
|
||
|
// adjust the start width by the delta
|
||
|
leaf.containerEl.style.width = startWidth_1 + deltaX + "px";
|
||
|
};
|
||
|
// the mouseup event to trigger at the end of resizing
|
||
|
var mouseup_1 = function () {
|
||
|
// if stacking is enabled, we need to re-jig the "right" value
|
||
|
if (_this.settings.stackingEnabled) {
|
||
|
// we need the leaf count and index to calculate the correct value
|
||
|
var rootLeaves = _this.rootLeaves;
|
||
|
var leafCount = rootLeaves.length;
|
||
|
var leafIndex = rootLeaves.findIndex(function (l) { return l == leaf; });
|
||
|
leaf.containerEl.style.right = (((leafCount - leafIndex - 1) * _this.settings.headerWidth) - leaf.containerEl.clientWidth) + "px";
|
||
|
}
|
||
|
// remove these event listeners. We're done with them
|
||
|
document.removeEventListener("mousemove", mousemove_1);
|
||
|
document.removeEventListener("mouseup", mouseup_1);
|
||
|
};
|
||
|
// Add the above two event listeners
|
||
|
document.addEventListener("mousemove", mousemove_1);
|
||
|
document.addEventListener("mouseup", mouseup_1);
|
||
|
}
|
||
|
};
|
||
|
return _this;
|
||
|
}
|
||
|
Object.defineProperty(SlidingPanesPlugin.prototype, "rootSplitAny", {
|
||
|
// helper gets for any casts (for undocumented API stuff)
|
||
|
get: function () { return this.app.workspace.rootSplit; },
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
Object.defineProperty(SlidingPanesPlugin.prototype, "rootContainerEl", {
|
||
|
get: function () { return this.rootSplitAny.containerEl; },
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
Object.defineProperty(SlidingPanesPlugin.prototype, "rootLeaves", {
|
||
|
get: function () {
|
||
|
var rootContainerEl = this.rootContainerEl;
|
||
|
var rootLeaves = [];
|
||
|
this.app.workspace.iterateRootLeaves(function (leaf) {
|
||
|
if (leaf.containerEl.parentElement === rootContainerEl) {
|
||
|
rootLeaves.push(leaf);
|
||
|
}
|
||
|
});
|
||
|
return rootLeaves;
|
||
|
},
|
||
|
enumerable: false,
|
||
|
configurable: true
|
||
|
});
|
||
|
// when the plugin is loaded
|
||
|
SlidingPanesPlugin.prototype.onload = function () {
|
||
|
return __awaiter(this, void 0, void 0, function () {
|
||
|
var _a, observerTarget, observerConfig;
|
||
|
var _this = this;
|
||
|
return __generator(this, function (_b) {
|
||
|
switch (_b.label) {
|
||
|
case 0:
|
||
|
// load settings
|
||
|
_a = this;
|
||
|
return [4 /*yield*/, this.loadData()];
|
||
|
case 1:
|
||
|
// load settings
|
||
|
_a.settings = (_b.sent()) || new SlidingPanesSettings();
|
||
|
// if it's not disabled in the settings, enable it
|
||
|
if (!this.settings.disabled) {
|
||
|
this.enable();
|
||
|
}
|
||
|
// add the settings tab
|
||
|
this.addSettingTab(new SlidingPanesSettingTab(this.app, this));
|
||
|
// add the toggle on/off command
|
||
|
this.addCommand({
|
||
|
id: 'toggle-sliding-panes',
|
||
|
name: 'Toggle Sliding Panes',
|
||
|
callback: function () {
|
||
|
// switch the disabled setting and save
|
||
|
_this.settings.disabled = !_this.settings.disabled;
|
||
|
_this.saveData(_this.settings);
|
||
|
// disable or enable as necessary
|
||
|
_this.settings.disabled ? _this.disable() : _this.enable();
|
||
|
}
|
||
|
});
|
||
|
// add a command to toggle leaf auto width
|
||
|
this.addCommand({
|
||
|
id: 'toggle-sliding-panes-leaf-auto-width',
|
||
|
name: 'Toggle Leaf Auto Width',
|
||
|
callback: function () {
|
||
|
// switch the setting, save and refresh
|
||
|
_this.settings.leafAutoWidth = !_this.settings.leafAutoWidth;
|
||
|
_this.saveData(_this.settings);
|
||
|
_this.refresh();
|
||
|
}
|
||
|
});
|
||
|
// add a command to toggle stacking
|
||
|
this.addCommand({
|
||
|
id: 'toggle-sliding-panes-stacking',
|
||
|
name: 'Toggle Stacking',
|
||
|
callback: function () {
|
||
|
// switch the setting, save and refresh
|
||
|
_this.settings.stackingEnabled = !_this.settings.stackingEnabled;
|
||
|
_this.saveData(_this.settings);
|
||
|
_this.refresh();
|
||
|
}
|
||
|
});
|
||
|
// add a command to toggle rotated headers
|
||
|
this.addCommand({
|
||
|
id: 'toggle-sliding-panes-rotated-headers',
|
||
|
name: 'Toggle Rotated Headers',
|
||
|
callback: function () {
|
||
|
// switch the setting, save and refresh
|
||
|
_this.settings.rotateHeaders = !_this.settings.rotateHeaders;
|
||
|
_this.saveData(_this.settings);
|
||
|
_this.refresh();
|
||
|
}
|
||
|
});
|
||
|
// add a command to toggle swapped header direction
|
||
|
this.addCommand({
|
||
|
id: 'toggle-sliding-panes-header-alt',
|
||
|
name: 'Swap rotated header direction',
|
||
|
callback: function () {
|
||
|
// switch the setting, save and refresh
|
||
|
_this.settings.headerAlt = !_this.settings.headerAlt;
|
||
|
_this.saveData(_this.settings);
|
||
|
_this.refresh();
|
||
|
}
|
||
|
});
|
||
|
// observe the app-container for when the suggestion-container appears
|
||
|
this.suggestionContainerObserver = new MutationObserver(function (mutations) {
|
||
|
mutations.forEach(function (mutation) {
|
||
|
mutation.addedNodes.forEach(function (node) {
|
||
|
if (node.className === 'suggestion-container') {
|
||
|
_this.positionSuggestionContainer(node);
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
observerTarget = this.app.dom.appContainerEl;
|
||
|
observerConfig = { childList: true };
|
||
|
this.suggestionContainerObserver.observe(observerTarget, observerConfig);
|
||
|
return [2 /*return*/];
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
};
|
||
|
// on unload, perform the same steps as disable
|
||
|
SlidingPanesPlugin.prototype.onunload = function () {
|
||
|
this.disable();
|
||
|
};
|
||
|
SlidingPanesPlugin.prototype.focusActiveLeaf = function (animated) {
|
||
|
var _this = this;
|
||
|
if (animated === void 0) { animated = true; }
|
||
|
// get back to the leaf which has been andy'd (`any` because parentSplit is undocumented)
|
||
|
var activeLeaf = this.app.workspace.activeLeaf;
|
||
|
while (activeLeaf != null && activeLeaf.parentSplit != null && activeLeaf.parentSplit != this.app.workspace.rootSplit) {
|
||
|
activeLeaf = activeLeaf.parentSplit;
|
||
|
}
|
||
|
if (activeLeaf != null && this.rootSplitAny) {
|
||
|
var rootContainerEl = this.rootContainerEl;
|
||
|
var rootLeaves = this.rootLeaves;
|
||
|
var leafCount = rootLeaves.length;
|
||
|
// get the index of the active leaf
|
||
|
// also, get the position of this leaf, so we can scroll to it
|
||
|
// as leaves are resizable, we have to iterate through all leaves to the
|
||
|
// left until we get to the active one and add all their widths together
|
||
|
var position_1 = 0;
|
||
|
this.activeLeafIndex = -1;
|
||
|
rootLeaves.forEach(function (leaf, index) {
|
||
|
// this is the active one
|
||
|
if (leaf == activeLeaf) {
|
||
|
_this.activeLeafIndex = index;
|
||
|
leaf.containerEl.classList.remove('mod-am-left-of-active');
|
||
|
leaf.containerEl.classList.remove('mod-am-right-of-active');
|
||
|
}
|
||
|
else if (_this.activeLeafIndex == -1 || index < _this.activeLeafIndex) {
|
||
|
// this is before the active one, add the width
|
||
|
position_1 += leaf.containerEl.clientWidth;
|
||
|
leaf.containerEl.classList.add('mod-am-left-of-active');
|
||
|
leaf.containerEl.classList.remove('mod-am-right-of-active');
|
||
|
}
|
||
|
else {
|
||
|
// this is right of the active one
|
||
|
leaf.containerEl.classList.remove('mod-am-left-of-active');
|
||
|
leaf.containerEl.classList.add('mod-am-right-of-active');
|
||
|
}
|
||
|
});
|
||
|
// get this leaf's left value (the amount of space to the left for sticky headers)
|
||
|
var left = parseInt(activeLeaf.containerEl.style.left) || 0;
|
||
|
// the amount of space to the right we need to leave for sticky headers
|
||
|
var headersToRightWidth = this.settings.stackingEnabled ? (leafCount - this.activeLeafIndex - 1) * this.settings.headerWidth : 0;
|
||
|
// it's too far left
|
||
|
if (rootContainerEl.scrollLeft > position_1 - left) {
|
||
|
// scroll the left side of the pane into view
|
||
|
rootContainerEl.scrollTo({ left: position_1 - left, top: 0, behavior: animated ? 'smooth' : 'auto' });
|
||
|
}
|
||
|
// it's too far right
|
||
|
else if (rootContainerEl.scrollLeft + rootContainerEl.clientWidth < position_1 + activeLeaf.containerEl.clientWidth + headersToRightWidth) {
|
||
|
// scroll the right side of the pane into view
|
||
|
rootContainerEl.scrollTo({ left: position_1 + activeLeaf.containerEl.clientWidth + headersToRightWidth - rootContainerEl.clientWidth, top: 0, behavior: animated ? 'smooth' : 'auto' });
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
return SlidingPanesPlugin;
|
||
|
}(obsidian.Plugin));
|
||
|
var SlidingPanesSettings = /** @class */ (function () {
|
||
|
function SlidingPanesSettings() {
|
||
|
this.headerWidth = 32;
|
||
|
this.leafWidth = 700;
|
||
|
this.leafAutoWidth = false;
|
||
|
this.disabled = false;
|
||
|
this.rotateHeaders = true;
|
||
|
this.headerAlt = false;
|
||
|
this.stackingEnabled = true;
|
||
|
}
|
||
|
return SlidingPanesSettings;
|
||
|
}());
|
||
|
var SlidingPanesSettingTab = /** @class */ (function (_super) {
|
||
|
__extends(SlidingPanesSettingTab, _super);
|
||
|
function SlidingPanesSettingTab(app, plugin) {
|
||
|
var _this = _super.call(this, app, plugin) || this;
|
||
|
_this.plugin = plugin;
|
||
|
return _this;
|
||
|
}
|
||
|
SlidingPanesSettingTab.prototype.display = function () {
|
||
|
var _this = this;
|
||
|
var containerEl = this.containerEl;
|
||
|
containerEl.empty();
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName("Toggle Sliding Panes")
|
||
|
.setDesc("Turns sliding panes on or off globally")
|
||
|
.addToggle(function (toggle) { return toggle.setValue(!_this.plugin.settings.disabled)
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.disabled = !value;
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
if (_this.plugin.settings.disabled) {
|
||
|
_this.plugin.disable();
|
||
|
}
|
||
|
else {
|
||
|
_this.plugin.enable();
|
||
|
}
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Leaf Auto Width')
|
||
|
.setDesc('If on, the width of the pane should fill the available space')
|
||
|
.addToggle(function (toggle) { return toggle.setValue(_this.plugin.settings.leafAutoWidth)
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.leafAutoWidth = value;
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Leaf Width')
|
||
|
.setDesc('The width of a single pane (only if auto width is off)')
|
||
|
.addText(function (text) { return text.setPlaceholder('Example: 700')
|
||
|
.setValue((_this.plugin.settings.leafWidth || '') + '')
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.leafWidth = parseInt(value.trim());
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName("Toggle rotated headers")
|
||
|
.setDesc("Rotates headers to use as spines")
|
||
|
.addToggle(function (toggle) { return toggle.setValue(_this.plugin.settings.rotateHeaders)
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.rotateHeaders = value;
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName("Swap rotated header direction")
|
||
|
.setDesc("Swaps the direction of rotated headers")
|
||
|
.addToggle(function (toggle) { return toggle.setValue(_this.plugin.settings.headerAlt)
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.headerAlt = value;
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName("Toggle stacking")
|
||
|
.setDesc("Panes will stack up to the left and right")
|
||
|
.addToggle(function (toggle) { return toggle.setValue(_this.plugin.settings.stackingEnabled)
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.stackingEnabled = value;
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
new obsidian.Setting(containerEl)
|
||
|
.setName('Spine Width')
|
||
|
.setDesc('The width of the rotated header (or gap) for stacking')
|
||
|
.addText(function (text) { return text.setPlaceholder('Example: 32')
|
||
|
.setValue((_this.plugin.settings.headerWidth || '') + '')
|
||
|
.onChange(function (value) {
|
||
|
_this.plugin.settings.headerWidth = parseInt(value.trim());
|
||
|
_this.plugin.saveData(_this.plugin.settings);
|
||
|
_this.plugin.refresh();
|
||
|
}); });
|
||
|
};
|
||
|
return SlidingPanesSettingTab;
|
||
|
}(obsidian.PluginSettingTab));
|
||
|
|
||
|
module.exports = SlidingPanesPlugin;
|
||
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsIm1haW4udHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyohICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbkNvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLlxyXG5cclxuUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55XHJcbnB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZC5cclxuXHJcblRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEhcclxuUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZXHJcbkFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIERJUkVDVCxcclxuSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NXHJcbkxPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SXHJcbk9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1JcclxuUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS5cclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi9cclxuLyogZ2xvYmFsIFJlZmxlY3QsIFByb21pc2UgKi9cclxuXHJcbnZhciBleHRlbmRTdGF0aWNzID0gZnVuY3Rpb24oZCwgYikge1xyXG4gICAgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYiwgcCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbn07XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gX19leHRlbmRzKGQsIGIpIHtcclxuICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxufVxyXG5cclxuZXhwb3J0IHZhciBfX2Fzc2lnbiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgX19hc3NpZ24gPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uIF9fYXNzaWduKHQpIHtcclxuICAgICAgICBmb3IgKHZhciBzLCBpID0gMSwgbiA9IGFyZ3VtZW50cy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcclxuICAgICAgICAgICAgcyA9IGFyZ3VtZW50c1tpXTtcclxuICAgICAgICAgICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApKSB0W3BdID0gc1twXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gX19hc3NpZ24uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fcmVzdChzLCBlKSB7XHJcbiAgICB2YXIgdCA9IHt9O1xyXG4gICAgZm9yICh2YXIgcCBpbiBzKSBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHMsIHApICYmIGUuaW5kZXhPZihwKSA8IDApXHJcbiAgICAgICAgdFtwXSA9IHNbcF07XHJcbiAgICBpZiAocyAhPSBudWxsICYmIHR5cGVvZiBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzID09PSBcImZ1bmN0aW9uXCIpXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIHAgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlTeW1ib2xzKHMpOyBpIDwgcC5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAoZS5pbmRleE9mKHBbaV0pIDwgMCAmJiBPYmplY3QucHJvdG90eXBlLnByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwocywgcFtpXSkpXHJcbiAgICAgICAgICAgICAgICB0W3BbaV1dID0gc1twW2ldXTtcclxuICAgICAgICB9XHJcbiAgICByZXR1cm4gdDtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIF9fZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpIHtcclxuICAgIHZhciBjID0gYXJndW1lbnRzLmxlbmd0aCwgciA9IGMgPCAzID8gdGFyZ2V0IDogZGVzYyA9PT0gbnVsbCA/IGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHRhcmdldCwga2V5KSA6IGRlc2MsIGQ7XHJcbiAgICBpZiAodHlwZW9mIFJlZmxlY3QgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIFJlZmxlY3QuZGVjb3JhdGUgPT09IFwiZnVuY3Rpb25cIikgciA9IFJlZmxlY3QuZGVjb3JhdGUoZGVjb3JhdG9ycywgdGFyZ2V0LCBrZXksIGRlc2MpO1xyXG4gICAgZWxzZSBmb3IgKHZhciBpID0gZGVjb3JhdG9ycy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgaWYgKGQgPSBkZWNvcmF0b3JzW2ldKSByID0gKGMgPCAzID8gZChyKSA6IGMgPiAzID8gZCh0YXJnZXQsIGtleSwgcikgOiBkKHRhcmdldCwga2V5KSkgfHwgcjtcclxuICAgIHJldHVybiBjID4gMyAmJiByICYmIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0YXJnZXQsIGtleSwgciksIHI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBfX3BhcmF
|