mirror of
https://github.com/pomerium/pomerium.git
synced 2025-05-10 07:37:33 +02:00
site: fix site on mobile (#597)
Signed-off-by: Bobby DeSimone <bobbydesimone@gmail.com>
This commit is contained in:
parent
8111a3d1b5
commit
ad56322c7e
31 changed files with 233 additions and 2324 deletions
|
@ -1,18 +1,18 @@
|
||||||
// .vuepress/config.js
|
// .vuepress/config.js
|
||||||
module.exports = {
|
module.exports = {
|
||||||
title: "Pomerium",
|
// title: "Pomerium",
|
||||||
description:
|
description:
|
||||||
"Pomerium is a beyond-corp inspired, zero trust, open source identity-aware access proxy.",
|
"Pomerium is a beyond-corp inspired, zero trust, open source identity-aware access proxy.",
|
||||||
plugins: {
|
plugins: {
|
||||||
sitemap: {
|
sitemap: {
|
||||||
hostname: "https://www.pomerium.io"
|
hostname: "https://www.pomerium.io",
|
||||||
},
|
},
|
||||||
"@vuepress/google-analytics": {
|
"@vuepress/google-analytics": {
|
||||||
ga: "UA-129872447-2"
|
ga: "UA-129872447-2",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
markdown: {
|
markdown: {
|
||||||
externalLinkSymbol: false
|
externalLinkSymbol: false,
|
||||||
},
|
},
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
logo: "/logo-long-civez.png",
|
logo: "/logo-long-civez.png",
|
||||||
|
@ -38,13 +38,13 @@ module.exports = {
|
||||||
{ text: "v0.4.x", link: "https://0-4-0.docs.pomerium.io/docs" },
|
{ text: "v0.4.x", link: "https://0-4-0.docs.pomerium.io/docs" },
|
||||||
{ text: "v0.3.x", link: "https://0-3-0.docs.pomerium.io/docs" },
|
{ text: "v0.3.x", link: "https://0-3-0.docs.pomerium.io/docs" },
|
||||||
{ text: "v0.2.x", link: "https://0-2-0.docs.pomerium.io/docs" },
|
{ text: "v0.2.x", link: "https://0-2-0.docs.pomerium.io/docs" },
|
||||||
{ text: "v0.1.x", link: "https://0-1-0.docs.pomerium.io/docs" }
|
{ text: "v0.1.x", link: "https://0-1-0.docs.pomerium.io/docs" },
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
algolia: {
|
algolia: {
|
||||||
apiKey: "1653e881f3a6c17d3ad37f4d4c428e20",
|
apiKey: "1653e881f3a6c17d3ad37f4d4c428e20",
|
||||||
indexName: "pomerium"
|
indexName: "pomerium",
|
||||||
},
|
},
|
||||||
sidebar: {
|
sidebar: {
|
||||||
"/docs/": [
|
"/docs/": [
|
||||||
|
@ -59,8 +59,8 @@ module.exports = {
|
||||||
"releases",
|
"releases",
|
||||||
"upgrading",
|
"upgrading",
|
||||||
"CHANGELOG",
|
"CHANGELOG",
|
||||||
"FAQ"
|
"FAQ",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Quick Start",
|
title: "Quick Start",
|
||||||
|
@ -74,8 +74,8 @@ module.exports = {
|
||||||
"quick-start/helm",
|
"quick-start/helm",
|
||||||
"quick-start/kubernetes",
|
"quick-start/kubernetes",
|
||||||
"quick-start/synology",
|
"quick-start/synology",
|
||||||
"quick-start/from-source"
|
"quick-start/from-source",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Identity Providers",
|
title: "Identity Providers",
|
||||||
|
@ -90,8 +90,8 @@ module.exports = {
|
||||||
"identity-providers/gitlab",
|
"identity-providers/gitlab",
|
||||||
"identity-providers/google",
|
"identity-providers/google",
|
||||||
"identity-providers/okta",
|
"identity-providers/okta",
|
||||||
"identity-providers/one-login"
|
"identity-providers/one-login",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Community",
|
title: "Community",
|
||||||
|
@ -103,8 +103,8 @@ module.exports = {
|
||||||
"community/",
|
"community/",
|
||||||
"community/contributing",
|
"community/contributing",
|
||||||
"community/code-of-conduct",
|
"community/code-of-conduct",
|
||||||
"community/security"
|
"community/security",
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: "Reference",
|
title: "Reference",
|
||||||
|
@ -118,9 +118,9 @@ module.exports = {
|
||||||
"reference/impersonation",
|
"reference/impersonation",
|
||||||
"reference/programmatic-access",
|
"reference/programmatic-access",
|
||||||
"reference/getting-users-identity",
|
"reference/getting-users-identity",
|
||||||
"reference/production-deployment"
|
"reference/production-deployment",
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"/recipes/": [
|
"/recipes/": [
|
||||||
{
|
{
|
||||||
|
@ -129,8 +129,8 @@ module.exports = {
|
||||||
|
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
sidebarDepth: 1,
|
sidebarDepth: 1,
|
||||||
children: ["", "ad-guard", "vs-code-server", "kubernetes"]
|
children: ["", "ad-guard", "vs-code-server", "kubernetes"],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"/enterprise/": [
|
"/enterprise/": [
|
||||||
{
|
{
|
||||||
|
@ -138,8 +138,8 @@ module.exports = {
|
||||||
type: "group",
|
type: "group",
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
sidebarDepth: 1,
|
sidebarDepth: 1,
|
||||||
children: [""]
|
children: [""],
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
"/configuration/": [
|
"/configuration/": [
|
||||||
{
|
{
|
||||||
|
@ -147,9 +147,9 @@ module.exports = {
|
||||||
type: "group",
|
type: "group",
|
||||||
collapsable: false,
|
collapsable: false,
|
||||||
sidebarDepth: 1,
|
sidebarDepth: 1,
|
||||||
children: ["", "examples"]
|
children: ["", "examples"],
|
||||||
}
|
},
|
||||||
]
|
],
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
|
|
74
docs/.vuepress/styles/palette.styl
Normal file
74
docs/.vuepress/styles/palette.styl
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// colors
|
||||||
|
$mainColor= #6E43E8
|
||||||
|
|
||||||
|
|
||||||
|
$sidebarColor=#FAFAFC
|
||||||
|
$accentColor = #6E43E8
|
||||||
|
$textColor =rgb(51, 51, 51)
|
||||||
|
$headerColor=rgb(17, 17, 17)
|
||||||
|
$borderColor = #e8e8fb
|
||||||
|
$codeBgColor = #282c34
|
||||||
|
$arrowBgColor = #ccc
|
||||||
|
$section-color=#f7f7f7;
|
||||||
|
$fontSize = 16px
|
||||||
|
|
||||||
|
// navbar
|
||||||
|
// $navbarHeight = 5.2rem
|
||||||
|
$navbar-vertical-padding = 1.4rem;
|
||||||
|
$navbar-horizontal-padding = 1.4rem;
|
||||||
|
$navbar-background = #6E43E8;
|
||||||
|
$navbar-text-color = #ffffff;
|
||||||
|
|
||||||
|
$sidebarWidth = 16rem
|
||||||
|
$contentWidth = 960px
|
||||||
|
|
||||||
|
// // responsive breakpoints
|
||||||
|
$MQNarrow = 959px
|
||||||
|
$MQMobile = 719px
|
||||||
|
$MQMobileNarrow = 419px
|
||||||
|
|
||||||
|
.icon.outbound
|
||||||
|
display none !important
|
||||||
|
|
||||||
|
.navbar
|
||||||
|
background-color: $navbar-background !important
|
||||||
|
border-bottom 1px solid $navbar-background !important
|
||||||
|
.logo
|
||||||
|
height $navbarHeight - 3.2rem
|
||||||
|
min-width $navbarHeight - 3.2rem
|
||||||
|
margin-right 0.8rem
|
||||||
|
vertical-align top
|
||||||
|
.links
|
||||||
|
background-color: $navbar-background !important
|
||||||
|
color: $navbar-text-color !important
|
||||||
|
padding-left 0rem
|
||||||
|
|
||||||
|
.nav-links
|
||||||
|
a
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
color lighten($textColor, 8%) !important
|
||||||
|
|
||||||
|
@media (min-width: $MQMobile)
|
||||||
|
.nav-links a
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
color lighten($navbar-text-color, 8%) !important
|
||||||
|
.nav-item > a:not(.external)
|
||||||
|
&:hover, &.router-link-active
|
||||||
|
margin-bottom -2px
|
||||||
|
border-bottom 2px solid lighten($navbar-text-color, 8%) !important
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.dropdown-wrapper
|
||||||
|
.dropdown-title
|
||||||
|
color $navbar-text-color !important
|
||||||
|
|
||||||
|
@media (max-width: $MQMobile)
|
||||||
|
.dropdown-wrapper
|
||||||
|
.dropdown-title
|
||||||
|
color $textColor !important
|
||||||
|
|
||||||
|
@media (min-width: $MQMobile)
|
||||||
|
.dropdown-wrapper
|
||||||
|
.dropdown-title
|
||||||
|
color $navbar-text-color !important
|
|
@ -1,213 +0,0 @@
|
||||||
<template>
|
|
||||||
<form id="search-form" class="algolia-search-wrapper search-box" role="search">
|
|
||||||
<input id="algolia-search-input" class="search-query" />
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: ["options"],
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
this.initialize(this.options, this.$lang);
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
initialize(userOptions, lang) {
|
|
||||||
Promise.all([
|
|
||||||
import(
|
|
||||||
/* webpackChunkName: "docsearch" */ "docsearch.js/dist/cdn/docsearch.min.js"
|
|
||||||
),
|
|
||||||
import(
|
|
||||||
/* webpackChunkName: "docsearch" */ "docsearch.js/dist/cdn/docsearch.min.css"
|
|
||||||
)
|
|
||||||
]).then(([docsearch]) => {
|
|
||||||
docsearch = docsearch.default;
|
|
||||||
const { algoliaOptions = {} } = userOptions;
|
|
||||||
docsearch(
|
|
||||||
Object.assign({}, userOptions, {
|
|
||||||
inputSelector: "#algolia-search-input",
|
|
||||||
// #697 Make docsearch work well at i18n mode.
|
|
||||||
algoliaOptions: Object.assign(
|
|
||||||
{
|
|
||||||
facetFilters: [`lang:${lang}`].concat(
|
|
||||||
algoliaOptions.facetFilters || []
|
|
||||||
)
|
|
||||||
},
|
|
||||||
algoliaOptions
|
|
||||||
),
|
|
||||||
handleSelected: (input, event, suggestion) => {
|
|
||||||
const { pathname, hash } = new URL(suggestion.url);
|
|
||||||
this.$router.push(`${pathname}${hash}`);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
update(options, lang) {
|
|
||||||
this.$el.innerHTML =
|
|
||||||
'<input id="algolia-search-input" class="search-query">';
|
|
||||||
this.initialize(options, lang);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
$lang(newValue) {
|
|
||||||
this.update(this.options, newValue);
|
|
||||||
},
|
|
||||||
|
|
||||||
options(newValue) {
|
|
||||||
this.update(newValue, this.$lang);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.algolia-search-wrapper {
|
|
||||||
& > span {
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-autocomplete {
|
|
||||||
line-height: normal;
|
|
||||||
|
|
||||||
.ds-dropdown-menu {
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #999;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 16px;
|
|
||||||
margin: 6px 0 0;
|
|
||||||
padding: 4px;
|
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
border-color: #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
[class*=ds-dataset-] {
|
|
||||||
border: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ds-suggestions {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ds-suggestion {
|
|
||||||
border-bottom: 1px solid $borderColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--highlight {
|
|
||||||
color: #2c815b;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion {
|
|
||||||
border-color: $borderColor;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--category-header {
|
|
||||||
padding: 5px 10px;
|
|
||||||
margin-top: 0;
|
|
||||||
background: $accentColor;
|
|
||||||
color: #fff;
|
|
||||||
font-weight: 600;
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--highlight {
|
|
||||||
background: rgba(255, 255, 255, 0.6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--wrapper {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--title {
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 0;
|
|
||||||
color: $textColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--subcategory-column {
|
|
||||||
vertical-align: top;
|
|
||||||
padding: 5px 7px 5px 5px;
|
|
||||||
border-color: $borderColor;
|
|
||||||
background: #f1f3f5;
|
|
||||||
|
|
||||||
&:after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--subcategory-column-text {
|
|
||||||
color: #555;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-footer {
|
|
||||||
border-color: $borderColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ds-cursor .algolia-docsearch-suggestion--content {
|
|
||||||
background-color: #e7edf3 !important;
|
|
||||||
color: $textColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $MQMobile) {
|
|
||||||
.algolia-search-wrapper {
|
|
||||||
.algolia-autocomplete {
|
|
||||||
.algolia-docsearch-suggestion {
|
|
||||||
.algolia-docsearch-suggestion--subcategory-column {
|
|
||||||
float: none;
|
|
||||||
width: 150px;
|
|
||||||
min-width: 150px;
|
|
||||||
display: table-cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--content {
|
|
||||||
float: none;
|
|
||||||
display: table-cell;
|
|
||||||
width: 100%;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ds-dropdown-menu {
|
|
||||||
min-width: 515px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.algolia-search-wrapper {
|
|
||||||
.ds-dropdown-menu {
|
|
||||||
min-width: calc(100vw - 4rem) !important;
|
|
||||||
max-width: calc(100vw - 4rem) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--wrapper {
|
|
||||||
padding: 5px 7px 5px 5px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--subcategory-column {
|
|
||||||
padding: 0 !important;
|
|
||||||
background: white !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.algolia-docsearch-suggestion--subcategory-column-text:after {
|
|
||||||
content: ' > ';
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 14.4px;
|
|
||||||
display: inline-block;
|
|
||||||
width: 5px;
|
|
||||||
margin: -3px 3px 0;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,208 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="dropdown-wrapper" :class="{ open }">
|
|
||||||
<a class="dropdown-title" @click="toggle">
|
|
||||||
<span class="title">{{ item.text }}</span>
|
|
||||||
<span class="arrow" :class="open ? 'down' : 'right'"></span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<DropdownTransition>
|
|
||||||
<ul class="nav-dropdown" v-show="open">
|
|
||||||
<li
|
|
||||||
class="dropdown-item"
|
|
||||||
:key="subItem.link || index"
|
|
||||||
v-for="(subItem, index) in item.items"
|
|
||||||
>
|
|
||||||
<h4 v-if="subItem.type === 'links'">{{ subItem.text }}</h4>
|
|
||||||
|
|
||||||
<ul class="dropdown-subitem-wrapper" v-if="subItem.type === 'links'">
|
|
||||||
<li
|
|
||||||
class="dropdown-subitem"
|
|
||||||
:key="childSubItem.link"
|
|
||||||
v-for="childSubItem in subItem.items"
|
|
||||||
>
|
|
||||||
<NavLink :item="childSubItem" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
<NavLink v-else :item="subItem" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</DropdownTransition>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import NavLink from "@theme/components/NavLink.vue";
|
|
||||||
import DropdownTransition from "@theme/components/DropdownTransition.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { NavLink, DropdownTransition },
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
open: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
item: {
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
toggle() {
|
|
||||||
this.open = !this.open;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.dropdown-wrapper {
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.dropdown-title {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-top: -1px;
|
|
||||||
margin-left: 0.4rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-dropdown {
|
|
||||||
.dropdown-item {
|
|
||||||
color: inherit;
|
|
||||||
line-height: 1.7rem;
|
|
||||||
|
|
||||||
h4 {
|
|
||||||
margin: 0.45rem 0 0;
|
|
||||||
border-top: 1px solid #eee;
|
|
||||||
padding: 0.45rem 1.5rem 0 1.25rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-subitem-wrapper {
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
.dropdown-subitem {
|
|
||||||
font-size: 0.9em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: block;
|
|
||||||
line-height: 1.7rem;
|
|
||||||
position: relative;
|
|
||||||
border-bottom: none;
|
|
||||||
font-weight: 400;
|
|
||||||
margin-bottom: 0;
|
|
||||||
padding: 0 1.5rem 0 1.25rem;
|
|
||||||
color: $accentColor;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $accentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.router-link-active {
|
|
||||||
color: $accentColor;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
width: 0;
|
|
||||||
height: 0;
|
|
||||||
border-left: 5px solid $accentColor;
|
|
||||||
border-top: 3px solid transparent;
|
|
||||||
border-bottom: 3px solid transparent;
|
|
||||||
position: absolute;
|
|
||||||
top: calc(50% - 2px);
|
|
||||||
left: 9px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child h4 {
|
|
||||||
margin-top: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
border-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.dropdown-wrapper {
|
|
||||||
&.open .dropdown-title {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-dropdown {
|
|
||||||
transition: height 0.1s ease-out;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.dropdown-item {
|
|
||||||
h4 {
|
|
||||||
border-top: 0;
|
|
||||||
margin-top: 0;
|
|
||||||
padding-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4, & > a {
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-subitem {
|
|
||||||
font-size: 14px;
|
|
||||||
padding-left: 1rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $MQMobile) {
|
|
||||||
.dropdown-wrapper {
|
|
||||||
height: 1.8rem;
|
|
||||||
|
|
||||||
&:hover .nav-dropdown {
|
|
||||||
// override the inline style.
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-title .arrow {
|
|
||||||
// make the arrow always down at desktop
|
|
||||||
border-left: 4px solid transparent;
|
|
||||||
border-right: 4px solid transparent;
|
|
||||||
border-top: 6px solid $arrowBgColor;
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-dropdown {
|
|
||||||
display: none;
|
|
||||||
// Avoid height shaked by clicking
|
|
||||||
height: auto !important;
|
|
||||||
box-sizing: border-box;
|
|
||||||
max-height: calc(100vh - 2.7rem);
|
|
||||||
overflow-y: auto;
|
|
||||||
position: absolute;
|
|
||||||
top: 100%;
|
|
||||||
right: 0;
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 0.6rem 0;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-bottom-color: #ccc;
|
|
||||||
text-align: left;
|
|
||||||
border-radius: 0.25rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,33 +0,0 @@
|
||||||
<template>
|
|
||||||
<transition
|
|
||||||
name="dropdown"
|
|
||||||
@enter="setHeight"
|
|
||||||
@after-enter="unsetHeight"
|
|
||||||
@before-leave="setHeight"
|
|
||||||
>
|
|
||||||
<slot/>
|
|
||||||
</transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: 'DropdownTransition',
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
setHeight (items) {
|
|
||||||
// explicitly set height so that it can be transitioned
|
|
||||||
items.style.height = items.scrollHeight + 'px'
|
|
||||||
},
|
|
||||||
|
|
||||||
unsetHeight (items) {
|
|
||||||
items.style.height = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.dropdown-enter, .dropdown-leave-to
|
|
||||||
height 0 !important
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -109,7 +109,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NavLink from "@theme/components/NavLink.vue";
|
import NavLink from "@parent-theme/components/NavLink.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: { NavLink },
|
components: { NavLink },
|
||||||
|
@ -122,10 +122,10 @@ export default {
|
||||||
actionLink() {
|
actionLink() {
|
||||||
return {
|
return {
|
||||||
link: this.data.actionLink,
|
link: this.data.actionLink,
|
||||||
text: this.data.actionText
|
text: this.data.actionText,
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
<template>
|
|
||||||
<router-link class="nav-link" :to="link" v-if="!isExternal(link)" :exact="exact">{{ item.text }}</router-link>
|
|
||||||
<a
|
|
||||||
v-else
|
|
||||||
:href="link"
|
|
||||||
class="nav-link external"
|
|
||||||
:target="isMailto(link) || isTel(link) ? null : '_blank'"
|
|
||||||
:rel="isMailto(link) || isTel(link) ? null : 'noopener noreferrer'"
|
|
||||||
>
|
|
||||||
{{ item.text }}
|
|
||||||
<OutboundLink />
|
|
||||||
</a>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { isExternal, isMailto, isTel, ensureExt } from "../util";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
item: {
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
link() {
|
|
||||||
return ensureExt(this.item.link);
|
|
||||||
},
|
|
||||||
|
|
||||||
exact() {
|
|
||||||
if (this.$site.locales) {
|
|
||||||
return Object.keys(this.$site.locales).some(
|
|
||||||
rootLink => rootLink === this.link
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.link === "/";
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
isExternal,
|
|
||||||
isMailto,
|
|
||||||
isTel
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
|
@ -1,119 +0,0 @@
|
||||||
<template>
|
|
||||||
<nav class="nav-links" v-if="userLinks.length || repoLink">
|
|
||||||
<!-- user links -->
|
|
||||||
<div class="nav-item" v-for="item in userLinks" :key="item.link">
|
|
||||||
<DropdownLink v-if="item.type === 'links'" :item="item" />
|
|
||||||
<NavLink v-else :item="item" />
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DropdownLink from "@theme/components/DropdownLink.vue";
|
|
||||||
import { resolveNavLinkItem } from "../util";
|
|
||||||
import NavLink from "@theme/components/NavLink.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { NavLink, DropdownLink },
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
userNav() {
|
|
||||||
return this.$themeLocaleConfig.nav || this.$site.themeConfig.nav || [];
|
|
||||||
},
|
|
||||||
|
|
||||||
nav() {
|
|
||||||
const { locales } = this.$site;
|
|
||||||
if (locales && Object.keys(locales).length > 1) {
|
|
||||||
const currentLink = this.$page.path;
|
|
||||||
const routes = this.$router.options.routes;
|
|
||||||
const themeLocales = this.$site.themeConfig.locales || {};
|
|
||||||
const languageDropdown = {
|
|
||||||
text: this.$themeLocaleConfig.selectText || "Languages",
|
|
||||||
items: Object.keys(locales).map(path => {
|
|
||||||
const locale = locales[path];
|
|
||||||
const text =
|
|
||||||
(themeLocales[path] && themeLocales[path].label) || locale.lang;
|
|
||||||
let link;
|
|
||||||
// Stay on the current page
|
|
||||||
if (locale.lang === this.$lang) {
|
|
||||||
link = currentLink;
|
|
||||||
} else {
|
|
||||||
// Try to stay on the same page
|
|
||||||
link = currentLink.replace(this.$localeConfig.path, path);
|
|
||||||
// fallback to homepage
|
|
||||||
if (!routes.some(route => route.path === link)) {
|
|
||||||
link = path;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return { text, link };
|
|
||||||
})
|
|
||||||
};
|
|
||||||
return [...this.userNav, languageDropdown];
|
|
||||||
}
|
|
||||||
return this.userNav;
|
|
||||||
},
|
|
||||||
|
|
||||||
userLinks() {
|
|
||||||
return (this.nav || []).map(link => {
|
|
||||||
return Object.assign(resolveNavLinkItem(link), {
|
|
||||||
items: (link.items || []).map(resolveNavLinkItem)
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.nav-links {
|
|
||||||
display: inline-block;
|
|
||||||
color: $navbar-text-color;
|
|
||||||
|
|
||||||
a {
|
|
||||||
line-height: 1.4rem;
|
|
||||||
color: $navbar-text-color;
|
|
||||||
|
|
||||||
&:hover, &.router-link-active {
|
|
||||||
color: $navbar-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item {
|
|
||||||
position: relative;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
line-height: 2rem;
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.repo-link {
|
|
||||||
margin-left: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.nav-links {
|
|
||||||
.nav-item, .repo-link {
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: $MQMobile) {
|
|
||||||
.nav-links a {
|
|
||||||
&:hover, &.router-link-active {
|
|
||||||
color: $navbar-text-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item > a:not(.external) {
|
|
||||||
&:hover, &.router-link-active {
|
|
||||||
margin-bottom: -2px;
|
|
||||||
border-bottom: 2px solid darken($navbar-text-color, 15%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,142 +0,0 @@
|
||||||
<template>
|
|
||||||
<header class="navbar">
|
|
||||||
<SidebarButton @toggle-sidebar="$emit('toggle-sidebar')" />
|
|
||||||
|
|
||||||
<router-link :to="$localePath" class="home-link">
|
|
||||||
<img
|
|
||||||
class="logo"
|
|
||||||
v-if="$site.themeConfig.logo"
|
|
||||||
:src="$withBase($site.themeConfig.logo)"
|
|
||||||
:alt="$siteTitle"
|
|
||||||
/>
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="links"
|
|
||||||
:style="linksWrapMaxWidth ? {
|
|
||||||
'max-width': linksWrapMaxWidth + 'px'
|
|
||||||
} : {}"
|
|
||||||
>
|
|
||||||
<NavLinks class="can-hide" />
|
|
||||||
<AlgoliaSearchBox v-if="isAlgoliaSearch" :options="algolia" />
|
|
||||||
<SearchBox
|
|
||||||
v-else-if="$site.themeConfig.search !== false && $page.frontmatter.search !== false"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AlgoliaSearchBox from "@AlgoliaSearchBox";
|
|
||||||
import SearchBox from "@SearchBox";
|
|
||||||
import SidebarButton from "@theme/components/SidebarButton.vue";
|
|
||||||
import NavLinks from "@theme/components/NavLinks.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
linksWrapMaxWidth: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
const MOBILE_DESKTOP_BREAKPOINT = 719; // refer to config.styl
|
|
||||||
const NAVBAR_VERTICAL_PADDING =
|
|
||||||
parseInt(css(this.$el, "paddingLeft")) +
|
|
||||||
parseInt(css(this.$el, "paddingRight"));
|
|
||||||
const handleLinksWrapWidth = () => {
|
|
||||||
if (document.documentElement.clientWidth < MOBILE_DESKTOP_BREAKPOINT) {
|
|
||||||
this.linksWrapMaxWidth = null;
|
|
||||||
} else {
|
|
||||||
this.linksWrapMaxWidth =
|
|
||||||
this.$el.offsetWidth -
|
|
||||||
NAVBAR_VERTICAL_PADDING -
|
|
||||||
((this.$refs.siteName && this.$refs.siteName.offsetWidth) || 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
handleLinksWrapWidth();
|
|
||||||
window.addEventListener("resize", handleLinksWrapWidth, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
algolia() {
|
|
||||||
return (
|
|
||||||
this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
isAlgoliaSearch() {
|
|
||||||
return this.algolia && this.algolia.apiKey && this.algolia.indexName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function css(el, property) {
|
|
||||||
// NOTE: Known bug, will return 'auto' if style value is 'auto'
|
|
||||||
const win = el.ownerDocument.defaultView;
|
|
||||||
// null means not to return pseudo styles
|
|
||||||
return win.getComputedStyle(el, null)[property];
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
$navbar-vertical-padding = 0.7rem;
|
|
||||||
$navbar-horizontal-padding = 1.5rem;
|
|
||||||
|
|
||||||
.navbar {
|
|
||||||
padding: $navbar-vertical-padding $navbar-horizontal-padding;
|
|
||||||
line-height: $navbarHeight - 1.4rem;
|
|
||||||
background: $navbar-background;
|
|
||||||
|
|
||||||
a, span, img {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.logo {
|
|
||||||
height: $navbarHeight - 3.1rem;
|
|
||||||
margin-right: 0.2rem;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.site-name {
|
|
||||||
font-size: 1.3rem;
|
|
||||||
font-weight: 600;
|
|
||||||
color: $textColor;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links {
|
|
||||||
// padding-left: 1.5rem;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: $navbar-background;
|
|
||||||
white-space: nowrap;
|
|
||||||
font-size: 0.95rem;
|
|
||||||
position: absolute;
|
|
||||||
right: $navbar-horizontal-padding;
|
|
||||||
top: $navbar-vertical-padding;
|
|
||||||
display: flex;
|
|
||||||
|
|
||||||
.search-box {
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.navbar {
|
|
||||||
padding-left: 4rem;
|
|
||||||
|
|
||||||
.can-hide {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.links {
|
|
||||||
padding-left: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,241 +0,0 @@
|
||||||
<template>
|
|
||||||
<main class="page">
|
|
||||||
<slot name="top" />
|
|
||||||
|
|
||||||
<Content class="theme-default-content" />
|
|
||||||
|
|
||||||
<footer class="page-edit">
|
|
||||||
<div class="edit-link" v-if="editLink">
|
|
||||||
<a :href="editLink" target="_blank" rel="noopener noreferrer">{{ editLinkText }}</a>
|
|
||||||
<OutboundLink />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="last-updated" v-if="lastUpdated">
|
|
||||||
<span class="prefix">{{ lastUpdatedText }}:</span>
|
|
||||||
<span class="time">{{ lastUpdated }}</span>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<div class="page-nav" v-if="prev || next">
|
|
||||||
<p class="inner">
|
|
||||||
<span v-if="prev" class="prev">
|
|
||||||
←
|
|
||||||
<router-link v-if="prev" class="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<span v-if="next" class="next">
|
|
||||||
<router-link v-if="next" :to="next.path">{{ next.title || next.path }}</router-link>→
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<slot name="bottom" />
|
|
||||||
</main>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { resolvePage, outboundRE, endingSlashRE } from "../util";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
props: ["sidebarItems"],
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
lastUpdated() {
|
|
||||||
return this.$page.lastUpdated;
|
|
||||||
},
|
|
||||||
|
|
||||||
lastUpdatedText() {
|
|
||||||
if (typeof this.$themeLocaleConfig.lastUpdated === "string") {
|
|
||||||
return this.$themeLocaleConfig.lastUpdated;
|
|
||||||
}
|
|
||||||
if (typeof this.$site.themeConfig.lastUpdated === "string") {
|
|
||||||
return this.$site.themeConfig.lastUpdated;
|
|
||||||
}
|
|
||||||
return "Last Updated";
|
|
||||||
},
|
|
||||||
|
|
||||||
prev() {
|
|
||||||
const prev = this.$page.frontmatter.prev;
|
|
||||||
if (prev === false) {
|
|
||||||
return;
|
|
||||||
} else if (prev) {
|
|
||||||
return resolvePage(this.$site.pages, prev, this.$route.path);
|
|
||||||
} else {
|
|
||||||
return resolvePrev(this.$page, this.sidebarItems);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
next() {
|
|
||||||
const next = this.$page.frontmatter.next;
|
|
||||||
if (next === false) {
|
|
||||||
return;
|
|
||||||
} else if (next) {
|
|
||||||
return resolvePage(this.$site.pages, next, this.$route.path);
|
|
||||||
} else {
|
|
||||||
return resolveNext(this.$page, this.sidebarItems);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
editLink() {
|
|
||||||
if (this.$page.frontmatter.editLink === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
repo,
|
|
||||||
editLinks,
|
|
||||||
docsDir = "",
|
|
||||||
docsBranch = "master",
|
|
||||||
docsRepo = repo
|
|
||||||
} = this.$site.themeConfig;
|
|
||||||
|
|
||||||
if (docsRepo && editLinks && this.$page.relativePath) {
|
|
||||||
return this.createEditLink(
|
|
||||||
repo,
|
|
||||||
docsRepo,
|
|
||||||
docsDir,
|
|
||||||
docsBranch,
|
|
||||||
this.$page.relativePath
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
editLinkText() {
|
|
||||||
return (
|
|
||||||
this.$themeLocaleConfig.editLinkText ||
|
|
||||||
this.$site.themeConfig.editLinkText ||
|
|
||||||
`Edit this page`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
createEditLink(repo, docsRepo, docsDir, docsBranch, path) {
|
|
||||||
const bitbucket = /bitbucket.org/;
|
|
||||||
if (bitbucket.test(repo)) {
|
|
||||||
const base = outboundRE.test(docsRepo) ? docsRepo : repo;
|
|
||||||
return (
|
|
||||||
base.replace(endingSlashRE, "") +
|
|
||||||
`/src` +
|
|
||||||
`/${docsBranch}/` +
|
|
||||||
(docsDir ? docsDir.replace(endingSlashRE, "") + "/" : "") +
|
|
||||||
path +
|
|
||||||
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const base = outboundRE.test(docsRepo)
|
|
||||||
? docsRepo
|
|
||||||
: `https://github.com/${docsRepo}`;
|
|
||||||
return (
|
|
||||||
base.replace(endingSlashRE, "") +
|
|
||||||
`/edit` +
|
|
||||||
`/${docsBranch}/` +
|
|
||||||
(docsDir ? docsDir.replace(endingSlashRE, "") + "/" : "") +
|
|
||||||
path
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function resolvePrev(page, items) {
|
|
||||||
return find(page, items, -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function resolveNext(page, items) {
|
|
||||||
return find(page, items, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
function find(page, items, offset) {
|
|
||||||
const res = [];
|
|
||||||
flatten(items, res);
|
|
||||||
for (let i = 0; i < res.length; i++) {
|
|
||||||
const cur = res[i];
|
|
||||||
if (cur.type === "page" && cur.path === decodeURIComponent(page.path)) {
|
|
||||||
return res[i + offset];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function flatten(items, res) {
|
|
||||||
for (let i = 0, l = items.length; i < l; i++) {
|
|
||||||
if (items[i].type === "group") {
|
|
||||||
flatten(items[i].children || [], res);
|
|
||||||
} else {
|
|
||||||
res.push(items[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
@require '../styles/wrapper.styl';
|
|
||||||
|
|
||||||
.page {
|
|
||||||
padding-bottom: 2rem;
|
|
||||||
display: block;
|
|
||||||
background: rgba(255, 255, 255, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-edit {
|
|
||||||
@extend $wrapper;
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
.edit-link {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: lighten($textColor, 25%);
|
|
||||||
margin-right: 0.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-updated {
|
|
||||||
float: right;
|
|
||||||
font-size: 0.9em;
|
|
||||||
|
|
||||||
.prefix {
|
|
||||||
font-weight: 500;
|
|
||||||
color: lighten($textColor, 25%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.time {
|
|
||||||
font-weight: 400;
|
|
||||||
color: #aaa;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-nav {
|
|
||||||
@extend $wrapper;
|
|
||||||
padding-top: 1rem;
|
|
||||||
padding-bottom: 0;
|
|
||||||
|
|
||||||
.inner {
|
|
||||||
min-height: 2rem;
|
|
||||||
margin-top: 0;
|
|
||||||
border-top: 1px solid $borderColor;
|
|
||||||
padding-top: 1rem;
|
|
||||||
overflow: auto; // clear float
|
|
||||||
}
|
|
||||||
|
|
||||||
.next {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.page-edit {
|
|
||||||
.edit-link {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.last-updated {
|
|
||||||
font-size: 0.8em;
|
|
||||||
float: none;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,92 +0,0 @@
|
||||||
<template>
|
|
||||||
<aside class="sidebar">
|
|
||||||
<NavLinks />
|
|
||||||
<slot name="top" />
|
|
||||||
<SidebarLinks :depth="0" :items="items" />
|
|
||||||
<slot name="bottom" />
|
|
||||||
</aside>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import SidebarLinks from "@theme/components/SidebarLinks.vue";
|
|
||||||
import NavLinks from "@theme/components/NavLinks.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "Sidebar",
|
|
||||||
|
|
||||||
components: { SidebarLinks, NavLinks },
|
|
||||||
|
|
||||||
props: ["items"]
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.sidebar {
|
|
||||||
background-color: $sidebarColor;
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
display: none;
|
|
||||||
border-bottom: 1px solid $borderColor;
|
|
||||||
padding: 0.5rem 0 0.75rem 0;
|
|
||||||
|
|
||||||
a {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-item, .repo-link {
|
|
||||||
display: block;
|
|
||||||
line-height: 1.15rem;
|
|
||||||
font-size: 1.1em;
|
|
||||||
padding: 0.5rem 0 0.5rem 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .sidebar-links {
|
|
||||||
padding: 1.5rem 0;
|
|
||||||
|
|
||||||
& > li > a.sidebar-link {
|
|
||||||
font-size: 1.1em;
|
|
||||||
line-height: 1.3;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > li:not(:first-child) {
|
|
||||||
margin-top: 0.75rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobileNarrow) {
|
|
||||||
.sidebar {
|
|
||||||
background-color: #6E43E8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.sidebar {
|
|
||||||
background-color: #6E43E8;
|
|
||||||
|
|
||||||
.nav-links {
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active::after {
|
|
||||||
top: calc(1rem - 2px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .sidebar-links {
|
|
||||||
padding: 1rem 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,42 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="sidebar-button" @click="$emit('toggle-sidebar')">
|
|
||||||
<svg
|
|
||||||
class="icon"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
aria-hidden="true"
|
|
||||||
role="img"
|
|
||||||
viewBox="0 0 448 512"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
fill="currentColor"
|
|
||||||
d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"
|
|
||||||
class
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.sidebar-button {
|
|
||||||
cursor: pointer;
|
|
||||||
display: none;
|
|
||||||
width: 1.25rem;
|
|
||||||
height: 1.25rem;
|
|
||||||
position: absolute;
|
|
||||||
padding: 0.6rem;
|
|
||||||
top: 0.6rem;
|
|
||||||
left: 1rem;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
display: block;
|
|
||||||
width: 1.25rem;
|
|
||||||
height: 1.25rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: $MQMobile) {
|
|
||||||
.sidebar-button {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,136 +0,0 @@
|
||||||
<template>
|
|
||||||
<section
|
|
||||||
class="sidebar-group"
|
|
||||||
:class="[
|
|
||||||
{
|
|
||||||
collapsable,
|
|
||||||
'is-sub-group': depth !== 0
|
|
||||||
},
|
|
||||||
`depth-${depth}`
|
|
||||||
]"
|
|
||||||
>
|
|
||||||
<router-link
|
|
||||||
v-if="item.path"
|
|
||||||
class="sidebar-heading clickable"
|
|
||||||
:class="{
|
|
||||||
open,
|
|
||||||
'active': isActive($route, item.path)
|
|
||||||
}"
|
|
||||||
:to="item.path"
|
|
||||||
@click.native="$emit('toggle')"
|
|
||||||
>
|
|
||||||
<span>{{ item.title }}</span>
|
|
||||||
<span class="arrow" v-if="collapsable" :class="open ? 'down' : 'right'"></span>
|
|
||||||
</router-link>
|
|
||||||
|
|
||||||
<p v-else class="sidebar-heading" :class="{ open }" @click="$emit('toggle')">
|
|
||||||
<span>{{ item.title }}</span>
|
|
||||||
<span class="arrow" v-if="collapsable" :class="open ? 'down' : 'right'"></span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<DropdownTransition>
|
|
||||||
<SidebarLinks
|
|
||||||
class="sidebar-group-items"
|
|
||||||
:items="item.children"
|
|
||||||
v-if="open || !collapsable"
|
|
||||||
:sidebarDepth="item.sidebarDepth"
|
|
||||||
:depth="depth + 1"
|
|
||||||
/>
|
|
||||||
</DropdownTransition>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { isActive } from "../util";
|
|
||||||
import DropdownTransition from "@theme/components/DropdownTransition.vue";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "SidebarGroup",
|
|
||||||
props: ["item", "open", "collapsable", "depth"],
|
|
||||||
components: { DropdownTransition },
|
|
||||||
// ref: https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components
|
|
||||||
beforeCreate() {
|
|
||||||
this.$options.components.SidebarLinks = require("./SidebarLinks.vue").default;
|
|
||||||
},
|
|
||||||
methods: { isActive }
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.sidebar-group {
|
|
||||||
.sidebar-group {
|
|
||||||
padding-left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(.collapsable) {
|
|
||||||
.sidebar-heading:not(.clickable) {
|
|
||||||
cursor: auto;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// refine styles of nested sidebar groups
|
|
||||||
&.is-sub-group {
|
|
||||||
padding-left: 0;
|
|
||||||
|
|
||||||
& > .sidebar-heading {
|
|
||||||
font-size: 0.95em;
|
|
||||||
line-height: 1.4;
|
|
||||||
font-weight: normal;
|
|
||||||
padding-left: 2rem;
|
|
||||||
|
|
||||||
&:not(.clickable) {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > .sidebar-group-items {
|
|
||||||
padding-left: 1rem;
|
|
||||||
|
|
||||||
& > li > .sidebar-link {
|
|
||||||
font-size: 0.95em;
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.depth-2 {
|
|
||||||
& > .sidebar-heading {
|
|
||||||
border-left: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-heading {
|
|
||||||
color: lighten($textColor, 50%);
|
|
||||||
transition: color 0.15s ease;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 1em;
|
|
||||||
font-weight: 600;
|
|
||||||
text-transform: uppercase;
|
|
||||||
// text-transform uppercase
|
|
||||||
padding: 0.35rem 1.5rem 0.35rem 1.25rem;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
border-left: 0.25rem solid transparent;
|
|
||||||
|
|
||||||
.arrow {
|
|
||||||
position: relative;
|
|
||||||
top: -0.12em;
|
|
||||||
left: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.clickable {
|
|
||||||
&:hover {
|
|
||||||
color: $accentColor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-group-items {
|
|
||||||
transition: height 0.1s ease-out;
|
|
||||||
font-size: 0.95em;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,153 +0,0 @@
|
||||||
<script>
|
|
||||||
import { isActive, hashRE, groupHeaders } from "../util";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
functional: true,
|
|
||||||
|
|
||||||
props: ["item", "sidebarDepth"],
|
|
||||||
|
|
||||||
render(
|
|
||||||
h,
|
|
||||||
{
|
|
||||||
parent: { $page, $site, $route, $themeConfig, $themeLocaleConfig },
|
|
||||||
props: { item, sidebarDepth }
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
// use custom active class matching logic
|
|
||||||
// due to edge case of paths ending with / + hash
|
|
||||||
const selfActive = isActive($route, item.path);
|
|
||||||
// for sidebar: auto pages, a hash link should be active if one of its child
|
|
||||||
// matches
|
|
||||||
const active =
|
|
||||||
item.type === "auto"
|
|
||||||
? selfActive ||
|
|
||||||
item.children.some(c =>
|
|
||||||
isActive($route, item.basePath + "#" + c.slug)
|
|
||||||
)
|
|
||||||
: selfActive;
|
|
||||||
const link =
|
|
||||||
item.type === "external"
|
|
||||||
? renderExternal(h, item.path, item.title || item.path)
|
|
||||||
: renderLink(h, item.path, item.title || item.path, active);
|
|
||||||
|
|
||||||
const configDepth =
|
|
||||||
$page.frontmatter.sidebarDepth ||
|
|
||||||
sidebarDepth ||
|
|
||||||
$themeLocaleConfig.sidebarDepth ||
|
|
||||||
$themeConfig.sidebarDepth;
|
|
||||||
|
|
||||||
const maxDepth = configDepth == null ? 1 : configDepth;
|
|
||||||
|
|
||||||
const displayAllHeaders =
|
|
||||||
$themeLocaleConfig.displayAllHeaders || $themeConfig.displayAllHeaders;
|
|
||||||
|
|
||||||
if (item.type === "auto") {
|
|
||||||
return [
|
|
||||||
link,
|
|
||||||
renderChildren(h, item.children, item.basePath, $route, maxDepth)
|
|
||||||
];
|
|
||||||
} else if (
|
|
||||||
(active || displayAllHeaders) &&
|
|
||||||
item.headers &&
|
|
||||||
!hashRE.test(item.path)
|
|
||||||
) {
|
|
||||||
const children = groupHeaders(item.headers);
|
|
||||||
return [link, renderChildren(h, children, item.path, $route, maxDepth)];
|
|
||||||
} else {
|
|
||||||
return link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function renderLink(h, to, text, active) {
|
|
||||||
return h(
|
|
||||||
"router-link",
|
|
||||||
{
|
|
||||||
props: {
|
|
||||||
to,
|
|
||||||
activeClass: "",
|
|
||||||
exactActiveClass: ""
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
active,
|
|
||||||
"sidebar-link": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
text
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderChildren(h, children, path, route, maxDepth, depth = 1) {
|
|
||||||
if (!children || depth > maxDepth) return null;
|
|
||||||
return h(
|
|
||||||
"ul",
|
|
||||||
{ class: "sidebar-sub-headers" },
|
|
||||||
children.map(c => {
|
|
||||||
const active = isActive(route, path + "#" + c.slug);
|
|
||||||
return h("li", { class: "sidebar-sub-header" }, [
|
|
||||||
renderLink(h, path + "#" + c.slug, c.title, active),
|
|
||||||
renderChildren(h, c.children, path, route, maxDepth, depth + 1)
|
|
||||||
]);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderExternal(h, to, text) {
|
|
||||||
return h(
|
|
||||||
"a",
|
|
||||||
{
|
|
||||||
attrs: {
|
|
||||||
href: to,
|
|
||||||
target: "_blank",
|
|
||||||
rel: "noopener noreferrer"
|
|
||||||
},
|
|
||||||
class: {
|
|
||||||
"sidebar-link": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[text, h("OutboundLink")]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus">
|
|
||||||
.sidebar .sidebar-sub-headers {
|
|
||||||
padding-left: 1rem;
|
|
||||||
font-size: 0.95em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.sidebar-link {
|
|
||||||
// font-size: 0.95em;
|
|
||||||
font-weight: 400;
|
|
||||||
display: inline-block;
|
|
||||||
color: $textColor;
|
|
||||||
border-left: 0.25rem solid transparent;
|
|
||||||
padding: 0.35rem 1rem 0.35rem 1.25rem;
|
|
||||||
line-height: 1.3;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $accentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
font-weight: 600;
|
|
||||||
color: $accentColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-group & {
|
|
||||||
padding-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebar-sub-headers & {
|
|
||||||
padding-top: 0.25rem;
|
|
||||||
padding-bottom: 0.25rem;
|
|
||||||
border-left: none;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,79 +0,0 @@
|
||||||
<template>
|
|
||||||
<ul class="sidebar-links" v-if="items.length">
|
|
||||||
<li v-for="(item, i) in items" :key="i">
|
|
||||||
<SidebarGroup
|
|
||||||
v-if="item.type === 'group'"
|
|
||||||
:item="item"
|
|
||||||
:open="i === openGroupIndex"
|
|
||||||
:collapsable="item.collapsable || item.collapsible"
|
|
||||||
:depth="depth"
|
|
||||||
@toggle="toggleGroup(i)"
|
|
||||||
/>
|
|
||||||
<SidebarLink v-else :sidebarDepth="sidebarDepth" :item="item" />
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import SidebarGroup from "@theme/components/SidebarGroup.vue";
|
|
||||||
import SidebarLink from "@theme/components/SidebarLink.vue";
|
|
||||||
import { isActive } from "../util";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "SidebarLinks",
|
|
||||||
|
|
||||||
components: { SidebarGroup, SidebarLink },
|
|
||||||
|
|
||||||
props: [
|
|
||||||
"items",
|
|
||||||
"depth", // depth of current sidebar links
|
|
||||||
"sidebarDepth" // depth of headers to be extracted
|
|
||||||
],
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
openGroupIndex: 0
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.refreshIndex();
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
$route() {
|
|
||||||
this.refreshIndex();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
refreshIndex() {
|
|
||||||
const index = resolveOpenGroupIndex(this.$route, this.items);
|
|
||||||
if (index > -1) {
|
|
||||||
this.openGroupIndex = index;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleGroup(index) {
|
|
||||||
this.openGroupIndex = index === this.openGroupIndex ? -1 : index;
|
|
||||||
},
|
|
||||||
|
|
||||||
isActive(page) {
|
|
||||||
return isActive(this.$route, page.regularPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
function resolveOpenGroupIndex(route, items) {
|
|
||||||
for (let i = 0; i < items.length; i++) {
|
|
||||||
const item = items[i];
|
|
||||||
if (
|
|
||||||
item.type === "group" &&
|
|
||||||
item.children.some(c => c.type === "page" && isActive(route, c.path))
|
|
||||||
) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,57 +0,0 @@
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
functional: true,
|
|
||||||
props: {
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: "tip"
|
|
||||||
},
|
|
||||||
text: String,
|
|
||||||
vertical: {
|
|
||||||
type: String,
|
|
||||||
default: "top"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
render(h, { props, slots }) {
|
|
||||||
return h(
|
|
||||||
"span",
|
|
||||||
{
|
|
||||||
class: ["badge", props.type],
|
|
||||||
style: {
|
|
||||||
verticalAlign: props.vertical
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props.text || slots().default
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.badge {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 14px;
|
|
||||||
height: 18px;
|
|
||||||
line-height: 18px;
|
|
||||||
border-radius: 3px;
|
|
||||||
padding: 0 6px;
|
|
||||||
color: white;
|
|
||||||
background-color: #42b983;
|
|
||||||
|
|
||||||
&.tip, &.green {
|
|
||||||
background-color: #42b983;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
background-color: #DA5961; // #f66
|
|
||||||
}
|
|
||||||
|
|
||||||
&.warning, &.warn, &.yellow {
|
|
||||||
background-color: darken(#ffe564, 35%);
|
|
||||||
}
|
|
||||||
|
|
||||||
& + & {
|
|
||||||
margin-left: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,52 +1,3 @@
|
||||||
const path = require("path");
|
module.exports = {
|
||||||
|
extend: '@vuepress/theme-default'
|
||||||
// Theme API.
|
}
|
||||||
module.exports = (options, ctx) => ({
|
|
||||||
alias() {
|
|
||||||
const { themeConfig, siteConfig } = ctx;
|
|
||||||
// resolve algolia
|
|
||||||
const isAlgoliaSearch =
|
|
||||||
themeConfig.algolia ||
|
|
||||||
Object.keys((siteConfig.locales && themeConfig.locales) || {}).some(
|
|
||||||
base => themeConfig.locales[base].algolia
|
|
||||||
);
|
|
||||||
return {
|
|
||||||
"@AlgoliaSearchBox": isAlgoliaSearch
|
|
||||||
? path.resolve(__dirname, "components/AlgoliaSearchBox.vue")
|
|
||||||
: path.resolve(__dirname, "noopModule.js")
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
plugins: [
|
|
||||||
["@vuepress/active-header-links", options.activeHeaderLinks],
|
|
||||||
"@vuepress/search",
|
|
||||||
"@vuepress/plugin-nprogress",
|
|
||||||
[
|
|
||||||
"container",
|
|
||||||
{
|
|
||||||
type: "tip",
|
|
||||||
defaultTitle: {
|
|
||||||
"/zh/": "提示"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"container",
|
|
||||||
{
|
|
||||||
type: "warning",
|
|
||||||
defaultTitle: {
|
|
||||||
"/zh/": "注意"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"container",
|
|
||||||
{
|
|
||||||
type: "danger",
|
|
||||||
defaultTitle: {
|
|
||||||
"/zh/": "警告"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="theme-container">
|
|
||||||
<div class="theme-default-content">
|
|
||||||
<h1>404</h1>
|
|
||||||
<blockquote>{{ getMsg() }}</blockquote>
|
|
||||||
<router-link to="/">Take me home.</router-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const msgs = [
|
|
||||||
`There's nothing here.`,
|
|
||||||
`How did we get here?`,
|
|
||||||
`That's a Four-Oh-Four.`,
|
|
||||||
`Looks like we've got some broken links.`
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
|
||||||
methods: {
|
|
||||||
getMsg() {
|
|
||||||
return msgs[Math.floor(Math.random() * msgs.length)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|
||||||
<Home v-if="$page.frontmatter.home" />
|
<Home v-if="$page.frontmatter.home" />
|
||||||
|
|
||||||
<Page v-else :sidebar-items="sidebarItems">
|
<Page v-else :sidebar-items="sidebarItems">
|
||||||
<slot name="page-top" slot="top" />
|
<slot name="page-top" slot="top" />
|
||||||
<slot name="page-bottom" slot="bottom" />
|
<slot name="page-bottom" slot="bottom" />
|
||||||
|
@ -25,9 +24,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Home from "@theme/components/Home.vue";
|
import Home from "@theme/components/Home.vue";
|
||||||
import Navbar from "@theme/components/Navbar.vue";
|
import Navbar from "@parent-theme/components/Navbar.vue";
|
||||||
import Page from "@theme/components/Page.vue";
|
import Page from "@parent-theme/components/Page.vue";
|
||||||
import Sidebar from "@theme/components/Sidebar.vue";
|
import Sidebar from "@parent-theme/components/Sidebar.vue";
|
||||||
import { resolveSidebarItems } from "../util";
|
import { resolveSidebarItems } from "../util";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -35,7 +34,7 @@ export default {
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isSidebarOpen: false
|
isSidebarOpen: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -79,11 +78,11 @@ export default {
|
||||||
{
|
{
|
||||||
"no-navbar": !this.shouldShowNavbar,
|
"no-navbar": !this.shouldShowNavbar,
|
||||||
"sidebar-open": this.isSidebarOpen,
|
"sidebar-open": this.isSidebarOpen,
|
||||||
"no-sidebar": !this.shouldShowSidebar
|
"no-sidebar": !this.shouldShowSidebar,
|
||||||
},
|
},
|
||||||
userPageClass
|
userPageClass,
|
||||||
];
|
];
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -101,7 +100,7 @@ export default {
|
||||||
onTouchStart(e) {
|
onTouchStart(e) {
|
||||||
this.touchStart = {
|
this.touchStart = {
|
||||||
x: e.changedTouches[0].clientX,
|
x: e.changedTouches[0].clientX,
|
||||||
y: e.changedTouches[0].clientY
|
y: e.changedTouches[0].clientY,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ export default {
|
||||||
this.toggleSidebar(false);
|
this.toggleSidebar(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
export default {}
|
|
|
@ -1,41 +0,0 @@
|
||||||
{
|
|
||||||
"name": "@vuepress/theme-default",
|
|
||||||
"version": "1.0.2",
|
|
||||||
"description": "Default theme for VuePress",
|
|
||||||
"main": "index.js",
|
|
||||||
"publishConfig": {
|
|
||||||
"access": "public"
|
|
||||||
},
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "git+https://github.com/vuejs/vuepress.git",
|
|
||||||
"directory": "packages/@vuepress/theme-default"
|
|
||||||
},
|
|
||||||
"keywords": [
|
|
||||||
"documentation",
|
|
||||||
"vue",
|
|
||||||
"vuepress",
|
|
||||||
"generator"
|
|
||||||
],
|
|
||||||
"author": "Evan You",
|
|
||||||
"maintainers": [
|
|
||||||
{
|
|
||||||
"name": "ULIVZ",
|
|
||||||
"email": "chl814@foxmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"license": "MIT",
|
|
||||||
"bugs": {
|
|
||||||
"url": "https://github.com/vuejs/vuepress/issues"
|
|
||||||
},
|
|
||||||
"homepage": "https://github.com/vuejs/vuepress/packages/@vuepress/theme-default#readme",
|
|
||||||
"dependencies": {
|
|
||||||
"@vuepress/plugin-active-header-links": "^1.0.2",
|
|
||||||
"@vuepress/plugin-nprogress": "^1.0.2",
|
|
||||||
"@vuepress/plugin-search": "^1.0.2",
|
|
||||||
"docsearch.js": "^2.5.2",
|
|
||||||
"stylus": "^0.54.5",
|
|
||||||
"stylus-loader": "^3.0.2",
|
|
||||||
"vuepress-plugin-container": "^2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
@require './config'
|
|
||||||
|
|
||||||
.arrow
|
|
||||||
display inline-block
|
|
||||||
width 0
|
|
||||||
height 0
|
|
||||||
&.up
|
|
||||||
border-left 4px solid transparent
|
|
||||||
border-right 4px solid transparent
|
|
||||||
border-bottom 6px solid $arrowBgColor
|
|
||||||
&.down
|
|
||||||
border-left 4px solid transparent
|
|
||||||
border-right 4px solid transparent
|
|
||||||
border-top 6px solid $arrowBgColor
|
|
||||||
&.right
|
|
||||||
border-top 4px solid transparent
|
|
||||||
border-bottom 4px solid transparent
|
|
||||||
border-left 6px solid $arrowBgColor
|
|
||||||
&.left
|
|
||||||
border-top 4px solid transparent
|
|
||||||
border-bottom 4px solid transparent
|
|
||||||
border-right 6px solid $arrowBgColor
|
|
|
@ -1,140 +0,0 @@
|
||||||
{$contentClass}
|
|
||||||
code
|
|
||||||
color lighten($textColor, 20%)
|
|
||||||
padding 0.25rem 0.5rem
|
|
||||||
margin 0
|
|
||||||
font-size 0.85em
|
|
||||||
background-color rgba(27,31,35,0.05)
|
|
||||||
border-radius 3px
|
|
||||||
.token
|
|
||||||
&.deleted
|
|
||||||
color #EC5975
|
|
||||||
&.inserted
|
|
||||||
color $accentColor
|
|
||||||
|
|
||||||
{$contentClass}
|
|
||||||
pre, pre[class*="language-"]
|
|
||||||
line-height 1.4
|
|
||||||
padding 1.25rem 1.5rem
|
|
||||||
margin 0.85rem 0
|
|
||||||
background-color $codeBgColor
|
|
||||||
border-radius 6px
|
|
||||||
overflow auto
|
|
||||||
code
|
|
||||||
color #fff
|
|
||||||
padding 0
|
|
||||||
background-color transparent
|
|
||||||
border-radius 0
|
|
||||||
|
|
||||||
div[class*="language-"]
|
|
||||||
position relative
|
|
||||||
background-color $codeBgColor
|
|
||||||
border-radius 6px
|
|
||||||
.highlight-lines
|
|
||||||
user-select none
|
|
||||||
padding-top 1.3rem
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width 100%
|
|
||||||
line-height 1.4
|
|
||||||
.highlighted
|
|
||||||
background-color rgba(0, 0, 0, 66%)
|
|
||||||
pre, pre[class*="language-"]
|
|
||||||
background transparent
|
|
||||||
position relative
|
|
||||||
z-index 1
|
|
||||||
&::before
|
|
||||||
position absolute
|
|
||||||
z-index 3
|
|
||||||
top 0.8em
|
|
||||||
right 1em
|
|
||||||
font-size 0.75rem
|
|
||||||
color rgba(255, 255, 255, 0.4)
|
|
||||||
&:not(.line-numbers-mode)
|
|
||||||
.line-numbers-wrapper
|
|
||||||
display none
|
|
||||||
&.line-numbers-mode
|
|
||||||
.highlight-lines .highlighted
|
|
||||||
position relative
|
|
||||||
&:before
|
|
||||||
content ' '
|
|
||||||
position absolute
|
|
||||||
z-index 3
|
|
||||||
left 0
|
|
||||||
top 0
|
|
||||||
display block
|
|
||||||
width $lineNumbersWrapperWidth
|
|
||||||
height 100%
|
|
||||||
background-color rgba(0, 0, 0, 66%)
|
|
||||||
pre
|
|
||||||
padding-left $lineNumbersWrapperWidth + 1 rem
|
|
||||||
vertical-align middle
|
|
||||||
.line-numbers-wrapper
|
|
||||||
position absolute
|
|
||||||
top 0
|
|
||||||
width $lineNumbersWrapperWidth
|
|
||||||
text-align center
|
|
||||||
color rgba(255, 255, 255, 0.3)
|
|
||||||
padding 1.25rem 0
|
|
||||||
line-height 1.4
|
|
||||||
br
|
|
||||||
user-select none
|
|
||||||
.line-number
|
|
||||||
position relative
|
|
||||||
z-index 4
|
|
||||||
user-select none
|
|
||||||
font-size 0.85em
|
|
||||||
&::after
|
|
||||||
content ''
|
|
||||||
position absolute
|
|
||||||
z-index 2
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width $lineNumbersWrapperWidth
|
|
||||||
height 100%
|
|
||||||
border-radius 6px 0 0 6px
|
|
||||||
border-right 1px solid rgba(0, 0, 0, 66%)
|
|
||||||
background-color $codeBgColor
|
|
||||||
|
|
||||||
|
|
||||||
for lang in $codeLang
|
|
||||||
div{'[class~="language-' + lang + '"]'}
|
|
||||||
&:before
|
|
||||||
content ('' + lang)
|
|
||||||
|
|
||||||
div[class~="language-javascript"]
|
|
||||||
&:before
|
|
||||||
content "js"
|
|
||||||
|
|
||||||
div[class~="language-typescript"]
|
|
||||||
&:before
|
|
||||||
content "ts"
|
|
||||||
|
|
||||||
div[class~="language-markup"]
|
|
||||||
&:before
|
|
||||||
content "html"
|
|
||||||
|
|
||||||
div[class~="language-markdown"]
|
|
||||||
&:before
|
|
||||||
content "md"
|
|
||||||
|
|
||||||
div[class~="language-json"]:before
|
|
||||||
content "json"
|
|
||||||
|
|
||||||
div[class~="language-ruby"]:before
|
|
||||||
content "rb"
|
|
||||||
|
|
||||||
div[class~="language-python"]:before
|
|
||||||
content "py"
|
|
||||||
|
|
||||||
div[class~="language-bash"]:before
|
|
||||||
content "sh"
|
|
||||||
|
|
||||||
div[class~="language-sh"]:before
|
|
||||||
content "sh"
|
|
||||||
|
|
||||||
div[class~="language-php"]:before
|
|
||||||
content "php"
|
|
||||||
|
|
||||||
@import '~prismjs/themes/prism-tomorrow.css'
|
|
|
@ -1 +0,0 @@
|
||||||
$contentClass = '.theme-default-content'
|
|
|
@ -1,31 +0,0 @@
|
||||||
.custom-block
|
|
||||||
.custom-block-title
|
|
||||||
font-weight 600
|
|
||||||
margin-bottom -0.4rem
|
|
||||||
&.tip, &.warning, &.danger
|
|
||||||
padding .1rem 1.5rem
|
|
||||||
border-left-width .5rem
|
|
||||||
border-left-style solid
|
|
||||||
margin 1rem 0
|
|
||||||
&.tip
|
|
||||||
background-color #f3f5f7
|
|
||||||
border-color #42b983
|
|
||||||
&.warning
|
|
||||||
background-color rgba(255,229,100,.3)
|
|
||||||
border-color darken(#ffe564, 35%)
|
|
||||||
color darken(#ffe564, 70%)
|
|
||||||
.custom-block-title
|
|
||||||
color darken(#ffe564, 50%)
|
|
||||||
a
|
|
||||||
color $textColor
|
|
||||||
&.danger
|
|
||||||
background-color #ffe6e6
|
|
||||||
border-color darken(red, 20%)
|
|
||||||
color darken(red, 70%)
|
|
||||||
.custom-block-title
|
|
||||||
color darken(red, 40%)
|
|
||||||
a
|
|
||||||
color $textColor
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,203 +0,0 @@
|
||||||
@require './config'
|
|
||||||
@require './code'
|
|
||||||
@require './custom-blocks'
|
|
||||||
@require './arrow'
|
|
||||||
@require './wrapper'
|
|
||||||
@require './toc'
|
|
||||||
|
|
||||||
html, body
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
background-color #fff
|
|
||||||
|
|
||||||
body
|
|
||||||
font-family -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif
|
|
||||||
-webkit-font-smoothing antialiased
|
|
||||||
-moz-osx-font-smoothing grayscale
|
|
||||||
font-size $fontSize
|
|
||||||
color $textColor
|
|
||||||
|
|
||||||
.page
|
|
||||||
padding-left $sidebarWidth
|
|
||||||
|
|
||||||
.navbar
|
|
||||||
position fixed
|
|
||||||
z-index 20
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
right 0
|
|
||||||
height $navbarHeight
|
|
||||||
background-color $navbar-background
|
|
||||||
box-sizing border-box
|
|
||||||
border-bottom 1px solid $accentColor
|
|
||||||
|
|
||||||
.sidebar-mask
|
|
||||||
position fixed
|
|
||||||
z-index 9
|
|
||||||
top 0
|
|
||||||
left 0
|
|
||||||
width 100vw
|
|
||||||
height 100vh
|
|
||||||
display none
|
|
||||||
|
|
||||||
.sidebar
|
|
||||||
font-size 16px
|
|
||||||
background-color $sidebarColor
|
|
||||||
width $sidebarWidth
|
|
||||||
position fixed
|
|
||||||
z-index 10
|
|
||||||
margin 0
|
|
||||||
top $navbarHeight
|
|
||||||
left 0
|
|
||||||
bottom 0
|
|
||||||
box-sizing border-box
|
|
||||||
border-right 1px solid $borderColor
|
|
||||||
overflow-y auto
|
|
||||||
|
|
||||||
{$contentClass}:not(.custom)
|
|
||||||
@extend $wrapper
|
|
||||||
> *:first-child
|
|
||||||
margin-top $navbarHeight
|
|
||||||
|
|
||||||
a:hover
|
|
||||||
text-decoration underline
|
|
||||||
|
|
||||||
p.demo
|
|
||||||
padding 1rem 1.5rem
|
|
||||||
border 1px solid #ddd
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
img
|
|
||||||
display: block;
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width 92%
|
|
||||||
|
|
||||||
{$contentClass}.custom
|
|
||||||
padding 0
|
|
||||||
margin 0
|
|
||||||
|
|
||||||
img
|
|
||||||
max-width 100%
|
|
||||||
|
|
||||||
a
|
|
||||||
font-weight 500
|
|
||||||
color $accentColor
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
p a code
|
|
||||||
font-weight 400
|
|
||||||
color $accentColor
|
|
||||||
|
|
||||||
kbd
|
|
||||||
background #eee
|
|
||||||
border solid 0.15rem #ddd
|
|
||||||
border-bottom solid 0.25rem #ddd
|
|
||||||
border-radius 0.15rem
|
|
||||||
padding 0 0.15em
|
|
||||||
|
|
||||||
blockquote
|
|
||||||
font-size 1rem
|
|
||||||
color #999;
|
|
||||||
border-left .2rem solid #dfe2e5
|
|
||||||
margin 1rem 0
|
|
||||||
padding .25rem 0 .25rem 1rem
|
|
||||||
|
|
||||||
& > p
|
|
||||||
margin 0
|
|
||||||
|
|
||||||
ul, ol
|
|
||||||
padding-left 1.2em
|
|
||||||
|
|
||||||
strong
|
|
||||||
font-weight 600
|
|
||||||
|
|
||||||
h1, h2, h3, h4, h5, h6
|
|
||||||
font-weight 600
|
|
||||||
line-height 1.25
|
|
||||||
|
|
||||||
{$contentClass}:not(.custom) > &
|
|
||||||
margin-top (0.5rem - $navbarHeight)
|
|
||||||
padding-top ($navbarHeight + 1rem)
|
|
||||||
margin-bottom 0
|
|
||||||
|
|
||||||
&:first-child
|
|
||||||
margin-top -1.5rem
|
|
||||||
margin-bottom 1rem
|
|
||||||
|
|
||||||
+ p, + pre, + .custom-block
|
|
||||||
margin-top 2rem
|
|
||||||
|
|
||||||
&:hover .header-anchor
|
|
||||||
opacity: 1
|
|
||||||
|
|
||||||
h1
|
|
||||||
font-size 2.2rem
|
|
||||||
|
|
||||||
h2
|
|
||||||
font-size 1.65rem
|
|
||||||
padding-bottom .3rem
|
|
||||||
border-bottom 1px solid $borderColor
|
|
||||||
|
|
||||||
h3
|
|
||||||
font-size 1.35rem
|
|
||||||
|
|
||||||
a.header-anchor
|
|
||||||
font-size 0.85em
|
|
||||||
float left
|
|
||||||
margin-left -0.87em
|
|
||||||
padding-right 0.23em
|
|
||||||
margin-top 0.125em
|
|
||||||
opacity 0
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
text-decoration none
|
|
||||||
|
|
||||||
code, kbd, .line-number
|
|
||||||
font-family source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace
|
|
||||||
|
|
||||||
p, ul, ol
|
|
||||||
line-height 1.7
|
|
||||||
|
|
||||||
hr
|
|
||||||
border 0
|
|
||||||
border-top 1px solid $borderColor
|
|
||||||
|
|
||||||
table
|
|
||||||
border-collapse collapse
|
|
||||||
margin 1rem 0
|
|
||||||
display: block
|
|
||||||
overflow-x: auto
|
|
||||||
|
|
||||||
tr
|
|
||||||
border-top 1px solid #dfe2e5
|
|
||||||
|
|
||||||
&:nth-child(2n)
|
|
||||||
background-color #f6f8fa
|
|
||||||
|
|
||||||
th, td
|
|
||||||
border 1px solid #dfe2e5
|
|
||||||
padding .6em 1em
|
|
||||||
|
|
||||||
.theme-container
|
|
||||||
&.sidebar-open
|
|
||||||
.sidebar-mask
|
|
||||||
display: block
|
|
||||||
|
|
||||||
&.no-navbar
|
|
||||||
{$contentClass}:not(.custom) > h1, h2, h3, h4, h5, h6
|
|
||||||
margin-top 1.5rem
|
|
||||||
padding-top 0
|
|
||||||
|
|
||||||
.sidebar
|
|
||||||
top 0
|
|
||||||
|
|
||||||
|
|
||||||
@media (min-width: ($MQMobile + 1px))
|
|
||||||
.theme-container.no-sidebar
|
|
||||||
.sidebar
|
|
||||||
display none
|
|
||||||
|
|
||||||
.page
|
|
||||||
padding-left 0
|
|
||||||
|
|
||||||
@require 'mobile.styl'
|
|
|
@ -1,37 +0,0 @@
|
||||||
@require './config'
|
|
||||||
|
|
||||||
$mobileSidebarWidth = $sidebarWidth * 0.82
|
|
||||||
|
|
||||||
// narrow desktop / iPad
|
|
||||||
@media (max-width: $MQNarrow)
|
|
||||||
.sidebar
|
|
||||||
font-size 15px
|
|
||||||
width $mobileSidebarWidth
|
|
||||||
.page
|
|
||||||
padding-left $mobileSidebarWidth
|
|
||||||
|
|
||||||
// wide mobile
|
|
||||||
@media (max-width: $MQMobile)
|
|
||||||
.sidebar
|
|
||||||
top 0
|
|
||||||
padding-top $navbarHeight
|
|
||||||
transform translateX(-100%)
|
|
||||||
transition transform .2s ease
|
|
||||||
.page
|
|
||||||
padding-left 0
|
|
||||||
.theme-container
|
|
||||||
&.sidebar-open
|
|
||||||
.sidebar
|
|
||||||
transform translateX(0)
|
|
||||||
&.no-navbar
|
|
||||||
.sidebar
|
|
||||||
padding-top: 0
|
|
||||||
|
|
||||||
// narrow mobile
|
|
||||||
@media (max-width: $MQMobileNarrow)
|
|
||||||
h1
|
|
||||||
font-size 1.9rem
|
|
||||||
{$contentClass}
|
|
||||||
div[class*="language-"]
|
|
||||||
margin 0.85rem -1.5rem
|
|
||||||
border-radius 0
|
|
|
@ -1,32 +0,0 @@
|
||||||
// colors
|
|
||||||
$mainColor= #6E43E8
|
|
||||||
|
|
||||||
|
|
||||||
$sidebarColor=#FAFAFC
|
|
||||||
$accentColor = #6E43E8
|
|
||||||
$textColor =rgb(51, 51, 51)
|
|
||||||
$headerColor=rgb(17, 17, 17)
|
|
||||||
$borderColor = #e8e8fb
|
|
||||||
$codeBgColor = #282c34
|
|
||||||
$arrowBgColor = #ccc
|
|
||||||
$navbar-background = #6E43E8;
|
|
||||||
$navbar-text-color = #ffffff;
|
|
||||||
$section-color=#f7f7f7;
|
|
||||||
$fontSize = 16px
|
|
||||||
|
|
||||||
// layout
|
|
||||||
$navbarHeight = 5.2rem
|
|
||||||
$navbar-vertical-padding = 1.4rem;
|
|
||||||
$navbar-horizontal-padding = 1.4rem;
|
|
||||||
|
|
||||||
$sidebarWidth = 16rem
|
|
||||||
$contentWidth = 960px
|
|
||||||
|
|
||||||
// // responsive breakpoints
|
|
||||||
$MQNarrow = 959px
|
|
||||||
$MQMobile = 719px
|
|
||||||
$MQMobileNarrow = 419px
|
|
||||||
|
|
||||||
.icon.outbound
|
|
||||||
display none !important
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
.table-of-contents
|
|
||||||
.badge
|
|
||||||
vertical-align middle
|
|
|
@ -1,9 +0,0 @@
|
||||||
$wrapper
|
|
||||||
max-width $contentWidth
|
|
||||||
margin 0 auto
|
|
||||||
padding 2rem 2.5rem
|
|
||||||
@media (max-width: $MQNarrow)
|
|
||||||
padding 2rem
|
|
||||||
@media (max-width: $MQMobileNarrow)
|
|
||||||
padding 1.5rem
|
|
||||||
|
|
|
@ -1,119 +1,117 @@
|
||||||
export const hashRE = /#.*$/;
|
export const hashRE = /#.*$/
|
||||||
export const extRE = /\.(md|html)$/;
|
export const extRE = /\.(md|html)$/
|
||||||
export const endingSlashRE = /\/$/;
|
export const endingSlashRE = /\/$/
|
||||||
export const outboundRE = /^(https?:|mailto:|tel:|[a-zA-Z]{4,}:)/;
|
export const outboundRE = /^[a-z]+:/i
|
||||||
|
|
||||||
export function normalize(path) {
|
export function normalize (path) {
|
||||||
return decodeURI(path)
|
return decodeURI(path)
|
||||||
.replace(hashRE, "")
|
.replace(hashRE, '')
|
||||||
.replace(extRE, "");
|
.replace(extRE, '')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getHash(path) {
|
export function getHash (path) {
|
||||||
const match = path.match(hashRE);
|
const match = path.match(hashRE)
|
||||||
if (match) {
|
if (match) {
|
||||||
return match[0];
|
return match[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isExternal(path) {
|
export function isExternal (path) {
|
||||||
return outboundRE.test(path);
|
return outboundRE.test(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isMailto(path) {
|
export function isMailto (path) {
|
||||||
return /^mailto:/.test(path);
|
return /^mailto:/.test(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTel(path) {
|
export function isTel (path) {
|
||||||
return /^tel:/.test(path);
|
return /^tel:/.test(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ensureExt(path) {
|
export function ensureExt (path) {
|
||||||
if (isExternal(path)) {
|
if (isExternal(path)) {
|
||||||
return path;
|
return path
|
||||||
}
|
}
|
||||||
const hashMatch = path.match(hashRE);
|
const hashMatch = path.match(hashRE)
|
||||||
const hash = hashMatch ? hashMatch[0] : "";
|
const hash = hashMatch ? hashMatch[0] : ''
|
||||||
const normalized = normalize(path);
|
const normalized = normalize(path)
|
||||||
|
|
||||||
if (endingSlashRE.test(normalized)) {
|
if (endingSlashRE.test(normalized)) {
|
||||||
return path;
|
return path
|
||||||
}
|
}
|
||||||
return normalized + ".html" + hash;
|
return normalized + '.html' + hash
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isActive(route, path) {
|
export function isActive (route, path) {
|
||||||
const routeHash = route.hash;
|
const routeHash = decodeURIComponent(route.hash)
|
||||||
const linkHash = getHash(path);
|
const linkHash = getHash(path)
|
||||||
if (linkHash && routeHash !== linkHash) {
|
if (linkHash && routeHash !== linkHash) {
|
||||||
return false;
|
return false
|
||||||
}
|
}
|
||||||
const routePath = normalize(route.path);
|
const routePath = normalize(route.path)
|
||||||
const pagePath = normalize(path);
|
const pagePath = normalize(path)
|
||||||
return routePath === pagePath;
|
return routePath === pagePath
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolvePage(pages, rawPath, base) {
|
export function resolvePage (pages, rawPath, base) {
|
||||||
if (isExternal(rawPath)) {
|
if (isExternal(rawPath)) {
|
||||||
return {
|
return {
|
||||||
type: "external",
|
type: 'external',
|
||||||
path: rawPath
|
path: rawPath
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
if (base) {
|
if (base) {
|
||||||
rawPath = resolvePath(rawPath, base);
|
rawPath = resolvePath(rawPath, base)
|
||||||
}
|
}
|
||||||
const path = normalize(rawPath);
|
const path = normalize(rawPath)
|
||||||
for (let i = 0; i < pages.length; i++) {
|
for (let i = 0; i < pages.length; i++) {
|
||||||
if (normalize(pages[i].regularPath) === path) {
|
if (normalize(pages[i].regularPath) === path) {
|
||||||
return Object.assign({}, pages[i], {
|
return Object.assign({}, pages[i], {
|
||||||
type: "page",
|
type: 'page',
|
||||||
path: ensureExt(pages[i].path)
|
path: ensureExt(pages[i].path)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.error(
|
console.error(`[vuepress] No matching page found for sidebar item "${rawPath}"`)
|
||||||
`[vuepress] No matching page found for sidebar item "${rawPath}"`
|
return {}
|
||||||
);
|
|
||||||
return {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolvePath(relative, base, append) {
|
function resolvePath (relative, base, append) {
|
||||||
const firstChar = relative.charAt(0);
|
const firstChar = relative.charAt(0)
|
||||||
if (firstChar === "/") {
|
if (firstChar === '/') {
|
||||||
return relative;
|
return relative
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstChar === "?" || firstChar === "#") {
|
if (firstChar === '?' || firstChar === '#') {
|
||||||
return base + relative;
|
return base + relative
|
||||||
}
|
}
|
||||||
|
|
||||||
const stack = base.split("/");
|
const stack = base.split('/')
|
||||||
|
|
||||||
// remove trailing segment if:
|
// remove trailing segment if:
|
||||||
// - not appending
|
// - not appending
|
||||||
// - appending to trailing slash (last segment is empty)
|
// - appending to trailing slash (last segment is empty)
|
||||||
if (!append || !stack[stack.length - 1]) {
|
if (!append || !stack[stack.length - 1]) {
|
||||||
stack.pop();
|
stack.pop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// resolve relative path
|
// resolve relative path
|
||||||
const segments = relative.replace(/^\//, "").split("/");
|
const segments = relative.replace(/^\//, '').split('/')
|
||||||
for (let i = 0; i < segments.length; i++) {
|
for (let i = 0; i < segments.length; i++) {
|
||||||
const segment = segments[i];
|
const segment = segments[i]
|
||||||
if (segment === "..") {
|
if (segment === '..') {
|
||||||
stack.pop();
|
stack.pop()
|
||||||
} else if (segment !== ".") {
|
} else if (segment !== '.') {
|
||||||
stack.push(segment);
|
stack.push(segment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensure leading slash
|
// ensure leading slash
|
||||||
if (stack[0] !== "") {
|
if (stack[0] !== '') {
|
||||||
stack.unshift("");
|
stack.unshift('')
|
||||||
}
|
}
|
||||||
|
|
||||||
return stack.join("/");
|
return stack.join('/')
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,26 +121,26 @@ function resolvePath(relative, base, append) {
|
||||||
* @param { string } localePath
|
* @param { string } localePath
|
||||||
* @returns { SidebarGroup }
|
* @returns { SidebarGroup }
|
||||||
*/
|
*/
|
||||||
export function resolveSidebarItems(page, regularPath, site, localePath) {
|
export function resolveSidebarItems (page, regularPath, site, localePath) {
|
||||||
const { pages, themeConfig } = site;
|
const { pages, themeConfig } = site
|
||||||
|
|
||||||
const localeConfig =
|
const localeConfig = localePath && themeConfig.locales
|
||||||
localePath && themeConfig.locales
|
? themeConfig.locales[localePath] || themeConfig
|
||||||
? themeConfig.locales[localePath] || themeConfig
|
: themeConfig
|
||||||
: themeConfig;
|
|
||||||
|
|
||||||
const pageSidebarConfig =
|
const pageSidebarConfig = page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar
|
||||||
page.frontmatter.sidebar || localeConfig.sidebar || themeConfig.sidebar;
|
if (pageSidebarConfig === 'auto') {
|
||||||
if (pageSidebarConfig === "auto") {
|
return resolveHeaders(page)
|
||||||
return resolveHeaders(page);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar;
|
const sidebarConfig = localeConfig.sidebar || themeConfig.sidebar
|
||||||
if (!sidebarConfig) {
|
if (!sidebarConfig) {
|
||||||
return [];
|
return []
|
||||||
} else {
|
} else {
|
||||||
const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig);
|
const { base, config } = resolveMatchingConfig(regularPath, sidebarConfig)
|
||||||
return config ? config.map(item => resolveItem(item, pages, base)) : [];
|
return config
|
||||||
|
? config.map(item => resolveItem(item, pages, base))
|
||||||
|
: []
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,43 +148,41 @@ export function resolveSidebarItems(page, regularPath, site, localePath) {
|
||||||
* @param { Page } page
|
* @param { Page } page
|
||||||
* @returns { SidebarGroup }
|
* @returns { SidebarGroup }
|
||||||
*/
|
*/
|
||||||
function resolveHeaders(page) {
|
function resolveHeaders (page) {
|
||||||
const headers = groupHeaders(page.headers || []);
|
const headers = groupHeaders(page.headers || [])
|
||||||
return [
|
return [{
|
||||||
{
|
type: 'group',
|
||||||
type: "group",
|
collapsable: false,
|
||||||
collapsable: false,
|
title: page.title,
|
||||||
title: page.title,
|
path: null,
|
||||||
path: null,
|
children: headers.map(h => ({
|
||||||
children: headers.map(h => ({
|
type: 'auto',
|
||||||
type: "auto",
|
title: h.title,
|
||||||
title: h.title,
|
basePath: page.path,
|
||||||
basePath: page.path,
|
path: page.path + '#' + h.slug,
|
||||||
path: page.path + "#" + h.slug,
|
children: h.children || []
|
||||||
children: h.children || []
|
}))
|
||||||
}))
|
}]
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function groupHeaders(headers) {
|
export function groupHeaders (headers) {
|
||||||
// group h3s under h2
|
// group h3s under h2
|
||||||
headers = headers.map(h => Object.assign({}, h));
|
headers = headers.map(h => Object.assign({}, h))
|
||||||
let lastH2;
|
let lastH2
|
||||||
headers.forEach(h => {
|
headers.forEach(h => {
|
||||||
if (h.level === 2) {
|
if (h.level === 2) {
|
||||||
lastH2 = h;
|
lastH2 = h
|
||||||
} else if (lastH2) {
|
} else if (lastH2) {
|
||||||
(lastH2.children || (lastH2.children = [])).push(h);
|
(lastH2.children || (lastH2.children = [])).push(h)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
return headers.filter(h => h.level === 2);
|
return headers.filter(h => h.level === 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveNavLinkItem(linkItem) {
|
export function resolveNavLinkItem (linkItem) {
|
||||||
return Object.assign(linkItem, {
|
return Object.assign(linkItem, {
|
||||||
type: linkItem.items && linkItem.items.length ? "links" : "link"
|
type: linkItem.items && linkItem.items.length ? 'links' : 'link'
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -194,54 +190,51 @@ export function resolveNavLinkItem(linkItem) {
|
||||||
* @param { Array<string|string[]> | Array<SidebarGroup> | [link: string]: SidebarConfig } config
|
* @param { Array<string|string[]> | Array<SidebarGroup> | [link: string]: SidebarConfig } config
|
||||||
* @returns { base: string, config: SidebarConfig }
|
* @returns { base: string, config: SidebarConfig }
|
||||||
*/
|
*/
|
||||||
export function resolveMatchingConfig(regularPath, config) {
|
export function resolveMatchingConfig (regularPath, config) {
|
||||||
if (Array.isArray(config)) {
|
if (Array.isArray(config)) {
|
||||||
return {
|
return {
|
||||||
base: "/",
|
base: '/',
|
||||||
config: config
|
config: config
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
for (const base in config) {
|
for (const base in config) {
|
||||||
if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) {
|
if (ensureEndingSlash(regularPath).indexOf(encodeURI(base)) === 0) {
|
||||||
return {
|
return {
|
||||||
base,
|
base,
|
||||||
config: config[base]
|
config: config[base]
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return {};
|
return {}
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureEndingSlash(path) {
|
function ensureEndingSlash (path) {
|
||||||
return /(\.html|\/)$/.test(path) ? path : path + "/";
|
return /(\.html|\/)$/.test(path)
|
||||||
|
? path
|
||||||
|
: path + '/'
|
||||||
}
|
}
|
||||||
|
|
||||||
function resolveItem(item, pages, base, groupDepth = 1) {
|
function resolveItem (item, pages, base, groupDepth = 1) {
|
||||||
if (typeof item === "string") {
|
if (typeof item === 'string') {
|
||||||
return resolvePage(pages, item, base);
|
return resolvePage(pages, item, base)
|
||||||
} else if (Array.isArray(item)) {
|
} else if (Array.isArray(item)) {
|
||||||
return Object.assign(resolvePage(pages, item[0], base), {
|
return Object.assign(resolvePage(pages, item[0], base), {
|
||||||
title: item[1]
|
title: item[1]
|
||||||
});
|
})
|
||||||
} else {
|
} else {
|
||||||
if (groupDepth > 3) {
|
const children = item.children || []
|
||||||
console.error("[vuepress] detected a too deep nested sidebar group.");
|
|
||||||
}
|
|
||||||
const children = item.children || [];
|
|
||||||
if (children.length === 0 && item.path) {
|
if (children.length === 0 && item.path) {
|
||||||
return Object.assign(resolvePage(pages, item.path, base), {
|
return Object.assign(resolvePage(pages, item.path, base), {
|
||||||
title: item.title
|
title: item.title
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
type: "group",
|
type: 'group',
|
||||||
path: item.path,
|
path: item.path,
|
||||||
title: item.title,
|
title: item.title,
|
||||||
sidebarDepth: item.sidebarDepth,
|
sidebarDepth: item.sidebarDepth,
|
||||||
children: children.map(child =>
|
children: children.map(child => resolveItem(child, pages, base, groupDepth + 1)),
|
||||||
resolveItem(child, pages, base, groupDepth + 1)
|
|
||||||
),
|
|
||||||
collapsable: item.collapsable !== false
|
collapsable: item.collapsable !== false
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue