From 212269e23d4ed4509566e3149fa3653948a5e5dd Mon Sep 17 00:00:00 2001 From: Kushagra Gour Date: Sat, 9 Jun 2018 19:00:26 +0530 Subject: [PATCH] port showErrors --- webmaker/src/components/ContentWrap.jsx | 50 +++++- webmaker/src/components/Login.jsx | 12 ++ webmaker/src/components/app.jsx | 22 ++- webmaker/src/computes.js | 199 ++++++++++++++++-------- webmaker/src/utils.js | 1 + 5 files changed, 206 insertions(+), 78 deletions(-) diff --git a/webmaker/src/components/ContentWrap.jsx b/webmaker/src/components/ContentWrap.jsx index 813fc24..062b7b5 100644 --- a/webmaker/src/components/ContentWrap.jsx +++ b/webmaker/src/components/ContentWrap.jsx @@ -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); + } + }); }); } diff --git a/webmaker/src/components/Login.jsx b/webmaker/src/components/Login.jsx index fe46299..51797fb 100644 --- a/webmaker/src/components/Login.jsx +++ b/webmaker/src/components/Login.jsx @@ -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 (
diff --git a/webmaker/src/components/app.jsx b/webmaker/src/components/app.jsx index 8fc8983..aef0160 100644 --- a/webmaker/src/components/app.jsx +++ b/webmaker/src/components/app.jsx @@ -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 )} diff --git a/webmaker/src/computes.js b/webmaker/src/computes.js index 80d52d8..826d2e6 100644 --- a/webmaker/src/computes.js +++ b/webmaker/src/computes.js @@ -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 - }]); + } } diff --git a/webmaker/src/utils.js b/webmaker/src/utils.js index 21b779a..02a4c22 100644 --- a/webmaker/src/utils.js +++ b/webmaker/src/utils.js @@ -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);