Fix: rewrite loadScript, merge onDOMscripted, injectCSS, injectScript

This commit is contained in:
eight 2017-09-12 23:19:16 +08:00
parent dc37588cd1
commit 2506b957f8
8 changed files with 86 additions and 154 deletions

View File

@ -172,7 +172,7 @@ function buildWarning(err) {
return $element({className: 'warning', appendChild: [
t('parseUsercssError'),
$element({tag: 'pre', appendChild: String(err)})
]})
]});
}
function initErrorPage(err, source) {

View File

@ -1,9 +1,9 @@
/* eslint brace-style: 0, operator-linebreak: 0 */
/* global CodeMirror parserlib */
/* global onDOMscripted */
/* global css_beautify */
/* global CSSLint initLint linterConfig updateLintReport renderLintReport updateLinter */
/* global mozParser createSourceEditor */
/* global loadScript */
'use strict';
@ -1206,14 +1206,13 @@ function getEditorInSight(nearbyElement) {
}
function beautify(event) {
onDOMscripted([
'vendor-overwrites/beautify/beautify-css-mod.js',
() => {
loadScript('/vendor-overwrites/beautify/beautify-css-mod.js')
.then(() => {
if (!window.css_beautify && window.exports) {
window.css_beautify = window.exports.css_beautify;
}
},
]).then(doBeautify);
})
.then(doBeautify);
function doBeautify() {
const tabs = prefs.get('editor.indentWithTabs');
@ -1352,7 +1351,7 @@ function setStyleMeta(style) {
function initWithStyle(request) {
if (!editor) {
if (!style.usercss) {
if (!request.style.usercss) {
initWithSectionStyle(request);
} else {
editor = createSourceEditor(request.style);
@ -1670,20 +1669,29 @@ function fromMozillaFormat() {
});
function doImport(event) {
// parserlib contained in CSSLint-worker.js
onDOMscripted(['vendor-overwrites/csslint/csslint-worker.js']).then(() => {
doImportWhenReady(event.target);
editors.forEach(cm => updateLintReportIfEnabled(cm, 1));
editors.last.state.renderLintReportNow = true;
});
}
function doImportWhenReady(target) {
const replaceOldStyle = target.name === 'import-replace';
$('.dismiss', popup).onclick();
const replaceOldStyle = event.target.name === 'import-replace';
const mozStyle = trimNewLines(popup.codebox.getValue());
mozParser.parse(mozStyle).then(sections => {
mozParser.parse(mozStyle)
.then(updateSection)
.then(() => {
editors.forEach(cm => updateLintReportIfEnabled(cm, 1));
editors.last.state.renderLintReportNow = true;
$('.dismiss', popup).onclick();
})
.catch(showError);
function showError(errors) {
if (!errors.join) {
errors = [errors];
}
showHelp(t('issues'), $element({
tag: 'pre',
textContent: errors.join('\n'),
}));
}
function updateSection(sections) {
if (replaceOldStyle) {
editors.slice(0).reverse().forEach(cm => {
removeSection({target: cm.getSection().firstElementChild});
@ -1709,13 +1717,9 @@ function fromMozillaFormat() {
makeSectionVisible(firstAddedCM);
firstAddedCM.focus();
}, errors => {
showHelp(t('issues'), $element({
tag: 'pre',
textContent: errors.join('\n'),
}));
});
}
}
function trimNewLines(s) {
return s.replace(/^[\s\n]+/, '').replace(/[\s\n]+$/, '');
}

View File

@ -1,6 +1,6 @@
/* global CodeMirror messageBox */
/* global editors makeSectionVisible showCodeMirrorPopup showHelp */
/* global onDOMscripted injectCSS require CSSLint stylelint */
/* global loadScript require CSSLint stylelint */
'use strict';
loadLinterAssets();
@ -503,10 +503,10 @@ function setupLinterPopup(config) {
$('.save', popup).disabled = cm.isClean();
});
setupLinterSettingsEvents(popup);
onDOMscripted([
'vendor/codemirror/mode/javascript/javascript.js',
'vendor/codemirror/addon/lint/json-lint.js',
'vendor/jsonlint/jsonlint.js'
loadScript([
'/vendor/codemirror/mode/javascript/javascript.js',
'/vendor/codemirror/addon/lint/json-lint.js',
'/vendor/jsonlint/jsonlint.js'
]).then(() => {
popup.codebox.setOption('mode', 'application/json');
popup.codebox.setOption('lint', 'json');
@ -514,32 +514,28 @@ function setupLinterPopup(config) {
}
function loadLinterAssets(name = prefs.get('editor.linter')) {
if (loadLinterAssets.loadingName === name) {
return onDOMscripted();
}
loadLinterAssets.loadingName = name;
const scripts = [];
if (name === 'csslint' && !window.CSSLint) {
scripts.push(
'vendor-overwrites/csslint/csslint-worker.js',
'edit/lint-defaults-csslint.js'
'/vendor-overwrites/csslint/csslint-worker.js',
'/edit/lint-defaults-csslint.js'
);
} else if (name === 'stylelint' && !window.stylelint) {
scripts.push(
'vendor-overwrites/stylelint/stylelint-bundle.min.js',
() => (window.stylelint = require('stylelint')),
'edit/lint-defaults-stylelint.js'
loadScript([
'/vendor-overwrites/stylelint/stylelint-bundle.min.js',
'/edit/lint-defaults-stylelint.js'
]).then(() => (window.stylelint = require('stylelint')))
);
}
if (name && !$('script[src$="vendor/codemirror/addon/lint/lint.js"]')) {
injectCSS('vendor/codemirror/addon/lint/lint.css');
injectCSS('msgbox/msgbox.css');
if (name && !$('script[src$="/vendor/codemirror/addon/lint/lint.js"]')) {
scripts.push(
'vendor/codemirror/addon/lint/lint.js',
'edit/lint-codemirror-helper.js',
'msgbox/msgbox.js'
'/vendor/codemirror/addon/lint/lint.css',
'/msgbox/msgbox.css',
'/vendor/codemirror/addon/lint/lint.js',
'/edit/lint-codemirror-helper.js',
'/msgbox/msgbox.js'
);
}
return onDOMscripted(scripts)
.then(() => (loadLinterAssets.loadingName = null));
return loadScript(scripts);
}

View File

@ -1,6 +1,7 @@
/* global CodeMirror dirtyReporter initLint beautify showKeyMapHelp */
/* global showToggleStyleHelp goBackToManage updateLintReportIfEnabled */
/* global hotkeyRerouter setupAutocomplete */
/* global editors */
'use strict';

View File

@ -80,83 +80,6 @@ function onDOMready() {
}
function onDOMscripted(scripts) {
const queue = onDOMscripted.queue = onDOMscripted.queue || [];
if (scripts) {
return new Promise(resolve => {
addResolver(resolve);
queue.push(...scripts.filter(el => !queue.includes(el)));
loadNextScript();
});
}
if (queue.length) {
return new Promise(resolve => addResolver(resolve));
}
if (document.readyState !== 'loading') {
if (onDOMscripted.resolveOnReady) {
onDOMscripted.resolveOnReady.forEach(r => r());
onDOMscripted.resolveOnReady = null;
}
return Promise.resolve();
}
return onDOMready().then(onDOMscripted);
function loadNextScript() {
const empty = !queue.length;
const next = !empty && queue.shift();
if (empty) {
onDOMscripted();
} else if (typeof next === 'function') {
Promise.resolve(next())
.then(loadNextScript);
} else {
Promise.all(
(next instanceof Array ? next : [next]).map(next =>
typeof next === 'function'
? next()
: injectScript({src: next, async: true})
)
).then(loadNextScript);
}
}
function addResolver(r) {
if (!onDOMscripted.resolveOnReady) {
onDOMscripted.resolveOnReady = [];
}
onDOMscripted.resolveOnReady.push(r);
}
}
function injectScript(properties) {
if (typeof properties === 'string') {
properties = {src: properties};
}
if (!properties || !properties.src) {
return;
}
if (injectScript.cache) {
if (injectScript.cache.has(properties.src)) {
return Promise.resolve();
}
} else {
injectScript.cache = new Set();
}
injectScript.cache.add(properties.src);
const script = document.head.appendChild(document.createElement('script'));
Object.assign(script, properties);
if (!properties.onload) {
return new Promise(resolve => {
script.onload = () => {
script.onload = null;
resolve();
};
});
}
}
function injectCSS(url) {
if (!url) {
return;

View File

@ -126,11 +126,8 @@ var mozParser = (function () {
return {
// Parse mozilla-format userstyle into sections
parse(text) {
if (typeof parserlib === 'undefined') {
return loadScript('vendor-overwrites/csslint/csslint-worker.js')
.then(() => parseMozFormat(text));
}
return parseMozFormat(text);
return loadScript('/vendor-overwrites/csslint/csslint-worker.js')
.then(() => parseMozFormat(text));
},
format(style) {
return style.sections.map(section => {

View File

@ -1,34 +1,46 @@
'use strict';
// loadScript(script: Array<Promise|string>|string): Promise
// eslint-disable-next-line no-var
var loadScript = (function () {
const cache = new Map();
return function (path) {
if (!path.includes('://')) {
path = chrome.runtime.getURL(path);
function inject(file) {
if (!cache.has(file)) {
cache.set(file, doInject(file));
}
return new Promise((resolve, reject) => {
if (cache.has(path)) {
resolve(cache.get(path));
return;
}
const script = document.createElement('script');
script.src = path;
script.onload = () => {
resolve(script);
script.onload = null;
script.onerror = null;
return cache.get(file);
}
cache.set(path, script);
function doInject(file) {
return new Promise((resolve, reject) => {
let el;
if (file.endsWith('.js')) {
el = document.createElement('script');
el.src = file;
} else {
el = document.createElement('link');
el.rel = 'stylesheet';
el.href = file;
}
el.onload = () => {
el.onload = null;
el.onerror = null;
resolve();
};
script.onerror = () => {
reject(new Error(`failed to load script: ${path}`));
script.onload = null;
script.onerror = null;
script.parentNode.removeChild(script);
el.onerror = () => {
el.onload = null;
el.onerror = null;
reject(new Error(`Failed to load script: ${file}`));
};
document.head.appendChild(script);
document.head.appendChild(el);
});
}
return files => {
if (!files.map) {
files = [files];
}
return Promise.all(files.map(f => (typeof f === 'string' ? inject(f) : f)));
};
})();

View File

@ -12,7 +12,7 @@ var usercss = (function () {
const BUILDER = {
default: {
postprocess(sections, vars) {
let varDef =
const varDef =
':root {\n' +
Object.keys(vars).map(k => ` --${k}: ${vars[k].value};\n`).join('') +
'}\n';
@ -24,7 +24,7 @@ var usercss = (function () {
},
stylus: {
preprocess(source, vars) {
return loadScript('vendor/stylus-lang/stylus.min.js').then(() => (
return loadScript('/vendor/stylus-lang/stylus.min.js').then(() => (
new Promise((resolve, reject) => {
let varDef = '';
for (const key of Object.keys(vars)) {
@ -73,7 +73,6 @@ var usercss = (function () {
}
function formatHex({r, g, b, a = null}) {
const values = [r, g, b];
let hex = '#' + (0x1000000 + (r << 16) + (g << 8) + (b | 0)).toString(16).substr(1);
if (a !== null) {
hex += (0x100 + Math.floor(a * 255)).toString(16).substr(1);