Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
深夜程序员
Spring 中文文档社区
提交
65de1751
Spring 中文文档社区
项目概览
深夜程序员
/
Spring 中文文档社区
与 Fork 源项目一致
Fork自
开发云 / Spring 中文文档社区
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Spring 中文文档社区
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
65de1751
编写于
3月 02, 2022
作者:
璃白.
🌻
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:创建gitcode主题
上级
5d7184f8
变更
35
显示空白变更内容
内联
并排
Showing
35 changed file
with
3095 addition
and
0 deletion
+3095
-0
docs/.vuepress/config.js
docs/.vuepress/config.js
+2
-0
docs/.vuepress/themes/theme-gitcode/LICENSE
docs/.vuepress/themes/theme-gitcode/LICENSE
+21
-0
docs/.vuepress/themes/theme-gitcode/README.md
docs/.vuepress/themes/theme-gitcode/README.md
+11
-0
docs/.vuepress/themes/theme-gitcode/components/AlgoliaSearchBox.vue
...ress/themes/theme-gitcode/components/AlgoliaSearchBox.vue
+172
-0
docs/.vuepress/themes/theme-gitcode/components/DropdownLink.vue
...vuepress/themes/theme-gitcode/components/DropdownLink.vue
+252
-0
docs/.vuepress/themes/theme-gitcode/components/DropdownTransition.vue
...ss/themes/theme-gitcode/components/DropdownTransition.vue
+33
-0
docs/.vuepress/themes/theme-gitcode/components/Home.vue
docs/.vuepress/themes/theme-gitcode/components/Home.vue
+181
-0
docs/.vuepress/themes/theme-gitcode/components/NavLink.vue
docs/.vuepress/themes/theme-gitcode/components/NavLink.vue
+90
-0
docs/.vuepress/themes/theme-gitcode/components/NavLinks.vue
docs/.vuepress/themes/theme-gitcode/components/NavLinks.vue
+156
-0
docs/.vuepress/themes/theme-gitcode/components/Navbar.vue
docs/.vuepress/themes/theme-gitcode/components/Navbar.vue
+140
-0
docs/.vuepress/themes/theme-gitcode/components/Page.vue
docs/.vuepress/themes/theme-gitcode/components/Page.vue
+31
-0
docs/.vuepress/themes/theme-gitcode/components/PageEdit.vue
docs/.vuepress/themes/theme-gitcode/components/PageEdit.vue
+167
-0
docs/.vuepress/themes/theme-gitcode/components/PageNav.vue
docs/.vuepress/themes/theme-gitcode/components/PageNav.vue
+163
-0
docs/.vuepress/themes/theme-gitcode/components/Sidebar.vue
docs/.vuepress/themes/theme-gitcode/components/Sidebar.vue
+64
-0
docs/.vuepress/themes/theme-gitcode/components/SidebarButton.vue
...uepress/themes/theme-gitcode/components/SidebarButton.vue
+40
-0
docs/.vuepress/themes/theme-gitcode/components/SidebarGroup.vue
...vuepress/themes/theme-gitcode/components/SidebarGroup.vue
+141
-0
docs/.vuepress/themes/theme-gitcode/components/SidebarLink.vue
....vuepress/themes/theme-gitcode/components/SidebarLink.vue
+133
-0
docs/.vuepress/themes/theme-gitcode/components/SidebarLinks.vue
...vuepress/themes/theme-gitcode/components/SidebarLinks.vue
+106
-0
docs/.vuepress/themes/theme-gitcode/global-components/Badge.vue
...vuepress/themes/theme-gitcode/global-components/Badge.vue
+44
-0
docs/.vuepress/themes/theme-gitcode/global-components/CodeBlock.vue
...ress/themes/theme-gitcode/global-components/CodeBlock.vue
+41
-0
docs/.vuepress/themes/theme-gitcode/global-components/CodeGroup.vue
...ress/themes/theme-gitcode/global-components/CodeGroup.vue
+120
-0
docs/.vuepress/themes/theme-gitcode/index.js
docs/.vuepress/themes/theme-gitcode/index.js
+61
-0
docs/.vuepress/themes/theme-gitcode/layouts/404.vue
docs/.vuepress/themes/theme-gitcode/layouts/404.vue
+30
-0
docs/.vuepress/themes/theme-gitcode/layouts/Layout.vue
docs/.vuepress/themes/theme-gitcode/layouts/Layout.vue
+151
-0
docs/.vuepress/themes/theme-gitcode/noopModule.js
docs/.vuepress/themes/theme-gitcode/noopModule.js
+1
-0
docs/.vuepress/themes/theme-gitcode/package.json
docs/.vuepress/themes/theme-gitcode/package.json
+45
-0
docs/.vuepress/themes/theme-gitcode/styles/arrow.styl
docs/.vuepress/themes/theme-gitcode/styles/arrow.styl
+22
-0
docs/.vuepress/themes/theme-gitcode/styles/code.styl
docs/.vuepress/themes/theme-gitcode/styles/code.styl
+137
-0
docs/.vuepress/themes/theme-gitcode/styles/config.styl
docs/.vuepress/themes/theme-gitcode/styles/config.styl
+1
-0
docs/.vuepress/themes/theme-gitcode/styles/custom-blocks.styl
.../.vuepress/themes/theme-gitcode/styles/custom-blocks.styl
+44
-0
docs/.vuepress/themes/theme-gitcode/styles/index.styl
docs/.vuepress/themes/theme-gitcode/styles/index.styl
+202
-0
docs/.vuepress/themes/theme-gitcode/styles/mobile.styl
docs/.vuepress/themes/theme-gitcode/styles/mobile.styl
+37
-0
docs/.vuepress/themes/theme-gitcode/styles/toc.styl
docs/.vuepress/themes/theme-gitcode/styles/toc.styl
+3
-0
docs/.vuepress/themes/theme-gitcode/styles/wrapper.styl
docs/.vuepress/themes/theme-gitcode/styles/wrapper.styl
+9
-0
docs/.vuepress/themes/theme-gitcode/util/index.js
docs/.vuepress/themes/theme-gitcode/util/index.js
+244
-0
未找到文件。
docs/.vuepress/config.js
浏览文件 @
65de1751
// .vuepress/config.js
const
path
=
require
(
'
path
'
);
const
autometa_options
=
{
site
:
{
name
:
'
Spring 中文文档社区
'
...
...
@@ -76,6 +77,7 @@ module.exports = {
plugins
:
[
[
'
autometa
'
,
autometa_options
]
],
theme
:
path
.
resolve
(
__dirname
,
'
./themes/theme-gitcode/index.js
'
),
themeConfig
:
{
repo
:
"
https://gitcode.net/dev-cloud/spring
"
,
repoLabel
:
"
GitCode
"
,
...
...
docs/.vuepress/themes/theme-gitcode/LICENSE
0 → 100644
浏览文件 @
65de1751
The MIT License (MIT)
Copyright (c) 2018-present, Yuxi (Evan) You
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
docs/.vuepress/themes/theme-gitcode/README.md
0 → 100644
浏览文件 @
65de1751
# @vuepress/theme-default
> theme-default for VuePress
## Plugins
The default theme has the following plugin built in:
-
[
@vuepress/plugin-active-header-links
](
https://github.com/vuejs/vuepress/tree/master/packages/@vuepress/plugin-active-header-links
)
-
[
@vuepress/plugin-google-analytics
](
https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-google-analytics
)
-
[
@vuepress/plugin-search
](
https://github.com/vuejs/vuepress/tree/master/packages/%40vuepress/plugin-search
)
docs/.vuepress/themes/theme-gitcode/components/AlgoliaSearchBox.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<form
id=
"search-form"
class=
"algolia-search-wrapper search-box"
role=
"search"
>
<input
id=
"algolia-search-input"
class=
"search-query"
:placeholder=
"placeholder"
>
</form>
</
template
>
<
script
>
export
default
{
name
:
'
AlgoliaSearchBox
'
,
props
:
[
'
options
'
],
data
()
{
return
{
placeholder
:
undefined
}
},
watch
:
{
$lang
(
newValue
)
{
this
.
update
(
this
.
options
,
newValue
)
},
options
(
newValue
)
{
this
.
update
(
newValue
,
this
.
$lang
)
}
},
mounted
()
{
this
.
initialize
(
this
.
options
,
this
.
$lang
)
this
.
placeholder
=
this
.
$site
.
themeConfig
.
searchPlaceholder
||
''
},
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
:
{
...
algoliaOptions
,
facetFilters
:
[
`lang:
${
lang
}
`
].
concat
(
algoliaOptions
.
facetFilters
||
[])
},
handleSelected
:
(
input
,
event
,
suggestion
)
=>
{
const
{
pathname
,
hash
}
=
new
URL
(
suggestion
.
url
)
const
routepath
=
pathname
.
replace
(
this
.
$site
.
base
,
'
/
'
)
const
_hash
=
decodeURIComponent
(
hash
)
this
.
$router
.
push
(
`
${
routepath
}${
_hash
}
`
)
}
}
))
})
},
update
(
options
,
lang
)
{
this
.
$el
.
innerHTML
=
'
<input id="algolia-search-input" class="search-query">
'
this
.
initialize
(
options
,
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
>
docs/.vuepress/themes/theme-gitcode/components/DropdownLink.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<div
class=
"dropdown-wrapper"
:class=
"
{ open }"
>
<button
class=
"dropdown-title"
type=
"button"
:aria-label=
"dropdownAriaLabel"
@
click=
"handleDropdown"
>
<span
class=
"title"
>
{{
item
.
text
}}
</span>
<span
class=
"arrow down"
/>
</button>
<button
class=
"mobile-dropdown-title"
type=
"button"
:aria-label=
"dropdownAriaLabel"
@
click=
"setOpen(!open)"
>
<span
class=
"title"
>
{{
item
.
text
}}
</span>
<span
class=
"arrow"
:class=
"open ? 'down' : 'right'"
/>
</button>
<DropdownTransition>
<ul
v-show=
"open"
class=
"nav-dropdown"
>
<li
v-for=
"(subItem, index) in item.items"
:key=
"subItem.link || index"
class=
"dropdown-item"
>
<h4
v-if=
"subItem.type === 'links'"
>
{{
subItem
.
text
}}
</h4>
<ul
v-if=
"subItem.type === 'links'"
class=
"dropdown-subitem-wrapper"
>
<li
v-for=
"childSubItem in subItem.items"
:key=
"childSubItem.link"
class=
"dropdown-subitem"
>
<NavLink
:item=
"childSubItem"
@
focusout=
"
isLastItemOfArray(childSubItem, subItem.items) &&
isLastItemOfArray(subItem, item.items) &&
setOpen(false)
"
/>
</li>
</ul>
<NavLink
v-else
:item=
"subItem"
@
focusout=
"isLastItemOfArray(subItem, item.items) && setOpen(false)"
/>
</li>
</ul>
</DropdownTransition>
</div>
</
template
>
<
script
>
import
NavLink
from
'
@theme/components/NavLink.vue
'
import
DropdownTransition
from
'
@theme/components/DropdownTransition.vue
'
import
last
from
'
lodash/last
'
export
default
{
name
:
'
DropdownLink
'
,
components
:
{
NavLink
,
DropdownTransition
},
props
:
{
item
:
{
required
:
true
}
},
data
()
{
return
{
open
:
false
}
},
computed
:
{
dropdownAriaLabel
()
{
return
this
.
item
.
ariaLabel
||
this
.
item
.
text
}
},
watch
:
{
$route
()
{
this
.
open
=
false
}
},
methods
:
{
setOpen
(
value
)
{
this
.
open
=
value
},
isLastItemOfArray
(
item
,
array
)
{
return
last
(
array
)
===
item
},
/**
* Open the dropdown when user tab and click from keyboard.
*
* Use event.detail to detect tab and click from keyboard. Ref: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail
* The Tab + Click is UIEvent > KeyboardEvent, so the detail is 0.
*/
handleDropdown
()
{
const
isTriggerByTab
=
event
.
detail
===
0
if
(
isTriggerByTab
)
this
.
setOpen
(
!
this
.
open
)
}
}
}
</
script
>
<
style
lang=
"stylus"
>
.dropdown-wrapper
cursor pointer
.dropdown-title
display block
font-size 0.9rem
font-family inherit
cursor inherit
padding inherit
line-height 1.4rem
background transparent
border none
font-weight 500
color $textColor
&:hover
border-color transparent
.arrow
vertical-align middle
margin-top -1px
margin-left 0.4rem
.mobile-dropdown-title
@extends .dropdown-title
display none
font-weight 600
font-size inherit
&:hover
color $accentColor
.nav-dropdown
.dropdown-item
color inherit
line-height 1.7rem
h4
margin 0.45rem 0 0
border-top 1px solid #eee
padding 1rem 1.5rem 0.45rem 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
&: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
.dropdown-title
display: none
.mobile-dropdown-title
display: block
.nav-dropdown
transition height .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,
&.open .nav-dropdown
// override the inline style.
display block !important
&.open:blur
display none
.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
>
docs/.vuepress/themes/theme-gitcode/components/DropdownTransition.vue
0 → 100644
浏览文件 @
65de1751
<
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
>
docs/.vuepress/themes/theme-gitcode/components/Home.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<main
class=
"home"
:aria-labelledby=
"data.heroText !== null ? 'main-title' : null"
>
<header
class=
"hero"
>
<img
v-if=
"data.heroImage"
:src=
"$withBase(data.heroImage)"
:alt=
"data.heroAlt || 'hero'"
>
<h1
v-if=
"data.heroText !== null"
id=
"main-title"
>
{{
data
.
heroText
||
$title
||
'
Hello
'
}}
</h1>
<p
v-if=
"data.tagline !== null"
class=
"description"
>
{{
data
.
tagline
||
$description
||
'
Welcome to your VuePress site
'
}}
</p>
<p
v-if=
"data.actionText && data.actionLink"
class=
"action"
>
<NavLink
class=
"action-button"
:item=
"actionLink"
/>
</p>
</header>
<div
v-if=
"data.features && data.features.length"
class=
"features"
>
<div
v-for=
"(feature, index) in data.features"
:key=
"index"
class=
"feature"
>
<h2>
{{
feature
.
title
}}
</h2>
<p>
{{
feature
.
details
}}
</p>
</div>
</div>
<Content
class=
"theme-default-content custom"
/>
<div
v-if=
"data.footer"
class=
"footer"
>
{{
data
.
footer
}}
</div>
<Content
v-else
slot-key=
"footer"
class=
"footer"
/>
</main>
</
template
>
<
script
>
import
NavLink
from
'
@theme/components/NavLink.vue
'
export
default
{
name
:
'
Home
'
,
components
:
{
NavLink
},
computed
:
{
data
()
{
return
this
.
$page
.
frontmatter
},
actionLink
()
{
return
{
link
:
this
.
data
.
actionLink
,
text
:
this
.
data
.
actionText
}
}
}
}
</
script
>
<
style
lang=
"stylus"
>
.home
padding $navbarHeight 2rem 0
max-width $homePageWidth
margin 0px auto
display block
.hero
text-align center
img
max-width: 100%
max-height 280px
display block
margin 3rem auto 1.5rem
h1
font-size 3rem
h1, .description, .action
margin 1.8rem auto
.description
max-width 35rem
font-size 1.6rem
line-height 1.3
color lighten($textColor, 40%)
.action-button
display inline-block
font-size 1.2rem
color #fff
background-color $accentColor
padding 0.8rem 1.6rem
border-radius 4px
transition background-color .1s ease
box-sizing border-box
border-bottom 1px solid darken($accentColor, 10%)
&:hover
background-color lighten($accentColor, 10%)
.features
border-top 1px solid $borderColor
padding 1.2rem 0
margin-top 2.5rem
display flex
flex-wrap wrap
align-items flex-start
align-content stretch
justify-content space-between
.feature
flex-grow 1
flex-basis 30%
max-width 30%
h2
font-size 1.4rem
font-weight 500
border-bottom none
padding-bottom 0
color lighten($textColor, 10%)
p
color lighten($textColor, 25%)
.footer
padding 2.5rem
border-top 1px solid $borderColor
text-align center
color lighten($textColor, 25%)
@media (max-width: $MQMobile)
.home
.features
flex-direction column
.feature
max-width 100%
padding 0 2.5rem
@media (max-width: $MQMobileNarrow)
.home
padding-left 1.5rem
padding-right 1.5rem
.hero
img
max-height 210px
margin 2rem auto 1.2rem
h1
font-size 2rem
h1, .description, .action
margin 1.2rem auto
.description
font-size 1.2rem
.action-button
font-size 1rem
padding 0.6rem 1.2rem
.feature
h2
font-size 1.25rem
</
style
>
docs/.vuepress/themes/theme-gitcode/components/NavLink.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<RouterLink
v-if=
"isInternal"
class=
"nav-link"
:to=
"link"
:exact=
"exact"
@
focusout.native=
"focusoutAction"
>
{{
item
.
text
}}
</RouterLink>
<a
v-else
:href=
"link"
class=
"nav-link external"
:target=
"target"
:rel=
"rel"
@
focusout=
"focusoutAction"
>
{{
item
.
text
}}
<OutboundLink
v-if=
"isBlankTarget"
/>
</a>
</
template
>
<
script
>
import
{
isExternal
,
isMailto
,
isTel
,
ensureExt
}
from
'
../util
'
export
default
{
name
:
'
NavLink
'
,
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
===
'
/
'
},
isNonHttpURI
()
{
return
isMailto
(
this
.
link
)
||
isTel
(
this
.
link
)
},
isBlankTarget
()
{
return
this
.
target
===
'
_blank
'
},
isInternal
()
{
return
!
isExternal
(
this
.
link
)
&&
!
this
.
isBlankTarget
},
target
()
{
if
(
this
.
isNonHttpURI
)
{
return
null
}
if
(
this
.
item
.
target
)
{
return
this
.
item
.
target
}
return
isExternal
(
this
.
link
)
?
'
_blank
'
:
''
},
rel
()
{
if
(
this
.
isNonHttpURI
)
{
return
null
}
if
(
this
.
item
.
rel
===
false
)
{
return
null
}
if
(
this
.
item
.
rel
)
{
return
this
.
item
.
rel
}
return
this
.
isBlankTarget
?
'
noopener noreferrer
'
:
null
}
},
methods
:
{
focusoutAction
()
{
this
.
$emit
(
'
focusout
'
)
}
}
}
</
script
>
docs/.vuepress/themes/theme-gitcode/components/NavLinks.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<nav
v-if=
"userLinks.length || repoLink"
class=
"nav-links"
>
<!-- user links -->
<div
v-for=
"item in userLinks"
:key=
"item.link"
class=
"nav-item"
>
<DropdownLink
v-if=
"item.type === 'links'"
:item=
"item"
/>
<NavLink
v-else
:item=
"item"
/>
</div>
<!-- repo link -->
<a
v-if=
"repoLink"
:href=
"repoLink"
class=
"repo-link"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
repoLabel
}}
<OutboundLink
/>
</a>
</nav>
</
template
>
<
script
>
import
DropdownLink
from
'
@theme/components/DropdownLink.vue
'
import
{
resolveNavLinkItem
}
from
'
../util
'
import
NavLink
from
'
@theme/components/NavLink.vue
'
export
default
{
name
:
'
NavLinks
'
,
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
'
,
ariaLabel
:
this
.
$themeLocaleConfig
.
ariaLabel
||
'
Select language
'
,
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
)
})
})
},
repoLink
()
{
const
{
repo
}
=
this
.
$site
.
themeConfig
if
(
repo
)
{
return
/^https
?
:/
.
test
(
repo
)
?
repo
:
`https://github.com/
${
repo
}
`
}
return
null
},
repoLabel
()
{
if
(
!
this
.
repoLink
)
return
if
(
this
.
$site
.
themeConfig
.
repoLabel
)
{
return
this
.
$site
.
themeConfig
.
repoLabel
}
const
repoHost
=
this
.
repoLink
.
match
(
/^https
?
:
\/\/[^/]
+/
)[
0
]
const
platforms
=
[
'
GitHub
'
,
'
GitLab
'
,
'
Bitbucket
'
]
for
(
let
i
=
0
;
i
<
platforms
.
length
;
i
++
)
{
const
platform
=
platforms
[
i
]
if
(
new
RegExp
(
platform
,
'
i
'
).
test
(
repoHost
))
{
return
platform
}
}
return
'
Source
'
}
}
}
</
script
>
<
style
lang=
"stylus"
>
.nav-links
display inline-block
a
line-height 1.4rem
color inherit
&:hover, &.router-link-active
color $accentColor
.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 $textColor
.nav-item > a:not(.external)
&:hover, &.router-link-active
margin-bottom -2px
border-bottom 2px solid lighten($accentColor, 8%)
</
style
>
docs/.vuepress/themes/theme-gitcode/components/Navbar.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<header
class=
"navbar"
>
<SidebarButton
@
toggle-sidebar=
"$emit('toggle-sidebar')"
/>
<RouterLink
:to=
"$localePath"
class=
"home-link"
>
<img
v-if=
"$site.themeConfig.logo"
class=
"logo"
:src=
"$withBase($site.themeConfig.logo)"
:alt=
"$siteTitle"
>
<span
v-if=
"$siteTitle"
ref=
"siteName"
class=
"site-name"
:class=
"
{ 'can-hide': $site.themeConfig.logo }"
>
{{
$siteTitle
}}
</span>
</RouterLink>
<div
class=
"links"
:style=
"linksWrapMaxWidth ?
{
'max-width': linksWrapMaxWidth + 'px'
} : {}"
>
<AlgoliaSearchBox
v-if=
"isAlgoliaSearch"
:options=
"algolia"
/>
<SearchBox
v-else-if=
"$site.themeConfig.search !== false && $page.frontmatter.search !== false"
/>
<NavLinks
class=
"can-hide"
/>
</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
{
name
:
'
Navbar
'
,
components
:
{
SidebarButton
,
NavLinks
,
SearchBox
,
AlgoliaSearchBox
},
data
()
{
return
{
linksWrapMaxWidth
:
null
}
},
computed
:
{
algolia
()
{
return
this
.
$themeLocaleConfig
.
algolia
||
this
.
$site
.
themeConfig
.
algolia
||
{}
},
isAlgoliaSearch
()
{
return
this
.
algolia
&&
this
.
algolia
.
apiKey
&&
this
.
algolia
.
indexName
}
},
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
)
}
}
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
a, span, img
display inline-block
.logo
height $navbarHeight - 1.4rem
min-width $navbarHeight - 1.4rem
margin-right 0.8rem
vertical-align top
.site-name
font-size 1.3rem
font-weight 600
color $textColor
position relative
.links
padding-left 1.5rem
box-sizing border-box
background-color white
white-space nowrap
font-size 0.9rem
position absolute
right $navbar-horizontal-padding
top $navbar-vertical-padding
display flex
.search-box
flex: 0 0 auto
vertical-align top
@media (max-width: $MQMobile)
.navbar
padding-left 4rem
.can-hide
display none
.links
padding-left 1.5rem
.site-name
width calc(100vw - 9.4rem)
overflow hidden
white-space nowrap
text-overflow ellipsis
</
style
>
docs/.vuepress/themes/theme-gitcode/components/Page.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<main
class=
"page"
>
<slot
name=
"top"
/>
<Content
class=
"theme-default-content"
/>
<PageEdit
/>
<PageNav
v-bind=
"
{ sidebarItems }" />
<slot
name=
"bottom"
/>
</main>
</
template
>
<
script
>
import
PageEdit
from
'
@theme/components/PageEdit.vue
'
import
PageNav
from
'
@theme/components/PageNav.vue
'
export
default
{
components
:
{
PageEdit
,
PageNav
},
props
:
[
'
sidebarItems
'
]
}
</
script
>
<
style
lang=
"stylus"
>
@require '../styles/wrapper.styl'
.page
padding-bottom 2rem
display block
</
style
>
docs/.vuepress/themes/theme-gitcode/components/PageEdit.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<footer
class=
"page-edit"
>
<div
v-if=
"editLink"
class=
"edit-link"
>
<a
:href=
"editLink"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
editLinkText
}}
</a>
<OutboundLink
/>
</div>
<div
v-if=
"lastUpdated"
class=
"last-updated"
>
<span
class=
"prefix"
>
{{
lastUpdatedText
}}
:
</span>
<span
class=
"time"
>
{{
lastUpdated
}}
</span>
</div>
</footer>
</
template
>
<
script
>
import
isNil
from
'
lodash/isNil
'
import
{
endingSlashRE
,
outboundRE
}
from
'
../util
'
export
default
{
name
:
'
PageEdit
'
,
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
'
},
editLink
()
{
const
showEditLink
=
isNil
(
this
.
$page
.
frontmatter
.
editLink
)
?
this
.
$site
.
themeConfig
.
editLinks
:
this
.
$page
.
frontmatter
.
editLink
const
{
repo
,
docsDir
=
''
,
docsBranch
=
'
master
'
,
docsRepo
=
repo
}
=
this
.
$site
.
themeConfig
if
(
showEditLink
&&
docsRepo
&&
this
.
$page
.
relativePath
)
{
return
this
.
createEditLink
(
repo
,
docsRepo
,
docsDir
,
docsBranch
,
this
.
$page
.
relativePath
)
}
return
null
},
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
(
docsRepo
))
{
const
base
=
docsRepo
return
(
base
.
replace
(
endingSlashRE
,
''
)
+
`/src`
+
`/
${
docsBranch
}
/`
+
(
docsDir
?
docsDir
.
replace
(
endingSlashRE
,
''
)
+
'
/
'
:
''
)
+
path
+
`?mode=edit&spa=0&at=
${
docsBranch
}
&fileviewer=file-view-default`
)
}
const
gitlab
=
/gitlab.com/
if
(
gitlab
.
test
(
docsRepo
))
{
const
base
=
docsRepo
return
(
base
.
replace
(
endingSlashRE
,
''
)
+
`/-/edit`
+
`/
${
docsBranch
}
/`
+
(
docsDir
?
docsDir
.
replace
(
endingSlashRE
,
''
)
+
'
/
'
:
''
)
+
path
)
}
const
gitcode
=
/gitcode.net/
if
(
gitcode
.
test
(
docsRepo
))
{
const
base
=
docsRepo
return
(
base
.
replace
(
endingSlashRE
,
''
)
+
`/-/blob`
+
`/
${
docsBranch
}
/`
+
(
docsDir
?
docsDir
.
replace
(
endingSlashRE
,
''
)
+
'
/
'
:
''
)
+
path
)
}
const
base
=
outboundRE
.
test
(
docsRepo
)
?
docsRepo
:
`https://github.com/
${
docsRepo
}
`
return
(
base
.
replace
(
endingSlashRE
,
''
)
+
'
/edit
'
+
`/
${
docsBranch
}
/`
+
(
docsDir
?
docsDir
.
replace
(
endingSlashRE
,
''
)
+
'
/
'
:
''
)
+
path
)
}
}
}
</
script
>
<
style
lang=
"stylus"
>
@require '../styles/wrapper.styl'
.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 #767676
@media (max-width: $MQMobile)
.page-edit
.edit-link
margin-bottom 0.5rem
.last-updated
font-size 0.8em
float none
text-align left
</
style
>
docs/.vuepress/themes/theme-gitcode/components/PageNav.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<div
v-if=
"prev || next"
class=
"page-nav"
>
<p
class=
"inner"
>
<span
v-if=
"prev"
class=
"prev"
>
←
<a
v-if=
"prev.type === 'external'"
class=
"prev"
:href=
"prev.path"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
prev
.
title
||
prev
.
path
}}
<OutboundLink
/>
</a>
<RouterLink
v-else
class=
"prev"
:to=
"prev.path"
>
{{
prev
.
title
||
prev
.
path
}}
</RouterLink>
</span>
<span
v-if=
"next"
class=
"next"
>
<a
v-if=
"next.type === 'external'"
:href=
"next.path"
target=
"_blank"
rel=
"noopener noreferrer"
>
{{
next
.
title
||
next
.
path
}}
<OutboundLink
/>
</a>
<RouterLink
v-else
:to=
"next.path"
>
{{
next
.
title
||
next
.
path
}}
</RouterLink>
→
</span>
</p>
</div>
</
template
>
<
script
>
import
{
resolvePage
}
from
'
../util
'
import
isString
from
'
lodash/isString
'
import
isNil
from
'
lodash/isNil
'
export
default
{
name
:
'
PageNav
'
,
props
:
[
'
sidebarItems
'
],
computed
:
{
prev
()
{
return
resolvePageLink
(
LINK_TYPES
.
PREV
,
this
)
},
next
()
{
return
resolvePageLink
(
LINK_TYPES
.
NEXT
,
this
)
}
}
}
function
resolvePrev
(
page
,
items
)
{
return
find
(
page
,
items
,
-
1
)
}
function
resolveNext
(
page
,
items
)
{
return
find
(
page
,
items
,
1
)
}
const
LINK_TYPES
=
{
NEXT
:
{
resolveLink
:
resolveNext
,
getThemeLinkConfig
:
({
nextLinks
})
=>
nextLinks
,
getPageLinkConfig
:
({
frontmatter
})
=>
frontmatter
.
next
},
PREV
:
{
resolveLink
:
resolvePrev
,
getThemeLinkConfig
:
({
prevLinks
})
=>
prevLinks
,
getPageLinkConfig
:
({
frontmatter
})
=>
frontmatter
.
prev
}
}
function
resolvePageLink
(
linkType
,
{
$themeConfig
,
$page
,
$route
,
$site
,
sidebarItems
}
)
{
const
{
resolveLink
,
getThemeLinkConfig
,
getPageLinkConfig
}
=
linkType
// Get link config from theme
const
themeLinkConfig
=
getThemeLinkConfig
(
$themeConfig
)
// Get link config from current page
const
pageLinkConfig
=
getPageLinkConfig
(
$page
)
// Page link config will overwrite global theme link config if defined
const
link
=
isNil
(
pageLinkConfig
)
?
themeLinkConfig
:
pageLinkConfig
if
(
link
===
false
)
{
return
}
else
if
(
isString
(
link
))
{
return
resolvePage
(
$site
.
pages
,
link
,
$route
.
path
)
}
else
{
return
resolveLink
(
$page
,
sidebarItems
)
}
}
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-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
</
style
>
docs/.vuepress/themes/theme-gitcode/components/Sidebar.vue
0 → 100644
浏览文件 @
65de1751
<
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
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.25rem
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.7
font-weight bold
& > li:not(:first-child)
margin-top .75rem
@media (max-width: $MQMobile)
.sidebar
.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
>
docs/.vuepress/themes/theme-gitcode/components/SidebarButton.vue
0 → 100644
浏览文件 @
65de1751
<
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
>
docs/.vuepress/themes/theme-gitcode/components/SidebarGroup.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<section
class=
"sidebar-group"
:class=
"[
{
collapsable,
'is-sub-group': depth !== 0
},
`depth-${depth}`
]"
>
<RouterLink
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
v-if=
"collapsable"
class=
"arrow"
:class=
"open ? 'down' : 'right'"
/>
</RouterLink>
<p
v-else
class=
"sidebar-heading"
:class=
"
{ open }"
@click="$emit('toggle')"
>
<span>
{{
item
.
title
}}
</span>
<span
v-if=
"collapsable"
class=
"arrow"
:class=
"open ? 'down' : 'right'"
/>
</p>
<DropdownTransition>
<SidebarLinks
v-if=
"open || !collapsable"
class=
"sidebar-group-items"
:items=
"item.children"
:sidebar-depth=
"item.sidebarDepth"
:initial-open-group-index=
"item.initialOpenGroupIndex"
:depth=
"depth + 1"
/>
</DropdownTransition>
</section>
</
template
>
<
script
>
import
{
isActive
}
from
'
../util
'
import
DropdownTransition
from
'
@theme/components/DropdownTransition.vue
'
export
default
{
name
:
'
SidebarGroup
'
,
components
:
{
DropdownTransition
},
props
:
[
'
item
'
,
'
open
'
,
'
collapsable
'
,
'
depth
'
],
// ref: https://vuejs.org/v2/guide/components-edge-cases.html#Circular-References-Between-Components
beforeCreate
()
{
this
.
$options
.
components
.
SidebarLinks
=
require
(
'
@theme/components/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 $textColor
transition color .15s ease
cursor pointer
font-size 1.1em
font-weight bold
// 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
&.open, &:hover
color inherit
.arrow
position relative
top -0.12em
left 0.5em
&.clickable
&.active
font-weight 600
color $accentColor
border-left-color $accentColor
&:hover
color $accentColor
.sidebar-group-items
transition height .1s ease-out
font-size 0.95em
overflow hidden
</
style
>
docs/.vuepress/themes/theme-gitcode/components/SidebarLink.vue
0 → 100644
浏览文件 @
65de1751
<
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
maxDepth
=
[
$page
.
frontmatter
.
sidebarDepth
,
sidebarDepth
,
$themeLocaleConfig
.
sidebarDepth
,
$themeConfig
.
sidebarDepth
,
1
].
find
(
depth
=>
depth
!==
undefined
)
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
,
level
)
{
const
component
=
{
props
:
{
to
,
activeClass
:
''
,
exactActiveClass
:
''
},
class
:
{
active
,
'
sidebar-link
'
:
true
}
}
if
(
level
>
2
)
{
component
.
style
=
{
'
padding-left
'
:
level
+
'
rem
'
}
}
return
h
(
'
RouterLink
'
,
component
,
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
,
c
.
level
-
1
),
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 1em
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.4
width: 100%
box-sizing: border-box
&:hover
color $accentColor
&.active
font-weight 600
color $accentColor
border-left-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
>
docs/.vuepress/themes/theme-gitcode/components/SidebarLinks.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<ul
v-if=
"items.length"
class=
"sidebar-links"
>
<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
:sidebar-depth=
"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
'
initialOpenGroupIndex
'
],
data
()
{
return
{
openGroupIndex
:
this
.
initialOpenGroupIndex
||
0
}
},
watch
:
{
'
$route
'
()
{
this
.
refreshIndex
()
}
},
created
()
{
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
(
descendantIsActive
(
route
,
item
))
{
return
i
}
}
return
-
1
}
function
descendantIsActive
(
route
,
item
)
{
if
(
item
.
type
===
'
group
'
)
{
const
childIsActive
=
item
.
path
&&
isActive
(
route
,
item
.
path
)
const
grandChildIsActive
=
item
.
children
.
some
(
child
=>
{
if
(
child
.
type
===
'
group
'
)
{
return
descendantIsActive
(
route
,
child
)
}
else
{
return
child
.
type
===
'
page
'
&&
isActive
(
route
,
child
.
path
)
}
})
return
childIsActive
||
grandChildIsActive
}
return
false
}
</
script
>
docs/.vuepress/themes/theme-gitcode/global-components/Badge.vue
0 → 100644
浏览文件 @
65de1751
<
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 $badgeTipColor
&.error
background-color $badgeErrorColor
&.warning, &.warn, &.yellow
background-color $badgeWarningColor
& + &
margin-left 5px
</
style
>
docs/.vuepress/themes/theme-gitcode/global-components/CodeBlock.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<div
class=
"theme-code-block"
:class=
"
{ 'theme-code-block__active': active }"
>
<slot
/>
</div>
</
template
>
<
script
>
export
default
{
name
:
'
CodeBlock
'
,
props
:
{
title
:
{
type
:
String
,
required
:
true
},
active
:
{
type
:
Boolean
,
default
:
false
}
},
mounted
()
{
if
(
this
.
$parent
&&
this
.
$parent
.
loadTabs
)
{
this
.
$parent
.
loadTabs
()
}
}
}
</
script
>
<
style
scoped
>
.theme-code-block
{
display
:
none
;
}
.theme-code-block__active
{
display
:
block
;
}
.theme-code-block
>
pre
{
background-color
:
orange
;
}
</
style
>
docs/.vuepress/themes/theme-gitcode/global-components/CodeGroup.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<ClientOnly>
<div
class=
"theme-code-group"
>
<div
class=
"theme-code-group__nav"
>
<ul
class=
"theme-code-group__ul"
>
<li
v-for=
"(tab, i) in codeTabs"
:key=
"tab.title"
class=
"theme-code-group__li"
>
<button
class=
"theme-code-group__nav-tab"
:class=
"
{
'theme-code-group__nav-tab-active': i === activeCodeTabIndex,
}"
@click="changeCodeTab(i)"
>
{{
tab
.
title
}}
</button>
</li>
</ul>
</div>
<slot
/>
<pre
v-if=
"codeTabs.length
<
1"
class=
"pre-blank"
>
// Make sure to add code blocks to your code group
</pre>
</div>
</ClientOnly>
</
template
>
<
script
>
export
default
{
name
:
'
CodeGroup
'
,
data
()
{
return
{
codeTabs
:
[],
activeCodeTabIndex
:
-
1
}
},
watch
:
{
activeCodeTabIndex
(
index
)
{
this
.
activateCodeTab
(
index
)
}
},
mounted
()
{
this
.
loadTabs
()
},
methods
:
{
changeCodeTab
(
index
)
{
this
.
activeCodeTabIndex
=
index
},
loadTabs
()
{
this
.
codeTabs
=
(
this
.
$slots
.
default
||
[]).
filter
(
slot
=>
Boolean
(
slot
.
componentOptions
)).
map
((
slot
,
index
)
=>
{
if
(
slot
.
componentOptions
.
propsData
.
active
===
''
)
{
this
.
activeCodeTabIndex
=
index
}
return
{
title
:
slot
.
componentOptions
.
propsData
.
title
,
elm
:
slot
.
elm
}
})
if
(
this
.
activeCodeTabIndex
===
-
1
&&
this
.
codeTabs
.
length
>
0
)
{
this
.
activeCodeTabIndex
=
0
}
this
.
activateCodeTab
(
0
)
},
activateCodeTab
(
index
)
{
this
.
codeTabs
.
forEach
(
tab
=>
{
if
(
tab
.
elm
)
{
tab
.
elm
.
classList
.
remove
(
'
theme-code-block__active
'
)
}
})
if
(
this
.
codeTabs
[
index
].
elm
)
{
this
.
codeTabs
[
index
].
elm
.
classList
.
add
(
'
theme-code-block__active
'
)
}
}
}
}
</
script
>
<
style
lang=
"stylus"
scoped
>
.theme-code-group {}
.theme-code-group__nav {
margin-bottom: -35px;
background-color: $codeBgColor;
padding-bottom: 22px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
padding-left: 10px;
padding-top: 10px;
}
.theme-code-group__ul {
margin: auto 0;
padding-left: 0;
display: inline-flex;
list-style: none;
}
.theme-code-group__li {}
.theme-code-group__nav-tab {
border: 0;
padding: 5px;
cursor: pointer;
background-color: transparent;
font-size: 0.85em;
line-height: 1.4;
color: rgba(255, 255, 255, 0.9);
font-weight: 600;
}
.theme-code-group__nav-tab-active {
border-bottom: #42b983 1px solid;
}
.pre-blank {
color: #42b983;
}
</
style
>
docs/.vuepress/themes/theme-gitcode/index.js
0 → 100644
浏览文件 @
65de1751
const
path
=
require
(
'
path
'
)
/**
* @type {import('@vuepress/types').Theme<import('@vuepress/types').DefaultThemeConfig>}
*/
module
.
exports
=
(
options
,
ctx
)
=>
{
const
{
themeConfig
,
siteConfig
}
=
ctx
// resolve algolia
const
isAlgoliaSearch
=
(
themeConfig
.
algolia
||
Object
.
keys
(
siteConfig
.
locales
&&
themeConfig
.
locales
||
{})
.
some
(
base
=>
themeConfig
.
locales
[
base
].
algolia
)
)
const
enableSmoothScroll
=
themeConfig
.
smoothScroll
===
true
return
{
alias
()
{
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
:
{
'
/
'
:
'
TIP
'
,
'
/zh/
'
:
'
提示
'
}
}],
[
'
container
'
,
{
type
:
'
warning
'
,
defaultTitle
:
{
'
/
'
:
'
WARNING
'
,
'
/zh/
'
:
'
注意
'
}
}],
[
'
container
'
,
{
type
:
'
danger
'
,
defaultTitle
:
{
'
/
'
:
'
DANGER
'
,
'
/zh/
'
:
'
警告
'
}
}],
[
'
container
'
,
{
type
:
'
details
'
,
before
:
info
=>
`<details class="custom-block details">
${
info
?
`<summary>
${
info
}
</summary>`
:
''
}
\n`
,
after
:
()
=>
'
</details>
\n
'
}],
[
'
smooth-scroll
'
,
enableSmoothScroll
]
]
}
}
docs/.vuepress/themes/theme-gitcode/layouts/404.vue
0 → 100644
浏览文件 @
65de1751
<
template
>
<div
class=
"theme-container"
>
<div
class=
"theme-default-content"
>
<h1>
404
</h1>
<blockquote>
{{
getMsg
()
}}
</blockquote>
<RouterLink
to=
"/"
>
Take me home.
</RouterLink>
</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
>
docs/.vuepress/themes/theme-gitcode/layouts/Layout.vue
0 → 100644
浏览文件 @
65de1751
<
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)"
/>
<Sidebar
:items=
"sidebarItems"
@
toggle-sidebar=
"toggleSidebar"
>
<template
#top
>
<slot
name=
"sidebar-top"
/>
</
template
>
<
template
#bottom
>
<slot
name=
"sidebar-bottom"
/>
</
template
>
</Sidebar>
<Home
v-if=
"$page.frontmatter.home"
/>
<Page
v-else
:sidebar-items=
"sidebarItems"
>
<
template
#top
>
<slot
name=
"page-top"
/>
</
template
>
<
template
#bottom
>
<slot
name=
"page-bottom"
/>
</
template
>
</Page>
</div>
</template>
<
script
>
import
Home
from
'
@theme/components/Home.vue
'
import
Navbar
from
'
@theme/components/Navbar.vue
'
import
Page
from
'
@theme/components/Page.vue
'
import
Sidebar
from
'
@theme/components/Sidebar.vue
'
import
{
resolveSidebarItems
}
from
'
../util
'
export
default
{
name
:
'
Layout
'
,
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
.
home
&&
frontmatter
.
sidebar
!==
false
&&
this
.
sidebarItems
.
length
)
},
sidebarItems
()
{
return
resolveSidebarItems
(
this
.
$page
,
this
.
$page
.
regularPath
,
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
()
{
this
.
$router
.
afterEach
(()
=>
{
this
.
isSidebarOpen
=
false
})
},
methods
:
{
toggleSidebar
(
to
)
{
this
.
isSidebarOpen
=
typeof
to
===
'
boolean
'
?
to
:
!
this
.
isSidebarOpen
this
.
$emit
(
'
toggle-sidebar
'
,
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
>
docs/.vuepress/themes/theme-gitcode/noopModule.js
0 → 100644
浏览文件 @
65de1751
export
default
{}
docs/.vuepress/themes/theme-gitcode/package.json
0 → 100644
浏览文件 @
65de1751
{
"name"
:
"@vuepress/theme-default"
,
"version"
:
"1.9.7"
,
"description"
:
"Default theme for VuePress"
,
"keywords"
:
[
"documentation"
,
"generator"
,
"vue"
,
"vuepress"
],
"homepage"
:
"https://github.com/vuejs/vuepress/blob/master/packages/@vuepress/theme-default#readme"
,
"bugs"
:
{
"url"
:
"https://github.com/vuejs/vuepress/issues"
},
"repository"
:
{
"type"
:
"git"
,
"url"
:
"git+https://github.com/vuejs/vuepress.git"
,
"directory"
:
"packages/@vuepress/theme-default"
},
"license"
:
"MIT"
,
"author"
:
"Evan You"
,
"maintainers"
:
[
{
"name"
:
"ULIVZ"
,
"email"
:
"chl814@foxmail.com"
}
],
"main"
:
"index.js"
,
"dependencies"
:
{
"@vuepress/plugin-active-header-links"
:
"1.9.7"
,
"@vuepress/plugin-nprogress"
:
"1.9.7"
,
"@vuepress/plugin-search"
:
"1.9.7"
,
"@vuepress/types"
:
"1.9.7"
,
"docsearch.js"
:
"^2.5.2"
,
"lodash"
:
"^4.17.15"
,
"stylus"
:
"^0.54.8"
,
"stylus-loader"
:
"^3.0.2"
,
"vuepress-plugin-container"
:
"^2.0.2"
,
"vuepress-plugin-smooth-scroll"
:
"^0.0.3"
},
"publishConfig"
:
{
"access"
:
"public"
},
"gitHead"
:
"2f2357acce09eab875325c05f26d6bd26d41a861"
}
docs/.vuepress/themes/theme-gitcode/styles/arrow.styl
0 → 100644
浏览文件 @
65de1751
@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
docs/.vuepress/themes/theme-gitcode/styles/code.styl
0 → 100644
浏览文件 @
65de1751
{$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-php"]:before
content "php"
@import '~prismjs/themes/prism-tomorrow.css'
docs/.vuepress/themes/theme-gitcode/styles/config.styl
0 → 100644
浏览文件 @
65de1751
$contentClass = '.theme-default-content'
docs/.vuepress/themes/theme-gitcode/styles/custom-blocks.styl
0 → 100644
浏览文件 @
65de1751
.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
&.details
display block
position relative
border-radius 2px
margin 1.6em 0
padding 1.6em
background-color #eee
h4
margin-top 0
figure, p
&:last-child
margin-bottom 0
padding-bottom 0
summary
outline none
cursor pointer
docs/.vuepress/themes/theme-gitcode/styles/index.styl
0 → 100644
浏览文件 @
65de1751
@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 16px
color $textColor
.page
padding-left $sidebarWidth
.navbar
position fixed
z-index 20
top 0
left 0
right 0
height $navbarHeight
background-color #fff
box-sizing border-box
border-bottom 1px solid $borderColor
.sidebar-mask
position fixed
z-index 9
top 0
left 0
width 100vw
height 100vh
display none
.sidebar
font-size 16px
background-color #fff
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
max-width 100%
{$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
&:focus .header-anchor,
&: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
&:focus,
&: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'
docs/.vuepress/themes/theme-gitcode/styles/mobile.styl
0 → 100644
浏览文件 @
65de1751
@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
docs/.vuepress/themes/theme-gitcode/styles/toc.styl
0 → 100644
浏览文件 @
65de1751
.table-of-contents
.badge
vertical-align middle
docs/.vuepress/themes/theme-gitcode/styles/wrapper.styl
0 → 100644
浏览文件 @
65de1751
$wrapper
max-width $contentWidth
margin 0 auto
padding 2rem 2.5rem
@media (max-width: $MQNarrow)
padding 2rem
@media (max-width: $MQMobileNarrow)
padding 1.5rem
docs/.vuepress/themes/theme-gitcode/util/index.js
0 → 100644
浏览文件 @
65de1751
export
const
hashRE
=
/#.*$/
export
const
extRE
=
/
\.(
md|html
)
$/
export
const
endingSlashRE
=
/
\/
$/
export
const
outboundRE
=
/^
[
a-z
]
+:/i
export
function
normalize
(
path
)
{
return
decodeURI
(
path
)
.
replace
(
hashRE
,
''
)
.
replace
(
extRE
,
''
)
}
export
function
getHash
(
path
)
{
const
match
=
path
.
match
(
hashRE
)
if
(
match
)
{
return
match
[
0
]
}
}
export
function
isExternal
(
path
)
{
return
outboundRE
.
test
(
path
)
}
export
function
isMailto
(
path
)
{
return
/^mailto:/
.
test
(
path
)
}
export
function
isTel
(
path
)
{
return
/^tel:/
.
test
(
path
)
}
export
function
ensureExt
(
path
)
{
if
(
isExternal
(
path
))
{
return
path
}
const
hashMatch
=
path
.
match
(
hashRE
)
const
hash
=
hashMatch
?
hashMatch
[
0
]
:
''
const
normalized
=
normalize
(
path
)
if
(
endingSlashRE
.
test
(
normalized
))
{
return
path
}
return
normalized
+
'
.html
'
+
hash
}
export
function
isActive
(
route
,
path
)
{
const
routeHash
=
decodeURIComponent
(
route
.
hash
)
const
linkHash
=
getHash
(
path
)
if
(
linkHash
&&
routeHash
!==
linkHash
)
{
return
false
}
const
routePath
=
normalize
(
route
.
path
)
const
pagePath
=
normalize
(
path
)
return
routePath
===
pagePath
}
export
function
resolvePage
(
pages
,
rawPath
,
base
)
{
if
(
isExternal
(
rawPath
))
{
return
{
type
:
'
external
'
,
path
:
rawPath
}
}
if
(
base
)
{
rawPath
=
resolvePath
(
rawPath
,
base
)
}
const
path
=
normalize
(
rawPath
)
for
(
let
i
=
0
;
i
<
pages
.
length
;
i
++
)
{
if
(
normalize
(
pages
[
i
].
regularPath
)
===
path
)
{
return
Object
.
assign
({},
pages
[
i
],
{
type
:
'
page
'
,
path
:
ensureExt
(
pages
[
i
].
path
)
})
}
}
console
.
error
(
`[vuepress] No matching page found for sidebar item "
${
rawPath
}
"`
)
return
{}
}
function
resolvePath
(
relative
,
base
,
append
)
{
const
firstChar
=
relative
.
charAt
(
0
)
if
(
firstChar
===
'
/
'
)
{
return
relative
}
if
(
firstChar
===
'
?
'
||
firstChar
===
'
#
'
)
{
return
base
+
relative
}
const
stack
=
base
.
split
(
'
/
'
)
// remove trailing segment if:
// - not appending
// - appending to trailing slash (last segment is empty)
if
(
!
append
||
!
stack
[
stack
.
length
-
1
])
{
stack
.
pop
()
}
// resolve relative path
const
segments
=
relative
.
replace
(
/^
\/
/
,
''
).
split
(
'
/
'
)
for
(
let
i
=
0
;
i
<
segments
.
length
;
i
++
)
{
const
segment
=
segments
[
i
]
if
(
segment
===
'
..
'
)
{
stack
.
pop
()
}
else
if
(
segment
!==
'
.
'
)
{
stack
.
push
(
segment
)
}
}
// ensure leading slash
if
(
stack
[
0
]
!==
''
)
{
stack
.
unshift
(
''
)
}
return
stack
.
join
(
'
/
'
)
}
/**
* @param { Page } page
* @param { string } regularPath
* @param { SiteData } site
* @param { string } localePath
* @returns { SidebarGroup }
*/
export
function
resolveSidebarItems
(
page
,
regularPath
,
site
,
localePath
)
{
const
{
pages
,
themeConfig
}
=
site
const
localeConfig
=
localePath
&&
themeConfig
.
locales
?
themeConfig
.
locales
[
localePath
]
||
themeConfig
:
themeConfig
const
pageSidebarConfig
=
page
.
frontmatter
.
sidebar
||
localeConfig
.
sidebar
||
themeConfig
.
sidebar
if
(
pageSidebarConfig
===
'
auto
'
)
{
return
resolveHeaders
(
page
)
}
const
sidebarConfig
=
localeConfig
.
sidebar
||
themeConfig
.
sidebar
if
(
!
sidebarConfig
)
{
return
[]
}
else
{
const
{
base
,
config
}
=
resolveMatchingConfig
(
regularPath
,
sidebarConfig
)
if
(
config
===
'
auto
'
)
{
return
resolveHeaders
(
page
)
}
return
config
?
config
.
map
(
item
=>
resolveItem
(
item
,
pages
,
base
))
:
[]
}
}
/**
* @param { Page } page
* @returns { SidebarGroup }
*/
function
resolveHeaders
(
page
)
{
const
headers
=
groupHeaders
(
page
.
headers
||
[])
return
[{
type
:
'
group
'
,
collapsable
:
false
,
title
:
page
.
title
,
path
:
null
,
children
:
headers
.
map
(
h
=>
({
type
:
'
auto
'
,
title
:
h
.
title
,
basePath
:
page
.
path
,
path
:
page
.
path
+
'
#
'
+
h
.
slug
,
children
:
h
.
children
||
[]
}))
}]
}
export
function
groupHeaders
(
headers
)
{
// group h3s under h2
headers
=
headers
.
map
(
h
=>
Object
.
assign
({},
h
))
let
lastH2
headers
.
forEach
(
h
=>
{
if
(
h
.
level
===
2
)
{
lastH2
=
h
}
else
if
(
lastH2
)
{
(
lastH2
.
children
||
(
lastH2
.
children
=
[])).
push
(
h
)
}
})
return
headers
.
filter
(
h
=>
h
.
level
===
2
)
}
export
function
resolveNavLinkItem
(
linkItem
)
{
return
Object
.
assign
(
linkItem
,
{
type
:
linkItem
.
items
&&
linkItem
.
items
.
length
?
'
links
'
:
'
link
'
})
}
/**
* @param { Route } route
* @param { Array<string|string[]> | Array<SidebarGroup> | [link: string]: SidebarConfig } config
* @returns { base: string, config: SidebarConfig }
*/
export
function
resolveMatchingConfig
(
regularPath
,
config
)
{
if
(
Array
.
isArray
(
config
))
{
return
{
base
:
'
/
'
,
config
:
config
}
}
for
(
const
base
in
config
)
{
if
(
ensureEndingSlash
(
regularPath
).
indexOf
(
encodeURI
(
base
))
===
0
)
{
return
{
base
,
config
:
config
[
base
]
}
}
}
return
{}
}
function
ensureEndingSlash
(
path
)
{
return
/
(\.
html|
\/)
$/
.
test
(
path
)
?
path
:
path
+
'
/
'
}
function
resolveItem
(
item
,
pages
,
base
,
groupDepth
=
1
)
{
if
(
typeof
item
===
'
string
'
)
{
return
resolvePage
(
pages
,
item
,
base
)
}
else
if
(
Array
.
isArray
(
item
))
{
return
Object
.
assign
(
resolvePage
(
pages
,
item
[
0
],
base
),
{
title
:
item
[
1
]
})
}
else
{
const
children
=
item
.
children
||
[]
if
(
children
.
length
===
0
&&
item
.
path
)
{
return
Object
.
assign
(
resolvePage
(
pages
,
item
.
path
,
base
),
{
title
:
item
.
title
})
}
return
{
type
:
'
group
'
,
path
:
item
.
path
,
title
:
item
.
title
,
sidebarDepth
:
item
.
sidebarDepth
,
initialOpenGroupIndex
:
item
.
initialOpenGroupIndex
,
children
:
children
.
map
(
child
=>
resolveItem
(
child
,
pages
,
base
,
groupDepth
+
1
)),
collapsable
:
item
.
collapsable
!==
false
}
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录