Comparing version 0.1.3 to 0.1.4
{ | ||
"name": "corridor", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "JSON/DOM data corridor for data-binding", | ||
@@ -17,3 +17,9 @@ "repository": { | ||
"license": "MIT", | ||
"readmeFilename": "README.md" | ||
"readmeFilename": "README.md", | ||
"scripts": { | ||
"test": "./node_modules/nodeunit/bin/nodeunit ./test" | ||
}, | ||
"devDependencies": { | ||
"nodeunit": "~0.8.1" | ||
} | ||
} |
# corridor | ||
JSON/DOM data corridor. | ||
Data binding without the fuss. | ||
**{json} → <html> → {json}** | ||
Bi-directional data binding without the fuss. | ||
## why corridor | ||
Your data is in JSON, but your users interact with HTML. | ||
corridor's singular mission is to shuttle your data between your JSON and your HTML. | ||
It is a runtime library, not a templating language. | ||
corridor runs in the browser, able to transfer your data both ways: from form fields to JSON and back again. | ||
## getting corridor | ||
corridor is just a single js file. | ||
corridor is a single js file with no dependencies. | ||
You can get it in either of two ways: | ||
@@ -17,9 +27,15 @@ * from github: grab [corridor.js](https://github.com/jimbojw/corridor/blob/master/src/corridor.js) out of the [corridor repo](https://github.com/jimbojw/corridor) | ||
## using corridor | ||
## corridor tutorial | ||
It would be great if users could just edit JSON directly. | ||
That way, your REST API would be all you'd need. | ||
But unfortunately, your users interact with the Document Object Model (DOM) representation of your HTML. | ||
Which means that it's your job to figure out how to get these two views of the data to match. | ||
The corridor library has only one function called `corridor()`. | ||
This function does one of two things: | ||
* extract data out of a DOM heirarchy, or | ||
* insert data into a DOM heirarchy. | ||
* extract data out of a DOM heirarchy (form elements), or | ||
* insert data into the DOM. | ||
@@ -212,4 +228,45 @@ It knows how to shuttle data back and forth by looking at HTML5 data attributes on the DOM elements. | ||
## issues and feature requests | ||
If you find any issues with corridor, or if you'd like to request a feature, please head over to the [issues page on github](https://github.com/jimbojw/corridor/issues). | ||
Keep in mind that the more specific you are, the more likely your issue or feature is to be addressed. | ||
## questions | ||
If you have a question about how to use corridor, or if you're not sure if you're doing it right, go to [stackoverflow](http://stackoverflow.com/) and [ask a question](http://stackoverflow.com/questions/ask?tags=corridor). | ||
Make sure you add the `corridor` tag to your question. | ||
## developing corridor | ||
If you're interested in developing corridor, great! | ||
Start by forking [corridor on github](https://github.com/jimbojw/corridor). | ||
Once you've forked the project, clone it using `git clone`: | ||
```sh | ||
$ git clone git@github.com:<YOUR_USERNAME>/corridor.git | ||
``` | ||
corridor uses npm for packaging and deployment, so you'll need to install Node.js if you haven't already. | ||
Once you have node, you can pull in corridor's development dependencies: | ||
```sh | ||
$ npm install | ||
``` | ||
After installing the dependencies, you can run the unit tests: | ||
```sh | ||
$ npm test | ||
``` | ||
The source code for corridor is in the `src/` directory, and unit tests are under `test/`. | ||
corridor's unit tests are written for [nodeunit](https://npmjs.org/package/nodeunit). | ||
When you're satisfied with your changes, commit them and push them to your forked repository. | ||
Then open a pull request in github by hitting the big "Pull Request" button from the main project repo page. | ||
## License | ||
See LICENSE |
/** | ||
* corridor.js | ||
* | ||
* corridor is written to run in either a Node.js context or a browser context. | ||
* The context and property objects are used to know how to export corridor. | ||
* | ||
* @param {mixed} context The context object (either module or window) | ||
* @param {string} property The name of the key to assign on the context object (either 'exports' or 'corridor') | ||
*/ | ||
(function(window, document, undefined){ | ||
(function(context, property, undefined){ | ||
'use strict'; | ||
@@ -12,2 +18,4 @@ | ||
document = context.document || null, | ||
/** | ||
@@ -28,9 +36,10 @@ * Internal logging function. | ||
/** | ||
* Extract data from DOM or insert values back into it. | ||
* @param {HTMLElement} elem The element to scan for data (defaults to document) | ||
* Extract data from the DOM or insert values back into it. | ||
* @param {HTMLElement} root The element to scan for data (defaults to document) | ||
* @param {mixed} data The data to insert (optional) | ||
* @param {object} opts Hash of options (optional) | ||
*/ | ||
corridor = window['corridor'] = function(elem, data) { | ||
elem = elem || document; | ||
return data ? insert(elem, data) : extract(elem); | ||
corridor = context[property] = function(root, data, opts) { | ||
root = root || document; | ||
return data ? insert(root, data, opts) : extract(root, opts); | ||
}, | ||
@@ -41,33 +50,43 @@ | ||
* @param {HTMLElement} root The root element to scan for data. | ||
* @param {object} opts Hash of options (optional) | ||
*/ | ||
extract = corridor.extract = function(root) { | ||
extract = corridor.extract = function(root, opts) { | ||
root = root || document; | ||
var data = {}; | ||
// fail fast if there's no root element to use | ||
if (!root) { | ||
throw Error('corridor requires a queryable root element to insert data into'); | ||
} | ||
var | ||
settings = extend({}, defaults, opts), | ||
data = {}, | ||
fields = slice.call(root.querySelectorAll('[data-field]')).filter(hasVal); | ||
slice.call(root.querySelectorAll('[data-field]')) | ||
.filter(hasVal) | ||
.filter(enabled) | ||
.forEach(function(elem) { | ||
if (settings.enabledOnly) { | ||
fields = fields.filter(enabled); | ||
} | ||
var | ||
opts = options(elem, defaults), | ||
value = val(elem); | ||
if (opts.empty === 'omit' && !value) { | ||
return; | ||
} | ||
// create type-specific value string | ||
value = JSON.stringify(coerce(value, opts.type, opts)); | ||
// build out full contribution | ||
value = buildup(value, elem, root); | ||
// merge contribution into the result data | ||
merge(data, JSON.parse(value)); | ||
}); | ||
fields.forEach(function(elem) { | ||
var | ||
opts = options(elem, settings), | ||
value = val(elem); | ||
if (opts.empty === 'omit' && !value) { | ||
return; | ||
} | ||
// create type-specific value string | ||
value = JSON.stringify(coerce(value, opts.type, opts)); | ||
// build out full contribution | ||
value = buildup(value, elem, root); | ||
// merge contribution into the result data | ||
merge(data, JSON.parse(value)); | ||
}); | ||
return data; | ||
@@ -79,15 +98,31 @@ | ||
* Insert data into the DOM under the specified element from provided data. | ||
* @param {HTMLElement} root The element to scan for insertion fields. | ||
* @param {HTMLElement} root The element to scan for insertion fields (optional). | ||
* @param {mixed} data The data to insert. | ||
*/ | ||
insert = corridor.insert = function(root, data) { | ||
insert = corridor.insert = function(root, data, opts) { | ||
// data structure for existing fields | ||
// used to figure out true contribution paths for inserting data into elements | ||
var workspace = {}; | ||
// allow root to be optional | ||
root = root || document; | ||
// fail fast if there's no root element to use | ||
if (!root) { | ||
throw Error('corridor requires a queryable root element to insert data into'); | ||
} | ||
var | ||
settings = extend({}, defaults, opts), | ||
// data structure for existing fields | ||
// used to figure out true contribution paths for inserting data into elements | ||
workspace = {}, | ||
fields = slice.call(root.querySelectorAll('[data-field]')).filter(hasVal); | ||
if (settings.enabledOnly) { | ||
fields = fields.filter(enabled); | ||
} | ||
// for each value'd, enabled data-field | ||
slice.call(root.querySelectorAll('[data-field]')) | ||
.filter(hasVal) | ||
.filter(enabled) | ||
fields | ||
.map(function(elem) { | ||
@@ -110,3 +145,3 @@ | ||
var | ||
opts = options(elem, defaults), | ||
opts = options(elem, settings), | ||
node = workspace; | ||
@@ -148,3 +183,3 @@ while (pathCopy.length > 1) { | ||
/** | ||
* Default values applied to data-opts. | ||
* Default values applied to options. | ||
*/ | ||
@@ -179,4 +214,9 @@ defaults = corridor.defaults = { | ||
*/ | ||
type: "string" | ||
type: "string", | ||
/** | ||
* Only operate on enabled fields when this is true (the default). | ||
*/ | ||
enabledOnly: true | ||
}, | ||
@@ -522,2 +562,4 @@ | ||
})(window, document); | ||
}).apply(null, | ||
typeof module === 'object' ? [module, 'exports'] : [window, 'corridor'] | ||
); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54718
11
1024
271
1