summaryrefslogtreecommitdiff
path: root/public
diff options
context:
space:
mode:
authorSheogorath2019-12-03 14:40:00 +0100
committerGitHub2019-12-03 14:40:00 +0100
commit33150b79c7a4c3ba456afdadb31c709b3be18980 (patch)
treee8f4be1a385a70336830e1851ab86d7d9fb686a5 /public
parent2ddec15af8e77fcad85e62ee8c0b6eccefc52405 (diff)
parentad1a2fb19c842ea5e4cb46a24989ce95b2041902 (diff)
Merge pull request #218 from hoijui/linkifyHeaderStyle
Linkify header style
Diffstat (limited to 'public')
-rw-r--r--public/js/extra.js85
-rw-r--r--public/js/lib/common/constant.ejs2
2 files changed, 67 insertions, 20 deletions
diff --git a/public/js/extra.js b/public/js/extra.js
index d381576f..6cda6171 100644
--- a/public/js/extra.js
+++ b/public/js/extra.js
@@ -825,6 +825,36 @@ const anchorForId = id => {
return anchor
}
+const createHeaderId = (headerContent, headerIds = null) => {
+ // to escape characters not allow in css and humanize
+ const slug = slugifyWithUTF8(headerContent)
+ let id
+ if (window.linkifyHeaderStyle === 'keep-case') {
+ id = slug
+ } else if (window.linkifyHeaderStyle === 'lower-case') {
+ // to make compatible with GitHub, GitLab, Pandoc and many more
+ id = slug.toLowerCase()
+ } else if (window.linkifyHeaderStyle === 'gfm') {
+ // see GitHub implementation reference:
+ // https://gist.github.com/asabaylus/3071099#gistcomment-1593627
+ // it works like 'lower-case', but ...
+ const idBase = slug.toLowerCase()
+ id = idBase
+ if (headerIds !== null) {
+ // ... making sure the id is unique
+ let i = 1
+ while (headerIds.has(id)) {
+ id = idBase + '-' + i
+ i++
+ }
+ headerIds.add(id)
+ }
+ } else {
+ throw new Error('Unknown linkifyHeaderStyle value "' + window.linkifyHeaderStyle + '"')
+ }
+ return id
+}
+
const linkifyAnchors = (level, containingElement) => {
const headers = containingElement.getElementsByTagName(`h${level}`)
@@ -832,13 +862,7 @@ const linkifyAnchors = (level, containingElement) => {
let header = headers[i]
if (header.getElementsByClassName('anchor').length === 0) {
if (typeof header.id === 'undefined' || header.id === '') {
- // to escape characters not allow in css and humanize
- let id = slugifyWithUTF8(getHeaderContent(header))
- // to make compatible with GitHub, GitLab, Pandoc and many more
- if (window.linkifyHeaderStyle !== 'keep-case') {
- id = id.toLowerCase()
- }
- header.id = id
+ header.id = createHeaderId(getHeaderContent(header))
}
if (!(typeof header.id === 'undefined' || header.id === '')) {
header.insertBefore(anchorForId(header.id), header.firstChild)
@@ -864,20 +888,43 @@ function getHeaderContent (header) {
return headerHTML[0].innerHTML
}
+function changeHeaderId ($header, id, newId) {
+ $header.attr('id', newId)
+ const $headerLink = $header.find(`> a.anchor[href="#${id}"]`)
+ $headerLink.attr('href', `#${newId}`)
+ $headerLink.attr('title', newId)
+}
+
export function deduplicatedHeaderId (view) {
+ // headers contained in the last change
const headers = view.find(':header.raw').removeClass('raw').toArray()
- for (let i = 0; i < headers.length; i++) {
- const id = $(headers[i]).attr('id')
- if (!id) continue
- const duplicatedHeaders = view.find(`:header[id="${id}"]`).toArray()
- for (let j = 0; j < duplicatedHeaders.length; j++) {
- if (duplicatedHeaders[j] !== headers[i]) {
- const newId = id + j
- const $duplicatedHeader = $(duplicatedHeaders[j])
- $duplicatedHeader.attr('id', newId)
- const $headerLink = $duplicatedHeader.find(`> a.anchor[href="#${id}"]`)
- $headerLink.attr('href', `#${newId}`)
- $headerLink.attr('title', newId)
+ if (headers.length === 0) {
+ return
+ }
+ if (window.linkifyHeaderStyle === 'gfm') {
+ // consistent with GitHub, GitLab, Pandoc & co.
+ // all headers contained in the document, in order of appearance
+ const allHeaders = view.find(`:header`).toArray()
+ // list of finaly assigned header IDs
+ const headerIds = new Set()
+ for (let j = 0; j < allHeaders.length; j++) {
+ const $header = $(allHeaders[j])
+ const id = $header.attr('id')
+ const newId = createHeaderId(getHeaderContent($header), headerIds)
+ changeHeaderId($header, id, newId)
+ }
+ } else {
+ // the legacy way
+ for (let i = 0; i < headers.length; i++) {
+ const id = $(headers[i]).attr('id')
+ if (!id) continue
+ const duplicatedHeaders = view.find(`:header[id="${id}"]`).toArray()
+ for (let j = 0; j < duplicatedHeaders.length; j++) {
+ if (duplicatedHeaders[j] !== headers[i]) {
+ const newId = id + j
+ const $header = $(duplicatedHeaders[j])
+ changeHeaderId($header, id, newId)
+ }
}
}
}
diff --git a/public/js/lib/common/constant.ejs b/public/js/lib/common/constant.ejs
index bbcb8c7a..114a9077 100644
--- a/public/js/lib/common/constant.ejs
+++ b/public/js/lib/common/constant.ejs
@@ -5,6 +5,6 @@ window.version = '<%- version %>'
window.allowedUploadMimeTypes = <%- JSON.stringify(allowedUploadMimeTypes) %>
-window.linkifyHeaderStyle = <%- JSON.stringify(linkifyHeaderStyle) %>
+window.linkifyHeaderStyle = '<%- linkifyHeaderStyle %>'
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'