├── .gitignore ├── .travis.yml ├── docs └── jsnox-specstring.png ├── tests ├── test_autokey.js ├── test_trees.js └── test_parsing.js ├── package.json ├── LICENSE ├── .jshintrc ├── README.md └── jsnox.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.DS_Store 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4.0" 4 | - "0.12" 5 | - "0.10" 6 | -------------------------------------------------------------------------------- /docs/jsnox-specstring.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/af/JSnoX/HEAD/docs/jsnox-specstring.png -------------------------------------------------------------------------------- /tests/test_autokey.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var React = require('react') 3 | var d = require('..')(React) 4 | 5 | 6 | test('Does not set a key by default', function(t) { 7 | var vdom = d('div.foo') 8 | t.equal(vdom.key, null) 9 | t.end() 10 | }) 11 | 12 | test('Does set a key if spec string has ^ suffix', function(t) { 13 | var spec1 = 'div.foo^' 14 | t.equal(d(spec1).key, spec1) 15 | 16 | var spec2 = 'input:email#hi.foo.baz[placeholder=Email]^' 17 | t.equal(d(spec2).key, spec2) 18 | t.end() 19 | }) 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsnox", 3 | "version": "2.1.3", 4 | "description": "Write concise React components without JSX", 5 | "main": "jsnox.js", 6 | "scripts": { 7 | "jshint": "jshint jsnox.js tests", 8 | "test": "./node_modules/tape/bin/tape tests/*.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "http://github.com/af/jsnox" 13 | }, 14 | "keywords": [ 15 | "react", 16 | "reactjs", 17 | "jsx" 18 | ], 19 | "author": "Aaron Franks (http://aaronfranks.com/)", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/af/jsnox/issues" 23 | }, 24 | "homepage": "https://github.com/af/jsnox", 25 | "devDependencies": { 26 | "ghooks": "^0.3.0", 27 | "jshint": "2.7.0", 28 | "react": "15.0.1", 29 | "react-dom": "15.0.1", 30 | "tape": "^3.0.3" 31 | }, 32 | "config": { 33 | "ghooks": { 34 | "pre-push": "npm test && npm run jshint" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2014 Aaron Franks 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // JSHint config 3 | // See http://www.jshint.com/options/ for full config documentation 4 | 5 | "browser" : true, // Standard browser globals e.g. `window`, `document`. 6 | "node" : true, // For testing if "module" exists 7 | "debug" : false, // Allow debugger statements 8 | "devel" : false, // Allow development statements (eg. console.log) 9 | 10 | // EcmaScript 5. 11 | "strict" : false, // Require `use strict` pragma in every file. 12 | "globalstrict" : false, // Allow global "use strict" (enables "strict"). 13 | 14 | // Enforcing Options 15 | // These options tell JSHint to be more strict towards your code. 16 | "bitwise" : true, // Prohibit bitwise operators (&, |, ^, etc.). 17 | "curly" : false, // Requires {} for every new block or scope. 18 | "eqeqeq" : true, // Requires triple equals i.e. `===`. 19 | "forin" : false, // Requires `for in` loops to be filtered with 20 | // `hasOwnPrototype`. 21 | "immed" : true, // Requires IIFEs to be wrapped in parens 22 | // eg. `( function(){}() );` 23 | "latedef" : false, // Prohibits variable use before definition. 24 | "newcap" : false, // Requires capitalization of all constructors 25 | "noarg" : true, // Prohibits use of `arguments.caller` and `callee`. 26 | "noempty" : true, // Prohibits use of empty blocks. 27 | "nonew" : false, // Prohibits use of constructors for side-effects. 28 | "plusplus" : false, // Prohibits use of `++` & `--`. 29 | "regexp" : true, // Prohibits `.` and `[^...]` in regular expressions. 30 | "trailing" : true, // Prohibits trailing whitespaces. 31 | "undef" : true, // Requires all non-globals be declared before use. 32 | "unused" : "vars", // Warns when you define unused vars (but not fn args) 33 | 34 | // Relaxing Options 35 | // These options allow you to suppress certain types of warnings. 36 | "asi" : true, // Allows statements without semicolons 37 | "boss" : false, // Tolerates assignments inside if, for & while. 38 | "eqnull" : true, // Tolerates use of `== null`. 39 | "evil" : false, // Tolerates use of `eval`. 40 | "expr" : true, // Tolerates `ExpressionStatement` as Programs. 41 | "laxbreak" : false, // Tolerates unsafe line breaks 42 | // eg. `return [\n] x` without semicolons. 43 | "loopfunc" : false, // Allows functions to be defined within loops. 44 | "regexdash" : false, // Tolerates unescaped last dash i.e. `[-...]`. 45 | "scripturl" : true, // Tolerates script-targeted URLs. 46 | "shadow" : false, // Allows re-defined variables later in code 47 | // eg. `var x=1; x=2;`. 48 | "sub" : true, // Tolerates use of subscript notation 49 | // (eg. obj['key'] instead of obj.key). 50 | "supernew" : true, // Tolerate `new function()` and `new Object;`. 51 | "lastsemic" : true // Tolerate missing ; for final statements in blocks 52 | } 53 | -------------------------------------------------------------------------------- /tests/test_trees.js: -------------------------------------------------------------------------------- 1 | var test = require('tape') 2 | var React = require('react') 3 | var ReactDOM = require('react-dom/server') 4 | var d = require('..')(React) 5 | 6 | var render = function(domTree) { 7 | return ReactDOM.renderToStaticMarkup(domTree) 8 | } 9 | 10 | var Greeting = React.createClass({ 11 | displayName: 'Greeting', // Used to auto-generate a "key" prop 12 | render: function() { 13 | return React.DOM.div(null, this.props.text || 'hi') 14 | } 15 | }) 16 | 17 | 18 | test('trees of elements render correctly', function(t) { 19 | var tree = d('form.foo', 20 | d('input:email'), 21 | d('input:password'), 22 | d('button:submit', 'Submit') 23 | ) 24 | t.equal(render(tree), '
') 27 | t.end() 28 | }) 29 | 30 | test('rendering custom components and text nodes', function(t) { 31 | var tree = d('section#stuff', 32 | d('span', 'a greeting:'), 33 | d(Greeting, { text: 'yo' }), 34 | d('span', '!') 35 | ) 36 | t.equal(render(tree), '