This commit is contained in:
2019-05-30 18:52:14 +08:00
commit aa360a22bf
341 changed files with 30369 additions and 0 deletions

View File

@ -0,0 +1,45 @@
/* global hexo */
'use strict';
hexo.extend.filter.register('after_post_render', function(data) {
var theme = hexo.theme.config;
// Exit if `exturl` option disable in NexT.
if (!theme.exturl) return;
var url = require('url');
var cheerio;
var config = this.config;
if (!cheerio) cheerio = require('cheerio');
var $ = cheerio.load(data.content, {decodeEntities: false});
var siteHost = url.parse(config.url).hostname || config.url;
$('a').each(function() {
var href = $(this).attr('href');
// Exit if the href attribute doesn't exists.
if (!href) return;
var data = url.parse(href);
// Exit if the link doesn't have protocol, which means it's an internal link.
if (!data.protocol) return;
// Exit if the url has same host with `config.url`.
if (data.hostname === siteHost) return;
// If title atribute filled, set it as title; if not, set url as title.
var title = $(this).attr('title') || href;
var encoded = Buffer.from(href).toString('base64');
$(this).replaceWith(function() {
return $(`<span class="exturl" data-url="${encoded}" title="${title}">${$(this).html()}<i class="fa fa-external-link"></i></span>`);
});
});
data.content = $.html();
}, 0);

View File

@ -0,0 +1,26 @@
/* global hexo */
'use strict';
hexo.extend.helper.register('hexo_env', function(type) {
return this.env[type];
});
hexo.extend.helper.register('next_env', function(type) {
var path = require('path');
var env = require(path.normalize('../../package.json'));
return env[type];
});
hexo.extend.helper.register('item_active', function(path, className) {
var canonical = this.page.canonical_path;
var current = this.url_for(canonical).replace('index.html', '', 'g');
var result = '';
if (current.indexOf(path) !== -1) {
if (path !== '/' || path === current) {
result = ' ' + className;
}
}
return result;
});

View File

@ -0,0 +1,70 @@
/**
* next-url.js | https://theme-next.org/api/helpers/next-url/
*/
/* global hexo */
'use strict';
hexo.extend.helper.register('next_url', function(path, text, options) {
var htmlTag = require('hexo-util').htmlTag;
var config = this.config;
var url = require('url');
var data = url.parse(path);
var siteHost = url.parse(config.url).hostname || config.url;
var theme = hexo.theme.config;
var exturl = '';
var tag = 'a';
var attrs = { href: this.url_for(path) };
// If `exturl` enabled, set spanned links only on external links.
if (theme.exturl && data.protocol && data.hostname !== siteHost) {
tag = 'span';
exturl = 'exturl';
var encoded = Buffer.from(path).toString('base64');
attrs = {
class : exturl,
'data-url': encoded
};
}
options = options || {};
var keys = Object.keys(options);
var key = '';
for (var i = 0, len = keys.length; i < len; i++) {
key = keys[i];
/**
* If option have `class` attribute, add it to
* 'exturl' class if `exturl` option enabled.
*/
if (exturl !== '' && key === 'class') {
attrs[key] += ' ' + options[key];
} else {
attrs[key] = options[key];
}
}
if (attrs.class && Array.isArray(attrs.class)) {
attrs.class = attrs.class.join(' ');
}
// If it's external link, rewrite attributes.
if (data.protocol && data.hostname !== siteHost) {
attrs.external = null;
if (!theme.exturl) {
// Only for simple link need to rewrite/add attributes.
attrs.rel = 'noopener';
attrs.target = '_blank';
} else {
// Remove rel attributes for `exturl` in main menu.
attrs.rel = null;
}
}
return htmlTag(tag, attrs, text);
});

View File

@ -0,0 +1,45 @@
/* global hexo */
'use strict';
var merge = require('./merge');
hexo.on('generateBefore', function() {
if (hexo.locals.get) {
var data = hexo.locals.get('data');
/**
* Merge configs from _data/next.yml into hexo.theme.config.
* If `override`, configs in next.yml will rewrite configs in hexo.theme.config.
* If next.yml not exists, merge all `theme_config.*` into hexo.theme.config.
*/
if (data && data.next) {
if (data.next.override) {
hexo.theme.config = data.next;
} else {
merge(hexo.config, data.next);
merge(hexo.theme.config, data.next);
}
} else {
merge(hexo.theme.config, hexo.config.theme_config);
}
// Custom languages support. Introduced in NexT v6.3.0.
if (data && data.languages) {
var lang = this.config.language;
var i18n = this.theme.i18n;
var mergeLang = function(lang) {
i18n.set(lang, merge(i18n.get([lang]), data.languages[lang]));
};
if (Array.isArray(lang)) {
for (var i = 0; i < lang.length; i++) {
mergeLang(lang[i]);
}
} else {
mergeLang(lang);
}
}
}
});

2225
themes/next/scripts/merge.js vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/**
* button.js | https://theme-next.org/docs/tag-plugins/button
*/
/* global hexo */
'use strict';
function postButton(args) {
args = args.join(' ').split(',');
var url = args[0];
var text = args[1] || '';
var icon = args[2] || '';
var title = args[3] || '';
if (!url) {
hexo.log.warn('URL can NOT be empty');
}
text = text.trim();
icon = icon.trim();
title = title.trim();
var result = [`<a class="btn" href="${url}"`];
title.length > 0 && result.push(` title="${title}"`);
result.push('>');
icon.length > 0 && result.push(`<i class="fa fa-${icon}"></i>`);
text.length > 0 && result.push(text);
result.push('</a>');
return result.join('');
}
hexo.extend.tag.register('button', postButton, {ends: false});
hexo.extend.tag.register('btn', postButton, {ends: false});

View File

@ -0,0 +1,16 @@
/**
* center-quote.js | https://theme-next.org/docs/tag-plugins/
*/
/* global hexo */
'use strict';
function centerQuote(args, content) {
return '<blockquote class="blockquote-center">'
+ hexo.render.renderSync({text: content, engine: 'markdown'})
+ '</blockquote>';
}
hexo.extend.tag.register('centerquote', centerQuote, {ends: true});
hexo.extend.tag.register('cq', centerQuote, {ends: true});

View File

@ -0,0 +1,62 @@
/**
* exturl.js | https://theme-next.org/docs/tag-plugins/exturl
* Note: need to remove in NexT v7.0.0
*/
/* global hexo */
'use strict';
var util = require('hexo-util');
var htmlTag = util.htmlTag;
/* eslint-disable */
var rUrl = /((([A-Za-z]{3,9}:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\w]*))?)/;
// Create Base64 Object
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9+/=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/rn/g,"n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
/* eslint-enable */
function extURL(args) {
var exturl = 'exturl';
var url = '';
var text = [];
var title = '';
var item = '';
var i = 0;
var len = args.length;
// Find link URL and text
for (; i < len; i++) {
item = args[i];
if (rUrl.test(item)) {
url = Base64.encode(item);
break;
} else {
text.push(item);
}
}
// Delete link URL and text from arguments
args = args.slice(i + 1);
// If any arguments exists, collect the last text as the link title,
// if not, set title as url.
if (args.length) {
title = args.join(' ');
} else {
title = item;
}
var attrs = {
class : exturl,
'data-url': url,
title : title
};
hexo.log.warn('WARNING: `exturl` and `extlink` tag will not longer be supported. More info here: https://theme-next.org/docs/theme-settings/seo#ExtURL');
return htmlTag('span', attrs, text.join(' ') + '<i class="fa fa-external-link"></i>');
}
hexo.extend.tag.register('exturl', extURL, {ends: false});
hexo.extend.tag.register('extlink', extURL, {ends: false});

View File

@ -0,0 +1,32 @@
/**
* full-image.js | https://theme-next.org/docs/tag-plugins/full-image
*/
/* global hexo */
'use strict';
function fullImage(args) {
args = args.join(' ').split(',');
var mixed = args[0].split('@');
var img = mixed[0];
var src = mixed[1] === 'lazy' ? '/images/loading.gif" data-original="' + img : img;
var alt = args[1] || '';
var title = args[2] || '';
var width = args[3] || '';
if (!img) {
hexo.log.warn('Image src can NOT be empty');
}
var image = [`<span itemprop="image" itemscope itemtype="http://schema.org/ImageObject"><img itemprop="url image" src="${src}" class="full-image"`];
alt.length > 0 && image.push(`alt="${alt.trim()}"`);
title.length > 0 && image.push(`title="${title.trim()}"`);
width.length > 0 && image.push(`style="max-width: none; width:${width};"`);
image.push('/><meta itemprop="width" content="auto"/><meta itemprop="height" content="auto"/></span>');
return image.join(' ');
}
hexo.extend.tag.register('fullimage', fullImage, {ends: false});
hexo.extend.tag.register('fi', fullImage, {ends: false});

View File

@ -0,0 +1,150 @@
/**
* group-pictures.js | https://theme-next.org/docs/tag-plugins/group-pictures
*/
/* global hexo */
'use strict';
var LAYOUTS = {
2: {
1: [1, 1],
2: [2]
},
3: {
1: [3],
2: [1, 2],
3: [2, 1]
},
4: {
1: [1, 2, 1],
2: [1, 3],
3: [2, 2],
4: [3, 1]
},
5: {
1: [1, 2, 2],
2: [2, 1, 2],
3: [2, 3],
4: [3, 2]
},
6: {
1: [1, 2, 3],
2: [1, 3, 2],
3: [2, 1, 3],
4: [2, 2, 2],
5: [3, 3]
},
7: {
1: [1, 2, 2, 2],
2: [1, 3, 3],
3: [2, 2, 3],
4: [2, 3, 2],
5: [3, 2, 2]
},
8: {
1: [1, 2, 2, 3],
2: [1, 2, 3, 2],
3: [1, 3, 2, 2],
4: [2, 2, 2, 2],
5: [2, 3, 3],
6: [3, 2, 3],
7: [3, 3, 2]
},
9: {
1: [1, 2, 3, 3],
2: [1, 3, 2, 3],
3: [2, 2, 2, 3],
4: [2, 2, 3, 2],
5: [2, 3, 2, 2],
6: [3, 2, 2, 2],
7: [3, 3, 3]
},
10: {
1: [1, 3, 3, 3],
2: [2, 2, 3, 3],
3: [2, 3, 2, 3],
4: [2, 3, 3, 2],
5: [3, 2, 2, 3],
6: [3, 2, 3, 2],
7: [3, 3, 2, 2]
}
};
function groupBy(group, data) {
var r = [];
for (var i = 0; i < group.length; i++) {
r.push(data.slice(0, group[i]));
data = data.slice(group[i]);
}
return r;
}
var templates = {
dispatch: function(pictures, group, layout) {
var rule = LAYOUTS[group] ? LAYOUTS[group][layout] : null;
return rule ? this.getHTML(groupBy(rule, pictures)) : templates.defaults(pictures);
},
/**
* Defaults Layout
*
* □ □ □
* □ □ □
* ...
*
* @param pictures
*/
defaults: function(pictures) {
var ROW_SIZE = 3;
var rows = pictures.length / (ROW_SIZE + 1);
var pictureArr = [];
for (var i = 0; i < rows; i++) {
pictureArr.push(pictures.slice(i * ROW_SIZE, (i + 1) * ROW_SIZE));
}
return this.getHTML(pictureArr);
},
getHTML: function(rows) {
var rowHTML = '';
for (var i = 0; i < rows.length; i++) {
rowHTML += this.getRowHTML(rows[i]);
}
return `<div class="group-picture-container">${rowHTML}</div>`;
},
getRowHTML: function(pictures) {
return `<div class="group-picture-row">${this.getColumnHTML(pictures)}</div>`;
},
getColumnHTML: function(pictures) {
var columns = [];
var columnWidth = 100 / pictures.length;
var columnStyle = `style="width: ${columnWidth}%;"`;
for (var i = 0; i < pictures.length; i++) {
columns.push(`<div class="group-picture-column" ${columnStyle}>${pictures[i]}</div>`);
}
return columns.join('');
}
};
function groupPicture(args, content) {
args = args[0].split('-');
var group = parseInt(args[0], 10);
var layout = parseInt(args[1], 10);
content = hexo.render.renderSync({text: content, engine: 'markdown'});
var pictures = content.match(/<img[\s\S]*?>/g);
return `<div class="group-picture">${templates.dispatch(pictures, group, layout)}</div>`;
}
hexo.extend.tag.register('grouppicture', groupPicture, {ends: true});
hexo.extend.tag.register('gp', groupPicture, {ends: true});

View File

@ -0,0 +1,30 @@
/**
* include-raw.js | https://theme-next.org/docs/tag-plugins/
*/
/* global hexo */
'use strict';
var pathFn = require('path');
var fs = require('hexo-fs');
function includeRaw(args) {
var path = pathFn.join(hexo.source_dir, args[0]);
return fs.exists(path).then(function(exist) {
if (!exist) {
hexo.log.error('Include file not found!');
return;
}
return fs.readFile(path).then(function(contents) {
if (!contents) {
hexo.log.warn('Include file empty.');
return;
}
return contents;
});
});
}
hexo.extend.tag.register('include_raw', includeRaw, {ends: false, async: true});

View File

@ -0,0 +1,19 @@
/**
* label.js | https://theme-next.org/docs/tag-plugins/label
*/
/* global hexo */
'use strict';
function postLabel(args) {
args = args.join(' ').split('@');
var classes = args[0] || 'default';
var text = args[1] || '';
!text && hexo.log.warn('Label text must be defined!');
return `<span class="label ${classes.trim()}">${text}</span>`;
}
hexo.extend.tag.register('label', postLabel, {ends: false});

View File

@ -0,0 +1,16 @@
/**
* mermaid.js | https://theme-next.org/docs/tag-plugins/mermaid
*/
/* global hexo */
'use strict';
function mermaid(args, content) {
return `<pre class="mermaid" style="text-align: center;">
${args.join(' ')}
${content}
</pre>`;
}
hexo.extend.tag.register('mermaid', mermaid, {ends: true});

View File

@ -0,0 +1,16 @@
/**
* note.js | https://theme-next.org/docs/tag-plugins/note
*/
/* global hexo */
'use strict';
function postNote(args, content) {
return `<div class="note ${args.join(' ')}">
${hexo.render.renderSync({text: content, engine: 'markdown'}).split('\n').join('')}
</div>`;
}
hexo.extend.tag.register('note', postNote, {ends: true});
hexo.extend.tag.register('subnote', postNote, {ends: true});

View File

@ -0,0 +1,13 @@
/**
* pdf.js | https://theme-next.org/docs/tag-plugins/pdf
*/
/* global hexo */
'use strict';
function pdf(args) {
return `<div class="pdf" target="${args[0]}" height="${args[1] || ''}"></div>`;
}
hexo.extend.tag.register('pdf', pdf, {ends: false});

View File

@ -0,0 +1,59 @@
/**
* tabs.js | https://theme-next.org/docs/tag-plugins/tabs
*/
/* global hexo */
'use strict';
function postTabs(args, content) {
var tabBlock = /<!--\s*tab (.*?)\s*-->\n([\w\W\s\S]*?)<!--\s*endtab\s*-->/g;
args = args.join(' ').split(',');
var tabName = args[0];
var tabActive = Number(args[1]) || 0;
var matches = [];
var match;
var tabId = 0;
var tabNav = '';
var tabContent = '';
!tabName && hexo.log.warn('Tabs block must have unique name!');
while ((match = tabBlock.exec(content)) !== null) {
matches.push(match[1]);
matches.push(match[2]);
}
for (var i = 0; i < matches.length; i += 2) {
var tabParameters = matches[i].split('@');
var postContent = matches[i + 1];
var tabCaption = tabParameters[0] || '';
var tabIcon = tabParameters[1] || '';
var tabHref = '';
postContent = hexo.render.renderSync({text: postContent, engine: 'markdown'}).trim();
tabId += 1;
tabHref = (tabName + ' ' + tabId).toLowerCase().split(' ').join('-');
((tabCaption.length === 0) && (tabIcon.length === 0)) && (tabCaption = tabName + ' ' + tabId);
var isOnlyicon = tabIcon.length > 0 && tabCaption.length === 0 ? ' style="text-align: center;"' : '';
tabIcon.length > 0 && (tabIcon = `<i class="fa fa-${tabIcon.trim()}"${isOnlyicon}></i>`);
var isActive = (tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1) ? ' active' : '';
tabNav += `<li class="tab${isActive}"><a href="#${tabHref}">${tabIcon + tabCaption.trim()}</a></li>`;
tabContent += `<div class="tab-pane${isActive}" id="${tabHref}">${postContent}</div>`;
}
tabNav = `<ul class="nav-tabs">${tabNav}</ul>`;
tabContent = `<div class="tab-content">${tabContent}</div>`;
return `<div class="tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent}</div>`;
}
hexo.extend.tag.register('tabs', postTabs, {ends: true});
hexo.extend.tag.register('subtabs', postTabs, {ends: true});
hexo.extend.tag.register('subsubtabs', postTabs, {ends: true});

View File

@ -0,0 +1,13 @@
/**
* video.js | https://theme-next.org/docs/tag-plugins/video
*/
/* global hexo */
'use strict';
function postVideo(args) {
return `<video src="${args}" preload="metadata" controls playsinline poster="">Sorry, your browser does not support the video tag.</video>`;
}
hexo.extend.tag.register('video', postVideo, {ends: false});