Skip to content

Commit 9f932a0

Browse files
authored
Merge pull request #3002 from AWolf81/feature-tag-links
Add tag link handling with :tag:#tag syntax
2 parents 71f05b9 + 2b4e263 commit 9f932a0

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

browser/components/MarkdownPreview.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import PropTypes from 'prop-types'
22
import React from 'react'
3+
import { connect } from 'react-redux'
34
import Markdown from 'browser/lib/markdown'
45
import _ from 'lodash'
56
import CodeMirror from 'codemirror'
@@ -21,6 +22,7 @@ import { escapeHtmlCharacters } from 'browser/lib/utils'
2122
import yaml from 'js-yaml'
2223
import { render } from 'react-dom'
2324
import Carousel from 'react-image-carousel'
25+
import { push } from 'connected-react-router'
2426
import ConfigManager from '../main/lib/ConfigManager'
2527
import uiThemes from 'browser/lib/ui-themes'
2628
import i18n from 'browser/lib/i18n'
@@ -252,7 +254,7 @@ function getSourceLineNumberByElement(element) {
252254
return parent.dataset.line !== undefined ? parseInt(parent.dataset.line) : -1
253255
}
254256

255-
export default class MarkdownPreview extends React.Component {
257+
class MarkdownPreview extends React.Component {
256258
constructor(props) {
257259
super(props)
258260

@@ -1116,13 +1118,16 @@ export default class MarkdownPreview extends React.Component {
11161118
e.stopPropagation()
11171119

11181120
const rawHref = e.target.getAttribute('href')
1121+
const { dispatch } = this.props
11191122
if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()
11201123

11211124
const parser = document.createElement('a')
11221125
parser.href = rawHref
11231126
const isStartWithHash = rawHref[0] === '#'
11241127
const { href, hash } = parser
11251128

1129+
if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()
1130+
11261131
const linkHash = hash === '' ? rawHref : hash // needed because we're having special link formats that are removed by parser e.g. :line:10
11271132

11281133
const extractIdRegex = /file:\/\/.*main.?\w*.html#/ // file://path/to/main(.development.)html
@@ -1169,6 +1174,13 @@ export default class MarkdownPreview extends React.Component {
11691174
return
11701175
}
11711176

1177+
const regexIsTagLink = /^:tag:([\w]+)$/
1178+
if (regexIsTagLink.test(rawHref)) {
1179+
const tag = rawHref.match(regexIsTagLink)[1]
1180+
dispatch(push(`/tags/${encodeURIComponent(tag)}`))
1181+
return
1182+
}
1183+
11721184
// other case
11731185
this.openExternal(href)
11741186
}
@@ -1213,3 +1225,5 @@ MarkdownPreview.propTypes = {
12131225
smartArrows: PropTypes.bool,
12141226
breaks: PropTypes.bool
12151227
}
1228+
1229+
export default connect()(MarkdownPreview)

extra_scripts/codemirror/addon/hyperlink/hyperlink.js

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
const modifier = macOS ? 'metaKey' : 'ctrlKey'
1717

1818
class HyperLink {
19-
constructor(cm) {
19+
constructor (cm) {
2020
this.cm = cm
2121
this.lineDiv = cm.display.lineDiv
2222

@@ -47,7 +47,7 @@
4747
passive: true
4848
})
4949
}
50-
getUrl(el) {
50+
getUrl (el) {
5151
const className = el.className.split(' ')
5252

5353
if (className.indexOf('cm-url') !== -1) {
@@ -60,7 +60,7 @@
6060

6161
return null
6262
}
63-
onMouseDown(e) {
63+
onMouseDown (e) {
6464
const { target } = e
6565
if (!e[modifier]) {
6666
return
@@ -73,39 +73,37 @@
7373
shell.openExternal(url)
7474
}
7575
}
76-
onMouseEnter(e) {
76+
onMouseEnter (e) {
7777
const { target } = e
7878

7979
const url = this.getUrl(target)
8080
if (url) {
8181
if (e[modifier]) {
8282
target.classList.add('CodeMirror-activeline-background', 'CodeMirror-hyperlink')
83-
}
84-
else {
83+
} else {
8584
target.classList.add('CodeMirror-activeline-background')
8685
}
8786

8887
this.showInfo(target)
8988
}
9089
}
91-
onMouseLeave(e) {
90+
onMouseLeave (e) {
9291
if (this.tooltip.parentElement === this.lineDiv) {
9392
e.target.classList.remove('CodeMirror-activeline-background', 'CodeMirror-hyperlink')
9493

9594
this.lineDiv.removeChild(this.tooltip)
9695
}
9796
}
98-
onMouseMove(e) {
97+
onMouseMove (e) {
9998
if (this.tooltip.parentElement === this.lineDiv) {
10099
if (e[modifier]) {
101100
e.target.classList.add('CodeMirror-hyperlink')
102-
}
103-
else {
101+
} else {
104102
e.target.classList.remove('CodeMirror-hyperlink')
105103
}
106104
}
107105
}
108-
showInfo(relatedTo) {
106+
showInfo (relatedTo) {
109107
const b1 = relatedTo.getBoundingClientRect()
110108
const b2 = this.lineDiv.getBoundingClientRect()
111109
const tdiv = this.tooltip
@@ -117,8 +115,7 @@
117115
const top = b1.top - b2.top - b3.height - yOffset
118116
if (top < 0) {
119117
tdiv.style.top = (b1.top - b2.top + b1.height + yOffset) + 'px'
120-
}
121-
else {
118+
} else {
122119
tdiv.style.top = top + 'px'
123120
}
124121
}
@@ -127,4 +124,4 @@
127124
CodeMirror.defineOption('hyperlink', true, (cm) => {
128125
const addon = new HyperLink(cm)
129126
})
130-
})
127+
})

0 commit comments

Comments
 (0)