diff --git a/_config.yml b/_config.yml index f10ec2a..f0cfff6 100644 --- a/_config.yml +++ b/_config.yml @@ -868,16 +868,20 @@ canvas_ribbon: vendors: # The CDN provider of NexT internal scripts. - # Available values: local | jsdelivr | unpkg | cdnjs + # Available values: local | jsdelivr | unpkg | cdnjs | custom # Warning: If you are using the latest master branch of NexT, please set `internal: local` internal: local # The default CDN provider of third-party plugins. - # Available values: local | jsdelivr | unpkg | cdnjs + # Available values: local | jsdelivr | unpkg | cdnjs | custom # Dependencies for `plugins: local`: https://github.com/next-theme/plugins plugins: jsdelivr + # Custom CDN URL + # For example: + # custom_cdn_url: https://cdn.jsdelivr.net/npm/${npm_name}@${version}/${minified} + # custom_cdn_url: https://cdnjs.cloudflare.com/ajax/libs/${cdnjs_name}/${version}/${cdnjs_file} + custom_cdn_url: # Assets # Accelerate delivery of static files using a CDN css: css -js: js images: images diff --git a/scripts/events/lib/utils.js b/scripts/events/lib/utils.js index 65aa50f..cc24eaa 100644 --- a/scripts/events/lib/utils.js +++ b/scripts/events/lib/utils.js @@ -13,10 +13,6 @@ function resolve(name, file = '') { return `${dir}/${file}`; } -function parse(line, attr) { - return line.split(attr)[1].replace(';', '').trim(); -} - function highlightTheme(name) { const file = resolve('highlight.js', `styles/${name}.css`); const css = fs.readFileSync(file).toString(); @@ -27,6 +23,7 @@ function highlightTheme(name) { rule += content; return match; }); + const parse = (line, attr) => line.split(attr)[1].replace(';', '').trim(); rule.split('\n').forEach(line => { if (line.includes('background:')) background = parse(line, 'background:'); else if (line.includes('background-color:')) background = parse(line, 'background-color:'); @@ -39,6 +36,29 @@ function highlightTheme(name) { }; } +function getVendors({ name, alias, version, file, minified, local, custom }) { + // Make it possible to set `cdnjs_name` and `cdnjs_file` in `custom_cdn_url` + const npm_name = name; + const cdnjs_name = alias || name; + const npm_file = file; + const cdnjs_file = minified.replace(/^(dist|lib|source\/js|)\/(browser\/|)/, ''); + const value = { + npm_name, + cdnjs_name, + version, + npm_file, + minified, + cdnjs_file + }; + return { + local, + jsdelivr: `https://cdn.jsdelivr.net/npm/${npm_name}@${version}/${minified}`, + unpkg : `https://unpkg.com/${npm_name}@${version}/${npm_file}`, + cdnjs : `https://cdnjs.cloudflare.com/ajax/libs/${cdnjs_name}/${version}/${cdnjs_file}`, + custom : (custom || '').replace(/\$\{(.+?)\}/g, (match, $1) => value[$1]) + }; +} + const points = { views: [ 'head', @@ -61,5 +81,6 @@ const points = { module.exports = { resolve, highlightTheme, + getVendors, points }; diff --git a/scripts/events/lib/vendors.js b/scripts/events/lib/vendors.js index b8a63b2..8f5e591 100644 --- a/scripts/events/lib/vendors.js +++ b/scripts/events/lib/vendors.js @@ -4,6 +4,7 @@ const fs = require('fs'); const path = require('path'); const yaml = require('js-yaml'); const { url_for } = require('hexo-util'); +const { getVendors } = require('./utils'); let internal; try { @@ -33,13 +34,13 @@ module.exports = hexo => { if (key === 'pace_css') { value.file = `${value.dir}/${pace.color}/pace-theme-${pace.theme}.css`; } - const { name, version, file, alias, unavailable } = value; - const links = { + const { name, file, unavailable } = value; + const links = getVendors({ + ...value, + minified: file, local : url_for.call(hexo, `lib/${name}/${file}`), - jsdelivr: `https://cdn.jsdelivr.net/npm/${name}@${version}/${file}`, - unpkg : `https://unpkg.com/${name}@${version}/${file}`, - cdnjs : `https://cdnjs.cloudflare.com/ajax/libs/${alias || name}/${version}/${file.replace(/^(dist|lib|)\/(browser\/|)/, '')}` - }; + custom : vendors.custom_cdn_url + }); let { plugins = 'jsdelivr' } = vendors; if (plugins === 'cdnjs' && unavailable && unavailable.includes('cdnjs')) plugins = 'jsdelivr'; if (plugins === 'local' && typeof internal === 'undefined') plugins = 'jsdelivr'; diff --git a/scripts/helpers/engine.js b/scripts/helpers/engine.js index 9ff8d3f..beaf178 100644 --- a/scripts/helpers/engine.js +++ b/scripts/helpers/engine.js @@ -3,8 +3,10 @@ 'use strict'; const crypto = require('crypto'); +const { parse } = require('url'); const nextFont = require('./font'); const nextUrl = require('./next-url'); +const { getVendors } = require('../events/lib/utils'); hexo.extend.helper.register('next_font', nextFont); hexo.extend.helper.register('next_url', nextUrl); @@ -17,14 +19,15 @@ hexo.extend.helper.register('next_inject', function(point) { hexo.extend.helper.register('next_js', function(file, pjax = false) { const { next_version } = this; - const { internal } = this.theme.vendors; - const minified_file = file.endsWith('.js') && !file.endsWith('.min.js') ? file.slice(0, -3) + '.min.js' : file; - const links = { - local : this.url_for(`${this.theme.js}/${file}`), - jsdelivr: `https://cdn.jsdelivr.net/npm/hexo-theme-next@${next_version}/source/js/${minified_file}`, - unpkg : `https://unpkg.com/hexo-theme-next@${next_version}/source/js/${file}`, - cdnjs : `https://cdnjs.cloudflare.com/ajax/libs/hexo-theme-next/${next_version}/${minified_file}` - }; + const { internal, custom_cdn_url } = this.theme.vendors; + const links = getVendors({ + name : 'hexo-theme-next', + version : next_version, + file : 'source/js/' + file, + minified: 'source/js/' + file.replace(/\.js$/, '.min.js'), + local : this.url_for(`js/${file}`), + custom : custom_cdn_url + }); const src = links[internal] || links.local; return ``; }); @@ -48,23 +51,22 @@ hexo.extend.helper.register('next_data', function(name, ...data) { }); hexo.extend.helper.register('next_pre', function() { - const { preconnect } = this.theme; - if (!preconnect) return ''; + if (!this.theme.preconnect) return ''; const { enable, host } = this.theme.font; - const { internal, plugins } = this.theme.vendors; + const { internal, plugins, custom_cdn_url } = this.theme.vendors; const links = { local : '', jsdelivr: 'https://cdn.jsdelivr.net', unpkg : 'https://unpkg.com', - cdnjs : 'https://cdnjs.cloudflare.com' + cdnjs : 'https://cdnjs.cloudflare.com', + custom : parse(custom_cdn_url || '').hostname }; const h = enable ? host || 'https://fonts.googleapis.com' : ''; const i = links[internal]; const p = links[plugins]; - const results = [...new Set([h, i, p].filter(origin => origin))].map( + return [...new Set([h, i, p].filter(origin => origin))].map( origin => `` - ); - return results.join('\n'); + ).join('\n'); }); hexo.extend.helper.register('post_gallery', function(photos) {