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.

726 lines
67 KiB

3 years ago
/*
THIS IS A GENERATED/BUNDLED FILE BY ROLLUP
if you want to view the source visit the plugins github repository
*/
'use strict';
var obsidian = require('obsidian');
2 years ago
/******************************************************************************
3 years ago
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.
***************************************************************************** */
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());
});
}
const DEFAULT_SETTINGS = {
expansionMode: 'expanded',
ignoreNulls: false,
nullValue: '',
skipKey: 'metatable',
ignoredKeys: [],
filterKeys: ['metatable', 'frontmatter'],
filterMode: 'ignore',
autolinks: false,
3 years ago
naked: false,
3 years ago
vault: null,
};
class MetatableSettingTab extends obsidian.PluginSettingTab {
constructor(app, plugin) {
super(app, plugin);
this.plugin = plugin;
}
display() {
return __awaiter(this, void 0, void 0, function* () {
const { containerEl, plugin } = this;
containerEl.empty();
containerEl.createEl('h2', { text: 'Metatable Settings' });
new obsidian.Setting(containerEl)
.setName('Expansion level')
.setDesc('Level of expansion of the metatable tree')
.addDropdown(drop => drop
.addOption('expanded', 'Fully expanded')
.addOption('leaf-collapsed', 'Collapse leafs')
.addOption('all-collapsed', 'Collapse all')
3 years ago
.addOption('root-collapsed', 'Collapse root')
3 years ago
.setValue(plugin.settings.expansionMode)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.expansionMode = value;
yield plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName('Skip key')
.setDesc('When this key is found and `true`, the metatable will not be displayed')
.addText(text => text
.setValue(plugin.settings.skipKey)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.skipKey = value;
yield plugin.saveSettings();
})));
containerEl.createEl('h3', { text: 'Nulls' });
new obsidian.Setting(containerEl)
.setName('Ignore null values')
.setDesc('Ignore any member with a null value.')
.addToggle(setting => setting
.setValue(plugin.settings.ignoreNulls)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.ignoreNulls = value;
yield plugin.saveSettings();
this.display();
})));
if (!plugin.settings.ignoreNulls) {
new obsidian.Setting(containerEl)
.setName('Null value')
.setDesc('Text to show when a key has no value. Defaults to nothing')
.addText(text => text
.setValue(plugin.settings.nullValue)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.nullValue = value;
yield plugin.saveSettings();
})));
}
containerEl.createEl('h3', { text: 'Filter' });
new obsidian.Setting(containerEl)
.setName('Filter mode')
.setDesc('Either ignore or keep the filter keys')
.addDropdown(drop => drop
.addOption('ignore', 'Ignore')
.addOption('keep', 'Keep')
.setValue(plugin.settings.filterMode)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.filterMode = value;
yield plugin.saveSettings();
})));
new obsidian.Setting(containerEl)
.setName('Filter keys')
3 years ago
.setDesc('Any empty field will be ignored.');
2 years ago
let keyset = plugin.settings.filterKeys;
3 years ago
let filterKeys = containerEl.createEl('ol');
2 years ago
for (const [idx, originalValue] of [...keyset].entries()) {
if (originalValue === '') {
continue;
}
addFilterInput(originalValue, filterKeys, keyset, plugin, idx);
3 years ago
}
new obsidian.Setting(containerEl)
.addButton(x => x
.setButtonText("Add key")
.onClick(() => __awaiter(this, void 0, void 0, function* () {
2 years ago
addFilterInput('', filterKeys, keyset, plugin, keyset.length);
3 years ago
})));
containerEl.createEl('h3', { text: 'Experimental' });
new obsidian.Setting(containerEl)
.setName('Autolink')
.setDesc('Enables autolinks for wikilinks `[[target]]`, frontmatter links `%target%` and local links `./deep/target`')
.addToggle(setting => setting
.setValue(plugin.settings.autolinks)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.autolinks = value;
yield plugin.saveSettings();
})));
3 years ago
new obsidian.Setting(containerEl)
.setName('Naked')
.setDesc('Removes the Shadow DOM and the default CSS so you can bring your own via CSS snippets.')
.addToggle(setting => setting
.setValue(plugin.settings.naked)
.onChange((value) => __awaiter(this, void 0, void 0, function* () {
plugin.settings.naked = value;
yield plugin.saveSettings();
})));
3 years ago
});
}
}
2 years ago
function addFilterInput(originalValue, el, keyset, plugin, idx) {
3 years ago
const item = el.createEl('li');
const input = item.createEl('input');
2 years ago
item.setAttribute('id', `filter-${idx}`);
3 years ago
input.setAttribute('type', 'text');
input.setAttribute('value', originalValue);
input.setAttribute('data-prev', originalValue);
input.addEventListener('input', (e) => __awaiter(this, void 0, void 0, function* () {
let target = e.target;
2 years ago
keyset[idx] = target.value;
3 years ago
input.setAttribute('data-prev', target.value);
2 years ago
plugin.settings.filterKeys = keyset;
3 years ago
yield plugin.saveSettings();
}));
}
3 years ago
/**
* A store of rules to apply to set members.
*
* Only one rule can be assigned to a member. If you add two rules against the
* same member key it will only keep the last one.
*
* ## Example
*
* ```
* const rules = new RuleStore()
* const tagsRule = { toHtml: tagslist, foldable: false }
* rules.set('tags', tagsRule)
* ```
*/
class RuleStore extends Map {
}
function isEmptyArray(value) {
if (typeof value === 'string') {
return value === '[]';
}
if (Array.isArray(value) && value.length === 0) {
return true;
}
return false;
}
function toggle(trigger) {
const isExpanded = trigger.getAttribute('aria-expanded') == 'true';
trigger.setAttribute('aria-expanded', String(!isExpanded));
}
function clickHandler(event, searchFn, openLinkFn) {
const trigger = event.target;
if (trigger === null || trigger === void 0 ? void 0 : trigger.hasAttribute('aria-expanded')) {
event.stopPropagation();
event.preventDefault();
toggle(trigger);
return;
}
if (trigger === null || trigger === void 0 ? void 0 : trigger.hasAttribute('href')) {
event.stopPropagation();
const href = trigger.getAttribute('href');
if (trigger.hasClass('internal-link')) {
event.preventDefault();
openLinkFn(trigger.dataset.href, '');
}
if (trigger.hasClass('tag')) {
event.preventDefault();
searchFn(`tag:${href}`);
}
}
}
function keyHandler(event) {
const trigger = event.target;
if ((event.code == 'Space' || event.code == 'Enter') && (trigger === null || trigger === void 0 ? void 0 : trigger.hasAttribute('aria-expanded'))) {
event.stopPropagation();
event.preventDefault();
toggle(trigger);
}
}
function externalLink(value) {
var _a, _b;
const a = document.createElement('a');
// @ts-ignore
(_a = a.part) === null || _a === void 0 ? void 0 : _a.add('link');
// @ts-ignore
(_b = a.part) === null || _b === void 0 ? void 0 : _b.add('external-link');
a.classList.add('external-link');
a.setAttribute('target', '_blank');
a.setAttribute('rel', 'noopener');
a.setAttribute('href', value);
a.append(value);
return a;
}
function obsidianUrl(vaultName, fileName) {
return `obsidian://open?vault=${vaultName}&file=${encodeURI(obsidian.getLinkpath(fileName))}`;
}
2 years ago
function internalLink(url, label) {
3 years ago
var _a, _b;
const a = document.createElement('a');
2 years ago
const localUrl = url.searchParams.get('file');
// const label = url.searchParams.get('file')
a.dataset.href = localUrl;
a.setAttribute('href', localUrl);
3 years ago
// @ts-ignore
(_a = a.part) === null || _a === void 0 ? void 0 : _a.add('link');
// @ts-ignore
(_b = a.part) === null || _b === void 0 ? void 0 : _b.add('internal-link');
a.classList.add('internal-link');
a.setAttribute('target', '_blank');
a.setAttribute('rel', 'noopener');
2 years ago
a.append(label ? label : localUrl);
3 years ago
return a;
}
/**
/* Creates a link for internal links from a string of the form `[[text]]`.
*/
function wikiLink(value, vaultName) {
const cleanValue = value.slice(2, -2);
2 years ago
let url;
let label;
if (cleanValue.includes('|')) {
const [urlValue, labelValue] = cleanValue.split('|');
url = new URL(obsidianUrl(vaultName, urlValue.trim()));
label = labelValue.trim();
}
else {
url = new URL(obsidianUrl(vaultName, cleanValue));
}
return internalLink(url, label);
3 years ago
}
/**
/* Creates a link for internal links from a string of the form `%text%`.
*/
function frontmatterLink(value, vaultName) {
const cleanValue = value.slice(1, -1);
const url = new URL(obsidianUrl(vaultName, cleanValue));
return internalLink(url);
}
/**
* Creates a link for local paths.
*/
function localLink(value, vaultName) {
const url = new URL(obsidianUrl(vaultName, value));
return internalLink(url);
}
function isOpen(mode, depth) {
if (mode == 'expanded') {
return true;
}
// Keep the root open when leafs are collapsed
if (mode == 'leaf-collapsed' && depth == 0) {
return true;
}
3 years ago
// Keep the root close when leafs are opened
if (mode == 'root-collapsed' && depth != 0) {
return true;
}
3 years ago
// all-collapsed
return false;
}
function isObsidianUrl(url) {
return (url instanceof URL && url.protocol == 'obsidian:');
}
function isUrl(url) {
3 years ago
const allowedProtocols = ['http:', 'https:', 'evernote:', 'zotero:'];
3 years ago
return (url instanceof URL && allowedProtocols.some(protocol => url.protocol == protocol));
}
function isLocalLink(value) {
return value.startsWith('./');
}
function tryUrl(value) {
try {
return new URL(value);
}
catch (_) {
}
}
function isWikiLink(value) {
return (value.startsWith('[[') && value.endsWith(']]'));
}
function isFrontmatterLink(value) {
return (value.startsWith('%') && value.endsWith('%'));
}
function enrichValue(value, context) {
const { settings, vaultName } = context;
const { autolinks } = settings;
const cleanValue = value.toString().trim();
if (autolinks) {
if (isWikiLink(cleanValue)) {
return wikiLink(cleanValue, vaultName);
}
if (isFrontmatterLink(cleanValue)) {
return frontmatterLink(cleanValue, vaultName);
}
if (isLocalLink(cleanValue)) {
return localLink(cleanValue, vaultName);
}
}
const url = tryUrl(cleanValue);
if (isObsidianUrl(url)) {
return internalLink(url);
}
if (isUrl(url)) {
return externalLink(cleanValue);
}
return value.toString();
}
function isNully(value) {
if (typeof value == 'string') {
return value.length == 0;
}
return value == null;
}
/**
* A set member with a scalar value.
*/
function leafMember(label, data, context) {
2 years ago
var _a, _b, _c;
const { rules } = context;
3 years ago
const root = document.createElement('tr');
const key = document.createElement('th');
const value = document.createElement('td');
2 years ago
const rule = rules.get(label.toLocaleLowerCase());
const datum = (rules.has(label.toLocaleLowerCase()) && !isNully(data))
3 years ago
? rule.toHtml(data, rule)
: enrichValue(data, context);
// XXX: Note that `part` is an `Element` extension in draft. Checking for
// undefined lets us get away with plain jest dom testing.
// @ts-ignore
(_a = key.part) === null || _a === void 0 ? void 0 : _a.add('key');
key.classList.add('key');
key.append(label);
// @ts-ignore
(_b = value.part) === null || _b === void 0 ? void 0 : _b.add('value');
value.classList.add('value');
value.append(datum);
2 years ago
// @ts-ignore
(_c = root.part) === null || _c === void 0 ? void 0 : _c.add('member');
3 years ago
root.classList.add('member');
root.append(key);
root.append(value);
return root;
}
/**
* A set member with a complex value.
*/
function nodeMember(label, value, context) {
2 years ago
var _a;
3 years ago
const root = details(label, value, Object.assign(Object.assign({}, context), { depth: context.depth + 1 }));
2 years ago
// @ts-ignore
(_a = root.part) === null || _a === void 0 ? void 0 : _a.add('member');
3 years ago
root.classList.add('member');
return root;
}
/**
* A set member.
*/
function member(label, value, context) {
const { settings } = context;
const patchedValue = value == null ? settings.nullValue : value;
if (typeof patchedValue == 'object') {
return nodeMember(label, value, context);
}
return leafMember(label, patchedValue, context);
}
/**
* A set of members.
*/
function set(data, context) {
2 years ago
var _a;
3 years ago
const { settings, depth } = context;
const { filterMode, filterKeys, ignoreNulls } = settings;
const valueContext = Object.assign(Object.assign({}, context), { depth: depth + 1 });
const root = document.createElement('table');
2 years ago
// @ts-ignore
(_a = root.part) === null || _a === void 0 ? void 0 : _a.add('set');
3 years ago
root.classList.add('set');
Object.entries(data).forEach(([label, value]) => {
if (ignoreNulls && (value == null || isEmptyArray(value)))
return;
if (filterMode == 'ignore') {
if (filterKeys.some(key => key == label))
return;
}
if (filterMode == 'keep') {
if (!filterKeys.some(key => key == label))
return;
}
root.append(member(label, value, valueContext));
});
return root;
}
/**
* A list of members.
*/
function list(data, context) {
const { settings, depth } = context;
const valueContext = Object.assign(Object.assign({}, context), { depth: depth + 1 });
const root = document.createElement('ul');
data.forEach((item) => {
let value;
const li = document.createElement('li');
if (Array.isArray(item)) {
value = list(item, valueContext);
}
else if (typeof item == 'object') {
value = set(item, valueContext);
}
else {
value = enrichValue(item, valueContext);
}
li.append(value);
root.append(li);
});
return root;
}
function ordinaryValue(data, context) {
return Array.isArray(data)
? list(data, context)
: set(data, context);
}
/**
* A collapsible group.
*/
function details(label, data, context) {
2 years ago
var _a, _b, _c;
3 years ago
const { settings, rules, depth } = context;
const { mode } = settings;
const root = document.createElement('tr');
const key = document.createElement('th');
const value = document.createElement('td');
2 years ago
const rule = rules.get(label.toLocaleLowerCase());
3 years ago
const valueId = `${label}-${depth}`;
2 years ago
const datum = (rules.has(label.toLocaleLowerCase()) && !isNully(data))
3 years ago
? rule.toHtml(data, rule)
: ordinaryValue(data, Object.assign(Object.assign({}, context), { depth: depth + 1 }));
// @ts-ignore
(_a = key.part) === null || _a === void 0 ? void 0 : _a.add('key');
key.classList.add('key');
key.append(label);
root.append(key);
// @ts-ignore
(_b = value.part) === null || _b === void 0 ? void 0 : _b.add('value');
value.classList.add('value');
value.setAttribute('id', valueId);
value.append(datum);
root.append(value);
if (rule == undefined || rule.foldable) {
const marker = document.createElement('div');
key.classList.add('toggle');
key.setAttribute('role', 'button');
key.setAttribute('aria-expanded', String(isOpen(mode, depth)));
key.setAttribute('aria-controls', valueId);
key.setAttribute('tabindex', '0');
2 years ago
(_c = marker.part) === null || _c === void 0 ? void 0 : _c.add('marker');
3 years ago
marker.classList.add('marker');
value.append(marker);
}
return root;
}
function sheath(data, context) {
2 years ago
var _a;
3 years ago
const { settings } = context;
const root = document.createElement('details');
const summary = document.createElement('summary');
const value = set(data, context);
if (isOpen(settings.mode, 0)) {
root.setAttribute('open', '');
}
summary.append('Metadata');
2 years ago
// @ts-ignore
(_a = summary.part) === null || _a === void 0 ? void 0 : _a.add('summary');
3 years ago
root.classList.add('metatable');
root.append(summary);
root.append(value);
return root;
}
function metatable(data, context) {
2 years ago
const { searchFn, openLinkFn } = context;
3 years ago
const fragment = new DocumentFragment();
const root = sheath(data, context);
root.addEventListener('click', (e) => clickHandler(e, searchFn, openLinkFn));
root.addEventListener('keydown', keyHandler);
fragment.append(root);
return fragment;
}
/**
* Transforms a list of dirty tags into HTML.
*/
function taglist(data, rule) {
const list = normaliseTags(data);
// No valid tags found.
if (list.length == 0)
return null;
const root = document.createElement('ul');
root.classList.add('tag-list');
list.forEach((item) => {
const li = document.createElement('li');
const value = tag(item);
li.append(value);
root.append(li);
});
return root;
}
/**
* Normalises a list of tags as an array of strings.
*/
function normaliseTags(data) {
if (data == null) {
return [];
}
if (typeof data == 'string') {
return data.split(',').map(x => x.trim()).filter(x => x && x.length != 0);
}
return data.filter(x => x && x.length != 0);
}
function tag(value) {
var _a, _b;
const a = document.createElement('a');
a.classList.add('tag');
// XXX: Note that `part` is an `Element` extension in draft. Checking for
// undefined lets us get away with plain jest dom testing.
// @ts-ignore
(_a = a.part) === null || _a === void 0 ? void 0 : _a.add('tag');
// @ts-ignore
(_b = a.part) === null || _b === void 0 ? void 0 : _b.add(encodeURI(value));
a.setAttribute('target', '_blank');
a.setAttribute('rel', 'noopener');
a.setAttribute('href', `#${value}`);
a.append(`${value}`);
return a;
}
2 years ago
var styles = ":host-context(.theme-light) {\n --metatable-foreground: var(--text-muted, darkslategrey);\n --metatable-key-background: var(--background-primary-alt, #f3f3f3);\n --metatable-key-border-color: var(--background-modifier-border, lightgrey);\n --metatable-key-border-color-focus: orange;\n --metatable-key-focus: var(--background-match-highlight, lightyellow);\n --metatable-tag-background: var(--background-primary-alt, #f3f3f3);\n --metatable-link-color: var(--text-accent, #705dcf);\n --metatable-link-color-hover: var(--text-accent-hover, #8875ff);\n --metatable-warning-background: lightgoldenrodyellow;\n --metatable-warning-foreground: brown;\n --metatable-warning-border: 2px solid palegoldenrod;\n}\n\n:host-context(.theme-dark) {\n --metatable-foreground: var(--text-muted, #999);\n --metatable-key-background: var(--background-primary-alt, #111);\n --metatable-key-border-color: var(--background-modifier-border, #333);\n --metatable-key-border-color-focus: orange;\n --metatable-key-focus: black;\n --metatable-tag-background: var(--background-primary-alt, #111);\n --metatable-link-color: var(--text-accent, #705dcf);\n --metatable-link-color-hover: var(--text-accent-hover, #8875ff);\n --metatable-warning-background: inherit;\n --metatable-warning-foreground: gold;\n --metatable-warning-border: 2px solid palegoldenrod;\n}\n\n:host {\n --metatable-background: transparent;\n --metatable-collapsed-symbol: \"▶︎\";\n --metatable-expanded-symbol: \"▼\";\n --metatable-external-link-color-hover: var(--metatable-link-color-hover);\n --metatable-external-link-color: var(--metatable-link-color);\n --metatable-external-link-icon: url(app://obsidian.md/public/images/874d8b8e340f75575caa.svg);\n --metatable-font-family: var(--text, sans-serif);\n --metatable-font-size: var(--font-small, 13px);\n --metatable-internal-link-color-hover: var(--metatable-link-color-hover);\n --metatable-internal-link-color: var(--metatable-link-color);\n --metatable-internal-link-icon: none;\n --metatable-key-border-width: 2px;\n --metatable-mark-symbol: \"…\";\n --metatable-member-gap: 2px;\n --metatable-tag-symbol: \"\";\n --metatable-value-background: transparent;\n}\n\n\n* {\n box-sizing: border-box;\n}\n\ndetails {\n background-color: var(--metatable-background);\n color: var(--metatable-foreground);\n font-family: var(--metatable-font-family);\n font-size: var(--metatable-font-size);\n}\n\nsummary {\n cursor: pointer;\n}\n\nsummary:focus {\n outline: none;\n}\n\nsummary:focus-visible {\n outline: none;\n background-color: var(--metatable-key-focus)\n}\n\n.set {\n background-color: var(--metatable-background);\n display: grid;\n grid-gap: 2px;\n margin-top: 0.4rem;\n}\n\n.member {\n display: grid;\n grid-gap: var(--metatable-member-gap);\n grid-template-columns: minmax(0, 1fr) minmax(0, 4fr);\n grid-template-areas: \"key value\";\n}\n\n.key[role=button] {\n cursor: pointer;\n}\n\n.member .key {\n background-color: var(--metatable-key-background);\n border-right: var(--metatable-key-border-width) solid var(--metatable-key-border-color);\n display: grid;\n grid-template-columns: 10px auto;\n grid-gap: 0.4rem;\n font-weight: bold;\n grid-area: key;\n overflow: hidden;\n padding: 0.4rem;\n text-align: left;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.member .value {\n background-color: var(--metatable-value-background);\n grid-area: value;\n margin: 0;\n overflow: auto;\n padding: 0.4rem;\n}\n\n.member .key:focus {\n outline: none;\n}\n\n.member .key:focus-visible {\n outline: none;\n border-right-color: var(--metatable-key-border-color-focus);\n background-color: var(--metatable-key-focus);\n}\n\n.value ul {\n margin: 0;\n padding: 0;\n}\n\n.value li {\n margin-left: 1rem;\n}\n\n.key[aria-expanded]::before {\n font-size: 0.6rem;\n padding-top: 0.3rem;\n}\n\n.key[aria-expanded=true]::before {\n content: var(--metatable-expanded-symbol);\n}\n\n.key[aria-expanded=false]::before {\n content: var(--metatable-collapsed-symbol);\n}\n\n.key[aria-expande
3 years ago
function log(msg) {
console.log(`metatable: ${msg}`);
}
function createMetatable(el, data, context) {
const wrapper = el.createEl('div');
const fragment = new DocumentFragment();
3 years ago
wrapper.classList.add('obsidian-metatable');
if (!context.settings.naked) {
wrapper.attachShadow({ mode: 'open' });
fragment.createEl('style', { text: styles });
}
3 years ago
fragment.append(metatable(data, context));
3 years ago
if (context.settings.naked) {
wrapper.append(fragment);
}
else {
wrapper.shadowRoot.append(fragment);
}
3 years ago
}
2 years ago
function createWarning(el, message, context) {
const wrapper = el.createEl('div');
const fragment = new DocumentFragment();
wrapper.classList.add('obsidian-metatable');
if (!context.settings.naked) {
wrapper.attachShadow({ mode: 'open' });
fragment.createEl('style', { text: styles });
}
const warning = el.createEl('p');
warning.classList.add('warning');
warning.append(message);
fragment.append(warning);
if (context.settings.naked) {
wrapper.append(fragment);
}
else {
wrapper.shadowRoot.append(fragment);
}
}
3 years ago
function isEmpty(data) {
return Object.entries(data)
.every(([_, value]) => value == null || isEmptyArray(value));
}
function filterSet(data, filterKeys, filterMode) {
const filterFn = filterMode == 'ignore'
? (x => !x)
: (x => x);
const newData = Object.entries(data)
.filter(([key, _value]) => filterFn(filterKeys.some(x => x == key)));
return Object.fromEntries(newData);
}
function frontmatterProcessor(el, ctx) {
return __awaiter(this, void 0, void 0, function* () {
const plugin = this;
2 years ago
const frontmatter = el.querySelector('.frontmatter');
3 years ago
if (frontmatter !== null) {
2 years ago
const embed = el.querySelector('.internal-embed');
3 years ago
// If an embed has already been loaded, writing after the embed expression
// triggers a re-render for the embedded markdown wrongly injecting the
// parent metatable for every keystroke.
//
// See https://github.com/arnau/obsidian-metatable/issues/12
if (embed !== null) {
return;
}
2 years ago
const target = el.querySelector('.frontmatter-container');
target.style.display = 'none';
3 years ago
// @ts-ignore
const searchFn = plugin.app.internalPlugins.getPluginById('global-search').instance.openGlobalSearch.bind(plugin);
const openLinkFn = plugin.app.workspace.openLinkText.bind(plugin.app.workspace);
const { ignoreNulls, filterMode, filterKeys, skipKey } = plugin.settings;
const rules = new RuleStore();
rules.set('tags', {
toHtml: taglist,
foldable: false,
});
const context = {
vaultName: plugin.app.vault.getName(),
rules,
searchFn,
openLinkFn,
settings: {
mode: plugin.settings.expansionMode,
ignoreNulls,
nullValue: plugin.settings.nullValue,
filterKeys,
filterMode,
autolinks: plugin.settings.autolinks,
3 years ago
naked: plugin.settings.naked,
3 years ago
},
depth: 0,
};
if (ctx.frontmatter) {
const data = filterSet(ctx.frontmatter, filterKeys, filterMode);
if (ctx.frontmatter[skipKey]) {
return;
}
// Nothing to render if all top-level are null and nulls should be
// ignored.
if (ignoreNulls && isEmpty(data)) {
return;
}
if (Object.isEmpty(data)) {
return;
}
2 years ago
createMetatable(target.parentNode, data, context);
}
else {
// When null, the frontmatter YAML is invalid. There is no insight to tap
// on to give a meaningful error message though.
const label = frontmatter.querySelector('.mod-error');
createWarning(target.parentNode, label.textContent, context);
3 years ago
}
}
});
}
class MetatablePlugin extends obsidian.Plugin {
onload() {
return __awaiter(this, void 0, void 0, function* () {
yield this.loadSettings();
this.registerMarkdownPostProcessor(frontmatterProcessor.bind(this));
this.addSettingTab(new MetatableSettingTab(this.app, this));
log('loaded');
});
}
onunload() {
log('unloaded');
}
loadSettings() {
return __awaiter(this, void 0, void 0, function* () {
this.settings = Object.assign({}, DEFAULT_SETTINGS, yield this.loadData());
});
}
saveSettings() {
return __awaiter(this, void 0, void 0, function* () {
yield this.saveData(this.settings);
});
}
}
module.exports = MetatablePlugin;
2 years ago
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9zZXR0aW5ncy50cyIsInNyYy9ydWxlLnRzIiwic3JjL3V0aWxzLnRzIiwic3JjL3RhYmxlLnRzIiwic3JjL21hcHBlcnMudHMiLCJzcmMvcGx1Z2luLnRzIl0sInNvdXJjZXNDb250ZW50IjpudWxsLCJuYW1lcyI6WyJQbHVnaW5TZXR0aW5nVGFiIiwiU2V0dGluZyIsImdldExpbmtwYXRoIiwiUGx1Z2luIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBdURBO0FBQ08sU0FBUyxTQUFTLENBQUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxDQUFDLEVBQUUsU0FBUyxFQUFFO0FBQzdELElBQUksU0FBUyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsT0FBTyxLQUFLLFlBQVksQ0FBQyxHQUFHLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVLE9BQU8sRUFBRSxFQUFFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFO0FBQ2hILElBQUksT0FBTyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsVUFBVSxPQUFPLEVBQUUsTUFBTSxFQUFFO0FBQy9ELFFBQVEsU0FBUyxTQUFTLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtBQUNuRyxRQUFRLFNBQVMsUUFBUSxDQUFDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFD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