hugo-book

This commit is contained in:
JamesFlare1212
2023-04-26 22:19:59 +08:00
parent 0d2ffd0447
commit c6ca9d6524
215 changed files with 7267 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
/* You can add custom styles here. */
// @import "plugins/numbered";

View File

@@ -0,0 +1,66 @@
// Used in layout
$padding-1: 1px !default;
$padding-4: 0.25rem !default;
$padding-8: 0.5rem !default;
$padding-16: 1rem !default;
$font-size-base: 16px !default;
$font-size-12: 0.75rem !default;
$font-size-14: 0.875rem !default;
$font-size-16: 1rem !default;
$border-radius: $padding-4 !default;
$body-font-weight: normal !default;
$body-min-width: 20rem !default;
$container-max-width: 80rem !default;
$header-height: 3.5rem !default;
$menu-width: 16rem !default;
$toc-width: 16rem !default;
$mobile-breakpoint: $menu-width + $body-min-width * 1.2 + $toc-width !default;
$hint-colors: (
info: #6bf,
warning: #fd6,
danger: #f66,
) !default;
// Themes
@mixin theme-light {
--gray-100: #f8f9fa;
--gray-200: #e9ecef;
--gray-500: #adb5bd;
--color-link: #0055bb;
--color-visited-link: #8440f1;
--body-background: white;
--body-font-color: black;
--icon-filter: none;
--hint-color-info: #6bf;
--hint-color-warning: #fd6;
--hint-color-danger: #f66;
}
@mixin theme-dark {
--gray-100: rgba(255, 255, 255, 0.1);
--gray-200: rgba(255, 255, 255, 0.2);
--gray-500: rgba(255, 255, 255, 0.5);
--color-link: #84b2ff;
--color-visited-link: #b88dff;
--body-background: #343a40;
--body-font-color: #e9ecef;
--icon-filter: brightness(0) invert(1);
--hint-color-info: #6bf;
--hint-color-warning: #fd6;
--hint-color-danger: #f66;
}

View File

@@ -0,0 +1,39 @@
/* roboto-regular - latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local(''),
url('fonts/roboto-v27-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/roboto-v27-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* roboto-700 - latin */
@font-face {
font-family: 'Roboto';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local(''),
url('fonts/roboto-v27-latin-700.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/roboto-v27-latin-700.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
/* roboto-mono-regular - latin */
@font-face {
font-family: 'Roboto Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: local(''),
url('fonts/roboto-mono-v13-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
url('fonts/roboto-mono-v13-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
}
body {
font-family: 'Roboto', sans-serif;
}
code {
font-family: 'Roboto Mono', monospace;
}

View File

@@ -0,0 +1,364 @@
html {
font-size: $font-size-base;
scroll-behavior: smooth;
touch-action: manipulation;
}
body {
min-width: $body-min-width;
color: var(--body-font-color);
background: var(--body-background);
letter-spacing: 0.33px;
font-weight: $body-font-weight;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
box-sizing: border-box;
* {
box-sizing: inherit;
}
}
h1,
h2,
h3,
h4,
h5 {
font-weight: $body-font-weight;
}
a {
text-decoration: none;
color: var(--color-link);
}
img {
vertical-align: baseline;
}
:focus {
@include outline;
}
aside nav ul {
padding: 0;
margin: 0;
list-style: none;
li {
margin: 1em 0;
position: relative;
}
a {
display: block;
}
a:hover {
opacity: 0.5;
}
ul {
padding-inline-start: $padding-16;
}
}
ul.pagination {
display: flex;
justify-content: center;
list-style-type: none;
padding-inline-start: 0px;
.page-item a {
padding: $padding-16;
}
}
.container {
max-width: $container-max-width;
margin: 0 auto;
}
.book-icon {
filter: var(--icon-filter);
}
.book-brand {
margin-top: 0;
margin-bottom: $padding-16;
img {
height: 1.5em;
width: 1.5em;
margin-inline-end: $padding-8;
}
}
.book-menu {
flex: 0 0 $menu-width;
font-size: $font-size-14;
.book-menu-content {
width: $menu-width;
padding: $padding-16;
background: var(--body-background);
@include fixed;
}
a,
label {
color: inherit;
cursor: pointer;
word-wrap: break-word;
}
a.active {
color: var(--color-link);
}
input.toggle + label + ul {
display: none;
}
input.toggle:checked + label + ul {
display: block;
}
input.toggle + label::after {
content: "";
}
input.toggle:checked + label::after {
content: "";
}
}
// for RTL support
body[dir="rtl"] .book-menu {
input.toggle + label::after {
content: "";
}
input.toggle:checked + label::after {
content: "";
}
}
.book-section-flat {
margin: $padding-16 * 2 0;
> a,
> span,
> label {
font-weight: bolder;
}
> ul {
padding-inline-start: 0;
}
}
.book-page {
min-width: $body-min-width;
flex-grow: 1;
padding: $padding-16;
}
.book-post {
margin-bottom: $padding-16 * 3;
}
.book-header {
display: none;
margin-bottom: $padding-16;
label {
line-height: 0;
}
img.book-icon {
height: 1.5em;
width: 1.5em;
}
}
.book-search {
position: relative;
margin: $padding-16 0;
border-bottom: 1px solid transparent;
input {
width: 100%;
padding: $padding-8;
border: 0;
border-radius: $border-radius;
background: var(--gray-100);
color: var(--body-font-color);
&:required + .book-search-spinner {
display: block;
}
}
.book-search-spinner {
position: absolute;
top: 0;
margin: $padding-8;
margin-inline-start: calc(100% - #{$padding-16 + $padding-8});
width: $padding-16;
height: $padding-16;
border: $padding-1 solid transparent;
border-top-color: var(--body-font-color);
border-radius: 50%;
@include spin(1s);
}
small {
opacity: 0.5;
}
}
.book-toc {
flex: 0 0 $toc-width;
font-size: $font-size-12;
.book-toc-content {
width: $toc-width;
padding: $padding-16;
@include fixed;
}
img {
height: 1em;
width: 1em;
}
nav > ul > li:first-child {
margin-top: 0;
}
}
.book-footer {
padding-top: $padding-16;
font-size: $font-size-14;
img {
height: 1em;
width: 1em;
margin-inline-end: $padding-8;
}
}
.book-comments {
margin-top: $padding-16;
}
.book-languages {
margin-block-end: $padding-16 * 2;
.book-icon {
height: 1em;
width: 1em;
margin-inline-end: .5em;
}
ul {
padding-inline-start: 1.5em;
}
}
// Responsive styles
.book-menu-content,
.book-toc-content,
.book-page,
.book-header aside,
.markdown {
transition: 0.2s ease-in-out;
transition-property: transform, margin, opacity, visibility;
will-change: transform, margin, opacity;
}
@media screen and (max-width: $mobile-breakpoint) {
#menu-control,
#toc-control {
display: inline;
}
.book-menu {
visibility: hidden;
margin-inline-start: -$menu-width;
font-size: $font-size-base;
z-index: 1;
}
.book-toc {
display: none;
}
.book-header {
display: block;
}
#menu-control:focus ~ main label[for="menu-control"] {
@include outline;
}
#menu-control:checked ~ main {
.book-menu {
visibility: initial;
}
.book-menu .book-menu-content {
transform: translateX($menu-width);
box-shadow: 0 0 $padding-8 rgba(0, 0, 0, 0.1);
}
.book-page {
opacity: 0.25;
}
.book-menu-overlay {
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
}
#toc-control:focus ~ main label[for="toc-control"] {
@include outline;
}
#toc-control:checked ~ main {
.book-header aside {
display: block;
}
}
// for RTL support
body[dir="rtl"] #menu-control:checked ~ main {
.book-menu .book-menu-content {
transform: translateX(-$menu-width);
}
}
}
// Extra space for big screens
@media screen and (min-width: $container-max-width) {
.book-page,
.book-menu .book-menu-content,
.book-toc .book-toc-content {
padding: $padding-16 * 2 $padding-16;
}
}

View File

@@ -0,0 +1,197 @@
@import "variables";
.markdown {
line-height: 1.6;
// remove padding at the beginning of page
> :first-child {
margin-top: 0;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-weight: normal;
line-height: 1;
margin-top: 1.5em;
margin-bottom: $padding-16;
a.anchor {
opacity: 0;
font-size: 0.75em;
vertical-align: middle;
text-decoration: none;
}
&:hover a.anchor,
a.anchor:focus {
opacity: initial;
}
}
h4,
h5,
h6 {
font-weight: bolder;
}
h5 {
font-size: 0.875em;
}
h6 {
font-size: 0.75em;
}
b,
optgroup,
strong {
font-weight: bolder;
}
a {
text-decoration: none;
&:hover {
text-decoration: underline;
}
&:visited {
color: var(--color-visited-link);
}
}
img {
max-width: 100%;
height: auto;
}
code {
padding: 0 $padding-4;
background: var(--gray-200);
border-radius: $border-radius;
font-size: 0.875em;
}
pre {
padding: $padding-16;
background: var(--gray-100);
border-radius: $border-radius;
overflow-x: auto;
code {
padding: 0;
background: none;
}
}
p {
word-wrap: break-word;
}
blockquote {
margin: $padding-16 0;
padding: $padding-8 $padding-16 $padding-8 ($padding-16 - $padding-4); //to keep total left space 16dp
border-inline-start: $padding-4 solid var(--gray-200);
border-radius: $border-radius;
:first-child {
margin-top: 0;
}
:last-child {
margin-bottom: 0;
}
}
table {
overflow: auto;
display: block;
border-spacing: 0;
border-collapse: collapse;
margin-top: $padding-16;
margin-bottom: $padding-16;
tr th,
tr td {
padding: $padding-8 $padding-16;
border: $padding-1 solid var(--gray-200);
}
tr:nth-child(2n) {
background: var(--gray-100);
}
}
hr {
height: $padding-1;
border: none;
background: var(--gray-200);
}
ul,
ol {
padding-inline-start: $padding-16 * 2;
word-wrap: break-word;
}
dl {
dt {
font-weight: bolder;
margin-top: $padding-16;
}
dd {
margin-inline-start: 0;
margin-bottom: $padding-16;
}
}
// Special case for highlighted code with line numbers
.highlight table tr {
td:nth-child(1) pre {
margin: 0;
padding-inline-end: 0;
}
td:nth-child(2) pre {
margin: 0;
padding-inline-start: 0;
}
}
details {
padding: $padding-16;
border: $padding-1 solid var(--gray-200);
border-radius: $border-radius;
summary {
line-height: 1;
padding: $padding-16;
margin: -$padding-16;
cursor: pointer;
}
&[open] summary {
margin-bottom: 0;
}
}
figure {
margin: $padding-16 0;
figcaption p {
margin-top: 0;
}
}
}
.markdown-inner {
// Util class to remove extra margin in nested markdown content
> :first-child {
margin-top: 0;
}
> :last-child {
margin-bottom: 0;
}
}

View File

@@ -0,0 +1,17 @@
@media print {
.book-menu,
.book-footer,
.book-toc {
display: none;
}
.book-header,
.book-header aside {
display: block;
}
main {
// Fix for https://bugzilla.mozilla.org/show_bug.cgi?id=939897
display: block !important;
}
}

View File

@@ -0,0 +1,104 @@
.markdown {
// {{< expand "Label" "icon" >}}
.book-expand {
margin-top: $padding-16;
margin-bottom: $padding-16;
border: $padding-1 solid var(--gray-200);
border-radius: $border-radius;
overflow: hidden;
.book-expand-head {
background: var(--gray-100);
padding: $padding-8 $padding-16;
cursor: pointer;
}
.book-expand-content {
display: none;
padding: $padding-16;
}
input[type="checkbox"]:checked + .book-expand-content {
display: block;
}
}
// {{< tabs >}}
.book-tabs {
margin-top: $padding-16;
margin-bottom: $padding-16;
border: $padding-1 solid var(--gray-200);
border-radius: $border-radius;
overflow: hidden;
display: flex;
flex-wrap: wrap;
label {
display: inline-block;
padding: $padding-8 $padding-16;
border-bottom: $padding-1 transparent;
cursor: pointer;
}
.book-tabs-content {
order: 999; //Move content blocks to the end
width: 100%;
border-top: $padding-1 solid var(--gray-100);
padding: $padding-16;
display: none;
}
input[type="radio"]:checked + label {
border-bottom: $padding-1 solid var(--color-link);
}
input[type="radio"]:checked + label + .book-tabs-content {
display: block;
}
input[type="radio"]:focus + label {
@include outline;
}
}
// {{< columns >}}
.book-columns {
margin-left: -$padding-16;
margin-right: -$padding-16;
> div {
margin: $padding-16 0;
min-width: $body-min-width / 2;
padding: 0 $padding-16;
}
}
// {{< button >}}
a.book-btn {
display: inline-block;
font-size: $font-size-14;
color: var(--color-link);
line-height: $padding-16 * 2;
padding: 0 $padding-16;
border: $padding-1 solid var(--color-link);
border-radius: $border-radius;
cursor: pointer;
&:hover {
text-decoration: none;
}
}
// {{< hint >}}
.book-hint {
@each $name, $color in $hint-colors {
&.#{$name} {
border-color: $color;
background-color: rgba($color, 0.1);
}
}
}
}

View File

@@ -0,0 +1,92 @@
.flex {
display: flex;
}
.flex-auto {
flex: 1 1 auto;
}
.flex-even {
flex: 1 1;
}
.flex-wrap {
flex-wrap: wrap;
}
.justify-start {
justify-content: flex-start;
}
.justify-end {
justify-content: flex-end;
}
.justify-center {
justify-content: center;
}
.justify-between {
justify-content: space-between;
}
.align-center {
align-items: center;
}
.mx-auto {
margin: 0 auto;
}
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.hidden {
display: none;
}
input.toggle {
height: 0;
width: 0;
overflow: hidden;
opacity: 0;
position: absolute;
}
.clearfix::after {
content: "";
display: table;
clear: both;
}
@mixin spin($duration) {
animation: spin $duration ease infinite;
@keyframes spin {
100% {
transform: rotate(360deg);
}
}
}
@mixin fixed {
position: fixed;
top: 0;
bottom: 0;
overflow-x: hidden;
overflow-y: auto;
}
@mixin outline {
outline-style: auto;
outline-color: currentColor;
outline-color: -webkit-focus-ring-color;
}

View File

@@ -0,0 +1,3 @@
/* You can override SASS variables here. */
// @import "plugins/dark";

View File

@@ -0,0 +1,15 @@
@import "defaults";
@import "variables";
@import "themes/{{ default "light" .Site.Params.BookTheme }}";
@import "normalize";
@import "utils";
@import "main";
@import "fonts";
@import "print";
@import "markdown";
@import "shortcodes";
// Custom defined styles
@import "custom";

View File

@@ -0,0 +1,24 @@
(function () {
function select(element) {
const selection = window.getSelection();
const range = document.createRange();
range.selectNodeContents(element);
selection.removeAllRanges();
selection.addRange(range);
}
document.querySelectorAll("pre code").forEach(code => {
code.addEventListener("click", function (event) {
if (window.getSelection().toString()) {
return;
}
select(code.parentElement);
if (navigator.clipboard) {
navigator.clipboard.writeText(code.parentElement.textContent);
}
});
});
})();

View File

@@ -0,0 +1,15 @@
{
"name": "{{ .Site.Title }}",
"short_name": "{{ .Site.Title }}",
"start_url": "{{ "/" | relURL }}",
"scope": "{{ "/" | relURL }}",
"display": "standalone",
"background_color": "#000000",
"theme_color": "#000000",
"icons": [
{
"src": "{{ "/favicon.svg" | relURL }}",
"sizes": "512x512"
}
]
}

View File

@@ -0,0 +1,7 @@
(function() {
var menu = document.querySelector("aside .book-menu-content");
addEventListener("beforeunload", function(event) {
localStorage.setItem("menu.scrollTop", menu.scrollTop);
});
menu.scrollTop = localStorage.getItem("menu.scrollTop");
})();

View File

@@ -0,0 +1,6 @@
{
"flowchart": {
"useMaxWidth":true
},
"theme": "default"
}

349
themes/hugo-book/assets/normalize.css vendored Normal file
View File

@@ -0,0 +1,349 @@
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
========================================================================== */
/**
* 1. Correct the line height in all browsers.
* 2. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */
}
/* Sections
========================================================================== */
/**
* Remove the margin in all browsers.
*/
body {
margin: 0;
}
/**
* Render the `main` element consistently in IE.
*/
main {
display: block;
}
/**
* Correct the font size and margin on `h1` elements within `section` and
* `article` contexts in Chrome, Firefox, and Safari.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/* Grouping content
========================================================================== */
/**
* 1. Add the correct box sizing in Firefox.
* 2. Show the overflow in Edge and IE.
*/
hr {
box-sizing: content-box; /* 1 */
height: 0; /* 1 */
overflow: visible; /* 2 */
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
pre {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/* Text-level semantics
========================================================================== */
/**
* Remove the gray background on active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* 1. Remove the bottom border in Chrome 57-
* 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */
}
/**
* Add the correct font weight in Chrome, Edge, and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
* 1. Correct the inheritance and scaling of font size in all browsers.
* 2. Correct the odd `em` font sizing in all browsers.
*/
code,
kbd,
samp {
font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */
}
/**
* Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` elements from affecting the line height in
* all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/* Embedded content
========================================================================== */
/**
* Remove the border on images inside links in IE 10.
*/
img {
border-style: none;
}
/* Forms
========================================================================== */
/**
* 1. Change the font styles in all browsers.
* 2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
* Show the overflow in IE.
* 1. Show the overflow in Edge.
*/
button,
input { /* 1 */
overflow: visible;
}
/**
* Remove the inheritance of text transform in Edge, Firefox, and IE.
* 1. Remove the inheritance of text transform in Firefox.
*/
button,
select { /* 1 */
text-transform: none;
}
/**
* Correct the inability to style clickable types in iOS and Safari.
*/
button,
[type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
/**
* Remove the inner border and padding in Firefox.
*/
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
/**
* Restore the focus styles unset by the previous rule.
*/
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
/**
* Correct the padding in Firefox.
*/
fieldset {
padding: 0.35em 0.75em 0.625em;
}
/**
* 1. Correct the text wrapping in Edge and IE.
* 2. Correct the color inheritance from `fieldset` elements in IE.
* 3. Remove the padding so developers are not caught out when they zero out
* `fieldset` elements in all browsers.
*/
legend {
box-sizing: border-box; /* 1 */
color: inherit; /* 2 */
display: table; /* 1 */
max-width: 100%; /* 1 */
padding: 0; /* 3 */
white-space: normal; /* 1 */
}
/**
* Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
progress {
vertical-align: baseline;
}
/**
* Remove the default vertical scrollbar in IE 10+.
*/
textarea {
overflow: auto;
}
/**
* 1. Add the correct box sizing in IE 10.
* 2. Remove the padding in IE 10.
*/
[type="checkbox"],
[type="radio"] {
box-sizing: border-box; /* 1 */
padding: 0; /* 2 */
}
/**
* Correct the cursor style of increment and decrement buttons in Chrome.
*/
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Correct the odd appearance in Chrome and Safari.
* 2. Correct the outline style in Safari.
*/
[type="search"] {
-webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */
}
/**
* Remove the inner padding in Chrome and Safari on macOS.
*/
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* 1. Correct the inability to style clickable types in iOS and Safari.
* 2. Change font properties to `inherit` in Safari.
*/
::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */
font: inherit; /* 2 */
}
/* Interactive
========================================================================== */
/*
* Add the correct display in Edge, IE 10+, and Firefox.
*/
details {
display: block;
}
/*
* Add the correct display in all browsers.
*/
summary {
display: list-item;
}
/* Misc
========================================================================== */
/**
* Add the correct display in IE 10+.
*/
template {
display: none;
}
/**
* Add the correct display in IE 10.
*/
[hidden] {
display: none;
}

View File

@@ -0,0 +1,36 @@
$startLevel: 1;
$endLevel: 6;
.book-page .markdown {
@for $currentLevel from $startLevel through $endLevel {
> h#{$currentLevel} {
counter-increment: h#{$currentLevel};
counter-reset: h#{$currentLevel + 1};
$content: "";
@for $n from $startLevel through $currentLevel {
$content: $content + 'counter(h#{$n})"."';
}
&::before {
content: unquote($content) " ";
}
}
}
}
.book-toc nav ul {
li {
counter-increment: item;
&:first-child {
counter-reset: item;
}
&:before {
content: counters(item, ".") ". ";
float: left;
margin-inline-end: $padding-4;
}
}
}

View File

@@ -0,0 +1,26 @@
@import "defaults";
@import "variables";
// Webkit
::-webkit-scrollbar {
width: $padding-8;
}
::-webkit-scrollbar-thumb {
background: transparent;
border-radius: $padding-8;
}
:hover::-webkit-scrollbar-thumb {
background: var(--gray-500);
}
// MS
body {
-ms-overflow-style: -ms-autohiding-scrollbar;
}
// Future
.book-menu nav {
scrollbar-color: transparent var(--gray-500);
}

View File

@@ -0,0 +1,17 @@
[
{{- $pages := where .Site.Pages "Kind" "in" (slice "page" "section") -}}
{{- $pages = where $pages "Params.booksearchexclude" "!=" true -}}
{{/* Remove until we know why it does not work, see https://github.com/alex-shpak/hugo-book/issues/528 */}}
{{/*- $pages = where $pages "Content" "not in" (slice nil "") -*/}}
{{- $pages = where $pages "Content" "!=" "" -}}
{{ range $index, $page := $pages }}
{{ if gt $index 0}},{{end}} {
"id": {{ $index }},
"href": "{{ $page.RelPermalink }}",
"title": {{ (partial "docs/title" $page) | jsonify }},
"section": {{ (partial "docs/title" $page.Parent) | jsonify }},
"content": {{ $page.Plain | jsonify }}
}
{{- end -}}
]

View File

@@ -0,0 +1,104 @@
'use strict';
{{ $searchDataFile := printf "%s.search-data.json" .Language.Lang }}
{{ $searchData := resources.Get "search-data.json" | resources.ExecuteAsTemplate $searchDataFile . | resources.Minify | resources.Fingerprint }}
{{ $searchConfig := i18n "bookSearchConfig" | default "{}" }}
(function () {
const searchDataURL = '{{ $searchData.RelPermalink }}';
const indexConfig = Object.assign({{ $searchConfig }}, {
doc: {
id: 'id',
field: ['title', 'content'],
store: ['title', 'href', 'section']
}
});
const input = document.querySelector('#book-search-input');
const results = document.querySelector('#book-search-results');
if (!input) {
return
}
input.addEventListener('focus', init);
input.addEventListener('keyup', search);
document.addEventListener('keypress', focusSearchFieldOnKeyPress);
/**
* @param {Event} event
*/
function focusSearchFieldOnKeyPress(event) {
if (event.target.value !== undefined) {
return;
}
if (input === document.activeElement) {
return;
}
const characterPressed = String.fromCharCode(event.charCode);
if (!isHotkey(characterPressed)) {
return;
}
input.focus();
event.preventDefault();
}
/**
* @param {String} character
* @returns {Boolean}
*/
function isHotkey(character) {
const dataHotkeys = input.getAttribute('data-hotkeys') || '';
return dataHotkeys.indexOf(character) >= 0;
}
function init() {
input.removeEventListener('focus', init); // init once
input.required = true;
fetch(searchDataURL)
.then(pages => pages.json())
.then(pages => {
window.bookSearchIndex = FlexSearch.create('balance', indexConfig);
window.bookSearchIndex.add(pages);
})
.then(() => input.required = false)
.then(search);
}
function search() {
while (results.firstChild) {
results.removeChild(results.firstChild);
}
if (!input.value) {
return;
}
const searchHits = window.bookSearchIndex.search(input.value, 10);
searchHits.forEach(function (page) {
const li = element('<li><a href></a><small></small></li>');
const a = li.querySelector('a'), small = li.querySelector('small');
a.href = page.href;
a.textContent = page.title;
small.textContent = page.section;
results.appendChild(li);
});
}
/**
* @param {String} content
* @returns {Node}
*/
function element(content) {
const div = document.createElement('div');
div.innerHTML = content;
return div.firstChild;
}
})();

View File

@@ -0,0 +1,7 @@
{{- $swJS := resources.Get "sw.js" | resources.ExecuteAsTemplate "sw.js" . -}}
if (navigator.serviceWorker) {
navigator.serviceWorker.register(
"{{ $swJS.RelPermalink }}",
{ scope: "{{ "/" | relURL }}" }
);
}

View File

@@ -0,0 +1,55 @@
const cacheName = self.location.pathname
const pages = [
{{ if eq .Site.Params.BookServiceWorker "precache" }}
{{ range .Site.AllPages -}}
"{{ .RelPermalink }}",
{{ end -}}
{{ end }}
];
self.addEventListener("install", function (event) {
self.skipWaiting();
caches.open(cacheName).then((cache) => {
return cache.addAll(pages);
});
});
self.addEventListener("fetch", (event) => {
const request = event.request;
if (request.method !== "GET") {
return;
}
/**
* @param {Response} response
* @returns {Promise<Response>}
*/
function saveToCache(response) {
if (cacheable(response)) {
return caches
.open(cacheName)
.then((cache) => cache.put(request, response.clone()))
.then(() => response);
} else {
return response;
}
}
/**
* @param {Error} error
*/
function serveFromCache(error) {
return caches.open(cacheName).then((cache) => cache.match(request.url));
}
/**
* @param {Response} response
* @returns {Boolean}
*/
function cacheable(response) {
return response.type === "basic" && response.ok && !response.headers.has("Content-Disposition")
}
event.respondWith(fetch(request).then(saveToCache).catch(serveFromCache));
});

View File

@@ -0,0 +1,9 @@
:root {
@include theme-light;
}
@media (prefers-color-scheme: dark) {
:root {
@include theme-dark;
}
}

View File

@@ -0,0 +1,3 @@
:root {
@include theme-dark;
}

View File

@@ -0,0 +1,3 @@
:root {
@include theme-light;
}