Skip to content

Commit

Permalink
Make CONFIG more overridable & Fix quicklink
Browse files Browse the repository at this point in the history
- Deprecate quicklink.ignores but not obsolete it
- Rename `load-config.js` in source/js/ to `config.js`
  • Loading branch information
PaperStrike committed Apr 9, 2021
1 parent f475608 commit 7a5b348
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 64 deletions.
1 change: 1 addition & 0 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ quicklink:

# For more flexibility you can add some patterns (RegExp, Function, or Array) to ignores.
# See: https://github.com/GoogleChromeLabs/quicklink#custom-ignore-patterns
# This option is deprecated. Use `CONFIG.quicklink.ignores` in your custom scripts instead.
ignores:


Expand Down
2 changes: 1 addition & 1 deletion layout/_layout.njk
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
{{ partial('_partials/head/head.njk', {}, {cache: theme.cache.enable}) }}
{%- include '_partials/head/head-unique.njk' -%}
<title>{% block title %}{% endblock %}</title>
{{- next_js('load-config.js') }}
{{- next_js('config.js') }}
{{- next_inject('head') }}
{{ partial('_third-party/analytics/index.njk', {}, {cache: theme.cache.enable}) }}
<noscript>
Expand Down
3 changes: 2 additions & 1 deletion layout/_third-party/quicklink.njk
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{%- if theme.quicklink.enable %}
<script src="{{ theme.vendors.quicklink }}"></script>
{{ next_data('quicklink', page.quicklink, {
js: theme.vendors.quicklink
url: url | replace(r/index\.html$/, '')
}) }}
{{ next_js('third-party/quicklink.js') }}
{%- endif %}
4 changes: 2 additions & 2 deletions scripts/helpers/engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ hexo.extend.helper.register('next_js', function(file, pjax = false) {
hexo.extend.helper.register('next_data', function(name, ...data) {
const { escape_html } = this;
const json = data.length === 1 ? data[0] : Object.assign({}, ...data);
return `<script id="next-config-${name}" type="application/json">${
escape_html(JSON.stringify(json) ?? '')
return `<script class="next-config" data-name="${name}" type="application/json">${
escape_html(JSON.stringify(json))
}</script>`;
});

Expand Down
60 changes: 60 additions & 0 deletions source/js/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
if (!window.NexT) window.NexT = {};

const className = 'next-config';

const staticConfig = {};
let variableConfig = {};

const parse = (text) => {
const jsonString = new DOMParser()
.parseFromString(text, 'text/html').documentElement
.textContent;
return JSON.parse(jsonString || '{}');
};

const update = (name) => {
const targetEle = document.querySelector(`.${className}[data-name="${name}"]`);
if (!targetEle) return;
const parsedConfig = parse(targetEle.text);
if (name === 'main') {
Object.assign(staticConfig, parsedConfig);
} else {
variableConfig[name] = parsedConfig;
}
};

update('main');

window.CONFIG = new Proxy({}, {
get(overrideConfig, name) {
let existing;
if (name in staticConfig) {
existing = staticConfig[name];
} else {
if (!(name in variableConfig)) update(name);
existing = variableConfig[name];
}

let override = overrideConfig[name];
if (override === undefined && typeof existing === 'object') {
override = {};
overrideConfig[name] = override;
}

if (typeof override === 'object') {
return new Proxy({...existing, ...override}, {
set(target, prop, value) {
override[prop] = value;
return true;
}
});
}
return existing;
}
});

document.addEventListener('pjax:success', () => {
variableConfig = {};
});
}
43 changes: 0 additions & 43 deletions source/js/load-config.js

This file was deleted.

46 changes: 29 additions & 17 deletions source/js/third-party/quicklink.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,41 @@
/* global NexT, CONFIG, quicklink */
/* global CONFIG, quicklink */

{
const quicklinkListen = () => {
quicklink.listen({
let resetFn = null;

const onRefresh = () => {
if (resetFn) resetFn();
if (!CONFIG.quicklink.enable) return;

let ignoresArr = CONFIG.quicklink.ignores || [];
if (typeof ignoresArr === 'string') {
try {
ignoresArr = JSON.parse(`[${ignoresArr}]`);
} catch {
// eslint-disable-next-line no-console
console.error('Setting regex and function in config file is deprecated. Try setting `CONFIG.quicklink.ignores` in any script code.');
// eslint-disable-next-line no-eval
ignoresArr = eval(`[${ignoresArr}]`);
}
} else if (!Array.isArray(ignoresArr)) {
ignoresArr = [ignoresArr];
}

resetFn = quicklink.listen({
timeout : CONFIG.quicklink.timeout,
priority: CONFIG.quicklink.priority,
ignores : [
uri => uri.includes('#'),
uri => uri === CONFIG.quicklink.url,
// TODO: `quicklink.ignores` may includes functions that can not be parsed safely in JS runtime
...JSON.parse(`[${CONFIG.quicklink.ignores}]`)
...ignoresArr
]
});
};

document.addEventListener('page:loaded', () => {
if (!CONFIG.quicklink.enable) return;

NexT.utils.getScript(CONFIG.quicklink.js)
.then(() => {
if (CONFIG.quicklink.delay) {
window.addEventListener('load', quicklinkListen);
} else {
quicklinkListen();
}
});
});
if (CONFIG.quicklink.delay) {
window.addEventListener('load', onRefresh);
document.addEventListener('pjax:success', onRefresh);
} else {
document.addEventListener('page:loaded', onRefresh);
}
}

0 comments on commit 7a5b348

Please sign in to comment.