1
0
mirror of https://github.com/bobwen-dev/react-templates synced 2025-04-12 00:56:39 +02:00

add panel with errors

This commit is contained in:
ido 2014-12-10 14:14:22 +02:00
parent a65eff45c4
commit d60af285c3
6 changed files with 156 additions and 18 deletions

View File

@ -1,14 +1,15 @@
define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
define(['react', 'lodash', 'jquery', './libs/codemirror-4.8/lib/codemirror',
'./libs/codemirror-4.8/mode/javascript/javascript',
'./libs/codemirror-4.8/addon/hint/html-hint',
'./libs/codemirror-4.8/addon/hint/show-hint',
'./libs/codemirror-4.8/addon/hint/xml-hint',
'./libs/codemirror-4.8/addon/hint/html-hint',
'./libs/codemirror-4.8/addon/display/panel',
'./libs/codemirror-4.8/mode/xml/xml',
'./libs/codemirror-4.8/mode/css/css',
'./libs/codemirror-4.8/mode/htmlmixed/htmlmixed'
//'./libs/codemirror-4.8/addon/display/placeholder'
], function (React, _, CodeMirror) {
], function (React, _, $, CodeMirror) {
'use strict';
//codeMirror: 'libs/codemirror-4.8/lib/codemirror',
//htmlmixed: 'libs/codemirror-4.8/mode/htmlmixed/htmlmixed',
@ -33,7 +34,7 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
});
function completeAfter(cm, pred) {
var cur = cm.getCursor();
//var cur = cm.getCursor();
if (!pred || pred()) {
setTimeout(function () {
if (!cm.state.completionActive) {
@ -47,6 +48,7 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
function completeIfAfterLt(cm) {
return completeAfter(cm, function () {
var cur = cm.getCursor();
/*eslint new-cap:0*/
return cm.getRange(CodeMirror.Pos(cur.line, cur.ch - 1), cur) === '<';
});
}
@ -70,7 +72,6 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
};
},
componentWillMount: function () {
},
render: function () {
var props = _.omit(this.props, ['ref', 'key', 'value', 'valueLink', 'onChange']);
@ -79,7 +80,7 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
},
componentWillUpdate: function (nextProps/*, nextState*/) {
var value = nextProps.valueLink ? nextProps.valueLink() : nextProps.value;
if (this.editor && this.editor.getValue() != value) {
if (this.editor && this.editor.getValue() !== value) {
this.editor.setValue(value || '');
}
},
@ -88,10 +89,12 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
var options = {
readOnly: this.props.readOnly,
lineWrapping: true,
smartIndent: true,
matchBrackets: true,
value: value,
lineNumbers: true,
mode: 'javascript',
theme: 'solarized' //solarized_light
theme: 'solarized' //solarized_light solarized-light
};
if (this.props.mode === 'html') {
@ -124,6 +127,21 @@ define(['react', 'lodash', './libs/codemirror-4.8/lib/codemirror',
}.bind(this));
}
},
showMessage: function (msg) {
var anOption = document.createElement('div');
anOption.innerText = msg;
anOption.setAttribute('class', 'error-panel');
if (this.panel) {
this.panel.clear();
}
this.panel = this.editor.addPanel(anOption, {height: 22}); // {position: 'bottom'}
},
clearMessage: function () {
if (this.panel) {
this.panel.clear();
this.panel = null;
}
},
componentWillUnmount: function () {
this.editor.destroy();
}

View File

@ -125,4 +125,13 @@ body {
padding: 1px;
}
.error-panel {
/*padding: 4px; */
padding-left: 20px;
/* position: static; */
color: red;
background: #f7f7f7;
border-bottom: 1px solid #000;
}
/*position: relative; min-height: 100%;*/

View File

@ -0,0 +1,94 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
CodeMirror.defineExtension("addPanel", function(node, options) {
if (!this.state.panels) initPanels(this);
var info = this.state.panels;
if (options && options.position == "bottom")
info.wrapper.appendChild(node);
else
info.wrapper.insertBefore(node, info.wrapper.firstChild);
var height = (options && options.height) || node.offsetHeight;
this._setSize(null, info.heightLeft -= height);
info.panels++;
return new Panel(this, node, options, height);
});
function Panel(cm, node, options, height) {
this.cm = cm;
this.node = node;
this.options = options;
this.height = height;
this.cleared = false;
}
Panel.prototype.clear = function() {
if (this.cleared) return;
this.cleared = true;
var info = this.cm.state.panels;
this.cm._setSize(null, info.heightLeft += this.height);
info.wrapper.removeChild(this.node);
if (--info.panels == 0) removePanels(this.cm);
};
Panel.prototype.changed = function(height) {
var newHeight = height == null ? this.node.offsetHeight : height;
var info = this.cm.state.panels;
this.cm._setSize(null, info.height += (newHeight - this.height));
this.height = newHeight;
};
function initPanels(cm) {
var wrap = cm.getWrapperElement();
var style = window.getComputedStyle ? window.getComputedStyle(wrap) : wrap.currentStyle;
var height = parseInt(style.height);
var info = cm.state.panels = {
setHeight: wrap.style.height,
heightLeft: height,
panels: 0,
wrapper: document.createElement("div")
};
wrap.parentNode.insertBefore(info.wrapper, wrap);
var hasFocus = cm.hasFocus();
info.wrapper.appendChild(wrap);
if (hasFocus) cm.focus();
cm._setSize = cm.setSize;
if (height != null) cm.setSize = function(width, newHeight) {
if (newHeight == null) return this._setSize(width, newHeight);
info.setHeight = newHeight;
if (typeof newHeight != "number") {
var px = /^(\d+\.?\d*)px$/.exec(newHeight);
if (px) {
newHeight = Number(px[1]);
} else {
info.wrapper.style.height = newHeight;
newHeight = info.wrapper.offsetHeight;
info.wrapper.style.height = "";
}
}
cm._setSize(width, info.heightLeft += (newHeight - height));
height = newHeight;
};
}
function removePanels(cm) {
var info = cm.state.panels;
cm.state.panels = null;
var wrap = cm.getWrapperElement();
info.wrapper.parentNode.replaceChild(wrap, info.wrapper);
wrap.style.height = info.setHeight;
cm.setSize = cm._setSize;
cm.setSize();
}
});

View File

@ -3,13 +3,13 @@
<div class="playground">
<div class="fiddle-row">
<div class="code-area">
<CodeEditor id="editor-rt" class="large-text-area" style="border: {this.validHTML ? '1px solid black' : '2px solid red'};"
<CodeEditor ref="editorRT" id="editor-rt" class="large-text-area" style="border: {this.validHTML ? '1px solid black' : '2px solid red'};"
value="{this.state.templateHTML}"
mode="html"
onChange="(evt) => this.setState({'templateHTML':evt.target.value})" />
</div>
<div class="code-area">
<CodeEditor id="editor-code" class="large-text-area" style="border: {this.validProps ? '1px solid black' : '2px solid red'};"
<CodeEditor ref="editorCode" id="editor-code" class="large-text-area" style="border: {this.validProps ? '1px solid black' : '2px solid red'};"
value="{this.state.templateProps}"
mode="javascript"
onChange="(evt) => this.setState({'templateProps':evt.target.value})" />

View File

@ -16,6 +16,7 @@ define([
}
return function () {
return React.createElement('div', { 'className': 'playground' }, React.createElement('div', { 'className': 'fiddle-row' }, React.createElement('div', { 'className': 'code-area' }, React.createElement(CodeEditor, {
'ref': 'editorRT',
'id': 'editor-rt',
'className': 'large-text-area',
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
@ -23,6 +24,7 @@ define([
'mode': 'html',
'onChange': onChange1.bind(this)
})), React.createElement('div', { 'className': 'code-area' }, React.createElement(CodeEditor, {
'ref': 'editorCode',
'id': 'editor-code',
'className': 'large-text-area',
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },

View File

@ -1,20 +1,29 @@
'use strict';
/*eslint-env browser*/
define(['react', 'lodash', './playground-fiddle.rt', './playground.rt'], function (React, _, pgFiddleTemplate, playgroundTemplate) {
'use strict';
function emptyFunc() {
return null;
}
function generateTemplateSource(html) {
function generateTemplateSource(html, editor) {
var code = null;
try {
code = window.reactTemplates.convertTemplateToReact(html.trim().replace(/\r/g, ''));
} catch (e) {
if (e.name === 'RTCodeError') {
console.log('');
//index: -1 line: -1 message: "Document should have a root element" name: "RTCodeError"
if (editor) {
editor.clearMessage();
}
console.log('' + e);
} catch (e) {
var msg;
if (e.name === 'RTCodeError') {
//index: -1 line: -1 message: "Document should have a root element" name: "RTCodeError"
msg = e.message + ', line: ' + e.line;
} else {
msg = e.message;
}
if (editor) {
editor.showMessage(msg);
}
console.log(e);
}
return code;
}
@ -32,7 +41,7 @@ define(['react', 'lodash', './playground-fiddle.rt', './playground.rt'], functio
var res = eval(code);
return res;
} catch (e) {
console.log('' + e);
console.log(e);
return emptyFunc;
}
}
@ -72,8 +81,8 @@ define(['react', 'lodash', './playground-fiddle.rt', './playground.rt'], functio
};
},
updateSample: function (state) {
this.templateSource = generateTemplateSource(state.templateHTML);
this.sampleFunc = generateTemplateFunction(this.templateSource);
this.templateSource = generateTemplateSource(state.templateHTML, this.refs.editorRT);
this.sampleFunc = generateTemplateFunction(this.templateSource, this.refs.editorCode);
this.validHTML = this.sampleFunc !== emptyFunc;
this.sampleRender = generateRenderFunc(this.sampleFunc);
var classBase = {};
@ -84,9 +93,15 @@ define(['react', 'lodash', './playground-fiddle.rt', './playground.rt'], functio
if (!_.isObject(classBase)) {
throw 'failed to eval';
}
if (this.refs.editorCode) {
this.refs.editorCode.clearMessage();
}
} catch (e) {
classBase = {};
this.validProps = false;
if (this.refs.editorCode) {
this.refs.editorCode.showMessage(e.message);
}
}
classBase.render = this.sampleRender;
this.sample = React.createFactory(React.createClass(classBase));