1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-04-05 03:12:25 +02:00

port showErrors

This commit is contained in:
Kushagra Gour 2018-06-09 19:00:26 +05:30
parent ae675ef985
commit 212269e23d
5 changed files with 206 additions and 78 deletions

View File

@ -134,6 +134,21 @@ export default class ContentWrap extends Component {
});
}
}
cleanupErrors(lang) {
this.cm[lang].clearGutter('error-gutter');
}
showErrors(lang, errors) {
var editor = this.cm[lang];
errors.forEach(function(e) {
editor.operation(function() {
var n = document.createElement('div');
n.setAttribute('data-title', e.message);
n.classList.add('gutter-error-marker');
editor.setGutterMarker(e.lineNumber, 'error-gutter', n);
});
});
}
/**
* Generates the preview from the current code.
@ -148,6 +163,9 @@ export default class ContentWrap extends Component {
if (!this.props.prefs.preserveConsoleLogs) {
this.clearConsole();
}
this.cleanupErrors('html');
this.cleanupErrors('css');
this.cleanupErrors('js');
var currentCode = {
html: this.cmCodes.html,
@ -171,12 +189,15 @@ export default class ContentWrap extends Component {
cssMode === CssModes.ACSS ? currentCode.html : currentCode.css,
cssMode,
this.props.currentItem.cssSettings
).then(function(css) {
this.cm.css.setValue(css);
).then(result => {
if (cssMode === CssModes.ACSS) {
this.cm.css.setValue(result.code || '');
}
if (targetFrame.contentDocument.querySelector('#webmakerstyle')) {
targetFrame.contentDocument.querySelector(
'#webmakerstyle'
).textContent = css;
).textContent =
result.code || '';
}
});
} else {
@ -189,12 +210,27 @@ export default class ContentWrap extends Component {
cssMode,
this.props.currentItem.cssSettings
);
var jsPromise = computeJs(currentCode.js, this.props.currentItem.jsMode);
var jsPromise = computeJs(
currentCode.js,
this.props.currentItem.jsMode,
true,
this.props.prefs.infiniteLoopTimeout
);
Promise.all([htmlPromise, cssPromise, jsPromise]).then(result => {
if (result[1]) {
this.cm.css.setValue(result[1]);
if (cssMode === CssModes.ACSS) {
this.cm.css.setValue(result[1].code || '');
}
this.createPreviewFile(result[0], result[1], result[2]);
this.createPreviewFile(
result[0].code || '',
result[1].code || '',
result[2].code || ''
);
result.forEach(result => {
if (result.errors) {
this.showErrors(result.errors.lang, result.errors.data);
}
});
});
}

View File

@ -9,6 +9,18 @@ export default class Login extends Component {
trackEvent('ui', 'loginProviderClick', provider);
auth.login(provider);
}
componentDidMount() {
window.db.local.get(
{
lastAuthProvider: ''
},
result => {
if (result.lastAuthProvider) {
document.body.classList.add(`last-login-${result.lastAuthProvider}`);
}
}
);
}
render() {
return (
<div>

View File

@ -202,7 +202,7 @@ export default class App extends Component {
semverCompare(lastSeenVersion, version) === -1 &&
!window.localStorage.pledgeModalSeen
) {
scope.openSupportDeveloperModal();
this.openSupportDeveloperModal();
window.localStorage.pledgeModalSeen = true;
}
@ -846,6 +846,18 @@ export default class App extends Component {
});
e.preventDefault();
}
openSupportDeveloperModal(e) {
// this.closeAllModals();
this.setState({
isSupportDeveloperModalOpen: true
});
if (e) {
trackEvent('ui', e.target.dataset.eventAction);
}
}
supportDeveloperBtnClickHandler(e) {
this.openSupportDeveloperModal(e);
}
render() {
return (
@ -886,11 +898,9 @@ export default class App extends Component {
notificationsBtnClickHandler={() =>
this.setState({ notificationsBtnClickHandler: true })
}
supportDeveloperBtnClickHandler={() =>
this.setState({
isSupportDeveloperModalOpen: true
})
}
supportDeveloperBtnClickHandler={this.supportDeveloperBtnClickHandler.bind(
this
)}
detachedPreviewBtnHandler={this.detachedPreviewBtnHandler.bind(
this
)}

View File

@ -1,32 +1,49 @@
import {
deferred
} from './deferred';
import {
addInfiniteLoopProtection
} from './utils';
import {
HtmlModes,
CssModes,
JsModes
} from './codeModes';
const esprima = require('esprima');
// computeHtml, computeCss & computeJs evaluate the final code according
// to whatever mode is selected and resolve the returned promise with the code.
export function computeHtml(code, mode) {
var d = deferred();
if (mode === HtmlModes.HTML) {
d.resolve(code);
d.resolve({
code
});
} else if (mode === HtmlModes.MARKDOWN) {
d.resolve(window.marked ? marked(code) : code);
d.resolve(window.marked ? {
code: marked(code)
} : {
code
});
} else if (mode === HtmlModes.JADE) {
d.resolve(window.jade ? jade.render(code) : code);
d.resolve(window.jade ? {
code: jade.render(code)
} : {
code
});
}
return d.promise;
}
export function computeCss(code, mode, settings) {
var d = deferred();
// cleanupErrors('css');
var errors;
if (mode === CssModes.CSS) {
d.resolve(code);
d.resolve({
code
});
} else if (mode === CssModes.SCSS || mode === CssModes.SASS) {
if (window.sass && code) {
window.sass.compile(
@ -36,27 +53,44 @@ export function computeCss(code, mode, settings) {
function (result) {
// Something was wrong
if (result.line && result.message) {
showErrors('css', [{
lineNumber: result.line - 1,
message: result.message
}]);
errors = {
lang: 'css',
data: [{
lineNumber: result.line - 1,
message: result.message
}]
};
}
d.resolve(result.text);
d.resolve({
code: result.text,
errors
});
}
);
} else {
d.resolve(code);
d.resolve({
code
});
}
} else if (mode === CssModes.LESS) {
less.render(code).then(
function (result) {
d.resolve(result.css);
d.resolve({
code: result.css
});
},
function (error) {
showErrors('css', [{
lineNumber: error.line,
message: error.message
}]);
errors = {
lang: 'css',
data: [{
lineNumber: error.line,
message: error.message
}]
};
d.resolve({
code: '',
errors
})
}
);
} else if (mode === CssModes.STYLUS) {
@ -66,16 +100,24 @@ export function computeCss(code, mode, settings) {
// Last line of message is the actual message
var tempArr = error.message.split('\n');
tempArr.pop(); // This is empty string in the end
showErrors('css', [{
lineNumber: +error.message.match(/stylus:(\d+):/)[1] - 298,
message: tempArr.pop()
}]);
errors = {
lang: 'css',
data: [{
lineNumber: +error.message.match(/stylus:(\d+):/)[1] - 298,
message: tempArr.pop()
}]
};
}
d.resolve(result);
d.resolve({
code: result,
errors
});
});
} else if (mode === CssModes.ACSS) {
if (!window.atomizer) {
d.resolve('');
d.resolve({
code: ''
});
} else {
const html = code;
const foundClasses = atomizer.findClassNames(html);
@ -89,41 +131,50 @@ export function computeCss(code, mode, settings) {
finalConfig = atomizer.getConfig(foundClasses, {});
}
const acss = atomizer.getCss(finalConfig);
d.resolve(acss);
d.resolve({
code: acss
});
}
}
return d.promise;
}
export function computeJs(code, mode, shouldPreventInfiniteLoops) {
var d = deferred();
// cleanupErrors('js');
export function computeJs(code, mode, shouldPreventInfiniteLoops, infiniteLoopTimeout) {
var d = deferred();
var errors;
if (!code) {
d.resolve('');
return d.promise;
}
if (mode === JsModes.JS) {
d.resolve(code);
return d.promise;
try {
esprima.parse(code, {
tolerant: true
});
} catch (e) {
showErrors('js', [{
lineNumber: e.lineNumber - 1,
message: e.description
}]);
errors = {
lang: 'js',
data: [{
lineNumber: e.lineNumber - 1,
message: e.description
}]
};
} finally {
if (shouldPreventInfiniteLoops !== false) {
code = utils.addInfiniteLoopProtection(code, {
timeout: prefs.infiniteLoopTimeout
// If errors are found in last parse, we don't run infinite loop
// protection otherwise it will again throw error.
code = errors ? code : addInfiniteLoopProtection(code, {
timeout: infiniteLoopTimeout
});
}
d.resolve(code);
d.resolve({
code,
errors
});
}
} else if (mode === JsModes.COFFEESCRIPT) {
if (!window.CoffeeScript) {
@ -135,17 +186,23 @@ export function computeJs(code, mode, shouldPreventInfiniteLoops) {
bare: true
});
} catch (e) {
showErrors('js', [{
lineNumber: e.location.first_line,
message: e.message
}]);
errors = {
lang: 'js',
data: [{
lineNumber: e.location.first_line,
message: e.message
}]
};
} finally {
if (shouldPreventInfiniteLoops !== false) {
code = utils.addInfiniteLoopProtection(code, {
timeout: prefs.infiniteLoopTimeout
code = errors ? code : addInfiniteLoopProtection(code, {
timeout: infiniteLoopTimeout
});
}
d.resolve(code);
d.resolve({
code,
errors
});
}
} else if (mode === JsModes.ES6) {
if (!window.Babel) {
@ -158,25 +215,33 @@ export function computeJs(code, mode, shouldPreventInfiniteLoops) {
jsx: true
});
} catch (e) {
showErrors('js', [{
lineNumber: e.lineNumber - 1,
message: e.description
}]);
errors = {
lang: 'js',
data: [{
lineNumber: e.lineNumber - 1,
message: e.description
}]
};
} finally {
code = Babel.transform(code, {
presets: ['latest', 'stage-2', 'react']
}).code;
if (shouldPreventInfiniteLoops !== false) {
code = utils.addInfiniteLoopProtection(code, {
timeout: prefs.infiniteLoopTimeout
code = errors ? code : addInfiniteLoopProtection(code, {
timeout: infiniteLoopTimeout
});
}
d.resolve(code);
d.resolve({
code,
errors
});
}
} else if (mode === JsModes.TS) {
try {
if (!window.ts) {
d.resolve('');
d.resolve({
code: ''
});
return d.promise;
}
code = ts.transpileModule(code, {
@ -189,25 +254,29 @@ export function computeJs(code, mode, shouldPreventInfiniteLoops) {
});
if (code.diagnostics.length) {
/* eslint-disable no-throw-literal */
throw {
description: code.diagnostics[0].messageText,
lineNumber: ts.getLineOfLocalPosition(
code.diagnostics[0].file,
code.diagnostics[0].start
)
errors = {
lang: 'js',
data: [{
message: code.diagnostics[0].messageText,
lineNumber: ts.getLineOfLocalPosition(
code.diagnostics[0].file,
code.diagnostics[0].start
) - 1
}]
};
}
if (shouldPreventInfiniteLoops !== false) {
code = utils.addInfiniteLoopProtection(code.outputText, {
timeout: prefs.infiniteLoopTimeout
code = code.outputText;
if (shouldPreventInfiniteLoops !== false && !errors) {
code = addInfiniteLoopProtection(code, {
timeout: infiniteLoopTimeout
});
}
d.resolve(code);
d.resolve({
code,
errors
});
} catch (e) {
showErrors('js', [{
lineNumber: e.lineNumber - 1,
message: e.description
}]);
}
}

View File

@ -13,6 +13,7 @@ import {
import {
deferred
} from './deferred';
const esprima = require('esprima');
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
window.$ = document.querySelector.bind(document);