stylus/js/usercss.js

654 lines
19 KiB
JavaScript
Raw Normal View History

/* global loadScript semverCompare colorConverter styleCodeEmpty */
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
'use strict';
// eslint-disable-next-line no-var
2017-10-29 17:22:10 +00:00
var usercss = (() => {
// true = global
// false or 0 = private
// <string> = global key name
// <function> = (style, newValue)
const KNOWN_META = new Map([
['author', true],
['advanced', 0],
['description', true],
['homepageURL', 'url'],
['icon', 0],
['license', 0],
['name', true],
['namespace', 0],
//['noframes', 0],
['preprocessor', 0],
['supportURL', 0],
['updateURL', (style, newValue) => {
// always preserve locally installed style's updateUrl
if (!/^file:/.test(style.updateUrl)) {
style.updateUrl = newValue;
}
}],
['var', 0],
['version', 0],
]);
const MANDATORY_META = ['name', 'namespace', 'version'];
2018-09-05 02:16:40 +00:00
const META_VARS = ['text', 'color', 'checkbox', 'select', 'dropdown', 'image', 'number', 'range'];
const META_URLS = [...KNOWN_META.keys()].filter(k => k.endsWith('URL'));
2017-09-15 05:40:04 +00:00
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
const BUILDER = {
default: {
postprocess(sections, vars) {
let varDef = Object.keys(vars).map(k => ` --${k}: ${vars[k].value};\n`).join('');
if (!varDef) return;
varDef = ':root {\n' + varDef + '}\n';
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
for (const section of sections) {
if (!styleCodeEmpty(section.code)) {
section.code = varDef + section.code;
}
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
}
},
stylus: {
preprocess(source, vars) {
2018-07-21 17:58:54 +00:00
return loadScript('/vendor/stylus-lang-bundle/stylus.min.js').then(() => (
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
new Promise((resolve, reject) => {
2017-11-09 00:24:37 +00:00
const varDef = Object.keys(vars).map(key => `${key} = ${vars[key].value};\n`).join('');
if (!Error.captureStackTrace) Error.captureStackTrace = () => {};
window.stylus(varDef + source).render((err, output) => {
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
if (err) {
reject(err);
} else {
resolve(output);
}
});
})
));
}
2017-09-15 05:40:04 +00:00
},
2018-04-19 08:12:23 +00:00
less: {
preprocess(source, vars) {
window.less = window.less || {
logLevel: 0,
useFileCache: false,
};
const varDefs = Object.keys(vars).map(key => `@${key}:${vars[key].value};\n`).join('');
return loadScript('/vendor/less/less.min.js')
.then(() => window.less.render(varDefs + source))
.then(({css}) => css);
}
},
2017-09-15 05:40:04 +00:00
uso: {
preprocess(source, vars) {
const pool = new Map();
return Promise.resolve(doReplace(source));
function getValue(name, rgb) {
if (!vars.hasOwnProperty(name)) {
if (name.endsWith('-rgb')) {
return getValue(name.slice(0, -4), true);
}
return null;
}
if (rgb) {
if (vars[name].type === 'color') {
2018-01-07 08:20:55 +00:00
const color = colorConverter.parse(vars[name].value);
if (!color) return null;
const {r, g, b} = color;
return `${r}, ${g}, ${b}`;
2017-09-15 05:40:04 +00:00
}
return null;
}
if (vars[name].type === 'dropdown' || vars[name].type === 'select') {
2017-09-15 05:40:04 +00:00
// prevent infinite recursion
pool.set(name, '');
2017-09-15 05:40:04 +00:00
return doReplace(vars[name].value);
}
return vars[name].value;
}
function doReplace(text) {
return text.replace(/\/\*\[\[([\w-]+)\]\]\*\//g, (match, name) => {
if (!pool.has(name)) {
const value = getValue(name);
pool.set(name, value === null ? match : value);
}
return pool.get(name);
});
}
}
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
};
const RX_NUMBER = /-?\d+(\.\d+)?\s*/y;
const RX_WHITESPACE = /\s*/y;
const RX_WORD = /([\w-]+)\s*/y;
const RX_STRING_BACKTICK = /(`(?:\\`|[\s\S])*?`)\s*/y;
const RX_STRING_QUOTED = /((['"])(?:\\\2|[^\n])*?\2|\w+)\s*/y;
2017-11-30 23:35:56 +00:00
const worker = {};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
function getMetaSource(source) {
const commentRe = /\/\*[\s\S]*?\*\//g;
const metaRe = /==userstyle==[\s\S]*?==\/userstyle==/i;
let m;
// iterate through each comment
while ((m = commentRe.exec(source))) {
const commentSource = source.slice(m.index, m.index + m[0].length);
const n = commentSource.match(metaRe);
if (n) {
2017-11-09 07:53:09 +00:00
return {
index: m.index + n.index,
text: n[0]
};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
}
return {text: '', index: 0};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
function parseWord(state, error = 'invalid word') {
RX_WORD.lastIndex = state.re.lastIndex;
const match = RX_WORD.exec(state.text);
2017-09-15 05:40:04 +00:00
if (!match) {
throw new Error((state.errorPrefix || '') + error);
}
2017-09-15 05:40:04 +00:00
state.value = match[1];
state.re.lastIndex += match[0].length;
}
2017-09-15 05:40:04 +00:00
function parseVar(state) {
const result = {
2017-09-15 05:40:04 +00:00
type: null,
label: null,
name: null,
value: null,
default: null,
2017-09-15 05:40:04 +00:00
options: null
};
2017-09-15 05:40:04 +00:00
parseWord(state, 'missing type');
result.type = state.type = state.value;
2017-09-15 05:40:04 +00:00
if (!META_VARS.includes(state.type)) {
throw new Error(`unknown type: ${state.type}`);
}
2017-09-15 05:40:04 +00:00
parseWord(state, 'missing name');
result.name = state.value;
parseString(state);
result.label = state.value;
const {re, type, text} = state;
switch (type === 'image' && state.key === 'var' ? '@image@var' : type) {
case 'checkbox': {
const match = text.slice(re.lastIndex).match(/([01])\s+/);
if (!match) {
throw new Error('value must be 0 or 1');
}
re.lastIndex += match[0].length;
result.default = match[1];
break;
2017-10-08 16:59:10 +00:00
}
case 'select':
case '@image@var': {
state.errorPrefix = 'Invalid JSON: ';
parseJSONValue(state);
state.errorPrefix = '';
2018-09-18 03:10:43 +00:00
const extractDefaultOption = (key, value) => {
if (key.endsWith('*')) {
const option = createOption(key.slice(0, -1), value);
result.default = option.name;
return option;
2018-09-16 22:17:15 +00:00
}
2018-09-18 03:10:43 +00:00
return createOption(key, value);
2018-09-16 22:17:15 +00:00
};
if (Array.isArray(state.value)) {
2018-09-18 03:10:43 +00:00
result.options = state.value.map(k => extractDefaultOption(k));
} else {
2018-09-18 03:10:43 +00:00
result.options = Object.keys(state.value).map(k => extractDefaultOption(k, state.value[k]));
}
2018-09-16 22:17:15 +00:00
if (result.default === null) {
result.default = (result.options[0] || {}).name || '';
}
break;
2017-09-15 05:40:04 +00:00
}
case 'number':
2018-09-05 02:16:40 +00:00
case 'range': {
state.errorPrefix = 'Invalid JSON: ';
parseJSONValue(state);
state.errorPrefix = '';
// [default, start, end, step, units] (start, end, step & units are optional)
if (Array.isArray(state.value) && state.value.length) {
// label may be placed anywhere
2018-09-16 22:17:15 +00:00
result.units = (state.value.find(i => typeof i === 'string') || '').replace(/[\d.+-]/g, '');
2018-09-19 11:39:54 +00:00
const range = state.value.filter(i => typeof i === 'number' || i === null);
result.default = range[0];
result.min = range[1];
result.max = range[2];
2018-09-19 11:39:54 +00:00
result.step = range[3] === 0 ? 1 : range[3];
2018-09-05 02:16:40 +00:00
}
break;
}
case 'dropdown':
case 'image': {
if (text[re.lastIndex] !== '{') {
throw new Error('no open {');
}
result.options = [];
re.lastIndex++;
while (text[re.lastIndex] !== '}') {
const option = {};
2017-09-15 05:40:04 +00:00
parseStringUnquoted(state);
option.name = state.value;
2017-09-15 05:40:04 +00:00
parseString(state);
option.label = state.value;
if (type === 'dropdown') {
parseEOT(state);
} else {
parseString(state);
}
option.value = state.value;
result.options.push(option);
2017-09-15 05:40:04 +00:00
}
re.lastIndex++;
eatWhitespace(state);
result.default = result.options[0].name;
break;
}
2017-09-15 05:40:04 +00:00
default: {
2018-09-19 11:40:20 +00:00
// text, color
parseStringToEnd(state);
result.default = state.value;
2017-09-15 05:40:04 +00:00
}
}
2017-09-16 01:24:50 +00:00
state.usercssData.vars[result.name] = result;
validateVar(result);
2017-09-15 05:40:04 +00:00
}
2017-11-04 00:38:17 +00:00
function createOption(label, value) {
let name;
const match = label.match(/^(\w+):(.*)/);
if (match) {
([, name, label] = match);
}
if (!name) {
name = label;
}
if (!value) {
value = name;
}
return {name, label, value};
}
2017-09-15 05:40:04 +00:00
function parseEOT(state) {
const re = /<<<EOT([\s\S]+?)EOT;/y;
re.lastIndex = state.re.lastIndex;
const match = state.text.match(re);
2017-09-15 05:40:04 +00:00
if (!match) {
throw new Error('missing EOT');
}
state.re.lastIndex += match[0].length;
state.value = match[1].trim().replace(/\*\\\//g, '*/');
eatWhitespace(state);
}
function parseStringUnquoted(state) {
const pos = state.re.lastIndex;
const nextQuoteOrEOL = posOrEnd(state.text, '"', pos);
state.re.lastIndex = nextQuoteOrEOL;
state.value = state.text.slice(pos, nextQuoteOrEOL).trim().replace(/\s+/g, '-');
2017-09-15 05:40:04 +00:00
}
function parseString(state) {
const pos = state.re.lastIndex;
const rx = state.text[pos] === '`' ? RX_STRING_BACKTICK : RX_STRING_QUOTED;
rx.lastIndex = pos;
const match = rx.exec(state.text);
if (!match) {
throw new Error((state.errorPrefix || '') + 'Quoted string expected');
}
2017-09-15 05:40:04 +00:00
state.re.lastIndex += match[0].length;
state.value = unquote(match[1]);
}
function parseJSONValue(state) {
const JSON_PRIME = {
__proto__: null,
'null': null,
'true': true,
'false': false
};
const {text, re, errorPrefix} = state;
if (text[re.lastIndex] === '{') {
// object
const obj = {};
re.lastIndex++;
eatWhitespace(state);
while (text[re.lastIndex] !== '}') {
parseString(state);
const key = state.value;
if (text[re.lastIndex] !== ':') {
throw new Error(`${errorPrefix}missing ':'`);
}
re.lastIndex++;
eatWhitespace(state);
parseJSONValue(state);
obj[key] = state.value;
if (text[re.lastIndex] === ',') {
re.lastIndex++;
eatWhitespace(state);
} else if (text[re.lastIndex] !== '}') {
throw new Error(`${errorPrefix}missing ',' or '}'`);
}
}
re.lastIndex++;
eatWhitespace(state);
state.value = obj;
} else if (text[re.lastIndex] === '[') {
// array
const arr = [];
re.lastIndex++;
eatWhitespace(state);
while (text[re.lastIndex] !== ']') {
parseJSONValue(state);
arr.push(state.value);
if (text[re.lastIndex] === ',') {
re.lastIndex++;
eatWhitespace(state);
} else if (text[re.lastIndex] !== ']') {
throw new Error(`${errorPrefix}missing ',' or ']'`);
}
}
re.lastIndex++;
eatWhitespace(state);
state.value = arr;
} else if (text[re.lastIndex] === '"' || text[re.lastIndex] === '`') {
// string
parseString(state);
} else if (/\d/.test(text[re.lastIndex])) {
// number
parseNumber(state);
} else {
parseWord(state);
if (!(state.value in JSON_PRIME)) {
throw new Error(`${errorPrefix}unknown literal '${state.value}'`);
}
state.value = JSON_PRIME[state.value];
}
}
function parseNumber(state) {
RX_NUMBER.lastIndex = state.re.lastIndex;
const match = RX_NUMBER.exec(state.text);
if (!match) {
throw new Error((state.errorPrefix || '') + 'invalid number');
}
state.value = Number(match[0].trim());
state.re.lastIndex += match[0].length;
2017-09-15 05:40:04 +00:00
}
function eatWhitespace(state) {
RX_WHITESPACE.lastIndex = state.re.lastIndex;
state.re.lastIndex += RX_WHITESPACE.exec(state.text)[0].length;
2017-09-15 05:40:04 +00:00
}
2017-09-15 05:40:04 +00:00
function parseStringToEnd(state) {
const EOL = posOrEnd(state.text, '\n', state.re.lastIndex);
const match = state.text.slice(state.re.lastIndex, EOL);
state.value = unquote(match.trim());
state.re.lastIndex += match.length;
2017-09-15 05:40:04 +00:00
}
function unquote(s) {
2017-10-08 18:45:26 +00:00
const q = s[0];
if (q === s[s.length - 1] && (q === '"' || q === "'" || q === '`')) {
2017-10-08 18:45:26 +00:00
// http://www.json.org/
return s.slice(1, -1).replace(
new RegExp(`\\\\([${q}\\\\/bfnrt]|u[0-9a-fA-F]{4})`, 'g'),
s => {
if (s[1] === q) {
return q;
}
return JSON.parse(`"${s}"`);
}
);
2017-09-15 05:40:04 +00:00
}
return s;
}
function posOrEnd(haystack, needle, start) {
const pos = haystack.indexOf(needle, start);
return pos < 0 ? haystack.length : pos;
}
2017-11-09 00:49:10 +00:00
function buildMeta(sourceCode) {
2017-09-18 00:16:11 +00:00
sourceCode = sourceCode.replace(/\r\n?/g, '\n');
2017-09-16 01:24:50 +00:00
const usercssData = {
vars: {}
};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
const style = {
reason: 'install',
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
enabled: true,
2017-09-16 01:24:50 +00:00
sourceCode,
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
sections: [],
2017-09-16 01:24:50 +00:00
usercssData
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
};
2017-11-09 07:53:09 +00:00
const {text, index: metaIndex} = getMetaSource(sourceCode);
const re = /@(\w+)[ \t\xA0]*/mg;
2017-09-16 01:24:50 +00:00
const state = {style, re, text, usercssData};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
2017-11-09 07:53:09 +00:00
function doParse() {
let match;
while ((match = re.exec(text))) {
const key = state.key = match[1];
const route = KNOWN_META.get(key);
if (route === undefined) {
2017-11-09 07:53:09 +00:00
continue;
}
if (key === 'var' || key === 'advanced') {
if (key === 'advanced') {
2017-11-09 07:53:09 +00:00
state.maybeUSO = true;
}
parseVar(state);
} else {
parseStringToEnd(state);
usercssData[key] = state.value;
2017-11-09 07:53:09 +00:00
}
let value = state.value;
if (key === 'version') {
value = usercssData[key] = normalizeVersion(value);
validateVersion(value);
2017-11-09 07:53:09 +00:00
}
if (META_URLS.includes(key)) {
validateUrl(key, value);
2017-11-09 07:53:09 +00:00
}
switch (typeof route) {
case 'function':
route(style, value);
break;
case 'string':
style[route] = value;
break;
default:
if (route) {
style[key] = value;
}
2017-09-15 05:40:04 +00:00
}
2017-09-16 01:24:50 +00:00
}
}
2017-11-09 07:53:09 +00:00
try {
doParse();
} catch (e) {
// the source code string offset
e.index = metaIndex + state.re.lastIndex;
2017-11-09 07:53:09 +00:00
throw e;
}
2017-09-16 01:24:50 +00:00
if (state.maybeUSO && !usercssData.preprocessor) {
usercssData.preprocessor = 'uso';
}
2017-11-09 00:49:10 +00:00
validateStyle(style);
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
return style;
}
2017-10-06 09:09:28 +00:00
function normalizeVersion(version) {
// https://docs.npmjs.com/misc/semver#versions
if (version[0] === 'v' || version[0] === '=') {
return version.slice(1);
}
return version;
}
/**
* @param {Object} style
* @param {Boolean} [allowErrors=false]
* @returns {(Style | {style: Style, errors: (false|String[])})} - style object
* when allowErrors is falsy or {style, errors} object when allowErrors is truthy
*/
function buildCode(style, allowErrors) {
2017-09-16 01:24:50 +00:00
const {usercssData: {preprocessor, vars}, sourceCode} = style;
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
let builder;
2017-09-16 01:24:50 +00:00
if (preprocessor) {
if (!BUILDER[preprocessor]) {
2017-11-09 00:56:25 +00:00
return Promise.reject(chrome.i18n.getMessage('styleMetaErrorPreprocessor', preprocessor));
}
2017-09-16 01:24:50 +00:00
builder = BUILDER[preprocessor];
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
} else {
builder = BUILDER.default;
}
2017-09-16 01:24:50 +00:00
const sVars = simpleVars(vars);
2017-09-01 06:38:46 +00:00
return (
Promise.resolve(
builder.preprocess && builder.preprocess(sourceCode, sVars) ||
sourceCode)
.then(mozStyle => invokeWorker({
action: 'parse',
styleId: style.id,
code: mozStyle,
}))
.then(({sections, errors}) => {
if (!errors.length) errors = false;
if (!sections.length || errors && !allowErrors) {
return Promise.reject(errors);
}
style.sections = sections;
if (builder.postprocess) builder.postprocess(style.sections, sVars);
return allowErrors ? {style, errors} : style;
}));
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
2017-09-01 06:38:46 +00:00
function simpleVars(vars) {
// simplify vars by merging `va.default` to `va.value`, so BUILDER don't
// need to test each va's default value.
return Object.keys(vars).reduce((output, key) => {
const va = vars[key];
2017-09-15 05:40:04 +00:00
output[key] = Object.assign({}, va, {
2017-09-01 06:38:46 +00:00
value: va.value === null || va.value === undefined ?
2017-11-04 00:38:17 +00:00
getVarValue(va, 'default') : getVarValue(va, 'value')
2017-09-15 05:40:04 +00:00
});
2017-09-01 06:38:46 +00:00
return output;
}, {});
}
2017-11-04 00:38:17 +00:00
function getVarValue(va, prop) {
if (va.type === 'select' || va.type === 'dropdown' || va.type === 'image') {
// TODO: handle customized image
return va.options.find(o => o.name === va[prop]).value;
}
if ((va.type === 'number' || va.type === 'range') && va.units) {
return va[prop] + va.units;
}
2017-11-04 00:38:17 +00:00
return va[prop];
}
function validateStyle({usercssData: data}) {
for (const prop of MANDATORY_META) {
2017-09-16 01:24:50 +00:00
if (!data[prop]) {
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
throw new Error(chrome.i18n.getMessage('styleMissingMeta', prop));
}
}
validateVersion(data.version);
META_URLS.forEach(k => validateUrl(k, data[k]));
Object.keys(data.vars).forEach(k => validateVar(data.vars[k]));
2017-09-09 11:29:35 +00:00
}
function validateVersion(version) {
2017-11-09 07:53:09 +00:00
semverCompare(version, '0.0.0');
}
function validateUrl(key, url) {
2017-09-11 18:46:37 +00:00
if (!url) {
return;
}
url = new URL(url);
if (!/^https?:/.test(url.protocol)) {
throw new Error(`${url.protocol} is not a valid protocol in ${key}`);
2017-09-11 18:46:37 +00:00
}
}
function validateVar(va, value = 'default') {
2017-09-15 05:40:04 +00:00
if (va.type === 'select' || va.type === 'dropdown') {
2017-11-04 00:38:17 +00:00
if (va.options.every(o => o.name !== va[value])) {
throw new Error(chrome.i18n.getMessage('styleMetaErrorSelectValueMismatch'));
2017-09-15 05:40:04 +00:00
}
2017-09-09 11:29:35 +00:00
} else if (va.type === 'checkbox' && !/^[01]$/.test(va[value])) {
2017-09-11 17:48:10 +00:00
throw new Error(chrome.i18n.getMessage('styleMetaErrorCheckbox'));
2017-09-09 11:29:35 +00:00
} else if (va.type === 'color') {
2018-01-07 08:20:55 +00:00
va[value] = colorConverter.format(colorConverter.parse(va[value]), 'rgb');
} else if ((va.type === 'number' || va.type === 'range') && typeof va[value] !== 'number') {
2018-09-08 14:46:29 +00:00
throw new Error(chrome.i18n.getMessage('styleMetaErrorRangeOrNumber', va.type));
2017-09-09 11:29:35 +00:00
}
}
2017-11-01 02:47:15 +00:00
function assignVars(style, oldStyle) {
2017-09-16 01:24:50 +00:00
const {usercssData: {vars}} = style;
2017-11-01 02:47:15 +00:00
const {usercssData: {vars: oldVars}} = oldStyle;
2017-09-09 11:29:35 +00:00
// The type of var might be changed during the update. Set value to null if the value is invalid.
2017-09-16 01:24:50 +00:00
for (const key of Object.keys(vars)) {
if (oldVars[key] && oldVars[key].value) {
vars[key].value = oldVars[key].value;
2017-09-09 11:29:35 +00:00
try {
validateVar(vars[key], 'value');
2017-09-12 12:48:03 +00:00
} catch (e) {
2017-09-16 01:24:50 +00:00
vars[key].value = null;
2017-09-09 11:29:35 +00:00
}
}
}
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
}
2017-11-30 23:35:56 +00:00
function invokeWorker(message) {
if (!worker.queue) {
Rewrite linter system (#487) * Add: implement new linter system * Refactor: pull out editor worker * Switch to new linter and worker * Enable eslint cache * Fix: undefined error * Windows compatibility * Fix: refresh linter if the editor.linter changes * Add: stylelint * Add: getStylelintRules, getCsslintRules * Fix: logic to get correct linter * WIP: linter-report * Fix: toggle hidden state * Add: matain the order of lint report for section editor * Add: unhook event * Add: gotoLintIssue * Fix: shouldn't delete rule.init * Add: linter-help-dialog * Drop linterConfig * Add: linter-config-dialog, cacheFn * Add: use cacheFn * Drop lint.js * Add: refresh. Fix report order * Fix: hide empty table * Add: updateCount. Fix table caption * Switch to new linter/worker * Fix: remove unneeded comment * Fix: cacheFn -> cacheFirstCall * Fix: use cacheFirstCall * Fix: cache metaIndex * Fix: i < trs.length * Fix: drop isEmpty * Fix: expose some simple states to global * Fix: return object code style * Fix: use proxy to reflect API * Fix: eslint-disable-line -> eslint-disable-next-line * Fix: requestId -> id * Fix: one-liner * Fix: one-liner * Fix: move dom event block to top * Fix: pending -> pendingResponse * Fix: onSuccess -> onUpdated * Fix: optimize row removing when i === 0 * Fix: hook/unhook -> enableForEditor/disableForEditor * Fix: linter.refresh -> linter.run * Fix: some shadowing * Fix: simplify getAnnotations * Fix: cacheFirstCall -> memoize * Fix: table.update -> table.updateCaption * Fix: unneeded reassign * Fix: callbacks -> listeners * Fix: don't compose but extend * Refactor: replace linter modules with linter-defaults and linter-engines * Fix: implement linter fallbacks * Fix: linter.onChange -> linter.onLintingUpdated * Fix: cms -> tables * Fix: parseMozFormat is not called correctly * Move csslint-loader to background * Fix: watch config changes * Fix: switch to LINTER_DEFAULTS * Fix: csslint-loader -> parserlib-loader
2018-10-01 14:03:17 +00:00
worker.instance = new Worker('/background/parserlib-loader.js');
2017-11-30 23:35:56 +00:00
worker.queue = [];
worker.instance.onmessage = ({data}) => {
worker.queue.shift().resolve(data.__ERROR__ ? Promise.reject(data.__ERROR__) : data);
2017-11-30 23:35:56 +00:00
if (worker.queue.length) {
worker.instance.postMessage(worker.queue[0].message);
}
};
}
return new Promise(resolve => {
worker.queue.push({message, resolve});
if (worker.queue.length === 1) {
worker.instance.postMessage(message);
}
});
}
return {buildMeta, buildCode, assignVars, invokeWorker};
Add: install styles from *.user.css file Fix: handle dup name+namespace Fix: eslint eqeqeq Fix: trim @name's spaces Add: check update for userstyle Add: build CSS variable Fix: only check dup when id is not provided Refactor: userStyle2json -> userstyle.json Add: style for input Add: config dialog Fix: preserve config during update Fix: onchange doesn't fire on keyboard enter event Fix: remove empty file Add: validator. Metas must stay in the same line Add: warn the user if installation failed Fix: add some delay before starting installation Add: open the editor after first installation Fix: add openEditor to globals Fix: i18n Add: preprocessor. Move userstyle.build to background page. Fix: remove unused global Fix: preserved unknown prop in saveStyleSource() like saveStyle() Add: edit userstyle source Fix: load preprocessor dynamically Fix: load content script dynamically Fix: buildCode is async function Fix: drop Object.entries Fix: style.sections is undefined Fix: don't hide the name input but disable it Fix: query the style before installation Revert: changes to editor, editor.html Refactor: use term `usercss` instead of `userstyle` Fix: don't show homepage action for usercss Refactor: move script-loader to js/ Refactor: pull out mozParser Fix: code style Fix: we don't need to build meta anymore Fix: use saveUsercss instead of saveStyle to get responsed error Fix: last is undefined, load script error Fix: switch to moz-format Fix: drop injectContentScript. Move usercss check into install-user-css Fix: response -> respond Fix: globals -> global Fix: queryUsercss -> filterUsercss Fix: add processUsercss function Fix: only open editor for usercss Fix: remove findupUsercss fixme Fix: globals -> global Fix: globals -> global Fix: global pollution Revert: update.js Refactor: checkStyle Add: support usercss Fix: no need to getURL in background page Fix: merget semver.js into usercss.js Fix: drop all_urls in match pattern Fix: drop respondWithError Move stylus -> stylus-lang Add stylus-lang/readme Fix: use include_globs Fix: global pollution
2017-08-05 16:49:25 +00:00
})();