├── .gitignore ├── README.md ├── _config.yml ├── db.json ├── docs ├── document-guide.md └── post-guide.md ├── package-lock.json ├── package.json ├── scaffolds ├── draft.md ├── page.md └── post.md ├── source ├── CNAME ├── _posts │ ├── 2019-08 │ │ ├── CSS Houdini实现动态波浪纹.md │ │ ├── Javascript抽象语法树上篇(基础篇).md │ │ ├── Javascript抽象语法树下篇(实践篇).md │ │ └── collision-detection.md │ ├── 2019-09 │ │ ├── guid-mask.md │ │ ├── 【译】Web内容如何影响电池的使用.md │ │ ├── 【译】在生产环境中使用原生JavaScript模块.md │ │ ├── 前端资源治理(一).md │ │ ├── 手把手教你写webpack-loader.md │ │ └── 记一次Node-js直出服务的性能优化.md │ ├── 2019-10 │ │ ├── Electron-实践笔记.md │ │ ├── TypeScript安利指南.md │ │ ├── V8-引擎和Javascript优化建议.md │ │ ├── Vue-js-3-0编译器compiler-core源码解析.md │ │ ├── 【译】interection-observer如何观察变化.md │ │ ├── 写一个四则运算表达式转换成AST的方法.md │ │ ├── 手把手教你写一个AST解析器.md │ │ ├── 换种方式读源码:如何实现一个简易版的Mocha.md │ │ ├── 浏览器层合成与页面渲染优化.md │ │ └── 网页设计和开发中,关于字体的常识.md │ ├── 2019-11 │ │ ├── Interection-Observer如何观察变化.md │ │ ├── 你应该知道的折叠屏收集适配.md │ │ ├── 前端er须知的Nginx技巧.md │ │ ├── 深度揭秘Promise注册微任务和执行过程.md │ │ └── 老板的手机收到一个红包,为什么红包没居中?.md │ └── 2019-12 │ │ ├── Node-js项目TypeScript改造指南-二.md │ │ ├── Node-js项目TypeScript改造指南.md │ │ ├── 京东微信购物首页性能优化实践.md │ │ ├── 前端-JavaScript-错误分析实践.md │ │ ├── 负责任地编写JavaScript代码:第一部分.md │ │ ├── 负责任地编写JavaScript代码:第三部分.md │ │ └── 负责任地编写JavaScript代码:第二部分.md └── about │ └── index.md └── themes ├── icarus ├── LICENSE ├── README.md ├── _config.yml ├── includes │ ├── common │ │ ├── ConfigGenerator.js │ │ ├── ConfigValidator.js │ │ └── utils.js │ ├── filters │ │ └── highlight.js │ ├── generators │ │ ├── categories.js │ │ ├── category.js │ │ ├── insight.js │ │ └── tags.js │ ├── helpers │ │ ├── cdn.js │ │ ├── config.js │ │ ├── layout.js │ │ ├── override.js │ │ ├── page.js │ │ └── site.js │ ├── specs │ │ ├── article.spec.js │ │ ├── comment.spec.js │ │ ├── config.spec.js │ │ ├── donate.spec.js │ │ ├── footer.spec.js │ │ ├── icon_link.spec.js │ │ ├── meta.spec.js │ │ ├── navbar.spec.js │ │ ├── plugins.spec.js │ │ ├── providers.spec.js │ │ ├── search.spec.js │ │ ├── share.spec.js │ │ ├── sidebar.spec.js │ │ └── widgets.spec.js │ └── tasks │ │ ├── check_config.js │ │ ├── check_deps.js │ │ └── welcome.js ├── languages │ ├── en.yml │ ├── es.yml │ ├── fr.yml │ ├── id.yml │ ├── ja.yml │ ├── ko.yml │ ├── pt-BR.yml │ ├── ru.yml │ ├── tr.yml │ ├── vn.yml │ ├── zh-CN.yml │ ├── zh-Hans.yml │ └── zh-TW.yml ├── layout │ ├── archive.ejs │ ├── categories.ejs │ ├── category.ejs │ ├── comment │ │ ├── changyan.ejs │ │ ├── disqus.ejs │ │ ├── facebook.ejs │ │ ├── gitalk.ejs │ │ ├── gitment.ejs │ │ ├── isso.ejs │ │ ├── livere.ejs │ │ └── valine.ejs │ ├── common │ │ ├── article.ejs │ │ ├── footer.ejs │ │ ├── head.ejs │ │ ├── navbar.ejs │ │ ├── paginator.ejs │ │ ├── scripts.ejs │ │ └── widget.ejs │ ├── donate │ │ ├── alipay.ejs │ │ ├── patreon.ejs │ │ ├── paypal.ejs │ │ └── wechat.ejs │ ├── index.ejs │ ├── layout.ejs │ ├── page.ejs │ ├── plugin │ │ ├── animejs.ejs │ │ ├── back-to-top.ejs │ │ ├── baidu-analytics.ejs │ │ ├── busuanzi.ejs │ │ ├── gallery.ejs │ │ ├── google-analytics.ejs │ │ ├── hotjar.ejs │ │ ├── mathjax.ejs │ │ ├── outdated-browser.ejs │ │ └── progressbar.ejs │ ├── post.ejs │ ├── search │ │ ├── baidu.ejs │ │ ├── google-cse.ejs │ │ └── insight.ejs │ ├── share │ │ ├── addthis.ejs │ │ ├── addtoany.ejs │ │ ├── bdshare.ejs │ │ ├── sharejs.ejs │ │ └── sharethis.ejs │ ├── tag.ejs │ ├── tags.ejs │ └── widget │ │ ├── archive.ejs │ │ ├── category.ejs │ │ ├── links.ejs │ │ ├── profile.ejs │ │ ├── recent_posts.ejs │ │ ├── tag.ejs │ │ ├── tagcloud.ejs │ │ └── toc.ejs ├── package.json ├── scripts │ └── index.js └── source │ ├── css │ ├── back-to-top.css │ ├── insight.css │ ├── progressbar.css │ ├── search.css │ └── style.styl │ ├── images │ ├── avatar.png │ ├── favicon.ico │ ├── favicon.svg │ ├── logo.svg │ ├── og_image.png │ ├── og_image1.png │ └── thumbnail.svg │ └── js │ ├── animation.js │ ├── back-to-top.js │ ├── gallery.js │ ├── insight.js │ └── main.js └── landscape ├── .gitignore ├── Gruntfile.js ├── LICENSE ├── README.md ├── _config.yml ├── languages ├── de.yml ├── default.yml ├── es.yml ├── fr.yml ├── ja.yml ├── ko.yml ├── nl.yml ├── no.yml ├── pt.yml ├── ru.yml ├── zh-CN.yml └── zh-TW.yml ├── layout ├── _partial │ ├── after-footer.ejs │ ├── archive-post.ejs │ ├── archive.ejs │ ├── article.ejs │ ├── footer.ejs │ ├── gauges-analytics.ejs │ ├── google-analytics.ejs │ ├── head.ejs │ ├── header.ejs │ ├── mobile-nav.ejs │ ├── post │ │ ├── category.ejs │ │ ├── date.ejs │ │ ├── gallery.ejs │ │ ├── nav.ejs │ │ ├── tag.ejs │ │ └── title.ejs │ └── sidebar.ejs ├── _widget │ ├── archive.ejs │ ├── category.ejs │ ├── recent_posts.ejs │ ├── tag.ejs │ └── tagcloud.ejs ├── archive.ejs ├── category.ejs ├── index.ejs ├── layout.ejs ├── page.ejs ├── post.ejs └── tag.ejs ├── package.json ├── scripts └── fancybox.js └── source ├── css ├── _extend.styl ├── _partial │ ├── archive.styl │ ├── article.styl │ ├── comment.styl │ ├── footer.styl │ ├── header.styl │ ├── highlight.styl │ ├── mobile.styl │ ├── sidebar-aside.styl │ ├── sidebar-bottom.styl │ └── sidebar.styl ├── _util │ ├── grid.styl │ └── mixin.styl ├── _variables.styl ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── images │ └── banner.jpg └── style.styl ├── fancybox ├── blank.gif ├── fancybox_loading.gif ├── fancybox_loading@2x.gif ├── fancybox_overlay.png ├── fancybox_sprite.png ├── fancybox_sprite@2x.png ├── helpers │ ├── fancybox_buttons.png │ ├── jquery.fancybox-buttons.css │ ├── jquery.fancybox-buttons.js │ ├── jquery.fancybox-media.js │ ├── jquery.fancybox-thumbs.css │ └── jquery.fancybox-thumbs.js ├── jquery.fancybox.css ├── jquery.fancybox.js └── jquery.fancybox.pack.js └── js └── script.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | db.json 4 | *.log 5 | node_modules/ 6 | public/ 7 | .deploy*/ 8 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | # Hexo Configuration 2 | ## Docs: https://hexo.io/docs/configuration.html 3 | ## Source: https://github.com/hexojs/hexo/ 4 | 5 | # Site 6 | title: WecTeam 7 | subtitle: 8 | description: 9 | keywords: 10 | author: WecTeam 11 | language: zh-Hans 12 | timezone: 13 | 14 | # URL 15 | ## If your site is put in a subdirectory, set url as 'http://yoursite.com/child' and root as '/child/' 16 | url: https://wecteam.io/ 17 | root: / 18 | permalink: :year/:month/:day/:title/ 19 | permalink_defaults: 20 | 21 | # Directory 22 | source_dir: source 23 | public_dir: public 24 | tag_dir: tags 25 | archive_dir: archives 26 | category_dir: categories 27 | code_dir: downloads/code 28 | i18n_dir: :lang 29 | skip_render: 30 | 31 | # Writing 32 | new_post_name: :year-:month/:title.md # File name of new posts 33 | default_layout: post 34 | titlecase: false # Transform title into titlecase 35 | external_link: true # Open external links in new tab 36 | filename_case: 0 37 | render_drafts: false 38 | post_asset_folder: false 39 | relative_link: false 40 | future: true 41 | highlight: 42 | enable: true 43 | line_number: true 44 | auto_detect: false 45 | tab_replace: 46 | 47 | # Home page setting 48 | # path: Root path for your blogs index page. (default = '') 49 | # per_page: Posts displayed per page. (0 = disable pagination) 50 | # order_by: Posts order. (Order by date descending by default) 51 | index_generator: 52 | path: '' 53 | per_page: 10 54 | order_by: -date 55 | 56 | # Category & Tag 57 | default_category: uncategorized 58 | category_map: 59 | tag_map: 60 | 61 | # Date / Time format 62 | ## Hexo uses Moment.js to parse and display date 63 | ## You can customize the date format as defined in 64 | ## http://momentjs.com/docs/#/displaying/format/ 65 | date_format: YYYY-MM-DD 66 | time_format: HH:mm:ss 67 | 68 | # Pagination 69 | ## Set per_page to 0 to disable pagination 70 | per_page: 10 71 | pagination_dir: page 72 | 73 | # Extensions 74 | ## Plugins: https://hexo.io/plugins/ 75 | ## Themes: https://hexo.io/themes/ 76 | theme: icarus 77 | 78 | # Deployment 79 | ## Docs: https://hexo.io/docs/deployment.html 80 | deploy: 81 | type: git 82 | repository: https://github.com/wecteam/blog.git 83 | branch: gh-pages 84 | 85 | busuanzi: 86 | enable: true 87 | -------------------------------------------------------------------------------- /db.json: -------------------------------------------------------------------------------- 1 | {"meta":{"version":1,"warehouse":"2.2.0"},"models":{"Asset":[],"Cache":[],"Category":[],"Data":[],"Page":[],"Post":[],"PostAsset":[],"PostCategory":[],"PostTag":[],"Tag":[]}} -------------------------------------------------------------------------------- /docs/post-guide.md: -------------------------------------------------------------------------------- 1 | # 如何参与本博客文章的编写 2 | 3 | 本博客基于[hexo](https://hexo.io/zh-cn/docs/)搭建,hexo是一个著名的基于[markdown](https://www.jianshu.com/p/191d1e21f7ed)语法的静态博客工具。你只要按照以下基本操作,即可参与文章的编写! 4 | 5 | #### 克隆项目地址 6 | 首先在你本机创建一个空目录,然后在该目录下执行一下命令 7 | ``` bash 8 | $ git clone https://github.com/wecteam/blog 9 | ``` 10 | 如果没有权限,请联系steelli添加权限。 11 | 12 | #### 安装hexo 13 | 14 | ``` bash 15 | $ npm install hexo-cli -g 16 | 17 | ``` 18 | 写文章时建议在本地查看和预览,确认OK了才提交,因此强烈建议安装此工具,官方文档为[hexo概述](https://hexo.io/zh-cn/docs/)。 19 | 20 | #### 创建文章 21 | 在项目根目录下执行以下命令 22 | ``` bash 23 | $ hexo new your_title //直接创建post,可以直接查看 24 | $ hexo new draft your_title //创建草稿先(草稿不能直接被预览),需要执行publish命令发布到post目录才可以查看 25 | ``` 26 | 创建文章的相关命令参见[hexo写作](https://hexo.io/zh-cn/docs/writing)。 27 | 28 | #### 进入文章目录 29 | ``` bash 30 | $ cd blogs/source/_posts/{year}-{month}/ //若直接创建文章,{year}-{month}/表示文章所在目录,形如2019-08 31 | $ cd blogs/source/_drafts/{year}-{month}/ //若创建的是草稿,{year}-{month}/表示文章所在目录,形如2019-08 32 | ``` 33 | 如果一切正常,你将会看到以下目录结构: 34 | ``` 35 | ├── your-title //目录,用于存放图片等资源 36 | └── your-title.md //文章内容 37 | ``` 38 | 39 | #### 写文章 40 | 41 | 用你喜欢的IDE或者普通的文本编辑器编写文章。文章的内容包括两部分:元信息和内容主体。 42 | 43 | 文章元信息(metadata)格式如下: 44 | ``` 45 | --- 46 | title: 你的文章的标题 47 | date: 创建时间,自动生成 48 | cover: 封面图,请用绝对地址 49 | thumbnail: 缩略图,请用绝对地址 50 | tags: 51 | - 标签1 52 | - 标签2 53 | - 标签数量任意,请根据文章的内容来填写 54 | categories: 文章分类,目前仅 Node.js 和 Web前端 两个选项,后续有需要再添加 55 | --- 56 | ``` 57 | 此信息被hexo称为[Front-matter](https://hexo.io/zh-cn/docs/front-matter),语法采用[YMAL](https://www.jianshu.com/p/97222440cd08)语法。 58 | 59 | 内容主体紧接着元信息,采用标准的[markdown](https://www.jianshu.com/p/191d1e21f7ed)语法编写。 60 | 如果你已在其他地方编写好文章内容,直接复制过来贴在主体部分即可。 61 | 62 | 另外,每篇文章在首页显示的时候,仅显示文章开头一两段即可,完整的内容在文章详情页显示,因此这部分需要分隔出来,hexo是用HTML的注释‘’来隔开。 63 | 如下为示例: 64 | 65 | ```md 66 | # 是什么在耗电? 67 | 68 | 移动设备的电力消耗有以下几个因素: 69 | 70 | * CPU (核心处理器) 71 | * GPU (图形处理) 72 | * 网络 (wifi或者蜂窝移动网络) 73 | * 屏幕 74 | 75 | 屏幕功耗相对稳定,并且主要由用户控制(通过屏幕使用时间和亮度),但是对于其他组件,例如CPU,GPU,网络模块,功耗是动态变化的,而且变化范围很大。 76 | 77 | 78 | 79 | 系统根据当前正在处理的任务调整CPU和GPU性能,包括在Web浏览器中用户正在交互的网页以及使用Web内容的其他应用程序。这是通过打开或关闭某些组件以及通过更改其时钟频率来完成的。总的来说,芯片所需的性能越高,其功率效率就越低。硬件可以非常快速地提升到高性能(但是需要很大的功率),然后迅速恢复到更高效的低功耗状态。 80 | ``` 81 | 82 | #### 本地预览 83 | 编写的时候,建议先在本地预览确保内容OK。 84 | ``` bash 85 | $ hexo s //直接预览文章 86 | $ hexo s --draft //预览文章和草稿 87 | ``` 88 | 此会启动一个server,默认地址为http://localhost:4000 。你可以在本地进行预览。 89 | 更多hexo的命令参见[hexo命令](https://hexo.io/zh-cn/docs/commands)。 90 | 91 | #### 草稿转为正式文章 92 | 如果你创建的是草稿,请执行以下命令,将文章转成正式的post,从而让可以看到。 93 | ``` bash 94 | $ hexo publish your_title 95 | ``` 96 | 此命令将文章从_draft目录移动到_post目录。 97 | 98 | #### 生成静态HTML 99 | 本博客托管在github page上,部署之前需要先将markdown文件生成为静态HTML文件,执行以下命令生成: 100 | ``` bash 101 | $ hexo clean //清理缓存 102 | $ hexo g //全量生成HTML文件 103 | ``` 104 | 105 | #### 部署到官网 106 | 生成的静态HTML文件通过以下命令部署到官网。 107 | ``` bash 108 | $ hexo d 109 | ``` 110 | 此命令将HTML文件提交到github pages,大概2分钟之后刷新[https://wecteam.io](https://wecteam.io)就可以看到了。 111 | 112 | #### 提交到git 113 | 确认你的文章OK之后,直接提交到git即可。 114 | ``` bash 115 | $ git add * 116 | $ git commit -m "feat:add new post:{your_title}" 117 | $ git push 118 | ``` 119 | 120 | #### 文档排版规范 121 | 写文章前,请先看一下[文档排版规范](https://github.com/wecteam/blog/blob/master/docs/document-guide.md)。 122 | 123 | #### 图床工具 124 | 写文章免不了要做图片传图片,推荐使用iPic工具,不论屏幕截图、还是复制图片,都可以自动上传、保存 Markdown 格式的链接,直接粘贴插入。[神器地址](https://toolinbox.net/iPic/) -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-site", 3 | "version": "0.0.0", 4 | "private": true, 5 | "hexo": { 6 | "version": "3.9.0" 7 | }, 8 | "dependencies": { 9 | "eslint": "^6.3.0", 10 | "hexo": "^3.9.0", 11 | "hexo-deployer-git": "^1.0.0", 12 | "hexo-generator-archive": "^0.1.5", 13 | "hexo-generator-category": "^0.1.3", 14 | "hexo-generator-index": "^0.2.1", 15 | "hexo-generator-tag": "^0.2.0", 16 | "hexo-renderer-ejs": "^0.3.1", 17 | "hexo-renderer-marked": "^1.0.1", 18 | "hexo-renderer-stylus": "^0.3.3", 19 | "hexo-server": "^0.3.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /scaffolds/draft.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | tags: 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/page.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | --- 5 | -------------------------------------------------------------------------------- /scaffolds/post.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: {{ title }} 3 | date: {{ date }} 4 | tags: 5 | --- 6 | -------------------------------------------------------------------------------- /source/CNAME: -------------------------------------------------------------------------------- 1 | wecteam.io -------------------------------------------------------------------------------- /source/about/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: WecTeam | 京东社交电商前端团队 3 | date: 2019-09-10 18:08:41 4 | --- 5 | ## 维C团简介 6 | 7 | 维C团(WecTeam)是京东社交电商部一群热爱技术、乐于分享的前端工程师自发成立的一个前端技术团队,希望通过技术实践总结、新技术探秘、Bug深度分析、优质英文资料引入等方式,参与和推动前端技术的发展,为公司及行业带来价值! 8 | 9 | ## 联系我们 10 | ![qr_code](https://wq.360buyimg.com/data/ppms/picture/wecteam_qrcode.jpeg) -------------------------------------------------------------------------------- /themes/icarus/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 PPOffice 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /themes/icarus/includes/common/ConfigGenerator.js: -------------------------------------------------------------------------------- 1 | const yaml = require('js-yaml'); 2 | const Type = require('js-yaml/lib/js-yaml/type'); 3 | const Schema = require('js-yaml/lib/js-yaml/schema'); 4 | 5 | const { is, descriptors } = require('./utils'); 6 | const { doc, type, requires, defaultValue } = descriptors; 7 | 8 | const UNDEFINED = Symbol('undefined'); 9 | // output null as empty in yaml 10 | const YAML_SCHEMA = new Schema({ 11 | include: [ 12 | require('js-yaml/lib/js-yaml/schema/default_full') 13 | ], 14 | implicit: [ 15 | new Type('tag:yaml.org,2002:null', { 16 | kind: 'scalar', 17 | resolve(data) { 18 | if (data === null) { 19 | return true; 20 | } 21 | const max = data.length; 22 | return (max === 1 && data === '~') || 23 | (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL')); 24 | }, 25 | construct: () => null, 26 | predicate: object => object === null, 27 | represent: { 28 | empty: function () { return ''; } 29 | }, 30 | defaultStyle: 'empty' 31 | }) 32 | ] 33 | }); 34 | 35 | function appendDoc(spec, defaults) { 36 | if (defaults === null) { 37 | return null; 38 | } 39 | if (is.array(defaults) && spec.hasOwnProperty('*')) { 40 | return defaults.map(value => appendDoc(spec['*'], value)); 41 | } else if (is.object(defaults)) { 42 | const _defaults = {}; 43 | for (let key in defaults) { 44 | if (spec.hasOwnProperty(key) && spec[key].hasOwnProperty(doc)) { 45 | let i = 0; 46 | for (let line of spec[key][doc].split('\n')) { 47 | _defaults['#' + key + i++] = line; 48 | } 49 | } 50 | _defaults[key] = appendDoc(spec.hasOwnProperty(key) ? spec[key] : {}, defaults[key]); 51 | } 52 | return _defaults; 53 | } 54 | return defaults; 55 | } 56 | 57 | function generate(spec, parentConfig = null) { 58 | if (!is.spec(spec)) { 59 | return UNDEFINED; 60 | } 61 | if (spec.hasOwnProperty(requires) && !spec[requires](parentConfig)) { 62 | return UNDEFINED; 63 | } 64 | if (spec.hasOwnProperty(defaultValue)) { 65 | return appendDoc(spec, spec[defaultValue]); 66 | } 67 | const types = is.array(spec[type]) ? spec[type] : [spec[type]]; 68 | if (types.includes('object')) { 69 | let defaults = UNDEFINED; 70 | for (let key in spec) { 71 | if (key === '*') { 72 | continue; 73 | } 74 | const value = generate(spec[key], defaults); 75 | if (value !== UNDEFINED) { 76 | if (defaults === UNDEFINED) { 77 | defaults = {}; 78 | } 79 | defaults[key] = value; 80 | } 81 | } 82 | return appendDoc(spec, defaults); 83 | } else if (types.includes('array') && spec.hasOwnProperty('*')) { 84 | return [generate(spec['*'], {})]; 85 | } 86 | return UNDEFINED; 87 | } 88 | 89 | class ConfigGenerator { 90 | constructor(spec) { 91 | this.spec = spec; 92 | } 93 | 94 | generate() { 95 | return yaml.safeDump(generate(this.spec), { 96 | indent: 4, 97 | lineWidth: 1024, 98 | schema: YAML_SCHEMA 99 | }).replace(/^(\s*)\'#.*?\':\s*\'*(.*?)\'*$/mg, '$1# $2'); // make comment lines 100 | } 101 | } 102 | 103 | module.exports = ConfigGenerator; 104 | -------------------------------------------------------------------------------- /themes/icarus/includes/common/ConfigValidator.js: -------------------------------------------------------------------------------- 1 | const { is, descriptors } = require('./utils'); 2 | const { type, required, requires, format, defaultValue } = descriptors; 3 | const { 4 | InvalidSpecError, 5 | MissingRequiredError, 6 | TypeMismatchError, 7 | FormatMismatchError, 8 | VersionMalformedError, 9 | VersionNotFoundError, 10 | VersionMismatchError } = require('./utils').errors; 11 | 12 | function isRequiresSatisfied(spec, config) { 13 | try { 14 | if (!spec.hasOwnProperty(requires) || spec[requires](config) === true) { 15 | return true; 16 | } 17 | } catch (e) { } 18 | return false; 19 | } 20 | 21 | function getConfigType(spec, config) { 22 | const specTypes = is.array(spec[type]) ? spec[type] : [spec[type]]; 23 | for (let specType of specTypes) { 24 | if (is[specType](config)) { 25 | return specType; 26 | } 27 | } 28 | return null; 29 | } 30 | 31 | function hasFormat(spec, config) { 32 | if (!spec.hasOwnProperty(format)) { 33 | return true; 34 | } 35 | return spec[format].test(config); 36 | } 37 | 38 | function validate(spec, config, parentConfig, path) { 39 | if (!is.spec(spec)) { 40 | throw new InvalidSpecError(spec, path); 41 | } 42 | if (!isRequiresSatisfied(spec, parentConfig)) { 43 | return; 44 | } 45 | if (is.undefined(config) || is.null(config)) { 46 | if (spec[required] === true) { 47 | throw new MissingRequiredError(spec, path); 48 | } 49 | return; 50 | } 51 | const type = getConfigType(spec, config); 52 | if (type === null) { 53 | throw new TypeMismatchError(spec, path, config); 54 | } 55 | if (type === 'string') { 56 | if (!hasFormat(spec, config)) { 57 | throw new FormatMismatchError(spec, path, config); 58 | } 59 | } else if (type === 'array' && spec.hasOwnProperty('*')) { 60 | config.forEach((child, i) => validate(spec['*'], child, config, path.concat(`[${i}]`))); 61 | } else if (type === 'object') { 62 | for (let key in spec) { 63 | if (key === '*') { 64 | Object.keys(config).forEach(k => validate(spec['*'], config[k], config, path.concat(k))); 65 | } else { 66 | validate(spec[key], config[key], config, path.concat(key)); 67 | } 68 | } 69 | } 70 | } 71 | 72 | function formatVersion(ver) { 73 | const m = /^(\d)+\.(\d)+\.(\d)+(?:-([0-9A-Za-z-]+))*$/.exec(ver); 74 | if (m === null) { 75 | throw new VersionMalformedError(ver); 76 | } 77 | return { 78 | major: m[1], 79 | minor: m[2], 80 | patch: m[3], 81 | identifier: m.length > 4 ? m[4] : null 82 | }; 83 | } 84 | 85 | function compareVersion(ver1, ver2) { 86 | for (let section of ['major', 'minor', 'patch']) { 87 | if (ver1[section] !== ver2[section]) { 88 | return Math.sign(ver1[section] - ver2[section]); 89 | } 90 | } 91 | const id1 = ver1.hasOwnProperty('identifier') ? ver1.identifier : null; 92 | const id2 = ver2.hasOwnProperty('identifier') ? ver2.identifier : null; 93 | if (id1 === id2) { 94 | return 0; 95 | } 96 | if (id1 === null) { 97 | return 1; 98 | } 99 | if (id2 === null) { 100 | return -1; 101 | } 102 | return id1.localeCompare(id2); 103 | } 104 | 105 | function isBreakingChange(base, ver) { 106 | return base.major !== ver.major || base.minor !== ver.minor; 107 | } 108 | 109 | 110 | function checkVersion(spec, config) { 111 | if (!config.hasOwnProperty('version')) { 112 | throw new VersionNotFoundError(); 113 | } 114 | const configVersion = formatVersion(config.version); 115 | const specVersion = formatVersion(spec.version[defaultValue]); 116 | if (isBreakingChange(specVersion, configVersion)) { 117 | throw new VersionMismatchError(spec.version[defaultValue], config.version, compareVersion(specVersion, configVersion) > 0); 118 | } 119 | } 120 | 121 | class ConfigValidator { 122 | constructor(spec) { 123 | this.spec = spec; 124 | } 125 | 126 | validate(config) { 127 | checkVersion(this.spec, config); 128 | validate(this.spec, config, null, []); 129 | } 130 | } 131 | 132 | module.exports = ConfigValidator; -------------------------------------------------------------------------------- /themes/icarus/includes/common/utils.js: -------------------------------------------------------------------------------- 1 | const doc = Symbol('@doc'); 2 | const type = Symbol('@type'); 3 | const format = Symbol('@format'); 4 | const required = Symbol('@required'); 5 | const requires = Symbol('@requires'); 6 | const defaultValue = Symbol('@default'); 7 | 8 | const descriptors = { 9 | doc, 10 | type, 11 | format, 12 | requires, 13 | required, 14 | defaultValue 15 | }; 16 | 17 | const is = (() => ({ 18 | number(value) { 19 | return typeof (value) === 'number'; 20 | }, 21 | string(value) { 22 | return typeof (value) === 'string'; 23 | }, 24 | array(value) { 25 | return Array.isArray(value); 26 | }, 27 | boolean(value) { 28 | return typeof (value) === 'boolean'; 29 | }, 30 | object(value) { 31 | return typeof (value) === 'object' && value.constructor == Object; 32 | }, 33 | function(value) { 34 | return typeof (value) === 'function'; 35 | }, 36 | regexp(value) { 37 | return value instanceof RegExp; 38 | }, 39 | undefined(value) { 40 | return typeof (value) === 'undefined'; 41 | }, 42 | null(value) { 43 | return value === null; 44 | }, 45 | spec(value) { 46 | if (!value.hasOwnProperty(type)) { 47 | return false; 48 | } 49 | if (!is.string(value[type]) && !is.array(value[type])) { 50 | return false; 51 | } 52 | if (value.hasOwnProperty(doc) && !is.string(value[doc])) { 53 | return false; 54 | } 55 | if (value.hasOwnProperty(required) && !is.boolean(value[required])) { 56 | return false; 57 | } 58 | if (value.hasOwnProperty(requires) && !is.function(value[requires])) { 59 | return false; 60 | } 61 | if (value.hasOwnProperty(format) && !is.regexp(value[format])) { 62 | return false; 63 | } 64 | return true; 65 | } 66 | }))(); 67 | 68 | class ConfigError extends Error { 69 | constructor(spec, path) { 70 | super(); 71 | this.spec = spec; 72 | this.path = path; 73 | } 74 | } 75 | 76 | class InvalidSpecError extends ConfigError { 77 | constructor(spec, path) { 78 | super(spec, path); 79 | this.message = `The specification '${path.join('.')}' is invalid.`; 80 | } 81 | } 82 | 83 | class MissingRequiredError extends ConfigError { 84 | constructor(spec, path) { 85 | super(spec, path); 86 | this.message = `Configuration file do not have the required '${path.join('.')}' field.`; 87 | } 88 | } 89 | 90 | class TypeMismatchError extends ConfigError { 91 | constructor(spec, path, config) { 92 | super(spec, path); 93 | this.config = config; 94 | this.message = `Configuration '${path.join('.')}' is not one of the '${spec[type]}' type.`; 95 | } 96 | } 97 | 98 | class FormatMismatchError extends ConfigError { 99 | constructor(spec, path, config) { 100 | super(spec, path); 101 | this.config = config; 102 | this.message = `Configuration '${path.join('.')}' do not match the format '${spec[format]}'.`; 103 | } 104 | } 105 | 106 | class VersionError extends Error { 107 | } 108 | 109 | class VersionNotFoundError extends VersionError { 110 | constructor() { 111 | super(`Version number is not found in the configuration file.`); 112 | } 113 | } 114 | 115 | class VersionMalformedError extends VersionError { 116 | constructor(version) { 117 | super(`Version number ${version} is malformed.`); 118 | this.version = version; 119 | } 120 | } 121 | 122 | class VersionMismatchError extends VersionError { 123 | constructor(specVersion, configVersion, isConfigVersionSmaller) { 124 | super(); 125 | this.specVersion = specVersion; 126 | this.configVersion = configVersion; 127 | if (isConfigVersionSmaller) { 128 | this.message = `The configuration version ${configVersion} is far behind the specification version ${specVersion}.`; 129 | } else { 130 | this.message = `The configuration version ${configVersion} is way ahead of the specification version ${specVersion}.`; 131 | } 132 | } 133 | } 134 | 135 | const errors = { 136 | ConfigError, 137 | InvalidSpecError, 138 | MissingRequiredError, 139 | TypeMismatchError, 140 | FormatMismatchError, 141 | VersionError, 142 | VersionMalformedError, 143 | VersionNotFoundError, 144 | VersionMismatchError 145 | } 146 | 147 | module.exports = { 148 | is, 149 | descriptors, 150 | errors 151 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/filters/highlight.js: -------------------------------------------------------------------------------- 1 | const cheerio = require('cheerio'); 2 | 3 | module.exports = function (hexo) { 4 | function patchCodeHighlight(content) { 5 | const $ = cheerio.load(content, { decodeEntities: false }); 6 | $('figure.highlight').addClass('hljs'); 7 | $('figure.highlight .code .line span').each(function () { 8 | const classes = $(this).attr('class').split(' '); 9 | if (classes.length === 1) { 10 | $(this).addClass('hljs-' + classes[0]); 11 | $(this).removeClass(classes[0]); 12 | } 13 | }); 14 | return $.html(); 15 | } 16 | 17 | /** 18 | * Add .hljs class name to the code blocks and code elements 19 | */ 20 | hexo.extend.filter.register('after_post_render', function (data) { 21 | data.content = data.content ? patchCodeHighlight(data.content) : data.content; 22 | data.excerpt = data.excerpt ? patchCodeHighlight(data.excerpt) : data.excerpt; 23 | return data; 24 | }); 25 | } -------------------------------------------------------------------------------- /themes/icarus/includes/generators/categories.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Category list page generator 3 | */ 4 | module.exports = function (hexo) { 5 | hexo.extend.generator.register('categories', function (locals) { 6 | return { 7 | path: 'categories/', 8 | layout: ['categories'], 9 | data: Object.assign({}, locals, { 10 | __categories: true 11 | }) 12 | }; 13 | }); 14 | } -------------------------------------------------------------------------------- /themes/icarus/includes/generators/category.js: -------------------------------------------------------------------------------- 1 | const pagination = require('hexo-pagination'); 2 | 3 | module.exports = function (hexo) { 4 | // ATTENTION: This will override the default category generator! 5 | hexo.extend.generator.register('category', function(locals) { 6 | const config = this.config; 7 | const perPage = config.category_generator.per_page; 8 | const paginationDir = config.pagination_dir || 'page'; 9 | 10 | function findParent(category) { 11 | let parents = []; 12 | if (category && category.hasOwnProperty('parent')) { 13 | const parent = locals.categories.filter(cat => cat._id === category.parent).first(); 14 | parents = [parent].concat(findParent(parent)); 15 | } 16 | return parents; 17 | } 18 | 19 | return locals.categories.reduce(function(result, category){ 20 | const posts = category.posts.sort('-date'); 21 | const data = pagination(category.path, posts, { 22 | perPage: perPage, 23 | layout: ['category', 'archive', 'index'], 24 | format: paginationDir + '/%d/', 25 | data: { 26 | category: category.name, 27 | parents: findParent(category) 28 | } 29 | }); 30 | 31 | return result.concat(data); 32 | }, []); 33 | }); 34 | } -------------------------------------------------------------------------------- /themes/icarus/includes/generators/insight.js: -------------------------------------------------------------------------------- 1 | const util = require('hexo-util'); 2 | 3 | /** 4 | * Insight search content.json generator. 5 | */ 6 | module.exports = function (hexo) { 7 | hexo.extend.generator.register('insight', function (locals) { 8 | const url_for = hexo.extend.helper.get('url_for').bind(this); 9 | function minify(str) { 10 | return util.stripHTML(str).trim().replace(/\n/g, ' ').replace(/\s+/g, ' ') 11 | .replace(/&#x([\da-fA-F]+);/g, function (match, hex) { 12 | return String.fromCharCode(parseInt(hex, 16)); 13 | }) 14 | .replace(/&#([\d]+);/g, function (match, dec) { 15 | return String.fromCharCode(dec); 16 | }); 17 | } 18 | function postMapper(post) { 19 | return { 20 | title: post.title, 21 | text: minify(post.content), 22 | link: url_for(post.path) 23 | } 24 | } 25 | function tagMapper(tag) { 26 | return { 27 | name: tag.name, 28 | slug: tag.slug, 29 | link: url_for(tag.path) 30 | } 31 | } 32 | const site = { 33 | pages: locals.pages.map(postMapper), 34 | posts: locals.posts.map(postMapper), 35 | tags: locals.tags.map(tagMapper), 36 | categories: locals.categories.map(tagMapper) 37 | }; 38 | return { 39 | path: '/content.json', 40 | data: JSON.stringify(site) 41 | }; 42 | }); 43 | } -------------------------------------------------------------------------------- /themes/icarus/includes/generators/tags.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Tag list page generator 3 | */ 4 | module.exports = function (hexo) { 5 | hexo.extend.generator.register('tags', function (locals) { 6 | return { 7 | path: 'tags/', 8 | layout: ['tags'], 9 | data: Object.assign({}, locals, { 10 | __tags: true 11 | }) 12 | }; 13 | }); 14 | } -------------------------------------------------------------------------------- /themes/icarus/includes/helpers/cdn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * CDN static file resolvers. 3 | * 4 | * @example 5 | * <%- cdn(package, version, filename) %> 6 | * <%- fontcdn(fontName) %> 7 | * <%- iconcdn() %> 8 | */ 9 | const cdn_providers = { 10 | cdnjs: 'https://cdnjs.cloudflare.com/ajax/libs/${ package }/${ version }/${ filename }', 11 | jsdelivr: 'https://cdn.jsdelivr.net/npm/${ package }@${ version }/${ filename }', 12 | unpkg: 'https://unpkg.com/${ package }@${ version }/${ filename }' 13 | }; 14 | 15 | const font_providers = { 16 | google: 'https://fonts.googleapis.com/${ type }?family=${ fontname }' 17 | }; 18 | 19 | const icon_providers = { 20 | fontawesome: 'https://cdn.bootcss.com/font-awesome/5.4.1/css/all.min.css' 21 | }; 22 | 23 | module.exports = function (hexo) { 24 | hexo.extend.helper.register('cdn', function (_package, version, filename) { 25 | let provider = hexo.extend.helper.get('get_config').bind(this)('providers.cdn'); 26 | // cdn.js does not follow a GitHub npm style like jsdeliver and unpkg do. Patch it! 27 | if (provider === 'cdnjs' || provider.startsWith('[cdnjs]')) { 28 | if (provider.startsWith('[cdnjs]')) { 29 | provider = provider.substr(7); 30 | } 31 | if (filename.startsWith('dist/')) { 32 | filename = filename.substr(5); 33 | } 34 | if (_package === 'moment') { 35 | _package = 'moment.js'; 36 | filename = filename.startsWith('min/') ? filename.substr(4) : filename; 37 | } 38 | if (_package === 'outdatedbrowser') { 39 | _package = 'outdated-browser'; 40 | filename = filename.startsWith('outdatedbrowser/') ? filename.substr(16) : filename; 41 | } 42 | if (_package === 'highlight.js') { 43 | filename = filename.endsWith('.css') && filename.indexOf('.min.') === -1 ? 44 | filename.substr(0, filename.length - 4) + '.min.css' : filename; 45 | } 46 | if (_package === 'mathjax') { 47 | filename = filename.startsWith('unpacked/') ? filename.substr(9) : filename; 48 | } 49 | if (_package === 'pace-js') { 50 | _package = 'pace'; 51 | } 52 | if (_package === 'clipboard') { 53 | _package = 'clipboard.js'; 54 | } 55 | } 56 | if (provider !== null && cdn_providers.hasOwnProperty(provider)) { 57 | provider = cdn_providers[provider]; 58 | } 59 | return provider.replace(/\${\s*package\s*}/gi, _package) 60 | .replace(/\${\s*version\s*}/gi, version) 61 | .replace(/\${\s*filename\s*}/gi, filename); 62 | }); 63 | 64 | hexo.extend.helper.register('fontcdn', function (fontName, type = 'css') { 65 | let provider = hexo.extend.helper.get('get_config').bind(this)('providers.fontcdn'); 66 | if (provider !== null && font_providers.hasOwnProperty(provider)) { 67 | provider = font_providers[provider]; 68 | } 69 | return provider.replace(/\${\s*fontname\s*}/gi, fontName) 70 | .replace(/\${\s*type\s*}/gi, type); 71 | }); 72 | 73 | hexo.extend.helper.register('iconcdn', function (provider = null) { 74 | if (provider !== null && icon_providers.hasOwnProperty(provider)) { 75 | provider = icon_providers[provider]; 76 | } else { 77 | provider = hexo.extend.helper.get('get_config').bind(this)('providers.iconcdn'); 78 | if (provider !== null && icon_providers.hasOwnProperty(provider)) { 79 | provider = icon_providers[provider]; 80 | } 81 | } 82 | return provider; 83 | }); 84 | } -------------------------------------------------------------------------------- /themes/icarus/includes/helpers/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Theme configuration helpers. 3 | * 4 | * @description Test if a configuration is set or fetch its value. If `exclude_page` is set, the helpers will 5 | * not look up configurations in the current page's front matter. 6 | * @example 7 | * <%- has_config(config_name, exclude_page) %> 8 | * <%- get_config(config_name, default_value, exclude_page) %> 9 | */ 10 | const specs = require('../specs/config.spec'); 11 | const descriptors = require('../common/utils').descriptors; 12 | 13 | module.exports = function (hexo) { 14 | function readProperty(object, path) { 15 | const paths = path.split('.'); 16 | for (let path of paths) { 17 | if (typeof (object) === 'undefined' || object === null || !object.hasOwnProperty(path)) { 18 | return null; 19 | } 20 | object = object[path]; 21 | } 22 | return object; 23 | } 24 | 25 | hexo.extend.helper.register('get_config', function (configName, defaultValue = undefined, excludePage = false) { 26 | const value = readProperty(Object.assign({}, this.config, hexo.theme.config, 27 | !excludePage ? this.page : {}), configName); 28 | if (value === null) { 29 | if (typeof(defaultValue) !== 'undefined') { 30 | return defaultValue; 31 | } else { 32 | const property = readProperty(specs, configName); 33 | return property === null ? null : property[descriptors.defaultValue]; 34 | } 35 | } 36 | return value; 37 | }); 38 | 39 | hexo.extend.helper.register('has_config', function (configName, excludePage = false) { 40 | const readProperty = hexo.extend.helper.get('get_config').bind(this); 41 | return readProperty(configName, null, excludePage) != null; 42 | }); 43 | 44 | hexo.extend.helper.register('get_config_from_obj', function (object, configName, defaultValue = null) { 45 | const value = readProperty(object, configName); 46 | return value === null ? defaultValue : value; 47 | }); 48 | } -------------------------------------------------------------------------------- /themes/icarus/includes/helpers/layout.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper functions for controlling layout. 3 | * 4 | * @example 5 | * <%- get_widgets(position) %> 6 | * <%- has_column() %> 7 | * <%- column_count() %> 8 | */ 9 | module.exports = function (hexo) { 10 | hexo.extend.helper.register('has_widget', function (type) { 11 | const hasWidgets = hexo.extend.helper.get('has_config').bind(this)('widgets'); 12 | if (!hasWidgets) { 13 | return false; 14 | } 15 | const widgets = hexo.extend.helper.get('get_config').bind(this)('widgets'); 16 | return widgets.some(widget => widget.hasOwnProperty('type') && widget.type === type); 17 | }); 18 | 19 | hexo.extend.helper.register('get_widgets', function (position) { 20 | const hasWidgets = hexo.extend.helper.get('has_config').bind(this)('widgets'); 21 | if (!hasWidgets) { 22 | return []; 23 | } 24 | const widgets = hexo.extend.helper.get('get_config').bind(this)('widgets'); 25 | return widgets.filter(widget => widget.hasOwnProperty('position') && widget.position === position); 26 | }); 27 | 28 | hexo.extend.helper.register('has_column', function (position) { 29 | const getWidgets = hexo.extend.helper.get('get_widgets').bind(this); 30 | return getWidgets(position).length > 0; 31 | }); 32 | 33 | hexo.extend.helper.register('column_count', function () { 34 | let columns = 1; 35 | const hasColumn = hexo.extend.helper.get('has_column').bind(this); 36 | columns += hasColumn('left') ? 1 : 0; 37 | columns += hasColumn('right') ? 1 : 0; 38 | return columns; 39 | }); 40 | } -------------------------------------------------------------------------------- /themes/icarus/includes/helpers/page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper functions for page/post. 3 | * 4 | * @example 5 | * <%- is_categories(page) %> 6 | * <%- is_tags(page) %> 7 | * <%- page_title(page) %> 8 | * <%- has_thumbnail(post) %> 9 | * <%- get_thumbnail(post) %> 10 | * <%- get_og_image(post) %> 11 | */ 12 | module.exports = function (hexo) { 13 | hexo.extend.helper.register('is_categories', function (page = null) { 14 | return (page === null ? this.page : page).__categories; 15 | }); 16 | 17 | hexo.extend.helper.register('is_tags', function (page = null) { 18 | return (page === null ? this.page : page).__tags; 19 | }); 20 | 21 | /** 22 | * Generate html head title based on page type 23 | */ 24 | hexo.extend.helper.register('page_title', function (page = null) { 25 | page = page === null ? this.page : page; 26 | let title = page.title; 27 | 28 | if (this.is_archive()) { 29 | title = this._p('common.archive', Infinity); 30 | if (this.is_month()) { 31 | title += ': ' + page.year + '/' + page.month; 32 | } else if (this.is_year()) { 33 | title += ': ' + page.year; 34 | } 35 | } else if (this.is_category()) { 36 | title = this._p('common.category', 1) + ': ' + page.category; 37 | } else if (this.is_tag()) { 38 | title = this._p('common.tag', 1) + ': ' + page.tag; 39 | } else if (this.is_categories()) { 40 | title = this._p('common.category', Infinity); 41 | } else if (this.is_tags()) { 42 | title = this._p('common.tag', Infinity); 43 | } 44 | 45 | const siteTitle = hexo.extend.helper.get('get_config').bind(this)('title', '', true); 46 | return [title, siteTitle].filter(str => typeof (str) !== 'undefined' && str.trim() !== '').join(' - '); 47 | }); 48 | 49 | hexo.extend.helper.register('has_thumbnail', function (post) { 50 | const getConfig = hexo.extend.helper.get('get_config').bind(this); 51 | const allowThumbnail = getConfig('article.thumbnail', true); 52 | if (!allowThumbnail) { 53 | return false; 54 | } 55 | return post.hasOwnProperty('thumbnail') && post.thumbnail; 56 | }); 57 | 58 | hexo.extend.helper.register('get_thumbnail', function (post) { 59 | const hasThumbnail = hexo.extend.helper.get('has_thumbnail').bind(this)(post); 60 | return this.url_for(hasThumbnail ? post.thumbnail : 'images/thumbnail.svg'); 61 | }); 62 | 63 | hexo.extend.helper.register('has_og_image', function (post) { 64 | return post.hasOwnProperty('og_image'); 65 | }); 66 | 67 | hexo.extend.helper.register('get_og_image', function (post) { 68 | const getConfig = hexo.extend.helper.get('get_config').bind(this); 69 | const hasConfig = hexo.extend.helper.get('has_config').bind(this); 70 | 71 | const hasOGImage = hexo.extend.helper.get('has_og_image').bind(this)(post); 72 | const hasThumbnail = hexo.extend.helper.get('has_thumbnail').bind(this)(post); 73 | 74 | const getThumbnail = hexo.extend.helper.get('get_thumbnail').bind(this); 75 | 76 | let og_image 77 | 78 | if (hasOGImage) 79 | og_image = post.og_image 80 | else if (hasThumbnail) 81 | og_image = getThumbnail(post); 82 | else 83 | og_image = getConfig('article.og_image', '/images/og_image.png'); 84 | 85 | return this.url_for(og_image); 86 | }); 87 | } 88 | -------------------------------------------------------------------------------- /themes/icarus/includes/helpers/site.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Helper functions related the site properties. 3 | * 4 | * @example 5 | * <%- is_same_link(url_a, url_b) %> 6 | * <%- get_domain(url) %> 7 | * <%- post_count() %> 8 | * <%- category_count() %> 9 | * <%- tag_count() %> 10 | * <%- duration() %> 11 | * <%- word_count(content) %> 12 | * <%- md5(data) %> 13 | * <%- meta() %> 14 | * <%- hexo_version() %> 15 | */ 16 | const URL = require('url').URL; 17 | const moment = require('moment'); 18 | const crypto = require('crypto'); 19 | 20 | module.exports = function (hexo) { 21 | hexo.extend.helper.register('is_same_link', function (a, b) { 22 | function santize(url) { 23 | let paths = url.replace(/(^\w+:|^)\/\//, '').split('#')[0].split('/').filter(p => p.trim() !== ''); 24 | if (paths.length > 0 && paths[paths.length - 1].trim() === 'index.html') { 25 | paths = paths.slice(0, paths.length - 1) 26 | } 27 | return paths.join('/'); 28 | } 29 | return santize(this.url_for(a)) == santize(this.url_for(b)); 30 | }); 31 | 32 | hexo.extend.helper.register('get_domain', function (link) { 33 | const url = new URL(link); 34 | return url.hostname; 35 | }); 36 | 37 | hexo.extend.helper.register('post_count', function () { 38 | return this.site.posts.length; 39 | }); 40 | 41 | hexo.extend.helper.register('category_count', function () { 42 | return this.site.categories.filter(category => category.length).length; 43 | }); 44 | 45 | hexo.extend.helper.register('tag_count', function () { 46 | return this.site.tags.filter(tag => tag.length).length; 47 | }); 48 | 49 | /** 50 | * Export moment.duration 51 | */ 52 | hexo.extend.helper.register('duration', function () { 53 | return moment.duration.apply(moment, arguments); 54 | }); 55 | 56 | /** 57 | * Get the word count of a paragraph. 58 | */ 59 | hexo.extend.helper.register('word_count', function (content) { 60 | content = content.replace(/<\/?[a-z][^>]*>/gi, ''); 61 | content = content.trim(); 62 | return content ? (content.match(/[\u00ff-\uffff]|[a-zA-Z]+/g) || []).length : 0; 63 | }); 64 | 65 | hexo.extend.helper.register('md5', function (data) { 66 | return crypto.createHash('md5').update(data).digest("hex"); 67 | }); 68 | 69 | hexo.extend.helper.register('meta', function () { 70 | function trim(str) { 71 | return str.trim().replace(/^"(.*)"$/, '$1').replace(/^'(.*)'$/, '$1'); 72 | } 73 | 74 | function split(str, sep) { 75 | const result = []; 76 | let matched = null; 77 | while (matched = sep.exec(str)) { 78 | result.push(matched[0]); 79 | } 80 | return result; 81 | } 82 | 83 | const getConfig = hexo.extend.helper.get('get_config').bind(this); 84 | const metas = getConfig('meta', []); 85 | const metaDOMArray = metas.map(function (meta) { 86 | const entities = split(meta, /(?:[^\\;]+|\\.)+/g); 87 | const entityArray = entities.map(function (entity) { 88 | const keyValue = split(entity, /(?:[^\\=]+|\\.)+/g); 89 | if (keyValue.length < 2) { 90 | return null; 91 | } 92 | const key = trim(keyValue[0]); 93 | const value = trim(keyValue[1]); 94 | return key + '="' + value + '"'; 95 | }).filter(function (entity) { 96 | return entity; 97 | }); 98 | return ''; 99 | }); 100 | return metaDOMArray.join('\n'); 101 | }); 102 | 103 | hexo.extend.helper.register('hexo_version', function (data) { 104 | return hexo.version; 105 | }); 106 | } -------------------------------------------------------------------------------- /themes/icarus/includes/specs/article.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Article display settings', 6 | highlight: { 7 | [type]: 'object', 8 | [doc]: 'Code highlight settings', 9 | theme: { 10 | [type]: 'string', 11 | [doc]: 'Code highlight themes\nhttps://github.com/highlightjs/highlight.js/tree/master/src/styles', 12 | [defaultValue]: 'atom-one-light' 13 | }, 14 | clipboard: { 15 | [type]: 'boolean', 16 | [doc]: 'Show code copying button', 17 | [defaultValue]: true 18 | }, 19 | fold: { 20 | [type]: 'string', 21 | [doc]: 'Default folding status of the code blocks. Can be "", "folded", "unfolded"', 22 | [defaultValue]: 'unfolded' 23 | } 24 | }, 25 | thumbnail: { 26 | [type]: 'boolean', 27 | [doc]: 'Whether to show article thumbnail images', 28 | [defaultValue]: true 29 | }, 30 | readtime: { 31 | [type]: 'boolean', 32 | [doc]: 'Whether to show estimate article reading time', 33 | [defaultValue]: true 34 | } 35 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/config.spec.js: -------------------------------------------------------------------------------- 1 | const { version } = require('../../package.json'); 2 | const { type, required, defaultValue, doc } = require('../common/utils').descriptors; 3 | 4 | module.exports = { 5 | [type]: 'object', 6 | [doc]: 'Root of the configuration file', 7 | [required]: true, 8 | version: { 9 | [type]: 'string', 10 | [doc]: 'Version of the Icarus theme that is currently used', 11 | [required]: true, 12 | [defaultValue]: version 13 | }, 14 | ...require('./meta.spec'), 15 | navbar: require('./navbar.spec'), 16 | footer: require('./footer.spec'), 17 | article: require('./article.spec'), 18 | search: require('./search.spec'), 19 | comment: require('./comment.spec'), 20 | donate: require('./donate.spec'), 21 | share: require('./share.spec'), 22 | sidebar: require('./sidebar.spec'), 23 | widgets: require('./widgets.spec'), 24 | plugins: require('./plugins.spec'), 25 | providers: require('./providers.spec') 26 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/donate.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue, required, requires, format } = require('../common/utils').descriptors; 2 | 3 | const DEFAULT_DONATE = [ 4 | { 5 | type: 'alipay', 6 | qrcode: '' 7 | }, 8 | { 9 | type: 'wechat', 10 | qrcode: '' 11 | }, 12 | { 13 | type: 'paypal', 14 | business: '', 15 | currency_code: 'USD' 16 | }, 17 | { 18 | type: 'patreon', 19 | url: '' 20 | } 21 | ]; 22 | 23 | const QrcodeSpec = { 24 | qrcode: { 25 | [type]: 'string', 26 | [doc]: 'Qrcode image URL', 27 | [required]: true, 28 | [requires]: donate => donate.type === 'alipay' || donate.type === 'wechat' 29 | } 30 | }; 31 | 32 | const PaypalSpec = { 33 | business: { 34 | [type]: 'string', 35 | [doc]: 'Paypal business ID or email address', 36 | [required]: true, 37 | [requires]: donate => donate.type === 'paypal' 38 | }, 39 | currency_code: { 40 | [type]: 'string', 41 | [doc]: 'Currency code', 42 | [required]: true, 43 | [requires]: donate => donate.type === 'paypal' 44 | } 45 | }; 46 | 47 | const PatreonSpec = { 48 | url: { 49 | [type]: 'string', 50 | [doc]: 'URL to the Patreon page', 51 | [required]: true, 52 | [requires]: donate => donate.type === 'patreon' 53 | } 54 | }; 55 | 56 | module.exports = { 57 | [type]: 'array', 58 | [doc]: 'Donation entries\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Donation/', 59 | [defaultValue]: DEFAULT_DONATE, 60 | '*': { 61 | [type]: 'object', 62 | [doc]: 'Single donation entry settings', 63 | type: { 64 | [type]: 'string', 65 | [doc]: 'Donation entry name', 66 | [required]: true 67 | }, 68 | ...QrcodeSpec, 69 | ...PaypalSpec, 70 | ...PatreonSpec 71 | } 72 | } -------------------------------------------------------------------------------- /themes/icarus/includes/specs/footer.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Footer section link settings', 6 | links: { 7 | ...require('./icon_link.spec'), 8 | [doc]: 'Links to be shown on the right of the footer section', 9 | [defaultValue]: { 10 | 'Creative Commons': { 11 | icon: 'fab fa-creative-commons', 12 | url: 'https://creativecommons.org/' 13 | }, 14 | 'Attribution 4.0 International': { 15 | icon: 'fab fa-creative-commons-by', 16 | url: 'https://creativecommons.org/licenses/by/4.0/' 17 | }, 18 | 'Download on GitHub': { 19 | icon: 'fab fa-github', 20 | url: 'https://github.com/ppoffice/hexo-theme-icarus' 21 | } 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/icon_link.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, required } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Link icon settings', 6 | '*': { 7 | [type]: ['string', 'object'], 8 | [doc]: 'Path or URL to the menu item, and/or link icon class names', 9 | icon: { 10 | [required]: true, 11 | [type]: 'string', 12 | [doc]: 'Link icon class names' 13 | }, 14 | url: { 15 | [required]: true, 16 | [type]: 'string', 17 | [doc]: 'Path or URL to the menu item' 18 | } 19 | } 20 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/meta.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | favicon: { 5 | [type]: 'string', 6 | [doc]: 'Path or URL to the website\'s icon', 7 | [defaultValue]: '/images/favicon.svg', 8 | }, 9 | meta: { 10 | [type]: 'array', 11 | [doc]: 'Additional HTML meta tags in an array.', 12 | [defaultValue]: null, 13 | '*': { 14 | [type]: 'string', 15 | [doc]: 'Meta tag specified in = style.\nE.g., name=theme-color;content=#123456 => ' 16 | } 17 | }, 18 | rss: { 19 | [type]: 'string', 20 | [doc]: 'Path or URL to RSS atom.xml', 21 | [defaultValue]: null 22 | }, 23 | logo: { 24 | [type]: ['string', 'object'], 25 | [defaultValue]: '/images/logo.svg', 26 | [doc]: 'Path or URL to the website\'s logo to be shown on the left of the navigation bar or footer', 27 | text: { 28 | [type]: 'string', 29 | [doc]: 'Text to be shown in place of the logo image' 30 | } 31 | }, 32 | open_graph: { 33 | [type]: 'object', 34 | [doc]: 'Open Graph metadata\nhttps://hexo.io/docs/helpers.html#open-graph', 35 | fb_app_id: { 36 | [type]: 'string', 37 | [doc]: 'Facebook App ID', 38 | [defaultValue]: null 39 | }, 40 | fb_admins: { 41 | [type]: 'string', 42 | [doc]: 'Facebook Admin ID', 43 | [defaultValue]: null 44 | }, 45 | twitter_id: { 46 | [type]: 'string', 47 | [doc]: 'Twitter ID', 48 | [defaultValue]: null 49 | }, 50 | twitter_site: { 51 | [type]: 'string', 52 | [doc]: 'Twitter site', 53 | [defaultValue]: null 54 | }, 55 | google_plus: { 56 | [type]: 'string', 57 | [doc]: 'Google+ profile link', 58 | [defaultValue]: null 59 | } 60 | } 61 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/navbar.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Navigation bar link settings', 6 | menu: { 7 | [type]: 'object', 8 | [doc]: 'Navigation bar menu links', 9 | [defaultValue]: { 10 | Home: '/', 11 | Archives: '/archives', 12 | Categories: '/categories', 13 | Tags: '/tags', 14 | About: '/about' 15 | }, 16 | '*': { 17 | [type]: 'string', 18 | [doc]: 'Path or URL to the menu item' 19 | } 20 | }, 21 | links: { 22 | ...require('./icon_link.spec'), 23 | [doc]: 'Navigation bar links to be shown on the right', 24 | [defaultValue]: { 25 | 'Download on GitHub': { 26 | icon: 'fab fa-github', 27 | url: 'https://github.com/ppoffice/hexo-theme-icarus' 28 | } 29 | } 30 | } 31 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/plugins.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Other plugin settings', 6 | animejs: { 7 | [type]: 'boolean', 8 | [doc]: 'Enable page animations', 9 | [defaultValue]: true 10 | }, 11 | gallery: { 12 | [type]: 'boolean', 13 | [doc]: 'Enable the lightGallery and Justified Gallery plugins\nhttps://ppoffice.github.io/hexo-theme-icarus/Plugins/General/gallery-plugin/', 14 | [defaultValue]: true 15 | }, 16 | 'outdated-browser': { 17 | [type]: 'boolean', 18 | [doc]: 'Enable the Outdated Browser plugin\nhttp://outdatedbrowser.com/', 19 | [defaultValue]: true 20 | }, 21 | mathjax: { 22 | [type]: 'boolean', 23 | [doc]: 'Enable the MathJax plugin\nhttps://ppoffice.github.io/hexo-theme-icarus/Plugins/General/mathjax-plugin/', 24 | [defaultValue]: true 25 | }, 26 | 'back-to-top': { 27 | [type]: 'boolean', 28 | [doc]: 'Show the back to top button on mobile devices', 29 | [defaultValue]: true 30 | }, 31 | 'google-analytics': { 32 | [type]: ['boolean', 'object'], 33 | [doc]: 'Google Analytics plugin settings\nhttps://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Google-Analytics', 34 | tracking_id: { 35 | [type]: 'string', 36 | [doc]: 'Google Analytics tracking id', 37 | [defaultValue]: null 38 | } 39 | }, 40 | 'baidu-analytics': { 41 | [type]: ['boolean', 'object'], 42 | [doc]: 'Baidu Analytics plugin settings\nhttps://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Baidu-Analytics', 43 | tracking_id: { 44 | [type]: 'string', 45 | [doc]: 'Baidu Analytics tracking id', 46 | [defaultValue]: null 47 | } 48 | }, 49 | hotjar: { 50 | [type]: ['boolean', 'object'], 51 | [doc]: 'Hotjar user feedback plugin\nhttps://ppoffice.github.io/hexo-theme-icarus/Plugins/General/site-analytics-plugin/#Hotjar', 52 | site_id: { 53 | [type]: ['string', 'number'], 54 | [doc]: 'Hotjar site id', 55 | [defaultValue]: null 56 | } 57 | }, 58 | progressbar: { 59 | [type]: 'boolean', 60 | [doc]: 'Show a loading progress bar at top of the page', 61 | [defaultValue]: true 62 | }, 63 | busuanzi: { 64 | [type]: 'boolean', 65 | [doc]: 'BuSuanZi site/page view counter\nhttps://busuanzi.ibruce.info', 66 | [defaultValue]: false 67 | } 68 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/providers.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'CDN provider settings\nhttps://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/speed-up-your-site-with-custom-cdn/', 6 | cdn: { 7 | [type]: 'string', 8 | [doc]: 'Name or URL of the JavaScript and/or stylesheet CDN provider', 9 | [defaultValue]: 'jsdelivr' 10 | }, 11 | fontcdn: { 12 | [type]: 'string', 13 | [doc]: 'Name or URL of the webfont CDN provider', 14 | [defaultValue]: 'google' 15 | }, 16 | iconcdn: { 17 | [type]: 'string', 18 | [doc]: 'Name or URL of the webfont Icon CDN provider', 19 | [defaultValue]: 'fontawesome' 20 | } 21 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/search.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue, required, requires } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Search plugin settings\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Search', 6 | type: { 7 | [type]: 'string', 8 | [doc]: 'Name of the search plugin', 9 | [defaultValue]: 'insight' 10 | }, 11 | cx: { 12 | [type]: 'string', 13 | [doc]: 'Google CSE cx value', 14 | [required]: true, 15 | [requires]: search => search.type === 'google-cse' 16 | } 17 | }; -------------------------------------------------------------------------------- /themes/icarus/includes/specs/share.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue, required, requires } = require('../common/utils').descriptors; 2 | 3 | module.exports = { 4 | [type]: 'object', 5 | [doc]: 'Share plugin settings\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Plugins/Share', 6 | type: { 7 | [type]: 'string', 8 | [doc]: 'Share plugin name', 9 | [defaultValue]: null 10 | }, 11 | install_url: { 12 | [type]: 'string', 13 | [doc]: 'URL to the share plugin script provided by share plugin service provider', 14 | [required]: true, 15 | [requires]: share => share.type === 'sharethis' || share.type === 'addthis' 16 | } 17 | } -------------------------------------------------------------------------------- /themes/icarus/includes/specs/sidebar.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue, required, requires, format } = require('../common/utils').descriptors; 2 | 3 | function commonSettings(position) { 4 | return { 5 | [type]: 'object', 6 | [doc]: position + ' sidebar settings', 7 | sticky: { 8 | [type]: 'boolean', 9 | [doc]: 'Whether the ' + position + ' sidebar is sticky when page scrolls\nhttps://ppoffice.github.io/hexo-theme-icarus/Configuration/Theme/make-a-sidebar-sticky-when-page-scrolls/', 10 | [defaultValue]: false 11 | } 12 | } 13 | } 14 | 15 | module.exports = { 16 | [type]: 'object', 17 | [doc]: 'Sidebar settings.\nPlease be noted that a sidebar is only visible when it has at least one widget', 18 | left: commonSettings('left'), 19 | right: commonSettings('right') 20 | } -------------------------------------------------------------------------------- /themes/icarus/includes/specs/widgets.spec.js: -------------------------------------------------------------------------------- 1 | const { doc, type, defaultValue, required, requires, format } = require('../common/utils').descriptors; 2 | 3 | const DEFAULT_WIDGETS = [ 4 | { 5 | type: 'profile', 6 | position: 'left', 7 | author: 'Your name', 8 | author_title: 'Your title', 9 | location: 'Your location', 10 | avatar: null, 11 | gravatar: null, 12 | avatar_rounded: false, 13 | follow_link: 'https://github.com/ppoffice', 14 | social_links: { 15 | Github: { 16 | icon: 'fab fa-github', 17 | url: 'https://github.com/ppoffice' 18 | }, 19 | Facebook: { 20 | icon: 'fab fa-facebook', 21 | url: 'https://facebook.com' 22 | }, 23 | Twitter: { 24 | icon: 'fab fa-twitter', 25 | url: 'https://twitter.com' 26 | }, 27 | Dribbble: { 28 | icon: 'fab fa-dribbble', 29 | url: 'https://dribbble.com' 30 | }, 31 | RSS: { 32 | icon: 'fas fa-rss', 33 | url: '/' 34 | } 35 | } 36 | }, 37 | { 38 | type: 'toc', 39 | position: 'left' 40 | }, 41 | { 42 | type: 'links', 43 | position: 'left', 44 | links: { 45 | Hexo: 'https://hexo.io', 46 | PPOffice: 'https://github.com/ppoffice' 47 | } 48 | }, 49 | { 50 | type: 'category', 51 | position: 'left' 52 | }, 53 | { 54 | type: 'tagcloud', 55 | position: 'left' 56 | }, 57 | { 58 | type: 'recent_posts', 59 | position: 'right' 60 | }, 61 | { 62 | type: 'archive', 63 | position: 'right' 64 | }, 65 | { 66 | type: 'tag', 67 | position: 'right' 68 | } 69 | ]; 70 | 71 | const ProfileSpec = { 72 | author: { 73 | [type]: 'string', 74 | [doc]: 'Author name to be shown in the profile widget', 75 | [defaultValue]: 'Your name' 76 | }, 77 | author_title: { 78 | [type]: 'string', 79 | [doc]: 'Title of the author to be shown in the profile widget', 80 | [defaultValue]: 'Your title' 81 | }, 82 | location: { 83 | [type]: 'string', 84 | [doc]: 'Author\'s current location to be shown in the profile widget', 85 | [defaultValue]: 'Your location' 86 | }, 87 | avatar: { 88 | [type]: 'string', 89 | [doc]: 'Path or URL to the avatar to be shown in the profile widget', 90 | [defaultValue]: '/images/avatar.png' 91 | }, 92 | avatar_rounded: { 93 | [type]: 'boolean', 94 | [doc]: 'Whether to show avatar image rounded or square', 95 | [defaultValue]: false 96 | }, 97 | gravatar: { 98 | [type]: 'string', 99 | [doc]: 'Email address for the Gravatar to be shown in the profile widget', 100 | }, 101 | follow_link: { 102 | [type]: 'string', 103 | [doc]: 'Path or URL for the follow button', 104 | }, 105 | social_links: { 106 | ...require('./icon_link.spec'), 107 | [doc]: 'Links to be shown on the bottom of the profile widget', 108 | } 109 | }; 110 | 111 | for (let key in ProfileSpec) { 112 | ProfileSpec[key][requires] = widget => widget.type === 'profile'; 113 | } 114 | 115 | const LinksSpec = { 116 | links: { 117 | [type]: 'object', 118 | [doc]: 'Links to be shown in the links widget', 119 | [requires]: parent => parent.type === 'links', 120 | '*': { 121 | [type]: 'string', 122 | [doc]: 'Path or URL to the link', 123 | [required]: true 124 | } 125 | } 126 | }; 127 | 128 | module.exports = { 129 | [type]: 'array', 130 | [doc]: 'Sidebar widget settings\nhttps://ppoffice.github.io/hexo-theme-icarus/categories/Widgets/', 131 | [defaultValue]: DEFAULT_WIDGETS, 132 | '*': { 133 | [type]: 'object', 134 | [doc]: 'Single widget settings', 135 | type: { 136 | [type]: 'string', 137 | [doc]: 'Widget name', 138 | [required]: true, 139 | [defaultValue]: 'profile' 140 | }, 141 | position: { 142 | [type]: 'string', 143 | [doc]: 'Where should the widget be placed, left or right', 144 | [format]: /^(left|right)$/, 145 | [required]: true, 146 | [defaultValue]: 'left' 147 | }, 148 | ...ProfileSpec, 149 | ...LinksSpec 150 | } 151 | } -------------------------------------------------------------------------------- /themes/icarus/includes/tasks/check_config.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const util = require('util'); 3 | const path = require('path'); 4 | const logger = require('hexo-log')(); 5 | const yaml = require('js-yaml'); 6 | 7 | const { errors } = require('../common/utils'); 8 | const rootSpec = require('../specs/config.spec'); 9 | const ConfigValidator = require('../common/ConfigValidator'); 10 | const ConfigGenerator = require('../common/ConfigGenerator'); 11 | 12 | const CONFIG_PATH = path.join(__dirname, '../..', '_config.yml'); 13 | 14 | logger.info('Validating the configuration file'); 15 | 16 | if (!fs.existsSync(CONFIG_PATH)) { 17 | const relativePath = path.relative(process.cwd(), CONFIG_PATH); 18 | logger.warn(`${relativePath} is not found. We are creating one for you...`); 19 | fs.writeFileSync(CONFIG_PATH, new ConfigGenerator(rootSpec).generate()); 20 | logger.info(`${relativePath} is created. Please restart Hexo to apply changes.`); 21 | process.exit(0); 22 | } 23 | 24 | const validator = new ConfigValidator(rootSpec); 25 | const config = yaml.safeLoad(fs.readFileSync(CONFIG_PATH)); 26 | try { 27 | validator.validate(config); 28 | } catch (e) { 29 | if (e instanceof errors.ConfigError) { 30 | logger.error(e.message); 31 | if (e.hasOwnProperty('spec')) { 32 | logger.error('The specification of this configuration is:'); 33 | logger.error(util.inspect(e.spec)); 34 | } 35 | if (e.hasOwnProperty('config')) { 36 | logger.error('Configuration value is:'); 37 | logger.error(util.inspect(e.config)); 38 | } 39 | } else if (e instanceof errors.VersionError) { 40 | logger.error(e.message); 41 | logger.warn(`To let us create a fresh configuration file for you, please rename or delete the following file:`); 42 | logger.warn(CONFIG_PATH); 43 | } else { 44 | throw e; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /themes/icarus/includes/tasks/check_deps.js: -------------------------------------------------------------------------------- 1 | const logger = require('hexo-log')(); 2 | 3 | function checkDependency(name) { 4 | try { 5 | require.resolve(name); 6 | return true; 7 | } catch(e) { 8 | logger.error(`Package ${name} is not installed.`) 9 | } 10 | return false; 11 | } 12 | 13 | logger.info('Checking dependencies'); 14 | const missingDeps = [ 15 | 'js-yaml', 16 | 'moment', 17 | 'cheerio', 18 | 'hexo-util', 19 | 'hexo-log', 20 | 'hexo-pagination', 21 | 'hexo-generator-archive', 22 | 'hexo-generator-category', 23 | 'hexo-generator-index', 24 | 'hexo-generator-tag', 25 | 'hexo-renderer-ejs', 26 | 'hexo-renderer-marked', 27 | 'hexo-renderer-stylus', 28 | ].map(checkDependency).some(installed => !installed); 29 | if (missingDeps) { 30 | logger.error('Please install the missing dependencies from the root directory of your Hexo site.'); 31 | process.exit(-1); 32 | } 33 | -------------------------------------------------------------------------------- /themes/icarus/includes/tasks/welcome.js: -------------------------------------------------------------------------------- 1 | const logger = require('hexo-log')(); 2 | 3 | logger.info(`======================================= 4 | ██╗ ██████╗ █████╗ ██████╗ ██╗ ██╗███████╗ 5 | ██║██╔════╝██╔══██╗██╔══██╗██║ ██║██╔════╝ 6 | ██║██║ ███████║██████╔╝██║ ██║███████╗ 7 | ██║██║ ██╔══██║██╔══██╗██║ ██║╚════██║ 8 | ██║╚██████╗██║ ██║██║ ██║╚██████╔╝███████║ 9 | ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝ ╚══════╝ 10 | =============================================`); -------------------------------------------------------------------------------- /themes/icarus/languages/en.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Archive' 4 | other: 'Archives' 5 | category: 6 | one: 'Category' 7 | other: 'Categories' 8 | tag: 9 | one: 'Tag' 10 | other: 'Tags' 11 | post: 12 | one: 'Post' 13 | other: 'Posts' 14 | prev: 'Previous' 15 | next: 'Next' 16 | widget: 17 | follow: 'Follow' 18 | recents: 'Recent' 19 | links: 'Links' 20 | tag_cloud: 'Tag Cloud' 21 | catalogue: 'Catalogue' 22 | article: 23 | more: 'Read More' 24 | comments: 'Comments' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | donate: 29 | title: 'Like this article? Support the author with' 30 | alipay: 'Alipay' 31 | wechat: 'Wechat' 32 | paypal: 'Paypal' 33 | patreon: 'Patreon' 34 | plugin: 35 | backtotop: 'Back to Top' 36 | visit: '%s visits' 37 | visitor: 'Visited by %s users' 38 | search: 39 | search: 'Search' 40 | hint: 'Type something...' 41 | insight: 42 | hint: 'Type something...' 43 | posts: 'Posts' 44 | pages: 'Pages' 45 | categories: 'Categories' 46 | tags: 'Tags' 47 | untitled: '(Untitled)' 48 | -------------------------------------------------------------------------------- /themes/icarus/languages/es.yml: -------------------------------------------------------------------------------- 1 | #By SrWoOoW 2 | common: 3 | archive: 4 | one: 'Archivo' 5 | other: 'Archivos' 6 | category: 7 | one: 'Categoria' 8 | other: 'Categorias' 9 | tag: 10 | one: 'Etiqueta' 11 | other: 'Etiquetas' 12 | post: 13 | one: 'Entrada' 14 | other: 'Entradas' 15 | prev: 'Anterior' 16 | next: 'Siguiente' 17 | widget: 18 | follow: 'SEGUIR' 19 | recents: 'Recientes' 20 | links: 'Links' 21 | tag_cloud: 'Nube de etiquetas' 22 | catalogue: 'Catálogo' 23 | article: 24 | more: 'Read More' 25 | comments: 'Comentarios' 26 | read: 'read' 27 | about: 'About' 28 | words: 'words' 29 | search: 30 | search: 'Search' 31 | hint: 'Type something...' 32 | insight: 33 | hint: 'Type something...' 34 | posts: 'Entradas' 35 | pages: 'Pages' 36 | categories: 'Categorias' 37 | tags: 'Etiquetas' 38 | untitled: '(Untitled)' 39 | -------------------------------------------------------------------------------- /themes/icarus/languages/fr.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Archive' 4 | other: 'Archives' 5 | category: 6 | one: 'Catégorie' 7 | other: 'Catégories' 8 | tag: 9 | one: 'Tag' 10 | other: 'Tags' 11 | post: 12 | one: 'Article' 13 | other: 'Articles' 14 | prev: 'Préc' 15 | next: 'Suiv' 16 | widget: 17 | follow: 'SUIVRE' 18 | recents: 'Récents' 19 | links: 'Liens' 20 | tag_cloud: 'Nuage de tags' 21 | catalogue: 'Catalogue' 22 | article: 23 | more: 'Read More' 24 | comments: 'Commentaires' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | search: 29 | search: 'Search' 30 | hint: 'Type something...' 31 | insight: 32 | hint: 'Type something...' 33 | posts: 'Articles' 34 | pages: 'Pages' 35 | categories: 'Catégories' 36 | tags: 'Tags' 37 | untitled: '(Untitled)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/id.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Arsip' 4 | other: 'Arsip' 5 | category: 6 | one: 'Kategori' 7 | other: 'Kategori' 8 | tag: 9 | one: 'Tag' 10 | other: 'Tag' 11 | post: 12 | one: 'Artikel' 13 | other: 'Artikel' 14 | prev: 'Sebelumnya' 15 | next: 'Berikutnya' 16 | widget: 17 | follow: 'IKUTI' 18 | recents: 'Terbaru' 19 | links: 'Tautan' 20 | tag_cloud: 'Awan tag' 21 | catalogue: 'Katalog' 22 | article: 23 | more: 'Selengkapnya' 24 | comments: 'Komentar' 25 | read: 'membaca' 26 | about: 'Sekitar' 27 | words: 'kata' 28 | search: 29 | search: 'Pencarian' 30 | hint: 'Tulis Sesuatu..' 31 | insight: 32 | hint: 'Tulis Sesuatu..' 33 | posts: 'Artikel' 34 | pages: 'Halaman' 35 | categories: 'Kategori' 36 | tags: 'Tag' 37 | untitled: 'Tanpa Judul' 38 | donate: 39 | title: 'Suka dengan artikel ini? Bantu penulis dengan donasi melalui' 40 | alipay: 'Alipay' 41 | wechat: 'Wechat' 42 | paypal: 'Paypal' 43 | patreon: 'Patreon' 44 | plugin: 45 | backtotop: 'Kembali ke atas' 46 | -------------------------------------------------------------------------------- /themes/icarus/languages/ja.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'アーカイブ' 4 | other: 'アーカイブ' 5 | category: 6 | one: 'カテゴリ' 7 | other: 'カテゴリ' 8 | tag: 9 | one: 'タグ' 10 | other: 'タグ' 11 | post: 12 | one: '投稿' 13 | other: '投稿' 14 | prev: '前' 15 | next: '次' 16 | widget: 17 | follow: 'フォローする' 18 | recents: '最近の記事' 19 | links: 'リンク' 20 | tag_cloud: 'タグクラウド' 21 | catalogue: 'カタログ' 22 | article: 23 | more: 'Read More' 24 | comments: 'コメント' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | search: 29 | search: 'Search' 30 | hint: 'Type something...' 31 | insight: 32 | hint: 'Type something...' 33 | posts: '投稿' 34 | pages: 'Pages' 35 | categories: 'カテゴリ' 36 | tags: 'タグ' 37 | untitled: '(Untitled)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/ko.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: '아카이브' 4 | other: '아카이브' 5 | category: 6 | one: '카테고리' 7 | other: '카테고리' 8 | tag: 9 | one: '태그' 10 | other: '태그' 11 | post: 12 | one: '포스트' 13 | other: '포스트' 14 | prev: '이전' 15 | next: '다음' 16 | widget: 17 | follow: '팔로우' 18 | recents: '최근 글' 19 | links: '링크' 20 | tag_cloud: '태그 클라우드' 21 | catalogue: '카탈로그' 22 | article: 23 | more: '자세히 보기' 24 | comments: '댓글' 25 | read: '읽기' 26 | about: '나에 대하여' 27 | words: '단어' 28 | search: 29 | search: '검색' 30 | hint: '입력 하세요...' 31 | insight: 32 | hint: '입력 하세요...' 33 | posts: '포스트' 34 | pages: '페이지' 35 | categories: '카테고리' 36 | tags: '태그' 37 | untitled: '(제목없음)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/pt-BR.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Arquivo' 4 | other: 'Arquivos' 5 | category: 6 | one: 'Categoria' 7 | other: 'Categorias' 8 | tag: 9 | one: 'Tag' 10 | other: 'Tags' 11 | post: 12 | one: 'Artigo' 13 | other: 'Artigos' 14 | prev: 'Anterior' 15 | next: 'Próximo' 16 | widget: 17 | follow: 'SEGUIR' 18 | recents: 'Recentes' 19 | links: 'Links' 20 | tag_cloud: 'Nuvem de tags' 21 | catalogue: 'Catálogo' 22 | article: 23 | more: 'Ler Mais' 24 | comments: 'Comentarios' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | search: 29 | search: 'Search' 30 | hint: 'Digite alguma coisa...' 31 | insight: 32 | hint: 'Digite alguma coisa...' 33 | posts: 'Artigos' 34 | pages: 'Paginas' 35 | categories: 'Categorias' 36 | tags: 'Tags' 37 | untitled: '(Untitled)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/ru.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'архив' 4 | other: 'архивы' 5 | category: 6 | one: 'категории' 7 | other: 'категории' 8 | tag: 9 | one: 'тег' 10 | other: 'теги' 11 | post: 12 | one: 'пост' 13 | other: 'посты' 14 | prev: 'Назад' 15 | next: 'Далее' 16 | widget: 17 | follow: 'Подписаться' 18 | recents: 'недавние' 19 | links: 'ссылки' 20 | tag_cloud: 'облако тегов' 21 | catalogue: 'Каталог' 22 | article: 23 | more: 'Читать дальше' 24 | comments: 'Комментарии' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | search: 29 | search: 'Search' 30 | hint: 'Введите что-нибудь...' 31 | insight: 32 | hint: 'Введите что-нибудь...' 33 | posts: 'посты' 34 | pages: 'страницы' 35 | categories: 'категории' 36 | tags: 'теги' 37 | untitled: '(Без названия)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/tr.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Arşiv' 4 | other: 'Arşivler' 5 | category: 6 | one: 'Kategori' 7 | other: 'Kategoriler' 8 | tag: 9 | one: 'Etiket' 10 | other: 'Etiketler' 11 | post: 12 | one: 'Gönderi' 13 | other: 'Gönderiler' 14 | prev: 'Önceki' 15 | next: 'Sonraki' 16 | widget: 17 | follow: 'TAKİP ET' 18 | recents: 'Son' 19 | links: 'Linkler' 20 | tag_cloud: 'Etiket bulutu' 21 | catalogue: 'Katalog' 22 | article: 23 | more: 'Daha fazla oku' 24 | comments: 'Yorumlar' 25 | read: 'read' 26 | about: 'About' 27 | words: 'words' 28 | search: 29 | search: 'Search' 30 | hint: 'Bir şeyler yaz...' 31 | insight: 32 | hint: 'Bir şeyler yaz...' 33 | posts: 'Gönderiler' 34 | pages: 'Sayfalar' 35 | categories: 'Kategoriler' 36 | tags: 'Etiketler' 37 | untitled: '(Başlıksız)' 38 | -------------------------------------------------------------------------------- /themes/icarus/languages/vn.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: 'Archive' 4 | other: 'Archives' 5 | category: 6 | one: 'Category' 7 | other: 'Categories' 8 | tag: 9 | one: 'Tag' 10 | other: 'Tags' 11 | post: 12 | one: 'Bài viết' 13 | other: 'Bài viết' 14 | prev: 'Trước' 15 | next: 'Sau' 16 | widget: 17 | follow: 'Theo dõi' 18 | recents: 'Gần đây' 19 | links: 'Link' 20 | tag_cloud: 'Tag Cloud' 21 | catalogue: 'Mục lục' 22 | article: 23 | more: 'Đọc thêm' 24 | comments: 'Bình luận' 25 | read: 'đọc' 26 | about: 'Giới thiệu' 27 | words: 'từ' 28 | donate: 29 | title: 'Bạn đọc có thể ủng hộ blog qua' 30 | alipay: 'Alipay' 31 | wechat: 'Wechat' 32 | paypal: 'Paypal' 33 | patreon: 'Patreon' 34 | plugin: 35 | backtotop: 'Trở lai đầu trang' 36 | visit: '%s Bạn đọc' 37 | visitor: 'Thăm bởi %s bạn đọc' 38 | search: 39 | search: 'Tìm kiếm' 40 | hint: 'Gõ gì đó...' 41 | insight: 42 | hint: 'Gõ gì đó...' 43 | posts: 'Bài viết' 44 | pages: 'Trang' 45 | categories: 'Thể loại' 46 | tags: 'Thẻ' 47 | untitled: '(Untitled)' 48 | -------------------------------------------------------------------------------- /themes/icarus/languages/zh-CN.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: '归档' 4 | other: '归档' 5 | category: 6 | one: '分类' 7 | other: '分类' 8 | tag: 9 | one: '标签' 10 | other: '标签' 11 | post: 12 | one: '文章' 13 | other: '文章' 14 | prev: '上一页' 15 | next: '下一页' 16 | widget: 17 | follow: '关注我' 18 | recents: '最新文章' 19 | links: '链接' 20 | tag_cloud: '标签云' 21 | catalogue: '目录' 22 | article: 23 | more: '阅读更多' 24 | comments: '评论' 25 | read: '读完' 26 | about: '大约' 27 | words: '个字' 28 | donate: 29 | title: '喜欢这篇文章?打赏一下作者吧' 30 | alipay: '支付宝' 31 | wechat: '微信' 32 | plugin: 33 | backtotop: '回到顶端' 34 | visit: '%s次访问' 35 | visitor: '共%s个访客' 36 | search: 37 | search: '搜索' 38 | hint: '想要查找什么...' 39 | insight: 40 | hint: '想要查找什么...' 41 | posts: '文章' 42 | pages: '页面' 43 | categories: '分类' 44 | tags: '标签' 45 | untitled: '(无标题)' 46 | -------------------------------------------------------------------------------- /themes/icarus/languages/zh-Hans.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: '归档' 4 | other: '归档' 5 | category: 6 | one: '分类' 7 | other: '分类' 8 | tag: 9 | one: '标签' 10 | other: '标签' 11 | post: 12 | one: '文章' 13 | other: '文章' 14 | prev: '上一页' 15 | next: '下一页' 16 | widget: 17 | follow: '关注我' 18 | recents: '最新文章' 19 | links: '链接' 20 | tag_cloud: '标签云' 21 | catalogue: '目录' 22 | article: 23 | more: '阅读更多' 24 | comments: '评论' 25 | read: '读完' 26 | about: '大约' 27 | words: '个字' 28 | donate: 29 | title: '喜欢这篇文章?打赏一下作者吧' 30 | alipay: '支付宝' 31 | wechat: '微信' 32 | plugin: 33 | backtotop: '回到顶端' 34 | visit: '%s次访问' 35 | visitor: '共%s个访客' 36 | search: 37 | search: '搜索' 38 | hint: '想要查找什么...' 39 | insight: 40 | hint: '想要查找什么...' 41 | posts: '文章' 42 | pages: '页面' 43 | categories: '分类' 44 | tags: '标签' 45 | untitled: '(无标题)' 46 | -------------------------------------------------------------------------------- /themes/icarus/languages/zh-TW.yml: -------------------------------------------------------------------------------- 1 | common: 2 | archive: 3 | one: '彙整' 4 | other: '彙整' 5 | category: 6 | one: '分類' 7 | other: '分類' 8 | tag: 9 | one: '標籤' 10 | other: '標籤' 11 | post: 12 | one: '文章' 13 | other: '文章' 14 | prev: '上一頁' 15 | next: '下一頁' 16 | widget: 17 | follow: '追蹤' 18 | recents: '最新文章' 19 | links: '連結' 20 | tag_cloud: '標籤雲' 21 | catalogue: '文章目錄' 22 | article: 23 | more: '繼續閱讀' 24 | comments: '評論' 25 | read: '閱讀文' 26 | about: '大約' 27 | words: '個字' 28 | donate: 29 | title: '喜歡這篇文章嗎? 贊助一下作者吧!' 30 | alipay: '支付寶' 31 | wechat: 'WeChat' 32 | paypal: 'PayPal' 33 | patreon: 'Patreon' 34 | plugin: 35 | backtotop: '回到頁首' 36 | search: 37 | search: '搜尋' 38 | hint: '請輸入關鍵字...' 39 | insight: 40 | hint: '請輸入關鍵字...' 41 | posts: '文章' 42 | pages: '頁面' 43 | categories: '分類' 44 | tags: '標籤' 45 | untitled: '(無標題)' 46 | -------------------------------------------------------------------------------- /themes/icarus/layout/archive.ejs: -------------------------------------------------------------------------------- 1 | <% function buildArchive(posts, year, month = null) { 2 | const time = moment([page.year, page.month ? page.month - 1 : null].filter(i => i !== null)); %> 3 |
4 |
5 | 8 |
9 | <% posts.each(post => { %> 10 |
11 | <% if (has_thumbnail(post)) { %> 12 | 13 |

14 | <%= post.title %> 15 |

16 |
17 | <% } %> 18 |
19 |
20 | 21 | <%= post.title %> 22 | 36 |
37 |
38 |
39 | <% }) %> 40 |
41 |
42 |
43 | <% } 44 | if (!page.year) { 45 | let years = {}; 46 | page.posts.each(p => years[p.date.year()] = null); 47 | for (let year of Object.keys(years).sort((a, b) => b - a)) { 48 | let posts = page.posts.filter(p => p.date.year() == year); %> 49 | <%- buildArchive(posts, year, null) %> 50 | <% } 51 | } else { %> 52 | <%- buildArchive(page.posts, page.year, page.month) %> 53 | <% } %> 54 | <% if (page.total > 1) { %> 55 | <%- partial('common/paginator') %> 56 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/categories.ejs: -------------------------------------------------------------------------------- 1 | <% function build_list(categories) { 2 | return categories.map(category => { 3 | let result = `
  • 4 | 5 | 6 | ${category.name} 7 | 8 | 9 | ${category.count} 10 | 11 | `; 12 | if (category.hasOwnProperty('children')) { 13 | result += '
      ' + build_list(category.children) + '
    '; 14 | } 15 | return result + '
  • '; 16 | }).join(''); 17 | } 18 | %> 19 |
    20 |
    21 | 29 |
    30 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/category.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 12 |
    13 |
    14 | <%- partial('index', { page }) %> -------------------------------------------------------------------------------- /themes/icarus/layout/comment/changyan.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.appid') || !has_config('comment.conf')) { %> 2 |
    3 | You forgot to set the appid or conf for Changyan. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 8 | 14 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/comment/disqus.ejs: -------------------------------------------------------------------------------- 1 | <% if (has_config('comment.shortname')) { %> 2 | 14 | <% } %> 15 |
    16 | <% if (!has_config('comment.shortname')) { %> 17 |
    18 | You forgot to set the shortname for Disqus. Please set it in _config.yml. 19 |
    20 | <% } %> 21 | 22 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/comment/facebook.ejs: -------------------------------------------------------------------------------- 1 | 8 |
    9 | -------------------------------------------------------------------------------- /themes/icarus/layout/comment/gitalk.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.owner') || !has_config('comment.admin') || !has_config('comment.repo') || !has_config('comment.client_id') || 2 | !has_config('comment.client_secret')) { %> 3 |
    4 | You forgot to set the owner, admin, repo, client_id, or client_secret for Gittalk. 5 | Please set it in _config.yml. 6 |
    7 | <% } else { %> 8 |
    9 | <%- _css(cdn('gitalk', '1.4.1', 'dist/gitalk.css')) %> 10 | <%- _js(cdn('gitalk', '1.4.1', 'dist/gitalk.min.js')) %> 11 | 24 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/comment/gitment.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.owner') || !has_config('comment.repo') || !has_config('comment.client_id') || 2 | !has_config('comment.client_secret')) { %> 3 |
    4 | You forgot to set the owner, repo, client_id, or client_secret for Gitment. 5 | Please set it in _config.yml. 6 |
    7 | <% } else { %> 8 |
    9 | 10 | 11 | 23 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/comment/isso.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.url')) { %> 2 |
    3 | You forgot to set the url for Isso. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 9 | <% } %> 10 | 11 | -------------------------------------------------------------------------------- /themes/icarus/layout/comment/livere.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.uid')) { %> 2 |
    3 | You forgot to set the uid for LiveRe. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 20 | 21 |
    22 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/comment/valine.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('comment.app_id') || !has_config('comment.app_key')) { %> 2 |
    3 | You forgot to set the app_id or app_key for Valine. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 8 | 9 | 19 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/common/footer.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/icarus/layout/common/head.ejs: -------------------------------------------------------------------------------- 1 | 2 | <% if (get_config('meta_generator', true)) { %> 3 | 4 | <% } %> 5 | 6 | <%- meta() %> 7 | WecTeam 8 | 9 | <% if (has_config('favicon')) { %> 10 | 11 | <% } %> 12 | 13 | 14 | 15 | <%- _css(cdn('bulma', '0.7.2', 'css/bulma.css')) %> 16 | <%- _css(iconcdn()) %> 17 | 18 | <%- _css(cdn('highlight.js', '9.12.0', 'styles/' + get_config('article.highlight.theme') + '.css')) %> 19 | 20 | <% if (has_config('plugins')) { %> 21 | <% for (let plugin in get_config('plugins')) { %> 22 | <%- partial('plugin/' + plugin, { head: true, plugin: get_config('plugins')[plugin] }) %> 23 | <% } %> 24 | <% } %> 25 | 26 | <%- _css('css/style') %> -------------------------------------------------------------------------------- /themes/icarus/layout/common/navbar.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/icarus/layout/common/paginator.ejs: -------------------------------------------------------------------------------- 1 | <% function link_url(i) { 2 | return url_for(i === 1 ? page.base : page.base + get_config('pagination_dir') + '/' + i + '/'); 3 | } 4 | 5 | function pagination(c, m) { 6 | var current = c, 7 | last = m, 8 | delta = 1, 9 | left = current - delta, 10 | right = current + delta + 1, 11 | range = [], 12 | elements = [], 13 | l; 14 | 15 | for (let i = 1; i <= last; i++) { 16 | if (i == 1 || i == last || (i >= left && i < right)) { 17 | range.push(i); 18 | } 19 | } 20 | 21 | for (let i of range) { 22 | if (l) { 23 | if (i - l === 2) { 24 | elements.push(`
  • ${ l + 1 }
  • `); 25 | } else if (i - l !== 1) { 26 | elements.push(`
  • `); 27 | } 28 | } 29 | elements.push(`
  • ${ i }
  • `); 30 | l = i; 31 | } 32 | return elements; 33 | } %> 34 |
    35 | 48 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/common/scripts.ejs: -------------------------------------------------------------------------------- 1 | <%- _js(cdn('jquery', '3.3.1', 'dist/jquery.min.js')) %> 2 | <%- _js(cdn('moment', '2.22.2', 'min/moment-with-locales.min.js')) %> 3 | 4 | 5 | 15 | 16 | <% if (get_config('article.highlight.clipboard')) { %> 17 | <%- _js(cdn('clipboard', '2.0.4', 'dist/clipboard.min.js'), true) %> 18 | <% } %> 19 | 20 | <% if (has_config('plugins')) { %> 21 | <% for (let plugin in get_config('plugins')) { %> 22 | <%- partial('plugin/' + plugin, { head: false, plugin: get_config('plugins')[plugin] }) %> 23 | <% } %> 24 | <% } %> 25 | 26 | <%- _js('js/main', true) %> -------------------------------------------------------------------------------- /themes/icarus/layout/common/widget.ejs: -------------------------------------------------------------------------------- 1 | <% if (get_widgets(position).length) { %> 2 | <% function side_column_class() { 3 | switch (column_count()) { 4 | case 2: 5 | return 'is-4-tablet is-4-desktop is-4-widescreen'; 6 | case 3: 7 | return 'is-4-tablet is-4-desktop is-3-widescreen'; 8 | } 9 | return ''; 10 | } %> 11 | <% function visibility_class() { 12 | if (column_count() === 3 && position === 'right') { 13 | return 'is-hidden-touch is-hidden-desktop-only'; 14 | } 15 | return ''; 16 | } %> 17 | <% function order_class() { 18 | return position === 'left' ? 'has-order-1' : 'has-order-3'; 19 | } %> 20 | <% function sticky_class(position) { 21 | return get_config('sidebar.' + position + '.sticky', false) ? 'is-sticky' : ''; 22 | } %> 23 |
    24 | <% get_widgets(position).forEach(widget => {%> 25 | <%- partial('widget/' + widget.type, { widget, post: page }) %> 26 | <% }) %> 27 | <% if (position === 'left') { %> 28 |
    29 | <% get_widgets('right').forEach(widget => {%> 30 | <%- partial('widget/' + widget.type, { widget, post: page }) %> 31 | <% }) %> 32 |
    33 | <% } %> 34 |
    35 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/donate/alipay.ejs: -------------------------------------------------------------------------------- 1 | <% const qrcode = get_config_from_obj(service, 'qrcode'); 2 | if (qrcode) { %> 3 | 10 | <% } else { %> 11 |
    12 | You forgot to set the qrcode for Alipay. Please set it in _config.yml. 13 |
    14 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/donate/patreon.ejs: -------------------------------------------------------------------------------- 1 | <% const url = get_config_from_obj(service, 'url'); 2 | if (url) { %> 3 | 9 | <% } else { %> 10 |
    11 | You forgot to set the url Patreon. Please set it in _config.yml. 12 |
    13 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/donate/paypal.ejs: -------------------------------------------------------------------------------- 1 | 2 | <% const business = get_config_from_obj(service, 'business'); 3 | const currency_code = get_config_from_obj(service, 'currency_code'); 4 | if (business && currency_code) { %> 5 | 11 |
    12 | 13 | 14 | 15 |
    16 | <% } else { %> 17 |
    18 | You forgot to set the business and currency_code for Paypal. Please set it in _config.yml. 19 |
    20 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/donate/wechat.ejs: -------------------------------------------------------------------------------- 1 | <% const qrcode = get_config_from_obj(service, 'qrcode'); 2 | if (qrcode) { %> 3 | 10 | <% } else { %> 11 |
    12 | You forgot to set the qrcode for Wechat. Please set it in _config.yml. 13 |
    14 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/index.ejs: -------------------------------------------------------------------------------- 1 | <% page.posts.each(function(post){ %> 2 | <%- partial('common/article', { post, index: true }) %> 3 | <% }); %> 4 | <% if (page.total > 1) { %> 5 | <%- partial('common/paginator') %> 6 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/layout.ejs: -------------------------------------------------------------------------------- 1 | 2 | > 3 | 4 | <%- partial('common/head') %> 5 | 6 | 7 | <%- partial('common/navbar', { page }) %> 8 | <% function main_column_class() { 9 | switch (column_count()) { 10 | case 1: 11 | return 'is-12'; 12 | case 2: 13 | return 'is-8-tablet is-8-desktop is-8-widescreen'; 14 | case 3: 15 | return 'is-8-tablet is-8-desktop is-6-widescreen' 16 | } 17 | return ''; 18 | } %> 19 |
    20 |
    21 |
    22 |
    <%- body %>
    23 | <%- partial('common/widget', { position: 'left' }) %> 24 | <%- partial('common/widget', { position: 'right' }) %> 25 |
    26 |
    27 |
    28 | <%- partial('common/footer') %> 29 | <%- partial('common/scripts') %> 30 | 31 | <% if (has_config('search.type')) { %> 32 | <%- partial('search/' + get_config('search.type')) %> 33 | <% } %> 34 | 35 | -------------------------------------------------------------------------------- /themes/icarus/layout/page.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('common/article', {post: page, index: false}) %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/animejs.ejs: -------------------------------------------------------------------------------- 1 | <% if (plugin !== false) { %> 2 | <% if (head) { %> 3 | 4 | <% } else { %> 5 | <%- _js('js/animation') %> 6 | <% } %> 7 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/back-to-top.ejs: -------------------------------------------------------------------------------- 1 | <% if (plugin !== false) { %> 2 | <% if (head) { %> 3 | <%- _css('css/back-to-top') %> 4 | <% } else { %> 5 | 6 | 7 | 8 | <%- _js('js/back-to-top', true) %> 9 | <% } %> 10 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/baidu-analytics.ejs: -------------------------------------------------------------------------------- 1 | <% if (head && get_config_from_obj(plugin, 'tracking_id')) { %> 2 | 11 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/busuanzi.ejs: -------------------------------------------------------------------------------- 1 | <% if (plugin !== false) { %> 2 | <% if (head) { %> 3 | 4 | <% } %> 5 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/gallery.ejs: -------------------------------------------------------------------------------- 1 | <% if (plugin !== false) { %> 2 | <% if (head) { %> 3 | <%- _css(cdn('lightgallery', '1.6.8', 'dist/css/lightgallery.min.css')) %> 4 | <%- _css(cdn('justifiedGallery', '3.7.0', 'dist/css/justifiedGallery.min.css')) %> 5 | <% } else { %> 6 | <%- _js(cdn('lightgallery', '1.6.8', 'dist/js/lightgallery.min.js'), true) %> 7 | <%- _js(cdn('justifiedGallery', '3.7.0', 'dist/js/jquery.justifiedGallery.min.js'), true) %> 8 | <%- _js('js/gallery', true) %> 9 | <% } %> 10 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/google-analytics.ejs: -------------------------------------------------------------------------------- 1 | <% if (head && get_config_from_obj(plugin, 'tracking_id')) { %> 2 | 3 | 10 | <% } %> 11 | -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/hotjar.ejs: -------------------------------------------------------------------------------- 1 | <% if (head && get_config_from_obj(plugin, 'site_id')) { %> 2 | 12 | <% } %> 13 | -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/mathjax.ejs: -------------------------------------------------------------------------------- 1 | <% if (!head && plugin !== false) { %> 2 | <%- _js(cdn('mathjax', '2.7.5', 'unpacked/MathJax.js?config=TeX-MML-AM_CHTML'), true) %> 3 | 24 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/outdated-browser.ejs: -------------------------------------------------------------------------------- 1 | <% if (plugin !== false) { %> 2 | <% if (head) { %> 3 | <%- _css(cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.css')) %> 4 | <% } else { %> 5 |
    6 |
    Your browser is out-of-date!
    7 |

    Update your browser to view this website correctly. Update 8 | my browser now

    9 |

    ×

    10 |
    11 | <%- _js(cdn('outdatedbrowser', '1.1.5', 'outdatedbrowser/outdatedbrowser.min.js'), true) %> 12 | 21 | <% } %> 22 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/plugin/progressbar.ejs: -------------------------------------------------------------------------------- 1 | <% if (head && plugin !== false) { %> 2 | <%- _css('css/progressbar') %> 3 | <%- _js(cdn('pace-js', '1.0.2', 'pace.min.js')) %> 4 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/post.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('common/article', {post: page, index: false}) %> -------------------------------------------------------------------------------- /themes/icarus/layout/search/baidu.ejs: -------------------------------------------------------------------------------- 1 | <%- _css('css/search') %> 2 | 12 | -------------------------------------------------------------------------------- /themes/icarus/layout/search/google-cse.ejs: -------------------------------------------------------------------------------- 1 | <%- _css('css/search') %> 2 | 32 | -------------------------------------------------------------------------------- /themes/icarus/layout/search/insight.ejs: -------------------------------------------------------------------------------- 1 | 12 | 27 | <%- _js('js/insight', true) %> 28 | <%- _css('css/search') %> 29 | <%- _css('css/insight') %> -------------------------------------------------------------------------------- /themes/icarus/layout/share/addthis.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('share.install_url')) { %> 2 |
    3 | You need to set install_url to use AddThis. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 8 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/share/addtoany.ejs: -------------------------------------------------------------------------------- 1 | 2 |
    3 | 4 | 5 | 6 | 7 | 8 | 9 |
    10 | 11 | 12 | -------------------------------------------------------------------------------- /themes/icarus/layout/share/bdshare.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 3 | 4 | 5 | 6 | 7 | 8 |
    9 | -------------------------------------------------------------------------------- /themes/icarus/layout/share/sharejs.ejs: -------------------------------------------------------------------------------- 1 | 2 | <%- _css(cdn('social-share.js', '1.0.16', 'dist/css/share.min.css')) %> 3 | <%- _js(cdn('social-share.js', '1.0.16', 'dist/js/social-share.min.js')) %> -------------------------------------------------------------------------------- /themes/icarus/layout/share/sharethis.ejs: -------------------------------------------------------------------------------- 1 | <% if (!has_config('share.install_url')) { %> 2 |
    3 | You need to set install_url to use ShareThis. Please set it in _config.yml. 4 |
    5 | <% } else { %> 6 |
    7 | 8 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/tag.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 10 |
    11 | <%- partial('index', { page }) %> -------------------------------------------------------------------------------- /themes/icarus/layout/tags.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 18 |
    19 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/widget/archive.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 | 22 |
    23 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/widget/category.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('categories') %> -------------------------------------------------------------------------------- /themes/icarus/layout/widget/links.ejs: -------------------------------------------------------------------------------- 1 | <% const links = get_config_from_obj(widget, 'links'); %> 2 | <% if (links !== null) { %> 3 |
    4 |
    5 | 24 |
    25 |
    26 | <% } %> 27 | -------------------------------------------------------------------------------- /themes/icarus/layout/widget/profile.ejs: -------------------------------------------------------------------------------- 1 | <% function avatar() { 2 | const avatar = get_config_from_obj(widget, 'avatar'); 3 | const gravatar_email = get_config_from_obj(widget, 'gravatar'); 4 | if (gravatar_email !== null) { 5 | return gravatar(gravatar_email, 128); 6 | } 7 | if (avatar !== null) { 8 | return url_for(avatar) 9 | } 10 | return url_for('images/avatar.png'); 11 | } %> 12 |
    13 |
    14 | 40 | 72 | 76 | <% const socialLinks = get_config_from_obj(widget, 'social_links'); %> 77 | <% if (socialLinks !== null) { %> 78 |
    79 | <% for (let name in socialLinks) { 80 | let link = socialLinks[name]; %> 81 | 83 | <% if (typeof(link) === 'string') { %> 84 | <%= name %> 85 | <% } else { %> 86 | 87 | <% } %> 88 | 89 | <% } %> 90 |
    91 | <% } %> 92 |
    93 |
    -------------------------------------------------------------------------------- /themes/icarus/layout/widget/recent_posts.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.posts.length) { %> 2 |
    3 |
    4 | 7 | <% site.posts.sort('date', -1).limit(5).each(post => { %> 8 |
    9 | <% if (!has_config('article.thumbnail') || get_config('article.thumbnail') !== false) { %> 10 | 11 |

    12 | <%= post.title %> 13 |

    14 |
    15 | <% } %> 16 |
    17 |
    18 |
    19 | <%= post.title %> 20 |

    21 | <%- list_categories(post.categories, { 22 | show_count: false, 23 | class: 'has-link-grey ', 24 | depth:2, 25 | style: 'none', 26 | separator: ' / '}) %> 27 |

    28 |
    29 |
    30 |
    31 | <% }) %> 32 |
    33 |
    34 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/widget/tag.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('tags') %> -------------------------------------------------------------------------------- /themes/icarus/layout/widget/tagcloud.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.tags.length) { %> 2 |
    3 |
    4 | 7 | <%- tagcloud() %> 8 |
    9 |
    10 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/layout/widget/toc.ejs: -------------------------------------------------------------------------------- 1 | <% if (get_config('toc') === true && (post.layout === 'page' || post.layout === 'post')) { 2 | function buildToc(toc) { 3 | let result = ''; 4 | if (toc.hasOwnProperty('id') && toc.hasOwnProperty('index') && toc.hasOwnProperty('text')) { 5 | result += `
  • 6 | 7 | ${toc.index} 8 | ${toc.text} 9 | `; 10 | } 11 | let keys = Object.keys(toc); 12 | keys.indexOf('id') > -1 && keys.splice(keys.indexOf('id'), 1); 13 | keys.indexOf('text') > -1 && keys.splice(keys.indexOf('text'), 1); 14 | keys.indexOf('index') > -1 && keys.splice(keys.indexOf('index'), 1); 15 | keys = keys.map(k => parseInt(k)).sort((a, b) => a - b); 16 | if (keys.length > 0) { 17 | result += ''; 22 | } 23 | if (toc.hasOwnProperty('id') && toc.hasOwnProperty('index') && toc.hasOwnProperty('text')) { 24 | result += '
  • '; 25 | } 26 | return result; 27 | } 28 | %> 29 |
    30 |
    31 | 37 |
    38 |
    39 | <% } %> -------------------------------------------------------------------------------- /themes/icarus/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-icarus", 3 | "version": "2.6.0", 4 | "private": true 5 | } 6 | -------------------------------------------------------------------------------- /themes/icarus/scripts/index.js: -------------------------------------------------------------------------------- 1 | require('../includes/tasks/welcome'); 2 | require('../includes/tasks/check_deps'); 3 | require('../includes/tasks/check_config'); 4 | require('../includes/generators/categories')(hexo); 5 | require('../includes/generators/category')(hexo); 6 | require('../includes/generators/tags')(hexo); 7 | require('../includes/generators/insight')(hexo); 8 | require('../includes/filters/highlight')(hexo); 9 | require('../includes/helpers/cdn')(hexo); 10 | require('../includes/helpers/config')(hexo); 11 | require('../includes/helpers/layout')(hexo); 12 | require('../includes/helpers/override')(hexo); 13 | require('../includes/helpers/page')(hexo); 14 | require('../includes/helpers/site')(hexo); 15 | var fs = require("fs"); 16 | var path = require("path"); 17 | // Fix large blog rendering OOM 18 | const postHtmlFilter = hexo.extend.filter.list()['after_render:html']; 19 | for (let filter of postHtmlFilter) { 20 | if (filter.name === 'hexoMetaGeneratorInject') { 21 | hexo.extend.filter.unregister('after_render:html', filter); 22 | } 23 | } 24 | 25 | // Debug helper 26 | hexo.extend.helper.register('console', function () { 27 | console.log(arguments) 28 | }); 29 | 30 | hexo.extend.helper.register('post_key', function(path, customKey){ 31 | customKey = customKey || new Buffer(path).toString('base64'); 32 | return customKey; 33 | }); 34 | 35 | hexo.extend.generator.register('archive', function(locals){ 36 | var posts = locals.posts.map(item=>{ 37 | return { 38 | title:item.title, 39 | date:item.date.unix(), 40 | path:item.path 41 | } 42 | }).sort((a,b)=>{ 43 | return b.date - a.date 44 | }); 45 | // console.log(posts.length,posts.sort,posts); 46 | posts 47 | var content = ` 48 | # 这是什么? 49 | 50 | 这是京东社交电商部维C团(WecTeam)的在线博客,官网地址是:https://wecteam.io/。 51 | 52 | 维C团(WecTeam),京东社交电商部前端技术团队,我们是一群热爱技术、乐于分享的前端工程师。主要对外输出技术实践总结、新技术探秘、Bug深度分析、优质英文资料翻译等,参与和推动前端技术的发展,为公司及行业带来价值! 53 | 54 | # 文章列表 55 | 56 | ${posts.map(item=>{ 57 | // console.log(item.title); 58 | return `* [${item.title}](https://wecteam.io/${encodeURIComponent(item.path)})` 59 | }).join('\n\n')} 60 | 61 | # 文章排版指南 62 | 63 | [如何参与本博客](https://github.com/wecteam/blog/blob/master/docs/post-guide.md) 64 | 65 | [文章排版指南](https://github.com/wecteam/blog/blob/master/docs/document-guide.md) 66 | 67 | # 联系我们 68 | 69 | 请关注我们的微信公众号 70 | 71 | ![WecTeam](https://wq.360buyimg.com/data/ppms/picture/wecteam_qrcode.jpeg) 72 | 73 | `; 74 | fs.writeFile(path.join(this.base_dir,'README.md'),content,data=>{ 75 | // console.log(data); 76 | }) 77 | }); -------------------------------------------------------------------------------- /themes/icarus/source/css/back-to-top.css: -------------------------------------------------------------------------------- 1 | #back-to-top { 2 | position: fixed; 3 | padding: 8px 0; 4 | transition: 0.4s ease opacity, 0.4s ease width, 0.4s ease transform, 0.4s ease border-radius; 5 | opacity: 0; 6 | line-height: 24px; 7 | outline: none; 8 | transform: translateY(120px); 9 | } 10 | #back-to-top.fade-in { 11 | opacity: 1; 12 | } 13 | #back-to-top.rise-up { 14 | transform: translateY(0); 15 | } -------------------------------------------------------------------------------- /themes/icarus/source/css/insight.css: -------------------------------------------------------------------------------- 1 | .ins-section-container { 2 | position: relative; 3 | background: #f7f7f7; 4 | } 5 | 6 | .ins-section { 7 | font-size: 14px; 8 | line-height: 16px; 9 | } 10 | 11 | .ins-section .ins-section-header, .ins-section .ins-search-item { 12 | padding: 8px 15px; 13 | } 14 | 15 | .ins-section .ins-section-header { 16 | color: #9a9a9a; 17 | border-bottom: 1px solid #e2e2e2; 18 | } 19 | 20 | .ins-section .ins-slug { 21 | margin-left: 5px; 22 | color: #9a9a9a; 23 | } 24 | 25 | .ins-section .ins-slug:before { 26 | content: '('; 27 | } 28 | 29 | .ins-section .ins-slug:after { 30 | content: ')'; 31 | } 32 | 33 | .ins-section .ins-search-item header, .ins-section .ins-search-item .ins-search-preview { 34 | overflow: hidden; 35 | white-space: nowrap; 36 | text-overflow: ellipsis; 37 | } 38 | 39 | .ins-section .ins-search-item header .ins-title { 40 | margin-left: 8px; 41 | } 42 | 43 | .ins-section .ins-search-item .ins-search-preview { 44 | height: 15px; 45 | font-size: 12px; 46 | color: #9a9a9a; 47 | margin: 5px 0 0 20px; 48 | } 49 | 50 | .ins-section .ins-search-item:hover, .ins-section .ins-search-item.active { 51 | color: #fff; 52 | background: #3273dc; 53 | } 54 | 55 | .ins-section .ins-search-item:hover .ins-slug, .ins-section .ins-search-item.active .ins-slug, .ins-section .ins-search-item:hover .ins-search-preview, .ins-section .ins-search-item.active .ins-search-preview { 56 | color: #fff; 57 | } -------------------------------------------------------------------------------- /themes/icarus/source/css/progressbar.css: -------------------------------------------------------------------------------- 1 | .pace { 2 | -webkit-pointer-events: none; 3 | pointer-events: none; 4 | 5 | -webkit-user-select: none; 6 | -moz-user-select: none; 7 | user-select: none; 8 | } 9 | 10 | .pace-inactive { 11 | display: none; 12 | } 13 | 14 | .pace .pace-progress { 15 | background: #3273dc; 16 | position: fixed; 17 | z-index: 2000; 18 | top: 0; 19 | right: 100%; 20 | width: 100%; 21 | height: 2px; 22 | } -------------------------------------------------------------------------------- /themes/icarus/source/css/search.css: -------------------------------------------------------------------------------- 1 | .searchbox { 2 | display: none; 3 | perspective: 50em; 4 | top: 0; 5 | left: 0; 6 | width: 100%; 7 | height: 100%; 8 | z-index: 100; 9 | background: rgba(0, 0, 0, 0.7); 10 | transform-origin: 0%; 11 | perspective-origin: top center; 12 | } 13 | 14 | .searchbox.show { 15 | display: block; 16 | } 17 | 18 | .searchbox, .searchbox .searchbox-container { 19 | position: fixed; 20 | } 21 | 22 | .searchbox .searchbox-container { 23 | overflow: hidden; 24 | } 25 | 26 | .searchbox .searchbox-selectable { 27 | cursor: pointer; 28 | } 29 | 30 | .searchbox .searchbox-input-wrapper { 31 | position: relative; 32 | } 33 | 34 | .searchbox .searchbox-input-wrapper .searchbox-input { 35 | width: 100%; 36 | border: none; 37 | outline: none; 38 | font-size: 16px; 39 | box-shadow: none; 40 | font-weight: 200; 41 | border-radius: 0; 42 | background: #fff; 43 | line-height: 20px; 44 | box-sizing: border-box; 45 | padding: 12px 28px 12px 20px; 46 | border-bottom: 1px solid #e2e2e2; 47 | } 48 | 49 | .searchbox .searchbox-input-wrapper .searchbox-close { 50 | top: 50%; 51 | right: 6px; 52 | width: 20px; 53 | height: 20px; 54 | line-height: 20px; 55 | font-size: 16px; 56 | margin-top: -11px; 57 | position: absolute; 58 | text-align: center; 59 | display: inline-block; 60 | } 61 | 62 | .searchbox .searchbox-input-wrapper .searchbox-close:hover { 63 | color: #3273dc; 64 | } 65 | 66 | .searchbox .searchbox-result-wrapper { 67 | left: 0; 68 | right: 0; 69 | top: 45px; 70 | bottom: 0; 71 | overflow-y: auto; 72 | position: absolute; 73 | } 74 | 75 | .searchbox .searchbox-container { 76 | left: 50%; 77 | top: 100px; 78 | width: 540px; 79 | z-index: 101; 80 | bottom: 100px; 81 | margin-left: -270px; 82 | box-sizing: border-box; 83 | } 84 | 85 | @media screen and (max-width: 559px), screen and (max-height: 479px) { 86 | .searchbox .searchbox-container { 87 | top: 0; 88 | left: 0; 89 | margin: 0; 90 | width: 100%; 91 | height: 100%; 92 | background: #f7f7f7; 93 | } 94 | } -------------------------------------------------------------------------------- /themes/icarus/source/images/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/icarus/source/images/avatar.png -------------------------------------------------------------------------------- /themes/icarus/source/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/icarus/source/images/favicon.ico -------------------------------------------------------------------------------- /themes/icarus/source/images/favicon.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /themes/icarus/source/images/og_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/icarus/source/images/og_image.png -------------------------------------------------------------------------------- /themes/icarus/source/images/og_image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/icarus/source/images/og_image1.png -------------------------------------------------------------------------------- /themes/icarus/source/images/thumbnail.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /themes/icarus/source/js/animation.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function $() { 3 | return Array.prototype.slice.call(document.querySelectorAll.apply(document, arguments)); 4 | } 5 | 6 | $('body > .navbar, body > .section, body > .footer').forEach(function (element) { 7 | element.style.transition = '0s'; 8 | element.style.opacity = '0'; 9 | }); 10 | document.querySelector('body > .navbar').style.transform = 'translateY(-100px)'; 11 | ['.column-main > .card', 12 | '.column-left > .card, .column-right-shadow > .card', 13 | '.column-right > .card'].map(function (selector) { 14 | $(selector).forEach(function (element) { 15 | element.style.transition = '0s'; 16 | element.style.opacity = '0'; 17 | element.style.transform = 'scale(0.8)'; 18 | element.style.transformOrigin = 'center top'; 19 | }); 20 | }); 21 | setTimeout(function () { 22 | $('body > .navbar, body > .section, body > .footer').forEach(function (element) { 23 | element.style.opacity = '1'; 24 | element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out'; 25 | }); 26 | document.querySelector('body > .navbar').style.transform = 'translateY(0)'; 27 | ['.column-main > .card', 28 | '.column-left > .card, .column-right-shadow > .card', 29 | '.column-right > .card'].map(function (selector) { 30 | var i = 1; 31 | $(selector).forEach(function (element) { 32 | setTimeout(function () { 33 | element.style.opacity = '1'; 34 | element.style.transform = ''; 35 | element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out'; 36 | }, i * 100); 37 | i++; 38 | }); 39 | }); 40 | }); 41 | })(); 42 | -------------------------------------------------------------------------------- /themes/icarus/source/js/gallery.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', function () { 2 | if (typeof ($.fn.lightGallery) === 'function') { 3 | $('.article').lightGallery({ selector: '.gallery-item' }); 4 | } 5 | if (typeof ($.fn.justifiedGallery) === 'function') { 6 | if ($('.justified-gallery > p > .gallery-item').length) { 7 | $('.justified-gallery > p > .gallery-item').unwrap(); 8 | } 9 | $('.justified-gallery').justifiedGallery(); 10 | } 11 | }); -------------------------------------------------------------------------------- /themes/icarus/source/js/main.js: -------------------------------------------------------------------------------- 1 | (function ($) { 2 | $('.article img:not(".not-gallery-item")').each(function () { 3 | // wrap images with link and add caption if possible 4 | if ($(this).parent('a').length === 0) { 5 | $(this).wrap(''); 6 | if (this.alt) { 7 | $(this).after('
    ' + this.alt + '
    '); 8 | } 9 | } 10 | }); 11 | 12 | if (typeof (moment) === 'function') { 13 | $('.article-meta time').each(function () { 14 | $(this).text(moment($(this).attr('datetime')).fromNow()); 15 | }); 16 | } 17 | 18 | $('.article > .content > table').each(function () { 19 | if ($(this).width() > $(this).parent().width()) { 20 | $(this).wrap('
    '); 21 | } 22 | }); 23 | 24 | function adjustNavbar() { 25 | const navbarWidth = $('.navbar-main .navbar-start').outerWidth() + $('.navbar-main .navbar-end').outerWidth(); 26 | if ($(document).outerWidth() < navbarWidth) { 27 | $('.navbar-main .navbar-menu').addClass('is-flex-start'); 28 | } else { 29 | $('.navbar-main .navbar-menu').removeClass('is-flex-start'); 30 | } 31 | } 32 | adjustNavbar(); 33 | $(window).resize(adjustNavbar); 34 | 35 | $('figure.highlight table').wrap('
    '); 36 | if (typeof (IcarusThemeSettings) !== 'undefined' && 37 | typeof (IcarusThemeSettings.article) !== 'undefined' && 38 | typeof (IcarusThemeSettings.article.highlight) !== 'undefined') { 39 | if (typeof (ClipboardJS) !== 'undefined' && IcarusThemeSettings.article.highlight.clipboard) { 40 | $('figure.highlight').each(function () { 41 | var id = 'code-' + Date.now() + (Math.random() * 1000 | 0); 42 | var button = ''; 43 | $(this).attr('id', id); 44 | if ($(this).find('figcaption').length) { 45 | $(this).find('figcaption').prepend(button); 46 | } else { 47 | $(this).prepend('
    ' + button + '
    '); 48 | } 49 | }); 50 | new ClipboardJS('.highlight .copy'); 51 | } 52 | var fold = IcarusThemeSettings.article.highlight.fold; 53 | if (fold.trim()) { 54 | var button = '' + (fold === 'unfolded' ? '' : '') + ''; 55 | $('figure.highlight').each(function () { 56 | if ($(this).find('figcaption').length) { 57 | $(this).find('figcaption').prepend(button); 58 | } else { 59 | $(this).prepend('
    ' + button + '
    '); 60 | } 61 | }); 62 | 63 | function toggleFold(codeBlock, isFolded) { 64 | var $toggle = $(codeBlock).find('.fold i'); 65 | !isFolded ? $(codeBlock).removeClass('folded') : $(codeBlock).addClass('folded'); 66 | !isFolded ? $toggle.removeClass('fa-angle-right') : $toggle.removeClass('fa-angle-down'); 67 | !isFolded ? $toggle.addClass('fa-angle-down') : $toggle.addClass('fa-angle-right'); 68 | } 69 | 70 | $('figure.highlight').each(function () { 71 | toggleFold(this, fold === 'folded'); 72 | }); 73 | $('figure.highlight figcaption .fold').click(function () { 74 | var $code = $(this).closest('figure.highlight'); 75 | toggleFold($code.eq(0), !$code.hasClass('folded')); 76 | }); 77 | } 78 | } 79 | 80 | var $toc = $('#toc'); 81 | if ($toc.length > 0) { 82 | var $mask = $('
    '); 83 | $mask.attr('id', 'toc-mask'); 84 | 85 | $('body').append($mask); 86 | 87 | function toggleToc() { 88 | $toc.toggleClass('is-active'); 89 | $mask.toggleClass('is-active'); 90 | } 91 | 92 | $toc.on('click', toggleToc); 93 | $mask.on('click', toggleToc); 94 | $('.navbar-main .catalogue').on('click', toggleToc); 95 | } 96 | })(jQuery); 97 | -------------------------------------------------------------------------------- /themes/landscape/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | tmp -------------------------------------------------------------------------------- /themes/landscape/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt){ 2 | grunt.initConfig({ 3 | gitclone: { 4 | fontawesome: { 5 | options: { 6 | repository: 'https://github.com/FortAwesome/Font-Awesome.git', 7 | directory: 'tmp/fontawesome' 8 | }, 9 | }, 10 | fancybox: { 11 | options: { 12 | repository: 'https://github.com/fancyapps/fancyBox.git', 13 | directory: 'tmp/fancybox' 14 | } 15 | } 16 | }, 17 | copy: { 18 | fontawesome: { 19 | expand: true, 20 | cwd: 'tmp/fontawesome/fonts/', 21 | src: ['**'], 22 | dest: 'source/css/fonts/' 23 | }, 24 | fancybox: { 25 | expand: true, 26 | cwd: 'tmp/fancybox/source/', 27 | src: ['**'], 28 | dest: 'source/fancybox/' 29 | } 30 | }, 31 | _clean: { 32 | tmp: ['tmp'], 33 | fontawesome: ['source/css/fonts'], 34 | fancybox: ['source/fancybox'] 35 | } 36 | }); 37 | 38 | require('load-grunt-tasks')(grunt); 39 | 40 | grunt.renameTask('clean', '_clean'); 41 | 42 | grunt.registerTask('fontawesome', ['gitclone:fontawesome', 'copy:fontawesome', '_clean:tmp']); 43 | grunt.registerTask('fancybox', ['gitclone:fancybox', 'copy:fancybox', '_clean:tmp']); 44 | grunt.registerTask('default', ['gitclone', 'copy', '_clean:tmp']); 45 | grunt.registerTask('clean', ['_clean']); 46 | }; -------------------------------------------------------------------------------- /themes/landscape/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Tommy Chen 2 | 3 | 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: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | 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. -------------------------------------------------------------------------------- /themes/landscape/README.md: -------------------------------------------------------------------------------- 1 | # Landscape 2 | 3 | A brand new default theme for [Hexo]. 4 | 5 | - [Preview](http://hexo.io/hexo-theme-landscape/) 6 | 7 | ## Installation 8 | 9 | ### Install 10 | 11 | ``` bash 12 | $ git clone https://github.com/hexojs/hexo-theme-landscape.git themes/landscape 13 | ``` 14 | 15 | **Landscape requires Hexo 2.4 and above.** If you would like to enable the RSS, the [hexo-generate-feed] plugin is also required. 16 | 17 | ### Enable 18 | 19 | Modify `theme` setting in `_config.yml` to `landscape`. 20 | 21 | ### Update 22 | 23 | ``` bash 24 | cd themes/landscape 25 | git pull 26 | ``` 27 | 28 | ## Configuration 29 | 30 | ``` yml 31 | # Header 32 | menu: 33 | Home: / 34 | Archives: /archives 35 | rss: /atom.xml 36 | 37 | # Content 38 | excerpt_link: Read More 39 | fancybox: true 40 | 41 | # Sidebar 42 | sidebar: right 43 | widgets: 44 | - category 45 | - tag 46 | - tagcloud 47 | - archives 48 | - recent_posts 49 | 50 | # Miscellaneous 51 | google_analytics: 52 | favicon: /favicon.png 53 | twitter: 54 | google_plus: 55 | ``` 56 | 57 | - **menu** - Navigation menu 58 | - **rss** - RSS link 59 | - **excerpt_link** - "Read More" link at the bottom of excerpted articles. `false` to hide the link. 60 | - **fancybox** - Enable [Fancybox] 61 | - **sidebar** - Sidebar style. You can choose `left`, `right`, `bottom` or `false`. 62 | - **widgets** - Widgets displaying in sidebar 63 | - **google_analytics** - Google Analytics ID 64 | - **favicon** - Favicon path 65 | - **twitter** - Twiiter ID 66 | - **google_plus** - Google+ ID 67 | 68 | ## Features 69 | 70 | ### Fancybox 71 | 72 | Landscape uses [Fancybox] to showcase your photos. You can use Markdown syntax or fancybox tag plugin to add your photos. 73 | 74 | ``` 75 | ![img caption](img url) 76 | 77 | {% fancybox img_url [img_thumbnail] [img_caption] %} 78 | ``` 79 | 80 | ### Sidebar 81 | 82 | You can put your sidebar in left side, right side or bottom of your site by editing `sidebar` setting. 83 | 84 | Landscape provides 5 built-in widgets: 85 | 86 | - category 87 | - tag 88 | - tagcloud 89 | - archives 90 | - recent_posts 91 | 92 | All of them are enabled by default. You can edit them in `widget` setting. 93 | 94 | ## Development 95 | 96 | ### Requirements 97 | 98 | - [Grunt] 0.4+ 99 | - Hexo 2.4+ 100 | 101 | ### Grunt tasks 102 | 103 | - **default** - Download [Fancybox] and [Font Awesome]. 104 | - **fontawesome** - Only download [Font Awesome]. 105 | - **fancybox** - Only download [Fancybox]. 106 | - **clean** - Clean temporarily files and downloaded files. 107 | 108 | [Hexo]: https://hexo.io/ 109 | [Fancybox]: http://fancyapps.com/fancybox/ 110 | [Font Awesome]: http://fontawesome.io/ 111 | [Grunt]: http://gruntjs.com/ 112 | [hexo-generate-feed]: https://github.com/hexojs/hexo-generator-feed 113 | -------------------------------------------------------------------------------- /themes/landscape/_config.yml: -------------------------------------------------------------------------------- 1 | # Header 2 | menu: 3 | Home: / 4 | Archives: /archives 5 | rss: /atom.xml 6 | 7 | # Content 8 | excerpt_link: Read More 9 | fancybox: true 10 | 11 | # Sidebar 12 | sidebar: right 13 | widgets: 14 | - category 15 | - tag 16 | - tagcloud 17 | - archive 18 | - recent_posts 19 | 20 | # display widgets at the bottom of index pages (pagination == 2) 21 | index_widgets: 22 | # - category 23 | # - tagcloud 24 | # - archive 25 | 26 | # widget behavior 27 | archive_type: 'monthly' 28 | show_count: false 29 | 30 | # Miscellaneous 31 | google_analytics: 32 | gauges_analytics: 33 | favicon: /favicon.png 34 | twitter: 35 | google_plus: 36 | fb_admins: 37 | fb_app_id: 38 | -------------------------------------------------------------------------------- /themes/landscape/languages/de.yml: -------------------------------------------------------------------------------- 1 | categories: Kategorien 2 | search: Suche 3 | tags: Tags 4 | tagcloud: Tag Cloud 5 | tweets: Tweets 6 | prev: zurück 7 | next: weiter 8 | comment: Kommentare 9 | archive_a: Archiv 10 | archive_b: "Archive: %s" 11 | page: Seite %d 12 | recent_posts: letzter Beitrag 13 | newer: Neuer 14 | older: Älter 15 | share: Teilen 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: Kategorie 19 | tag: Tag 20 | -------------------------------------------------------------------------------- /themes/landscape/languages/default.yml: -------------------------------------------------------------------------------- 1 | categories: Categories 2 | search: Search 3 | tags: Tags 4 | tagcloud: Tag Cloud 5 | tweets: Tweets 6 | prev: Prev 7 | next: Next 8 | comment: Comments 9 | archive_a: Archives 10 | archive_b: "Archives: %s" 11 | page: Page %d 12 | recent_posts: Recent Posts 13 | newer: Newer 14 | older: Older 15 | share: Share 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: Category 19 | tag: Tag -------------------------------------------------------------------------------- /themes/landscape/languages/es.yml: -------------------------------------------------------------------------------- 1 | categories: Categorías 2 | search: Buscar 3 | tags: Tags 4 | tagcloud: Nube de Tags 5 | tweets: Tweets 6 | prev: Previo 7 | next: Siguiente 8 | comment: Comentarios 9 | archive_a: Archivos 10 | archive_b: "Archivos: %s" 11 | page: Página %d 12 | recent_posts: Posts recientes 13 | newer: Nuevo 14 | older: Viejo 15 | share: Compartir 16 | powered_by: Construido por 17 | rss_feed: RSS 18 | category: Categoría 19 | tag: Tag -------------------------------------------------------------------------------- /themes/landscape/languages/fr.yml: -------------------------------------------------------------------------------- 1 | categories: Catégories 2 | search: Rechercher 3 | tags: Mot-clés 4 | tagcloud: Nuage de mot-clés 5 | tweets: Tweets 6 | prev: Précédent 7 | next: Suivant 8 | comment: Commentaires 9 | archive_a: Archives 10 | archive_b: "Archives: %s" 11 | page: Page %d 12 | recent_posts: Articles récents 13 | newer: Récent 14 | older: Ancien 15 | share: Partager 16 | powered_by: Propulsé par 17 | rss_feed: Flux RSS 18 | category: Catégorie 19 | tag: Mot-clé 20 | -------------------------------------------------------------------------------- /themes/landscape/languages/ja.yml: -------------------------------------------------------------------------------- 1 | categories: カテゴリ 2 | search: 検索 3 | tags: タグ 4 | tagcloud: タグクラウド 5 | tweets: ツイート 6 | prev: 戻る 7 | next: 次へ 8 | comment: コメント 9 | archive_a: アーカイブ 10 | archive_b: "アーカイブ: %s" 11 | page: ページ %d 12 | recent_posts: 最近の投稿 13 | newer: 次の記事 14 | older: 前の記事 15 | share: 共有 16 | powered_by: Powered by 17 | rss_feed: RSSフィード 18 | category: カテゴリ 19 | tag: タグ 20 | -------------------------------------------------------------------------------- /themes/landscape/languages/ko.yml: -------------------------------------------------------------------------------- 1 | categories: 카테고리 2 | search: 검색 3 | tags: 태그 4 | tagcloud: 태그 클라우드 5 | tweets: 트윗 6 | prev: 이전 7 | next: 다음 8 | comment: 댓글 9 | archive_a: 아카이브 10 | archive_b: "아카이브: %s" 11 | page: 페이지 %d 12 | recent_posts: 최근 포스트 13 | newer: 최신 14 | older: 이전 15 | share: 공유 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: 카테고리 19 | tag: 태그 20 | -------------------------------------------------------------------------------- /themes/landscape/languages/nl.yml: -------------------------------------------------------------------------------- 1 | 2 | categories: Categorieën 3 | search: Zoeken 4 | tags: Labels 5 | tagcloud: Tag Cloud 6 | tweets: Tweets 7 | prev: Vorige 8 | next: Volgende 9 | comment: Commentaren 10 | archive_a: Archieven 11 | archive_b: "Archieven: %s" 12 | page: Pagina %d 13 | recent_posts: Recente berichten 14 | newer: Nieuwer 15 | older: Ouder 16 | share: Delen 17 | powered_by: Powered by 18 | rss_feed: RSS Feed 19 | category: Categorie 20 | tag: Label 21 | -------------------------------------------------------------------------------- /themes/landscape/languages/no.yml: -------------------------------------------------------------------------------- 1 | categories: Kategorier 2 | search: Søk 3 | tags: Tags 4 | tagcloud: Tag Cloud 5 | tweets: Tweets 6 | prev: Forrige 7 | next: Neste 8 | comment: Kommentarer 9 | archive_a: Arkiv 10 | archive_b: "Arkiv: %s" 11 | page: Side %d 12 | recent_posts: Siste innlegg 13 | newer: Newer 14 | older: Older 15 | share: Share 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: Category 19 | tag: Tag -------------------------------------------------------------------------------- /themes/landscape/languages/pt.yml: -------------------------------------------------------------------------------- 1 | categories: Categorias 2 | search: Buscar 3 | tags: Tags 4 | tagcloud: Nuvem de Tags 5 | tweets: Tweets 6 | prev: Anterior 7 | next: Próximo 8 | comment: Comentários 9 | archive_a: Arquivos 10 | archive_b: "Arquivos: %s" 11 | page: Página %d 12 | recent_posts: Postagens Recentes 13 | newer: Mais Recente 14 | older: Mais Antigo 15 | share: Compartilhar 16 | powered_by: Desenvolvido por 17 | rss_feed: Feed RSS 18 | category: Categoria 19 | tag: Tag 20 | -------------------------------------------------------------------------------- /themes/landscape/languages/ru.yml: -------------------------------------------------------------------------------- 1 | categories: Категории 2 | search: Поиск 3 | tags: Метки 4 | tagcloud: Облако меток 5 | tweets: Твиты 6 | prev: Назад 7 | next: Вперед 8 | comment: Комментарии 9 | archive_a: Архив 10 | archive_b: "Архив: %s" 11 | page: Страница %d 12 | recent_posts: Недавние записи 13 | newer: Следующий 14 | older: Предыдущий 15 | share: Поделиться 16 | powered_by: Создано с помощью 17 | rss_feed: RSS-каналы 18 | category: Категория 19 | tag: Метка -------------------------------------------------------------------------------- /themes/landscape/languages/zh-CN.yml: -------------------------------------------------------------------------------- 1 | categories: 分类 2 | search: 搜索 3 | tags: 标签 4 | tagcloud: 标签云 5 | tweets: 推文 6 | prev: 上一页 7 | next: 下一页 8 | comment: 留言 9 | archive_a: 归档 10 | archive_b: 归档:%s 11 | page: 第 %d 页 12 | recent_posts: 最新文章 13 | newer: Newer 14 | older: Older 15 | share: Share 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: Category 19 | tag: Tag -------------------------------------------------------------------------------- /themes/landscape/languages/zh-TW.yml: -------------------------------------------------------------------------------- 1 | categories: 分類 2 | search: 搜尋 3 | tags: 標籤 4 | tagcloud: 標籤雲 5 | tweets: 推文 6 | prev: 上一頁 7 | next: 下一頁 8 | comment: 留言 9 | archive_a: 彙整 10 | archive_b: 彙整:%s 11 | page: 第 %d 頁 12 | recent_posts: 最新文章 13 | newer: Newer 14 | older: Older 15 | share: Share 16 | powered_by: Powered by 17 | rss_feed: RSS Feed 18 | category: Category 19 | tag: Tag -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/after-footer.ejs: -------------------------------------------------------------------------------- 1 | <% if (config.disqus_shortname){ %> 2 | 15 | <% } %> 16 | 17 | 18 | 19 | <% if (theme.fancybox){ %> 20 | <%- css('fancybox/jquery.fancybox') %> 21 | <%- js('fancybox/jquery.fancybox.pack') %> 22 | <% } %> 23 | 24 | <%- js('js/script') %> 25 | <%- partial('gauges-analytics') %> 26 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/archive-post.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 | <%- partial('post/date', {class_name: 'archive-article-date', date_format: 'MMM D'}) %> 5 | <%- partial('post/title', {class_name: 'archive-article-title'}) %> 6 |
    7 |
    8 |
    -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/archive.ejs: -------------------------------------------------------------------------------- 1 | <% if (pagination == 2){ %> 2 | <% page.posts.each(function(post){ %> 3 | <%- partial('article', {post: post, index: true}) %> 4 | <% }) %> 5 | <% } else { %> 6 | <% var last; %> 7 | <% page.posts.each(function(post, i){ %> 8 | <% var year = post.date.year(); %> 9 | <% if (last != year){ %> 10 | <% if (last != null){ %> 11 |
    12 | <% } %> 13 | <% last = year; %> 14 |
    15 |
    16 | <%= year %> 17 |
    18 |
    19 | <% } %> 20 | <%- partial('archive-post', {post: post, even: i % 2 == 0}) %> 21 | <% }) %> 22 | <% if (page.posts.length){ %> 23 |
    24 | <% } %> 25 | <% } %> 26 | <% if (page.total > 1){ %> 27 | 34 | <% } %> 35 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/article.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 6 |
    7 | <%- partial('post/gallery') %> 8 | <% if (post.link || post.title){ %> 9 |
    10 | <%- partial('post/title', {class_name: 'article-title'}) %> 11 |
    12 | <% } %> 13 |
    14 | <% if (post.excerpt && index){ %> 15 | <%- post.excerpt %> 16 | <% if (theme.excerpt_link){ %> 17 |

    18 | <%= theme.excerpt_link %> 19 |

    20 | <% } %> 21 | <% } else { %> 22 | <%- post.content %> 23 | <% } %> 24 |
    25 | 32 |
    33 | <% if (!index){ %> 34 | <%- partial('post/nav') %> 35 | <% } %> 36 |
    37 | 38 | <% if (!index && post.comments && config.disqus_shortname){ %> 39 |
    40 |
    41 | 42 |
    43 |
    44 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/footer.ejs: -------------------------------------------------------------------------------- 1 |
    2 | <% if (theme.sidebar === 'bottom'){ %> 3 | <%- partial('_partial/sidebar') %> 4 | <% } %> 5 |
    6 | 10 |
    11 |
    -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/gauges-analytics.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.gauges_analytics){ %> 2 | 3 | 17 | 18 | <% } %> 19 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/google-analytics.ejs: -------------------------------------------------------------------------------- 1 | <% if (theme.google_analytics){ %> 2 | 3 | 13 | 14 | <% } %> 15 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/head.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%- partial('google-analytics') %> 6 | <% 7 | var title = page.title; 8 | 9 | if (is_archive()){ 10 | title = __('archive_a'); 11 | 12 | if (is_month()){ 13 | title += ': ' + page.year + '/' + page.month; 14 | } else if (is_year()){ 15 | title += ': ' + page.year; 16 | } 17 | } else if (is_category()){ 18 | title = __('category') + ': ' + page.category; 19 | } else if (is_tag()){ 20 | title = __('tag') + ': ' + page.tag; 21 | } 22 | %> 23 | <% if (title){ %><%= title %> | <% } %><%= config.title %> 24 | 25 | <%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %> 26 | <% if (theme.rss){ %> 27 | 28 | <% } %> 29 | <% if (theme.favicon){ %> 30 | 31 | <% } %> 32 | <% if (config.highlight.enable){ %> 33 | 34 | <% } %> 35 | <%- css('css/style') %> 36 | 37 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/header.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/mobile-nav.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/category.ejs: -------------------------------------------------------------------------------- 1 | <% if (post.categories && post.categories.length){ %> 2 | 10 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/date.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/gallery.ejs: -------------------------------------------------------------------------------- 1 | <% if (post.photos && post.photos.length){ %> 2 |
    3 |
    4 | <% post.photos.forEach(function(photo, i){ %> 5 | 6 | 7 | 8 | <% }) %> 9 |
    10 |
    11 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/nav.ejs: -------------------------------------------------------------------------------- 1 | <% if (post.prev || post.next){ %> 2 | 22 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/tag.ejs: -------------------------------------------------------------------------------- 1 | <% if (post.tags && post.tags.length){ %> 2 | <%- list_tags(post.tags, { 3 | show_count: false, 4 | class: 'article-tag' 5 | }) %> 6 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/post/title.ejs: -------------------------------------------------------------------------------- 1 | <% if (post.link){ %> 2 |

    3 | 4 |

    5 | <% } else if (post.title){ %> 6 | <% if (index){ %> 7 |

    8 | <%= post.title %> 9 |

    10 | <% } else { %> 11 |

    12 | <%= post.title %> 13 |

    14 | <% } %> 15 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_partial/sidebar.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /themes/landscape/layout/_widget/archive.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.posts.length){ %> 2 |
    3 |

    <%= __('archive_a') %>

    4 |
    5 | <%- list_archives({show_count: theme.show_count, type: theme.archive_type}) %> 6 |
    7 |
    8 | <% } %> 9 | -------------------------------------------------------------------------------- /themes/landscape/layout/_widget/category.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.categories.length){ %> 2 |
    3 |

    <%= __('categories') %>

    4 |
    5 | <%- list_categories({show_count: theme.show_count}) %> 6 |
    7 |
    8 | <% } %> 9 | -------------------------------------------------------------------------------- /themes/landscape/layout/_widget/recent_posts.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.posts.length){ %> 2 |
    3 |

    <%= __('recent_posts') %>

    4 |
    5 | 12 |
    13 |
    14 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/_widget/tag.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.tags.length){ %> 2 |
    3 |

    <%= __('tags') %>

    4 |
    5 | <%- list_tags({show_count: theme.show_count}) %> 6 |
    7 |
    8 | <% } %> 9 | -------------------------------------------------------------------------------- /themes/landscape/layout/_widget/tagcloud.ejs: -------------------------------------------------------------------------------- 1 | <% if (site.tags.length){ %> 2 |
    3 |

    <%= __('tagcloud') %>

    4 |
    5 | <%- tagcloud() %> 6 |
    7 |
    8 | <% } %> -------------------------------------------------------------------------------- /themes/landscape/layout/archive.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/archive', {pagination: config.archive, index: true}) %> -------------------------------------------------------------------------------- /themes/landscape/layout/category.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/archive', {pagination: config.category, index: true}) %> -------------------------------------------------------------------------------- /themes/landscape/layout/index.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/archive', {pagination: 2, index: true}) %> -------------------------------------------------------------------------------- /themes/landscape/layout/layout.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/head') %> 2 | 3 |
    4 |
    5 | <%- partial('_partial/header', null, {cache: !config.relative_link}) %> 6 |
    7 |
    <%- body %>
    8 | <% if (theme.sidebar && theme.sidebar !== 'bottom'){ %> 9 | <%- partial('_partial/sidebar', null, {cache: !config.relative_link}) %> 10 | <% } %> 11 |
    12 | <%- partial('_partial/footer', null, {cache: !config.relative_link}) %> 13 |
    14 | <%- partial('_partial/mobile-nav', null, {cache: !config.relative_link}) %> 15 | <%- partial('_partial/after-footer') %> 16 |
    17 | 18 | -------------------------------------------------------------------------------- /themes/landscape/layout/page.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/article', {post: page, index: false}) %> -------------------------------------------------------------------------------- /themes/landscape/layout/post.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/article', {post: page, index: false}) %> -------------------------------------------------------------------------------- /themes/landscape/layout/tag.ejs: -------------------------------------------------------------------------------- 1 | <%- partial('_partial/archive', {pagination: config.tag, index: true}) %> -------------------------------------------------------------------------------- /themes/landscape/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hexo-theme-landscape", 3 | "version": "0.0.2", 4 | "private": true, 5 | "devDependencies": { 6 | "grunt": "~0.4.2", 7 | "load-grunt-tasks": "~0.2.0", 8 | "grunt-git": "~0.2.2", 9 | "grunt-contrib-clean": "~0.5.0", 10 | "grunt-contrib-copy": "~0.4.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /themes/landscape/scripts/fancybox.js: -------------------------------------------------------------------------------- 1 | var rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[.\!\/\\w]*))?)/; 2 | 3 | /** 4 | * Fancybox tag 5 | * 6 | * Syntax: 7 | * {% fancybox /path/to/image [/path/to/thumbnail] [title] %} 8 | */ 9 | 10 | hexo.extend.tag.register('fancybox', function(args){ 11 | var original = args.shift(), 12 | thumbnail = ''; 13 | 14 | if (args.length && rUrl.test(args[0])){ 15 | thumbnail = args.shift(); 16 | } 17 | 18 | var title = args.join(' '); 19 | 20 | return '' + 21 | '' + title + '' 22 | '' + 23 | (title ? '' + title + '' : ''); 24 | }); -------------------------------------------------------------------------------- /themes/landscape/source/css/_extend.styl: -------------------------------------------------------------------------------- 1 | $block-caption 2 | text-decoration: none 3 | text-transform: uppercase 4 | letter-spacing: 2px 5 | color: color-grey 6 | margin-bottom: 1em 7 | margin-left: 5px 8 | line-height: 1em 9 | text-shadow: 0 1px #fff 10 | font-weight: bold 11 | 12 | $block 13 | background: #fff 14 | box-shadow: 1px 2px 3px #ddd 15 | border: 1px solid color-border 16 | border-radius: 3px 17 | 18 | $base-style 19 | h1 20 | font-size: 2em 21 | h2 22 | font-size: 1.5em 23 | h3 24 | font-size: 1.3em 25 | h4 26 | font-size: 1.2em 27 | h5 28 | font-size: 1em 29 | h6 30 | font-size: 1em 31 | color: color-grey 32 | hr 33 | border: 1px dashed color-border 34 | strong 35 | font-weight: bold 36 | em, cite 37 | font-style: italic 38 | sup, sub 39 | font-size: 0.75em 40 | line-height: 0 41 | position: relative 42 | vertical-align: baseline 43 | sup 44 | top: -0.5em 45 | sub 46 | bottom: -0.2em 47 | small 48 | font-size: 0.85em 49 | acronym, abbr 50 | border-bottom: 1px dotted 51 | ul, ol, dl 52 | margin: 0 20px 53 | line-height: line-height 54 | ul, ol 55 | ul, ol 56 | margin-top: 0 57 | margin-bottom: 0 58 | ul 59 | list-style: disc 60 | ol 61 | list-style: decimal 62 | dt 63 | font-weight: bold -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/archive.styl: -------------------------------------------------------------------------------- 1 | .archives-wrap 2 | margin: block-margin 0 3 | 4 | .archives 5 | clearfix() 6 | 7 | .archive-year-wrap 8 | margin-bottom: 1em 9 | 10 | .archive-year 11 | @extend $block-caption 12 | 13 | .archives 14 | column-gap: 10px 15 | @media mq-tablet 16 | column-count: 2 17 | @media mq-normal 18 | column-count: 3 19 | 20 | .archive-article 21 | avoid-column-break() 22 | 23 | .archive-article-inner 24 | @extend $block 25 | padding: 10px 26 | margin-bottom: 15px 27 | 28 | .archive-article-title 29 | text-decoration: none 30 | font-weight: bold 31 | color: color-default 32 | transition: color 0.2s 33 | line-height: line-height 34 | &:hover 35 | color: color-link 36 | 37 | .archive-article-footer 38 | margin-top: 1em 39 | 40 | .archive-article-date 41 | color: color-grey 42 | text-decoration: none 43 | font-size: 0.85em 44 | line-height: 1em 45 | margin-bottom: 0.5em 46 | display: block 47 | 48 | #page-nav 49 | clearfix() 50 | margin: block-margin auto 51 | background: #fff 52 | box-shadow: 1px 2px 3px #ddd 53 | border: 1px solid color-border 54 | border-radius: 3px 55 | text-align: center 56 | color: color-grey 57 | overflow: hidden 58 | a, span 59 | padding: 10px 20px 60 | line-height: 1 61 | height: 2ex 62 | a 63 | color: color-grey 64 | text-decoration: none 65 | &:hover 66 | background: color-grey 67 | color: #fff 68 | .prev 69 | float: left 70 | .next 71 | float: right 72 | .page-number 73 | display: inline-block 74 | @media mq-mobile 75 | display: none 76 | .current 77 | color: color-default 78 | font-weight: bold 79 | .space 80 | color: color-border -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/comment.styl: -------------------------------------------------------------------------------- 1 | #comments 2 | background: #fff 3 | box-shadow: 1px 2px 3px #ddd 4 | padding: article-padding 5 | border: 1px solid color-border 6 | border-radius: 3px 7 | margin: block-margin 0 8 | a 9 | color: color-link -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/footer.styl: -------------------------------------------------------------------------------- 1 | #footer 2 | background: color-footer-background 3 | padding: 50px 0 4 | border-top: 1px solid color-border 5 | color: color-grey 6 | a 7 | color: color-link 8 | text-decoration: none 9 | &:hover 10 | text-decoration: underline 11 | 12 | #footer-info 13 | line-height: line-height 14 | font-size: 0.85em -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/header.styl: -------------------------------------------------------------------------------- 1 | #header 2 | height: banner-height 3 | position: relative 4 | border-bottom: 1px solid color-border 5 | &:before, &:after 6 | content: "" 7 | position: absolute 8 | left: 0 9 | right: 0 10 | height: 40px 11 | &:before 12 | top: 0 13 | background: linear-gradient(rgba(0, 0, 0, 0.2), transparent) 14 | &:after 15 | bottom: 0 16 | background: linear-gradient(transparent, rgba(0, 0, 0, 0.2)) 17 | 18 | #header-outer 19 | height: 100% 20 | position: relative 21 | 22 | #header-inner 23 | position: relative 24 | overflow: hidden 25 | 26 | #banner 27 | position: absolute 28 | top: 0 29 | left: 0 30 | width: 100% 31 | height: 100% 32 | background: url(banner-url) center #000 33 | background-size: cover 34 | z-index: -1 35 | 36 | #header-title 37 | text-align: center 38 | height: logo-size 39 | position: absolute 40 | top: 50% 41 | left: 0 42 | margin-top: logo-size * -0.5 43 | 44 | $logo-text 45 | text-decoration: none 46 | color: #fff 47 | font-weight: 300 48 | text-shadow: 0 1px 4px rgba(0, 0, 0, 0.3) 49 | 50 | #logo 51 | @extend $logo-text 52 | font-size: logo-size 53 | line-height: logo-size 54 | letter-spacing: 2px 55 | 56 | #subtitle 57 | @extend $logo-text 58 | font-size: subtitle-size 59 | line-height: subtitle-size 60 | letter-spacing: 1px 61 | 62 | #subtitle-wrap 63 | margin-top: subtitle-size 64 | 65 | #main-nav 66 | float: left 67 | margin-left: -15px 68 | 69 | $nav-link 70 | float: left 71 | color: #fff 72 | opacity: 0.6 73 | text-decoration: none 74 | text-shadow: 0 1px rgba(0, 0, 0, 0.2) 75 | transition: opacity 0.2s 76 | display: block 77 | padding: 20px 15px 78 | &:hover 79 | opacity: 1 80 | 81 | .nav-icon 82 | @extend $nav-link 83 | font-family: font-icon 84 | text-align: center 85 | font-size: font-size 86 | width: font-size 87 | height: font-size 88 | padding: 20px 15px 89 | position: relative 90 | cursor: pointer 91 | 92 | .main-nav-link 93 | @extend $nav-link 94 | font-weight: 300 95 | letter-spacing: 1px 96 | @media mq-mobile 97 | display: none 98 | 99 | #main-nav-toggle 100 | display: none 101 | &:before 102 | content: "\f0c9" 103 | @media mq-mobile 104 | display: block 105 | 106 | #sub-nav 107 | float: right 108 | margin-right: -15px 109 | 110 | #nav-rss-link 111 | &:before 112 | content: "\f09e" 113 | 114 | #nav-search-btn 115 | &:before 116 | content: "\f002" 117 | 118 | #search-form-wrap 119 | position: absolute 120 | top: 15px 121 | width: 150px 122 | height: 30px 123 | right: -150px 124 | opacity: 0 125 | transition: 0.2s ease-out 126 | &.on 127 | opacity: 1 128 | right: 0 129 | @media mq-mobile 130 | width: 100% 131 | right: -100% 132 | 133 | .search-form 134 | position: absolute 135 | top: 0 136 | left: 0 137 | right: 0 138 | background: #fff 139 | padding: 5px 15px 140 | border-radius: 15px 141 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.3) 142 | 143 | .search-form-input 144 | border: none 145 | background: none 146 | color: color-default 147 | width: 100% 148 | font: 13px font-sans 149 | outline: none 150 | &::-webkit-search-results-decoration 151 | &::-webkit-search-cancel-button 152 | -webkit-appearance: none 153 | 154 | .search-form-submit 155 | position: absolute 156 | top: 50% 157 | right: 10px 158 | margin-top: -7px 159 | font: 13px font-icon 160 | border: none 161 | background: none 162 | color: #bbb 163 | cursor: pointer 164 | &:hover, &:focus 165 | color: #777 -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/highlight.styl: -------------------------------------------------------------------------------- 1 | // https://github.com/chriskempson/tomorrow-theme 2 | highlight-background = #2d2d2d 3 | highlight-current-line = #393939 4 | highlight-selection = #515151 5 | highlight-foreground = #cccccc 6 | highlight-comment = #999999 7 | highlight-red = #f2777a 8 | highlight-orange = #f99157 9 | highlight-yellow = #ffcc66 10 | highlight-green = #99cc99 11 | highlight-aqua = #66cccc 12 | highlight-blue = #6699cc 13 | highlight-purple = #cc99cc 14 | 15 | $code-block 16 | background: highlight-background 17 | margin: 0 article-padding * -1 18 | padding: 15px article-padding 19 | border-style: solid 20 | border-color: color-border 21 | border-width: 1px 0 22 | overflow: auto 23 | color: highlight-foreground 24 | line-height: font-size * line-height 25 | 26 | $line-numbers 27 | color: #666 28 | font-size: 0.85em 29 | 30 | .article-entry 31 | pre, code 32 | font-family: font-mono 33 | code 34 | background: color-background 35 | text-shadow: 0 1px #fff 36 | padding: 0 0.3em 37 | pre 38 | @extend $code-block 39 | code 40 | background: none 41 | text-shadow: none 42 | padding: 0 43 | .highlight 44 | @extend $code-block 45 | pre 46 | border: none 47 | margin: 0 48 | padding: 0 49 | table 50 | margin: 0 51 | width: auto 52 | td 53 | border: none 54 | padding: 0 55 | figcaption 56 | clearfix() 57 | font-size: 0.85em 58 | color: highlight-comment 59 | line-height: 1em 60 | margin-bottom: 1em 61 | a 62 | float: right 63 | .gutter pre 64 | @extend $line-numbers 65 | text-align: right 66 | padding-right: 20px 67 | .line 68 | height: font-size * line-height 69 | .line.marked 70 | background: highlight-selection 71 | .gist 72 | margin: 0 article-padding * -1 73 | border-style: solid 74 | border-color: color-border 75 | border-width: 1px 0 76 | background: highlight-background 77 | padding: 15px article-padding 15px 0 78 | .gist-file 79 | border: none 80 | font-family: font-mono 81 | margin: 0 82 | .gist-data 83 | background: none 84 | border: none 85 | .line-numbers 86 | @extend $line-numbers 87 | background: none 88 | border: none 89 | padding: 0 20px 0 0 90 | .line-data 91 | padding: 0 !important 92 | .highlight 93 | margin: 0 94 | padding: 0 95 | border: none 96 | .gist-meta 97 | background: highlight-background 98 | color: highlight-comment 99 | font: 0.85em font-sans 100 | text-shadow: 0 0 101 | padding: 0 102 | margin-top: 1em 103 | margin-left: article-padding 104 | a 105 | color: color-link 106 | font-weight: normal 107 | &:hover 108 | text-decoration: underline 109 | 110 | pre 111 | .comment 112 | .title 113 | color: highlight-comment 114 | .variable 115 | .attribute 116 | .tag 117 | .regexp 118 | .ruby .constant 119 | .xml .tag .title 120 | .xml .pi 121 | .xml .doctype 122 | .html .doctype 123 | .css .id 124 | .css .class 125 | .css .pseudo 126 | color: highlight-red 127 | .number 128 | .preprocessor 129 | .built_in 130 | .literal 131 | .params 132 | .constant 133 | color: highlight-orange 134 | .class 135 | .ruby .class .title 136 | .css .rules .attribute 137 | color: highlight-green 138 | .string 139 | .value 140 | .inheritance 141 | .header 142 | .ruby .symbol 143 | .xml .cdata 144 | color: highlight-green 145 | .css .hexcolor 146 | color: highlight-aqua 147 | .function 148 | .python .decorator 149 | .python .title 150 | .ruby .function .title 151 | .ruby .title .keyword 152 | .perl .sub 153 | .javascript .title 154 | .coffeescript .title 155 | color: highlight-blue 156 | .keyword 157 | .javascript .function 158 | color: highlight-purple 159 | -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/mobile.styl: -------------------------------------------------------------------------------- 1 | @media mq-mobile 2 | #mobile-nav 3 | position: absolute 4 | top: 0 5 | left: 0 6 | width: mobile-nav-width 7 | height: 100% 8 | background: color-mobile-nav-background 9 | border-right: 1px solid #fff 10 | 11 | @media mq-mobile 12 | .mobile-nav-link 13 | display: block 14 | color: color-grey 15 | text-decoration: none 16 | padding: 15px 20px 17 | font-weight: bold 18 | &:hover 19 | color: #fff 20 | -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/sidebar-aside.styl: -------------------------------------------------------------------------------- 1 | #sidebar 2 | @media mq-normal 3 | column(sidebar-column) 4 | 5 | .widget-wrap 6 | margin: block-margin 0 7 | 8 | .widget-title 9 | @extend $block-caption 10 | 11 | .widget 12 | color: color-sidebar-text 13 | text-shadow: 0 1px #fff 14 | background: color-widget-background 15 | box-shadow: 0 -1px 4px color-widget-border inset 16 | border: 1px solid color-widget-border 17 | padding: 15px 18 | border-radius: 3px 19 | a 20 | color: color-link 21 | text-decoration: none 22 | &:hover 23 | text-decoration: underline 24 | ul, ol, dl 25 | ul, ol, dl 26 | margin-left: 15px 27 | list-style: disc -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/sidebar-bottom.styl: -------------------------------------------------------------------------------- 1 | .widget-wrap 2 | margin-bottom: block-margin !important 3 | @media mq-normal 4 | column(main-column) 5 | 6 | .widget-title 7 | color: #ccc 8 | text-transform: uppercase 9 | letter-spacing: 2px 10 | margin-bottom: .5em 11 | line-height: 1em 12 | font-weight: bold 13 | 14 | .widget 15 | color: color-grey 16 | ul, ol 17 | li 18 | display: inline-block 19 | zoom:1 20 | *display:inline 21 | padding-right: .75em 22 | /* Having problems getting balanced white space between items 23 | li:before 24 | content: " | " 25 | li:first-child:before 26 | content: none 27 | */ 28 | -------------------------------------------------------------------------------- /themes/landscape/source/css/_partial/sidebar.styl: -------------------------------------------------------------------------------- 1 | if sidebar is bottom 2 | @import "sidebar-bottom" 3 | else 4 | @import "sidebar-aside" 5 | 6 | .widget 7 | @extend $base-style 8 | line-height: line-height 9 | word-wrap: break-word 10 | font-size: 0.9em 11 | ul, ol 12 | list-style: none 13 | margin: 0 14 | ul, ol 15 | margin: 0 20px 16 | ul 17 | list-style: disc 18 | ol 19 | list-style: decimal 20 | 21 | .category-list-count 22 | .tag-list-count 23 | .archive-list-count 24 | padding-left: 5px 25 | color: color-grey 26 | font-size: 0.85em 27 | &:before 28 | content: "(" 29 | &:after 30 | content: ")" 31 | 32 | .tagcloud 33 | a 34 | margin-right: 5px 35 | display: inline-block 36 | -------------------------------------------------------------------------------- /themes/landscape/source/css/_util/grid.styl: -------------------------------------------------------------------------------- 1 | ///////////////// 2 | // Semantic.gs // for Stylus: http://learnboost.github.com/stylus/ 3 | ///////////////// 4 | 5 | // Utility function — you should never need to modify this 6 | // _gridsystem-width = (column-width + gutter-width) * columns 7 | gridsystem-width(_columns = columns) 8 | (column-width + gutter-width) * _columns 9 | 10 | // Set @total-width to 100% for a fluid layout 11 | // total-width = gridsystem-width(columns) 12 | total-width = 100% 13 | 14 | ////////// 15 | // GRID // 16 | ////////// 17 | 18 | body 19 | clearfix() 20 | width: 100% 21 | 22 | row(_columns = columns) 23 | clearfix() 24 | display: block 25 | width: total-width * ((gutter-width + gridsystem-width(_columns)) / gridsystem-width(_columns)) 26 | margin: 0 total-width * (((gutter-width * .5) / gridsystem-width(_columns)) * -1) 27 | 28 | column(x, _columns = columns) 29 | display: inline 30 | float: left 31 | width: total-width * ((((gutter-width + column-width) * x) - gutter-width) / gridsystem-width(_columns)) 32 | margin: 0 total-width * ((gutter-width * .5) / gridsystem-width(_columns)) 33 | 34 | push(offset = 1) 35 | margin-left: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) 36 | 37 | pull(offset = 1) 38 | margin-right: total-width * (((gutter-width + column-width) * offset) / gridsystem-width(columns)) -------------------------------------------------------------------------------- /themes/landscape/source/css/_util/mixin.styl: -------------------------------------------------------------------------------- 1 | // http://www.zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement/ 2 | hide-text() 3 | text-indent: 100% 4 | white-space: nowrap 5 | overflow: hidden 6 | 7 | // http://codepen.io/shshaw/full/gEiDt 8 | absolute-center(width, height = width) 9 | // margin: auto 10 | // position: absolute 11 | // top: 50% 12 | // top: 0 13 | // left: 0 14 | // bottom: 0 15 | // right: 0 16 | // width: width 17 | // height: height 18 | // overflow: auto 19 | width: width 20 | height: height 21 | position: absolute 22 | top: 50% 23 | left: 50% 24 | margin-top: width * -0.5 25 | margin-left: height * -0.5 26 | 27 | avoid-column-break() 28 | vendor("column-break-inside", avoid, only: webkit) 29 | page-break-inside: avoid // for firefox 30 | overflow: hidden // fix for firefox 31 | break-inside: avoid-column 32 | -------------------------------------------------------------------------------- /themes/landscape/source/css/_variables.styl: -------------------------------------------------------------------------------- 1 | // Config 2 | support-for-ie = false 3 | vendor-prefixes = webkit moz ms official 4 | 5 | // Colors 6 | color-default = #555 7 | color-grey = #999 8 | color-border = #ddd 9 | color-link = #258fb8 10 | color-background = #eee 11 | color-sidebar-text = #777 12 | color-widget-background = #ddd 13 | color-widget-border = #ccc 14 | color-footer-background = #262a30 15 | color-mobile-nav-background = #191919 16 | color-twitter = #00aced 17 | color-facebook = #3b5998 18 | color-pinterest = #cb2027 19 | color-google = #dd4b39 20 | 21 | // Fonts 22 | font-sans = -apple-system, BlinkMacSystemFont, 23 | "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", 24 | "Fira Sans", "Droid Sans", "Helvetica Neue", 25 | sans-serif 26 | font-serif = Georgia, "Times New Roman", serif 27 | font-mono = "Source Code Pro", Consolas, Monaco, Menlo, Consolas, monospace 28 | font-icon = FontAwesome 29 | font-icon-path = "fonts/fontawesome-webfont" 30 | font-icon-version = "4.0.3" 31 | font-size = 14px 32 | line-height = 1.6em 33 | line-height-title = 1.1em 34 | 35 | // Header 36 | logo-size = 40px 37 | subtitle-size = 16px 38 | banner-height = 300px 39 | banner-url = "images/banner.jpg" 40 | 41 | sidebar = hexo-config("sidebar") 42 | 43 | // Layout 44 | block-margin = 50px 45 | article-padding = 20px 46 | mobile-nav-width = 280px 47 | main-column = 9 48 | sidebar-column = 3 49 | 50 | if sidebar and sidebar isnt bottom 51 | _sidebar-column = sidebar-column 52 | else 53 | _sidebar-column = 0 54 | 55 | // Grids 56 | column-width = 80px 57 | gutter-width = 20px 58 | columns = main-column + _sidebar-column 59 | 60 | // Media queries 61 | mq-mobile = "screen and (max-width: 479px)" 62 | mq-tablet = "screen and (min-width: 480px) and (max-width: 767px)" 63 | mq-normal = "screen and (min-width: 768px)" -------------------------------------------------------------------------------- /themes/landscape/source/css/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/css/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /themes/landscape/source/css/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/css/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /themes/landscape/source/css/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/css/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /themes/landscape/source/css/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/css/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /themes/landscape/source/css/images/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/css/images/banner.jpg -------------------------------------------------------------------------------- /themes/landscape/source/css/style.styl: -------------------------------------------------------------------------------- 1 | @import "nib" 2 | @import "_variables" 3 | @import "_util/mixin" 4 | @import "_util/grid" 5 | 6 | global-reset() 7 | 8 | input, button 9 | margin: 0 10 | padding: 0 11 | &::-moz-focus-inner 12 | border: 0 13 | padding: 0 14 | 15 | @font-face 16 | font-family: FontAwesome 17 | font-style: normal 18 | font-weight: normal 19 | src: url(font-icon-path + ".eot?v=#" + font-icon-version) 20 | src: url(font-icon-path + ".eot?#iefix&v=#" + font-icon-version) format("embedded-opentype"), 21 | url(font-icon-path + ".woff?v=#" + font-icon-version) format("woff"), 22 | url(font-icon-path + ".ttf?v=#" + font-icon-version) format("truetype"), 23 | url(font-icon-path + ".svg#fontawesomeregular?v=#" + font-icon-version) format("svg") 24 | 25 | html, body, #container 26 | height: 100% 27 | 28 | body 29 | background: color-background 30 | font: font-size font-sans 31 | -webkit-text-size-adjust: 100% 32 | 33 | .outer 34 | clearfix() 35 | max-width: (column-width + gutter-width) * columns + gutter-width 36 | margin: 0 auto 37 | padding: 0 gutter-width 38 | 39 | .inner 40 | column(columns) 41 | 42 | .left, .alignleft 43 | float: left 44 | 45 | .right, .alignright 46 | float: right 47 | 48 | .clear 49 | clear: both 50 | 51 | #container 52 | position: relative 53 | 54 | .mobile-nav-on 55 | overflow: hidden 56 | 57 | #wrap 58 | height: 100% 59 | width: 100% 60 | position: absolute 61 | top: 0 62 | left: 0 63 | transition: 0.2s ease-out 64 | z-index: 1 65 | background: color-background 66 | .mobile-nav-on & 67 | left: mobile-nav-width 68 | 69 | if sidebar and sidebar isnt bottom 70 | #main 71 | @media mq-normal 72 | column(main-column) 73 | 74 | if sidebar is left 75 | @media mq-normal 76 | #main 77 | float: right 78 | 79 | @import "_extend" 80 | @import "_partial/header" 81 | @import "_partial/article" 82 | @import "_partial/comment" 83 | @import "_partial/archive" 84 | @import "_partial/footer" 85 | @import "_partial/highlight" 86 | @import "_partial/mobile" 87 | 88 | if sidebar 89 | @import "_partial/sidebar" -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/blank.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/blank.gif -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/fancybox_loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/fancybox_loading.gif -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/fancybox_loading@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/fancybox_loading@2x.gif -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/fancybox_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/fancybox_overlay.png -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/fancybox_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/fancybox_sprite.png -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/fancybox_sprite@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/fancybox_sprite@2x.png -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/helpers/fancybox_buttons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wecteam/blog/c8f73cf6e3b5decd8f811144bcc6ffe3d7728b8d/themes/landscape/source/fancybox/helpers/fancybox_buttons.png -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.css: -------------------------------------------------------------------------------- 1 | #fancybox-buttons { 2 | position: fixed; 3 | left: 0; 4 | width: 100%; 5 | z-index: 8050; 6 | } 7 | 8 | #fancybox-buttons.top { 9 | top: 10px; 10 | } 11 | 12 | #fancybox-buttons.bottom { 13 | bottom: 10px; 14 | } 15 | 16 | #fancybox-buttons ul { 17 | display: block; 18 | width: 166px; 19 | height: 30px; 20 | margin: 0 auto; 21 | padding: 0; 22 | list-style: none; 23 | border: 1px solid #111; 24 | border-radius: 3px; 25 | -webkit-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 26 | -moz-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 27 | box-shadow: inset 0 0 0 1px rgba(255,255,255,.05); 28 | background: rgb(50,50,50); 29 | background: -moz-linear-gradient(top, rgb(68,68,68) 0%, rgb(52,52,52) 50%, rgb(41,41,41) 50%, rgb(51,51,51) 100%); 30 | background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(68,68,68)), color-stop(50%,rgb(52,52,52)), color-stop(50%,rgb(41,41,41)), color-stop(100%,rgb(51,51,51))); 31 | background: -webkit-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 32 | background: -o-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 33 | background: -ms-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 34 | background: linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%); 35 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 ); 36 | } 37 | 38 | #fancybox-buttons ul li { 39 | float: left; 40 | margin: 0; 41 | padding: 0; 42 | } 43 | 44 | #fancybox-buttons a { 45 | display: block; 46 | width: 30px; 47 | height: 30px; 48 | text-indent: -9999px; 49 | background-color: transparent; 50 | background-image: url('fancybox_buttons.png'); 51 | background-repeat: no-repeat; 52 | outline: none; 53 | opacity: 0.8; 54 | } 55 | 56 | #fancybox-buttons a:hover { 57 | opacity: 1; 58 | } 59 | 60 | #fancybox-buttons a.btnPrev { 61 | background-position: 5px 0; 62 | } 63 | 64 | #fancybox-buttons a.btnNext { 65 | background-position: -33px 0; 66 | border-right: 1px solid #3e3e3e; 67 | } 68 | 69 | #fancybox-buttons a.btnPlay { 70 | background-position: 0 -30px; 71 | } 72 | 73 | #fancybox-buttons a.btnPlayOn { 74 | background-position: -30px -30px; 75 | } 76 | 77 | #fancybox-buttons a.btnToggle { 78 | background-position: 3px -60px; 79 | border-left: 1px solid #111; 80 | border-right: 1px solid #3e3e3e; 81 | width: 35px 82 | } 83 | 84 | #fancybox-buttons a.btnToggleOn { 85 | background-position: -27px -60px; 86 | } 87 | 88 | #fancybox-buttons a.btnClose { 89 | border-left: 1px solid #111; 90 | width: 35px; 91 | background-position: -56px 0px; 92 | } 93 | 94 | #fancybox-buttons a.btnDisabled { 95 | opacity : 0.4; 96 | cursor: default; 97 | } -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/helpers/jquery.fancybox-buttons.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Buttons helper for fancyBox 3 | * version: 1.0.5 (Mon, 15 Oct 2012) 4 | * @requires fancyBox v2.0 or later 5 | * 6 | * Usage: 7 | * $(".fancybox").fancybox({ 8 | * helpers : { 9 | * buttons: { 10 | * position : 'top' 11 | * } 12 | * } 13 | * }); 14 | * 15 | */ 16 | ;(function ($) { 17 | //Shortcut for fancyBox object 18 | var F = $.fancybox; 19 | 20 | //Add helper object 21 | F.helpers.buttons = { 22 | defaults : { 23 | skipSingle : false, // disables if gallery contains single image 24 | position : 'top', // 'top' or 'bottom' 25 | tpl : '
    ' 26 | }, 27 | 28 | list : null, 29 | buttons: null, 30 | 31 | beforeLoad: function (opts, obj) { 32 | //Remove self if gallery do not have at least two items 33 | 34 | if (opts.skipSingle && obj.group.length < 2) { 35 | obj.helpers.buttons = false; 36 | obj.closeBtn = true; 37 | 38 | return; 39 | } 40 | 41 | //Increase top margin to give space for buttons 42 | obj.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30; 43 | }, 44 | 45 | onPlayStart: function () { 46 | if (this.buttons) { 47 | this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn'); 48 | } 49 | }, 50 | 51 | onPlayEnd: function () { 52 | if (this.buttons) { 53 | this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn'); 54 | } 55 | }, 56 | 57 | afterShow: function (opts, obj) { 58 | var buttons = this.buttons; 59 | 60 | if (!buttons) { 61 | this.list = $(opts.tpl).addClass(opts.position).appendTo('body'); 62 | 63 | buttons = { 64 | prev : this.list.find('.btnPrev').click( F.prev ), 65 | next : this.list.find('.btnNext').click( F.next ), 66 | play : this.list.find('.btnPlay').click( F.play ), 67 | toggle : this.list.find('.btnToggle').click( F.toggle ), 68 | close : this.list.find('.btnClose').click( F.close ) 69 | } 70 | } 71 | 72 | //Prev 73 | if (obj.index > 0 || obj.loop) { 74 | buttons.prev.removeClass('btnDisabled'); 75 | } else { 76 | buttons.prev.addClass('btnDisabled'); 77 | } 78 | 79 | //Next / Play 80 | if (obj.loop || obj.index < obj.group.length - 1) { 81 | buttons.next.removeClass('btnDisabled'); 82 | buttons.play.removeClass('btnDisabled'); 83 | 84 | } else { 85 | buttons.next.addClass('btnDisabled'); 86 | buttons.play.addClass('btnDisabled'); 87 | } 88 | 89 | this.buttons = buttons; 90 | 91 | this.onUpdate(opts, obj); 92 | }, 93 | 94 | onUpdate: function (opts, obj) { 95 | var toggle; 96 | 97 | if (!this.buttons) { 98 | return; 99 | } 100 | 101 | toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn'); 102 | 103 | //Size toggle button 104 | if (obj.canShrink) { 105 | toggle.addClass('btnToggleOn'); 106 | 107 | } else if (!obj.canExpand) { 108 | toggle.addClass('btnDisabled'); 109 | } 110 | }, 111 | 112 | beforeClose: function () { 113 | if (this.list) { 114 | this.list.remove(); 115 | } 116 | 117 | this.list = null; 118 | this.buttons = null; 119 | } 120 | }; 121 | 122 | }(jQuery)); 123 | -------------------------------------------------------------------------------- /themes/landscape/source/fancybox/helpers/jquery.fancybox-thumbs.css: -------------------------------------------------------------------------------- 1 | #fancybox-thumbs { 2 | position: fixed; 3 | left: 0; 4 | width: 100%; 5 | overflow: hidden; 6 | z-index: 8050; 7 | } 8 | 9 | #fancybox-thumbs.bottom { 10 | bottom: 2px; 11 | } 12 | 13 | #fancybox-thumbs.top { 14 | top: 2px; 15 | } 16 | 17 | #fancybox-thumbs ul { 18 | position: relative; 19 | list-style: none; 20 | margin: 0; 21 | padding: 0; 22 | } 23 | 24 | #fancybox-thumbs ul li { 25 | float: left; 26 | padding: 1px; 27 | opacity: 0.5; 28 | } 29 | 30 | #fancybox-thumbs ul li.active { 31 | opacity: 0.75; 32 | padding: 0; 33 | border: 1px solid #fff; 34 | } 35 | 36 | #fancybox-thumbs ul li:hover { 37 | opacity: 1; 38 | } 39 | 40 | #fancybox-thumbs ul li a { 41 | display: block; 42 | position: relative; 43 | overflow: hidden; 44 | border: 1px solid #222; 45 | background: #111; 46 | outline: none; 47 | } 48 | 49 | #fancybox-thumbs ul li img { 50 | display: block; 51 | position: relative; 52 | border: 0; 53 | padding: 0; 54 | max-width: none; 55 | } -------------------------------------------------------------------------------- /themes/landscape/source/js/script.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | // Search 3 | var $searchWrap = $('#search-form-wrap'), 4 | isSearchAnim = false, 5 | searchAnimDuration = 200; 6 | 7 | var startSearchAnim = function(){ 8 | isSearchAnim = true; 9 | }; 10 | 11 | var stopSearchAnim = function(callback){ 12 | setTimeout(function(){ 13 | isSearchAnim = false; 14 | callback && callback(); 15 | }, searchAnimDuration); 16 | }; 17 | 18 | $('#nav-search-btn').on('click', function(){ 19 | if (isSearchAnim) return; 20 | 21 | startSearchAnim(); 22 | $searchWrap.addClass('on'); 23 | stopSearchAnim(function(){ 24 | $('.search-form-input').focus(); 25 | }); 26 | }); 27 | 28 | $('.search-form-input').on('blur', function(){ 29 | startSearchAnim(); 30 | $searchWrap.removeClass('on'); 31 | stopSearchAnim(); 32 | }); 33 | 34 | // Share 35 | $('body').on('click', function(){ 36 | $('.article-share-box.on').removeClass('on'); 37 | }).on('click', '.article-share-link', function(e){ 38 | e.stopPropagation(); 39 | 40 | var $this = $(this), 41 | url = $this.attr('data-url'), 42 | encodedUrl = encodeURIComponent(url), 43 | id = 'article-share-box-' + $this.attr('data-id'), 44 | offset = $this.offset(); 45 | 46 | if ($('#' + id).length){ 47 | var box = $('#' + id); 48 | 49 | if (box.hasClass('on')){ 50 | box.removeClass('on'); 51 | return; 52 | } 53 | } else { 54 | var html = [ 55 | '
    ', 56 | '', 57 | '
    ', 58 | '', 59 | '', 60 | '', 61 | '', 62 | '
    ', 63 | '
    ' 64 | ].join(''); 65 | 66 | var box = $(html); 67 | 68 | $('body').append(box); 69 | } 70 | 71 | $('.article-share-box.on').hide(); 72 | 73 | box.css({ 74 | top: offset.top + 25, 75 | left: offset.left 76 | }).addClass('on'); 77 | }).on('click', '.article-share-box', function(e){ 78 | e.stopPropagation(); 79 | }).on('click', '.article-share-box-input', function(){ 80 | $(this).select(); 81 | }).on('click', '.article-share-box-link', function(e){ 82 | e.preventDefault(); 83 | e.stopPropagation(); 84 | 85 | window.open(this.href, 'article-share-box-window-' + Date.now(), 'width=500,height=450'); 86 | }); 87 | 88 | // Caption 89 | $('.article-entry').each(function(i){ 90 | $(this).find('img').each(function(){ 91 | if ($(this).parent().hasClass('fancybox')) return; 92 | 93 | var alt = this.alt; 94 | 95 | if (alt) $(this).after('' + alt + ''); 96 | 97 | $(this).wrap(''); 98 | }); 99 | 100 | $(this).find('.fancybox').each(function(){ 101 | $(this).attr('rel', 'article' + i); 102 | }); 103 | }); 104 | 105 | if ($.fancybox){ 106 | $('.fancybox').fancybox(); 107 | } 108 | 109 | // Mobile nav 110 | var $container = $('#container'), 111 | isMobileNavAnim = false, 112 | mobileNavAnimDuration = 200; 113 | 114 | var startMobileNavAnim = function(){ 115 | isMobileNavAnim = true; 116 | }; 117 | 118 | var stopMobileNavAnim = function(){ 119 | setTimeout(function(){ 120 | isMobileNavAnim = false; 121 | }, mobileNavAnimDuration); 122 | } 123 | 124 | $('#main-nav-toggle').on('click', function(){ 125 | if (isMobileNavAnim) return; 126 | 127 | startMobileNavAnim(); 128 | $container.toggleClass('mobile-nav-on'); 129 | stopMobileNavAnim(); 130 | }); 131 | 132 | $('#wrap').on('click', function(){ 133 | if (isMobileNavAnim || !$container.hasClass('mobile-nav-on')) return; 134 | 135 | $container.removeClass('mobile-nav-on'); 136 | }); 137 | })(jQuery); --------------------------------------------------------------------------------