UNPKG

hexo-theme-volantis

Version:

Elegant and powerful theme for Hexo.

207 lines (199 loc) 7.4 kB
/* Getting the version of the theme. */ const { version } = require('../../../package.json'); const theme_version = version; const path = require('path') const site_root = hexo.config.root; // _cdn.yml /* It's reading the `_cdn.yml` file in the theme directory. */ const cdn_info = hexo.render.renderSync({ path: path.join(hexo.theme_dir, '/_cdn.yml'), engine: 'yaml' }) /** * If the item is an object and not an array, then it's an object. * @param item - The item to test. */ function isObject(item) { return item && typeof item === 'object' && !Array.isArray(item); } /** * It takes two objects and merges the second object into the first object * @param target - The object that will be modified. * @param source - The object to merge into the target. * @returns The merged object. */ function merge(target, source) { for (const key in source) { if (isObject(target[key]) && isObject(source[key])) { merge(target[key], source[key]); } else { target[key] = source[key]; } } return target; } // volantis_cdn_system_prefix // 在本配置文件中 匹配以 "volantis-local/npm/static/cdnjs" 开头的链接路径替换为该格式的前缀开头 prefix /** * It will replace the prefix of the source with the prefix you set in the configuration file * @param source - the source object to be processed * @param hexo - The hexo object. */ function volantis_cdn_system_prefix(source, hexo) { const prefix_list = ["local", "npm", "static", "cdnjs"]; for (const key in source) { if (isObject(source[key])) { volantis_cdn_system_prefix(source[key], hexo); } else if (source[key] && typeof source[key] == "string") { for (const prefix of prefix_list) { if (source[key].match(new RegExp(`^volantis-${prefix}\/`, "g"))) { const my_prefix = hexo.theme.config.cdn_system.system_config[prefix].prefix.replace(/\$\{site_root\}/g, site_root) source[key] = my_prefix + source[key].replace(new RegExp(`^volantis-${prefix}`, "g"), "") break; } } } else if (source[key] && Array.isArray(source[key]) && source[key].length > 0) { source[key].forEach((item, index) => { if (item && typeof item == "string") { for (const prefix of prefix_list) { if (item.match(new RegExp(`^volantis-${prefix}\/`, "g"))) { const my_prefix = hexo.theme.config.cdn_system.system_config[prefix].prefix.replace(/\$\{site_root\}/g, site_root) source[key][index] = my_prefix + item.replace(new RegExp(`^volantis-${prefix}`, "g"), "") break; } } } else if (isObject(item)) { volantis_cdn_system_prefix(item, hexo); } }) } } } /** * It takes a file name and returns the same file name with the extension replaced with `.min` if the * file name doesn't already end with `.min` * @param file - The file name to be minified. * @returns The file name with the extension replaced with .min.ext */ const minFile = (file) => { return file.replace(/(?<!\.min)\.(js|css)$/g, ext => '.min' + ext) } // 匹配 CDN 资源 /** * `match_cdn_source` is a function that takes a key as an argument and returns the CDN source of the * corresponding key. * * The function first checks if the key is valid and if the corresponding CDN source exists. If so, it * will then check the priority of the CDN source. If the priority is `custom`, it will check if the * custom CDN source exists. If the priority is not `custom`, it will check if the corresponding CDN * source is enabled. If so, it will then return the CDN source. * * The `format` variable is the format of the CDN source. The `value` variable is the value of the CDN * source. The `value` variable is a JavaScript object that contains the following properties: * * - `version`: the version of the CDN source * - `name`: the name of the CDN source * - * @param key - The name of the library in the _cdn.yml file. * @returns The return value is a string. */ function match_cdn_source(key) { if (key && cdn_info[key]) { // _cdn.yml item const info = cdn_info[key]; const system_config = hexo.theme.config.cdn_system.system_config; for (const iterator of hexo.theme.config.cdn_system.priority) { // priority item if (iterator === "custom") { if (system_config.custom) { const r = system_config.custom[key]; if (r) { return r; } } } else { if (info[iterator] === true) { const prefix = system_config[iterator].prefix?.replace(/\$\{site_root\}/g, site_root); const format = system_config[iterator].format; let name = info.name; let file = info.file; if (iterator === "cdnjs") { if (info.cdnjs_name) { name = info.cdnjs_name; } if (info.cdnjs_file) { file = info.cdnjs_file; } else { file = file.replace(/^[lib|dist]*\/|browser\//g, ''); } } if (info.local === true) { file = file.replace(/^source\//g, '') } let min_file = minFile(file) if (iterator === "cdnjs") { if (info.cdnjs_no_min_file) { min_file = file; } } let version = info.version; if (info.local === true) { version = theme_version } const timestamp = hexo.theme.config.getStartTime; const value = { version, name, file, min_file, prefix, timestamp, } let res = format; let p = 0; while (/\$\{(.+?)\}/g.test(res)) { res = res?.replace(/\$\{(.+?)\}/g, (match, $1) => value[$1] ? value[$1] : eval($1)) || null // 防止死循环。。。 p++; if (p > 20) { break; } } return res } } } } return null; } // 收集 CDN 资源 /** * `hexo.theme.config.cdn` is an object that contains the CDN source for each library. * * The `cdn_info` object is defined in the `_cdn.yml` file. It contains the name of the library, the * version, and the CDN source etc. * * The `match_cdn_source` function returns the CDN source for * the library. * * The `collect_cdn_source` function is called in the `_cdn.yml` file. It loops through the * `cdn_info` object and adds the CDN source for each library to the `hexo.theme.config.cdn` object. * * The `hexo.theme.config.debug` variable is defined in the `_config.yml` file. It is set to `true` */ function collect_cdn_source() { hexo.theme.config.cdn = {} Object.keys(cdn_info).forEach(e => { hexo.theme.config.cdn[e] = match_cdn_source(e) }) if (hexo.theme.config.debug == "cdn") console.log(hexo.theme.config.cdn); } hexo.on('generateBefore', () => { /* It's replacing the prefix of the source with the prefix you set in the configuration file. */ volantis_cdn_system_prefix(hexo.theme.config, hexo); // 可以在 source/_data/cdn.yml 覆盖 theme/_cdn.yml const data = hexo.locals.get('data'); if (data.cdn) { merge(cdn_info, data.cdn); } /* Collecting the CDN source for each library. */ collect_cdn_source(); });