1/*!
2 * jquery.fancytree.columnview.js
3 *
4 * Render tree like a Mac Finder's column view.
5 * (Extension module for jquery.fancytree.js: https://github.com/mar10/fancytree/)
6 *
7 * Copyright (c) 2008-2023, Martin Wendt (https://wwWendt.de)
8 *
9 * Released under the MIT license
10 * https://github.com/mar10/fancytree/wiki/LicenseInfo
11 *
12 * @version 2.38.3
13 * @date 2023-02-01T20:52:50Z
14 */
15
16(function (factory) {
17	if (typeof define === "function" && define.amd) {
18		// AMD. Register as an anonymous module.
19		define(["jquery", "./jquery.fancytree"], factory);
20	} else if (typeof module === "object" && module.exports) {
21		// Node/CommonJS
22		require("./jquery.fancytree");
23		module.exports = factory(require("jquery"));
24	} else {
25		// Browser globals
26		factory(jQuery);
27	}
28})(function ($) {
29	"use strict";
30
31	/*******************************************************************************
32	 * Private functions and variables
33	 */
34	var _assert = $.ui.fancytree.assert,
35		FT = $.ui.fancytree;
36
37	/*******************************************************************************
38	 * Private functions and variables
39	 */
40	$.ui.fancytree.registerExtension({
41		name: "columnview",
42		version: "2.38.3",
43		// Default options for this extension.
44		options: {},
45		// Overide virtual methods for this extension.
46		// `this`       : is this extension object
47		// `this._base` : the Fancytree instance
48		// `this._super`: the virtual function that was overriden (member of prev. extension or Fancytree)
49		treeInit: function (ctx) {
50			var $tdFirst,
51				$ul,
52				tree = ctx.tree,
53				$table = tree.widget.element;
54
55			tree.tr = $("tbody tr", $table)[0];
56			tree.$tdList = $(">td", tree.tr);
57			tree.columnCount = tree.$tdList.length;
58			// Perform default behavior
59			this._superApply(arguments);
60			// Standard Fancytree created a root <ul>. Now move this into first table cell
61			$ul = $(tree.rootNode.ul);
62			$tdFirst = tree.$tdList.eq(0);
63
64			_assert(
65				$.inArray("table", this.options.extensions) < 0,
66				"columnview extensions must not use ext-table"
67			);
68			_assert(
69				tree.columnCount >= 2,
70				"columnview target must be a table with at least two columns"
71			);
72
73			$ul.removeClass("fancytree-container").removeAttr("tabindex");
74			tree.$container = $table;
75			$table
76				.addClass("fancytree-container fancytree-ext-columnview")
77				.attr("tabindex", "0");
78
79			$tdFirst.empty();
80			$ul.detach().appendTo($tdFirst);
81
82			// Force some required options
83			tree.widget.options.autoCollapse = true;
84			// tree.widget.options.autoActivate = true;
85			tree.widget.options.toggleEffect = false;
86			tree.widget.options.clickFolderMode = 1;
87
88			$table
89				// Make sure that only active path is expanded when a node is activated:
90				.on("fancytreeactivate", function (event, data) {
91					var node = data.node,
92						tree = data.tree,
93						level = node.getLevel();
94
95					tree._callHook("nodeCollapseSiblings", node);
96					// Clear right neighbours
97					if (!node.expanded) {
98						tree.$tdList.eq(level).nextAll().empty();
99					}
100					// Expand nodes on activate, so we populate the right neighbor cell
101					if (!node.expanded && (node.children || node.lazy)) {
102						node.setExpanded();
103					}
104				})
105				// Adjust keyboard behaviour:
106				.on("fancytreekeydown", function (event, data) {
107					var next = null,
108						handled = true,
109						node = data.node || data.tree.getFirstChild();
110
111					if (node.getLevel() >= tree.columnCount) {
112						return;
113					}
114					switch (FT.eventToString(event)) {
115						case "down":
116							next = node.getNextSibling();
117							break;
118						case "left":
119							if (!node.isTopLevel()) {
120								next = node.getParent();
121							}
122							break;
123						case "right":
124							next = node.getFirstChild();
125							if (!next) {
126								// default processing: expand or ignore
127								return;
128							}
129							// Prefer an expanded child if any
130							next.visitSiblings(function (n) {
131								if (n.expanded) {
132									next = n;
133									return false;
134								}
135							}, true);
136							break;
137						case "up":
138							next = node.getPrevSibling();
139							break;
140						default:
141							handled = false;
142					}
143					if (next) {
144						next.setActive();
145					}
146					return !handled;
147				});
148		},
149		nodeSetExpanded: function (ctx, flag, callOpts) {
150			var $wait,
151				node = ctx.node,
152				tree = ctx.tree,
153				level = node.getLevel();
154
155			if (flag !== false && !node.expanded && node.isUndefined()) {
156				$wait = $(
157					"<span class='fancytree-icon fancytree-icon-loading'>"
158				);
159				tree.$tdList.eq(level).empty().append($wait);
160			}
161			return this._superApply(arguments);
162		},
163		nodeRemoveChildren: function (ctx) {
164			// #899: node's children removed: remove child marker...
165			$(ctx.node.span).find("span.fancytree-cv-right").remove();
166			// ...and clear right columns
167			ctx.tree.$tdList.eq(ctx.node.getLevel()).nextAll().empty();
168			return this._superApply(arguments);
169		},
170		nodeRender: function (ctx, force, deep, collapsed, _recursive) {
171			// Render standard nested <ul> - <li> hierarchy
172			this._super(ctx, force, deep, collapsed, _recursive);
173			// Remove expander and add a trailing triangle instead
174			var level,
175				$tdChild,
176				$ul,
177				tree = ctx.tree,
178				node = ctx.node,
179				$span = $(node.span);
180
181			$span.find("span.fancytree-expander").remove();
182			if (
183				node.hasChildren() !== false &&
184				!$span.find("span.fancytree-cv-right").length
185			) {
186				$span.append(
187					$("<span class='fancytree-icon fancytree-cv-right'>")
188				);
189			}
190			// Move <ul> with children into the appropriate <td>
191			if (node.ul && node.expanded) {
192				node.ul.style.display = ""; // might be hidden if RIGHT was pressed
193				level = node.getLevel();
194				if (level < tree.columnCount) {
195					// only if we are not in the last column
196					$tdChild = tree.$tdList.eq(level);
197					$ul = $(node.ul).detach();
198					$tdChild.empty().append($ul);
199				}
200			}
201		},
202	});
203	// Value returned by `require('jquery.fancytree..')`
204	return $.ui.fancytree;
205}); // End of closure
206