Skip to content

Commit

Permalink
Port external gatsby-remark-autolink-headers plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
smikitky committed Feb 6, 2019
1 parent 2a5b6cc commit add5007
Show file tree
Hide file tree
Showing 7 changed files with 181 additions and 13 deletions.
2 changes: 1 addition & 1 deletion gatsby-config.js
Expand Up @@ -55,7 +55,7 @@ module.exports = {
maxWidth: 840,
},
},
'gatsby-remark-autolink-headers',
'gatsby-remark-header-custom-ids',
{
resolve: 'gatsby-remark-code-repls',
options: {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Expand Up @@ -29,7 +29,6 @@
"gatsby-plugin-react-helmet": "^3.0.0",
"gatsby-plugin-sharp": "^2.0.0",
"gatsby-plugin-twitter": "^2.0.0",
"gatsby-remark-autolink-headers": "^2.0.12",
"gatsby-remark-code-repls": "^2.0.0",
"gatsby-remark-copy-linked-files": "^2.0.0",
"gatsby-remark-embed-snippet": "^3.0.0",
Expand All @@ -40,8 +39,10 @@
"gatsby-source-filesystem": "^2.0.0",
"gatsby-transformer-remark": "^2.0.0",
"gatsby-transformer-sharp": "^2.0.0",
"github-slugger": "^1.2.1",
"glamor": "^2.20.40",
"hex2rgba": "^0.0.1",
"mdast-util-to-string": "^1.0.5",
"normalize.css": "^8.0.0",
"prettier": "^1.7.4",
"prismjs": "^1.15.0",
Expand Down
30 changes: 30 additions & 0 deletions plugins/gatsby-remark-header-custom-ids/gatsby-client.js
@@ -0,0 +1,30 @@
let offsetY = 0;

const getTargetOffset = hash => {
const id = window.decodeURI(hash.replace(`#`, ``));
if (id !== ``) {
const element = document.getElementById(id);
if (element) {
return element.offsetTop - offsetY;
}
}
return null;
};

exports.onInitialClientRender = (_, pluginOptions) => {
if (pluginOptions.offsetY) {
offsetY = pluginOptions.offsetY;
}

requestAnimationFrame(() => {
const offset = getTargetOffset(window.location.hash);
if (offset !== null) {
window.scrollTo(0, offset);
}
});
};

exports.shouldUpdateScroll = ({routerProps: {location}}) => {
const offset = getTargetOffset(location.hash);
return offset !== null ? [0, offset] : true;
};
76 changes: 76 additions & 0 deletions plugins/gatsby-remark-header-custom-ids/gatsby-ssr.js
@@ -0,0 +1,76 @@
const React = require(`react`);

const pluginDefaults = {
className: `anchor`,
icon: true,
offsetY: 0,
};

exports.onRenderBody = ({setHeadComponents}, pluginOptions) => {
const {className, icon, offsetY} = Object.assign(
pluginDefaults,
pluginOptions,
);

const styles = `
.${className} {
float: left;
padding-right: 4px;
margin-left: -20px;
}
h1 .${className} svg,
h2 .${className} svg,
h3 .${className} svg,
h4 .${className} svg,
h5 .${className} svg,
h6 .${className} svg {
visibility: hidden;
}
h1:hover .${className} svg,
h2:hover .${className} svg,
h3:hover .${className} svg,
h4:hover .${className} svg,
h5:hover .${className} svg,
h6:hover .${className} svg,
h1 .${className}:focus svg,
h2 .${className}:focus svg,
h3 .${className}:focus svg,
h4 .${className}:focus svg,
h5 .${className}:focus svg,
h6 .${className}:focus svg {
visibility: visible;
}
`;

const script = `
document.addEventListener("DOMContentLoaded", function(event) {
var hash = window.decodeURI(location.hash.replace('#', ''))
if (hash !== '') {
var element = document.getElementById(hash)
if (element) {
var offset = element.offsetTop
// Wait for the browser to finish rendering before scrolling.
setTimeout((function() {
window.scrollTo(0, offset - ${offsetY})
}), 0)
}
}
})
`;

const style = icon ? (
<style key={`gatsby-remark-autolink-headers-style`} type="text/css">
{styles}
</style>
) : (
undefined
);

return setHeadComponents([
style,
<script
key={`gatsby-remark-autolink-headers-script`}
dangerouslySetInnerHTML={{__html: script}}
/>,
]);
};
60 changes: 60 additions & 0 deletions plugins/gatsby-remark-header-custom-ids/index.js
@@ -0,0 +1,60 @@
/*!
* Based on 'gatsby-remark-autolink-headers'
* Original Author: Kyle Mathews <mathews.kyle@gmail.com>
* Copyright (c) 2015 Gatsbyjs
*/

const toString = require('mdast-util-to-string');
const visit = require('unist-util-visit');
const slugs = require('github-slugger')();

function patch(context, key, value) {
if (!context[key]) {
context[key] = value;
}

return context[key];
}

const svgIcon = `<svg aria-hidden="true" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg>`;

module.exports = (
{markdownAST},
{icon = svgIcon, className = `anchor`, maintainCase = false},
) => {
slugs.reset();

visit(markdownAST, 'heading', node => {
const id = slugs.slug(toString(node), maintainCase);
const data = patch(node, 'data', {});

patch(data, 'id', id);
patch(data, 'htmlAttributes', {});
patch(data, 'hProperties', {});
patch(data.htmlAttributes, 'id', id);
patch(data.hProperties, 'id', id);

if (icon !== false) {
node.children.unshift({
type: 'link',
url: `#${id}`,
title: null,
data: {
hProperties: {
'aria-hidden': true,
class: className,
},
hChildren: [
{
type: 'raw',
// The Octicon link icon is the default. But users can set their own icon via the "icon" option.
value: icon,
},
],
},
});
}
});

return markdownAST;
};
4 changes: 4 additions & 0 deletions plugins/gatsby-remark-header-custom-ids/package.json
@@ -0,0 +1,4 @@
{
"name": "gatsby-remark-header-custom-ids",
"version": "0.0.1"
}
19 changes: 8 additions & 11 deletions yarn.lock
Expand Up @@ -5463,16 +5463,6 @@ gatsby-react-router-scroll@^2.0.0:
scroll-behavior "^0.9.9"
warning "^3.0.0"

gatsby-remark-autolink-headers@^2.0.12:
version "2.0.12"
resolved "https://registry.yarnpkg.com/gatsby-remark-autolink-headers/-/gatsby-remark-autolink-headers-2.0.12.tgz#96830bd7496ace7d1b7e07444aa09ecbe2ac59d2"
integrity sha512-TI7dpdHOUohIWCW7i8ta4zZAdWG5C2ZmrHMC9flWGWQ62oq6Q2eW+I1I/v//UZ+vJ1dRaSX2lmsVFmt87rLVHQ==
dependencies:
"@babel/runtime" "^7.0.0"
github-slugger "^1.1.1"
mdast-util-to-string "^1.0.2"
unist-util-visit "^1.3.0"

gatsby-remark-code-repls@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/gatsby-remark-code-repls/-/gatsby-remark-code-repls-2.0.0.tgz#b3290987046f1d325e6e93dbe9295f3cbb3df34a"
Expand Down Expand Up @@ -5814,6 +5804,13 @@ github-slugger@^1.1.1:
dependencies:
emoji-regex ">=6.0.0 <=6.1.1"

github-slugger@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.2.1.tgz#47e904e70bf2dccd0014748142d31126cfd49508"
integrity sha512-SsZUjg/P03KPzQBt7OxJPasGw6NRO5uOgiZ5RGXVud5iSIZ0eNZeNp5rTwCxtavrRUa/A77j8mePVc5lEvk0KQ==
dependencies:
emoji-regex ">=6.0.0 <=6.1.1"

glamor@^2.20.40:
version "2.20.40"
resolved "https://registry.yarnpkg.com/glamor/-/glamor-2.20.40.tgz#f606660357b7cf18dface731ad1a2cfa93817f05"
Expand Down Expand Up @@ -8184,7 +8181,7 @@ mdast-util-to-nlcst@^3.2.0:
unist-util-position "^3.0.0"
vfile-location "^2.0.0"

mdast-util-to-string@^1.0.2:
mdast-util-to-string@^1.0.2, mdast-util-to-string@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.0.5.tgz#3552b05428af22ceda34f156afe62ec8e6d731ca"
integrity sha512-2qLt/DEOo5F6nc2VFScQiHPzQ0XXcabquRJxKMhKte8nt42o08HUxNDPk7tt0YPxnWjAT11I1SYi0X0iPnfI5A==
Expand Down

0 comments on commit add5007

Please sign in to comment.