mirror of
https://github.com/BoostIo/Boostnote
synced 2025-12-12 17:26:17 +00:00
Fixes that TOC hasn't id attribute when the title is all 2-byte characters (#2994)
* Fix: 2-byte character support of slug * Fix: Decodes slug to display slug * Fix: Removed a logic of replaceDiacritics * Fix: Fixed slugify to pass tests * Fix: Fixed not to remove underscore * Adds the test for slugify.js * Fix: Fix to jump to heading * Added a comment * Fix: Created click event only linking to heading * Fix: Fix to use handleLinkClick(e) * Fix: Changed the regex rule * Fix: Changed the regex rule of extractId
This commit is contained in:
@@ -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) {
|
||||
@@ -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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
const slug = encodeURI(
|
||||
title.trim()
|
||||
.replace(/^\s+/, '')
|
||||
.replace(/\s+$/, '')
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[\]\[\!\'\#\$\%\&\(\)\*\+\,\.\/\:\;\<\=\>\?\@\\\^\{\|\}\~\`]/g, '')
|
||||
)
|
||||
|
||||
slug = replaceDiacritics(slug)
|
||||
|
||||
slug = slug.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-')
|
||||
|
||||
return encodeURI(slug).replace(/\-+$/, '')
|
||||
return slug
|
||||
}
|
||||
|
||||
58
tests/lib/slugify-test.js
Normal file
58
tests/lib/slugify-test.js
Normal file
@@ -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)
|
||||
})
|
||||
Reference in New Issue
Block a user