From 4f630aadc84b2036d08f5445d1dbea92af55f628 Mon Sep 17 00:00:00 2001 From: Jori Lallo Date: Sun, 29 May 2016 15:22:33 -0700 Subject: [PATCH] Added anchors for document headings --- server/utils/markdown.js | 15 +++++++++++++- src/assets/icons/anchor.svg | 1 + src/components/Document/Document.js | 5 ++++- src/components/Document/Document.scss | 25 +++++++++++++++++++++++ src/scenes/DocumentScene/DocumentScene.js | 13 ++++++++++++ 5 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 src/assets/icons/anchor.svg diff --git a/server/utils/markdown.js b/server/utils/markdown.js index a5d22d23..c5355456 100644 --- a/server/utils/markdown.js +++ b/server/utils/markdown.js @@ -1,14 +1,27 @@ +import slug from 'slug'; import truncate from 'truncate-html'; import marked, { Renderer } from 'marked'; import highlight from 'highlight.js'; +slug.defaults.mode ='rfc3986'; + const renderer = new Renderer(); renderer.code = (code, language) => { const validLang = !!(language && highlight.getLanguage(language)); const highlighted = validLang ? highlight.highlight(language, code).value : code; return `
${highlighted}
`; }; - +renderer.heading = (text, level) => { + const headingSlug = slug(text); + return ` + + +   + + ${text} + + `; +}, marked.setOptions({ renderer: renderer, diff --git a/src/assets/icons/anchor.svg b/src/assets/icons/anchor.svg new file mode 100644 index 00000000..f9816437 --- /dev/null +++ b/src/assets/icons/anchor.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Document/Document.js b/src/components/Document/Document.js index 8d87fadd..6a42f1f3 100644 --- a/src/components/Document/Document.js +++ b/src/components/Document/Document.js @@ -20,7 +20,10 @@ class Document extends React.Component { name={ this.props.document.user.name } timestamp={ this.props.document.createdAt } /> -
+
); } diff --git a/src/components/Document/Document.scss b/src/components/Document/Document.scss index be5400ab..fa6dfcc5 100644 --- a/src/components/Document/Document.scss +++ b/src/components/Document/Document.scss @@ -2,3 +2,28 @@ width: 100%; padding: 20px; } + +.document { + h1, h2, h3, h4, h5, h6 { + :global { + .anchor { + visibility: hidden; + background-image: url('../../assets/icons/anchor.svg'); + background-repeat: no-repeat; + background-size: 100%; + background-position: 0 center; + margin-left: -26px; + width: 20px; + display: inline-block; + } + } + + &:hover { + :global { + .anchor { + visibility: visible; + } + } + } + } +} \ No newline at end of file diff --git a/src/scenes/DocumentScene/DocumentScene.js b/src/scenes/DocumentScene/DocumentScene.js index 4c4a1658..1286ca23 100644 --- a/src/scenes/DocumentScene/DocumentScene.js +++ b/src/scenes/DocumentScene/DocumentScene.js @@ -17,6 +17,19 @@ class DocumentScene extends React.Component { this.props.fetchDocumentAsync(documentId); } + componentWillReceiveProps = (nextProps) => { + // Scroll to anchor after loading + const hash = this.props.location.hash; + + if (nextProps.document && hash) { + const name = hash.split('#')[1]; + setTimeout(() => { + const element = document.getElementsByName(name)[0]; + if (element) element.scrollIntoView() + }, 0); + } + } + render() { const document = this.props.document; let title;