diff --git a/background/update-manager.js b/background/update-manager.js index 6fa28c1d..1c975281 100644 --- a/background/update-manager.js +++ b/background/update-manager.js @@ -78,17 +78,17 @@ const updateMan = (() => { /** * @param {{ - id?: number - style?: StyleObj - port?: chrome.runtime.Port - save?: boolean = true - ignoreDigest?: boolean + id?: number, + style?: StyleObj, + port?: chrome.runtime.Port, + save?: boolean, + ignoreDigest?: boolean, }} opts * @returns {{ - style: StyleObj - updated?: boolean - error?: any - STATES: UpdaterStates + style: StyleObj, + updated?: boolean, + error?: any, + STATES: UpdaterStates, }} Original style digests are calculated in these cases: @@ -127,7 +127,7 @@ const updateMan = (() => { err && err.message || err; res = {error, style, STATES}; - state = `${STATES.SKIPPED} (${error})`; + state = `${STATES.SKIPPED} (${Array.isArray(err) ? err[0].message : error})`; } log(`${state} #${id} ${style.customName || style.name}`); if (port) port.postMessage(res); diff --git a/js/csslint/parserlib.js b/js/csslint/parserlib.js index 546aad70..540bb5d7 100644 --- a/js/csslint/parserlib.js +++ b/js/csslint/parserlib.js @@ -2047,6 +2047,7 @@ self.parserlib = (() => { this.name = this.constructor.name; this.col = pos.col; this.line = pos.line; + this.offset = pos.offset; this.message = message; } } @@ -2056,6 +2057,7 @@ self.parserlib = (() => { super(); this.col = pos.col; this.line = pos.line; + this.offset = pos.offset; this.message = message; } } @@ -3462,7 +3464,7 @@ self.parserlib = (() => { * @param {string|Object} event * @param {parserlib.Token|SyntaxUnit} [token=this._tokenStream._token] - sets the position */ - fire(event, token = this._tokenStream._token) { + fire(event, token = event.offset != null ? event : this._tokenStream._token) { if (typeof event === 'string') { event = {type: event}; } diff --git a/js/moz-parser.js b/js/moz-parser.js index 4cef978d..a2f0f963 100644 --- a/js/moz-parser.js +++ b/js/moz-parser.js @@ -83,6 +83,12 @@ function extractSections({code, styleId, fast = true}) { parser.addListener('error', e => { errors.push(e); + const min = 5; // characters to show + const max = 100; + const i = e.offset; + const a = Math.max(mozStyle.lastIndexOf('\n', i - min) + 1, i - max); + const b = Math.min(mozStyle.indexOf('\n', i - a > min ? i : i + min) + 1 || 1e9, i + max); + e.context = mozStyle.slice(a, b); }); try { diff --git a/manage/updater-ui.js b/manage/updater-ui.js index 42bb66fe..ce4a5b8c 100644 --- a/manage/updater-ui.js +++ b/manage/updater-ui.js @@ -137,7 +137,6 @@ function reportUpdateState({updated, style, error, STATES}) { error === STATES.SAME_VERSION ); const edited = error === STATES.EDITED || error === STATES.MAYBE_EDITED; - entry.dataset.error = error; if (!error) { error = t('updateCheckFailServerUnreachable') + '\n' + style.updateUrl; } else if (typeof error === 'number') { @@ -149,7 +148,13 @@ function reportUpdateState({updated, style, error, STATES}) { } else if (typeof error === 'object' && error.message) { // UserCSS meta errors provide an object error = error.message; + } else if (Array.isArray(error)) { + // UserCSS build error + error = error.map(e => `${e.message || e}${ + e.context ? '\n' + e.context.replace(/^/gm, '\t') : '' // indenting source text + }`).join('\n'); } + entry.dataset.error = error; const message = same ? t('updateCheckSucceededNoUpdate') : error; newClasses.set('no-update', true); newClasses.set('update-problem', !same);