mirror of
https://github.com/pterodactyl/documentation.git
synced 2025-12-10 00:09:39 -06:00
upgrade vuepress and evertythin else to latest version
apart from tailwind
This commit is contained in:
parent
ccebf9cd6c
commit
0d99fbae04
@ -2,7 +2,14 @@ module.exports = {
|
||||
base: '/',
|
||||
title: 'Pterodactyl',
|
||||
description: 'The open-source server management solution.',
|
||||
ga: 'UA-87324178-1',
|
||||
plugins: [
|
||||
['@vuepress/google-analytics', {
|
||||
ga: 'UA-12345678-9'
|
||||
},],
|
||||
['@vuepress/search', {
|
||||
searchMaxSuggestions: 10
|
||||
}]
|
||||
],
|
||||
configureWebpack: {
|
||||
serve: {
|
||||
hot: {
|
||||
|
||||
@ -1,133 +1,135 @@
|
||||
<template>
|
||||
<div class="theme-container"
|
||||
:class="pageClasses"
|
||||
@touchstart="onTouchStart"
|
||||
@touchend="onTouchEnd">
|
||||
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar"/>
|
||||
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
||||
<slot name="sidebar-top" slot="top"/>
|
||||
<slot name="sidebar-bottom" slot="bottom"/>
|
||||
</Sidebar>
|
||||
<div class="custom-layout" v-if="$page.frontmatter.layout">
|
||||
<component :is="$page.frontmatter.layout"/>
|
||||
</div>
|
||||
<Home v-else-if="$page.frontmatter.home"/>
|
||||
<Page v-else :sidebar-items="sidebarItems">
|
||||
<slot name="page-top" slot="top"/>
|
||||
<slot name="page-bottom" slot="bottom"/>
|
||||
</Page>
|
||||
<div
|
||||
class="theme-container"
|
||||
:class="pageClasses"
|
||||
@touchstart="onTouchStart"
|
||||
@touchend="onTouchEnd"
|
||||
>
|
||||
<Navbar v-if="shouldShowNavbar" @toggle-sidebar="toggleSidebar" />
|
||||
<div class="sidebar-mask" @click="toggleSidebar(false)"></div>
|
||||
<Sidebar :items="sidebarItems" @toggle-sidebar="toggleSidebar">
|
||||
<slot name="sidebar-top" slot="top" />
|
||||
<slot name="sidebar-bottom" slot="bottom" />
|
||||
</Sidebar>
|
||||
<div class="custom-layout" v-if="$page.frontmatter.layout">
|
||||
<component :is="$page.frontmatter.layout" />
|
||||
</div>
|
||||
<Home v-else-if="$page.frontmatter.home" />
|
||||
<Page v-else :sidebar-items="sidebarItems">
|
||||
<slot name="page-top" slot="top" />
|
||||
<slot name="page-bottom" slot="bottom" />
|
||||
</Page>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue';
|
||||
import nprogress from 'nprogress';
|
||||
import Home from './Home.vue';
|
||||
import Navbar from './Navbar.vue';
|
||||
import Page from './Page.vue';
|
||||
import Sidebar from './Sidebar.vue';
|
||||
import { resolveSidebarItems } from './util';
|
||||
import Vue from "vue";
|
||||
import nprogress from "nprogress";
|
||||
import Home from "./Home.vue";
|
||||
import Navbar from "./Navbar.vue";
|
||||
import Page from "./Page.vue";
|
||||
import Sidebar from "./Sidebar.vue";
|
||||
import { resolveSidebarItems } from "./util";
|
||||
|
||||
export default {
|
||||
components: { Home, Page, Sidebar, Navbar },
|
||||
data() {
|
||||
return {
|
||||
isSidebarOpen: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
shouldShowNavbar() {
|
||||
const { themeConfig } = this.$site;
|
||||
const { frontmatter } = this.$page;
|
||||
if (
|
||||
frontmatter.navbar === false ||
|
||||
themeConfig.navbar === false) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
this.$title ||
|
||||
themeConfig.logo ||
|
||||
themeConfig.repo ||
|
||||
themeConfig.nav ||
|
||||
this.$themeLocaleConfig.nav
|
||||
);
|
||||
},
|
||||
shouldShowSidebar() {
|
||||
const { frontmatter } = this.$page;
|
||||
return (
|
||||
! frontmatter.layout &&
|
||||
! frontmatter.home &&
|
||||
frontmatter.sidebar !== false &&
|
||||
this.sidebarItems.length
|
||||
);
|
||||
},
|
||||
sidebarItems() {
|
||||
return resolveSidebarItems(
|
||||
this.$page,
|
||||
this.$route,
|
||||
this.$site,
|
||||
this.$localePath
|
||||
);
|
||||
},
|
||||
pageClasses() {
|
||||
const userPageClass = this.$page.frontmatter.pageClass;
|
||||
return [
|
||||
{
|
||||
'no-navbar': ! this.shouldShowNavbar,
|
||||
'sidebar-open': this.isSidebarOpen,
|
||||
'no-sidebar': ! this.shouldShowSidebar
|
||||
},
|
||||
userPageClass
|
||||
];
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.onScroll);
|
||||
|
||||
// configure progress bar
|
||||
nprogress.configure({ showSpinner: false });
|
||||
|
||||
this.$router.beforeEach((to, from, next) => {
|
||||
if (to.path !== from.path && ! Vue.component(to.name)) {
|
||||
nprogress.start();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
this.$router.afterEach(() => {
|
||||
nprogress.done();
|
||||
this.isSidebarOpen = false;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleSidebar(to) {
|
||||
this.isSidebarOpen = typeof to === 'boolean' ? to : ! this.isSidebarOpen;
|
||||
},
|
||||
// side swipe
|
||||
onTouchStart(e) {
|
||||
this.touchStart = {
|
||||
x: e.changedTouches[0].clientX,
|
||||
y: e.changedTouches[0].clientY
|
||||
};
|
||||
},
|
||||
onTouchEnd(e) {
|
||||
const dx = e.changedTouches[0].clientX - this.touchStart.x;
|
||||
const dy = e.changedTouches[0].clientY - this.touchStart.y;
|
||||
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
|
||||
if (dx > 0 && this.touchStart.x <= 80) {
|
||||
this.toggleSidebar(true);
|
||||
} else {
|
||||
this.toggleSidebar(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export default {
|
||||
components: { Home, Page, Sidebar, Navbar },
|
||||
data() {
|
||||
return {
|
||||
isSidebarOpen: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
shouldShowNavbar() {
|
||||
const { themeConfig } = this.$site;
|
||||
const { frontmatter } = this.$page;
|
||||
if (frontmatter.navbar === false || themeConfig.navbar === false) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
this.$title ||
|
||||
themeConfig.logo ||
|
||||
themeConfig.repo ||
|
||||
themeConfig.nav ||
|
||||
this.$themeLocaleConfig.nav
|
||||
);
|
||||
},
|
||||
shouldShowSidebar() {
|
||||
const { frontmatter } = this.$page;
|
||||
return (
|
||||
!frontmatter.layout &&
|
||||
!frontmatter.home &&
|
||||
frontmatter.sidebar !== false &&
|
||||
this.sidebarItems.length
|
||||
);
|
||||
},
|
||||
sidebarItems() {
|
||||
return resolveSidebarItems(
|
||||
this.$page,
|
||||
this.$route,
|
||||
this.$site,
|
||||
this.$localePath
|
||||
);
|
||||
},
|
||||
pageClasses() {
|
||||
const userPageClass = this.$page.frontmatter.pageClass;
|
||||
return [
|
||||
{
|
||||
"no-navbar": !this.shouldShowNavbar,
|
||||
"sidebar-open": this.isSidebarOpen,
|
||||
"no-sidebar": !this.shouldShowSidebar
|
||||
},
|
||||
userPageClass
|
||||
];
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
window.addEventListener("scroll", this.onScroll);
|
||||
|
||||
// configure progress bar
|
||||
nprogress.configure({ showSpinner: false });
|
||||
|
||||
this.$router.beforeEach((to, from, next) => {
|
||||
if (to.path !== from.path && !Vue.component(to.name)) {
|
||||
nprogress.start();
|
||||
}
|
||||
next();
|
||||
});
|
||||
|
||||
this.$router.afterEach(() => {
|
||||
nprogress.done();
|
||||
this.isSidebarOpen = false;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
toggleSidebar(to) {
|
||||
this.isSidebarOpen = typeof to === "boolean" ? to : !this.isSidebarOpen;
|
||||
},
|
||||
// side swipe
|
||||
onTouchStart(e) {
|
||||
this.touchStart = {
|
||||
x: e.changedTouches[0].clientX,
|
||||
y: e.changedTouches[0].clientY
|
||||
};
|
||||
},
|
||||
onTouchEnd(e) {
|
||||
const dx = e.changedTouches[0].clientX - this.touchStart.x;
|
||||
const dy = e.changedTouches[0].clientY - this.touchStart.y;
|
||||
if (Math.abs(dx) > Math.abs(dy) && Math.abs(dx) > 40) {
|
||||
if (dx > 0 && this.touchStart.x <= 80) {
|
||||
this.toggleSidebar(true);
|
||||
} else {
|
||||
this.toggleSidebar(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style src="prismjs/themes/prism-tomorrow.css"></style>
|
||||
<style src="./styles/main.css" lang="postcss"></style>
|
||||
<style lang="postcss">
|
||||
@import "./styles/main.css";
|
||||
</style>
|
||||
|
||||
@ -1,42 +1,35 @@
|
||||
<template>
|
||||
<header class="nav">
|
||||
<SidebarButton class="block md:hidden flex-no-shrink" @toggle-sidebar="$emit('toggle-sidebar')"/>
|
||||
<div class="logo-container">
|
||||
<router-link :to="$localePath" class="home-link">
|
||||
<img class="logo"
|
||||
v-if="$site.themeConfig.logo"
|
||||
:src="$withBase($site.themeConfig.logo)">
|
||||
<span class="site-name hidden md:inline"
|
||||
v-if="$siteTitle"
|
||||
:class="{ 'can-hide': $site.themeConfig.logo }">
|
||||
{{ $siteTitle }}
|
||||
</span>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex">
|
||||
<SearchBox/>
|
||||
<NavLinks class="hidden md:flex"/>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<header class="nav">
|
||||
<SidebarButton
|
||||
class="block md:hidden flex-no-shrink"
|
||||
@toggle-sidebar="$emit('toggle-sidebar')"
|
||||
/>
|
||||
<div class="logo-container">
|
||||
<router-link :to="$localePath" class="home-link">
|
||||
<img class="logo" v-if="$site.themeConfig.logo" :src="$withBase($site.themeConfig.logo)" />
|
||||
<span
|
||||
class="site-name hidden md:inline"
|
||||
v-if="$siteTitle"
|
||||
:class="{ 'can-hide': $site.themeConfig.logo }"
|
||||
>{{ $siteTitle }}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="w-full">
|
||||
<div class="flex">
|
||||
<SearchBox />
|
||||
<NavLinks class="hidden md:flex" />
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SidebarButton from './SidebarButton.vue';
|
||||
import AlgoliaSearchBox from '@AlgoliaSearchBox';
|
||||
import SearchBox from './SearchBox.vue';
|
||||
import NavLinks from './NavLinks.vue';
|
||||
import SidebarButton from "./SidebarButton.vue";
|
||||
import SearchBox from "./SearchBox.vue";
|
||||
import NavLinks from "./NavLinks.vue";
|
||||
|
||||
export default {
|
||||
components: { SidebarButton, NavLinks, SearchBox, AlgoliaSearchBox },
|
||||
computed: {
|
||||
algolia() {
|
||||
return this.$themeLocaleConfig.algolia || this.$site.themeConfig.algolia || {};
|
||||
},
|
||||
isAlgoliaSearch() {
|
||||
return this.algolia && this.algolia.apiKey && this.algolia.indexName;
|
||||
}
|
||||
}
|
||||
};
|
||||
export default {
|
||||
components: { SidebarButton, NavLinks, SearchBox },
|
||||
computed: {}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,156 +1,155 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<slot name="top"/>
|
||||
<Content :custom="false"/>
|
||||
<div 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>
|
||||
</div>
|
||||
<div class="page-nav" v-if="prev || next">
|
||||
<p class="inner"></p>
|
||||
<div class="prev">
|
||||
<span v-if="prev">
|
||||
← <router-link v-if="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
||||
</span>
|
||||
</div>
|
||||
<div class="next">
|
||||
<span v-if="next">
|
||||
<router-link v-if="next" :to="next.path">{{ next.title || next.path }}</router-link> →
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="bottom"/>
|
||||
<div class="page">
|
||||
<slot name="top" />
|
||||
<Content class="content" :custom="false" />
|
||||
<div 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>
|
||||
</div>
|
||||
<div class="page-nav" v-if="prev || next">
|
||||
<p class="inner"></p>
|
||||
<div class="prev">
|
||||
<span v-if="prev">
|
||||
←
|
||||
<router-link v-if="prev" :to="prev.path">{{ prev.title || prev.path }}</router-link>
|
||||
</span>
|
||||
</div>
|
||||
<div class="next">
|
||||
<span v-if="next">
|
||||
<router-link v-if="next" :to="next.path">{{ next.title || next.path }}</router-link>→
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<slot name="bottom" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { resolvePage, normalize, outboundRE, endingSlashRE } from './util';
|
||||
import { resolvePage, normalize, outboundRE, endingSlashRE } from "./util";
|
||||
|
||||
export default {
|
||||
props: ['sidebarItems'],
|
||||
computed: {
|
||||
lastUpdated() {
|
||||
if (this.$page.lastUpdated) {
|
||||
return new Date(this.$page.lastUpdated).toLocaleString(this.$lang);
|
||||
}
|
||||
},
|
||||
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;
|
||||
export default {
|
||||
props: ["sidebarItems"],
|
||||
computed: {
|
||||
lastUpdated() {
|
||||
if (this.$page.lastUpdated) {
|
||||
return new Date(this.$page.lastUpdated).toLocaleString(this.$lang);
|
||||
}
|
||||
},
|
||||
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;
|
||||
|
||||
let path = normalize(this.$page.path);
|
||||
if (endingSlashRE.test(path)) {
|
||||
path += 'README.md';
|
||||
} else {
|
||||
path += '.md';
|
||||
}
|
||||
if (docsRepo && editLinks) {
|
||||
return this.createEditLink(repo, docsRepo, docsDir, docsBranch, path);
|
||||
}
|
||||
},
|
||||
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, '') +
|
||||
`/${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);
|
||||
let path = normalize(this.$page.path);
|
||||
if (endingSlashRE.test(path)) {
|
||||
path += "README.md";
|
||||
} else {
|
||||
path += ".md";
|
||||
}
|
||||
if (docsRepo && editLinks) {
|
||||
return this.createEditLink(repo, docsRepo, docsDir, docsBranch, path);
|
||||
}
|
||||
},
|
||||
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, "") +
|
||||
`/${docsBranch}` +
|
||||
(docsDir ? "/" + docsDir.replace(endingSlashRE, "") : "") +
|
||||
path +
|
||||
`?mode=edit&spa=0&at=${docsBranch}&fileviewer=file-view-default`
|
||||
);
|
||||
}
|
||||
|
||||
function resolveNext(page, items) {
|
||||
return find(page, items, 1);
|
||||
}
|
||||
const base = outboundRE.test(docsRepo)
|
||||
? docsRepo
|
||||
: `https://github.com/${docsRepo}`;
|
||||
|
||||
function find(page, items, offset) {
|
||||
const res = [];
|
||||
items.forEach(item => {
|
||||
if (item.type === 'group') {
|
||||
res.push(...item.children || []);
|
||||
} else {
|
||||
res.push(item);
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < res.length; i ++) {
|
||||
const cur = res[i];
|
||||
if (cur.type === 'page' && cur.path === page.path) {
|
||||
return res[i + offset];
|
||||
}
|
||||
}
|
||||
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 = [];
|
||||
items.forEach(item => {
|
||||
if (item.type === "group") {
|
||||
res.push(...(item.children || []));
|
||||
} else {
|
||||
res.push(item);
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
const cur = res[i];
|
||||
if (cur.type === "page" && cur.path === page.path) {
|
||||
return res[i + offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,137 +1,137 @@
|
||||
<template>
|
||||
<div class="search-box">
|
||||
<input
|
||||
@input="query = $event.target.value"
|
||||
aria-label="Search"
|
||||
:value="query"
|
||||
placeholder="Search"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@keyup.enter="go(focusIndex)"
|
||||
@keyup.up="onUp"
|
||||
@keyup.down="onDown">
|
||||
<div class="suggestion-container" v-if="showSuggestions" @mouseleave="unfocus">
|
||||
<div class="suggestion-padding"></div>
|
||||
<ul class="suggestions" :class="{ 'align-right': alignRight }">
|
||||
<li class="suggestion" v-for="(s, i) in suggestions"
|
||||
:class="{ focused: i === focusIndex }"
|
||||
@mousedown="go(i)"
|
||||
@mouseenter="focus(i)">
|
||||
<a :href="s.path" @click.prevent>
|
||||
<span class="page-title">{{ s.title || s.path }}</span>
|
||||
<span v-if="s.header" class="header">> {{ s.header.title }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="search-box">
|
||||
<input
|
||||
@input="query = $event.target.value"
|
||||
aria-label="Search"
|
||||
:value="query"
|
||||
placeholder="Search"
|
||||
autocomplete="off"
|
||||
spellcheck="false"
|
||||
@focus="focused = true"
|
||||
@blur="focused = false"
|
||||
@keyup.enter="go(focusIndex)"
|
||||
@keyup.up="onUp"
|
||||
@keyup.down="onDown"
|
||||
/>
|
||||
<div class="suggestion-container" v-if="showSuggestions" @mouseleave="unfocus">
|
||||
<div class="suggestion-padding"></div>
|
||||
<ul class="suggestions" :class="{ 'align-right': alignRight }">
|
||||
<li
|
||||
class="suggestion"
|
||||
v-for="(s, i) in suggestions"
|
||||
:class="{ focused: i === focusIndex }"
|
||||
@mousedown="go(i)"
|
||||
@mouseenter="focus(i)"
|
||||
>
|
||||
<a :href="s.path" @click.prevent>
|
||||
<span class="page-title">{{ s.title || s.path }}</span>
|
||||
<span v-if="s.header" class="header">> {{ s.header.title }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query: '',
|
||||
focused: false,
|
||||
focusIndex: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showSuggestions() {
|
||||
return (
|
||||
this.focused &&
|
||||
this.suggestions &&
|
||||
this.suggestions.length
|
||||
);
|
||||
},
|
||||
suggestions() {
|
||||
const query = this.query.trim().toLowerCase();
|
||||
if (! query) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { pages, themeConfig } = this.$site;
|
||||
const max = themeConfig.searchMaxSuggestions || 5;
|
||||
const localePath = this.$localePath;
|
||||
const matches = item => (
|
||||
item.title &&
|
||||
item.title.toLowerCase().indexOf(query) > - 1
|
||||
);
|
||||
const res = [];
|
||||
for (let i = 0; i < pages.length; i ++) {
|
||||
if (res.length >= max) break;
|
||||
const p = pages[i];
|
||||
// filter out results that do not match current locale
|
||||
if (this.getPageLocalePath(p) !== localePath) {
|
||||
continue;
|
||||
}
|
||||
if (matches(p)) {
|
||||
res.push(p);
|
||||
} else if (p.headers) {
|
||||
for (let j = 0; j < p.headers.length; j ++) {
|
||||
if (res.length >= max) break;
|
||||
const h = p.headers[j];
|
||||
if (matches(h)) {
|
||||
res.push(Object.assign({}, p, {
|
||||
path: p.path + '#' + h.slug,
|
||||
header: h
|
||||
}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
// make suggestions align right when there are not enough items
|
||||
alignRight() {
|
||||
const navCount = (this.$site.themeConfig.nav || []).length;
|
||||
const repo = this.$site.repo ? 1 : 0;
|
||||
return navCount + repo <= 2;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPageLocalePath(page) {
|
||||
for (const localePath in this.$site.locales || {}) {
|
||||
if (localePath !== '/' && page.path.indexOf(localePath) === 0) {
|
||||
return localePath;
|
||||
}
|
||||
}
|
||||
return '/';
|
||||
},
|
||||
onUp() {
|
||||
if (this.showSuggestions) {
|
||||
if (this.focusIndex > 0) {
|
||||
this.focusIndex --;
|
||||
} else {
|
||||
this.focusIndex = this.suggestions.length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
onDown() {
|
||||
if (this.showSuggestions) {
|
||||
if (this.focusIndex < this.suggestions.length - 1) {
|
||||
this.focusIndex ++;
|
||||
} else {
|
||||
this.focusIndex = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
go(i) {
|
||||
if (! this.showSuggestions) {
|
||||
return;
|
||||
}
|
||||
this.$router.push(this.suggestions[i].path);
|
||||
this.query = '';
|
||||
this.focusIndex = 0;
|
||||
},
|
||||
focus(i) {
|
||||
this.focusIndex = i;
|
||||
},
|
||||
unfocus() {
|
||||
this.focusIndex = - 1;
|
||||
}
|
||||
}
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
query: "",
|
||||
focused: false,
|
||||
focusIndex: 0
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
showSuggestions() {
|
||||
return this.focused && this.suggestions && this.suggestions.length;
|
||||
},
|
||||
suggestions() {
|
||||
const query = this.query.trim().toLowerCase();
|
||||
if (!query) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { pages, themeConfig } = this.$site;
|
||||
const max = themeConfig.searchMaxSuggestions || 5;
|
||||
const localePath = this.$localePath;
|
||||
const matches = item =>
|
||||
item.title && item.title.toLowerCase().indexOf(query) > -1;
|
||||
const res = [];
|
||||
for (let i = 0; i < pages.length; i++) {
|
||||
if (res.length >= max) break;
|
||||
const p = pages[i];
|
||||
// filter out results that do not match current locale
|
||||
if (this.getPageLocalePath(p) !== localePath) {
|
||||
continue;
|
||||
}
|
||||
if (matches(p)) {
|
||||
res.push(p);
|
||||
} else if (p.headers) {
|
||||
for (let j = 0; j < p.headers.length; j++) {
|
||||
if (res.length >= max) break;
|
||||
const h = p.headers[j];
|
||||
if (matches(h)) {
|
||||
res.push(
|
||||
Object.assign({}, p, {
|
||||
path: p.path + "#" + h.slug,
|
||||
header: h
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
// make suggestions align right when there are not enough items
|
||||
alignRight() {
|
||||
const navCount = (this.$site.themeConfig.nav || []).length;
|
||||
const repo = this.$site.repo ? 1 : 0;
|
||||
return navCount + repo <= 2;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPageLocalePath(page) {
|
||||
for (const localePath in this.$site.locales || {}) {
|
||||
if (localePath !== "/" && page.path.indexOf(localePath) === 0) {
|
||||
return localePath;
|
||||
}
|
||||
}
|
||||
return "/";
|
||||
},
|
||||
onUp() {
|
||||
if (this.showSuggestions) {
|
||||
if (this.focusIndex > 0) {
|
||||
this.focusIndex--;
|
||||
} else {
|
||||
this.focusIndex = this.suggestions.length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
onDown() {
|
||||
if (this.showSuggestions) {
|
||||
if (this.focusIndex < this.suggestions.length - 1) {
|
||||
this.focusIndex++;
|
||||
} else {
|
||||
this.focusIndex = 0;
|
||||
}
|
||||
}
|
||||
},
|
||||
go(i) {
|
||||
if (!this.showSuggestions) {
|
||||
return;
|
||||
}
|
||||
this.$router.push(this.suggestions[i].path);
|
||||
this.query = "";
|
||||
this.focusIndex = 0;
|
||||
},
|
||||
focus(i) {
|
||||
this.focusIndex = i;
|
||||
},
|
||||
unfocus() {
|
||||
this.focusIndex = -1;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
@font-face {
|
||||
font-family: 'et-line';
|
||||
src:url('../fonts/et-line/et-line.eot');
|
||||
src:url('../fonts/et-line/et-line.eot?#iefix') format('embedded-opentype'),
|
||||
url('../fonts/et-line/et-line.woff') format('woff'),
|
||||
url('../fonts/et-line/et-line.ttf') format('truetype'),
|
||||
url('../fonts/et-line/et-line.svg#et-line') format('svg');
|
||||
src:url('./fonts/et-line/et-line.eot');
|
||||
src:url('./fonts/et-line/et-line.eot?#iefix') format('embedded-opentype'),
|
||||
url('./fonts/et-line/et-line.woff') format('woff'),
|
||||
url('./fonts/et-line/et-line.ttf') format('truetype'),
|
||||
url('./fonts/et-line/et-line.svg#et-line') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
@ -118,7 +118,7 @@
|
||||
@charset 'UTF-8';
|
||||
/* Slider */
|
||||
.slick-loading .slick-list {
|
||||
background: #fff url('../../public/frontpage/loading.svg') center center no-repeat;
|
||||
background: #fff url('../public/frontpage/loading.svg') center center no-repeat;
|
||||
}
|
||||
|
||||
/* Icons */
|
||||
@ -127,8 +127,8 @@
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
|
||||
src: url('../fonts/slick/slick.eot');
|
||||
src: url('../fonts/slick/slick.eot?#iefix') format('embedded-opentype'), url('../fonts/slick/slick.woff') format('woff'), url('../fonts/slick/slick.ttf') format('truetype'), url('../fonts/slick/slick.svg#slick') format('svg');
|
||||
src: url('./fonts/slick/slick.eot');
|
||||
src: url('./fonts/slick/slick.eot?#iefix') format('embedded-opentype'), url('./fonts/slick/slick.woff') format('woff'), url('./fonts/slick/slick.ttf') format('truetype'), url('./fonts/slick/slick.svg#slick') format('svg');
|
||||
}
|
||||
|
||||
/* Arrows */
|
||||
|
||||
11
package.json
11
package.json
@ -1,19 +1,20 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@vuepress/plugin-google-analytics": "^1.0.0-rc.1",
|
||||
"jquery": "^3.3.1",
|
||||
"slick-carousel": "^1.8.1",
|
||||
"vuepress": "^0.14.8"
|
||||
"vuepress": "^1.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "./node_modules/vuepress/bin/vuepress.js build",
|
||||
"watch": "./node_modules/vuepress/bin/vuepress.js dev"
|
||||
"build": "vuepress build",
|
||||
"watch": "vuepress dev"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.0.1",
|
||||
"cssnano": "^4.0.3",
|
||||
"lodash": "^4.17.13",
|
||||
"postcss-import": "^11.1.0",
|
||||
"precss": "^3.1.2",
|
||||
"postcss-import": "^12.0.0",
|
||||
"precss": "^4.0.0",
|
||||
"tailwindcss": "^0.6.4"
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user