| /** | ||
| * test-available.js - basic availability test. | ||
| */ | ||
| var corridor = require('../src/corridor.js'); | ||
| exports.testAvailable = function(test) { | ||
| test.expect(2); | ||
| test.ok(corridor, 'corridor exists'); | ||
| test.equals(Object.prototype.toString.call(corridor), '[object Function]', 'corridor is a function'); | ||
| test.done(); | ||
| }; |
| /** | ||
| * test-merge.js - tests the merge() function. | ||
| */ | ||
| var corridor = require('../src/corridor.js'); | ||
| exports.testMerge = function(test) { | ||
| var suite = [{ | ||
| obj: ['a'], | ||
| other: ['b'], | ||
| expected: ['a', 'b'], | ||
| reason: 'arrays of primitives should concatenate' | ||
| },{ | ||
| obj: [{a: 'hi'}], | ||
| other: [{b: 'there'}], | ||
| expected: [{a: 'hi'}, {b: 'there'}], | ||
| reason: 'arrays of objects should concatenate' | ||
| },{ | ||
| obj: {list: ['hi']}, | ||
| other: {list: ['there']}, | ||
| expected: {list: ['hi','there']}, | ||
| reason: 'nested arrays of primitives should concatenate' | ||
| },{ | ||
| obj: {list: ['hi'], foo: 7}, | ||
| other: {foo: 8, list: ['there']}, | ||
| expected: {list: ['hi','there'], foo: 8}, | ||
| reason: 'primitves should overwrite each other while arrays concatenate' | ||
| },{ | ||
| obj: {}, | ||
| other: { b: 'hi' }, | ||
| expected: { b: 'hi' }, | ||
| reason: 'all keys should be added to empty objects' | ||
| },{ | ||
| obj: { a: 'whut' }, | ||
| other: { b: 'hi' }, | ||
| expected: { a: 'whut', b: 'hi' }, | ||
| reason: 'missing keys should be added to non-empty objects' | ||
| } | ||
| ]; | ||
| test.expect(suite.length); | ||
| suite.forEach(function(data) { | ||
| var actual = corridor.merge(data.obj, data.other); | ||
| test.deepEqual(actual, data.expected, data.reason); | ||
| }); | ||
| test.done(); | ||
| }; | ||
+1
-1
@@ -139,3 +139,3 @@ <!doctype html> | ||
| (function(window, document, corridor, undefined){ | ||
| var | ||
@@ -142,0 +142,0 @@ |
+8
-2
| { | ||
| "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" | ||
| } | ||
| } |
+63
-6
| # 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 |
+84
-42
| /** | ||
| * 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'] | ||
| ); |
-44
| /** | ||
| * test.js - a couple of unit tests for intricate functionality. | ||
| */ | ||
| testMerge = corridor.testMerge = function() { | ||
| ([ | ||
| { | ||
| obj: ['a'], | ||
| other: ['b'], | ||
| expected: ['a', 'b'] | ||
| }, | ||
| { | ||
| obj: [{a: 'hi'}], | ||
| other: [{b: 'there'}], | ||
| expected: [{a: 'hi'}, {b: 'there'}] | ||
| }, | ||
| { | ||
| obj: {list: ['hi']}, | ||
| other: {list: ['there']}, | ||
| expected: {list: ['hi','there']} | ||
| }, | ||
| { | ||
| obj: {list: ['hi'], foo: 7}, | ||
| other: {foo: 8, list: ['there']}, | ||
| expected: {list: ['hi','there'], foo: 8} | ||
| }, | ||
| { | ||
| obj: {}, | ||
| other: { b: 'hi' }, | ||
| expected: { b: 'hi' } | ||
| }, | ||
| { | ||
| obj: { a: 'whut' }, | ||
| other: { b: 'hi' }, | ||
| expected: { a: 'whut', b: 'hi' } | ||
| }, | ||
| ]).forEach(function(test) { | ||
| var actual = merge(test.obj, test.other); | ||
| if (JSON.stringify(actual) !== JSON.stringify(test.expected)) { | ||
| console.log(["FAILED", test.expected, actual]); | ||
| } | ||
| }); | ||
| console.log("PASS"); | ||
| }; | ||
Sorry, the diff of this file is not supported yet
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
54718
8.91%11
10%1024
4.38%271
26.64%1
Infinity%