Skip to content
Merged
16 changes: 11 additions & 5 deletions browser/components/MarkdownPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -895,6 +895,12 @@ export default class MarkdownPreview extends React.Component {
this.setImgOnClickEventHelper(img, rect)
imgObserver.observe(parentEl, config)
}

const aList = markdownPreviewIframe.contentWindow.document.body.querySelectorAll('a')
for (const a of aList) {
a.removeEventListener('click', this.linkClickHandler)
a.addEventListener('click', this.linkClickHandler)
}
}

setImgOnClickEventHelper (img, rect) {
Expand Down Expand Up @@ -1023,11 +1029,11 @@ export default class MarkdownPreview extends React.Component {

if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()

const regexNoteInternalLink = /.*[main.\w]*.html#/

if (regexNoteInternalLink.test(href)) {
const targetId = mdurl.encode(linkHash)
const targetElement = this.refs.root.contentWindow.document.querySelector(
const extractId = /(main.html)?#/
const regexNoteInternalLink = new RegExp(`${extractId.source}(.+)`)
if (regexNoteInternalLink.test(linkHash)) {
const targetId = mdurl.encode(linkHash.replace(extractId, ''))
const targetElement = this.refs.root.contentWindow.document.getElementById(
targetId
)

Expand Down
2 changes: 1 addition & 1 deletion browser/lib/markdown-toc-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function uniqueSlug (slug, slugs, opts) {
}

function linkify (token) {
token.content = mdlink(token.content, '#' + token.slug)
token.content = mdlink(token.content, `#${decodeURI(token.slug)}`)
return token
}

Expand Down
24 changes: 9 additions & 15 deletions browser/lib/slugify.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import diacritics from 'diacritics-map'

function replaceDiacritics (str) {
return str.replace(/[Γ€-ΕΎ]/g, function (ch) {
return diacritics[ch] || ch
})
}

module.exports = function slugify (title) {
let slug = title.trim()

slug = replaceDiacritics(slug)

slug = slug.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-')

return encodeURI(slug).replace(/\-+$/, '')
const slug = encodeURI(
title.trim()
.replace(/^\s+/, '')
.replace(/\s+$/, '')
.replace(/\s+/g, '-')
.replace(/[\]\[\!\'\#\$\%\&\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\{\|\}\~\`]/g, '')
)

return slug
}
58 changes: 58 additions & 0 deletions tests/lib/slugify-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import test from 'ava'
import slugify from 'browser/lib/slugify'

test('alphabet and digit', t => {
const upperAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
const lowerAlphabet = 'abcdefghijklmnopqrstuvwxyz'
const digit = '0123456789'
const testCase = upperAlphabet + lowerAlphabet + digit
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === testCase)
})

test('should delete unavailable symbols', t => {
const availableSymbols = '_-'
const testCase = availableSymbols + '][!\'#$%&()*+,./:;<=>?@\\^{|}~`'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === availableSymbols)
})

test('should convert from white spaces between words to hyphens', t => {
const testCase = 'This is one'
const expectedString = 'This-is-one'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === expectedString)
})

test('should remove leading white spaces', t => {
const testCase = ' This is one'
const expectedString = 'This-is-one'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === expectedString)
})

test('should remove trailing white spaces', t => {
const testCase = 'This is one '
const expectedString = 'This-is-one'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === expectedString)
})

test('2-byte charactor support', t => {
const testCase = 'θ θθŠ’ζžœγƒ†γ‚ΉγƒˆΓ€ΕΎΖΖ΅'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === testCase)
})

test('emoji', t => {
const testCase = '🌸'
const decodeSlug = decodeURI(slugify(testCase))

t.true(decodeSlug === testCase)
})