Add: preview error

This commit is contained in:
eight 2018-10-08 20:12:39 +08:00
parent 47b2b4fc49
commit 30e8662946
3 changed files with 74 additions and 53 deletions

View File

@ -1,10 +1,16 @@
/* eslint no-eq-null: 0, eqeqeq: [2, "smart"] */
/*
global createCache db calcStyleDigest normalizeStyleSections db promisify
getStyleWithNoCode msg
*/
/* global createCache db calcStyleDigest normalizeStyleSections db promisify
getStyleWithNoCode msg */
'use strict';
/*
This style manager is a layer between content script and the DB. When a style
is added/updated, it broadcast a message to content script and the content
script would try to fetch the new code.
The live preview feature relies on `runtime.connect` and `port.onDisconnect`
to cleanup the temporary code. See /edit/live-preview.js.
*/
const styleManager = (() => {
const preparing = prepare();
const styles = new Map();
@ -13,29 +19,7 @@ const styleManager = (() => {
const compiledExclusion = createCache();
const BAD_MATCHER = {test: () => false};
// setup live preview
chrome.runtime.onConnect(port => {
if (port.name !== 'livePreview') {
return;
}
let id;
port.onMessage.addListener(data => {
if (!id) {
id = data.id;
}
const style = styles.get(id);
style.preview = data;
broadcastStyleUpdated(data, 'editPreview');
});
port.onDisconnect.addListener(() => {
port = null;
if (id) {
const style = styles.get(id);
style.preview = null;
broadcastStyleUpdated(style.data, 'editPreview');
}
});
});
handleLivePreviewConnections();
return ensurePrepared({
get,
@ -52,6 +36,31 @@ const styleManager = (() => {
countStylesByUrl, // used by icon badge
});
function handleLivePreviewConnections() {
chrome.runtime.onConnect(port => {
if (port.name !== 'livePreview') {
return;
}
let id;
port.onMessage.addListener(data => {
if (!id) {
id = data.id;
}
const style = styles.get(id);
style.preview = data;
broadcastStyleUpdated(style.preview, 'editPreview');
});
port.onDisconnect.addListener(() => {
port = null;
if (id) {
const style = styles.get(id);
style.preview = null;
broadcastStyleUpdated(style.data, 'editPreview');
}
});
});
}
function get(id) {
return styles.get(id).data;
}

View File

@ -1,16 +1,13 @@
/* global editors messageBox */
'use strict';
function createLivePreview() {
function createLivePreview(preprocess) {
let data;
let previewer;
let hidden;
let node;
document.addEventListener('DOMContentLoaded', () => {
node = $('#preview-label');
if (hidden !== undefined) {
node.classList.toggle('hidden', hidden);
}
}, {once: true});
let enabled = prefs.get('editor.livePreview');
const label = $('#preview-label');
const errorContainer = $('#preview-errors');
prefs.subscribe(['editor.livePreview'], (key, value) => {
if (value && data && data.id && data.enabled) {
previewer = createPreviewer;
@ -20,23 +17,18 @@ function createLivePreview() {
previewer.disconnect();
previewer = null;
}
enabled = value;
});
return {update, show};
function show(state) {
if (hidden === !state) {
return;
}
hidden = !state;
if (node) {
node.classList.toggle('hidden', hidden);
}
label.classList.toggle('hidden', !state);
}
function update(_data) {
data = _data;
if (!previewer) {
if (!data.id || !data.enabled) {
if (!data.id || !data.enabled || !enabled) {
return;
}
previewer = createPreviewer();
@ -54,7 +46,23 @@ function createLivePreview() {
return {update, disconnect};
function update(data) {
port.postMessage(data);
Promise.resolve()
.then(() => preprocess ? preprocess(data) : data)
.then(data => port.postMessage(data))
.then(
() => errorContainer.classList.add('hidden'),
err => {
if (Array.isArray(err)) {
err = err.join('\n');
} else if (err && err.index !== undefined) {
// FIXME: this would fail if editors[0].getValue() !== data.sourceCode
const pos = editors[0].posFromIndex(err.index);
err.message = `${pos.line}:${pos.ch} ${err.message || String(err)}`;
}
errorContainer.classList.remove('hidden');
errorContainer.onclick = () => messageBox.alert(err.message || String(err), 'pre');
}
);
}
function disconnect() {

View File

@ -37,7 +37,7 @@ function createSourceEditor(style) {
editors.push(cm);
const livePreview = createLivePreview();
const livePreview = createLivePreview(preprocess);
livePreview.show(Boolean(style.id));
$('#enabled').onchange = function () {
@ -92,20 +92,24 @@ function createSourceEditor(style) {
});
});
function updateLivePreview() {
if (!style.id) {
return;
}
API.buildUsercss({
sourceCode: cm.getValue(),
function preprocess(style) {
return API.buildUsercss({
sourceCode: style.sourceCode,
vars: style.usercssData.vars
})
.then(newStyle => {
delete newStyle.enabled;
livePreview.update(Object.assign({}, style, newStyle));
return Object.assign(style, newStyle);
});
}
function updateLivePreview() {
if (!style.id) {
return;
}
livePreview.update(Object.assign({}, style, {sourceCode: cm.getValue()}));
}
function initAppliesToLineWidget() {
const PREF_NAME = 'editor.appliesToLineWidget';
const widget = createAppliesToLineWidget(cm);