|
- /*!
- * jquery.fancytree.edit.js
- *
- * Make node titles editable.
- * (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 isMac = /Mac/.test(navigator.platform),
- escapeHtml = $.ui.fancytree.escapeHtml,
- trim = $.ui.fancytree.trim,
- unescapeHtml = $.ui.fancytree.unescapeHtml;
-
- /**
- * [ext-edit] Start inline editing of current node title.
- *
- * @alias FancytreeNode#editStart
- * @requires Fancytree
- */
- $.ui.fancytree._FancytreeNodeClass.prototype.editStart = function () {
- var $input,
- node = this,
- tree = this.tree,
- local = tree.ext.edit,
- instOpts = tree.options.edit,
- $title = $(".fancytree-title", node.span),
- eventData = {
- node: node,
- tree: tree,
- options: tree.options,
- isNew: $(node[tree.statusClassPropName]).hasClass(
- "fancytree-edit-new"
- ),
- orgTitle: node.title,
- input: null,
- dirty: false,
- };
-
- // beforeEdit may want to modify the title before editing
- if (
- instOpts.beforeEdit.call(
- node,
- { type: "beforeEdit" },
- eventData
- ) === false
- ) {
- return false;
- }
- $.ui.fancytree.assert(!local.currentNode, "recursive edit");
- local.currentNode = this;
- local.eventData = eventData;
-
- // Disable standard Fancytree mouse- and key handling
- tree.widget._unbind();
-
- local.lastDraggableAttrValue = node.span.draggable;
- if (local.lastDraggableAttrValue) {
- node.span.draggable = false;
- }
-
- // #116: ext-dnd prevents the blur event, so we have to catch outer clicks
- $(document).on("mousedown.fancytree-edit", function (event) {
- if (!$(event.target).hasClass("fancytree-edit-input")) {
- node.editEnd(true, event);
- }
- });
-
- // Replace node with <input>
- $input = $("<input />", {
- class: "fancytree-edit-input",
- type: "text",
- value: tree.options.escapeTitles
- ? eventData.orgTitle
- : unescapeHtml(eventData.orgTitle),
- });
- local.eventData.input = $input;
- if (instOpts.adjustWidthOfs != null) {
- $input.width($title.width() + instOpts.adjustWidthOfs);
- }
- if (instOpts.inputCss != null) {
- $input.css(instOpts.inputCss);
- }
-
- $title.html($input);
-
- // Focus <input> and bind keyboard handler
- $input
- .focus()
- .change(function (event) {
- $input.addClass("fancytree-edit-dirty");
- })
- .on("keydown", function (event) {
- switch (event.which) {
- case $.ui.keyCode.ESCAPE:
- node.editEnd(false, event);
- break;
- case $.ui.keyCode.ENTER:
- node.editEnd(true, event);
- return false; // so we don't start editmode on Mac
- }
- event.stopPropagation();
- })
- .blur(function (event) {
- return node.editEnd(true, event);
- });
-
- instOpts.edit.call(node, { type: "edit" }, eventData);
- };
-
- /**
- * [ext-edit] Stop inline editing.
- * @param {Boolean} [applyChanges=false] false: cancel edit, true: save (if modified)
- * @alias FancytreeNode#editEnd
- * @requires jquery.fancytree.edit.js
- */
- $.ui.fancytree._FancytreeNodeClass.prototype.editEnd = function (
- applyChanges,
- _event
- ) {
- var newVal,
- node = this,
- tree = this.tree,
- local = tree.ext.edit,
- eventData = local.eventData,
- instOpts = tree.options.edit,
- $title = $(".fancytree-title", node.span),
- $input = $title.find("input.fancytree-edit-input");
-
- if (instOpts.trim) {
- $input.val(trim($input.val()));
- }
- newVal = $input.val();
-
- eventData.dirty = newVal !== node.title;
- eventData.originalEvent = _event;
-
- // Find out, if saving is required
- if (applyChanges === false) {
- // If true/false was passed, honor this (except in rename mode, if unchanged)
- eventData.save = false;
- } else if (eventData.isNew) {
- // In create mode, we save everything, except for empty text
- eventData.save = newVal !== "";
- } else {
- // In rename mode, we save everyting, except for empty or unchanged text
- eventData.save = eventData.dirty && newVal !== "";
- }
- // Allow to break (keep editor open), modify input, or re-define data.save
- if (
- instOpts.beforeClose.call(
- node,
- { type: "beforeClose" },
- eventData
- ) === false
- ) {
- return false;
- }
- if (
- eventData.save &&
- instOpts.save.call(node, { type: "save" }, eventData) === false
- ) {
- return false;
- }
- $input.removeClass("fancytree-edit-dirty").off();
- // Unbind outer-click handler
- $(document).off(".fancytree-edit");
-
- if (eventData.save) {
- // # 171: escape user input (not required if global escaping is on)
- node.setTitle(
- tree.options.escapeTitles ? newVal : escapeHtml(newVal)
- );
- node.setFocus();
- } else {
- if (eventData.isNew) {
- node.remove();
- node = eventData.node = null;
- local.relatedNode.setFocus();
- } else {
- node.renderTitle();
- node.setFocus();
- }
- }
- local.eventData = null;
- local.currentNode = null;
- local.relatedNode = null;
- // Re-enable mouse and keyboard handling
- tree.widget._bind();
-
- if (node && local.lastDraggableAttrValue) {
- node.span.draggable = true;
- }
-
- // Set keyboard focus, even if setFocus() claims 'nothing to do'
- tree.$container.get(0).focus({ preventScroll: true });
- eventData.input = null;
- instOpts.close.call(node, { type: "close" }, eventData);
- return true;
- };
-
- /**
- * [ext-edit] Create a new child or sibling node and start edit mode.
- *
- * @param {String} [mode='child'] 'before', 'after', or 'child'
- * @param {Object} [init] NodeData (or simple title string)
- * @alias FancytreeNode#editCreateNode
- * @requires jquery.fancytree.edit.js
- * @since 2.4
- */
- $.ui.fancytree._FancytreeNodeClass.prototype.editCreateNode = function (
- mode,
- init
- ) {
- var newNode,
- tree = this.tree,
- self = this;
-
- mode = mode || "child";
- if (init == null) {
- init = { title: "" };
- } else if (typeof init === "string") {
- init = { title: init };
- } else {
- $.ui.fancytree.assert($.isPlainObject(init));
- }
- // Make sure node is expanded (and loaded) in 'child' mode
- if (
- mode === "child" &&
- !this.isExpanded() &&
- this.hasChildren() !== false
- ) {
- this.setExpanded().done(function () {
- self.editCreateNode(mode, init);
- });
- return;
- }
- newNode = this.addNode(init, mode);
-
- // #644: Don't filter new nodes.
- newNode.match = true;
- $(newNode[tree.statusClassPropName])
- .removeClass("fancytree-hide")
- .addClass("fancytree-match");
-
- newNode.makeVisible(/*{noAnimation: true}*/).done(function () {
- $(newNode[tree.statusClassPropName]).addClass("fancytree-edit-new");
- self.tree.ext.edit.relatedNode = self;
- newNode.editStart();
- });
- };
-
- /**
- * [ext-edit] Check if any node in this tree in edit mode.
- *
- * @returns {FancytreeNode | null}
- * @alias Fancytree#isEditing
- * @requires jquery.fancytree.edit.js
- */
- $.ui.fancytree._FancytreeClass.prototype.isEditing = function () {
- return this.ext.edit ? this.ext.edit.currentNode : null;
- };
-
- /**
- * [ext-edit] Check if this node is in edit mode.
- * @returns {Boolean} true if node is currently beeing edited
- * @alias FancytreeNode#isEditing
- * @requires jquery.fancytree.edit.js
- */
- $.ui.fancytree._FancytreeNodeClass.prototype.isEditing = function () {
- return this.tree.ext.edit
- ? this.tree.ext.edit.currentNode === this
- : false;
- };
-
- /*******************************************************************************
- * Extension code
- */
- $.ui.fancytree.registerExtension({
- name: "edit",
- version: "2.38.3",
- // Default options for this extension.
- options: {
- adjustWidthOfs: 4, // null: don't adjust input size to content
- allowEmpty: false, // Prevent empty input
- inputCss: { minWidth: "3em" },
- // triggerCancel: ["esc", "tab", "click"],
- triggerStart: ["f2", "mac+enter", "shift+click"],
- trim: true, // Trim whitespace before save
- // Events:
- beforeClose: $.noop, // Return false to prevent cancel/save (data.input is available)
- beforeEdit: $.noop, // Return false to prevent edit mode
- close: $.noop, // Editor was removed
- edit: $.noop, // Editor was opened (available as data.input)
- // keypress: $.noop, // Not yet implemented
- save: $.noop, // Save data.input.val() or return false to keep editor open
- },
- // Local attributes
- currentNode: null,
-
- treeInit: function (ctx) {
- var tree = ctx.tree;
-
- this._superApply(arguments);
-
- this.$container
- .addClass("fancytree-ext-edit")
- .on("fancytreebeforeupdateviewport", function (event, data) {
- var editNode = tree.isEditing();
- // When scrolling, the TR may be re-used by another node, so the
- // active cell marker an
- if (editNode) {
- editNode.info("Cancel edit due to scroll event.");
- editNode.editEnd(false, event);
- }
- });
- },
- nodeClick: function (ctx) {
- var eventStr = $.ui.fancytree.eventToString(ctx.originalEvent),
- triggerStart = ctx.options.edit.triggerStart;
-
- if (
- eventStr === "shift+click" &&
- $.inArray("shift+click", triggerStart) >= 0
- ) {
- if (ctx.originalEvent.shiftKey) {
- ctx.node.editStart();
- return false;
- }
- }
- if (
- eventStr === "click" &&
- $.inArray("clickActive", triggerStart) >= 0
- ) {
- // Only when click was inside title text (not aynwhere else in the row)
- if (
- ctx.node.isActive() &&
- !ctx.node.isEditing() &&
- $(ctx.originalEvent.target).hasClass("fancytree-title")
- ) {
- ctx.node.editStart();
- return false;
- }
- }
- return this._superApply(arguments);
- },
- nodeDblclick: function (ctx) {
- if ($.inArray("dblclick", ctx.options.edit.triggerStart) >= 0) {
- ctx.node.editStart();
- return false;
- }
- return this._superApply(arguments);
- },
- nodeKeydown: function (ctx) {
- switch (ctx.originalEvent.which) {
- case 113: // [F2]
- if ($.inArray("f2", ctx.options.edit.triggerStart) >= 0) {
- ctx.node.editStart();
- return false;
- }
- break;
- case $.ui.keyCode.ENTER:
- if (
- $.inArray("mac+enter", ctx.options.edit.triggerStart) >=
- 0 &&
- isMac
- ) {
- ctx.node.editStart();
- return false;
- }
- break;
- }
- return this._superApply(arguments);
- },
- });
- // Value returned by `require('jquery.fancytree..')`
- return $.ui.fancytree;
- }); // End of closure
|