82 lines
2.6 KiB
JavaScript
82 lines
2.6 KiB
JavaScript
/* global API */
|
|
/* exported usercss */
|
|
'use strict';
|
|
|
|
const usercss = (() => {
|
|
const GLOBAL_METAS = {
|
|
author: undefined,
|
|
description: undefined,
|
|
homepageURL: 'url',
|
|
updateURL: 'updateUrl',
|
|
name: undefined,
|
|
};
|
|
const RX_META = /\/\*!?\s*==userstyle==[\s\S]*?==\/userstyle==\s*\*\//i;
|
|
const ERR_ARGS_IS_LIST = new Set(['missingMandatory', 'missingChar']);
|
|
|
|
return {
|
|
|
|
RX_META,
|
|
|
|
// Methods are sorted alphabetically
|
|
|
|
async assignVars(style, oldStyle) {
|
|
const vars = style.usercssData.vars;
|
|
const oldVars = oldStyle.usercssData.vars;
|
|
if (vars && oldVars) {
|
|
// The type of var might be changed during the update. Set value to null if the value is invalid.
|
|
for (const [key, v] of Object.entries(vars)) {
|
|
const old = oldVars[key] && oldVars[key].value;
|
|
if (old) v.value = old;
|
|
}
|
|
style.usercssData.vars = await API.worker.nullifyInvalidVars(vars);
|
|
}
|
|
},
|
|
|
|
async buildCode(style) {
|
|
const {sourceCode: code, usercssData: {vars, preprocessor}} = style;
|
|
const match = code.match(RX_META);
|
|
const codeNoMeta = code.slice(0, match.index) + code.slice(match.index + match[0].length);
|
|
const {sections, errors} = API.worker.compileUsercss(preprocessor, codeNoMeta, vars);
|
|
const recoverable = errors.every(e => e.recoverable);
|
|
if (!sections.length || !recoverable) {
|
|
throw !recoverable ? errors : 'Style does not contain any actual CSS to apply.';
|
|
}
|
|
style.sections = sections;
|
|
return style;
|
|
},
|
|
|
|
async buildMeta(sourceCode) {
|
|
sourceCode = sourceCode.replace(/\r\n?/g, '\n');
|
|
const style = {
|
|
enabled: true,
|
|
sections: [],
|
|
sourceCode,
|
|
};
|
|
const match = sourceCode.match(RX_META);
|
|
if (!match) {
|
|
return Promise.reject(new Error('Could not find metadata.'));
|
|
}
|
|
try {
|
|
const {metadata} = await API.worker.parseUsercssMeta(match[0], match.index);
|
|
style.usercssData = metadata;
|
|
// https://github.com/openstyles/stylus/issues/560#issuecomment-440561196
|
|
for (const [key, value] of Object.entries(GLOBAL_METAS)) {
|
|
if (metadata[key] !== undefined) {
|
|
style[value || key] = metadata[key];
|
|
}
|
|
}
|
|
return style;
|
|
} catch (err) {
|
|
if (err.code) {
|
|
const args = ERR_ARGS_IS_LIST.has(err.code)
|
|
? err.args.map(e => e.length === 1 ? JSON.stringify(e) : e).join(', ')
|
|
: err.args;
|
|
const msg = chrome.i18n.getMessage(`meta_${err.code}`, args);
|
|
if (msg) err.message = msg;
|
|
}
|
|
return Promise.reject(err);
|
|
}
|
|
},
|
|
};
|
|
})();
|