Skip to content

Commit 80af8dc

Browse files
authored
Merge pull request #2382 from daiyam/link-clickable
Links are clickable
2 parents 62b2856 + a6a1291 commit 80af8dc

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

browser/main/global.styl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ body[data-theme="dark"]
132132
.CodeMirror-foldgutter-folded:after
133133
content: "\25B8"
134134

135+
.CodeMirror-hover
136+
padding 2px 4px 0 4px
137+
position absolute
138+
z-index 99
139+
140+
.CodeMirror-hyperlink
141+
cursor pointer
142+
143+
135144
.sortableItemHelper
136145
z-index modalZIndex + 5
137146

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
(function (mod) {
2+
if (typeof exports === 'object' && typeof module === 'object') { // Common JS
3+
mod(require('../codemirror/lib/codemirror'))
4+
} else if (typeof define === 'function' && define.amd) { // AMD
5+
define(['../codemirror/lib/codemirror'], mod)
6+
} else { // Plain browser env
7+
mod(CodeMirror)
8+
}
9+
})(function (CodeMirror) {
10+
'use strict'
11+
12+
const shell = require('electron').shell
13+
const yOffset = 2
14+
15+
const macOS = global.process.platform === 'darwin'
16+
const modifier = macOS ? 'metaKey' : 'ctrlKey'
17+
18+
class HyperLink {
19+
constructor(cm) {
20+
this.cm = cm
21+
this.lineDiv = cm.display.lineDiv
22+
23+
this.onMouseDown = this.onMouseDown.bind(this)
24+
this.onMouseEnter = this.onMouseEnter.bind(this)
25+
this.onMouseLeave = this.onMouseLeave.bind(this)
26+
this.onMouseMove = this.onMouseMove.bind(this)
27+
28+
this.tooltip = document.createElement('div')
29+
this.tooltipContent = document.createElement('div')
30+
this.tooltipIndicator = document.createElement('div')
31+
this.tooltip.setAttribute('class', 'CodeMirror-hover CodeMirror-matchingbracket CodeMirror-selected')
32+
this.tooltip.setAttribute('cm-ignore-events', 'true')
33+
this.tooltip.appendChild(this.tooltipContent)
34+
this.tooltip.appendChild(this.tooltipIndicator)
35+
this.tooltipContent.textContent = `${macOS ? 'Cmd(⌘)' : 'Ctrl(^)'} + click to follow link`
36+
37+
this.lineDiv.addEventListener('mousedown', this.onMouseDown)
38+
this.lineDiv.addEventListener('mouseenter', this.onMouseEnter, {
39+
capture: true,
40+
passive: true
41+
})
42+
this.lineDiv.addEventListener('mouseleave', this.onMouseLeave, {
43+
capture: true,
44+
passive: true
45+
})
46+
this.lineDiv.addEventListener('mousemove', this.onMouseMove, {
47+
passive: true
48+
})
49+
}
50+
getUrl(el) {
51+
const className = el.className.split(' ')
52+
53+
if (className.indexOf('cm-url') !== -1) {
54+
const match = /^\((.*)\)|\[(.*)\]|(.*)$/.exec(el.textContent)
55+
return match[1] || match[2] || match[3]
56+
}
57+
58+
return null
59+
}
60+
onMouseDown(e) {
61+
const { target } = e
62+
if (!e[modifier]) {
63+
return
64+
}
65+
66+
const url = this.getUrl(target)
67+
if (url) {
68+
e.preventDefault()
69+
70+
shell.openExternal(url)
71+
}
72+
}
73+
onMouseEnter(e) {
74+
const { target } = e
75+
76+
const url = this.getUrl(target)
77+
if (url) {
78+
if (e[modifier]) {
79+
target.classList.add('CodeMirror-activeline-background', 'CodeMirror-hyperlink')
80+
}
81+
else {
82+
target.classList.add('CodeMirror-activeline-background')
83+
}
84+
85+
this.showInfo(target)
86+
}
87+
}
88+
onMouseLeave(e) {
89+
if (this.tooltip.parentElement === this.lineDiv) {
90+
e.target.classList.remove('CodeMirror-activeline-background', 'CodeMirror-hyperlink')
91+
92+
this.lineDiv.removeChild(this.tooltip)
93+
}
94+
}
95+
onMouseMove(e) {
96+
if (this.tooltip.parentElement === this.lineDiv) {
97+
if (e[modifier]) {
98+
e.target.classList.add('CodeMirror-hyperlink')
99+
}
100+
else {
101+
e.target.classList.remove('CodeMirror-hyperlink')
102+
}
103+
}
104+
}
105+
showInfo(relatedTo) {
106+
const b1 = relatedTo.getBoundingClientRect()
107+
const b2 = this.lineDiv.getBoundingClientRect()
108+
const tdiv = this.tooltip
109+
110+
tdiv.style.left = (b1.left - b2.left) + 'px'
111+
this.lineDiv.appendChild(tdiv)
112+
113+
const b3 = tdiv.getBoundingClientRect()
114+
const top = b1.top - b2.top - b3.height - yOffset
115+
if (top < 0) {
116+
tdiv.style.top = (b1.top - b2.top + b1.height + yOffset) + 'px'
117+
}
118+
else {
119+
tdiv.style.top = top + 'px'
120+
}
121+
}
122+
}
123+
124+
CodeMirror.defineOption('hyperlink', true, (cm) => {
125+
const addon = new HyperLink(cm)
126+
})
127+
})

lib/main.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<link rel="stylesheet" href="../node_modules/codemirror/lib/codemirror.css">
1111
<link rel="stylesheet" href="../node_modules/katex/dist/katex.min.css">
1212
<link rel="stylesheet" href="../node_modules/codemirror/addon/dialog/dialog.css">
13+
1314
<title>Boostnote</title>
1415

1516
<style>
@@ -95,6 +96,7 @@
9596
<script src="../node_modules/codemirror/addon/runmode/runmode.js"></script>
9697

9798
<script src="../extra_scripts/boost/boostNewLineIndentContinueMarkdownList.js"></script>
99+
<script src="../extra_scripts/codemirror/addon/hyperlink/hyperlink.js"></script>
98100

99101
<script src="../node_modules/codemirror/addon/edit/closebrackets.js"></script>
100102
<script src="../node_modules/codemirror/addon/edit/matchbrackets.js"></script>

0 commit comments

Comments
 (0)