From 2506b957f8779f6301eb04943b3de3f54926074b Mon Sep 17 00:00:00 2001 From: eight Date: Tue, 12 Sep 2017 23:19:16 +0800 Subject: [PATCH] Fix: rewrite loadScript, merge onDOMscripted, injectCSS, injectScript --- content/install-user-css.js | 2 +- edit/edit.js | 54 ++++++++++++++------------ edit/lint.js | 40 +++++++++---------- edit/source-editor.js | 1 + js/dom.js | 77 ------------------------------------- js/moz-parser.js | 7 +--- js/script-loader.js | 54 ++++++++++++++++---------- js/usercss.js | 5 +-- 8 files changed, 86 insertions(+), 154 deletions(-) diff --git a/content/install-user-css.js b/content/install-user-css.js index eeb050a5..bb46f245 100644 --- a/content/install-user-css.js +++ b/content/install-user-css.js @@ -172,7 +172,7 @@ function buildWarning(err) { return $element({className: 'warning', appendChild: [ t('parseUsercssError'), $element({tag: 'pre', appendChild: String(err)}) - ]}) + ]}); } function initErrorPage(err, source) { diff --git a/edit/edit.js b/edit/edit.js index 481e0d55..733a11f1 100644 --- a/edit/edit.js +++ b/edit/edit.js @@ -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]+$/, ''); } diff --git a/edit/lint.js b/edit/lint.js index 2b19f8c1..ea031aca 100644 --- a/edit/lint.js +++ b/edit/lint.js @@ -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); } diff --git a/edit/source-editor.js b/edit/source-editor.js index 74915ef7..b53cf0ab 100644 --- a/edit/source-editor.js +++ b/edit/source-editor.js @@ -1,6 +1,7 @@ /* global CodeMirror dirtyReporter initLint beautify showKeyMapHelp */ /* global showToggleStyleHelp goBackToManage updateLintReportIfEnabled */ /* global hotkeyRerouter setupAutocomplete */ +/* global editors */ 'use strict'; diff --git a/js/dom.js b/js/dom.js index 249de722..b94a3d98 100644 --- a/js/dom.js +++ b/js/dom.js @@ -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; diff --git a/js/moz-parser.js b/js/moz-parser.js index e3b900e3..251181e1 100644 --- a/js/moz-parser.js +++ b/js/moz-parser.js @@ -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 => { diff --git a/js/script-loader.js b/js/script-loader.js index 38a9c648..f31677a2 100644 --- a/js/script-loader.js +++ b/js/script-loader.js @@ -1,34 +1,46 @@ 'use strict'; +// loadScript(script: Array|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))); }; })(); diff --git a/js/usercss.js b/js/usercss.js index c37ed4f5..03eeb3bc 100644 --- a/js/usercss.js +++ b/js/usercss.js @@ -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);