1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2025-04-27 05:18:28 -04:00

add copy-to-clipboard button to code fences

This commit is contained in:
Jake Jarvis 2021-08-16 08:08:56 -04:00
parent 86ded40854
commit fdb9532cc5
Signed by: jake
GPG Key ID: 2B0C9CF251E69A39
5 changed files with 119 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import "./src/dark-mode.js";
import "./src/emoji.js";
import "./src/counter.js";
import "./src/clipboard.js";
import "./src/projects.js";
export default () => {};

View File

@ -0,0 +1,33 @@
import ClipboardJS from "clipboard";
// the default text of the copy button:
const copyTerm = "Copy";
// immediately give up if not supported
if (ClipboardJS.isSupported()) {
// loop through each code fence on page (if any)
document.querySelectorAll("div.highlight").forEach((highlightDiv) => {
const button = document.createElement("button");
button.className = "copy-button";
button.innerText = copyTerm;
// insert button as a sibling to Hugo's code fence
highlightDiv.insertBefore(button, highlightDiv.firstChild);
new ClipboardJS(button, {
// actual code element will have class "language-*", even if plaintext
text: (trigger) => trigger.parentElement.querySelector('code[class^="language-"]').innerText, // eslint-disable-line quotes
}).on("success", (e) => {
// show a subtle indication of success
e.trigger.innerText = "✓";
// reset button to original text after 2 seconds
setTimeout(() => {
e.trigger.innerText = copyTerm;
}, 2000);
// text needed to be auto-selected to copy, unselect immediately
e.clearSelection();
});
});
}

View File

@ -32,6 +32,7 @@ div.highlight {
overflow-x: scroll;
margin: 1em 0;
border: 1px solid;
position: relative;
pre {
padding-left: 1.5em;
@ -42,6 +43,25 @@ div.highlight {
> pre > code {
padding-right: 1.5em;
}
button.copy-button {
position: absolute;
top: 0;
right: 0;
z-index: 2;
cursor: pointer;
width: 5em;
padding: 0.75em 0.25em;
font-size: 0.9em;
font-weight: 500;
background: transparent;
border-top: 0;
border-right: 0;
border-left: 1px solid;
border-bottom: 1px solid;
}
}
// global table styles for line numbers and font styles
@ -95,6 +115,7 @@ div.highlight {
/*! Syntax Highlighting (light) - modified from Monokai Light: https://github.com/mlgill/pygments-style-monokailight */
body.light {
div.highlight,
button.copy-button,
:not(pre) > code {
color: #313131;
background-color: #fbfbfb;
@ -170,6 +191,7 @@ body.light {
/*! Syntax Highlighting (dark) - modified from Dracula: https://github.com/dracula/pygments */
body.dark {
div.highlight,
button.copy-button,
:not(pre) > code {
color: #e4e4e4;
background-color: #252525;

View File

@ -36,6 +36,7 @@
"@octokit/graphql": "^4.6.4",
"@octokit/graphql-schema": "^10.60.1",
"@sentry/node": "^6.11.0",
"clipboard": "2.0.8",
"cross-fetch": "3.1.4",
"date-fns": "2.23.0",
"fast-xml-parser": "^3.19.0",
@ -121,7 +122,7 @@
"webpack": "^5.50.0",
"webpack-assets-manifest": "^5.0.6",
"webpack-bundle-analyzer": "^4.4.2",
"webpack-cli": "^4.7.2",
"webpack-cli": "^4.8.0",
"webpack-dev-middleware": "^5.0.0",
"webpack-subresource-integrity": "^1.5.2"
},

View File

@ -1262,10 +1262,10 @@
resolved "https://registry.yarnpkg.com/@percy/logger/-/logger-1.0.0-beta.65.tgz#30a34797c935003334124e970f62914b0d124968"
integrity sha512-BJV0pjNlvcj4Y3nuMUGdb5RhjMduK40fRJJ9Lh/2qNk3pmnkGb9rH+GY+/0WY7quupNKxQjjyXcIP7I46/azNg==
"@polka/url@^1.0.0-next.15":
version "1.0.0-next.15"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23"
integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==
"@polka/url@^1.0.0-next.17":
version "1.0.0-next.17"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.17.tgz#25fdbdfd282c2f86ddf3fcefbd98be99cd2627e2"
integrity sha512-0p1rCgM3LLbAdwBnc7gqgnvjHg9KpbhcSphergHShlkWz8EdPawoMJ3/VbezI0mGC5eKCDzMaPgF9Yca6cKvrg==
"@sentry/core@6.11.0":
version "6.11.0"
@ -1741,10 +1741,10 @@
dependencies:
envinfo "^7.7.3"
"@webpack-cli/serve@^1.5.1":
version "1.5.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.5.1.tgz#b5fde2f0f79c1e120307c415a4c1d5eb15a6f278"
integrity sha512-4vSVUiOPJLmr45S8rMGy7WDvpWxfFxfP/Qx/cxZFCfvoypTYpPPL1X8VIZMe0WTA+Jr7blUxwUSEZNkjoMTgSw==
"@webpack-cli/serve@^1.5.2":
version "1.5.2"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.5.2.tgz#ea584b637ff63c5a477f6f21604b5a205b72c9ec"
integrity sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
@ -2870,6 +2870,15 @@ cli-truncate@^2.1.0:
slice-ansi "^3.0.0"
string-width "^4.2.0"
clipboard@2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.8.tgz#ffc6c103dd2967a83005f3f61976aa4655a4cdba"
integrity sha512-Y6WO0unAIQp5bLmk1zdThRhgJt/x3ks6f30s3oE3H1mgIEU33XyQjEf8gsf6DxC7NPX8Y1SsNWjUjL/ywLnnbQ==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
cliui@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
@ -2996,9 +3005,9 @@ color-support@^1.1.3:
integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==
colord@^2.0.1:
version "2.6.0"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.6.0.tgz#6cd716e1270cfff8d6f66e751768749650e209cd"
integrity sha512-8yMrtE20ZxH1YWvvSoeJFtvqY+GIAOfU+mZ3jx7ZSiEMasnAmNqD1BKUP3CuCWcy/XHgcXkLW6YU8C35nhOYVg==
version "2.7.0"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.7.0.tgz#706ea36fe0cd651b585eb142fe64b6480185270e"
integrity sha512-pZJBqsHz+pYyw3zpX6ZRXWoCHM1/cvFikY9TV8G3zcejCaKE0lhankoj8iScyrrePA8C7yJ5FStfA9zbcOnw7Q==
colorette@^1.2.1, colorette@^1.2.2:
version "1.3.0"
@ -3605,6 +3614,11 @@ delayed-stream@~1.0.0:
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -3860,9 +3874,9 @@ ee-first@1.1.1:
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.793:
version "1.3.805"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.805.tgz#a0873393a3b027ec60bdaf22a19c4946688cf941"
integrity sha512-uUJF59M6pNSRHQaXwdkaNB4BhSQ9lldRdG1qCjlrAFkynPGDc5wPoUcYEQQeQGmKyAWJPvGkYAWmtVrxWmDAkg==
version "1.3.806"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.806.tgz#21502100f11aead6c501d1cd7f2504f16c936642"
integrity sha512-AH/otJLAAecgyrYp0XK1DPiGVWcOgwPeJBOLeuFQ5l//vhQhwC9u6d+GijClqJAmsHG4XDue81ndSQPohUu0xA==
emoji-regex@^7.0.1:
version "7.0.3"
@ -4072,9 +4086,9 @@ eslint-config-prettier@~8.3.0:
integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==
eslint-import-resolver-node@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.5.tgz#939bbb0f74e179e757ca87f7a4a890dabed18ac4"
integrity sha512-XMoPKjSpXbkeJ7ZZ9icLnJMTY5Mc1kZbCakHquaFsXPpyWOwK0TK6CODO+0ca54UoM9LKOxyUNnoVZRl8TeaAg==
version "0.3.6"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd"
integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==
dependencies:
debug "^3.2.7"
resolve "^1.20.0"
@ -5176,6 +5190,13 @@ gonzales-pe@^4.3.0:
dependencies:
minimist "^1.2.5"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
dependencies:
delegate "^3.1.2"
got@^11.8.2:
version "11.8.2"
resolved "https://registry.yarnpkg.com/got/-/got-11.8.2.tgz#7abb3959ea28c31f3576f1576c1effce23f33599"
@ -9300,6 +9321,11 @@ seek-bzip@^1.0.5:
dependencies:
commander "^2.8.1"
select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
semver-compare@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
@ -9495,11 +9521,11 @@ simple-git-hooks@^2.5.1:
integrity sha512-iI/MEEVObv45slsxz+BT+5NCS2UDgVIqfQKmNjL4/XnEfacpdYAHd71Imc5Nw/FY100A+i1PIXdIdkLHYcC2Bg==
sirv@^1.0.7:
version "1.0.12"
resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.12.tgz#d816c882b35489b3c63290e2f455ae3eccd5f652"
integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==
version "1.0.14"
resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.14.tgz#b826343f573e12653c5b3c3080a3a2a6a06595cd"
integrity sha512-czTFDFjK9lXj0u9mJ3OmJoXFztoilYS+NdRPcJoT182w44wSEkHSiO7A2517GLJ8wKM4GjCm2OXE66Dhngbzjg==
dependencies:
"@polka/url" "^1.0.0-next.15"
"@polka/url" "^1.0.0-next.17"
mime "^2.3.1"
totalist "^1.0.0"
@ -10179,12 +10205,12 @@ svg-tags@^1.0.0:
integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=
svgo@^2.1.0, svgo@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.3.1.tgz#603a69ce50311c0e36791528f549644ec1b3f4bc"
integrity sha512-riDDIQgXpEnn0BEl9Gvhh1LNLIyiusSpt64IR8upJu7MwxnzetmF/Y57pXQD2NMX2lVyMRzXt5f2M5rO4wG7Dw==
version "2.4.0"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.4.0.tgz#0c42653101fd668692c0f69b55b8d7b182ef422b"
integrity sha512-W25S1UUm9Lm9VnE0TvCzL7aso/NCzDEaXLaElCUO/KaVitw0+IBicSVfM1L1c0YHK5TOFh73yQ2naCpVHEQ/OQ==
dependencies:
"@trysound/sax" "0.1.1"
chalk "^4.1.0"
colorette "^1.2.2"
commander "^7.1.0"
css-select "^4.1.3"
css-tree "^1.1.2"
@ -10340,6 +10366,11 @@ timsort@^0.3.0:
resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
to-absolute-glob@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz#1865f43d9e74b0822db9f145b78cff7d0f7c849b"
@ -10932,15 +10963,15 @@ webpack-bundle-analyzer@^4.4.2:
sirv "^1.0.7"
ws "^7.3.1"
webpack-cli@^4.7.2:
version "4.7.2"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.7.2.tgz#a718db600de6d3906a4357e059ae584a89f4c1a5"
integrity sha512-mEoLmnmOIZQNiRl0ebnjzQ74Hk0iKS5SiEEnpq3dRezoyR3yPaeQZCMCe+db4524pj1Pd5ghZXjT41KLzIhSLw==
webpack-cli@^4.8.0:
version "4.8.0"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.8.0.tgz#5fc3c8b9401d3c8a43e2afceacfa8261962338d1"
integrity sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==
dependencies:
"@discoveryjs/json-ext" "^0.5.0"
"@webpack-cli/configtest" "^1.0.4"
"@webpack-cli/info" "^1.3.0"
"@webpack-cli/serve" "^1.5.1"
"@webpack-cli/serve" "^1.5.2"
colorette "^1.2.1"
commander "^7.0.0"
execa "^5.0.0"