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"] */ /* eslint no-eq-null: 0, eqeqeq: [2, "smart"] */
/* /* global createCache db calcStyleDigest normalizeStyleSections db promisify
global createCache db calcStyleDigest normalizeStyleSections db promisify getStyleWithNoCode msg */
getStyleWithNoCode msg
*/
'use strict'; '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 styleManager = (() => {
const preparing = prepare(); const preparing = prepare();
const styles = new Map(); const styles = new Map();
@ -13,29 +19,7 @@ const styleManager = (() => {
const compiledExclusion = createCache(); const compiledExclusion = createCache();
const BAD_MATCHER = {test: () => false}; const BAD_MATCHER = {test: () => false};
// setup live preview 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(data, 'editPreview');
});
port.onDisconnect.addListener(() => {
port = null;
if (id) {
const style = styles.get(id);
style.preview = null;
broadcastStyleUpdated(style.data, 'editPreview');
}
});
});
return ensurePrepared({ return ensurePrepared({
get, get,
@ -52,6 +36,31 @@ const styleManager = (() => {
countStylesByUrl, // used by icon badge 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) { function get(id) {
return styles.get(id).data; return styles.get(id).data;
} }

View File

@ -1,16 +1,13 @@
/* global editors messageBox */
'use strict'; 'use strict';
function createLivePreview() { function createLivePreview(preprocess) {
let data; let data;
let previewer; let previewer;
let hidden; let enabled = prefs.get('editor.livePreview');
let node; const label = $('#preview-label');
document.addEventListener('DOMContentLoaded', () => { const errorContainer = $('#preview-errors');
node = $('#preview-label');
if (hidden !== undefined) {
node.classList.toggle('hidden', hidden);
}
}, {once: true});
prefs.subscribe(['editor.livePreview'], (key, value) => { prefs.subscribe(['editor.livePreview'], (key, value) => {
if (value && data && data.id && data.enabled) { if (value && data && data.id && data.enabled) {
previewer = createPreviewer; previewer = createPreviewer;
@ -20,23 +17,18 @@ function createLivePreview() {
previewer.disconnect(); previewer.disconnect();
previewer = null; previewer = null;
} }
enabled = value;
}); });
return {update, show}; return {update, show};
function show(state) { function show(state) {
if (hidden === !state) { label.classList.toggle('hidden', !state);
return;
}
hidden = !state;
if (node) {
node.classList.toggle('hidden', hidden);
}
} }
function update(_data) { function update(_data) {
data = _data; data = _data;
if (!previewer) { if (!previewer) {
if (!data.id || !data.enabled) { if (!data.id || !data.enabled || !enabled) {
return; return;
} }
previewer = createPreviewer(); previewer = createPreviewer();
@ -54,7 +46,23 @@ function createLivePreview() {
return {update, disconnect}; return {update, disconnect};
function update(data) { 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() { function disconnect() {

View File

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