Adding indexmenu version 2024-01-05 (ed06f21).
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
92cc8375f2
commit
f339727d60
766 changed files with 83299 additions and 0 deletions
|
@ -0,0 +1,544 @@
|
|||
/*!
|
||||
* jquery.fancytree.table.js
|
||||
*
|
||||
* Render tree as table (aka 'tree grid', 'table tree').
|
||||
* (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
|
||||
*
|
||||
* Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de)
|
||||
*
|
||||
* Released under the MIT license
|
||||
* https://github.com/mar10/fancytree/wiki/LicenseInfo
|
||||
*
|
||||
* @version 2.38.3
|
||||
* @date 2023-02-01T20:52:50Z
|
||||
*/
|
||||
|
||||
(function (factory) {
|
||||
if (typeof define === "function" && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(["jquery", "./jquery.fancytree"], factory);
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
// Node/CommonJS
|
||||
require("./jquery.fancytree");
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
"use strict";
|
||||
|
||||
/******************************************************************************
|
||||
* Private functions and variables
|
||||
*/
|
||||
var _assert = $.ui.fancytree.assert;
|
||||
|
||||
function insertFirstChild(referenceNode, newNode) {
|
||||
referenceNode.insertBefore(newNode, referenceNode.firstChild);
|
||||
}
|
||||
|
||||
function insertSiblingAfter(referenceNode, newNode) {
|
||||
referenceNode.parentNode.insertBefore(
|
||||
newNode,
|
||||
referenceNode.nextSibling
|
||||
);
|
||||
}
|
||||
|
||||
/* Show/hide all rows that are structural descendants of `parent`. */
|
||||
function setChildRowVisibility(parent, flag) {
|
||||
parent.visit(function (node) {
|
||||
var tr = node.tr;
|
||||
// currentFlag = node.hide ? false : flag; // fix for ext-filter
|
||||
if (tr) {
|
||||
tr.style.display = node.hide || !flag ? "none" : "";
|
||||
}
|
||||
if (!node.expanded) {
|
||||
return "skip";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Find node that is rendered in previous row. */
|
||||
function findPrevRowNode(node) {
|
||||
var i,
|
||||
last,
|
||||
prev,
|
||||
parent = node.parent,
|
||||
siblings = parent ? parent.children : null;
|
||||
|
||||
if (siblings && siblings.length > 1 && siblings[0] !== node) {
|
||||
// use the lowest descendant of the preceeding sibling
|
||||
i = $.inArray(node, siblings);
|
||||
prev = siblings[i - 1];
|
||||
_assert(prev.tr);
|
||||
// descend to lowest child (with a <tr> tag)
|
||||
while (prev.children && prev.children.length) {
|
||||
last = prev.children[prev.children.length - 1];
|
||||
if (!last.tr) {
|
||||
break;
|
||||
}
|
||||
prev = last;
|
||||
}
|
||||
} else {
|
||||
// if there is no preceding sibling, use the direct parent
|
||||
prev = parent;
|
||||
}
|
||||
return prev;
|
||||
}
|
||||
|
||||
$.ui.fancytree.registerExtension({
|
||||
name: "table",
|
||||
version: "2.38.3",
|
||||
// Default options for this extension.
|
||||
options: {
|
||||
checkboxColumnIdx: null, // render the checkboxes into the this column index (default: nodeColumnIdx)
|
||||
indentation: 16, // indent every node level by 16px
|
||||
mergeStatusColumns: true, // display 'nodata', 'loading', 'error' centered in a single, merged TR
|
||||
nodeColumnIdx: 0, // render node expander, icon, and title to this column (default: #0)
|
||||
},
|
||||
// Overide virtual methods for this extension.
|
||||
// `this` : is this extension object
|
||||
// `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
|
||||
treeInit: function (ctx) {
|
||||
var i,
|
||||
n,
|
||||
$row,
|
||||
$tbody,
|
||||
tree = ctx.tree,
|
||||
opts = ctx.options,
|
||||
tableOpts = opts.table,
|
||||
$table = tree.widget.element;
|
||||
|
||||
if (tableOpts.customStatus != null) {
|
||||
if (opts.renderStatusColumns == null) {
|
||||
tree.warn(
|
||||
"The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' instead."
|
||||
);
|
||||
opts.renderStatusColumns = tableOpts.customStatus;
|
||||
} else {
|
||||
$.error(
|
||||
"The 'customStatus' option is deprecated since v2.15.0. Use 'renderStatusColumns' only instead."
|
||||
);
|
||||
}
|
||||
}
|
||||
if (opts.renderStatusColumns) {
|
||||
if (opts.renderStatusColumns === true) {
|
||||
opts.renderStatusColumns = opts.renderColumns;
|
||||
// } else if( opts.renderStatusColumns === "wide" ) {
|
||||
// opts.renderStatusColumns = _renderStatusNodeWide;
|
||||
}
|
||||
}
|
||||
|
||||
$table.addClass("fancytree-container fancytree-ext-table");
|
||||
$tbody = $table.find(">tbody");
|
||||
if (!$tbody.length) {
|
||||
// TODO: not sure if we can rely on browsers to insert missing <tbody> before <tr>s:
|
||||
if ($table.find(">tr").length) {
|
||||
$.error(
|
||||
"Expected table > tbody > tr. If you see this please open an issue."
|
||||
);
|
||||
}
|
||||
$tbody = $("<tbody>").appendTo($table);
|
||||
}
|
||||
|
||||
tree.tbody = $tbody[0];
|
||||
|
||||
// Prepare row templates:
|
||||
// Determine column count from table header if any
|
||||
tree.columnCount = $("thead >tr", $table)
|
||||
.last()
|
||||
.find(">th", $table).length;
|
||||
// Read TR templates from tbody if any
|
||||
$row = $tbody.children("tr").first();
|
||||
if ($row.length) {
|
||||
n = $row.children("td").length;
|
||||
if (tree.columnCount && n !== tree.columnCount) {
|
||||
tree.warn(
|
||||
"Column count mismatch between thead (" +
|
||||
tree.columnCount +
|
||||
") and tbody (" +
|
||||
n +
|
||||
"): using tbody."
|
||||
);
|
||||
tree.columnCount = n;
|
||||
}
|
||||
$row = $row.clone();
|
||||
} else {
|
||||
// Only thead is defined: create default row markup
|
||||
_assert(
|
||||
tree.columnCount >= 1,
|
||||
"Need either <thead> or <tbody> with <td> elements to determine column count."
|
||||
);
|
||||
$row = $("<tr />");
|
||||
for (i = 0; i < tree.columnCount; i++) {
|
||||
$row.append("<td />");
|
||||
}
|
||||
}
|
||||
$row.find(">td")
|
||||
.eq(tableOpts.nodeColumnIdx)
|
||||
.html("<span class='fancytree-node' />");
|
||||
if (opts.aria) {
|
||||
$row.attr("role", "row");
|
||||
$row.find("td").attr("role", "gridcell");
|
||||
}
|
||||
tree.rowFragment = document.createDocumentFragment();
|
||||
tree.rowFragment.appendChild($row.get(0));
|
||||
|
||||
// // If tbody contains a second row, use this as status node template
|
||||
// $row = $tbody.children("tr").eq(1);
|
||||
// if( $row.length === 0 ) {
|
||||
// tree.statusRowFragment = tree.rowFragment;
|
||||
// } else {
|
||||
// $row = $row.clone();
|
||||
// tree.statusRowFragment = document.createDocumentFragment();
|
||||
// tree.statusRowFragment.appendChild($row.get(0));
|
||||
// }
|
||||
//
|
||||
$tbody.empty();
|
||||
|
||||
// Make sure that status classes are set on the node's <tr> elements
|
||||
tree.statusClassPropName = "tr";
|
||||
tree.ariaPropName = "tr";
|
||||
this.nodeContainerAttrName = "tr";
|
||||
|
||||
// #489: make sure $container is set to <table>, even if ext-dnd is listed before ext-table
|
||||
tree.$container = $table;
|
||||
|
||||
this._superApply(arguments);
|
||||
|
||||
// standard Fancytree created a root UL
|
||||
$(tree.rootNode.ul).remove();
|
||||
tree.rootNode.ul = null;
|
||||
|
||||
// Add container to the TAB chain
|
||||
// #577: Allow to set tabindex to "0", "-1" and ""
|
||||
this.$container.attr("tabindex", opts.tabindex);
|
||||
// this.$container.attr("tabindex", opts.tabbable ? "0" : "-1");
|
||||
if (opts.aria) {
|
||||
tree.$container
|
||||
.attr("role", "treegrid")
|
||||
.attr("aria-readonly", true);
|
||||
}
|
||||
},
|
||||
nodeRemoveChildMarkup: function (ctx) {
|
||||
var node = ctx.node;
|
||||
// node.debug("nodeRemoveChildMarkup()");
|
||||
node.visit(function (n) {
|
||||
if (n.tr) {
|
||||
$(n.tr).remove();
|
||||
n.tr = null;
|
||||
}
|
||||
});
|
||||
},
|
||||
nodeRemoveMarkup: function (ctx) {
|
||||
var node = ctx.node;
|
||||
// node.debug("nodeRemoveMarkup()");
|
||||
if (node.tr) {
|
||||
$(node.tr).remove();
|
||||
node.tr = null;
|
||||
}
|
||||
this.nodeRemoveChildMarkup(ctx);
|
||||
},
|
||||
/* Override standard render. */
|
||||
nodeRender: function (ctx, force, deep, collapsed, _recursive) {
|
||||
var children,
|
||||
firstTr,
|
||||
i,
|
||||
l,
|
||||
newRow,
|
||||
prevNode,
|
||||
prevTr,
|
||||
subCtx,
|
||||
tree = ctx.tree,
|
||||
node = ctx.node,
|
||||
opts = ctx.options,
|
||||
isRootNode = !node.parent;
|
||||
|
||||
if (tree._enableUpdate === false) {
|
||||
// $.ui.fancytree.debug("*** nodeRender _enableUpdate: false");
|
||||
return;
|
||||
}
|
||||
if (!_recursive) {
|
||||
ctx.hasCollapsedParents = node.parent && !node.parent.expanded;
|
||||
}
|
||||
// $.ui.fancytree.debug("*** nodeRender " + node + ", isRoot=" + isRootNode, "tr=" + node.tr, "hcp=" + ctx.hasCollapsedParents, "parent.tr=" + (node.parent && node.parent.tr));
|
||||
if (!isRootNode) {
|
||||
if (node.tr && force) {
|
||||
this.nodeRemoveMarkup(ctx);
|
||||
}
|
||||
if (node.tr) {
|
||||
if (force) {
|
||||
// Set icon, link, and title (normally this is only required on initial render)
|
||||
this.nodeRenderTitle(ctx); // triggers renderColumns()
|
||||
} else {
|
||||
// Update element classes according to node state
|
||||
this.nodeRenderStatus(ctx);
|
||||
}
|
||||
} else {
|
||||
if (ctx.hasCollapsedParents && !deep) {
|
||||
// #166: we assume that the parent will be (recursively) rendered
|
||||
// later anyway.
|
||||
// node.debug("nodeRender ignored due to unrendered parent");
|
||||
return;
|
||||
}
|
||||
// Create new <tr> after previous row
|
||||
// if( node.isStatusNode() ) {
|
||||
// newRow = tree.statusRowFragment.firstChild.cloneNode(true);
|
||||
// } else {
|
||||
newRow = tree.rowFragment.firstChild.cloneNode(true);
|
||||
// }
|
||||
prevNode = findPrevRowNode(node);
|
||||
// $.ui.fancytree.debug("*** nodeRender " + node + ": prev: " + prevNode.key);
|
||||
_assert(prevNode);
|
||||
if (collapsed === true && _recursive) {
|
||||
// hide all child rows, so we can use an animation to show it later
|
||||
newRow.style.display = "none";
|
||||
} else if (deep && ctx.hasCollapsedParents) {
|
||||
// also hide this row if deep === true but any parent is collapsed
|
||||
newRow.style.display = "none";
|
||||
// newRow.style.color = "red";
|
||||
}
|
||||
if (prevNode.tr) {
|
||||
insertSiblingAfter(prevNode.tr, newRow);
|
||||
} else {
|
||||
_assert(
|
||||
!prevNode.parent,
|
||||
"prev. row must have a tr, or be system root"
|
||||
);
|
||||
// tree.tbody.appendChild(newRow);
|
||||
insertFirstChild(tree.tbody, newRow); // #675
|
||||
}
|
||||
node.tr = newRow;
|
||||
if (node.key && opts.generateIds) {
|
||||
node.tr.id = opts.idPrefix + node.key;
|
||||
}
|
||||
node.tr.ftnode = node;
|
||||
// if(opts.aria){
|
||||
// $(node.tr).attr("aria-labelledby", "ftal_" + opts.idPrefix + node.key);
|
||||
// }
|
||||
node.span = $("span.fancytree-node", node.tr).get(0);
|
||||
// Set icon, link, and title (normally this is only required on initial render)
|
||||
this.nodeRenderTitle(ctx);
|
||||
// Allow tweaking, binding, after node was created for the first time
|
||||
// tree._triggerNodeEvent("createNode", ctx);
|
||||
if (opts.createNode) {
|
||||
opts.createNode.call(tree, { type: "createNode" }, ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Allow tweaking after node state was rendered
|
||||
// tree._triggerNodeEvent("renderNode", ctx);
|
||||
if (opts.renderNode) {
|
||||
opts.renderNode.call(tree, { type: "renderNode" }, ctx);
|
||||
}
|
||||
// Visit child nodes
|
||||
// Add child markup
|
||||
children = node.children;
|
||||
if (children && (isRootNode || deep || node.expanded)) {
|
||||
for (i = 0, l = children.length; i < l; i++) {
|
||||
subCtx = $.extend({}, ctx, { node: children[i] });
|
||||
subCtx.hasCollapsedParents =
|
||||
subCtx.hasCollapsedParents || !node.expanded;
|
||||
this.nodeRender(subCtx, force, deep, collapsed, true);
|
||||
}
|
||||
}
|
||||
// Make sure, that <tr> order matches node.children order.
|
||||
if (children && !_recursive) {
|
||||
// we only have to do it once, for the root branch
|
||||
prevTr = node.tr || null;
|
||||
firstTr = tree.tbody.firstChild;
|
||||
// Iterate over all descendants
|
||||
node.visit(function (n) {
|
||||
if (n.tr) {
|
||||
if (
|
||||
!n.parent.expanded &&
|
||||
n.tr.style.display !== "none"
|
||||
) {
|
||||
// fix after a node was dropped over a collapsed
|
||||
n.tr.style.display = "none";
|
||||
setChildRowVisibility(n, false);
|
||||
}
|
||||
if (n.tr.previousSibling !== prevTr) {
|
||||
node.debug("_fixOrder: mismatch at node: " + n);
|
||||
var nextTr = prevTr ? prevTr.nextSibling : firstTr;
|
||||
tree.tbody.insertBefore(n.tr, nextTr);
|
||||
}
|
||||
prevTr = n.tr;
|
||||
}
|
||||
});
|
||||
}
|
||||
// Update element classes according to node state
|
||||
// if(!isRootNode){
|
||||
// this.nodeRenderStatus(ctx);
|
||||
// }
|
||||
},
|
||||
nodeRenderTitle: function (ctx, title) {
|
||||
var $cb,
|
||||
res,
|
||||
tree = ctx.tree,
|
||||
node = ctx.node,
|
||||
opts = ctx.options,
|
||||
isStatusNode = node.isStatusNode();
|
||||
|
||||
res = this._super(ctx, title);
|
||||
|
||||
if (node.isRootNode()) {
|
||||
return res;
|
||||
}
|
||||
// Move checkbox to custom column
|
||||
if (
|
||||
opts.checkbox &&
|
||||
!isStatusNode &&
|
||||
opts.table.checkboxColumnIdx != null
|
||||
) {
|
||||
$cb = $("span.fancytree-checkbox", node.span); //.detach();
|
||||
$(node.tr)
|
||||
.find("td")
|
||||
.eq(+opts.table.checkboxColumnIdx)
|
||||
.html($cb);
|
||||
}
|
||||
// Update element classes according to node state
|
||||
this.nodeRenderStatus(ctx);
|
||||
|
||||
if (isStatusNode) {
|
||||
if (opts.renderStatusColumns) {
|
||||
// Let user code write column content
|
||||
opts.renderStatusColumns.call(
|
||||
tree,
|
||||
{ type: "renderStatusColumns" },
|
||||
ctx
|
||||
);
|
||||
} else if (opts.table.mergeStatusColumns && node.isTopLevel()) {
|
||||
$(node.tr)
|
||||
.find(">td")
|
||||
.eq(0)
|
||||
.prop("colspan", tree.columnCount)
|
||||
.text(node.title)
|
||||
.addClass("fancytree-status-merged")
|
||||
.nextAll()
|
||||
.remove();
|
||||
} // else: default rendering for status node: leave other cells empty
|
||||
} else if (opts.renderColumns) {
|
||||
opts.renderColumns.call(tree, { type: "renderColumns" }, ctx);
|
||||
}
|
||||
return res;
|
||||
},
|
||||
nodeRenderStatus: function (ctx) {
|
||||
var indent,
|
||||
node = ctx.node,
|
||||
opts = ctx.options;
|
||||
|
||||
this._super(ctx);
|
||||
|
||||
$(node.tr).removeClass("fancytree-node");
|
||||
// indent
|
||||
indent = (node.getLevel() - 1) * opts.table.indentation;
|
||||
if (opts.rtl) {
|
||||
$(node.span).css({ paddingRight: indent + "px" });
|
||||
} else {
|
||||
$(node.span).css({ paddingLeft: indent + "px" });
|
||||
}
|
||||
},
|
||||
/* Expand node, return Deferred.promise. */
|
||||
nodeSetExpanded: function (ctx, flag, callOpts) {
|
||||
// flag defaults to true
|
||||
flag = flag !== false;
|
||||
|
||||
if ((ctx.node.expanded && flag) || (!ctx.node.expanded && !flag)) {
|
||||
// Expanded state isn't changed - just call base implementation
|
||||
return this._superApply(arguments);
|
||||
}
|
||||
|
||||
var dfd = new $.Deferred(),
|
||||
subOpts = $.extend({}, callOpts, {
|
||||
noEvents: true,
|
||||
noAnimation: true,
|
||||
});
|
||||
|
||||
callOpts = callOpts || {};
|
||||
|
||||
function _afterExpand(ok, args) {
|
||||
// ctx.tree.info("ok:" + ok, args);
|
||||
if (ok) {
|
||||
// #1108 minExpandLevel: 2 together with table extension does not work
|
||||
// don't call when 'ok' is false:
|
||||
setChildRowVisibility(ctx.node, flag);
|
||||
if (
|
||||
flag &&
|
||||
ctx.options.autoScroll &&
|
||||
!callOpts.noAnimation &&
|
||||
ctx.node.hasChildren()
|
||||
) {
|
||||
// Scroll down to last child, but keep current node visible
|
||||
ctx.node
|
||||
.getLastChild()
|
||||
.scrollIntoView(true, { topNode: ctx.node })
|
||||
.always(function () {
|
||||
if (!callOpts.noEvents) {
|
||||
ctx.tree._triggerNodeEvent(
|
||||
flag ? "expand" : "collapse",
|
||||
ctx
|
||||
);
|
||||
}
|
||||
dfd.resolveWith(ctx.node);
|
||||
});
|
||||
} else {
|
||||
if (!callOpts.noEvents) {
|
||||
ctx.tree._triggerNodeEvent(
|
||||
flag ? "expand" : "collapse",
|
||||
ctx
|
||||
);
|
||||
}
|
||||
dfd.resolveWith(ctx.node);
|
||||
}
|
||||
} else {
|
||||
if (!callOpts.noEvents) {
|
||||
ctx.tree._triggerNodeEvent(
|
||||
flag ? "expand" : "collapse",
|
||||
ctx
|
||||
);
|
||||
}
|
||||
dfd.rejectWith(ctx.node);
|
||||
}
|
||||
}
|
||||
// Call base-expand with disabled events and animation
|
||||
this._super(ctx, flag, subOpts)
|
||||
.done(function () {
|
||||
_afterExpand(true, arguments);
|
||||
})
|
||||
.fail(function () {
|
||||
_afterExpand(false, arguments);
|
||||
});
|
||||
return dfd.promise();
|
||||
},
|
||||
nodeSetStatus: function (ctx, status, message, details) {
|
||||
if (status === "ok") {
|
||||
var node = ctx.node,
|
||||
firstChild = node.children ? node.children[0] : null;
|
||||
if (firstChild && firstChild.isStatusNode()) {
|
||||
$(firstChild.tr).remove();
|
||||
}
|
||||
}
|
||||
return this._superApply(arguments);
|
||||
},
|
||||
treeClear: function (ctx) {
|
||||
this.nodeRemoveChildMarkup(this._makeHookContext(this.rootNode));
|
||||
return this._superApply(arguments);
|
||||
},
|
||||
treeDestroy: function (ctx) {
|
||||
this.$container.find("tbody").empty();
|
||||
if (this.$source) {
|
||||
this.$source.removeClass("fancytree-helper-hidden");
|
||||
}
|
||||
return this._superApply(arguments);
|
||||
},
|
||||
/*,
|
||||
treeSetFocus: function(ctx, flag) {
|
||||
// alert("treeSetFocus" + ctx.tree.$container);
|
||||
ctx.tree.$container.focus();
|
||||
$.ui.fancytree.focusTree = ctx.tree;
|
||||
}*/
|
||||
});
|
||||
// Value returned by `require('jquery.fancytree..')`
|
||||
return $.ui.fancytree;
|
||||
}); // End of closure
|
Loading…
Add table
Add a link
Reference in a new issue