diff --git a/browser/main/global.styl b/browser/main/global.styl index 75ace0b3..815cff4e 100644 --- a/browser/main/global.styl +++ b/browser/main/global.styl @@ -132,6 +132,15 @@ body[data-theme="dark"] .CodeMirror-foldgutter-folded:after content: "\25B8" +.CodeMirror-hover + padding 2px 4px 0 4px + position absolute + z-index 99 + +.CodeMirror-hyperlink + cursor pointer + + .sortableItemHelper z-index modalZIndex + 5 diff --git a/extra_scripts/codemirror/addon/hyperlink/hyperlink.js b/extra_scripts/codemirror/addon/hyperlink/hyperlink.js new file mode 100755 index 00000000..3f548c51 --- /dev/null +++ b/extra_scripts/codemirror/addon/hyperlink/hyperlink.js @@ -0,0 +1,127 @@ +(function (mod) { + if (typeof exports === 'object' && typeof module === 'object') { // Common JS + mod(require('../codemirror/lib/codemirror')) + } else if (typeof define === 'function' && define.amd) { // AMD + define(['../codemirror/lib/codemirror'], mod) + } else { // Plain browser env + mod(CodeMirror) + } +})(function (CodeMirror) { + 'use strict' + + const shell = require('electron').shell + const yOffset = 2 + + const macOS = global.process.platform === 'darwin' + const modifier = macOS ? 'metaKey' : 'ctrlKey' + + class HyperLink { + constructor(cm) { + this.cm = cm + this.lineDiv = cm.display.lineDiv + + this.onMouseDown = this.onMouseDown.bind(this) + this.onMouseEnter = this.onMouseEnter.bind(this) + this.onMouseLeave = this.onMouseLeave.bind(this) + this.onMouseMove = this.onMouseMove.bind(this) + + this.tooltip = document.createElement('div') + this.tooltipContent = document.createElement('div') + this.tooltipIndicator = document.createElement('div') + this.tooltip.setAttribute('class', 'CodeMirror-hover CodeMirror-matchingbracket CodeMirror-selected') + this.tooltip.setAttribute('cm-ignore-events', 'true') + this.tooltip.appendChild(this.tooltipContent) + this.tooltip.appendChild(this.tooltipIndicator) + this.tooltipContent.textContent = `${macOS ? 'Cmd(⌘)' : 'Ctrl(^)'} + click to follow link` + + this.lineDiv.addEventListener('mousedown', this.onMouseDown) + this.lineDiv.addEventListener('mouseenter', this.onMouseEnter, { + capture: true, + passive: true + }) + this.lineDiv.addEventListener('mouseleave', this.onMouseLeave, { + capture: true, + passive: true + }) + this.lineDiv.addEventListener('mousemove', this.onMouseMove, { + passive: true + }) + } + getUrl(el) { + const className = el.className.split(' ') + + if (className.indexOf('cm-url') !== -1) { + const match = /^\((.*)\)|\[(.*)\]|(.*)$/.exec(el.textContent) + return match[1] || match[2] || match[3] + } + + return null + } + onMouseDown(e) { + const { target } = e + if (!e[modifier]) { + return + } + + const url = this.getUrl(target) + if (url) { + e.preventDefault() + + shell.openExternal(url) + } + } + onMouseEnter(e) { + const { target } = e + + const url = this.getUrl(target) + if (url) { + if (e[modifier]) { + target.classList.add('CodeMirror-activeline-background', 'CodeMirror-hyperlink') + } + else { + target.classList.add('CodeMirror-activeline-background') + } + + this.showInfo(target) + } + } + onMouseLeave(e) { + if (this.tooltip.parentElement === this.lineDiv) { + e.target.classList.remove('CodeMirror-activeline-background', 'CodeMirror-hyperlink') + + this.lineDiv.removeChild(this.tooltip) + } + } + onMouseMove(e) { + if (this.tooltip.parentElement === this.lineDiv) { + if (e[modifier]) { + e.target.classList.add('CodeMirror-hyperlink') + } + else { + e.target.classList.remove('CodeMirror-hyperlink') + } + } + } + showInfo(relatedTo) { + const b1 = relatedTo.getBoundingClientRect() + const b2 = this.lineDiv.getBoundingClientRect() + const tdiv = this.tooltip + + tdiv.style.left = (b1.left - b2.left) + 'px' + this.lineDiv.appendChild(tdiv) + + const b3 = tdiv.getBoundingClientRect() + const top = b1.top - b2.top - b3.height - yOffset + if (top < 0) { + tdiv.style.top = (b1.top - b2.top + b1.height + yOffset) + 'px' + } + else { + tdiv.style.top = top + 'px' + } + } + } + + CodeMirror.defineOption('hyperlink', true, (cm) => { + const addon = new HyperLink(cm) + }) +}) \ No newline at end of file diff --git a/lib/main.html b/lib/main.html index e03cac37..663c1d23 100644 --- a/lib/main.html +++ b/lib/main.html @@ -10,6 +10,7 @@ +