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,218 @@
|
|||
/*!
|
||||
* jquery.fancytree.gridnav.js
|
||||
*
|
||||
* Support keyboard navigation for trees with embedded input controls.
|
||||
* (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",
|
||||
"./jquery.fancytree.table",
|
||||
], factory);
|
||||
} else if (typeof module === "object" && module.exports) {
|
||||
// Node/CommonJS
|
||||
require("./jquery.fancytree.table"); // core + table
|
||||
module.exports = factory(require("jquery"));
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
})(function ($) {
|
||||
"use strict";
|
||||
|
||||
/*******************************************************************************
|
||||
* Private functions and variables
|
||||
*/
|
||||
|
||||
// Allow these navigation keys even when input controls are focused
|
||||
|
||||
var KC = $.ui.keyCode,
|
||||
// which keys are *not* handled by embedded control, but passed to tree
|
||||
// navigation handler:
|
||||
NAV_KEYS = {
|
||||
text: [KC.UP, KC.DOWN],
|
||||
checkbox: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
|
||||
link: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
|
||||
radiobutton: [KC.UP, KC.DOWN, KC.LEFT, KC.RIGHT],
|
||||
"select-one": [KC.LEFT, KC.RIGHT],
|
||||
"select-multiple": [KC.LEFT, KC.RIGHT],
|
||||
};
|
||||
|
||||
/* Calculate TD column index (considering colspans).*/
|
||||
function getColIdx($tr, $td) {
|
||||
var colspan,
|
||||
td = $td.get(0),
|
||||
idx = 0;
|
||||
|
||||
$tr.children().each(function () {
|
||||
if (this === td) {
|
||||
return false;
|
||||
}
|
||||
colspan = $(this).prop("colspan");
|
||||
idx += colspan ? colspan : 1;
|
||||
});
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* Find TD at given column index (considering colspans).*/
|
||||
function findTdAtColIdx($tr, colIdx) {
|
||||
var colspan,
|
||||
res = null,
|
||||
idx = 0;
|
||||
|
||||
$tr.children().each(function () {
|
||||
if (idx >= colIdx) {
|
||||
res = $(this);
|
||||
return false;
|
||||
}
|
||||
colspan = $(this).prop("colspan");
|
||||
idx += colspan ? colspan : 1;
|
||||
});
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Find adjacent cell for a given direction. Skip empty cells and consider merged cells */
|
||||
function findNeighbourTd($target, keyCode) {
|
||||
var $tr,
|
||||
colIdx,
|
||||
$td = $target.closest("td"),
|
||||
$tdNext = null;
|
||||
|
||||
switch (keyCode) {
|
||||
case KC.LEFT:
|
||||
$tdNext = $td.prev();
|
||||
break;
|
||||
case KC.RIGHT:
|
||||
$tdNext = $td.next();
|
||||
break;
|
||||
case KC.UP:
|
||||
case KC.DOWN:
|
||||
$tr = $td.parent();
|
||||
colIdx = getColIdx($tr, $td);
|
||||
while (true) {
|
||||
$tr = keyCode === KC.UP ? $tr.prev() : $tr.next();
|
||||
if (!$tr.length) {
|
||||
break;
|
||||
}
|
||||
// Skip hidden rows
|
||||
if ($tr.is(":hidden")) {
|
||||
continue;
|
||||
}
|
||||
// Find adjacent cell in the same column
|
||||
$tdNext = findTdAtColIdx($tr, colIdx);
|
||||
// Skip cells that don't conatain a focusable element
|
||||
if ($tdNext && $tdNext.find(":input,a").length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return $tdNext;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
* Extension code
|
||||
*/
|
||||
$.ui.fancytree.registerExtension({
|
||||
name: "gridnav",
|
||||
version: "2.38.3",
|
||||
// Default options for this extension.
|
||||
options: {
|
||||
autofocusInput: false, // Focus first embedded input if node gets activated
|
||||
handleCursorKeys: true, // Allow UP/DOWN in inputs to move to prev/next node
|
||||
},
|
||||
|
||||
treeInit: function (ctx) {
|
||||
// gridnav requires the table extension to be loaded before itself
|
||||
this._requireExtension("table", true, true);
|
||||
this._superApply(arguments);
|
||||
|
||||
this.$container.addClass("fancytree-ext-gridnav");
|
||||
|
||||
// Activate node if embedded input gets focus (due to a click)
|
||||
this.$container.on("focusin", function (event) {
|
||||
var ctx2,
|
||||
node = $.ui.fancytree.getNode(event.target);
|
||||
|
||||
if (node && !node.isActive()) {
|
||||
// Call node.setActive(), but also pass the event
|
||||
ctx2 = ctx.tree._makeHookContext(node, event);
|
||||
ctx.tree._callHook("nodeSetActive", ctx2, true);
|
||||
}
|
||||
});
|
||||
},
|
||||
nodeSetActive: function (ctx, flag, callOpts) {
|
||||
var $outer,
|
||||
opts = ctx.options.gridnav,
|
||||
node = ctx.node,
|
||||
event = ctx.originalEvent || {},
|
||||
triggeredByInput = $(event.target).is(":input");
|
||||
|
||||
flag = flag !== false;
|
||||
|
||||
this._superApply(arguments);
|
||||
|
||||
if (flag) {
|
||||
if (ctx.options.titlesTabbable) {
|
||||
if (!triggeredByInput) {
|
||||
$(node.span).find("span.fancytree-title").focus();
|
||||
node.setFocus();
|
||||
}
|
||||
// If one node is tabbable, the container no longer needs to be
|
||||
ctx.tree.$container.attr("tabindex", "-1");
|
||||
// ctx.tree.$container.removeAttr("tabindex");
|
||||
} else if (opts.autofocusInput && !triggeredByInput) {
|
||||
// Set focus to input sub input (if node was clicked, but not
|
||||
// when TAB was pressed )
|
||||
$outer = $(node.tr || node.span);
|
||||
$outer.find(":input:enabled").first().focus();
|
||||
}
|
||||
}
|
||||
},
|
||||
nodeKeydown: function (ctx) {
|
||||
var inputType,
|
||||
handleKeys,
|
||||
$td,
|
||||
opts = ctx.options.gridnav,
|
||||
event = ctx.originalEvent,
|
||||
$target = $(event.target);
|
||||
|
||||
if ($target.is(":input:enabled")) {
|
||||
inputType = $target.prop("type");
|
||||
} else if ($target.is("a")) {
|
||||
inputType = "link";
|
||||
}
|
||||
// ctx.tree.debug("ext-gridnav nodeKeydown", event, inputType);
|
||||
|
||||
if (inputType && opts.handleCursorKeys) {
|
||||
handleKeys = NAV_KEYS[inputType];
|
||||
if (handleKeys && $.inArray(event.which, handleKeys) >= 0) {
|
||||
$td = findNeighbourTd($target, event.which);
|
||||
if ($td && $td.length) {
|
||||
// ctx.node.debug("ignore keydown in input", event.which, handleKeys);
|
||||
$td.find(":input:enabled,a").focus();
|
||||
// Prevent Fancytree default navigation
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// ctx.tree.debug("ext-gridnav NOT HANDLED", event, inputType);
|
||||
return this._superApply(arguments);
|
||||
},
|
||||
});
|
||||
// Value returned by `require('jquery.fancytree..')`
|
||||
return $.ui.fancytree;
|
||||
}); // End of closure
|
Loading…
Add table
Add a link
Reference in a new issue