From 375091916966736c76a887afa5dcdda120f7955a Mon Sep 17 00:00:00 2001 From: azivner Date: Fri, 9 Nov 2018 22:18:51 +0100 Subject: [PATCH] fixed context menus in relation map --- .../javascripts/services/context_menu.js | 2 + .../services/note_detail_relation_map.js | 84 ++++++++-------- src/public/libraries/jsplumb.js | 98 ++++++++++--------- src/views/details/relation_map.ejs | 10 +- 4 files changed, 97 insertions(+), 97 deletions(-) diff --git a/src/public/javascripts/services/context_menu.js b/src/public/javascripts/services/context_menu.js index e2d1322f9..2ee0e552e 100644 --- a/src/public/javascripts/services/context_menu.js +++ b/src/public/javascripts/services/context_menu.js @@ -30,6 +30,8 @@ function initContextMenu(event, contextMenuItems, selectContextMenuItem) { $item.click(async function (e) { const cmd = $(e.target).prop("data-cmd"); + e.originalTarget = event.target; + await selectContextMenuItem(e, cmd); }); diff --git a/src/public/javascripts/services/note_detail_relation_map.js b/src/public/javascripts/services/note_detail_relation_map.js index 955f0accb..6887ef594 100644 --- a/src/public/javascripts/services/note_detail_relation_map.js +++ b/src/public/javascripts/services/note_detail_relation_map.js @@ -3,6 +3,7 @@ import noteDetailService from "./note_detail.js"; import linkService from "./link.js"; import libraryLoader from "./library_loader.js"; import treeService from "./tree.js"; +import contextMenuWidget from "./context_menu.js"; const $component = $("#note-detail-relation-map"); const $relationMapCanvas = $("#relation-map-canvas"); @@ -221,41 +222,43 @@ function initJsPlumbInstance () { jsPlumbInstance.bind("connection", connectionCreatedHandler); - $relationMapCanvas.contextmenu({ - delegate: ".note-box", - menu: [ - {title: "Remove note", cmd: "remove", uiIcon: "trash"}, - {title: "Edit title", cmd: "edit-title", uiIcon: "pencil"}, - ], - select: noteContextMenuHandler - }); - - $relationMapCanvas.contextmenuRelation({ - delegate: ".connection-label,.jtk-connector", - autoTrigger: false, // it doesn't open automatically, needs to be triggered explicitly by .open() call - menu: [ - {title: "Remove relation", cmd: "remove", uiIcon: "trash"} - ], - select: relationContextMenuHandler - }); - - jsPlumbInstance.bind("contextmenu", function (c, e) { - e.preventDefault(); - - $relationMapCanvas.contextmenuRelation("open", e, { connection: c }); - }); - // so that canvas is not panned when clicking/dragging note box $relationMapCanvas.on('mousedown touchstart', '.note-box, .connection-label', e => e.stopPropagation()); } +function connectionContextMenuHandler(connection, event) { + event.preventDefault(); + event.stopPropagation(); + + const contextMenuItems = [ {title: "Remove relation", cmd: "remove", uiIcon: "trash"} ]; + + contextMenuWidget.initContextMenu(event, contextMenuItems, async (event, cmd) => { + if (cmd === 'remove') { + if (!confirm("Are you sure you want to remove the relation?")) { + return; + } + + const relation = relations.find(rel => rel.attributeId === connection.id); + + await server.remove(`notes/${relation.sourceNoteId}/relations/${relation.name}/to/${relation.targetNoteId}`); + + jsPlumbInstance.deleteConnection(connection); + + relations = relations.filter(relation => relation.attributeId !== connection.id); + } + }); +} + async function connectionCreatedHandler(info, originalEvent) { + const connection = info.connection; + + connection.bind("contextmenu", (obj, event) => connectionContextMenuHandler(connection, event)); + // if there's no event, then this has been triggered programatically if (!originalEvent) { return; } - const connection = info.connection; const name = prompt("Specify new relation name:"); if (!name || !name.trim()) { @@ -288,29 +291,22 @@ async function connectionCreatedHandler(info, originalEvent) { connection.getOverlay("label").setLabel(name); } -async function relationContextMenuHandler(event, ui) { - const {connection} = ui.extraData; +$relationMapCanvas.on("contextmenu", ".note-box", e => { + const contextMenuItems = [ + {title: "Remove note", cmd: "remove", uiIcon: "trash"}, + {title: "Edit title", cmd: "edit-title", uiIcon: "pencil"}, + ]; - if (ui.cmd === 'remove') { - if (!confirm("Are you sure you want to remove the relation?")) { - return; - } + contextMenuWidget.initContextMenu(e, contextMenuItems, noteContextMenuHandler); - const relation = relations.find(rel => rel.attributeId === connection.id); + return false; +}); - await server.remove(`notes/${relation.sourceNoteId}/relations/${relation.name}/to/${relation.targetNoteId}`); - - jsPlumbInstance.deleteConnection(connection); - - relations = relations.filter(relation => relation.attributeId !== connection.id); - } -} - -async function noteContextMenuHandler(event, ui) { - const $noteBox = ui.target.closest(".note-box"); +async function noteContextMenuHandler(event, cmd) { + const $noteBox = $(event.originalTarget).closest(".note-box"); const noteId = $noteBox.prop("id"); - if (ui.cmd === "remove") { + if (cmd === "remove") { if (!confirm("Are you sure you want to remove the note from this diagram?")) { return; } @@ -323,7 +319,7 @@ async function noteContextMenuHandler(event, ui) { saveData(); } - else if (ui.cmd === "edit-title") { + else if (cmd === "edit-title") { const $title = $noteBox.find(".title a"); const title = prompt("Enter new note title:", $title.text()); diff --git a/src/public/libraries/jsplumb.js b/src/public/libraries/jsplumb.js index e34e8c334..96e9ac90a 100644 --- a/src/public/libraries/jsplumb.js +++ b/src/public/libraries/jsplumb.js @@ -2607,40 +2607,52 @@ }).call(typeof window !== 'undefined' ? window : this); -;(function() { - "use strict"; +(function() { var root = this; - var exports = root.jsPlumbUtil = {}; + root.jsPlumbUtil = root.jsPlumbUtil || {}; + var jsPlumbUtil = root.jsPlumbUtil; + + if (typeof exports !=='undefined') { exports.jsPlumbUtil = jsPlumbUtil;} + function isArray(a) { return Object.prototype.toString.call(a) === "[object Array]"; } + jsPlumbUtil.isArray = isArray; function isNumber(n) { return Object.prototype.toString.call(n) === "[object Number]"; } + jsPlumbUtil.isNumber = isNumber; function isString(s) { return typeof s === "string"; } + jsPlumbUtil.isString = isString; function isBoolean(s) { return typeof s === "boolean"; } + jsPlumbUtil.isBoolean = isBoolean; function isNull(s) { return s == null; } + jsPlumbUtil.isNull = isNull; function isObject(o) { return o == null ? false : Object.prototype.toString.call(o) === "[object Object]"; } + jsPlumbUtil.isObject = isObject; function isDate(o) { return Object.prototype.toString.call(o) === "[object Date]"; } + jsPlumbUtil.isDate = isDate; function isFunction(o) { return Object.prototype.toString.call(o) === "[object Function]"; } + jsPlumbUtil.isFunction = isFunction; function isNamedFunction(o) { return isFunction(o) && o.name != null && o.name.length > 0; } + jsPlumbUtil.isNamedFunction = isNamedFunction; function isEmpty(o) { for (var i in o) { if (o.hasOwnProperty(i)) { @@ -2649,6 +2661,7 @@ } return true; } + jsPlumbUtil.isEmpty = isEmpty; function clone(a) { if (isString(a)) { return "" + a; @@ -2680,16 +2693,21 @@ return a; } } - function merge(a, b, collations) { + jsPlumbUtil.clone = clone; + function merge(a, b, collations, overwrites) { // first change the collations array - if present - into a lookup table, because its faster. - var cMap = {}, ar, i; + var cMap = {}, ar, i, oMap = {}; collations = collations || []; + overwrites = overwrites || []; for (i = 0; i < collations.length; i++) { cMap[collations[i]] = true; } + for (i = 0; i < overwrites.length; i++) { + oMap[overwrites[i]] = true; + } var c = clone(a); for (i in b) { - if (c[i] == null) { + if (c[i] == null || oMap[i]) { c[i] = b[i]; } else if (isString(b[i]) || isBoolean(b[i])) { @@ -2727,6 +2745,7 @@ } return c; } + jsPlumbUtil.merge = merge; function replace(inObj, path, value) { if (inObj == null) { return; @@ -2768,6 +2787,7 @@ }); return inObj; } + jsPlumbUtil.replace = replace; // // chain a list of functions, supplied by [ object, method name, args ], and return on the first // one that returns the failValue. if none return the failValue, return the successValue. @@ -2781,6 +2801,7 @@ } return successValue; } + jsPlumbUtil.functionChain = functionChain; /** * * Take the given model and expand out any parameters. 'functionPrefix' is optional, and if present, helps jsplumb figure out what to do if a value is a Function. @@ -2838,6 +2859,7 @@ }; return _one(model); } + jsPlumbUtil.populate = populate; function findWithFunction(a, f) { if (a) { for (var i = 0; i < a.length; i++) { @@ -2848,6 +2870,7 @@ } return -1; } + jsPlumbUtil.findWithFunction = findWithFunction; function removeWithFunction(a, f) { var idx = findWithFunction(a, f); if (idx > -1) { @@ -2855,6 +2878,7 @@ } return idx !== -1; } + jsPlumbUtil.removeWithFunction = removeWithFunction; function remove(l, v) { var idx = l.indexOf(v); if (idx > -1) { @@ -2862,11 +2886,13 @@ } return idx !== -1; } + jsPlumbUtil.remove = remove; function addWithFunction(list, item, hashFunction) { if (findWithFunction(list, hashFunction) === -1) { list.push(item); } } + jsPlumbUtil.addWithFunction = addWithFunction; function addToList(map, key, value, insertAtStart) { var l = map[key]; if (l == null) { @@ -2876,6 +2902,7 @@ l[insertAtStart ? "unshift" : "push"](value); return l; } + jsPlumbUtil.addToList = addToList; function suggest(list, item, insertAtHead) { if (list.indexOf(item) === -1) { if (insertAtHead) { @@ -2888,6 +2915,7 @@ } return false; } + jsPlumbUtil.suggest = suggest; // // extends the given obj (which can be an array) with the given constructor function, prototype functions, and // class members, any of which may be null. @@ -2941,26 +2969,31 @@ } return child; } + jsPlumbUtil.extend = extend; function uuid() { return ('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); })); } + jsPlumbUtil.uuid = uuid; function fastTrim(s) { if (s == null) { return null; } var str = s.replace(/^\s\s*/, ''), ws = /\s/, i = str.length; - while (ws.test(str.charAt(--i))) { } + while (ws.test(str.charAt(--i))) { + } return str.slice(0, i + 1); } + jsPlumbUtil.fastTrim = fastTrim; function each(obj, fn) { obj = obj.length == null || typeof obj === "string" ? [obj] : obj; for (var i = 0; i < obj.length; i++) { fn(obj[i]); } } + jsPlumbUtil.each = each; function map(obj, fn) { var o = []; for (var i = 0; i < obj.length; i++) { @@ -2968,6 +3001,7 @@ } return o; } + jsPlumbUtil.map = map; function mergeWithParents(type, map, parentAttribute) { parentAttribute = parentAttribute || "parent"; var _def = function (id) { @@ -3014,13 +3048,14 @@ return {}; } } - var logEnabled = true; + jsPlumbUtil.mergeWithParents = mergeWithParents; + jsPlumbUtil.logEnabled = true; function log() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } - if (logEnabled && typeof console !== "undefined") { + if (jsPlumbUtil.logEnabled && typeof console !== "undefined") { try { var msg = arguments[arguments.length - 1]; console.log(msg); @@ -3029,6 +3064,7 @@ } } } + jsPlumbUtil.log = log; /** * Wraps one function with another, creating a placeholder for the * wrapped function if it was null. this is used to wrap the various @@ -3064,6 +3100,7 @@ return r; }; } + jsPlumbUtil.wrap = wrap; var EventGenerator = /** @class */ (function () { function EventGenerator() { var _this = this; @@ -3178,42 +3215,9 @@ } return EventGenerator; }()); - - exports.isArray = isArray; - exports.isNumber = isNumber; - exports.isString = isString; - exports.isBoolean = isBoolean; - exports.isNull = isNull; - exports.isObject = isObject; - exports.isDate = isDate; - exports.isFunction = isFunction; - exports.isNamedFunction = isNamedFunction; - exports.isEmpty = isEmpty; - exports.clone = clone; - exports.merge = merge; - exports.replace = replace; - exports.functionChain = functionChain; - exports.populate = populate; - exports.findWithFunction = findWithFunction; - exports.removeWithFunction = removeWithFunction; - exports.remove = remove; - exports.addWithFunction = addWithFunction; - exports.addToList = addToList; - exports.suggest = suggest; - exports.extend = extend; - exports.uuid = uuid; - exports.fastTrim = fastTrim; - exports.each = each; - exports.map = map; - exports.mergeWithParents = mergeWithParents; - exports.logEnabled = logEnabled; - exports.log = log; - exports.wrap = wrap; - exports.EventGenerator = EventGenerator; - + jsPlumbUtil.EventGenerator = EventGenerator; }).call(typeof window !== 'undefined' ? window : this); - /* * This file contains utility functions that run in browsers only. * @@ -3362,7 +3366,7 @@ if (tid !== "__default") { var _t = component._jsPlumb.instance.getType(tid, td); if (_t != null) { - o = _ju.merge(o, _t, [ "cssClass" ]); + o = _ju.merge(o, _t, [ "cssClass" ], [ "connector" ]); _mapType(map, _t, tid); } } @@ -3745,7 +3749,7 @@ var jsPlumbInstance = root.jsPlumbInstance = function (_defaults) { - this.version = "2.8.3"; + this.version = "2.8.4"; this.Defaults = { Anchor: "Bottom", @@ -11986,9 +11990,9 @@ if (this._jsPlumb.div == null) { var div = this._jsPlumb.div = _jp.getElement(this._jsPlumb.create(this._jsPlumb.component)); div.style.position = "absolute"; - div.className = this._jsPlumb.instance.overlayClass + " " + + jsPlumb.addClass(div, this._jsPlumb.instance.overlayClass + " " + (this.cssClass ? this.cssClass : - params.cssClass ? params.cssClass : ""); + params.cssClass ? params.cssClass : "")); this._jsPlumb.instance.appendElement(div); this._jsPlumb.instance.getId(div); this.canvas = div; diff --git a/src/views/details/relation_map.ejs b/src/views/details/relation_map.ejs index 1c544f725..dd87f63ef 100644 --- a/src/views/details/relation_map.ejs +++ b/src/views/details/relation_map.ejs @@ -9,16 +9,14 @@