mirror of
https://github.com/bobwen-dev/react-templates
synced 2025-04-12 00:56:39 +02:00
changed playground to work with requirejs instead of browserify
This commit is contained in:
parent
01a46e506c
commit
7c1ccff8ab
75
Gruntfile.js
75
Gruntfile.js
@ -10,8 +10,7 @@ module.exports = function (grunt) {
|
||||
all: {
|
||||
src: [
|
||||
'src/**/*.js', 'playground/**/*.js',
|
||||
'!playground/main.browser.js',
|
||||
'!playground/home-main.browser.js',
|
||||
'!playground/rt-main.browser.js',
|
||||
'!playground/bundle/**',
|
||||
'!playground/tmp/**',
|
||||
'!playground/**/*.rt.js'
|
||||
@ -37,63 +36,9 @@ module.exports = function (grunt) {
|
||||
grunt: ['conf/tasks/test']
|
||||
},
|
||||
browserify: {
|
||||
// libs: {
|
||||
// files: {
|
||||
// 'playground/libs.browser.js': ['playground/libs.js']
|
||||
// },
|
||||
// options: {
|
||||
// alias: [
|
||||
// 'react:react/addons'
|
||||
// ],
|
||||
// shim: {
|
||||
// "react/addons": {
|
||||
// path: 'react/addons',
|
||||
// exports: 'React',
|
||||
// depends: {
|
||||
// lodash: '_'
|
||||
// }
|
||||
// },
|
||||
// "../src/reactTemplates": {
|
||||
// path: '../src/reactTemplates.js',
|
||||
// exports: 'reactTemplates',
|
||||
// depends: {
|
||||
// lodash: '_'
|
||||
// }
|
||||
// },
|
||||
// "lodash": {
|
||||
// path: 'lodash',
|
||||
// exports: '_'
|
||||
// },
|
||||
// "brace": {
|
||||
// path: 'brace',
|
||||
// exports: 'brace',
|
||||
// depends: {
|
||||
// lodash: '_'
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// },
|
||||
pg: {
|
||||
rt: {
|
||||
files: {
|
||||
'playground/main.browser.js': ['playground/main.js']
|
||||
},
|
||||
options: {
|
||||
transform: ['brfs'],
|
||||
alias: ['react:react/addons']
|
||||
// exclude:['react','react/addons','../src/reactTemplates','lodash','brace','brace/mode/javascript','brace/mode/html','brace/theme/solarized_light'],
|
||||
// external: [
|
||||
// 'react/addons',
|
||||
// '../src/reactTemplates',
|
||||
// 'lodash',
|
||||
// 'brace'
|
||||
// ]
|
||||
}
|
||||
},
|
||||
home: {
|
||||
files: {
|
||||
'playground/home-main.browser.js': ['playground/home-main.js']
|
||||
'playground/rt-main.browser.js': ['playground/rt-main.js']
|
||||
},
|
||||
options: {
|
||||
transform: ['brfs'],
|
||||
@ -121,15 +66,6 @@ module.exports = function (grunt) {
|
||||
options: {
|
||||
spawn: false
|
||||
}
|
||||
},
|
||||
playground: {
|
||||
files: [
|
||||
'playground/**/*.js', '!playground/*.browser.js'
|
||||
],
|
||||
tasks: ['browserify:home'], /*'browserify:pg', */
|
||||
options: {
|
||||
spawn: false
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -147,9 +83,8 @@ module.exports = function (grunt) {
|
||||
grunt.registerTask('rt', function () {
|
||||
var reactTemplates = require('./src/cli');
|
||||
var files = grunt.file.expand('playground/*.rt');
|
||||
var conf = {commonJS: true, force: true};
|
||||
conf._ = files;
|
||||
var ret = reactTemplates.executeOptions(conf);
|
||||
var conf = {common: false, force: true, _: files};
|
||||
var ret = reactTemplates.execute(conf);
|
||||
return ret === 0;
|
||||
});
|
||||
|
||||
|
19
fiddle.html
19
fiddle.html
@ -11,24 +11,21 @@
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
|
||||
<link rel="stylesheet" href="playground/css/fiddle.css"/>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
</div>
|
||||
<!--<script src="playground/bundle/reactTemplates.bundle.js"></script>-->
|
||||
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
|
||||
<script src="https://cdn.firebase.com/js/client/2.0.5/firebase.js"></script>
|
||||
<!--<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>-->
|
||||
<script src="playground/libs/ace-builds-1.1.8/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<!--<script src="https://cdn.firebase.com/js/client/2.0.5/firebase.js"></script>-->
|
||||
<!--<script src="http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.js"></script>-->
|
||||
<!--<script src="playground/libs.browser.js"></script>-->
|
||||
<script src="playground/main.browser.js"></script>
|
||||
<script type="application/javascript">
|
||||
initFiddle();
|
||||
</script>
|
||||
<script src="playground/rt-main.browser.js"></script>
|
||||
<script data-main="playground/fiddle-main.js" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.15/require.js"></script>
|
||||
<!--<script type="application/javascript">-->
|
||||
<!--initFiddle();-->
|
||||
<!--</script>-->
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
56
index.html
56
index.html
@ -117,57 +117,6 @@
|
||||
</section>
|
||||
<hr class="home-divider" />
|
||||
<section id="home-section" class="home-section">
|
||||
<!--<div id="examples">-->
|
||||
<!--<div class="example">-->
|
||||
<!--<h3>A Simple Component</h3>-->
|
||||
<!--<p>-->
|
||||
<!--React components implement a <code>render()</code> method that takes input data and-->
|
||||
<!--returns what to display. This example uses an XML-like syntax called-->
|
||||
<!--JSX. Input data that is passed into the component can be accessed by-->
|
||||
<!--<code>render()</code> via <code>this.props</code>.-->
|
||||
<!--</p>-->
|
||||
<!--<p>-->
|
||||
<!--<strong>JSX is optional and not required to use React.</strong> Try-->
|
||||
<!--clicking on "Compiled JS" to see the raw JavaScript code produced by-->
|
||||
<!--the JSX compiler.-->
|
||||
<!--</p>-->
|
||||
<!--<div id="helloExample"></div>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="example">-->
|
||||
<!--<h3>A Stateful Component</h3>-->
|
||||
<!--<p>-->
|
||||
<!--In addition to taking input data (accessed via <code>this.props</code>), a-->
|
||||
<!--component can maintain internal state data (accessed via <code>this.state</code>).-->
|
||||
<!--When a component's state data changes, the rendered markup will be-->
|
||||
<!--updated by re-invoking <code>render()</code>.-->
|
||||
<!--</p>-->
|
||||
<!--<div id="timerExample"></div>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="example">-->
|
||||
<!--<h3>An Application</h3>-->
|
||||
<!--<p>-->
|
||||
<!--Using <code>props</code> and <code>state</code>, we can put together a small Todo application.-->
|
||||
<!--This example uses <code>state</code> to track the current list of items as well as-->
|
||||
<!--the text that the user has entered. Although event handlers appear to be-->
|
||||
<!--rendered inline, they will be collected and implemented using event-->
|
||||
<!--delegation.-->
|
||||
<!--</p>-->
|
||||
<!--<div id="todoExample"></div>-->
|
||||
<!--</div>-->
|
||||
<!--<div class="example">-->
|
||||
<!--<h3>A Component Using External Plugins</h3>-->
|
||||
<!--<p>-->
|
||||
<!--React is flexible and provides hooks that allow you to interface with-->
|
||||
<!--other libraries and frameworks. This example uses Showdown, an external-->
|
||||
<!--Markdown library, to convert the textarea's value in real-time.-->
|
||||
<!--</p>-->
|
||||
<!--<div id="markdownExample"></div>-->
|
||||
<!--</div>-->
|
||||
<!--</div>-->
|
||||
<!--<script type="text/javascript" src="js/examples/hello.js"></script>-->
|
||||
<!--<script type="text/javascript" src="js/examples/timer.js"></script>-->
|
||||
<!--<script type="text/javascript" src="js/examples/todo.js"></script>-->
|
||||
<!--<script type="text/javascript" src="js/examples/markdown.js"></script>-->
|
||||
</section>
|
||||
<hr class="home-divider" />
|
||||
<section class="home-bottom-section">
|
||||
@ -193,9 +142,10 @@
|
||||
</div>
|
||||
<div id="fb-root"></div>
|
||||
|
||||
<!--<script src="playground/bundle/reactTemplates.bundle.js"></script>-->
|
||||
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
|
||||
<script src="playground/home-main.browser.js"></script>
|
||||
<script src="playground/libs/ace-builds-1.1.8/src-noconflict/ace.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="playground/rt-main.browser.js"></script>
|
||||
<script data-main="playground/home-main.js" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.15/require.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,14 +2,7 @@
|
||||
* Created by avim on 11/25/2014.
|
||||
*/
|
||||
'use strict';
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var brace = require('brace');
|
||||
|
||||
require('brace/mode/javascript');
|
||||
require('brace/mode/html');
|
||||
//require('brace/theme/monokai');
|
||||
require('brace/theme/solarized_light');
|
||||
define(['react', 'lodash'/*, 'ace'*/], function (React, _/*, ace*/) {
|
||||
|
||||
var editor = React.createClass({
|
||||
displayName: 'BraceEditor',
|
||||
@ -33,7 +26,7 @@ var editor = React.createClass({
|
||||
}
|
||||
},
|
||||
componentDidMount: function () {
|
||||
this.editor = brace.edit(this.state.editorId);
|
||||
this.editor = ace.edit(this.state.editorId);
|
||||
// this.editor.setTheme('ace/theme/monokai');
|
||||
this.editor.setTheme('ace/theme/solarized_light');
|
||||
if (this.props.mode !== 'html') {
|
||||
@ -64,4 +57,5 @@ var editor = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = editor;
|
||||
return editor;
|
||||
});
|
@ -1,12 +1,21 @@
|
||||
body {
|
||||
/*padding: 20px;*/
|
||||
font-family: "Helvetica", "Arial", "FreeSans", "Verdana", "Tahoma", "Lucida Sans", "Lucida Sans Unicode", "Luxi Sans", sans-serif;
|
||||
background: #f6f6f6 url(../img/initializing.png) 50% 50% no-repeat;
|
||||
overflow: hidden;
|
||||
/*background: #f6f6f6 url(../img/initializing.png) 50% 50% no-repeat;*/
|
||||
/*overflow: hidden;*/
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
html {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#container {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#header {
|
||||
@ -23,20 +32,26 @@ body {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.hiddenTab {
|
||||
/*width: 0;*/
|
||||
/*height: 0;*/
|
||||
#buttons-bar {
|
||||
padding-left: 40px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.fiddle {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.large-text-area {
|
||||
height: 400px;
|
||||
height: 90%;
|
||||
width: 100%;
|
||||
display: block;
|
||||
margin: 10px;
|
||||
}
|
||||
|
||||
.result-area {
|
||||
width: 50%;
|
||||
float: left;
|
||||
margin-top: 48px;
|
||||
display: table-cell;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.sample-view {
|
||||
@ -52,6 +67,13 @@ body {
|
||||
}
|
||||
|
||||
.playground {
|
||||
display: table;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: table-row;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.code-area {
|
||||
@ -59,8 +81,8 @@ body {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
/*height: 166px;*/
|
||||
display: inline-block;
|
||||
float: left;
|
||||
display: table-cell;
|
||||
/*float: left;*/
|
||||
/*margin: 2px;*/
|
||||
/*padding: 10px;*/
|
||||
}
|
||||
|
@ -1,35 +1,41 @@
|
||||
'use strict';
|
||||
var examplesTemplate = require('./examples.rt.js');
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var fs = require('fs');
|
||||
define(['lodash', 'react', './examples.rt',
|
||||
'text!./samples/hello.code', 'text!./samples/hello.rt',
|
||||
'text!./samples/todo.code', 'text!./samples/todo.rt',
|
||||
'text!./samples/rt-if.code', 'text!./samples/rt-if.rt',
|
||||
'text!./samples/rt-props.code', 'text!./samples/rt-props.rt',
|
||||
'text!./samples/rt-repeat.code', 'text!./samples/rt-repeat.rt',
|
||||
'text!./samples/weather.code', 'text!./samples/weather.rt'
|
||||
], function (_, React, examplesTemplate, helloCode, helloRT, todoCode, todoRT, rtIfCode, rtIfRT, rtPropsCode, rtPropsRT, rtRepeatCode, rtRepeatRT, weatherCode, weatherRT) {
|
||||
var samples = {
|
||||
hello: [helloCode, helloRT],
|
||||
todo: [todoCode, todoRT],
|
||||
props: [rtPropsCode, rtPropsRT],
|
||||
rtIf: [rtIfCode, rtIfRT],
|
||||
repeat: [rtRepeatCode, rtRepeatRT],
|
||||
weather: [weatherCode, weatherRT]
|
||||
};
|
||||
//samples = _.map(samples, function (tuple) {
|
||||
// return {templateProps: tuple[0], templateHTML: tuple[1]};
|
||||
//});
|
||||
Object.keys(samples).forEach(function (k) {
|
||||
samples[k] = {templateProps: samples[k][0], templateHTML: samples[k][1]};
|
||||
});
|
||||
|
||||
var helloCode = fs.readFileSync(__dirname + '/samples/hello.code').toString();
|
||||
var helloRT = fs.readFileSync(__dirname + '/samples/hello.rt').toString();
|
||||
var todoCode = fs.readFileSync(__dirname + '/samples/todo.code').toString();
|
||||
var todoRT = fs.readFileSync(__dirname + '/samples/todo.rt').toString();
|
||||
var Examples = React.createClass({
|
||||
displayName: 'Examples',
|
||||
mixins: [React.addons.LinkedStateMixin],
|
||||
|
||||
var samples = [
|
||||
[helloCode, helloRT],
|
||||
[todoCode, todoRT]
|
||||
];
|
||||
samples = _.map(samples, function (tuple) {
|
||||
return {templateProps: tuple[0], templateHTML: tuple[1]};
|
||||
getInitialState: function () {
|
||||
return {
|
||||
samples: samples
|
||||
};
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return examplesTemplate.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
return Examples;
|
||||
});
|
||||
|
||||
var Examples = React.createClass({
|
||||
displayName: 'Examples',
|
||||
mixins: [React.addons.LinkedStateMixin],
|
||||
|
||||
getInitialState: function () {
|
||||
return {
|
||||
samples: samples
|
||||
};
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return examplesTemplate.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Examples;
|
@ -5,39 +5,41 @@
|
||||
<p>
|
||||
Simple hello world html transformed into react javascript code
|
||||
</p>
|
||||
<playground id="helloExample" rt-props="this.state.samples[0]" direction="horizontal" codeVisible="{false}" style="display: block"></playground>
|
||||
<playground id="helloExample" rt-props="this.state.samples.hello" direction="horizontal" codeVisible="{false}"></playground>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h3>A Stateful Component</h3>
|
||||
<h3>This shows the use of rt-if</h3>
|
||||
<p>
|
||||
In addition to taking input data (accessed via <code>this.props</code>), a
|
||||
component can maintain internal state data (accessed via <code>this.state</code>).
|
||||
When a component's state data changes, the rendered markup will be
|
||||
updated by re-invoking <code>render()</code>.
|
||||
This shows the use of rt-if
|
||||
</p>
|
||||
<div id="timerExample"></div>
|
||||
<playground id="example2" rt-props="this.state.samples[1]" direction="horizontal" style="display: block"></playground>
|
||||
<playground id="ifExample" rt-props="this.state.samples.rtIf" direction="horizontal"></playground>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h3>An Application</h3>
|
||||
<h3>This shows the use of rt-repeat</h3>
|
||||
<p>
|
||||
Using <code>props</code> and <code>state</code>, we can put together a small Todo application.
|
||||
This example uses <code>state</code> to track the current list of items as well as
|
||||
the text that the user has entered. Although event handlers appear to be
|
||||
rendered inline, they will be collected and implemented using event
|
||||
delegation.
|
||||
This shows the use of rt-repeat, to show multiple items, and the use of rt-scope to create a reusable name for multiple calculations
|
||||
</p>
|
||||
<div id="todoExample"></div>
|
||||
<playground id="example3" direction="horizontal" style="display: block"></playground>
|
||||
<playground id="repeatExample" rt-props="this.state.samples.repeat" direction="horizontal"></playground>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h3>A Component Using External Plugins</h3>
|
||||
<h3>This shows the use of rt-props</h3>
|
||||
<p>
|
||||
React is flexible and provides hooks that allow you to interface with
|
||||
other libraries and frameworks. This example uses Showdown, an external
|
||||
Markdown library, to convert the textarea's value in real-time.
|
||||
This shows the use of rt-props. It is used in this component to pass all the original properties set on this component (except the ones used for the component logic - onClick and eventId) to the element that will actually represent this component
|
||||
</p>
|
||||
<div id="markdownExample"></div>
|
||||
<playground id="example4" direction="horizontal" style="display: block"></playground>
|
||||
<playground id="propsExample" rt-props="this.state.samples.props" direction="horizontal"></playground>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h3>Improved todo list</h3>
|
||||
<p>
|
||||
This shows the use of rt-props. It is used in this component to pass all the original properties set on this component (except the ones used for the component logic - onClick and eventId) to the element that will actually represent this component
|
||||
</p>
|
||||
<playground id="todoExample" rt-props="this.state.samples.todo" direction="horizontal"></playground>
|
||||
</div>
|
||||
<div class="example">
|
||||
<h3>Weather</h3>
|
||||
<p>
|
||||
This example shows working with async events, usage of regular event handler function pointers instead of lambda expression, and working with 2 way binding
|
||||
</p>
|
||||
<playground id="weatherExample" rt-props="this.state.samples.weather" direction="horizontal"></playground>
|
||||
</div>
|
||||
</div>
|
@ -1,24 +1,30 @@
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var playground = require('./playground');
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return React.DOM.div({ 'id': 'examples' }, React.DOM.div({ 'className': 'example' }, React.DOM.h3({}, 'Hello world in react templates'), React.DOM.p({}, '\n Simple hello world html transformed into react javascript code\n '), playground(_.merge({}, {
|
||||
'id': 'helloExample',
|
||||
'direction': 'horizontal',
|
||||
'codeVisible': false,
|
||||
'style': { display: 'block' }
|
||||
}, this.state.samples[0]))), React.DOM.div({ 'className': 'example' }, React.DOM.h3({}, 'A Stateful Component'), React.DOM.p({}, '\n In addition to taking input data (accessed via ', React.DOM.code({}, 'this.props'), '), a\n component can maintain internal state data (accessed via ', React.DOM.code({}, 'this.state'), ').\n When a component\'s state data changes, the rendered markup will be\n updated by re-invoking ', React.DOM.code({}, 'render()'), '.\n '), React.DOM.div({ 'id': 'timerExample' }), playground(_.merge({}, {
|
||||
'id': 'example2',
|
||||
'direction': 'horizontal',
|
||||
'style': { display: 'block' }
|
||||
}, this.state.samples[1]))), React.DOM.div({ 'className': 'example' }, React.DOM.h3({}, 'An Application'), React.DOM.p({}, '\n Using ', React.DOM.code({}, 'props'), ' and ', React.DOM.code({}, 'state'), ', we can put together a small Todo application.\n This example uses ', React.DOM.code({}, 'state'), ' to track the current list of items as well as\n the text that the user has entered. Although event handlers appear to be\n rendered inline, they will be collected and implemented using event\n delegation.\n '), React.DOM.div({ 'id': 'todoExample' }), playground({
|
||||
'id': 'example3',
|
||||
'direction': 'horizontal',
|
||||
'style': { display: 'block' }
|
||||
})), React.DOM.div({ 'className': 'example' }, React.DOM.h3({}, 'A Component Using External Plugins'), React.DOM.p({}, '\n React is flexible and provides hooks that allow you to interface with\n other libraries and frameworks. This example uses Showdown, an external\n Markdown library, to convert the textarea\'s value in real-time.\n '), React.DOM.div({ 'id': 'markdownExample' }), playground({
|
||||
'id': 'example4',
|
||||
'direction': 'horizontal',
|
||||
'style': { display: 'block' }
|
||||
})));
|
||||
};
|
||||
/*eslint new-cap:0,no-unused-vars:0*/
|
||||
define([
|
||||
'react/addons',
|
||||
'lodash',
|
||||
'./playground'
|
||||
], function (React, _, playground) {
|
||||
'use strict';
|
||||
return function () {
|
||||
return React.createElement('div', { 'id': 'examples' }, React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'Hello world in react templates'), React.createElement('p', {}, '\n Simple hello world html transformed into react javascript code\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'helloExample',
|
||||
'direction': 'horizontal',
|
||||
'codeVisible': false
|
||||
}, this.state.samples.hello))), React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'This shows the use of rt-if'), React.createElement('p', {}, '\n This shows the use of rt-if\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'ifExample',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples.rtIf))), React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'This shows the use of rt-repeat'), React.createElement('p', {}, '\n This shows the use of rt-repeat, to show multiple items, and the use of rt-scope to create a reusable name for multiple calculations\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'repeatExample',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples.repeat))), React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'This shows the use of rt-props'), React.createElement('p', {}, '\n This shows the use of rt-props. It is used in this component to pass all the original properties set on this component (except the ones used for the component logic - onClick and eventId) to the element that will actually represent this component\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'propsExample',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples.props))), React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'Improved todo list'), React.createElement('p', {}, '\n This shows the use of rt-props. It is used in this component to pass all the original properties set on this component (except the ones used for the component logic - onClick and eventId) to the element that will actually represent this component\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'todoExample',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples.todo))), React.createElement('div', { 'className': 'example' }, React.createElement('h3', {}, 'Weather'), React.createElement('p', {}, '\n This example shows working with async events, usage of regular event handler function pointers instead of lambda expression, and working with 2 way binding\n '), React.createElement(playground, _.merge({}, {
|
||||
'id': 'weatherExample',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples.weather))));
|
||||
};
|
||||
});
|
30
playground/fiddle-main.js
Normal file
30
playground/fiddle-main.js
Normal file
@ -0,0 +1,30 @@
|
||||
requirejs.config({
|
||||
// baseUrl: '/',
|
||||
paths: {
|
||||
lodash: 'http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash',
|
||||
jquery: 'http://code.jquery.com/jquery-1.11.0.min',
|
||||
firebase: 'https://cdn.firebase.com/js/client/2.0.5/firebase',
|
||||
react: 'http://fb.me/react-with-addons-0.12.1',
|
||||
//ace: '../ace-builds-1.1.8/src-min/ace',
|
||||
fiddle: './fiddle'
|
||||
//'react/addons': 'http://fb.me/react-with-addons-0.12.1'
|
||||
},
|
||||
shim: {
|
||||
lodash: { exports: '_' },
|
||||
firebase: { exports: 'Firebase' },
|
||||
//ace: { exports: 'ace' },
|
||||
jquery: { exports: '$' },
|
||||
react: { exports: 'React' }
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
'react/addons': 'react'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
requirejs(['jquery', 'react', 'fiddle'], function ($, React, fiddle) {
|
||||
'use strict';
|
||||
window.fiddle = React.render(fiddle(), document.getElementById('container'));
|
||||
});
|
||||
|
@ -1,58 +1,56 @@
|
||||
/**
|
||||
* Created by avim on 12/2/2014.
|
||||
*/
|
||||
'use strict';
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var fiddleTemplate = require('./fiddle.rt.js');
|
||||
|
||||
/*eslint global-strict:0, no-alert:0*/
|
||||
/*global Firebase:true,alert:true*/
|
||||
/*eslint no-alert:0*/
|
||||
define(['react', 'firebase', 'lodash', './fiddle.rt'], function (React, Firebase, _, fiddleTemplate) {
|
||||
'use strict';
|
||||
|
||||
function generateRandomId() {
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = _.random(0, 15);
|
||||
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
|
||||
var Fiddle = React.createClass({
|
||||
displayName: 'Fiddle',
|
||||
componentDidMount: function () {
|
||||
if (window.location.hash) {
|
||||
var newHash = window.location.hash.replace('#', '');
|
||||
var firebase = new Firebase('https://reacttemplates.firebaseio-demo.com/');
|
||||
firebase.child('fiddles').child(newHash).on('value', function (snapshot) {
|
||||
this.refs.playground.setState(snapshot.val());
|
||||
Firebase.goOffline();
|
||||
}.bind(this));
|
||||
} else {
|
||||
Firebase.goOffline();
|
||||
}
|
||||
},
|
||||
|
||||
save: function () {
|
||||
var newHash = generateRandomId();
|
||||
window.location.hash = newHash;
|
||||
Firebase.goOnline();
|
||||
|
||||
var playgroundState = this.refs.playground.state;
|
||||
var firebase = new Firebase('https://reacttemplates.firebaseio-demo.com/');
|
||||
firebase.child('fiddles').child(newHash).set(playgroundState, function () {
|
||||
Firebase.goOffline();
|
||||
alert('saved the fiddle, you can share your url');
|
||||
}.bind(this));
|
||||
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return fiddleTemplate.apply(this);
|
||||
function generateRandomId() {
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||
var r = _.random(0, 15);
|
||||
return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
}
|
||||
|
||||
var Fiddle = React.createClass({
|
||||
displayName: 'Fiddle',
|
||||
componentDidMount: function () {
|
||||
if (window.location.hash) {
|
||||
var newHash = window.location.hash.replace('#', '');
|
||||
var firebase = new Firebase('https://reacttemplates.firebaseio-demo.com/');
|
||||
firebase.child('fiddles').child(newHash).on('value', function (snapshot) {
|
||||
this.refs.playground.setState(snapshot.val());
|
||||
Firebase.goOffline();
|
||||
}.bind(this));
|
||||
} else {
|
||||
Firebase.goOffline();
|
||||
}
|
||||
},
|
||||
|
||||
save: function () {
|
||||
var newHash = generateRandomId();
|
||||
window.location.hash = newHash;
|
||||
Firebase.goOnline();
|
||||
|
||||
var playgroundState = this.refs.playground.state;
|
||||
var firebase = new Firebase('https://reacttemplates.firebaseio-demo.com/');
|
||||
firebase.child('fiddles').child(newHash).set(playgroundState, function () {
|
||||
Firebase.goOffline();
|
||||
alert('saved the fiddle, you can share your url');
|
||||
}.bind(this));
|
||||
|
||||
},
|
||||
|
||||
render: function () {
|
||||
return fiddleTemplate.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
return Fiddle;
|
||||
});
|
||||
|
||||
module.exports = Fiddle;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,19 +1,19 @@
|
||||
<!DOCTYPE rt playground="./playground.js">
|
||||
<div>
|
||||
<!DOCTYPE rt playground="./playground">
|
||||
<div class="fiddle">
|
||||
<div id="header">
|
||||
<div id="header-title">
|
||||
<img class="nav-logo" src="https://facebook.github.io/react/img/logo.svg" width="36" height="36" />
|
||||
RTFIddle
|
||||
RTFiddle
|
||||
</div>
|
||||
<div style="padding-left: 20px; display: inline-block">
|
||||
<div id="buttons-bar">
|
||||
<button class="btn" onClick="(evt)=>evt.preventDefault();this.save()">Save fiddle</button>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<!--<div>-->
|
||||
<!--<h1>React Templates fiddle</h1>-->
|
||||
<!--<h2>Play with react templates and save/share your results</h2>-->
|
||||
<!--<button class="btn btn-lg btn-primary" onClick="(evt)=>evt.preventDefault();this.save()">Save fiddle</button>-->
|
||||
<!--<br />-->
|
||||
<playground ref="playground" direction="vertical" fiddle="{true}" />
|
||||
</div>
|
||||
<playground ref="playground" direction="vertical" fiddle="{true}" />
|
||||
<!--</div>-->
|
||||
</div>
|
@ -1,31 +1,31 @@
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var playground = require('./playground.js');
|
||||
'use strict';
|
||||
function onClick1(evt) {
|
||||
evt.preventDefault();
|
||||
this.save();
|
||||
}
|
||||
module.exports = function () {
|
||||
return React.DOM.div({}, React.DOM.div({ 'id': 'header' }, React.DOM.div({ 'id': 'header-title' }, React.DOM.img({
|
||||
'className': 'nav-logo',
|
||||
'src': 'https://facebook.github.io/react/img/logo.svg',
|
||||
'width': '36',
|
||||
'height': '36'
|
||||
}), '\n RTFIddle\n '), React.DOM.div({
|
||||
'style': {
|
||||
paddingLeft: '20px',
|
||||
display: 'inline-block'
|
||||
}
|
||||
}, React.DOM.button({
|
||||
'className': 'btn',
|
||||
'onClick': onClick1.bind(this)
|
||||
}, 'Save fiddle'))), React.DOM.div({} /* <h1>React Templates fiddle</h1> */
|
||||
/* <h2>Play with react templates and save/share your results</h2> */
|
||||
/* <button class="btn btn-lg btn-primary" onClick="(evt)=>evt.preventDefault();this.save()">Save fiddle</button> */
|
||||
/* <br /> */, playground({
|
||||
'ref': 'playground',
|
||||
'direction': 'vertical',
|
||||
'fiddle': true
|
||||
})));
|
||||
};
|
||||
/*eslint new-cap:0,no-unused-vars:0*/
|
||||
define([
|
||||
'react/addons',
|
||||
'lodash',
|
||||
'./playground'
|
||||
], function (React, _, playground) {
|
||||
'use strict';
|
||||
function onClick1(evt) {
|
||||
evt.preventDefault();
|
||||
this.save();
|
||||
}
|
||||
return function () {
|
||||
return React.createElement('div', { 'className': 'fiddle' }, React.createElement('div', { 'id': 'header' }, React.createElement('div', { 'id': 'header-title' }, React.createElement('img', {
|
||||
'className': 'nav-logo',
|
||||
'src': 'https://facebook.github.io/react/img/logo.svg',
|
||||
'width': '36',
|
||||
'height': '36'
|
||||
}), '\n RTFiddle\n '), React.createElement('div', { 'id': 'buttons-bar' }, React.createElement('button', {
|
||||
'className': 'btn',
|
||||
'onClick': onClick1.bind(this)
|
||||
}, 'Save fiddle'))) /* <div> */
|
||||
/* <h1>React Templates fiddle</h1> */
|
||||
/* <h2>Play with react templates and save/share your results</h2> */
|
||||
/* <button class="btn btn-lg btn-primary" onClick="(evt)=>evt.preventDefault();this.save()">Save fiddle</button> */
|
||||
/* <br /> */, React.createElement(playground, {
|
||||
'ref': 'playground',
|
||||
'direction': 'vertical',
|
||||
'fiddle': true
|
||||
}) /* </div> */);
|
||||
};
|
||||
});
|
@ -1,38 +1,33 @@
|
||||
'use strict';
|
||||
/*eslint-env browser*/
|
||||
var reactTemplates = require('../src/reactTemplates');
|
||||
|
||||
var React = require('react/addons');
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
var html = '<div>hello</div>';
|
||||
var res = reactTemplates.convertTemplateToReact(html.trim());
|
||||
//console.log(res);
|
||||
|
||||
|
||||
var Examples = require('./examples.js');
|
||||
React.render(Examples(), document.getElementById('home-section'));
|
||||
|
||||
|
||||
/*
|
||||
function generateRandomId() {
|
||||
var d = new Date().getTime();
|
||||
var uuid = 'xxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = _.random(0,15);
|
||||
return (c=='x' ? r : (r&0x3|0x8)).toString(16);
|
||||
});
|
||||
return uuid;
|
||||
};
|
||||
|
||||
|
||||
if (window.location.hash) {
|
||||
var firebase = new Firebase('https://co5qowu8b6k.firebaseio-demo.com/'+window.location.hash);
|
||||
firebase.on('value',function (snapshot) {
|
||||
window.playground.setState(snapshot.val());
|
||||
firebase.goOffline();
|
||||
});
|
||||
}*/
|
||||
|
||||
requirejs.config({
|
||||
// baseUrl: '/',
|
||||
paths: {
|
||||
lodash: 'http://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash',
|
||||
jquery: 'http://code.jquery.com/jquery-1.11.0.min',
|
||||
firebase: 'https://cdn.firebase.com/js/client/2.0.5/firebase',
|
||||
react: 'http://fb.me/react-with-addons-0.12.1',
|
||||
text: 'libs/requirejs-plugins/text',
|
||||
json: 'libs/requirejs-plugins/json'
|
||||
//ace: '../ace-builds-1.1.8/src-min/ace',
|
||||
//'react/addons': 'http://fb.me/react-with-addons-0.12.1'
|
||||
},
|
||||
shim: {
|
||||
lodash: { exports: '_' },
|
||||
firebase: { exports: 'Firebase' },
|
||||
//ace: { exports: 'ace' },
|
||||
jquery: { exports: '$' },
|
||||
react: { exports: 'React' }
|
||||
},
|
||||
map: {
|
||||
'*': {
|
||||
'react/addons': 'react'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
requirejs(['jquery', 'react', './Examples'], function ($, React, Examples) {
|
||||
'use strict';
|
||||
//var Examples = require('./examples.js');
|
||||
React.render(Examples(), document.getElementById('home-section'));
|
||||
//window.fiddle = React.render(fiddle(), document.getElementById('container'));
|
||||
});
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var playGround = require('./PlayGround.js');
|
||||
'use strict';
|
||||
module.exports = function () {
|
||||
return React.DOM.div({}, React.DOM.h1({}, 'React Templates'), playGround(_.merge({}, {
|
||||
'ref': 'playground',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples[0])), playGround(_.merge({}, {
|
||||
'ref': 'playground',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples[1])));
|
||||
};
|
||||
/*eslint new-cap:0,no-unused-vars:0*/
|
||||
define([
|
||||
'react/addons',
|
||||
'lodash',
|
||||
'./PlayGround.js'
|
||||
], function (React, _, playGround) {
|
||||
'use strict';
|
||||
return function () {
|
||||
return React.createElement('div', {}, React.createElement('h1', {}, 'React Templates'), React.createElement(playGround, _.merge({}, {
|
||||
'ref': 'playground',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples[0])), React.createElement(playGround, _.merge({}, {
|
||||
'ref': 'playground',
|
||||
'direction': 'horizontal'
|
||||
}, this.state.samples[1])));
|
||||
};
|
||||
});
|
11
playground/libs/ace-builds-1.1.8/src-min/ace.js
Executable file
11
playground/libs/ace-builds-1.1.8/src-min/ace.js
Executable file
File diff suppressed because one or more lines are too long
1
playground/libs/ace-builds-1.1.8/src-min/mode-html.js
Executable file
1
playground/libs/ace-builds-1.1.8/src-min/mode-html.js
Executable file
File diff suppressed because one or more lines are too long
1
playground/libs/ace-builds-1.1.8/src-min/mode-javascript.js
Executable file
1
playground/libs/ace-builds-1.1.8/src-min/mode-javascript.js
Executable file
File diff suppressed because one or more lines are too long
1
playground/libs/ace-builds-1.1.8/src-min/mode-json.js
Executable file
1
playground/libs/ace-builds-1.1.8/src-min/mode-json.js
Executable file
File diff suppressed because one or more lines are too long
61
playground/libs/requirejs-plugins/json.js
Normal file
61
playground/libs/requirejs-plugins/json.js
Normal file
@ -0,0 +1,61 @@
|
||||
/** @license
|
||||
* RequireJS plugin for loading JSON files
|
||||
* - depends on Text plugin and it was HEAVILY "inspired" by it as well.
|
||||
* Author: Miller Medeiros
|
||||
* Version: 0.3.1 (2013/02/04)
|
||||
* Released under the MIT license
|
||||
*/
|
||||
define(['text'], function(text){
|
||||
|
||||
var CACHE_BUST_QUERY_PARAM = 'bust',
|
||||
CACHE_BUST_FLAG = '!bust',
|
||||
jsonParse = (typeof JSON !== 'undefined' && typeof JSON.parse === 'function')? JSON.parse : function(val){
|
||||
return eval('('+ val +')'); //quick and dirty
|
||||
},
|
||||
buildMap = {};
|
||||
|
||||
function cacheBust(url){
|
||||
url = url.replace(CACHE_BUST_FLAG, '');
|
||||
url += (url.indexOf('?') < 0)? '?' : '&';
|
||||
return url + CACHE_BUST_QUERY_PARAM +'='+ Math.round(2147483647 * Math.random());
|
||||
}
|
||||
|
||||
//API
|
||||
return {
|
||||
|
||||
load : function(name, req, onLoad, config) {
|
||||
if ( config.isBuild && (config.inlineJSON === false || name.indexOf(CACHE_BUST_QUERY_PARAM +'=') !== -1) ) {
|
||||
//avoid inlining cache busted JSON or if inlineJSON:false
|
||||
onLoad(null);
|
||||
} else {
|
||||
text.get(req.toUrl(name), function(data){
|
||||
if (config.isBuild) {
|
||||
buildMap[name] = data;
|
||||
onLoad(data);
|
||||
} else {
|
||||
onLoad(jsonParse(data));
|
||||
}
|
||||
},
|
||||
onLoad.error, {
|
||||
accept: 'application/json'
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
normalize : function (name, normalize) {
|
||||
//used normalize to avoid caching references to a "cache busted" request
|
||||
return (name.indexOf(CACHE_BUST_FLAG) === -1)? name : cacheBust(name);
|
||||
},
|
||||
|
||||
//write method based on RequireJS official text plugin by James Burke
|
||||
//https://github.com/jrburke/requirejs/blob/master/text.js
|
||||
write : function(pluginName, moduleName, write){
|
||||
if(moduleName in buildMap){
|
||||
var content = buildMap[moduleName];
|
||||
write('define("'+ pluginName +'!'+ moduleName +'", function(){ return '+ content +';});\n');
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
});
|
332
playground/libs/requirejs-plugins/text.js
Normal file
332
playground/libs/requirejs-plugins/text.js
Normal file
@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @license RequireJS text 2.0.5 Copyright (c) 2010-2012, The Dojo Foundation All Rights Reserved.
|
||||
* Available via the MIT or new BSD license.
|
||||
* see: http://github.com/requirejs/text for details
|
||||
*/
|
||||
/*jslint regexp: true */
|
||||
/*global require: false, XMLHttpRequest: false, ActiveXObject: false,
|
||||
define: false, window: false, process: false, Packages: false,
|
||||
java: false, location: false */
|
||||
|
||||
define(['module'], function (module) {
|
||||
'use strict';
|
||||
|
||||
var text, fs,
|
||||
progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'],
|
||||
xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im,
|
||||
bodyRegExp = /<body[^>]*>\s*([\s\S]+)\s*<\/body>/im,
|
||||
hasLocation = typeof location !== 'undefined' && location.href,
|
||||
defaultProtocol = hasLocation && location.protocol && location.protocol.replace(/\:/, ''),
|
||||
defaultHostName = hasLocation && location.hostname,
|
||||
defaultPort = hasLocation && (location.port || undefined),
|
||||
buildMap = [],
|
||||
masterConfig = (module.config && module.config()) || {};
|
||||
|
||||
text = {
|
||||
version: '2.0.5',
|
||||
|
||||
strip: function (content) {
|
||||
//Strips <?xml ...?> declarations so that external SVG and XML
|
||||
//documents can be added to a document without worry. Also, if the string
|
||||
//is an HTML document, only the part inside the body tag is returned.
|
||||
if (content) {
|
||||
content = content.replace(xmlRegExp, "");
|
||||
var matches = content.match(bodyRegExp);
|
||||
if (matches) {
|
||||
content = matches[1];
|
||||
}
|
||||
} else {
|
||||
content = "";
|
||||
}
|
||||
return content;
|
||||
},
|
||||
|
||||
jsEscape: function (content) {
|
||||
return content.replace(/(['\\])/g, '\\$1')
|
||||
.replace(/[\f]/g, "\\f")
|
||||
.replace(/[\b]/g, "\\b")
|
||||
.replace(/[\n]/g, "\\n")
|
||||
.replace(/[\t]/g, "\\t")
|
||||
.replace(/[\r]/g, "\\r")
|
||||
.replace(/[\u2028]/g, "\\u2028")
|
||||
.replace(/[\u2029]/g, "\\u2029");
|
||||
},
|
||||
|
||||
createXhr: masterConfig.createXhr || function () {
|
||||
//Would love to dump the ActiveX crap in here. Need IE 6 to die first.
|
||||
var xhr, i, progId;
|
||||
if (typeof XMLHttpRequest !== "undefined") {
|
||||
return new XMLHttpRequest();
|
||||
} else if (typeof ActiveXObject !== "undefined") {
|
||||
for (i = 0; i < 3; i += 1) {
|
||||
progId = progIds[i];
|
||||
try {
|
||||
xhr = new ActiveXObject(progId);
|
||||
} catch (e) {}
|
||||
|
||||
if (xhr) {
|
||||
progIds = [progId]; // so faster next time
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xhr;
|
||||
},
|
||||
|
||||
/**
|
||||
* Parses a resource name into its component parts. Resource names
|
||||
* look like: module/name.ext!strip, where the !strip part is
|
||||
* optional.
|
||||
* @param {String} name the resource name
|
||||
* @returns {Object} with properties "moduleName", "ext" and "strip"
|
||||
* where strip is a boolean.
|
||||
*/
|
||||
parseName: function (name) {
|
||||
var modName, ext, temp,
|
||||
strip = false,
|
||||
index = name.indexOf("."),
|
||||
isRelative = name.indexOf('./') === 0 ||
|
||||
name.indexOf('../') === 0;
|
||||
|
||||
if (index !== -1 && (!isRelative || index > 1)) {
|
||||
modName = name.substring(0, index);
|
||||
ext = name.substring(index + 1, name.length);
|
||||
} else {
|
||||
modName = name;
|
||||
}
|
||||
|
||||
temp = ext || modName;
|
||||
index = temp.indexOf("!");
|
||||
if (index !== -1) {
|
||||
//Pull off the strip arg.
|
||||
strip = temp.substring(index + 1) === "strip";
|
||||
temp = temp.substring(0, index);
|
||||
if (ext) {
|
||||
ext = temp;
|
||||
} else {
|
||||
modName = temp;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
moduleName: modName,
|
||||
ext: ext,
|
||||
strip: strip
|
||||
};
|
||||
},
|
||||
|
||||
xdRegExp: /^((\w+)\:)?\/\/([^\/\\]+)/,
|
||||
|
||||
/**
|
||||
* Is an URL on another domain. Only works for browser use, returns
|
||||
* false in non-browser environments. Only used to know if an
|
||||
* optimized .js version of a text resource should be loaded
|
||||
* instead.
|
||||
* @param {String} url
|
||||
* @returns Boolean
|
||||
*/
|
||||
useXhr: function (url, protocol, hostname, port) {
|
||||
var uProtocol, uHostName, uPort,
|
||||
match = text.xdRegExp.exec(url);
|
||||
if (!match) {
|
||||
return true;
|
||||
}
|
||||
uProtocol = match[2];
|
||||
uHostName = match[3];
|
||||
|
||||
uHostName = uHostName.split(':');
|
||||
uPort = uHostName[1];
|
||||
uHostName = uHostName[0];
|
||||
|
||||
return (!uProtocol || uProtocol === protocol) &&
|
||||
(!uHostName || uHostName.toLowerCase() === hostname.toLowerCase()) &&
|
||||
((!uPort && !uHostName) || uPort === port);
|
||||
},
|
||||
|
||||
finishLoad: function (name, strip, content, onLoad) {
|
||||
content = strip ? text.strip(content) : content;
|
||||
if (masterConfig.isBuild) {
|
||||
buildMap[name] = content;
|
||||
}
|
||||
onLoad(content);
|
||||
},
|
||||
|
||||
load: function (name, req, onLoad, config) {
|
||||
//Name has format: some.module.filext!strip
|
||||
//The strip part is optional.
|
||||
//if strip is present, then that means only get the string contents
|
||||
//inside a body tag in an HTML string. For XML/SVG content it means
|
||||
//removing the <?xml ...?> declarations so the content can be inserted
|
||||
//into the current doc without problems.
|
||||
|
||||
// Do not bother with the work if a build and text will
|
||||
// not be inlined.
|
||||
if (config.isBuild && !config.inlineText) {
|
||||
onLoad();
|
||||
return;
|
||||
}
|
||||
|
||||
masterConfig.isBuild = config.isBuild;
|
||||
|
||||
var parsed = text.parseName(name),
|
||||
nonStripName = parsed.moduleName +
|
||||
(parsed.ext ? '.' + parsed.ext : ''),
|
||||
url = req.toUrl(nonStripName),
|
||||
useXhr = (masterConfig.useXhr) ||
|
||||
text.useXhr;
|
||||
|
||||
//Load the text. Use XHR if possible and in a browser.
|
||||
if (!hasLocation || useXhr(url, defaultProtocol, defaultHostName, defaultPort)) {
|
||||
text.get(url, function (content) {
|
||||
text.finishLoad(name, parsed.strip, content, onLoad);
|
||||
}, function (err) {
|
||||
if (onLoad.error) {
|
||||
onLoad.error(err);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
//Need to fetch the resource across domains. Assume
|
||||
//the resource has been optimized into a JS module. Fetch
|
||||
//by the module name + extension, but do not include the
|
||||
//!strip part to avoid file system issues.
|
||||
req([nonStripName], function (content) {
|
||||
text.finishLoad(parsed.moduleName + '.' + parsed.ext,
|
||||
parsed.strip, content, onLoad);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
write: function (pluginName, moduleName, write, config) {
|
||||
if (buildMap.hasOwnProperty(moduleName)) {
|
||||
var content = text.jsEscape(buildMap[moduleName]);
|
||||
write.asModule(pluginName + "!" + moduleName,
|
||||
"define(function () { return '" +
|
||||
content +
|
||||
"';});\n");
|
||||
}
|
||||
},
|
||||
|
||||
writeFile: function (pluginName, moduleName, req, write, config) {
|
||||
var parsed = text.parseName(moduleName),
|
||||
extPart = parsed.ext ? '.' + parsed.ext : '',
|
||||
nonStripName = parsed.moduleName + extPart,
|
||||
//Use a '.js' file name so that it indicates it is a
|
||||
//script that can be loaded across domains.
|
||||
fileName = req.toUrl(parsed.moduleName + extPart) + '.js';
|
||||
|
||||
//Leverage own load() method to load plugin value, but only
|
||||
//write out values that do not have the strip argument,
|
||||
//to avoid any potential issues with ! in file names.
|
||||
text.load(nonStripName, req, function (value) {
|
||||
//Use own write() method to construct full module value.
|
||||
//But need to create shell that translates writeFile's
|
||||
//write() to the right interface.
|
||||
var textWrite = function (contents) {
|
||||
return write(fileName, contents);
|
||||
};
|
||||
textWrite.asModule = function (moduleName, contents) {
|
||||
return write.asModule(moduleName, fileName, contents);
|
||||
};
|
||||
|
||||
text.write(pluginName, nonStripName, textWrite, config);
|
||||
}, config);
|
||||
}
|
||||
};
|
||||
|
||||
if (masterConfig.env === 'node' || (!masterConfig.env &&
|
||||
typeof process !== "undefined" &&
|
||||
process.versions &&
|
||||
!!process.versions.node)) {
|
||||
//Using special require.nodeRequire, something added by r.js.
|
||||
fs = require.nodeRequire('fs');
|
||||
|
||||
text.get = function (url, callback) {
|
||||
var file = fs.readFileSync(url, 'utf8');
|
||||
//Remove BOM (Byte Mark Order) from utf8 files if it is there.
|
||||
if (file.indexOf('\uFEFF') === 0) {
|
||||
file = file.substring(1);
|
||||
}
|
||||
callback(file);
|
||||
};
|
||||
} else if (masterConfig.env === 'xhr' || (!masterConfig.env &&
|
||||
text.createXhr())) {
|
||||
text.get = function (url, callback, errback, headers) {
|
||||
var xhr = text.createXhr(), header;
|
||||
xhr.open('GET', url, true);
|
||||
|
||||
//Allow plugins direct access to xhr headers
|
||||
if (headers) {
|
||||
for (header in headers) {
|
||||
if (headers.hasOwnProperty(header)) {
|
||||
xhr.setRequestHeader(header.toLowerCase(), headers[header]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Allow overrides specified in config
|
||||
if (masterConfig.onXhr) {
|
||||
masterConfig.onXhr(xhr, url);
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function (evt) {
|
||||
var status, err;
|
||||
//Do not explicitly handle errors, those should be
|
||||
//visible via console output in the browser.
|
||||
if (xhr.readyState === 4) {
|
||||
status = xhr.status;
|
||||
if (status > 399 && status < 600) {
|
||||
//An http 4xx or 5xx error. Signal an error.
|
||||
err = new Error(url + ' HTTP status: ' + status);
|
||||
err.xhr = xhr;
|
||||
errback(err);
|
||||
} else {
|
||||
callback(xhr.responseText);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
};
|
||||
} else if (masterConfig.env === 'rhino' || (!masterConfig.env &&
|
||||
typeof Packages !== 'undefined' && typeof java !== 'undefined')) {
|
||||
//Why Java, why is this so awkward?
|
||||
text.get = function (url, callback) {
|
||||
var stringBuffer, line,
|
||||
encoding = "utf-8",
|
||||
file = new java.io.File(url),
|
||||
lineSeparator = java.lang.System.getProperty("line.separator"),
|
||||
input = new java.io.BufferedReader(new java.io.InputStreamReader(new java.io.FileInputStream(file), encoding)),
|
||||
content = '';
|
||||
try {
|
||||
stringBuffer = new java.lang.StringBuffer();
|
||||
line = input.readLine();
|
||||
|
||||
// Byte Order Mark (BOM) - The Unicode Standard, version 3.0, page 324
|
||||
// http://www.unicode.org/faq/utf_bom.html
|
||||
|
||||
// Note that when we use utf-8, the BOM should appear as "EF BB BF", but it doesn't due to this bug in the JDK:
|
||||
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
|
||||
if (line && line.length() && line.charAt(0) === 0xfeff) {
|
||||
// Eat the BOM, since we've already found the encoding on this file,
|
||||
// and we plan to concatenating this buffer with others; the BOM should
|
||||
// only appear at the top of a file.
|
||||
line = line.substring(1);
|
||||
}
|
||||
|
||||
stringBuffer.append(line);
|
||||
|
||||
while ((line = input.readLine()) !== null) {
|
||||
stringBuffer.append(lineSeparator);
|
||||
stringBuffer.append(line);
|
||||
}
|
||||
//Make sure we return a JavaScript string and not a Java string.
|
||||
content = String(stringBuffer.toString()); //String
|
||||
} finally {
|
||||
input.close();
|
||||
}
|
||||
callback(content);
|
||||
};
|
||||
}
|
||||
|
||||
return text;
|
||||
});
|
File diff suppressed because one or more lines are too long
@ -1,30 +1,34 @@
|
||||
<!DOCTYPE rt CodeEditor="./aceEditor">
|
||||
<!--suppress ALL -->
|
||||
<div class="playground">
|
||||
<div class="code-area">
|
||||
<CodeEditor 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 class="row">
|
||||
<div class="code-area">
|
||||
<CodeEditor 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 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})" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-area">
|
||||
<CodeEditor 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})" />
|
||||
<div class="row">
|
||||
<div class="code-area">
|
||||
<CodeEditor class="large-text-area" style="border:1px solid black;"
|
||||
value="{this.templateSource}"
|
||||
mode="javascript"
|
||||
readOnly="{true}" />
|
||||
</div>
|
||||
<div key="result-area" class="result-area well">
|
||||
<h2>Preview:</h2>
|
||||
<form class="sample-view" onSubmit="(e) => e.preventDefault();">
|
||||
<this.sample key="sample">
|
||||
</this.sample>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="code-area">
|
||||
<CodeEditor class="large-text-area" style="border:1px solid black;"
|
||||
value="{this.templateSource}"
|
||||
mode="javascript"
|
||||
readOnly="{true}" />
|
||||
</div>
|
||||
<div key="result-area" class="result-area">
|
||||
<h2>Preview:</h2>
|
||||
<form class="sample-view" onSubmit="(e) => e.preventDefault();">
|
||||
<this.sample key="sample">
|
||||
</this.sample>
|
||||
</form>
|
||||
</div>
|
||||
<br style="clear:both">
|
||||
<!--<br style="clear:both">-->
|
||||
</div>
|
||||
|
@ -1,40 +1,44 @@
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var CodeEditor = require('./aceEditor');
|
||||
'use strict';
|
||||
function onChange1(evt) {
|
||||
this.setState({ 'templateHTML': evt.target.value });
|
||||
}
|
||||
function onChange2(evt) {
|
||||
this.setState({ 'templateProps': evt.target.value });
|
||||
}
|
||||
function onSubmit3(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
module.exports = function () {
|
||||
return React.DOM.div({ 'className': 'playground' }, React.DOM.div({ 'className': 'code-area' }, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateHTML,
|
||||
'mode': 'html',
|
||||
'onChange': onChange1.bind(this)
|
||||
})), React.DOM.div({ 'className': 'code-area' }, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateProps,
|
||||
'mode': 'javascript',
|
||||
'onChange': onChange2.bind(this)
|
||||
})), React.DOM.div({ 'className': 'code-area' }, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: '1px solid black' },
|
||||
'value': this.templateSource,
|
||||
'mode': 'javascript',
|
||||
'readOnly': true
|
||||
})), React.DOM.div({
|
||||
'key': 'result-area',
|
||||
'className': 'result-area'
|
||||
}, React.DOM.h2({}, 'Preview:'), React.DOM.form({
|
||||
'className': 'sample-view',
|
||||
'onSubmit': onSubmit3.bind(this)
|
||||
}, this.sample({ 'key': 'sample' }))), React.DOM.br({ 'style': { clear: 'both' } }));
|
||||
};
|
||||
/*eslint new-cap:0,no-unused-vars:0*/
|
||||
define([
|
||||
'react/addons',
|
||||
'lodash',
|
||||
'./aceEditor'
|
||||
], function (React, _, CodeEditor) {
|
||||
'use strict';
|
||||
function onChange1(evt) {
|
||||
this.setState({ 'templateHTML': evt.target.value });
|
||||
}
|
||||
function onChange2(evt) {
|
||||
this.setState({ 'templateProps': evt.target.value });
|
||||
}
|
||||
function onSubmit3(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return function () {
|
||||
return React.createElement('div', { 'className': 'playground' }, React.createElement('div', { 'className': 'row' }, React.createElement('div', { 'className': 'code-area' }, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateHTML,
|
||||
'mode': 'html',
|
||||
'onChange': onChange1.bind(this)
|
||||
})), React.createElement('div', { 'className': 'code-area' }, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateProps,
|
||||
'mode': 'javascript',
|
||||
'onChange': onChange2.bind(this)
|
||||
}))), React.createElement('div', { 'className': 'row' }, React.createElement('div', { 'className': 'code-area' }, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: '1px solid black' },
|
||||
'value': this.templateSource,
|
||||
'mode': 'javascript',
|
||||
'readOnly': true
|
||||
})), React.createElement('div', {
|
||||
'key': 'result-area',
|
||||
'className': 'result-area well'
|
||||
}, React.createElement('h2', {}, 'Preview:'), React.createElement('form', {
|
||||
'className': 'sample-view',
|
||||
'onSubmit': onSubmit3.bind(this)
|
||||
}, React.createElement(this.sample, { 'key': 'sample' })))) /* <br style="clear:both"> */);
|
||||
};
|
||||
});
|
@ -1,127 +1,124 @@
|
||||
'use strict';
|
||||
/*eslint-env browser*/
|
||||
var reactTemplates = require('../src/reactTemplates');
|
||||
var playgroundTemplate = require('./playground.rt.js');
|
||||
var pgFiddleTemplate = require('./playground-fiddle.rt.js');
|
||||
|
||||
var React = require('react/addons');
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
function emptyFunc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
function generateTemplateSource(html) {
|
||||
var code = null;
|
||||
try {
|
||||
code = reactTemplates.convertTemplateToReact(html.trim().replace(/\r/g, ''));
|
||||
} catch (e) {
|
||||
define(['react', 'lodash', './playground-fiddle.rt', './playground.rt'], function (React, _, pgFiddleTemplate, playgroundTemplate) {
|
||||
function emptyFunc() {
|
||||
return null;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
function generateTemplateFunction(code) {
|
||||
try {
|
||||
var defineMap = {'react/addons': React, lodash: _};
|
||||
var define = function (requirementsNames, content) {
|
||||
var requirements = _.map(requirementsNames, function (reqName) {
|
||||
return defineMap[reqName];
|
||||
});
|
||||
return content.apply(this, requirements);
|
||||
};
|
||||
/*eslint no-eval:0*/
|
||||
var res = eval(code);
|
||||
return res;
|
||||
} catch (e) {
|
||||
return emptyFunc;
|
||||
}
|
||||
}
|
||||
|
||||
function generateRenderFunc(renderFunc) {
|
||||
return function() {
|
||||
var res = null;
|
||||
function generateTemplateSource(html) {
|
||||
var code = null;
|
||||
try {
|
||||
res = renderFunc.apply(this);
|
||||
code = window.reactTemplates.convertTemplateToReact(html.trim().replace(/\r/g, ''));
|
||||
} catch (e) {
|
||||
res = React.DOM.div.apply(this, [{style: {color: 'red'}}, 'Exception:' + e.message]);
|
||||
}
|
||||
return React.DOM.div.apply(this, _.flatten([
|
||||
{key: 'result'},
|
||||
res
|
||||
]));
|
||||
};
|
||||
}
|
||||
var z = {getInitialState: function() {return {name: 'reactTemplates'};}};
|
||||
var templateHTML = '<div>\n' +
|
||||
'Have {_.filter(this.state.todos, {done:true}).length} todos done,\n' +
|
||||
'and {_.filter(this.state.todos, {done:false}).length} not done\n' +
|
||||
' <br/>\n' +
|
||||
' <div rt-repeat="todo in this.state.todos" key="{todo.key}">\n' +
|
||||
' <button onClick="()=>this.remove(todo)">x</button>\n' +
|
||||
' <input type="checkbox" checked="{todo.done}" onChange="()=>this.toggleChecked(todoIndex)"/>\n' +
|
||||
' <span style="text-decoration: {todo.done ? \'line-through\': \'none\'}">{todo.value}</span>\n' +
|
||||
' </div>\n' +
|
||||
' <input key="myinput" type="text" onKeyDown="(e) => if (e.keyCode == 13) { e.preventDefault(); this.add(); }" valueLink="{this.linkState(\'edited\')}"/>\n' +
|
||||
' <button onClick="()=>this.add()">Add</button><br/>\n' +
|
||||
' <button onClick="()=>this.clearDone()">Clear done</button>\n' +
|
||||
'</div>';
|
||||
var templateProps = "{\n mixins: [React.addons.LinkedStateMixin],\n getInitialState: function () {\n return {edited: '', todos: [], counter: 0};\n },\n add: function () {\n if (this.state.edited.trim().length === 0) {\n return;\n }\n var newTodo = {value: this.state.edited, done: false, key: this.state.counter};\n this.setState({todos: this.state.todos.concat(newTodo), edited: '', counter: this.state.counter + 1});\n },\n remove: function (todo) {\n this.setState({todos: _.reject(this.state.todos, todo)});\n },\n toggleChecked: function (index) {\n var todos = _.cloneDeep(this.state.todos);\n todos[index].done = !todos[index].done;\n this.setState({todos: todos});\n },\n clearDone: function () {\n this.setState({todos: _.filter(this.state.todos, {done: false})});\n }\n}";
|
||||
return code;
|
||||
}
|
||||
|
||||
var Playground = React.createClass({
|
||||
|
||||
displayName: 'Playground',
|
||||
mixins: [React.addons.LinkedStateMixin],
|
||||
propTypes: {
|
||||
direction: React.PropTypes.string,
|
||||
codeVisible: React.PropTypes.bool,
|
||||
fiddle: React.PropTypes.bool
|
||||
},
|
||||
getDefaultProps: function() {
|
||||
return {
|
||||
direction: 'horizontal', //vertical
|
||||
codeVisible: true,
|
||||
fiddle: false
|
||||
};
|
||||
},
|
||||
updateSample: function (state) {
|
||||
this.templateSource = generateTemplateSource(state.templateHTML);
|
||||
this.sampleFunc = generateTemplateFunction(this.templateSource);
|
||||
this.validHTML = this.sampleFunc !== emptyFunc;
|
||||
this.sampleRender = generateRenderFunc(this.sampleFunc);
|
||||
var classBase = {};
|
||||
function generateTemplateFunction(code) {
|
||||
try {
|
||||
this.validProps = true;
|
||||
console.log(state.templateProps);
|
||||
classBase = eval('(' + state.templateProps + ')');
|
||||
if (!_.isObject(classBase)) {
|
||||
throw 'failed to eval';
|
||||
var defineMap = {'react/addons': React, lodash: _};
|
||||
var define = function (requirementsNames, content) {
|
||||
var requirements = _.map(requirementsNames, function (reqName) {
|
||||
return defineMap[reqName];
|
||||
});
|
||||
return content.apply(this, requirements);
|
||||
};
|
||||
/*eslint no-eval:0*/
|
||||
var res = eval(code);
|
||||
return res;
|
||||
} catch (e) {
|
||||
return emptyFunc;
|
||||
}
|
||||
}
|
||||
|
||||
function generateRenderFunc(renderFunc) {
|
||||
return function () {
|
||||
var res = null;
|
||||
try {
|
||||
res = renderFunc.apply(this);
|
||||
} catch (e) {
|
||||
res = React.DOM.div.apply(this, [{style: {color: 'red'}}, 'Exception:' + e.message]);
|
||||
}
|
||||
} catch (e) {
|
||||
classBase = {};
|
||||
this.validProps = false;
|
||||
}
|
||||
classBase.render = this.sampleRender;
|
||||
this.sample = React.createFactory(React.createClass(classBase));
|
||||
},
|
||||
getInitialState: function () {
|
||||
var currentState = {
|
||||
templateHTML: this.props.templateHTML || templateHTML,
|
||||
templateProps: this.props.templateProps || templateProps
|
||||
return React.DOM.div.apply(this, _.flatten([
|
||||
{key: 'result'},
|
||||
res
|
||||
]));
|
||||
};
|
||||
this.updateSample(currentState);
|
||||
return currentState;
|
||||
},
|
||||
componentWillUpdate: function (nextProps, nextState) {
|
||||
if (nextState.templateHTML !== this.state.templateHTML || nextState.templateProps !== this.state.templateProps) {
|
||||
this.updateSample(nextState);
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var template = this.props.fiddle ? pgFiddleTemplate : playgroundTemplate;
|
||||
return template.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Playground;
|
||||
//var z = {getInitialState: function () {return {name: 'reactTemplates'};}};
|
||||
//var templateHTML = '<div>\n' +
|
||||
// 'Have {_.filter(this.state.todos, {done:true}).length} todos done,\n' +
|
||||
// 'and {_.filter(this.state.todos, {done:false}).length} not done\n' +
|
||||
// ' <br/>\n' +
|
||||
// ' <div rt-repeat="todo in this.state.todos" key="{todo.key}">\n' +
|
||||
// ' <button onClick="()=>this.remove(todo)">x</button>\n' +
|
||||
// ' <input type="checkbox" checked="{todo.done}" onChange="()=>this.toggleChecked(todoIndex)"/>\n' +
|
||||
// ' <span style="text-decoration: {todo.done ? \'line-through\': \'none\'}">{todo.value}</span>\n' +
|
||||
// ' </div>\n' +
|
||||
// ' <input key="myinput" type="text" onKeyDown="(e) => if (e.keyCode == 13) { e.preventDefault(); this.add(); }" valueLink="{this.linkState(\'edited\')}"/>\n' +
|
||||
// ' <button onClick="()=>this.add()">Add</button><br/>\n' +
|
||||
// ' <button onClick="()=>this.clearDone()">Clear done</button>\n' +
|
||||
// '</div>';
|
||||
var templateHTML = "<div></div>";
|
||||
var templateProps = "{}";
|
||||
//var templateProps = "{\n mixins: [React.addons.LinkedStateMixin],\n getInitialState: function () {\n return {edited: '', todos: [], counter: 0};\n },\n add: function () {\n if (this.state.edited.trim().length === 0) {\n return;\n }\n var newTodo = {value: this.state.edited, done: false, key: this.state.counter};\n this.setState({todos: this.state.todos.concat(newTodo), edited: '', counter: this.state.counter + 1});\n },\n remove: function (todo) {\n this.setState({todos: _.reject(this.state.todos, todo)});\n },\n toggleChecked: function (index) {\n var todos = _.cloneDeep(this.state.todos);\n todos[index].done = !todos[index].done;\n this.setState({todos: todos});\n },\n clearDone: function () {\n this.setState({todos: _.filter(this.state.todos, {done: false})});\n }\n}";
|
||||
|
||||
var Playground = React.createClass({
|
||||
|
||||
displayName: 'Playground',
|
||||
mixins: [React.addons.LinkedStateMixin],
|
||||
propTypes: {
|
||||
direction: React.PropTypes.string,
|
||||
codeVisible: React.PropTypes.bool,
|
||||
fiddle: React.PropTypes.bool
|
||||
},
|
||||
getDefaultProps: function () {
|
||||
return {
|
||||
direction: 'horizontal', //vertical
|
||||
codeVisible: true,
|
||||
fiddle: false
|
||||
};
|
||||
},
|
||||
updateSample: function (state) {
|
||||
this.templateSource = generateTemplateSource(state.templateHTML);
|
||||
this.sampleFunc = generateTemplateFunction(this.templateSource);
|
||||
this.validHTML = this.sampleFunc !== emptyFunc;
|
||||
this.sampleRender = generateRenderFunc(this.sampleFunc);
|
||||
var classBase = {};
|
||||
try {
|
||||
this.validProps = true;
|
||||
console.log(state.templateProps);
|
||||
classBase = eval('(' + state.templateProps + ')');
|
||||
if (!_.isObject(classBase)) {
|
||||
throw 'failed to eval';
|
||||
}
|
||||
} catch (e) {
|
||||
classBase = {};
|
||||
this.validProps = false;
|
||||
}
|
||||
classBase.render = this.sampleRender;
|
||||
this.sample = React.createFactory(React.createClass(classBase));
|
||||
},
|
||||
getInitialState: function () {
|
||||
var currentState = {
|
||||
templateHTML: this.props.templateHTML || templateHTML,
|
||||
templateProps: this.props.templateProps || templateProps
|
||||
};
|
||||
this.updateSample(currentState);
|
||||
return currentState;
|
||||
},
|
||||
componentWillUpdate: function (nextProps, nextState) {
|
||||
if (nextState.templateHTML !== this.state.templateHTML || nextState.templateProps !== this.state.templateProps) {
|
||||
this.updateSample(nextState);
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var template = this.props.fiddle ? pgFiddleTemplate : playgroundTemplate;
|
||||
return template.apply(this);
|
||||
}
|
||||
});
|
||||
|
||||
return Playground;
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!DOCTYPE rt CodeEditor="./aceEditor">
|
||||
<div>
|
||||
<div class="playground">
|
||||
<div id="{this.props.id}-myTab" role="tabpanel" class="code-area {(this.props.direction === 'horizontal' && 'horizontal') ||'vertical'}">
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
|
@ -1,78 +1,82 @@
|
||||
var React = require('react/addons');
|
||||
var _ = require('lodash');
|
||||
var CodeEditor = require('./aceEditor');
|
||||
'use strict';
|
||||
function onChange1(evt) {
|
||||
this.setState({ 'templateHTML': evt.target.value });
|
||||
}
|
||||
function onChange2(evt) {
|
||||
this.setState({ 'templateProps': evt.target.value });
|
||||
}
|
||||
function onSubmit3(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
module.exports = function () {
|
||||
return React.DOM.div({}, React.DOM.div({
|
||||
'id': this.props.id + '-myTab',
|
||||
'role': 'tabpanel',
|
||||
'className': 'code-area ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical')
|
||||
} /* Nav tabs */, React.DOM.ul({
|
||||
'className': 'nav nav-pills',
|
||||
'role': 'tablist'
|
||||
}, React.DOM.li({
|
||||
'role': 'presentation',
|
||||
'className': 'active'
|
||||
}, React.DOM.a({
|
||||
'href': '#' + this.props.id + '-template',
|
||||
'aria-controls': 'template',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Template')), this.props.codeVisible ? React.DOM.li({ 'role': 'presentation' }, React.DOM.a({
|
||||
'href': '#' + this.props.id + '-classCode',
|
||||
'aria-controls': 'classCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Class')) : null, React.DOM.li({ 'role': 'presentation' }, React.DOM.a({
|
||||
'href': '#' + this.props.id + '-generatedCode',
|
||||
'aria-controls': 'generatedCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Generated code'))) /* Tab panes */, React.DOM.div({ 'className': 'tab-content' }, React.DOM.div({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane active',
|
||||
'id': this.props.id + '-template'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateHTML,
|
||||
'mode': 'html',
|
||||
'onChange': onChange1.bind(this)
|
||||
})), this.props.codeVisible ? React.DOM.div({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': this.props.id + '-classCode'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateProps,
|
||||
'mode': 'javascript',
|
||||
'onChange': onChange2.bind(this)
|
||||
})) : null, React.DOM.div({
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': this.props.id + '-generatedCode'
|
||||
}, CodeEditor({
|
||||
'className': 'large-text-area',
|
||||
'style': { border: '1px solid black' },
|
||||
'value': this.templateSource,
|
||||
'mode': 'javascript',
|
||||
'readOnly': true
|
||||
})))), React.DOM.div({
|
||||
'key': 'result-area',
|
||||
'className': 'result-area well ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical'),
|
||||
'style': { marginTop: '48px' }
|
||||
}, React.DOM.h2({}, 'Preview:'), React.DOM.form({
|
||||
'className': 'sample-view',
|
||||
'onSubmit': onSubmit3.bind(this)
|
||||
}, this.sample({ 'key': 'sample' }))), React.DOM.br({ 'style': { clear: 'both' } }));
|
||||
};
|
||||
/*eslint new-cap:0,no-unused-vars:0*/
|
||||
define([
|
||||
'react/addons',
|
||||
'lodash',
|
||||
'./aceEditor'
|
||||
], function (React, _, CodeEditor) {
|
||||
'use strict';
|
||||
function onChange1(evt) {
|
||||
this.setState({ 'templateHTML': evt.target.value });
|
||||
}
|
||||
function onChange2(evt) {
|
||||
this.setState({ 'templateProps': evt.target.value });
|
||||
}
|
||||
function onSubmit3(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
return function () {
|
||||
return React.createElement('div', { 'className': 'playground' }, React.createElement('div', {
|
||||
'id': this.props.id + '-myTab',
|
||||
'role': 'tabpanel',
|
||||
'className': 'code-area ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical')
|
||||
} /* Nav tabs */, React.createElement('ul', {
|
||||
'className': 'nav nav-pills',
|
||||
'role': 'tablist'
|
||||
}, React.createElement('li', {
|
||||
'role': 'presentation',
|
||||
'className': 'active'
|
||||
}, React.createElement('a', {
|
||||
'href': '#' + this.props.id + '-template',
|
||||
'aria-controls': 'template',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Template')), this.props.codeVisible ? React.createElement('li', { 'role': 'presentation' }, React.createElement('a', {
|
||||
'href': '#' + this.props.id + '-classCode',
|
||||
'aria-controls': 'classCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Class')) : null, React.createElement('li', { 'role': 'presentation' }, React.createElement('a', {
|
||||
'href': '#' + this.props.id + '-generatedCode',
|
||||
'aria-controls': 'generatedCode',
|
||||
'role': 'tab',
|
||||
'data-toggle': 'tab'
|
||||
}, 'Generated code'))) /* Tab panes */, React.createElement('div', { 'className': 'tab-content' }, React.createElement('div', {
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane active',
|
||||
'id': this.props.id + '-template'
|
||||
}, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validHTML ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateHTML,
|
||||
'mode': 'html',
|
||||
'onChange': onChange1.bind(this)
|
||||
})), this.props.codeVisible ? React.createElement('div', {
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': this.props.id + '-classCode'
|
||||
}, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: this.validProps ? '1px solid black' : '2px solid red' },
|
||||
'value': this.state.templateProps,
|
||||
'mode': 'javascript',
|
||||
'onChange': onChange2.bind(this)
|
||||
})) : null, React.createElement('div', {
|
||||
'role': 'tabpanel',
|
||||
'className': 'tab-pane',
|
||||
'id': this.props.id + '-generatedCode'
|
||||
}, React.createElement(CodeEditor, {
|
||||
'className': 'large-text-area',
|
||||
'style': { border: '1px solid black' },
|
||||
'value': this.templateSource,
|
||||
'mode': 'javascript',
|
||||
'readOnly': true
|
||||
})))), React.createElement('div', {
|
||||
'key': 'result-area',
|
||||
'className': 'result-area well ' + (this.props.direction === 'horizontal' && 'horizontal' || 'vertical'),
|
||||
'style': { marginTop: '48px' }
|
||||
}, React.createElement('h2', {}, 'Preview:'), React.createElement('form', {
|
||||
'className': 'sample-view',
|
||||
'onSubmit': onSubmit3.bind(this)
|
||||
}, React.createElement(this.sample, { 'key': 'sample' }))), React.createElement('br', { 'style': { clear: 'both' } }));
|
||||
};
|
||||
});
|
File diff suppressed because one or more lines are too long
9
playground/rt-main.js
Normal file
9
playground/rt-main.js
Normal file
@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
/*eslint-env browser*/
|
||||
/*var _ = */require('lodash');
|
||||
var reactTemplates = require('../src/reactTemplates');
|
||||
window.reactTemplates = reactTemplates;
|
||||
|
||||
|
||||
|
||||
|
@ -1,13 +1,12 @@
|
||||
{
|
||||
mixins: [React.addons.LinkedStateMixin],
|
||||
getInitialState: function () {
|
||||
return {
|
||||
edited: '', todos: [], counter: 0};
|
||||
getInitialState: function () {
|
||||
return {edited: '', todos: [], counter: 0};
|
||||
},
|
||||
add: function () {
|
||||
if (this.state.edited.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
if (this.state.edited.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
var newTodo = {value: this.state.edited, done: false, key: this.state.counter};
|
||||
this.setState({todos: this.state.todos.concat(newTodo), edited: '', counter: this.state.counter + 1});
|
||||
},
|
||||
|
@ -1,9 +1,9 @@
|
||||
<div>
|
||||
Have {_.filter(this.state.todos, {done:true}).length} todos done,
|
||||
and {_.filter(this.state.todos, {done:false}).length} not done
|
||||
<strong>{_.filter(this.state.todos, {done:true}).length}</strong> done,
|
||||
<strong>{_.filter(this.state.todos, {done:false}).length}</strong> pending
|
||||
<br/>
|
||||
<div rt-repeat="todo in this.state.todos" key="{todo.key}">
|
||||
<button onClick="()=>this.remove(todo)">x</button>
|
||||
<button onClick="()=>this.remove(todo)" title="Remove Todo">x</button>
|
||||
<input type="checkbox" checked="{todo.done}" onChange="()=>this.toggleChecked(todoIndex)"/>
|
||||
<span style="text-decoration: {todo.done ? 'line-through': 'none'}">{todo.value}</span>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user