mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	middle click can now open links in new tab (and close tab)
This commit is contained in:
		
							
								
								
									
										2179
									
								
								libraries/jsplumb.js
									
									
									
									
									
								
							
							
						
						
									
										2179
									
								
								libraries/jsplumb.js
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -33,11 +33,11 @@ function createPanZoom(domElement, options) { | |||||||
|  |  | ||||||
|   if (!panController) { |   if (!panController) { | ||||||
|     if (domElement instanceof SVGElement) { |     if (domElement instanceof SVGElement) { | ||||||
|       panController = makeSvgController(domElement) |       panController = makeSvgController(domElement, options) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     if (domElement instanceof HTMLElement) { |     if (domElement instanceof HTMLElement) { | ||||||
|       panController = makeDomController(domElement) |       panController = makeDomController(domElement, options) | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -57,7 +57,8 @@ function createPanZoom(domElement, options) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   var filterKey = typeof options.filterKey === 'function' ? options.filterKey : noop; |   var filterKey = typeof options.filterKey === 'function' ? options.filterKey : noop; | ||||||
|   var realPinch = typeof options.realPinch === 'boolean' ? options.realPinch : false |   // TODO: likely need to unite pinchSpeed with zoomSpeed | ||||||
|  |   var pinchSpeed = typeof options.pinchSpeed === 'number' ? options.pinchSpeed : 1; | ||||||
|   var bounds = options.bounds |   var bounds = options.bounds | ||||||
|   var maxZoom = typeof options.maxZoom === 'number' ? options.maxZoom : Number.POSITIVE_INFINITY |   var maxZoom = typeof options.maxZoom === 'number' ? options.maxZoom : Number.POSITIVE_INFINITY | ||||||
|   var minZoom = typeof options.minZoom === 'number' ? options.minZoom : 0 |   var minZoom = typeof options.minZoom === 'number' ? options.minZoom : 0 | ||||||
| @@ -101,7 +102,7 @@ function createPanZoom(domElement, options) { | |||||||
|   var moveByAnimation |   var moveByAnimation | ||||||
|   var zoomToAnimation |   var zoomToAnimation | ||||||
|  |  | ||||||
|   var multitouch |   var multiTouch | ||||||
|   var paused = false |   var paused = false | ||||||
|  |  | ||||||
|   listenForEvents() |   listenForEvents() | ||||||
| @@ -144,7 +145,8 @@ function createPanZoom(domElement, options) { | |||||||
|  |  | ||||||
|   function showRectangle(rect) { |   function showRectangle(rect) { | ||||||
|     // TODO: this duplicates autocenter. I think autocenter should go. |     // TODO: this duplicates autocenter. I think autocenter should go. | ||||||
|     var size = transformToScreen(owner.clientWidth, owner.clientHeight) |     var clientRect = owner.getBoundingClientRect() | ||||||
|  |     var size = transformToScreen(clientRect.width, clientRect.height) | ||||||
|  |  | ||||||
|     var rectWidth = rect.right - rect.left |     var rectWidth = rect.right - rect.left | ||||||
|     var rectHeight = rect.bottom - rect.top |     var rectHeight = rect.bottom - rect.top | ||||||
| @@ -503,7 +505,7 @@ function createPanZoom(domElement, options) { | |||||||
|     } else if (e.touches.length === 2) { |     } else if (e.touches.length === 2) { | ||||||
|       // handleTouchMove() will care about pinch zoom. |       // handleTouchMove() will care about pinch zoom. | ||||||
|       pinchZoomLength = getPinchZoomLength(e.touches[0], e.touches[1]) |       pinchZoomLength = getPinchZoomLength(e.touches[0], e.touches[1]) | ||||||
|       multitouch  = true |       multiTouch  = true | ||||||
|       startTouchListenerIfNeeded() |       startTouchListenerIfNeeded() | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -568,25 +570,14 @@ function createPanZoom(domElement, options) { | |||||||
|       internalMoveBy(point.x, point.y) |       internalMoveBy(point.x, point.y) | ||||||
|     } else if (e.touches.length === 2) { |     } else if (e.touches.length === 2) { | ||||||
|       // it's a zoom, let's find direction |       // it's a zoom, let's find direction | ||||||
|       multitouch = true |       multiTouch = true | ||||||
|       var t1 = e.touches[0] |       var t1 = e.touches[0] | ||||||
|       var t2 = e.touches[1] |       var t2 = e.touches[1] | ||||||
|       var currentPinchLength = getPinchZoomLength(t1, t2) |       var currentPinchLength = getPinchZoomLength(t1, t2) | ||||||
|  |  | ||||||
|       var scaleMultiplier = 1 |       // since the zoom speed is always based on distance from 1, we need to apply | ||||||
|  |       // pinch speed only on that distance from 1: | ||||||
|       if (realPinch) { |       var scaleMultiplier = 1 + (currentPinchLength / pinchZoomLength - 1) * pinchSpeed | ||||||
|         scaleMultiplier = currentPinchLength / pinchZoomLength |  | ||||||
|       } else { |  | ||||||
|         var delta = 0 |  | ||||||
|         if (currentPinchLength < pinchZoomLength) { |  | ||||||
|           delta = 1 |  | ||||||
|         } else if (currentPinchLength > pinchZoomLength) { |  | ||||||
|           delta = -1 |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         scaleMultiplier = getScaleMultiplier(delta) |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|       mouseX = (t1.clientX + t2.clientX)/2 |       mouseX = (t1.clientX + t2.clientX)/2 | ||||||
|       mouseY = (t1.clientY + t2.clientY)/2 |       mouseY = (t1.clientY + t2.clientY)/2 | ||||||
| @@ -619,8 +610,9 @@ function createPanZoom(domElement, options) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   function getPinchZoomLength(finger1, finger2) { |   function getPinchZoomLength(finger1, finger2) { | ||||||
|     return Math.sqrt((finger1.clientX - finger2.clientX) * (finger1.clientX - finger2.clientX) + |     var dx = finger1.clientX - finger2.clientX | ||||||
|       (finger1.clientY - finger2.clientY) * (finger1.clientY - finger2.clientY)) |     var dy = finger1.clientY - finger2.clientY | ||||||
|  |     return Math.sqrt(dx * dx + dy * dy) | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   function onDoubleClick(e) { |   function onDoubleClick(e) { | ||||||
| @@ -630,12 +622,6 @@ function createPanZoom(domElement, options) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   function onMouseDown(e) { |   function onMouseDown(e) { | ||||||
|       if (options.onMouseDown && !options.onMouseDown(e)) { |  | ||||||
|           // if they return `false` from onTouch, we don't want to stop |  | ||||||
|           // events propagation. Fixes https://github.com/anvaka/panzoom/issues/46 |  | ||||||
|           return |  | ||||||
|       } |  | ||||||
|  |  | ||||||
|     if (touchInProgress) { |     if (touchInProgress) { | ||||||
|       // modern browsers will fire mousedown for touch events too |       // modern browsers will fire mousedown for touch events too | ||||||
|       // we do not want this: touch is handled separately. |       // we do not want this: touch is handled separately. | ||||||
| @@ -698,7 +684,7 @@ function createPanZoom(domElement, options) { | |||||||
|     document.removeEventListener('touchend', handleTouchEnd) |     document.removeEventListener('touchend', handleTouchEnd) | ||||||
|     document.removeEventListener('touchcancel', handleTouchEnd) |     document.removeEventListener('touchcancel', handleTouchEnd) | ||||||
|     panstartFired = false |     panstartFired = false | ||||||
|     multitouch = false |     multiTouch = false | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   function onMouseWheel(e) { |   function onMouseWheel(e) { | ||||||
| @@ -775,8 +761,8 @@ function createPanZoom(domElement, options) { | |||||||
|  |  | ||||||
|   function triggerPanEnd() { |   function triggerPanEnd() { | ||||||
|     if (panstartFired) { |     if (panstartFired) { | ||||||
|       // we should never run smooth scrolling if it was multitouch (pinch zoom animation): |       // we should never run smooth scrolling if it was multiTouch (pinch zoom animation): | ||||||
|       if (!multitouch) smoothScroll.stop() |       if (!multiTouch) smoothScroll.stop() | ||||||
|       triggerEvent('panend') |       triggerEvent('panend') | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @@ -828,11 +814,13 @@ function autoRun() { | |||||||
|   if (!scripts) return; |   if (!scripts) return; | ||||||
|   var panzoomScript; |   var panzoomScript; | ||||||
|  |  | ||||||
|   Array.from(scripts).forEach(function(x) { |   for (var i = 0; i < scripts.length; ++i) { | ||||||
|  |     var x = scripts[i]; | ||||||
|     if (x.src && x.src.match(/\bpanzoom(\.min)?\.js/)) { |     if (x.src && x.src.match(/\bpanzoom(\.min)?\.js/)) { | ||||||
|       panzoomScript = x |       panzoomScript = x | ||||||
|  |       break; | ||||||
|     } |     } | ||||||
|   }) |   } | ||||||
|  |  | ||||||
|   if (!panzoomScript) return; |   if (!panzoomScript) return; | ||||||
|  |  | ||||||
| @@ -894,7 +882,7 @@ autoRun(); | |||||||
| },{"./lib/domController.js":2,"./lib/kinetic.js":3,"./lib/svgController.js":4,"./lib/textSelectionInterceptor.js":5,"./lib/transform.js":6,"amator":7,"ngraph.events":9,"wheel":10}],2:[function(require,module,exports){ | },{"./lib/domController.js":2,"./lib/kinetic.js":3,"./lib/svgController.js":4,"./lib/textSelectionInterceptor.js":5,"./lib/transform.js":6,"amator":7,"ngraph.events":9,"wheel":10}],2:[function(require,module,exports){ | ||||||
| module.exports = makeDomController | module.exports = makeDomController | ||||||
|  |  | ||||||
| function makeDomController(domElement) { | function makeDomController(domElement, options) { | ||||||
|   var elementValid = (domElement instanceof HTMLElement) |   var elementValid = (domElement instanceof HTMLElement) | ||||||
|   if (!elementValid) { |   if (!elementValid) { | ||||||
|     throw new Error('svg element is required for svg.panzoom to work') |     throw new Error('svg element is required for svg.panzoom to work') | ||||||
| @@ -908,7 +896,10 @@ function makeDomController(domElement) { | |||||||
|   } |   } | ||||||
|  |  | ||||||
|   domElement.scrollTop = 0; |   domElement.scrollTop = 0; | ||||||
|   owner.setAttribute('tabindex', 1); // TODO: not sure if this is really polite |    | ||||||
|  |   if (!options.disableKeyboardInteraction) { | ||||||
|  |     owner.setAttribute('tabindex', 0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   var api = { |   var api = { | ||||||
|     getBBox: getBBox, |     getBBox: getBBox, | ||||||
| @@ -1067,7 +1058,7 @@ function kinetic(getPoint, scroll, settings) { | |||||||
| },{}],4:[function(require,module,exports){ | },{}],4:[function(require,module,exports){ | ||||||
| module.exports = makeSvgController | module.exports = makeSvgController | ||||||
|  |  | ||||||
| function makeSvgController(svgElement) { | function makeSvgController(svgElement, options) { | ||||||
|   var elementValid = (svgElement instanceof SVGElement) |   var elementValid = (svgElement instanceof SVGElement) | ||||||
|   if (!elementValid) { |   if (!elementValid) { | ||||||
|     throw new Error('svg element is required for svg.panzoom to work') |     throw new Error('svg element is required for svg.panzoom to work') | ||||||
| @@ -1081,7 +1072,9 @@ function makeSvgController(svgElement) { | |||||||
|       'As of March 2016 only FireFox supported transform on the root element') |       'As of March 2016 only FireFox supported transform on the root element') | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   owner.setAttribute('tabindex', 1); // TODO: not sure if this is really polite |   if (!options.disableKeyboardInteraction) { | ||||||
|  |     owner.setAttribute('tabindex', 0); | ||||||
|  |   } | ||||||
|  |  | ||||||
|   var api = { |   var api = { | ||||||
|     getBBox: getBBox, |     getBBox: getBBox, | ||||||
| @@ -1315,7 +1308,7 @@ function makeAggregateRaf() { | |||||||
|  |  | ||||||
|     var t = backBuffer; |     var t = backBuffer; | ||||||
|     backBuffer = frontBuffer; |     backBuffer = frontBuffer; | ||||||
|     frontBuffer = t; |     frontBuffer = t; | ||||||
|  |  | ||||||
|     frontBuffer.forEach(function(callback) { |     frontBuffer.forEach(function(callback) { | ||||||
|       callback(); |       callback(); | ||||||
| @@ -1578,7 +1571,7 @@ function removeWheelListener( elem, callback, useCapture ) { | |||||||
|   // unsubscription in some browsers. But in practice, I don't think we should |   // unsubscription in some browsers. But in practice, I don't think we should | ||||||
|   // worry too much about it (those browsers are on the way out) |   // worry too much about it (those browsers are on the way out) | ||||||
| function _addWheelListener( elem, eventName, callback, useCapture ) { | function _addWheelListener( elem, eventName, callback, useCapture ) { | ||||||
|   elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function( originalEvent ) { |   elem[ _addEventListener ]( prefix + eventName, support == "wheel" ? callback : function(originalEvent ) { | ||||||
|     !originalEvent && ( originalEvent = window.event ); |     !originalEvent && ( originalEvent = window.event ); | ||||||
|  |  | ||||||
|     // create a normalized event object |     // create a normalized event object | ||||||
| @@ -1620,7 +1613,10 @@ function _addWheelListener( elem, eventName, callback, useCapture ) { | |||||||
|     // it's time to fire the callback |     // it's time to fire the callback | ||||||
|     return callback( event ); |     return callback( event ); | ||||||
|  |  | ||||||
|   }, useCapture || false ); |   }, { | ||||||
|  |     capture: useCapture || false , | ||||||
|  |     passive: false | ||||||
|  |   }); | ||||||
| } | } | ||||||
|  |  | ||||||
| function _removeWheelListener( elem, eventName, callback, useCapture ) { | function _removeWheelListener( elem, eventName, callback, useCapture ) { | ||||||
|   | |||||||
| @@ -43,18 +43,19 @@ function getNotePathFromLink($link) { | |||||||
| } | } | ||||||
|  |  | ||||||
| function goToLink(e) { | function goToLink(e) { | ||||||
|     e.preventDefault(); |  | ||||||
|  |  | ||||||
|     const $link = $(e.target); |     const $link = $(e.target); | ||||||
|  |  | ||||||
|     const notePath = getNotePathFromLink($link); |     const notePath = getNotePathFromLink($link); | ||||||
|  |  | ||||||
|     if (notePath) { |     if (notePath) { | ||||||
|         if (e.ctrlKey) { |         if ((e.which === 1 && e.ctrlKey) || e.which === 2) { | ||||||
|             noteDetailService.loadNoteDetail(notePath.split("/").pop(), { newTab: true }); |             noteDetailService.openInTab(notePath); | ||||||
|  |         } | ||||||
|  |         else if (e.which === 1) { | ||||||
|  |             treeService.activateNote(notePath); | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             treeService.activateNote(notePath); |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
| @@ -64,6 +65,11 @@ function goToLink(e) { | |||||||
|             window.open(address, '_blank'); |             window.open(address, '_blank'); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     e.preventDefault(); | ||||||
|  |     e.stopPropagation(); | ||||||
|  |  | ||||||
|  |     return true; | ||||||
| } | } | ||||||
|  |  | ||||||
| function addLinkToEditor(linkTitle, linkHref) { | function addLinkToEditor(linkTitle, linkHref) { | ||||||
| @@ -129,22 +135,24 @@ $(document).on('contextmenu', ".note-detail-render a", tabContextMenu); | |||||||
|  |  | ||||||
| // when click on link popup, in case of internal link, just go the the referenced note instead of default behavior | // when click on link popup, in case of internal link, just go the the referenced note instead of default behavior | ||||||
| // of opening the link in new window/tab | // of opening the link in new window/tab | ||||||
| $(document).on('click', "a[data-action='note']", goToLink); | $(document).on('mousedown', "a[data-action='note']", goToLink); | ||||||
| $(document).on('click', 'div.popover-content a, div.ui-tooltip-content a', goToLink); | $(document).on('mousedown', 'div.popover-content a, div.ui-tooltip-content a', goToLink); | ||||||
| $(document).on('dblclick', '.note-detail-text a', goToLink); | $(document).on('dblclick', '.note-detail-text a', goToLink); | ||||||
| $(document).on('click', '.note-detail-text a', function (e) { | $(document).on('mousedown', '.note-detail-text a', function (e) { | ||||||
|     const notePath = getNotePathFromLink($(e.target)); |     const notePath = getNotePathFromLink($(e.target)); | ||||||
|     if (notePath && e.ctrlKey) { |     if (notePath && ((e.which === 1 && e.ctrlKey) || e.which === 2)) { | ||||||
|         // if it's a ctrl-click, then we open on new tab, otherwise normal flow (CKEditor opens link-editing dialog) |         // if it's a ctrl-click, then we open on new tab, otherwise normal flow (CKEditor opens link-editing dialog) | ||||||
|         e.preventDefault(); |         e.preventDefault(); | ||||||
|  |  | ||||||
|         noteDetailService.loadNoteDetail(notePath.split("/").pop(), { newTab: true }); |         noteDetailService.loadNoteDetail(notePath, { newTab: true }); | ||||||
|  |  | ||||||
|  |         return true; | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| $(document).on('click', '.note-detail-render a', goToLink); | $(document).on('mousedown', '.note-detail-render a', goToLink); | ||||||
| $(document).on('click', '.note-detail-text.ck-read-only a', goToLink); | $(document).on('mousedown', '.note-detail-text.ck-read-only a', goToLink); | ||||||
| $(document).on('click', 'span.ck-button__label', e => { | $(document).on('mousedown', 'span.ck-button__label', e => { | ||||||
|     // this is a link preview dialog from CKEditor link editing |     // this is a link preview dialog from CKEditor link editing | ||||||
|     // for some reason clicked element is span |     // for some reason clicked element is span | ||||||
|  |  | ||||||
| @@ -163,5 +171,6 @@ export default { | |||||||
|     createNoteLink, |     createNoteLink, | ||||||
|     addLinkToEditor, |     addLinkToEditor, | ||||||
|     addTextToEditor, |     addTextToEditor, | ||||||
|     init |     init, | ||||||
|  |     goToLink | ||||||
| }; | }; | ||||||
| @@ -46,7 +46,8 @@ function initNoteAutocomplete($el, options) { | |||||||
|                 .prop("title", "Show recent notes"); |                 .prop("title", "Show recent notes"); | ||||||
|  |  | ||||||
|         const $goToSelectedNoteButton = $("<a>") |         const $goToSelectedNoteButton = $("<a>") | ||||||
|             .addClass("input-group-text go-to-selected-note-button jam jam-arrow-right"); |             .addClass("input-group-text go-to-selected-note-button jam jam-arrow-right") | ||||||
|  |             .attr("data-action", "note"); | ||||||
|  |  | ||||||
|         const $sideButtons = $("<div>") |         const $sideButtons = $("<div>") | ||||||
|             .addClass("input-group-append") |             .addClass("input-group-append") | ||||||
| @@ -69,14 +70,6 @@ function initNoteAutocomplete($el, options) { | |||||||
|             return false; |             return false; | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         $goToSelectedNoteButton.click(() => { |  | ||||||
|             if ($el.hasClass("disabled")) { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             treeService.activateNote($el.getSelectedPath()); |  | ||||||
|         }); |  | ||||||
|  |  | ||||||
|         $el.autocomplete({ |         $el.autocomplete({ | ||||||
|             appendTo: document.querySelector('body'), |             appendTo: document.querySelector('body'), | ||||||
|             hint: false, |             hint: false, | ||||||
|   | |||||||
| @@ -372,11 +372,14 @@ $(tabRow.el).on('contextmenu', '.note-tab', e => { | |||||||
|     contextMenuService.initContextMenu(e, { |     contextMenuService.initContextMenu(e, { | ||||||
|         getContextMenuItems: () => { |         getContextMenuItems: () => { | ||||||
|             return [ |             return [ | ||||||
|  |                 {title: "Close all tabs", cmd: "removeAllTabs", uiIcon: "empty"}, | ||||||
|                 {title: "Close all tabs except for this", cmd: "removeAllTabsExceptForThis", uiIcon: "empty"} |                 {title: "Close all tabs except for this", cmd: "removeAllTabsExceptForThis", uiIcon: "empty"} | ||||||
|             ]; |             ]; | ||||||
|         }, |         }, | ||||||
|         selectContextMenuItem: (e, cmd) => { |         selectContextMenuItem: (e, cmd) => { | ||||||
|             if (cmd === 'removeAllTabsExceptForThis') { |             if (cmd === 'removeAllTabs') { | ||||||
|  |                 tabRow.removeAllTabs(); | ||||||
|  |             } else if (cmd === 'removeAllTabsExceptForThis') { | ||||||
|                 tabRow.removeAllTabsExceptForThis(tab[0]); |                 tabRow.removeAllTabsExceptForThis(tab[0]); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -90,6 +90,7 @@ class NoteDetailRelationMap { | |||||||
|             contextMenuWidget.initContextMenu(e, { |             contextMenuWidget.initContextMenu(e, { | ||||||
|                 getContextMenuItems: () => { |                 getContextMenuItems: () => { | ||||||
|                     return [ |                     return [ | ||||||
|  |                         {title: "Open in new tab", cmd: "open-in-new-tab", uiIcon: "empty"}, | ||||||
|                         {title: "Remove note", cmd: "remove", uiIcon: "trash"}, |                         {title: "Remove note", cmd: "remove", uiIcon: "trash"}, | ||||||
|                         {title: "Edit title", cmd: "edit-title", uiIcon: "pencil"}, |                         {title: "Edit title", cmd: "edit-title", uiIcon: "pencil"}, | ||||||
|                     ]; |                     ]; | ||||||
| @@ -125,7 +126,7 @@ class NoteDetailRelationMap { | |||||||
|  |  | ||||||
|         this.$resetPanZoomButton.click(() => { |         this.$resetPanZoomButton.click(() => { | ||||||
|             // reset to initial pan & zoom state |             // reset to initial pan & zoom state | ||||||
|             this.pzInstance.zoomTo(0, 0, 1 / getZoom()); |             this.pzInstance.zoomTo(0, 0, 1 / this.getZoom()); | ||||||
|             this.pzInstance.moveTo(0, 0); |             this.pzInstance.moveTo(0, 0); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -138,7 +139,10 @@ class NoteDetailRelationMap { | |||||||
|         const $title = $noteBox.find(".title a"); |         const $title = $noteBox.find(".title a"); | ||||||
|         const noteId = this.idToNoteId($noteBox.prop("id")); |         const noteId = this.idToNoteId($noteBox.prop("id")); | ||||||
|  |  | ||||||
|         if (cmd === "remove") { |         if (cmd === "open-in-new-tab") { | ||||||
|  |             noteDetailService.openInTab(noteId); | ||||||
|  |         } | ||||||
|  |         else if (cmd === "remove") { | ||||||
|             if (!await confirmDialog.confirmDeleteNoteBoxWithNote($title.text())) { |             if (!await confirmDialog.confirmDeleteNoteBoxWithNote($title.text())) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @@ -310,7 +314,7 @@ class NoteDetailRelationMap { | |||||||
|             maxZoom: 2, |             maxZoom: 2, | ||||||
|             minZoom: 0.3, |             minZoom: 0.3, | ||||||
|             smoothScroll: false, |             smoothScroll: false, | ||||||
|             onMouseDown: function(event) { |             onMouseDown: event => { | ||||||
|                 if (this.clipboard) { |                 if (this.clipboard) { | ||||||
|                     let {x, y} = this.getMousePosition(event); |                     let {x, y} = this.getMousePosition(event); | ||||||
|  |  | ||||||
| @@ -402,9 +406,6 @@ class NoteDetailRelationMap { | |||||||
|         this.jsPlumbInstance.registerConnectionType("link", { anchor:"Continuous", connector:"StateMachine", overlays: linkOverlays }); |         this.jsPlumbInstance.registerConnectionType("link", { anchor:"Continuous", connector:"StateMachine", overlays: linkOverlays }); | ||||||
|  |  | ||||||
|         this.jsPlumbInstance.bind("connection", (info, originalEvent) => this.connectionCreatedHandler(info, originalEvent)); |         this.jsPlumbInstance.bind("connection", (info, originalEvent) => this.connectionCreatedHandler(info, originalEvent)); | ||||||
|  |  | ||||||
|         // so that canvas is not panned when clicking/dragging note box |  | ||||||
|         this.$relationMapContainer.on('mousedown touchstart', '.note-box, .connection-label', e => e.stopPropagation()); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     async connectionCreatedHandler(info, originalEvent) { |     async connectionCreatedHandler(info, originalEvent) { | ||||||
| @@ -490,10 +491,17 @@ class NoteDetailRelationMap { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     async createNoteBox(noteId, title, x, y) { |     async createNoteBox(noteId, title, x, y) { | ||||||
|  |         const $link = await linkService.createNoteLink(noteId, title); | ||||||
|  |         $link.mousedown(e => { | ||||||
|  |             console.log(e); | ||||||
|  |  | ||||||
|  |             linkService.goToLink(e); | ||||||
|  |         }); | ||||||
|  |  | ||||||
|         const $noteBox = $("<div>") |         const $noteBox = $("<div>") | ||||||
|             .addClass("note-box") |             .addClass("note-box") | ||||||
|             .prop("id", this.noteIdToId(noteId)) |             .prop("id", this.noteIdToId(noteId)) | ||||||
|             .append($("<span>").addClass("title").html(await linkService.createNoteLink(noteId, title))) |             .append($("<span>").addClass("title").append($link)) | ||||||
|             .append($("<div>").addClass("endpoint").attr("title", "Start dragging relations from here and drop them on another note.")) |             .append($("<div>").addClass("endpoint").attr("title", "Start dragging relations from here and drop them on another note.")) | ||||||
|             .css("left", x + "px") |             .css("left", x + "px") | ||||||
|             .css("top", y + "px"); |             .css("top", y + "px"); | ||||||
|   | |||||||
| @@ -177,6 +177,14 @@ class TabRow { | |||||||
|  |  | ||||||
|     setTabCloseEventListener(tabEl) { |     setTabCloseEventListener(tabEl) { | ||||||
|         tabEl.querySelector('.note-tab-close').addEventListener('click', _ => this.removeTab(tabEl)); |         tabEl.querySelector('.note-tab-close').addEventListener('click', _ => this.removeTab(tabEl)); | ||||||
|  |  | ||||||
|  |         tabEl.addEventListener('mousedown', e => { | ||||||
|  |             if (e.which === 2) { | ||||||
|  |                 this.removeTab(tabEl); | ||||||
|  |  | ||||||
|  |                 return true; // event has been handled | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     get activeTabEl() { |     get activeTabEl() { | ||||||
| @@ -251,6 +259,12 @@ class TabRow { | |||||||
|         this.setVisibility(); |         this.setVisibility(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     async removeAllTabs() { | ||||||
|  |         for (const tabEl of this.tabEls) { | ||||||
|  |             await this.removeTab(tabEl); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     async removeAllTabsExceptForThis(remainingTabEl) { |     async removeAllTabsExceptForThis(remainingTabEl) { | ||||||
|         for (const tabEl of this.tabEls) { |         for (const tabEl of this.tabEls) { | ||||||
|             if (remainingTabEl !== tabEl) { |             if (remainingTabEl !== tabEl) { | ||||||
|   | |||||||
| @@ -852,6 +852,22 @@ $(window).bind('hashchange', async function() { | |||||||
|     } |     } | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | // fancytree doesn't support middle click so this is a way to support it | ||||||
|  | $tree.on('mousedown', '.fancytree-title', e => { | ||||||
|  |     if (e.which === 2) { | ||||||
|  |         const node = $.ui.fancytree.getNode(e); | ||||||
|  |  | ||||||
|  |         treeUtils.getNotePath(node).then(notePath => { | ||||||
|  |             if (notePath) { | ||||||
|  |                 noteDetailService.openInTab(notePath); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |  | ||||||
|  |         e.stopPropagation(); | ||||||
|  |         e.preventDefault(); | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  |  | ||||||
| utils.bindShortcut('alt+c', () => collapseTree()); // don't use shortened form since collapseTree() accepts argument | utils.bindShortcut('alt+c', () => collapseTree()); // don't use shortened form since collapseTree() accepts argument | ||||||
| $collapseTreeButton.click(() => collapseTree()); | $collapseTreeButton.click(() => collapseTree()); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -93,6 +93,7 @@ body { | |||||||
|  |  | ||||||
| #context-menu-container, #context-menu-container .dropdown-menu { | #context-menu-container, #context-menu-container .dropdown-menu { | ||||||
|     padding: 3px 0 0; |     padding: 3px 0 0; | ||||||
|  |     z-index: 1111; | ||||||
| } | } | ||||||
|  |  | ||||||
| #context-menu-container .dropdown-item { | #context-menu-container .dropdown-item { | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| #note-detail-relation-map { | .note-detail-relation-map { | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     overflow: hidden !important; |     overflow: hidden !important; | ||||||
| } | } | ||||||
|  |  | ||||||
| #relation-map-wrapper { | .relation-map-wrapper { | ||||||
|     position: relative; |     position: relative; | ||||||
|     height: 100%; |     height: 100%; | ||||||
|     outline: none; /* remove dotted outline on click */ |     outline: none; /* remove dotted outline on click */ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user