├── .gitignore
├── Makefile
├── README.md
├── app
├── about-text.html
├── about.jsx
├── ast-node.jsx
├── ast-output.jsx
├── event.js
├── input.jsx
├── main.jsx
├── mixins
│ ├── path.js
│ ├── render-node-property.jsx
│ └── toggle.js
├── node-component-finder.js
├── node-location.jsx
├── nodes
│ ├── assignment-expression.jsx
│ ├── binary-expression.jsx
│ ├── block-statement.jsx
│ ├── break-statement.jsx
│ ├── call-expression.jsx
│ ├── expression-statement.jsx
│ ├── for-statement.jsx
│ ├── function-declaration.jsx
│ ├── function-expression.jsx
│ ├── identifier.jsx
│ ├── if-statement.jsx
│ ├── literal.jsx
│ ├── member-expression.jsx
│ ├── object-expression.jsx
│ ├── property.jsx
│ ├── return-statement.jsx
│ ├── this-expression.jsx
│ ├── update-expression.jsx
│ ├── variable-declaration.jsx
│ └── variable-declarator.jsx
├── null-nodes.js
├── path.jsx
└── starting-code.js
├── build-script.js
├── config.js
├── index.html
├── package.json
└── style.css
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | jspm_packages/
3 | dist/
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | server:
2 | ./node_modules/.bin/serve -p 9876
3 |
4 | install:
5 | npm install
6 | jspm install
7 |
8 | build:
9 | mkdir -p dist/
10 | cp jspm_packages/traceur-runtime.js dist/traceur-runtime.js
11 | node build-script.js
12 | jspm bundle-sfx app/main.jsx! dist/app.js
13 | cat dist/traceur-runtime.js dist/app.js > dist/dist.js
14 | ./node_modules/.bin/uglifyjs dist/dist.js -o dist/dist.min.js
15 |
16 |
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AST Viewer
2 |
3 | # Install
4 |
5 | ```
6 | npm install --global jspm
7 | make install
8 | ```
9 |
10 | # Run
11 |
12 | ```
13 | make server
14 | ```
15 |
16 | Now visit `http://localhost:9876`.
17 |
18 | ## TODO
19 |
20 | - swap to [espree](https://github.com/eslint/espree) for ES6 support?
21 | - deal with invalid input code
22 | - add ability to "zoom in" on a section of the code (will require the ability to find some of the AST given the path of the component)
23 | - test with more complex code examples
24 | - have a few pre-generated code examples to load in
25 | - ability to fetch and load in a URL from GitHub or similar
26 | - add build task to minify all the things for production
27 | - add text to the homepage about checking console if nothing renders
28 |
29 |
--------------------------------------------------------------------------------
/app/about-text.html:
--------------------------------------------------------------------------------
1 |
ReactJS AST Viewer
2 |
3 | Built using the following:
4 |
5 |
6 | - ReactJS
7 | - ES6 Modules with jspm and SystemJS
8 | - Esprima
9 | - The ACE Code Editor
10 |
11 |
--------------------------------------------------------------------------------
/app/about.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import aboutText from './about-text.html!text';
3 |
4 | export default React.createClass({
5 | render: function() {
6 | return (
7 |
8 |
9 | )
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/app/ast-node.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import _ from 'lodash';
3 | import componentFinder from './node-component-finder';
4 | import ToggleMixin from './mixins/toggle';
5 | import Path from './path.jsx!';
6 | import PathMixin from './mixins/path';
7 | import emitter from './event';
8 | import NodeLocation from './node-location.jsx!';
9 |
10 | import NULL_NODE_TYPES from './null-nodes';
11 |
12 | export default React.createClass({
13 | mixins: [ToggleMixin, PathMixin],
14 | onMouseEnter: function(e) {
15 | e.stopPropagation();
16 | emitter.emit('active-node', this.props.node);
17 | this.setState({ isFocused: true });
18 | },
19 | onMouseLeave: function(e) {
20 | e.stopPropagation();
21 | emitter.emit('deactive-node', this.props.node);
22 | this.setState({ isFocused: false });
23 | },
24 | getRenderedContent: function() {
25 | if(this._content) return this._content;
26 |
27 | var newElementComponent = componentFinder(this.props.node.type);
28 |
29 | if(newElementComponent) {
30 | this._content = React.createElement(newElementComponent, this.props);
31 | return this._content;
32 | } else {
33 | console.err('No element found for node', this.props.node);
34 | }
35 | },
36 | isNullNode: function() {
37 | return NULL_NODE_TYPES.indexOf(this.props.node.type) > -1;
38 | },
39 | renderKey: function() {
40 | if(!this.props.nodeKey) return null;
41 |
42 | return {`${this.props.nodeKey}: `};
43 | },
44 | renderHeading: function() {
45 | return (
46 | {this.renderKey()}{ this.props.node.type }
47 |
48 |
49 | );
50 | },
51 | renderContent: function() {
52 | if(this.isNullNode()) return null;
53 |
54 | return (
55 |
56 | { this.getRenderedContent() }
57 |
58 | )
59 | },
60 | renderToggle: function() {
61 | var internalText = this.state.visible ? '-' : '+';
62 | if(this.isNullNode()) return null;
63 | return (
64 |
65 | { internalText }
66 |
67 | );
68 | },
69 | render: function() {
70 | var outputProperties = this.getRenderedContent();
71 |
72 | return (
73 |
74 |
75 |
76 | { this.renderToggle() }
77 |
78 | { this.renderHeading() }
79 |
80 |
81 | { this.renderContent() }
82 |
83 |
84 | );
85 | }
86 | });
87 |
--------------------------------------------------------------------------------
/app/ast-output.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import esprima from 'esprima';
3 | import ASTNode from './ast-node.jsx!';
4 |
5 | export default React.createClass({
6 | componentWillMount: function() {
7 | this.setState({
8 | tree: this.parseCode(this.props.code)
9 | });
10 | },
11 | componentWillReceiveProps: function(props) {
12 | this.setState({
13 | tree: this.parseCode(props.code)
14 | });
15 | },
16 | parseCode: function(code) {
17 | var tree = esprima.parse(code, { loc: true });
18 | console.log(tree);
19 | return tree;
20 | },
21 | render: function() {
22 | var nodes = this.state.tree.body.map((body, index) => {
23 | return ;
24 | });
25 |
26 | return ;
27 | }
28 | });
29 |
--------------------------------------------------------------------------------
/app/event.js:
--------------------------------------------------------------------------------
1 | import ee from 'event-emitter';
2 |
3 | export default ee({});
4 |
5 |
--------------------------------------------------------------------------------
/app/input.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import emitter from './event';
3 | import AboutProject from './about.jsx!';
4 |
5 | import ace from 'brace';
6 | import 'brace/mode/javascript'
7 |
8 | var {Range} = ace.acequire('ace/range');
9 |
10 | export default React.createClass({
11 | highlightRange: function(startRow, startCol, endRow, endCol) {
12 | var range = new Range(...arguments);
13 | this.marker = this.editor.getSession().addMarker(range, 'code-highlight', 'text', true);
14 | },
15 | shouldComponentUpdate: function(nextProps) {
16 | return false;
17 | },
18 | componentDidMount: function() {
19 | this.editor = ace.edit('ace-editor');
20 | this.editor.getSession().setMode('ace/mode/javascript');
21 | this.editor.setHighlightActiveLine(false);
22 |
23 | emitter.on('active-node', (node) => {
24 | this.editor.getSession().removeMarker(this.marker);
25 | this.highlightRange(
26 | node.loc.start.line - 1, node.loc.start.column - 1,
27 | node.loc.end.line - 1, node.loc.end.column - 1);
28 | });
29 |
30 | emitter.on('deactive-node', (node) => {
31 | this.editor.getSession().removeMarker(this.marker);
32 | });
33 | },
34 | handleSubmit: function(e) {
35 | e.preventDefault();
36 | this.emitChange();
37 | },
38 | emitChange: function() {
39 | var input = this.editor.getValue();
40 | emitter.emit('input-change', { code: input });
41 | },
42 | render: function() {
43 | return (
44 |
51 | );
52 | }
53 | });
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/main.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import CodeInput from './input.jsx!';
3 | import ASTOutput from './ast-output.jsx!';
4 | import emitter from './event';
5 |
6 | import code from './starting-code.js!text';
7 |
8 | var MainComponent = React.createClass({
9 | onInputChange: function(args) {
10 | this.setState({
11 | code: args.code
12 | });
13 | },
14 | componentWillMount: function() {
15 | emitter.on('input-change', this.onInputChange);
16 | },
17 | componentWillUnmount: function() {
18 | emitter.off('input-change', this.onInputChange);
19 | },
20 | getInitialState: function() {
21 | return { code: code, allVisible: false, showOnlyTree: false };
22 | },
23 | onToggleAllClick: function(e) {
24 | e.preventDefault();
25 | var newVisible = !this.state.allVisible;
26 | emitter.emit('toggle-all', { visible: newVisible });
27 | this.setState({ allVisible: newVisible });
28 | },
29 | onShowTreeToggle: function(e) {
30 | e.preventDefault();
31 | this.setState({
32 | showOnlyTree: !this.state.showOnlyTree
33 | });
34 | },
35 | renderCodeInput: function() {
36 | if(this.state.showOnlyTree) return;
37 |
38 | return (
39 |
40 |
41 |
42 | );
43 | },
44 | renderTreeOutput: function() {
45 | return (
46 |
49 | );
50 | },
51 | render: function() {
52 | var showOnlyTreeText = this.state.showOnlyTree ? 'View Code and Tree' : 'View Just Tree';
53 | var toggleText = this.state.allVisible ? 'Close Tree' : 'Expand Tree';
54 |
55 | return (
56 |
57 |
61 |
62 |
66 |
67 | { this.renderCodeInput() }
68 | { this.renderTreeOutput() }
69 |
70 | );
71 | }
72 | });
73 |
74 |
75 | React.render(, document.querySelector('.wrap'));
76 |
--------------------------------------------------------------------------------
/app/mixins/path.js:
--------------------------------------------------------------------------------
1 | export default {
2 | parentPath: function() {
3 | if(!this.props.parentPath) {
4 | console.warn('Warning: no parentPath set for', this.props.node);
5 | }
6 | return this.props.parentPath || '';
7 | },
8 | path: function() {
9 | return `${this.parentPath()}/${this.props.node.type}`
10 | },
11 | arrayPath: function(key, index) {
12 | return `${this.path()}.${key}[${index}]`;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/app/mixins/render-node-property.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from 'app/ast-node.jsx!';
3 |
4 | export default {
5 | renderNode: function(propertyName, optional=false) {
6 | if(optional && !this.props.node[propertyName]) {
7 | return null;
8 | }
9 |
10 | return (
11 |
12 |
17 |
18 | );
19 | },
20 | renderProp: function(propertyName, optional=false) {
21 | if(optional && !this.props.node[propertyName]) {
22 | return null;
23 | }
24 |
25 | return (
26 |
27 | {propertyName}{ this.props.node[propertyName] }
28 |
29 | );
30 | },
31 | renderArrayProps: function(propertyName, optional=false) {
32 | var items = this.props.node[propertyName].map((item, index) => {
33 | return (
34 |
35 |
36 |
37 | );
38 | });
39 |
40 | if(optional && !items.length) {
41 | return null;
42 | }
43 |
44 | return items;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/app/mixins/toggle.js:
--------------------------------------------------------------------------------
1 | import emitter from '../event';
2 |
3 | export default {
4 | onToggleAll: function(data) {
5 | if(data && data.visible) {
6 | this.setState({ visible: data.visible });
7 | } else {
8 | this.setState({ visible: !this.state.visible });
9 | }
10 | },
11 | componentWillUnmount: function() {
12 | emitter.off('toggle-all', this.onToggleAll);
13 | },
14 | componentWillMount: function() {
15 | emitter.on('toggle-all', this.onToggleAll);
16 | },
17 | getInitialState: function() {
18 | return { visible: false };
19 | },
20 | onToggleClick: function() {
21 | this.setState({ visible: !this.state.visible });
22 | }
23 | };
24 |
--------------------------------------------------------------------------------
/app/node-component-finder.js:
--------------------------------------------------------------------------------
1 | import emitter from './event';
2 |
3 | import FunctionDeclaration from './nodes/function-declaration.jsx!';
4 | import BlockStatement from './nodes/block-statement.jsx!';
5 | import ExpressionStatement from './nodes/expression-statement.jsx!';
6 | import CallExpression from './nodes/call-expression.jsx!';
7 | import MemberExpression from './nodes/member-expression.jsx!';
8 | import Literal from './nodes/literal.jsx!';
9 | import Identifier from './nodes/identifier.jsx!';
10 | import VariableDeclaration from './nodes/variable-declaration.jsx!';
11 | import VariableDeclarator from './nodes/variable-declarator.jsx!';
12 | import ObjectExpression from './nodes/object-expression.jsx!';
13 | import Property from './nodes/property.jsx!';
14 | import FunctionExpression from './nodes/function-expression.jsx!';
15 | import AssignmentExpression from './nodes/assignment-expression.jsx!';
16 | import ThisExpression from './nodes/this-expression.jsx!';
17 | import ReturnStatement from './nodes/return-statement.jsx!';
18 | import BinaryExpression from './nodes/binary-expression.jsx!';
19 | import ForStatement from './nodes/for-statement.jsx!';
20 | import UpdateExpression from './nodes/update-expression.jsx!';
21 | import IfStatement from './nodes/if-statement.jsx!';
22 | import BreakStatement from './nodes/break-statement.jsx!';
23 |
24 | const NODE_COMPONENTS = {
25 | FunctionDeclaration,
26 | BlockStatement,
27 | ExpressionStatement,
28 | CallExpression,
29 | MemberExpression,
30 | Literal,
31 | Identifier,
32 | VariableDeclaration,
33 | VariableDeclarator,
34 | ObjectExpression,
35 | Property,
36 | FunctionExpression,
37 | AssignmentExpression,
38 | ThisExpression,
39 | ReturnStatement,
40 | BinaryExpression,
41 | ForStatement,
42 | UpdateExpression,
43 | IfStatement,
44 | BreakStatement
45 | };
46 |
47 | export default function(type) {
48 | var component = NODE_COMPONENTS[type];
49 |
50 | if(component) return component;
51 |
52 | throw new Error(`No Component found for ${type}`);
53 | };
54 |
--------------------------------------------------------------------------------
/app/node-location.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default React.createClass({
4 | render: function() {
5 | return (
6 |
7 | Lines {this.props.loc.start.line} to {this.props.loc.end.line}
8 |
9 | );
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/app/nodes/assignment-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderProp('operator') }
12 | { this.renderNode('left') }
13 | { this.renderNode('right') }
14 |
15 | );
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/app/nodes/binary-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('left') }
12 | { this.renderNode('right') }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/block-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderArrayProps('body') }
12 |
13 | );
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/app/nodes/break-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
3 |
4 | export default React.createClass({
5 | mixins: [RenderNodeMixin],
6 | render: function() {
7 | return this.renderProp('label', true);
8 | }
9 | });
10 |
--------------------------------------------------------------------------------
/app/nodes/call-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('callee') }
12 | { this.renderArrayProps('arguments', true) }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/expression-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('expression') }
12 |
13 | );
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/app/nodes/for-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('init') }
12 | { this.renderNode('test') }
13 | { this.renderNode('update') }
14 | { this.renderNode('body') }
15 |
16 | );
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/app/nodes/function-declaration.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderProp('name') }
12 | { this.renderNode('body') }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/function-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderArrayProps('params', true) }
12 | { this.renderNode('body') }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/identifier.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
3 |
4 | export default React.createClass({
5 | mixins: [RenderNodeMixin],
6 | render: function() {
7 | return (
8 | { this.renderProp('name') }
9 | );
10 | }
11 | });
12 |
--------------------------------------------------------------------------------
/app/nodes/if-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('test') }
12 | { this.renderNode('consequent') }
13 | { this.renderNode('alternate', true) }
14 |
15 | );
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/app/nodes/literal.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
4 | import PathMixin from '../mixins/path';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 | { this.renderProp('value') }
11 | );
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/app/nodes/member-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('object') }
12 | { this.renderNode('property') }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/object-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderArrayProps('properties') }
12 |
13 | );
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/app/nodes/property.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('key') }
12 | { this.renderNode('value') }
13 |
14 | );
15 | }
16 | });
17 |
--------------------------------------------------------------------------------
/app/nodes/return-statement.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderNode('argument') }
12 |
13 | );
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/app/nodes/this-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default React.createClass({
4 | render: function() {
5 | // there's nothing in a ThisExpression, it's basically a noop
6 | return null;
7 | }
8 | });
9 |
--------------------------------------------------------------------------------
/app/nodes/update-expression.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | render: function() {
9 | return (
10 |
11 | { this.renderProp('operator') }
12 | { this.renderProp('prefix') }
13 | { this.renderNode('argument') }
14 |
15 | );
16 | }
17 | });
18 |
--------------------------------------------------------------------------------
/app/nodes/variable-declaration.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | getInitialState: function() {
9 | return { isFocused: false }
10 | },
11 | render: function() {
12 | return (
13 |
14 | { this.renderArrayProps('declarations') }
15 |
16 | );
17 | }
18 | });
19 |
--------------------------------------------------------------------------------
/app/nodes/variable-declarator.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ASTNode from '../ast-node.jsx!';
3 | import PathMixin from '../mixins/path';
4 | import RenderNodeMixin from '../mixins/render-node-property.jsx!';
5 |
6 | export default React.createClass({
7 | mixins: [PathMixin, RenderNodeMixin],
8 | getInitialState: function() {
9 | return { isFocused: false }
10 | },
11 | render: function() {
12 | return (
13 |
14 | { this.renderNode('id') }
15 | { this.renderNode('init', true) }
16 |
17 | );
18 | }
19 | });
20 |
--------------------------------------------------------------------------------
/app/null-nodes.js:
--------------------------------------------------------------------------------
1 | export default [
2 | 'ThisExpression'
3 | ];
4 |
--------------------------------------------------------------------------------
/app/path.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default React.createClass({
4 | render: function() {
5 | if(!this.props.visible) return null;
6 |
7 | return (
8 |
9 | {this.props.path}
10 |
11 | );
12 | }
13 | });
14 |
--------------------------------------------------------------------------------
/app/starting-code.js:
--------------------------------------------------------------------------------
1 | var x = obj.init({
2 | foo: true,
3 | bar: false,
4 | x: function() {
5 | return 2;
6 | }
7 | });
8 |
9 |
--------------------------------------------------------------------------------
/build-script.js:
--------------------------------------------------------------------------------
1 | var cheerio = require('cheerio');
2 | var _ = require('lodash');
3 | var fs = require('fs');
4 | var $ = cheerio.load(fs.readFileSync('index.html'));
5 |
6 | $('script').remove();
7 |
8 | $('body').append("");
9 |
10 | fs.writeFileSync('dist/style.css', fs.readFileSync('style.css'));
11 | fs.writeFileSync('dist/index.html', '' + $('html').html() + '');
12 |
--------------------------------------------------------------------------------
/config.js:
--------------------------------------------------------------------------------
1 | System.config({
2 | "baseURL": "/",
3 | "paths": {
4 | "*": "*.js",
5 | "github:*": "jspm_packages/github/*.js",
6 | "npm:*": "jspm_packages/npm/*.js"
7 | }
8 | });
9 |
10 | System.config({
11 | "map": {
12 | "ace": "github:ajaxorg/ace-builds@1.1.8",
13 | "brace": "npm:brace@0.5.0",
14 | "esprima": "npm:esprima@2.0.0",
15 | "event-emitter": "npm:event-emitter@0.3.3",
16 | "jsx": "github:floatdrop/plugin-jsx@0.1.1",
17 | "lodash": "npm:lodash@3.3.1",
18 | "react": "npm:react@0.12.2",
19 | "text": "github:systemjs/plugin-text@0.0.2",
20 | "github:floatdrop/plugin-jsx@0.1.1": {
21 | "react-tools": "npm:react-tools@0.12.2"
22 | },
23 | "github:jspm/nodelibs-assert@0.1.0": {
24 | "assert": "npm:assert@1.3.0"
25 | },
26 | "github:jspm/nodelibs-buffer@0.1.0": {
27 | "buffer": "npm:buffer@3.0.3"
28 | },
29 | "github:jspm/nodelibs-constants@0.1.0": {
30 | "constants-browserify": "npm:constants-browserify@0.0.1"
31 | },
32 | "github:jspm/nodelibs-crypto@0.1.0": {
33 | "crypto-browserify": "npm:crypto-browserify@3.9.13"
34 | },
35 | "github:jspm/nodelibs-events@0.1.0": {
36 | "events-browserify": "npm:events-browserify@0.0.1"
37 | },
38 | "github:jspm/nodelibs-http@1.7.0": {
39 | "Base64": "npm:Base64@0.2.1",
40 | "events": "github:jspm/nodelibs-events@0.1.0",
41 | "inherits": "npm:inherits@2.0.1",
42 | "stream": "github:jspm/nodelibs-stream@0.1.0",
43 | "url": "github:jspm/nodelibs-url@0.1.0",
44 | "util": "github:jspm/nodelibs-util@0.1.0"
45 | },
46 | "github:jspm/nodelibs-path@0.1.0": {
47 | "path-browserify": "npm:path-browserify@0.0.0"
48 | },
49 | "github:jspm/nodelibs-process@0.1.1": {
50 | "process": "npm:process@0.10.1"
51 | },
52 | "github:jspm/nodelibs-stream@0.1.0": {
53 | "stream-browserify": "npm:stream-browserify@1.0.0"
54 | },
55 | "github:jspm/nodelibs-string_decoder@0.1.0": {
56 | "string_decoder": "npm:string_decoder@0.10.31"
57 | },
58 | "github:jspm/nodelibs-url@0.1.0": {
59 | "url": "npm:url@0.10.3"
60 | },
61 | "github:jspm/nodelibs-util@0.1.0": {
62 | "util": "npm:util@0.10.3"
63 | },
64 | "github:jspm/nodelibs-vm@0.1.0": {
65 | "vm-browserify": "npm:vm-browserify@0.0.4"
66 | },
67 | "npm:amdefine@0.1.0": {
68 | "fs": "github:jspm/nodelibs-fs@0.1.1",
69 | "module": "github:jspm/nodelibs-module@0.1.0",
70 | "path": "github:jspm/nodelibs-path@0.1.0",
71 | "process": "github:jspm/nodelibs-process@0.1.1"
72 | },
73 | "npm:asn1.js-rfc3280@1.0.0": {
74 | "asn1.js": "npm:asn1.js@1.0.3"
75 | },
76 | "npm:asn1.js@1.0.3": {
77 | "assert": "github:jspm/nodelibs-assert@0.1.0",
78 | "bn.js": "npm:bn.js@1.3.0",
79 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
80 | "inherits": "npm:inherits@2.0.1",
81 | "minimalistic-assert": "npm:minimalistic-assert@1.0.0",
82 | "vm": "github:jspm/nodelibs-vm@0.1.0"
83 | },
84 | "npm:assert@1.3.0": {
85 | "util": "npm:util@0.10.3"
86 | },
87 | "npm:ast-types@0.6.16": {
88 | "assert": "github:jspm/nodelibs-assert@0.1.0",
89 | "util": "github:jspm/nodelibs-util@0.1.0"
90 | },
91 | "npm:brace@0.5.0": {
92 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
93 | "process": "github:jspm/nodelibs-process@0.1.1",
94 | "w3c-blob": "npm:w3c-blob@0.0.1"
95 | },
96 | "npm:browserify-aes@1.0.0": {
97 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
98 | "create-hash": "npm:create-hash@1.1.0",
99 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
100 | "fs": "github:jspm/nodelibs-fs@0.1.1",
101 | "inherits": "npm:inherits@2.0.1",
102 | "stream": "github:jspm/nodelibs-stream@0.1.0",
103 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
104 | },
105 | "npm:browserify-rsa@1.1.1": {
106 | "bn.js": "npm:bn.js@1.3.0",
107 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
108 | "constants": "github:jspm/nodelibs-constants@0.1.0",
109 | "crypto": "github:jspm/nodelibs-crypto@0.1.0"
110 | },
111 | "npm:browserify-rsa@2.0.0": {
112 | "bn.js": "npm:bn.js@1.3.0",
113 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
114 | "constants": "github:jspm/nodelibs-constants@0.1.0",
115 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
116 | "randombytes": "npm:randombytes@2.0.1"
117 | },
118 | "npm:browserify-sign@2.8.0": {
119 | "bn.js": "npm:bn.js@1.3.0",
120 | "browserify-rsa": "npm:browserify-rsa@1.1.1",
121 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
122 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
123 | "elliptic": "npm:elliptic@1.0.1",
124 | "inherits": "npm:inherits@2.0.1",
125 | "parse-asn1": "npm:parse-asn1@2.0.0",
126 | "stream": "github:jspm/nodelibs-stream@0.1.0"
127 | },
128 | "npm:buffer@3.0.3": {
129 | "base64-js": "npm:base64-js@0.0.8",
130 | "ieee754": "npm:ieee754@1.1.4",
131 | "is-array": "npm:is-array@1.0.1"
132 | },
133 | "npm:commander@2.5.1": {
134 | "child_process": "github:jspm/nodelibs-child_process@0.1.0",
135 | "events": "github:jspm/nodelibs-events@0.1.0",
136 | "path": "github:jspm/nodelibs-path@0.1.0",
137 | "process": "github:jspm/nodelibs-process@0.1.1"
138 | },
139 | "npm:commoner@0.10.1": {
140 | "assert": "github:jspm/nodelibs-assert@0.1.0",
141 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
142 | "child_process": "github:jspm/nodelibs-child_process@0.1.0",
143 | "commander": "npm:commander@2.5.1",
144 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
145 | "events": "github:jspm/nodelibs-events@0.1.0",
146 | "fs": "github:jspm/nodelibs-fs@0.1.1",
147 | "glob": "npm:glob@4.2.2",
148 | "graceful-fs": "npm:graceful-fs@3.0.5",
149 | "iconv-lite": "npm:iconv-lite@0.4.7",
150 | "install": "npm:install@0.1.8",
151 | "mkdirp": "npm:mkdirp@0.5.0",
152 | "path": "github:jspm/nodelibs-path@0.1.0",
153 | "private": "npm:private@0.1.6",
154 | "process": "github:jspm/nodelibs-process@0.1.1",
155 | "q": "npm:q@1.1.2",
156 | "recast": "npm:recast@0.9.18",
157 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
158 | },
159 | "npm:constants-browserify@0.0.1": {
160 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
161 | },
162 | "npm:core-util-is@1.0.1": {
163 | "buffer": "github:jspm/nodelibs-buffer@0.1.0"
164 | },
165 | "npm:create-ecdh@2.0.0": {
166 | "bn.js": "npm:bn.js@1.3.0",
167 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
168 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
169 | "elliptic": "npm:elliptic@1.0.1"
170 | },
171 | "npm:create-hash@1.1.0": {
172 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
173 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
174 | "fs": "github:jspm/nodelibs-fs@0.1.1",
175 | "inherits": "npm:inherits@2.0.1",
176 | "ripemd160": "npm:ripemd160@1.0.0",
177 | "sha.js": "npm:sha.js@2.3.6",
178 | "stream": "github:jspm/nodelibs-stream@0.1.0"
179 | },
180 | "npm:create-hmac@1.1.3": {
181 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
182 | "create-hash": "npm:create-hash@1.1.0",
183 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
184 | "inherits": "npm:inherits@2.0.1",
185 | "stream": "github:jspm/nodelibs-stream@0.1.0"
186 | },
187 | "npm:crypto-browserify@3.9.13": {
188 | "browserify-aes": "npm:browserify-aes@1.0.0",
189 | "browserify-sign": "npm:browserify-sign@2.8.0",
190 | "create-ecdh": "npm:create-ecdh@2.0.0",
191 | "create-hash": "npm:create-hash@1.1.0",
192 | "create-hmac": "npm:create-hmac@1.1.3",
193 | "diffie-hellman": "npm:diffie-hellman@3.0.1",
194 | "inherits": "npm:inherits@2.0.1",
195 | "pbkdf2-compat": "npm:pbkdf2-compat@3.0.2",
196 | "public-encrypt": "npm:public-encrypt@2.0.0",
197 | "randombytes": "npm:randombytes@2.0.1"
198 | },
199 | "npm:d@0.1.1": {
200 | "es5-ext": "npm:es5-ext@0.10.6"
201 | },
202 | "npm:diffie-hellman@3.0.1": {
203 | "bn.js": "npm:bn.js@1.3.0",
204 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
205 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
206 | "miller-rabin": "npm:miller-rabin@1.1.5",
207 | "process": "github:jspm/nodelibs-process@0.1.1",
208 | "randombytes": "npm:randombytes@2.0.1",
209 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
210 | },
211 | "npm:elliptic@1.0.1": {
212 | "bn.js": "npm:bn.js@1.3.0",
213 | "brorand": "npm:brorand@1.0.5",
214 | "hash.js": "npm:hash.js@1.0.2",
215 | "inherits": "npm:inherits@2.0.1",
216 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
217 | },
218 | "npm:envify@3.2.0": {
219 | "jstransform": "npm:jstransform@7.0.0",
220 | "process": "github:jspm/nodelibs-process@0.1.1",
221 | "through": "npm:through@2.3.6"
222 | },
223 | "npm:es5-ext@0.10.6": {
224 | "es6-iterator": "npm:es6-iterator@0.1.3",
225 | "es6-symbol": "npm:es6-symbol@2.0.1",
226 | "process": "github:jspm/nodelibs-process@0.1.1"
227 | },
228 | "npm:es6-iterator@0.1.3": {
229 | "d": "npm:d@0.1.1",
230 | "es5-ext": "npm:es5-ext@0.10.6",
231 | "es6-symbol": "npm:es6-symbol@2.0.1"
232 | },
233 | "npm:es6-symbol@2.0.1": {
234 | "d": "npm:d@0.1.1",
235 | "es5-ext": "npm:es5-ext@0.10.6"
236 | },
237 | "npm:esprima-fb@10001.1.0-dev-harmony-fb": {
238 | "fs": "github:jspm/nodelibs-fs@0.1.1",
239 | "process": "github:jspm/nodelibs-process@0.1.1"
240 | },
241 | "npm:esprima-fb@7001.1.0-dev-harmony-fb": {
242 | "fs": "github:jspm/nodelibs-fs@0.1.1",
243 | "process": "github:jspm/nodelibs-process@0.1.1"
244 | },
245 | "npm:esprima-fb@8001.1001.0-dev-harmony-fb": {
246 | "fs": "github:jspm/nodelibs-fs@0.1.1",
247 | "process": "github:jspm/nodelibs-process@0.1.1"
248 | },
249 | "npm:esprima@2.0.0": {
250 | "fs": "github:jspm/nodelibs-fs@0.1.1",
251 | "process": "github:jspm/nodelibs-process@0.1.1"
252 | },
253 | "npm:event-emitter@0.3.3": {
254 | "d": "npm:d@0.1.1",
255 | "es5-ext": "npm:es5-ext@0.10.6",
256 | "events": "github:jspm/nodelibs-events@0.1.0"
257 | },
258 | "npm:events-browserify@0.0.1": {
259 | "process": "github:jspm/nodelibs-process@0.1.1"
260 | },
261 | "npm:glob@4.2.2": {
262 | "assert": "github:jspm/nodelibs-assert@0.1.0",
263 | "events": "github:jspm/nodelibs-events@0.1.0",
264 | "fs": "github:jspm/nodelibs-fs@0.1.1",
265 | "inflight": "npm:inflight@1.0.4",
266 | "inherits": "npm:inherits@2.0.1",
267 | "minimatch": "npm:minimatch@1.0.0",
268 | "once": "npm:once@1.3.1",
269 | "path": "github:jspm/nodelibs-path@0.1.0",
270 | "process": "github:jspm/nodelibs-process@0.1.1",
271 | "util": "github:jspm/nodelibs-util@0.1.0"
272 | },
273 | "npm:graceful-fs@3.0.5": {
274 | "assert": "github:jspm/nodelibs-assert@0.1.0",
275 | "constants": "github:jspm/nodelibs-constants@0.1.0",
276 | "module": "github:jspm/nodelibs-module@0.1.0",
277 | "process": "github:jspm/nodelibs-process@0.1.1",
278 | "util": "github:jspm/nodelibs-util@0.1.0",
279 | "vm": "github:jspm/nodelibs-vm@0.1.0"
280 | },
281 | "npm:hash.js@1.0.2": {
282 | "inherits": "npm:inherits@2.0.1"
283 | },
284 | "npm:iconv-lite@0.4.7": {
285 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
286 | "process": "github:jspm/nodelibs-process@0.1.1",
287 | "stream": "github:jspm/nodelibs-stream@0.1.0",
288 | "string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
289 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
290 | },
291 | "npm:inflight@1.0.4": {
292 | "once": "npm:once@1.3.1",
293 | "process": "github:jspm/nodelibs-process@0.1.1",
294 | "wrappy": "npm:wrappy@1.0.1"
295 | },
296 | "npm:inherits@2.0.1": {
297 | "util": "github:jspm/nodelibs-util@0.1.0"
298 | },
299 | "npm:install@0.1.8": {
300 | "assert": "github:jspm/nodelibs-assert@0.1.0",
301 | "fs": "github:jspm/nodelibs-fs@0.1.1",
302 | "path": "github:jspm/nodelibs-path@0.1.0",
303 | "process": "github:jspm/nodelibs-process@0.1.1"
304 | },
305 | "npm:jstransform@7.0.0": {
306 | "base62": "npm:base62@0.1.1",
307 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
308 | "esprima-fb": "npm:esprima-fb@7001.1.0-dev-harmony-fb",
309 | "process": "github:jspm/nodelibs-process@0.1.1",
310 | "source-map": "npm:source-map@0.1.31"
311 | },
312 | "npm:jstransform@8.2.0": {
313 | "base62": "npm:base62@0.1.1",
314 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
315 | "esprima-fb": "npm:esprima-fb@8001.1001.0-dev-harmony-fb",
316 | "fs": "github:jspm/nodelibs-fs@0.1.1",
317 | "process": "github:jspm/nodelibs-process@0.1.1",
318 | "source-map": "npm:source-map@0.1.31"
319 | },
320 | "npm:lodash@3.3.1": {
321 | "process": "github:jspm/nodelibs-process@0.1.1"
322 | },
323 | "npm:miller-rabin@1.1.5": {
324 | "bn.js": "npm:bn.js@1.3.0",
325 | "brorand": "npm:brorand@1.0.5"
326 | },
327 | "npm:minimatch@1.0.0": {
328 | "lru-cache": "npm:lru-cache@2.5.0",
329 | "path": "github:jspm/nodelibs-path@0.1.0",
330 | "process": "github:jspm/nodelibs-process@0.1.1",
331 | "sigmund": "npm:sigmund@1.0.0"
332 | },
333 | "npm:mkdirp@0.5.0": {
334 | "fs": "github:jspm/nodelibs-fs@0.1.1",
335 | "minimist": "npm:minimist@0.0.8",
336 | "path": "github:jspm/nodelibs-path@0.1.0",
337 | "process": "github:jspm/nodelibs-process@0.1.1"
338 | },
339 | "npm:once@1.3.1": {
340 | "wrappy": "npm:wrappy@1.0.1"
341 | },
342 | "npm:parse-asn1@2.0.0": {
343 | "asn1.js": "npm:asn1.js@1.0.3",
344 | "asn1.js-rfc3280": "npm:asn1.js-rfc3280@1.0.0",
345 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
346 | "pemstrip": "npm:pemstrip@0.0.1",
347 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
348 | },
349 | "npm:parse-asn1@3.0.0": {
350 | "asn1.js": "npm:asn1.js@1.0.3",
351 | "browserify-aes": "npm:browserify-aes@1.0.0",
352 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
353 | "create-hash": "npm:create-hash@1.1.0",
354 | "pbkdf2-compat": "npm:pbkdf2-compat@3.0.2",
355 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
356 | },
357 | "npm:path-browserify@0.0.0": {
358 | "process": "github:jspm/nodelibs-process@0.1.1"
359 | },
360 | "npm:pbkdf2-compat@3.0.2": {
361 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
362 | "child_process": "github:jspm/nodelibs-child_process@0.1.0",
363 | "create-hmac": "npm:create-hmac@1.1.3",
364 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
365 | "path": "github:jspm/nodelibs-path@0.1.0",
366 | "process": "github:jspm/nodelibs-process@0.1.1",
367 | "systemjs-json": "github:systemjs/plugin-json@0.1.0"
368 | },
369 | "npm:public-encrypt@2.0.0": {
370 | "bn.js": "npm:bn.js@1.3.0",
371 | "browserify-rsa": "npm:browserify-rsa@2.0.0",
372 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
373 | "create-hash": "npm:create-hash@1.1.0",
374 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
375 | "parse-asn1": "npm:parse-asn1@3.0.0",
376 | "randombytes": "npm:randombytes@2.0.1"
377 | },
378 | "npm:punycode@1.3.2": {
379 | "process": "github:jspm/nodelibs-process@0.1.1"
380 | },
381 | "npm:q@1.1.2": {
382 | "process": "github:jspm/nodelibs-process@0.1.1"
383 | },
384 | "npm:randombytes@2.0.1": {
385 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
386 | "crypto": "github:jspm/nodelibs-crypto@0.1.0",
387 | "process": "github:jspm/nodelibs-process@0.1.1"
388 | },
389 | "npm:react-tools@0.12.2": {
390 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
391 | "commoner": "npm:commoner@0.10.1",
392 | "jstransform": "npm:jstransform@8.2.0",
393 | "process": "github:jspm/nodelibs-process@0.1.1"
394 | },
395 | "npm:react@0.12.2": {
396 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
397 | "envify": "npm:envify@3.2.0",
398 | "process": "github:jspm/nodelibs-process@0.1.1"
399 | },
400 | "npm:readable-stream@1.1.13": {
401 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
402 | "core-util-is": "npm:core-util-is@1.0.1",
403 | "events": "github:jspm/nodelibs-events@0.1.0",
404 | "inherits": "npm:inherits@2.0.1",
405 | "isarray": "npm:isarray@0.0.1",
406 | "process": "github:jspm/nodelibs-process@0.1.1",
407 | "stream": "npm:stream-browserify@1.0.0",
408 | "string_decoder": "npm:string_decoder@0.10.31",
409 | "util": "github:jspm/nodelibs-util@0.1.0"
410 | },
411 | "npm:recast@0.9.18": {
412 | "assert": "github:jspm/nodelibs-assert@0.1.0",
413 | "ast-types": "npm:ast-types@0.6.16",
414 | "esprima-fb": "npm:esprima-fb@10001.1.0-dev-harmony-fb",
415 | "fs": "github:jspm/nodelibs-fs@0.1.1",
416 | "private": "npm:private@0.1.6",
417 | "process": "github:jspm/nodelibs-process@0.1.1",
418 | "source-map": "npm:source-map@0.1.43"
419 | },
420 | "npm:ripemd160@1.0.0": {
421 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
422 | "process": "github:jspm/nodelibs-process@0.1.1"
423 | },
424 | "npm:sha.js@2.3.6": {
425 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
426 | "fs": "github:jspm/nodelibs-fs@0.1.1",
427 | "inherits": "npm:inherits@2.0.1",
428 | "process": "github:jspm/nodelibs-process@0.1.1"
429 | },
430 | "npm:sigmund@1.0.0": {
431 | "http": "github:jspm/nodelibs-http@1.7.0",
432 | "util": "github:jspm/nodelibs-util@0.1.0"
433 | },
434 | "npm:source-map@0.1.31": {
435 | "amdefine": "npm:amdefine@0.1.0",
436 | "fs": "github:jspm/nodelibs-fs@0.1.1",
437 | "path": "github:jspm/nodelibs-path@0.1.0",
438 | "process": "github:jspm/nodelibs-process@0.1.1"
439 | },
440 | "npm:source-map@0.1.43": {
441 | "amdefine": "npm:amdefine@0.1.0",
442 | "fs": "github:jspm/nodelibs-fs@0.1.1",
443 | "path": "github:jspm/nodelibs-path@0.1.0",
444 | "process": "github:jspm/nodelibs-process@0.1.1"
445 | },
446 | "npm:stream-browserify@1.0.0": {
447 | "events": "github:jspm/nodelibs-events@0.1.0",
448 | "inherits": "npm:inherits@2.0.1",
449 | "readable-stream": "npm:readable-stream@1.1.13"
450 | },
451 | "npm:string_decoder@0.10.31": {
452 | "buffer": "github:jspm/nodelibs-buffer@0.1.0"
453 | },
454 | "npm:through@2.3.6": {
455 | "process": "github:jspm/nodelibs-process@0.1.1",
456 | "stream": "github:jspm/nodelibs-stream@0.1.0"
457 | },
458 | "npm:url@0.10.3": {
459 | "assert": "github:jspm/nodelibs-assert@0.1.0",
460 | "punycode": "npm:punycode@1.3.2",
461 | "querystring": "npm:querystring@0.2.0",
462 | "util": "github:jspm/nodelibs-util@0.1.0"
463 | },
464 | "npm:util@0.10.3": {
465 | "inherits": "npm:inherits@2.0.1",
466 | "process": "github:jspm/nodelibs-process@0.1.1"
467 | },
468 | "npm:vm-browserify@0.0.4": {
469 | "indexof": "npm:indexof@0.0.1"
470 | },
471 | "npm:w3c-blob@0.0.1": {
472 | "buffer": "github:jspm/nodelibs-buffer@0.1.0",
473 | "process": "github:jspm/nodelibs-process@0.1.1"
474 | }
475 | }
476 | });
477 |
478 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AST Viewer
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ast-viewer",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "author": "",
10 | "license": "ISC",
11 | "jspm": {
12 | "directories": {
13 | "lib": ".",
14 | "packages": "jspm_packages"
15 | },
16 | "dependencies": {
17 | "ace": "github:ajaxorg/ace-builds@^1.1.8",
18 | "brace": "npm:brace@^0.5.0",
19 | "esprima": "npm:esprima@^2.0.0",
20 | "event-emitter": "npm:event-emitter@^0.3.3",
21 | "jsx": "github:floatdrop/plugin-jsx@^0.1.1",
22 | "lodash": "npm:lodash@^3.3.1",
23 | "react": "npm:react@^0.12.2",
24 | "text": "github:systemjs/plugin-text@^0.0.2"
25 | }
26 | },
27 | "devDependencies": {
28 | "cheerio": "^0.18.0",
29 | "serve": "^1.4.0",
30 | "uglify-js": "^2.4.16"
31 | },
32 | "dependencies": {
33 | "lodash": "^3.4.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | width: 90%;
3 | margin: 5px auto;
4 | overflow: auto;
5 | font-family: Helvetica, Arial, sans-serif;
6 | }
7 |
8 | .app {
9 | overflow: auto
10 | }
11 |
12 | .code {
13 | width: 35%;
14 | float: left;
15 | margin-top: -100px;
16 | }
17 |
18 | .ast {
19 | width: 63%;
20 | float: right;
21 | }
22 |
23 | .full-screen.ast {
24 | width: 100%;
25 | float: none;
26 | }
27 |
28 | .input-form textarea {
29 | display: block;
30 | height: 300px;
31 | width: 100%;
32 | font-family: Courier, sans-serif;
33 | font-size: 14px;
34 | padding: 5px;
35 | }
36 |
37 | div.path code {
38 | position: fixed;
39 | z-index: 999;
40 | background: white;
41 | bottom: 20px;
42 | right: 20px;
43 | padding: 5px;
44 | }
45 |
46 | div.path code.hidden, .hidden { display: none; }
47 |
48 | .btn {
49 | border: none;
50 | display: inline-block;
51 | background: #498EE0;
52 | color: white;
53 | width: 200px;
54 | text-decoration: none;
55 | border-radius: 2px;
56 | text-align: center;
57 | padding: 10px;
58 | margin-left: 10px;
59 | font-size: 13px;
60 | margin-bottom: 5px;
61 | }
62 |
63 | .app-btns {
64 | float: right;
65 | }
66 |
67 | .btn:hover {
68 | text-decoration: underline;
69 | }
70 |
71 | .header {
72 | text-align: center;
73 | }
74 |
75 | .input-form input {
76 | margin: 10px 0 0 0;
77 | box-sizing: content-box;
78 | }
79 |
80 | #ace-editor {
81 | border: 1px solid black;
82 | position: relative;
83 | width: 100%;
84 | height: 300px;
85 | }
86 |
87 |
88 | .code-highlight {
89 | background: rgba(255, 50, 50, 0.1);
90 | position: absolute;
91 | width: 100% !important;
92 | left: 0 !important;
93 | }
94 |
95 | .toggle-icon {
96 | display: block;
97 | float: left;
98 | height: 20px;
99 | width: 20px;
100 | text-align: center;
101 | line-height: 20px;
102 | border-radius: 2px;
103 | background: #498EE0;
104 | color: white;
105 | text-decoration: none;
106 | }
107 |
108 | .ast ul, .ast-node ul {
109 | list-style: none;
110 | padding: 0 0 0 10px;
111 | margin: 0;
112 | }
113 |
114 | .ast li,
115 | .ast-node li {
116 | padding: 0;
117 | margin: 0;
118 | }
119 |
120 | .ast-node-head {
121 | padding: 3px;
122 | margin: 0 0 3px 0;
123 | background: #f8faff;
124 | border: 1px solid #dae2ea;
125 | overflow: auto;
126 | }
127 | .ast-node-head h4 {
128 | float: left;
129 | margin: 0;
130 | font-weight: normal;
131 | padding: 3px 0 0 6px;
132 | position: relative;
133 | width: 95%;
134 | }
135 |
136 | .node-location {
137 | position: absolute;
138 | right: 5px;
139 | top: 3px;
140 | }
141 |
142 | .ast-node li.node-property {
143 | margin-left: 20px;
144 | border: 1px solid #498EE0;
145 | border-left: 10px solid #498EE0;
146 | padding-left: 5px;
147 | margin-bottom: 3px;
148 | }
149 |
150 | .node-property, .node-key {
151 | font-family: Courier;
152 | }
153 |
154 | .node-property strong {
155 | padding-right: 5px;
156 | display: inline-block;
157 | font-weight: normal;
158 | font-family: Helvetica, Arial, sans-serif;
159 | }
160 |
161 |
--------------------------------------------------------------------------------