Skip to content
This repository has been archived by the owner on Nov 21, 2017. It is now read-only.

Commit

Permalink
Added package.json, examples and a gulpfile to transform examples
Browse files Browse the repository at this point in the history
  • Loading branch information
insin committed Mar 21, 2014
1 parent 5d163ca commit 80fe78a
Show file tree
Hide file tree
Showing 11 changed files with 789 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
6 changes: 6 additions & 0 deletions README.md
@@ -0,0 +1,6 @@
# msx

(React)[http://facebook.github.io/reac]'s JSX Transformer, tweaked to output
calls to (Mithril)[http://lhorie.github.io/mithril/]'s `m()` function in the
format it expects, with the tag name in a String and any children present
wrapped in an Array.
53 changes: 53 additions & 0 deletions gulpfile.js
@@ -0,0 +1,53 @@
var gulp = require('gulp')

var msx = require('./main')
var through = require('through2')

var plumber = require('gulp-plumber')
var rename = require('gulp-rename')
var gutil = require('gulp-util')

var testJSX = './test/jsx/*.jsx'

function msxTransform(name) {
return through.obj(function (file, enc, cb) {
if (file.isNull()) {
this.push(file)
return cb()
}

if (file.isStream()) {
this.emit('error', new gutil.PluginError('msx', 'Streaming not supported'))
return cb()
}

try {
file.contents = new Buffer(msx.transform(file.contents.toString()))
file.path = gutil.replaceExtension(file.path, '.js')
}
catch (err) {
err.fileName = file.path
this.emit('error', new gutil.PluginError('msx', err))
}

this.push(file)
cb()
})
}

gulp.task('msx', function() {
return gulp.src(testJSX)
.pipe(plumber())
.pipe(msxTransform())
.on('error', function(e) {
console.error(e.message + '\n in ' + e.fileName)
})
.pipe(rename({ext: '.js'}))
.pipe(gulp.dest('./test/js/'))
})

gulp.task('watch', function() {
gulp.watch([testJSX], ['msx'])
})

gulp.task('default', ['watch', 'msx'])
16 changes: 16 additions & 0 deletions main.js
@@ -0,0 +1,16 @@
'use strict';

var visitors = require('./vendor/fbtransform/visitors');
var transform = require('jstransform').transform;

module.exports = {
transform: function(code, options) {
var visitorList;
if (options && options.harmony) {
visitorList = visitors.getAllVisitors();
} else {
visitorList = visitors.transformVisitors.react;
}
return transform(visitorList, code).code;
}
};
27 changes: 27 additions & 0 deletions package.json
@@ -0,0 +1,27 @@
{
"name": "msx",
"version": "0.1.0-alpha",
"description": "JSX for Mithril",
"main": "main.js",
"dependencies": {
"esprima-fb": "~3001.1.0-dev-harmony-fb",
"jstransform": "~3.0.0"
},
"devDependencies": {
"gulp": "~3.5.6",
"gulp-plumber": "^0.5.6",
"gulp-rename": "^1.2.0",
"gulp-util": "~2.2.14",
"through2": "~0.4.1"
},
"keywords": [
"jsx",
"mithril"
],
"author": "Jonathan Buchanan <jonathan.buchanan@gmail.com> (https://github.com/insin)",
"repository": {
"type": "git",
"url": "git://github.com/insin/msx.git"
},
"license": "MIT"
}
3 changes: 3 additions & 0 deletions test/js/example.html
@@ -0,0 +1,3 @@
<!doctype html>
<script src="../vendor/mithril-0.1.js"></script>
<script src="example.js"></script>
66 changes: 66 additions & 0 deletions test/js/example.js
@@ -0,0 +1,66 @@
/**
* JSX version of the Mithril Getting Started documentation's TODO example.
* http://lhorie.github.io/mithril/getting-started.html
* @jsx m
*/

//this application only has one module: todo
var todo = {};

//for simplicity, we use this module to namespace the model classes

//the Todo class has two properties
todo.Todo = function(data) {
this.description = m.prop(data.description);
this.done = m.prop(false);
};

//the TodoList class is a list of Todo's
todo.TodoList = Array;

//the controller uses 3 model-level entities, of which one is a custom defined class:
//`Todo` is the central class in this application
//`list` is merely a generic array, with standard array methods
//`description` is a temporary storage box that holds a string
//
//the `add` method simply adds a new todo to the list
todo.controller = function() {
this.list = new todo.TodoList();
this.description = m.prop("");

this.add = function(description) {
if (description()) {
this.list.push(new todo.Todo({description: description()}));
this.description("");
}
};
};

//here's the view
todo.view = function(ctrl) {
return m('html', [
m('body', [
m('input', {onchange:m.withAttr("value", ctrl.description), value:ctrl.description()}),
m('button', {onclick:ctrl.add.bind(ctrl, ctrl.description)}, ["Add"]),
m('table', [
ctrl.list.map(function(task, index) {
return m('tr', [
m('td', [
m('input',
{type:"checkbox",
onclick:m.withAttr("checked", task.done),
checked:task.done()}
)
]),
m('td', {style:{textDecoration: task.done() ? "line-through" : "none"}}, [
task.description()
])
])
})
])
])
])
};

//initialize the application
m.module(document, todo);
68 changes: 68 additions & 0 deletions test/js/test.js
@@ -0,0 +1,68 @@
/**
* JSX version of https://github.com/jpmonette/todomvc-mithril/blob/1d627f1d5dc0890d0a99cdcb16d09387f68f6df0/js/views/todo-view.js
* @jsx m
*/

'use strict';

function view(ctrl) {
var clearCompleted
if (ctrl.amountCompleted() != 0) {
clearCompleted = m('button', {id:"clear-completed", onclick:ctrl.clearCompleted.bind(ctrl)}, [
"Clear completed (",ctrl.amountCompleted(),")"
])
}

var todos = ctrl.list.map(function(task, index) {
return m('li', {className:task.completed() && 'completed'}, [
m('div', {className:"view"}, [
m('input',
{className:"toggle",
type:"checkbox",
onclick:m.withAttr('checked', task.completed),
checked:task.completed()}
),
m('label', [task.title()]),
m('button', {className:"destroy", onclick:ctrl.remove.bind(ctrl, index)})
]),
m('input', {className:"edit"})
])
})

return m('div', {id:"todoapp"}, [
m('header', {id:"header"}, [
m('h1', ["todos"]),
m('input',
{id:"new-todo",
placeholder:"What needs to be done?",
onkeydown:function(e) { m.withAttr('value', ctrl.title)(e); ctrl.add(ctrl.title, e) },
value:ctrl.title()}
)
]),
m('section', {id:"main"}, [
m('input', {id:"toggle-all", type:"checkbox"}),
m('ul', {id:"todo-list"}, [
todos
])
]),
m('footer', {id:"footer"}, [
m('span', {id:"todo-count"}, [
m('strong', [ctrl.list.length, " item",ctrl.list.length > 1 ? 's' : '', " left"])
]),
m('ul', {id:"filters"}, [
m('li', {className:"selected"}, [
m('a', {href:"#/"}, ["All"])
]),
m('li', [
m('a', {href:"#/active"}, ["Active"])
]),
m('li', [
m('a', {href:"#/completed"}, ["Completed"])
])
]),
clearCompleted
])
])
}

module.exports = view
66 changes: 66 additions & 0 deletions test/jsx/example.jsx
@@ -0,0 +1,66 @@
/**
* JSX version of the Mithril Getting Started documentation's TODO example.
* http://lhorie.github.io/mithril/getting-started.html
* @jsx m
*/

//this application only has one module: todo
var todo = {};

//for simplicity, we use this module to namespace the model classes

//the Todo class has two properties
todo.Todo = function(data) {
this.description = m.prop(data.description);
this.done = m.prop(false);
};

//the TodoList class is a list of Todo's
todo.TodoList = Array;

//the controller uses 3 model-level entities, of which one is a custom defined class:
//`Todo` is the central class in this application
//`list` is merely a generic array, with standard array methods
//`description` is a temporary storage box that holds a string
//
//the `add` method simply adds a new todo to the list
todo.controller = function() {
this.list = new todo.TodoList();
this.description = m.prop("");

this.add = function(description) {
if (description()) {
this.list.push(new todo.Todo({description: description()}));
this.description("");
}
};
};

//here's the view
todo.view = function(ctrl) {
return <html>
<body>
<input onchange={m.withAttr("value", ctrl.description)} value={ctrl.description()}/>
<button onclick={ctrl.add.bind(ctrl, ctrl.description)}>Add</button>
<table>
{ctrl.list.map(function(task, index) {
return <tr>
<td>
<input
type="checkbox"
onclick={m.withAttr("checked", task.done)}
checked={task.done()}
/>
</td>
<td style={{textDecoration: task.done() ? "line-through" : "none"}}>
{task.description()}
</td>
</tr>
})}
</table>
</body>
</html>
};

//initialize the application
m.module(document, todo);
68 changes: 68 additions & 0 deletions test/jsx/test.jsx
@@ -0,0 +1,68 @@
/**
* JSX version of https://github.com/jpmonette/todomvc-mithril/blob/1d627f1d5dc0890d0a99cdcb16d09387f68f6df0/js/views/todo-view.js
* @jsx m
*/

'use strict';

function view(ctrl) {
var clearCompleted
if (ctrl.amountCompleted() != 0) {
clearCompleted = <button id="clear-completed" onclick={ctrl.clearCompleted.bind(ctrl)}>
Clear completed ({ctrl.amountCompleted()})
</button>
}

var todos = ctrl.list.map(function(task, index) {
return <li className={task.completed() && 'completed'}>
<div className="view">
<input
className="toggle"
type="checkbox"
onclick={m.withAttr('checked', task.completed)}
checked={task.completed()}
/>
<label>{task.title()}</label>
<button className="destroy" onclick={ctrl.remove.bind(ctrl, index)}/>
</div>
<input className="edit"/>
</li>
})

return <div id="todoapp">
<header id="header">
<h1>todos</h1>
<input
id="new-todo"
placeholder='What needs to be done?'
onkeydown={function(e) { m.withAttr('value', ctrl.title)(e); ctrl.add(ctrl.title, e) }}
value={ctrl.title()}
/>
</header>
<section id="main">
<input id="toggle-all" type="checkbox"/>
<ul id="todo-list">
{todos}
</ul>
</section>
<footer id="footer">
<span id="todo-count">
<strong>{ctrl.list.length} item{ctrl.list.length > 1 ? 's' : ''} left</strong>
</span>
<ul id="filters">
<li className="selected">
<a href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
{clearCompleted}
</footer>
</div>
}

module.exports = view

0 comments on commit 80fe78a

Please sign in to comment.