|
|
|
/*
|
|
|
|
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');
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
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());
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// allows time to be optional
|
|
|
|
const ISO_DATE_REGEX = /^(\d{4}-\d{2}-\d{2})(T\d{2}:\d{2}:\d{2}(\.\d{3})?(Z|[+-]\d{2}:\d{2})?)?$/;
|
|
|
|
var CellTypes;
|
|
|
|
(function (CellTypes) {
|
|
|
|
CellTypes[CellTypes["TEXT"] = 0] = "TEXT";
|
|
|
|
CellTypes[CellTypes["NUMBER"] = 1] = "NUMBER";
|
|
|
|
CellTypes[CellTypes["ISO_DATE"] = 2] = "ISO_DATE";
|
|
|
|
})(CellTypes || (CellTypes = {}));
|
|
|
|
var SortOrder;
|
|
|
|
(function (SortOrder) {
|
|
|
|
SortOrder[SortOrder["DEFAULT"] = 0] = "DEFAULT";
|
|
|
|
SortOrder[SortOrder["ASCENDING"] = 1] = "ASCENDING";
|
|
|
|
SortOrder[SortOrder["DESCENDING"] = 2] = "DESCENDING";
|
|
|
|
})(SortOrder || (SortOrder = {}));
|
|
|
|
var AttributeName;
|
|
|
|
(function (AttributeName) {
|
|
|
|
AttributeName["tableHeader"] = "sortable-style";
|
|
|
|
AttributeName["cssAscending"] = "sortable-asc";
|
|
|
|
AttributeName["cssDescending"] = "sortable-desc";
|
|
|
|
})(AttributeName || (AttributeName = {}));
|
|
|
|
class TableState {
|
|
|
|
constructor() {
|
|
|
|
this.columnIdx = null;
|
|
|
|
this.sortOrder = SortOrder.DEFAULT;
|
|
|
|
this.defaultOrdering = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function shouldSort(htmlEl) {
|
|
|
|
// dataview table: parent must be a "dataview" HTMLTableElement
|
|
|
|
const p = htmlEl.matchParent(".dataview");
|
|
|
|
if (p instanceof HTMLTableElement)
|
|
|
|
return true;
|
|
|
|
// reading mode, i.e. non-editing
|
|
|
|
return null !== htmlEl.matchParent(".markdown-reading-view");
|
|
|
|
}
|
|
|
|
function onHeadClick(evt, tableStates) {
|
|
|
|
// check if the clicked element is a table header
|
|
|
|
const htmlEl = evt.target;
|
|
|
|
if (!shouldSort(htmlEl)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const th = htmlEl.closest("thead th");
|
|
|
|
if (th === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const table = htmlEl.closest("table");
|
|
|
|
const tableBody = table.querySelector("tbody");
|
|
|
|
const thArray = Array.from(th.parentNode.children);
|
|
|
|
const thIdx = thArray.indexOf(th);
|
|
|
|
// create a new table state if does not previously exist
|
|
|
|
if (!tableStates.has(table)) {
|
|
|
|
tableStates.set(table, new TableState());
|
|
|
|
}
|
|
|
|
const tableState = tableStates.get(table);
|
|
|
|
thArray.forEach((th, i) => {
|
|
|
|
if (i !== thIdx) {
|
|
|
|
th.removeAttribute(AttributeName.tableHeader);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (tableState.defaultOrdering === null) {
|
|
|
|
tableState.defaultOrdering = Array.from(tableBody.rows);
|
|
|
|
}
|
|
|
|
// sorting the same column, again
|
|
|
|
if (tableState.columnIdx === thIdx) {
|
|
|
|
tableState.sortOrder = (tableState.sortOrder + 1) % 3;
|
|
|
|
}
|
|
|
|
// sorting a new column
|
|
|
|
else {
|
|
|
|
tableState.columnIdx = thIdx;
|
|
|
|
tableState.sortOrder = SortOrder.ASCENDING;
|
|
|
|
}
|
|
|
|
sortTable(tableState, tableBody);
|
|
|
|
switch (tableState.sortOrder) {
|
|
|
|
case SortOrder.ASCENDING:
|
|
|
|
th.setAttribute(AttributeName.tableHeader, AttributeName.cssAscending);
|
|
|
|
break;
|
|
|
|
case SortOrder.DESCENDING:
|
|
|
|
th.setAttribute(AttributeName.tableHeader, AttributeName.cssDescending);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// if the current state is now the default one, then forget about this table
|
|
|
|
if (tableState.sortOrder === SortOrder.DEFAULT) {
|
|
|
|
tableStates.delete(table);
|
|
|
|
th.removeAttribute(AttributeName.tableHeader);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function sortTable(tableState, tableBody) {
|
|
|
|
emptyTable(tableBody, tableState.defaultOrdering);
|
|
|
|
if (tableState.sortOrder === SortOrder.DEFAULT) {
|
|
|
|
fillTable(tableBody, tableState.defaultOrdering);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const xs = [...tableState.defaultOrdering];
|
|
|
|
const collator = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" });
|
|
|
|
xs.sort((a, b) => compareRows(a, b, tableState.columnIdx, tableState.sortOrder, collator));
|
|
|
|
fillTable(tableBody, xs);
|
|
|
|
}
|
|
|
|
function resetTable(tableState, tableBody) {
|
|
|
|
emptyTable(tableBody, tableState.defaultOrdering);
|
|
|
|
fillTable(tableBody, tableState.defaultOrdering);
|
|
|
|
}
|
|
|
|
function compareRows(a, b, index, order, collator) {
|
|
|
|
if (order === SortOrder.DESCENDING) {
|
|
|
|
[a, b] = [b, a];
|
|
|
|
}
|
|
|
|
const [valueA, typeA] = valueFromCell(a.cells[index]);
|
|
|
|
const [valueB, typeB] = valueFromCell(b.cells[index]);
|
|
|
|
if (typeA !== typeB) {
|
|
|
|
return collator.compare(valueA.toString(), valueB.toString());
|
|
|
|
}
|
|
|
|
switch (typeA) {
|
|
|
|
case CellTypes.NUMBER:
|
|
|
|
case CellTypes.ISO_DATE:
|
|
|
|
return valueA === valueB ? 0 : valueA < valueB ? -1 : 1;
|
|
|
|
case CellTypes.TEXT:
|
|
|
|
return collator.compare(valueA.toString(), valueB.toString());
|
|
|
|
default:
|
|
|
|
// unreachable
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function valueFromCell(element) {
|
|
|
|
// TODO: extend to other data-types.
|
|
|
|
const text = element.textContent;
|
|
|
|
if (ISO_DATE_REGEX.test(text)) {
|
|
|
|
return [new Date(text), CellTypes.ISO_DATE];
|
|
|
|
}
|
|
|
|
// use `Number` in favour of `parseFloat` to disallow "false positives"
|
|
|
|
const value = Number(text);
|
|
|
|
if (!isNaN(value)) {
|
|
|
|
return [value, CellTypes.NUMBER];
|
|
|
|
}
|
|
|
|
// fallback: text value, will use collator for comparison
|
|
|
|
return [text, CellTypes.TEXT];
|
|
|
|
}
|
|
|
|
function emptyTable(tableBody, rows) {
|
|
|
|
rows.forEach(() => tableBody.deleteRow(-1));
|
|
|
|
}
|
|
|
|
function fillTable(tableBody, rows) {
|
|
|
|
rows.forEach((row) => tableBody.appendChild(row));
|
|
|
|
}
|
|
|
|
|
|
|
|
class SortablePlugin extends obsidian.Plugin {
|
|
|
|
onload() {
|
|
|
|
return __awaiter(this, void 0, void 0, function* () {
|
|
|
|
console.log("Sortable: loading plugin...");
|
|
|
|
this.tableStates = new WeakMap();
|
|
|
|
this.registerDomEvent(window, "click", (ev) => onHeadClick(ev, this.tableStates));
|
|
|
|
console.log("Sortable: loaded plugin.");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
onunload() {
|
|
|
|
// get all HTMLTableElements present in the map and reset their state
|
|
|
|
const tables = Array.from(document.querySelectorAll("table"));
|
|
|
|
for (const table of tables) {
|
|
|
|
if (this.tableStates.has(table)) {
|
|
|
|
const state = this.tableStates.get(table);
|
|
|
|
resetTable(state, table.querySelector("tbody"));
|
|
|
|
const th = table.querySelector(`thead th:nth-child(${state.columnIdx + 1})`);
|
|
|
|
th.removeAttribute(AttributeName.tableHeader);
|
|
|
|
this.tableStates.delete(table);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
delete this.tableStates;
|
|
|
|
console.log("Sortable: unloaded plugin.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = SortablePlugin;
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZXMiOlsibm9kZV9tb2R1bGVzL3RzbGliL3RzbGliLmVzNi5qcyIsInNyYy9zb3J0YWJsZS50cyIsInNyYy9tYWluLnRzIl0sInNvdXJjZXNDb250ZW50IjpudWxsLCJuYW1lcyI6WyJQbHVnaW4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUF1REE7QUFDTyxTQUFTLFNBQVMsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxTQUFTLEVBQUU7QUFDN0QsSUFBSSxTQUFTLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLFVBQVUsT0FBTyxFQUFFLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUU7QUFDaEgsSUFBSSxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsRUFBRSxVQUFVLE9BQU8sRUFBRSxNQUFNLEVBQUU7QUFDL0QsUUFBUSxTQUFTLFNBQVMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ25HLFFBQVEsU0FBUyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO0FBQ3RHLFFBQVEsU0FBUyxJQUFJ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
|