diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-05-03 15:35:00 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-05-03 15:35:00 +0200 |
commit | de98e0b232509d5f40c135d540a70e415272ff85 (patch) | |
tree | a79222a5b58484ab3b80d18efcaaa7ccc4769b33 /node_modules/dom-converter | |
parent | e0c9d480a73fa629c1e4a47d3e721f1d2d345406 (diff) |
node_modules
Diffstat (limited to 'node_modules/dom-converter')
24 files changed, 1191 insertions, 0 deletions
diff --git a/node_modules/dom-converter/.npmignore b/node_modules/dom-converter/.npmignore new file mode 100644 index 000000000..63370de0a --- /dev/null +++ b/node_modules/dom-converter/.npmignore @@ -0,0 +1,13 @@ +*.bat +.htaccess + +xeno/** +node_modules +scripts/dist + +-p + +npm-debug.log +!*.gitkeep + +pg
\ No newline at end of file diff --git a/node_modules/dom-converter/Cakefile b/node_modules/dom-converter/Cakefile new file mode 100644 index 000000000..b56014375 --- /dev/null +++ b/node_modules/dom-converter/Cakefile @@ -0,0 +1,86 @@ +
+exec = require('child_process').exec
+fs = require 'fs'
+sysPath = require 'path'
+
+task 'compile:coffee', ->
+
+ unless fs.existsSync './scripts/js'
+
+ fs.mkdirSync './scripts/js'
+
+ exec 'node ./node_modules/coffee-script/bin/coffee -bco ./scripts/js ./scripts/coffee',
+
+ (error) ->
+
+ if fs.existsSync '-p'
+
+ fs.rmdirSync '-p'
+
+ if error?
+
+ console.log 'Compile failed: ' + error
+
+ return
+
+task 'build', ->
+
+ invoke 'compile:coffee'
+
+# This is in place until we replace the test suite runner with popo
+task 'test', ->
+
+ runTestsIn 'scripts/coffee/test', '_prepare.coffee'
+
+runInCoffee = (path, cb) ->
+
+ exec 'node ./node_modules/coffee-script/bin/coffee ' + path, cb
+
+runTestsIn = (shortPath, except) ->
+
+ fullPath = sysPath.resolve shortPath
+
+ fs.readdir fullPath, (err, files) ->
+
+ if err then throw Error err
+
+ for file in files
+
+ return if file is except
+
+ fullFilePath = sysPath.resolve(fullPath, file)
+ shortFilePath = shortPath + '/' + file
+
+ if sysPath.extname(file) is '.coffee'
+
+ runAsTest shortFilePath, fullFilePath
+
+ else if fs.statSync(fullFilePath).isDirectory()
+
+ runTestsIn shortFilePath
+
+ return
+
+didBeep = no
+
+runAsTest = (shortPath, fullPath) ->
+
+ runInCoffee fullPath, (error, stdout, stderr) ->
+
+ output = 'Running ' + shortPath + '\n'
+
+ if stderr
+
+ unless didBeep
+
+ `console.log("\007")`
+
+ didBeep = yes
+
+ output += 'Error\n' + stdout + stderr + '\n'
+
+ else if stdout
+
+ output += '\n' + stdout
+
+ console.log output
\ No newline at end of file diff --git a/node_modules/dom-converter/LICENSE b/node_modules/dom-converter/LICENSE new file mode 100644 index 000000000..0641f709b --- /dev/null +++ b/node_modules/dom-converter/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Aria Minaei + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/node_modules/dom-converter/README.md b/node_modules/dom-converter/README.md new file mode 100644 index 000000000..da794892b --- /dev/null +++ b/node_modules/dom-converter/README.md @@ -0,0 +1,3 @@ +Converts bare objects to DOM objects, compatible with htmlparser2's DOM objects.
+
+This is useful when you want to work with DOM without having to compose/parse html.
\ No newline at end of file diff --git a/node_modules/dom-converter/package.json b/node_modules/dom-converter/package.json new file mode 100644 index 000000000..82117d552 --- /dev/null +++ b/node_modules/dom-converter/package.json @@ -0,0 +1,26 @@ +{ + "name": "dom-converter", + "version": "0.1.4", + "description": "converts bare objects to DOM objects or xml representations", + "main": "scripts/js/lib/domConverter.js", + "dependencies": { + "utila": "~0.3" + }, + "devDependencies": { + "coffee-script": "~1.6.3", + "little-popo": "~0.1" + }, + "scripts": { + "test": "node ./node_modules/coffee-script/bin/cake test", + "prepublish": "node ./node_modules/coffee-script/bin/cake build" + }, + "author": "Aria Minaei", + "license": "MIT", + "repository": { + "type": "git", + "url": "https://github.com/AriaMinaei/dom-converter" + }, + "bugs": { + "url": "https://github.com/AriaMinaei/dom-converter/issues" + } +} diff --git a/node_modules/dom-converter/scripts/coffee/lib/domConverter.coffee b/node_modules/dom-converter/scripts/coffee/lib/domConverter.coffee new file mode 100644 index 000000000..d7dce7303 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/lib/domConverter.coffee @@ -0,0 +1,32 @@ +objectToSaneObject = require './objectToSaneObject'
+saneObjectToDom = require './saneObjectToDom'
+domToMarkup = require './domToMarkup'
+{object} = require 'utila'
+
+module.exports = self =
+
+ objectToDom: (o) ->
+
+ o = self._object2SaneObject o
+
+ saneObjectToDom.convert o
+
+ object2markup: (o) ->
+
+ dom = self.toDom o
+
+ domToMarkup.convert dom
+
+ domToMarkup: (dom) ->
+
+ domToMarkup.convert dom
+
+ _object2SaneObject: (o) ->
+
+ unless Array.isArray o
+
+ unless object.isBareObject o
+
+ throw Error "toDom() only accepts arrays and bare objects as input"
+
+ objectToSaneObject.sanitize o
\ No newline at end of file diff --git a/node_modules/dom-converter/scripts/coffee/lib/domToMarkup.coffee b/node_modules/dom-converter/scripts/coffee/lib/domToMarkup.coffee new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/lib/domToMarkup.coffee diff --git a/node_modules/dom-converter/scripts/coffee/lib/objectToSaneObject.coffee b/node_modules/dom-converter/scripts/coffee/lib/objectToSaneObject.coffee new file mode 100644 index 000000000..74f114aa1 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/lib/objectToSaneObject.coffee @@ -0,0 +1,80 @@ +{object} = require 'utila'
+
+module.exports = self =
+
+ sanitize: (val) ->
+
+ self._toChildren val
+
+ _toChildren: (val) ->
+
+ if object.isBareObject val
+
+ return self._objectToChildren val
+
+ else if Array.isArray val
+
+ return self._arrayToChildren val
+
+ else if val is null or typeof val is 'undefined'
+
+ return []
+
+ else if typeof val in ['string', 'number']
+
+ return [String val]
+
+ else
+
+ throw Error "not a valid child node: `#{val}"
+
+ _objectToChildren: (o) ->
+
+ a = []
+
+ for own key, val of o
+
+ cur = {}
+
+ cur[key] = self.sanitize val
+
+ a.push cur
+
+ a
+
+ _arrayToChildren: (a) ->
+
+ ret = []
+
+ for v in a
+
+ ret.push self._toNode v
+
+ ret
+
+ _toNode: (o) ->
+
+ if typeof o in ['string', 'number']
+
+ return String o
+
+ else if object.isBareObject o
+
+ keys = Object.keys(o)
+
+ if keys.length isnt 1
+
+ throw Error "a node must only have one key as tag name"
+
+ key = keys[0]
+
+ obj = {}
+
+ obj[key] = self._toChildren o[key]
+
+ return obj
+
+ else
+
+ throw Error "not a valid node: `#{o}`"
+
diff --git a/node_modules/dom-converter/scripts/coffee/lib/saneObjectToDom.coffee b/node_modules/dom-converter/scripts/coffee/lib/saneObjectToDom.coffee new file mode 100644 index 000000000..58519b9c2 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/lib/saneObjectToDom.coffee @@ -0,0 +1,148 @@ +module.exports = self =
+
+ convert: (obj) ->
+
+ self._arrayToChildren obj
+
+ _arrayToChildren: (a, parent = null) ->
+
+ children = []
+
+ prev = null
+
+ for v in a
+
+ if typeof v is 'string'
+
+ node = self._getTextNodeFor v
+
+ else
+
+ node = self._objectToNode v, parent
+
+ node.prev = null
+ node.next = null
+ node.parent = parent
+
+ if prev?
+
+ node.prev = prev
+ prev.next = node
+
+ prev = node
+
+ children.push node
+
+ children
+
+ _objectToNode: (o) ->
+
+ i = 0
+
+ for own k, v of o
+
+ if i > 0
+
+ throw Error "_objectToNode() only accepts an object with one key/value"
+
+ key = k
+ val = v
+
+ i++
+
+ node = {}
+
+ if typeof key isnt 'string'
+
+ throw Error "_objectToNode()'s key must be a string of tag name and classes"
+
+ if typeof val is 'string'
+
+ children = [self._getTextNodeFor(val)]
+
+ else if Array.isArray val
+
+ children = self._arrayToChildren val, node
+
+ else
+
+ inspect o
+ throw Error "_objectToNode()'s key's value must only be a string or an array"
+
+ node.type = 'tag'
+ {name, attribs} = self._parseTag key
+ node.name = name
+ node.attribs = attribs
+ node.children = children
+
+ node
+
+ _getTextNodeFor: (s) ->
+
+ {type: 'text', data: s}
+
+ _nameRx: /^[a-zA-Z\-\_]{1}[a-zA-Z0-9\-\_]*$/
+
+ _parseTag: (k) ->
+
+ # validate
+ if not k.match(/^[a-zA-Z0-9\#\-\_\.\[\]\"\'\=\,\s]+$/) or k.match(/^[0-9]+/)
+
+ throw Error "cannot parse tag `#{k}`"
+
+ attribs = {}
+
+ parts =
+
+ name: ''
+
+ attribs: attribs
+
+ # tag name
+ if m = k.match /^([^\.#]+)/
+
+ name = m[1]
+
+ unless name.match self._nameRx
+
+ throw Error "tag name `#{name}` is not valid"
+
+ parts.name = name
+
+ k = k.substr name.length, k.length
+
+ # tag id
+ if m = k.match /^#([a-zA-Z0-9\-]+)/
+
+ id = m[1]
+
+ unless id.match self._nameRx
+
+ throw Error "tag id `#{id}` is not valid"
+
+ attribs.id = id
+
+ k = k.substr id.length + 1, k.length
+
+ classes = []
+
+ # the class attrib
+ while m = k.match /\.([a-zA-Z0-9\-\_]+)/
+
+ cls = m[1]
+
+ unless cls.match self._nameRx
+
+ throw Error "tag class `#{cls}` is not valid"
+
+ classes.push cls
+
+ k = k.replace '.' + cls, ''
+
+ if classes.length
+
+ attribs.class = classes.join " "
+
+ # TODO: match attributes like [a=b]
+
+ parts
\ No newline at end of file diff --git a/node_modules/dom-converter/scripts/coffee/test/_prepare.coffee b/node_modules/dom-converter/scripts/coffee/test/_prepare.coffee new file mode 100644 index 000000000..e2b854968 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/test/_prepare.coffee @@ -0,0 +1,5 @@ +path = require 'path' + +pathToLib = path.resolve __dirname, '../../js/lib' + +require('little-popo')(pathToLib, no)
\ No newline at end of file diff --git a/node_modules/dom-converter/scripts/coffee/test/domConverter.coffee b/node_modules/dom-converter/scripts/coffee/test/domConverter.coffee new file mode 100644 index 000000000..62d13ad11 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/test/domConverter.coffee @@ -0,0 +1,17 @@ +require './_prepare'
+
+domConverter = mod 'domConverter'
+
+describe "input types"
+
+it "should work with objects", ->
+
+ domConverter.objectToDom {}
+
+it "should work with arrays", ->
+
+ domConverter.objectToDom []
+
+it "should not work with other types", ->
+
+ (-> domConverter.objectToDom 'a').should.throw Error
\ No newline at end of file diff --git a/node_modules/dom-converter/scripts/coffee/test/objectToSaneObject.coffee b/node_modules/dom-converter/scripts/coffee/test/objectToSaneObject.coffee new file mode 100644 index 000000000..4673f2c57 --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/test/objectToSaneObject.coffee @@ -0,0 +1,73 @@ +require './_prepare'
+
+objectToSaneObject = mod 'objectToSaneObject'
+
+describe "sanitize()"
+
+test "case: 'text'", ->
+
+ input = 'text'
+
+ expectation = ['text']
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
+
+test "case: ['text']", ->
+
+ input = ['text']
+
+ expectation = ['text']
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
+
+test "case: {a:b}", ->
+
+ input = a: 'b'
+
+ expectation = [{a: ['b']}]
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
+
+test "case: {a:[b: 'c']}", ->
+
+ input = a: [b: 'c']
+
+ expectation = [{a: [{b: ['c']}]}]
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
+
+test "case: {a:b: 'c'}", ->
+
+ input = a: b: 'c'
+
+ expectation = [{
+ a: [{
+ b: ['c']
+ }]
+ }]
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
+
+test "case: {a:b: ['c', d: 'e']}", ->
+
+ input = a: b: ['c', d: 'e']
+
+ expectation = [{
+ a: [{
+ b: ['c', {d: ['e']}]
+ }]
+ }]
+
+ ret = objectToSaneObject.sanitize input
+
+ ret.should.be.like expectation
\ No newline at end of file diff --git a/node_modules/dom-converter/scripts/coffee/test/saneObjectToDom.coffee b/node_modules/dom-converter/scripts/coffee/test/saneObjectToDom.coffee new file mode 100644 index 000000000..661db8fcf --- /dev/null +++ b/node_modules/dom-converter/scripts/coffee/test/saneObjectToDom.coffee @@ -0,0 +1,79 @@ +require './_prepare'
+
+s2d = mod 'saneObjectToDom'
+
+describe "_arrayToChildren()"
+
+it "should work", ->
+
+ ret = s2d._arrayToChildren [
+
+ {
+ a: 'text'
+ }
+ {
+ 'b.someClass': ['b1', 'b2']
+ }
+ {
+ c: [
+
+ {d: 'text'}
+ {e: []}
+
+ ]
+ }
+
+ ]
+
+ ret.should.be.an 'array'
+ ret.should.have.length.of 3
+
+ for node in ret
+
+ node.should.be.an 'object'
+ node.should.have
+ .keys ['type', 'name', 'attribs', 'children', 'next', 'prev', 'parent']
+
+ a = ret[0]
+
+ a.children.should.be.an 'array'
+ a.children.should.have.length.of 1
+
+ aChild = a.children[0]
+ aChild.should.be.an 'object'
+ aChild.should.be.like {type: 'text', data: 'text'}
+
+ expect(a.prev).to.equal null
+ expect(a.parent).to.equal null
+
+ b = ret[1]
+
+ a.next.should.equal b
+ b.prev.should.equal a
+ b.attribs.should.be.like
+
+ class: 'someClass'
+
+ bChildren = b.children
+
+ bChildren[0].should.be.like {type: 'text', data: 'b1'}
+ bChildren[1].should.be.like {type: 'text', data: 'b2'}
+
+ ret.should.have.deep.property '[2].children[1].name', 'e'
+
+
+describe "_parseTag"
+
+it "should work", ->
+
+ s2d.
+ _parseTag('tagName#id.c1.c2[a=b, d="1 2 3"]')
+ .should.be.like
+
+ name: 'tagName'
+
+ attribs:
+
+ id: 'id'
+
+ class: 'c1 c2'
diff --git a/node_modules/dom-converter/scripts/js/lib/domConverter.js b/node_modules/dom-converter/scripts/js/lib/domConverter.js new file mode 100644 index 000000000..5e7f8d334 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/domConverter.js @@ -0,0 +1,33 @@ +// Generated by CoffeeScript 1.6.3 +var domToMarkup, object, objectToSaneObject, saneObjectToDom, self; + +objectToSaneObject = require('./objectToSaneObject'); + +saneObjectToDom = require('./saneObjectToDom'); + +domToMarkup = require('./domToMarkup'); + +object = require('utila').object; + +module.exports = self = { + objectToDom: function(o) { + o = self._object2SaneObject(o); + return saneObjectToDom.convert(o); + }, + object2markup: function(o) { + var dom; + dom = self.toDom(o); + return domToMarkup.convert(dom); + }, + domToMarkup: function(dom) { + return domToMarkup.convert(dom); + }, + _object2SaneObject: function(o) { + if (!Array.isArray(o)) { + if (!object.isBareObject(o)) { + throw Error("toDom() only accepts arrays and bare objects as input"); + } + } + return objectToSaneObject.sanitize(o); + } +}; diff --git a/node_modules/dom-converter/scripts/js/lib/domToMarkup.js b/node_modules/dom-converter/scripts/js/lib/domToMarkup.js new file mode 100644 index 000000000..38c1a97c6 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/domToMarkup.js @@ -0,0 +1,2 @@ +// Generated by CoffeeScript 1.6.3 + diff --git a/node_modules/dom-converter/scripts/js/lib/dummer.js b/node_modules/dom-converter/scripts/js/lib/dummer.js new file mode 100644 index 000000000..11fc31280 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/dummer.js @@ -0,0 +1,123 @@ +var dummer, object, sanitizer, + __hasProp = {}.hasOwnProperty; + +object = require('utila').object; + +sanitizer = require('./sanitizer'); + +module.exports = dummer = { + toDom: function(o) { + if (!Array.isArray(o)) { + if (!object.isBareObject(o)) { + throw Error("toDom() only accepts arrays and bare objects as input"); + } + } + o = sanitizer.sanitize(o); + return dummer._children(o); + }, + _children: function(a, parent) { + var children, node, prev, v, _i, _len; + if (parent == null) { + parent = null; + } + children = []; + prev = null; + for (_i = 0, _len = a.length; _i < _len; _i++) { + v = a[_i]; + if (typeof v === 'string') { + node = dummer._textNode(v); + } else { + node = dummer._objectToDom(v, parent); + node.prev = null; + node.next = null; + node.parent = parent; + if (prev != null) { + node.prev = prev; + prev.next = node; + } + prev = node; + } + children.push(node); + } + return children; + }, + _objectToDom: function(o) { + var attribs, children, i, k, key, name, node, v, val, _ref; + i = 0; + for (k in o) { + if (!__hasProp.call(o, k)) continue; + v = o[k]; + if (i > 0) { + throw Error("_objectToDom() only accepts an object with one key/value"); + } + key = k; + val = v; + i++; + } + node = {}; + if (typeof key !== 'string') { + throw Error("_objectToDom()'s key must be a string of tag name and classes"); + } + if (typeof val === 'string') { + children = [dummer._textNode(val)]; + } else if (Array.isArray(val)) { + children = dummer._children(val, node); + } else { + inspect(o); + throw Error("_objectToDom()'s key's value must only be a string or an array"); + } + node.type = 'tag'; + _ref = dummer._parseTag(key), name = _ref.name, attribs = _ref.attribs; + node.name = name; + node.attribs = attribs; + node.children = children; + return node; + }, + _textNode: function(s) { + return { + type: 'text', + data: s + }; + }, + _nameRx: /^[a-zA-Z\-\_]{1}[a-zA-Z0-9\-\_]*$/, + _parseTag: function(k) { + var attribs, classes, cls, id, m, name, parts; + if (!k.match(/^[a-zA-Z0-9\#\-\_\.\[\]\"\'\=\,\s]+$/) || k.match(/^[0-9]+/)) { + throw Error("cannot parse tag `" + k + "`"); + } + attribs = {}; + parts = { + name: '', + attribs: attribs + }; + if (m = k.match(/^([^\.#]+)/)) { + name = m[1]; + if (!name.match(dummer._nameRx)) { + throw Error("tag name `" + name + "` is not valid"); + } + parts.name = name; + k = k.substr(name.length, k.length); + } + if (m = k.match(/^#([a-zA-Z0-9\-]+)/)) { + id = m[1]; + if (!id.match(dummer._nameRx)) { + throw Error("tag id `" + id + "` is not valid"); + } + attribs.id = id; + k = k.substr(id.length + 1, k.length); + } + classes = []; + while (m = k.match(/\.([a-zA-Z0-9\-\_]+)/)) { + cls = m[1]; + if (!cls.match(dummer._nameRx)) { + throw Error("tag class `" + cls + "` is not valid"); + } + classes.push(cls); + k = k.replace('.' + cls, ''); + } + if (classes.length) { + attribs["class"] = classes.join(" "); + } + return parts; + } +}; diff --git a/node_modules/dom-converter/scripts/js/lib/objectToSaneObject.js b/node_modules/dom-converter/scripts/js/lib/objectToSaneObject.js new file mode 100644 index 000000000..fcfd90521 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/objectToSaneObject.js @@ -0,0 +1,63 @@ +// Generated by CoffeeScript 1.6.3 +var object, self, + __hasProp = {}.hasOwnProperty; + +object = require('utila').object; + +module.exports = self = { + sanitize: function(val) { + return self._toChildren(val); + }, + _toChildren: function(val) { + var _ref; + if (object.isBareObject(val)) { + return self._objectToChildren(val); + } else if (Array.isArray(val)) { + return self._arrayToChildren(val); + } else if (val === null || typeof val === 'undefined') { + return []; + } else if ((_ref = typeof val) === 'string' || _ref === 'number') { + return [String(val)]; + } else { + throw Error("not a valid child node: `" + val); + } + }, + _objectToChildren: function(o) { + var a, cur, key, val; + a = []; + for (key in o) { + if (!__hasProp.call(o, key)) continue; + val = o[key]; + cur = {}; + cur[key] = self.sanitize(val); + a.push(cur); + } + return a; + }, + _arrayToChildren: function(a) { + var ret, v, _i, _len; + ret = []; + for (_i = 0, _len = a.length; _i < _len; _i++) { + v = a[_i]; + ret.push(self._toNode(v)); + } + return ret; + }, + _toNode: function(o) { + var key, keys, obj, _ref; + if ((_ref = typeof o) === 'string' || _ref === 'number') { + return String(o); + } else if (object.isBareObject(o)) { + keys = Object.keys(o); + if (keys.length !== 1) { + throw Error("a node must only have one key as tag name"); + } + key = keys[0]; + obj = {}; + obj[key] = self._toChildren(o[key]); + return obj; + } else { + throw Error("not a valid node: `" + o + "`"); + } + } +}; diff --git a/node_modules/dom-converter/scripts/js/lib/saneObjectToDom.js b/node_modules/dom-converter/scripts/js/lib/saneObjectToDom.js new file mode 100644 index 000000000..09bcb9a71 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/saneObjectToDom.js @@ -0,0 +1,114 @@ +// Generated by CoffeeScript 1.6.3 +var self, + __hasProp = {}.hasOwnProperty; + +module.exports = self = { + convert: function(obj) { + return self._arrayToChildren(obj); + }, + _arrayToChildren: function(a, parent) { + var children, node, prev, v, _i, _len; + if (parent == null) { + parent = null; + } + children = []; + prev = null; + for (_i = 0, _len = a.length; _i < _len; _i++) { + v = a[_i]; + if (typeof v === 'string') { + node = self._getTextNodeFor(v); + } else { + node = self._objectToNode(v, parent); + node.prev = null; + node.next = null; + node.parent = parent; + if (prev != null) { + node.prev = prev; + prev.next = node; + } + prev = node; + } + children.push(node); + } + return children; + }, + _objectToNode: function(o) { + var attribs, children, i, k, key, name, node, v, val, _ref; + i = 0; + for (k in o) { + if (!__hasProp.call(o, k)) continue; + v = o[k]; + if (i > 0) { + throw Error("_objectToNode() only accepts an object with one key/value"); + } + key = k; + val = v; + i++; + } + node = {}; + if (typeof key !== 'string') { + throw Error("_objectToNode()'s key must be a string of tag name and classes"); + } + if (typeof val === 'string') { + children = [self._getTextNodeFor(val)]; + } else if (Array.isArray(val)) { + children = self._arrayToChildren(val, node); + } else { + inspect(o); + throw Error("_objectToNode()'s key's value must only be a string or an array"); + } + node.type = 'tag'; + _ref = self._parseTag(key), name = _ref.name, attribs = _ref.attribs; + node.name = name; + node.attribs = attribs; + node.children = children; + return node; + }, + _getTextNodeFor: function(s) { + return { + type: 'text', + data: s + }; + }, + _nameRx: /^[a-zA-Z\-\_]{1}[a-zA-Z0-9\-\_]*$/, + _parseTag: function(k) { + var attribs, classes, cls, id, m, name, parts; + if (!k.match(/^[a-zA-Z0-9\#\-\_\.\[\]\"\'\=\,\s]+$/) || k.match(/^[0-9]+/)) { + throw Error("cannot parse tag `" + k + "`"); + } + attribs = {}; + parts = { + name: '', + attribs: attribs + }; + if (m = k.match(/^([^\.#]+)/)) { + name = m[1]; + if (!name.match(self._nameRx)) { + throw Error("tag name `" + name + "` is not valid"); + } + parts.name = name; + k = k.substr(name.length, k.length); + } + if (m = k.match(/^#([a-zA-Z0-9\-]+)/)) { + id = m[1]; + if (!id.match(self._nameRx)) { + throw Error("tag id `" + id + "` is not valid"); + } + attribs.id = id; + k = k.substr(id.length + 1, k.length); + } + classes = []; + while (m = k.match(/\.([a-zA-Z0-9\-\_]+)/)) { + cls = m[1]; + if (!cls.match(self._nameRx)) { + throw Error("tag class `" + cls + "` is not valid"); + } + classes.push(cls); + k = k.replace('.' + cls, ''); + } + if (classes.length) { + attribs["class"] = classes.join(" "); + } + return parts; + } +}; diff --git a/node_modules/dom-converter/scripts/js/lib/saneObjectToMarkup.js b/node_modules/dom-converter/scripts/js/lib/saneObjectToMarkup.js new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/saneObjectToMarkup.js @@ -0,0 +1 @@ + diff --git a/node_modules/dom-converter/scripts/js/lib/sanitizer.js b/node_modules/dom-converter/scripts/js/lib/sanitizer.js new file mode 100644 index 000000000..726039563 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/lib/sanitizer.js @@ -0,0 +1,62 @@ +var object, sanitizer, + __hasProp = {}.hasOwnProperty; + +object = require('utila').object; + +module.exports = sanitizer = { + sanitize: function(val) { + return sanitizer._sanitizeAsChildren(val); + }, + _sanitizeAsChildren: function(val) { + var _ref; + if (object.isBareObject(val)) { + return sanitizer._sanitizeObjectAsChildren(val); + } else if (Array.isArray(val)) { + return sanitizer._sanitizeArrayAsChildren(val); + } else if (val === null || typeof val === 'undefined') { + return []; + } else if ((_ref = typeof val) === 'string' || _ref === 'number') { + return [String(val)]; + } else { + throw Error("not a valid child node: `" + val); + } + }, + _sanitizeObjectAsChildren: function(o) { + var a, cur, key, val; + a = []; + for (key in o) { + if (!__hasProp.call(o, key)) continue; + val = o[key]; + cur = {}; + cur[key] = sanitizer.sanitize(val); + a.push(cur); + } + return a; + }, + _sanitizeArrayAsChildren: function(a) { + var ret, v, _i, _len; + ret = []; + for (_i = 0, _len = a.length; _i < _len; _i++) { + v = a[_i]; + ret.push(sanitizer._sanitizeAsNode(v)); + } + return ret; + }, + _sanitizeAsNode: function(o) { + var key, keys, obj, _ref; + if ((_ref = typeof o) === 'string' || _ref === 'number') { + return String(o); + } else if (object.isBareObject(o)) { + keys = Object.keys(o); + if (keys.length !== 1) { + throw Error("a node must only have one key as tag name"); + } + key = keys[0]; + obj = {}; + obj[key] = sanitizer._sanitizeAsChildren(o[key]); + return obj; + } else { + throw Error("not a valid node: `" + o + "`"); + } + } +}; diff --git a/node_modules/dom-converter/scripts/js/test/_prepare.js b/node_modules/dom-converter/scripts/js/test/_prepare.js new file mode 100644 index 000000000..7c34f602f --- /dev/null +++ b/node_modules/dom-converter/scripts/js/test/_prepare.js @@ -0,0 +1,8 @@ +// Generated by CoffeeScript 1.6.3 +var path, pathToLib; + +path = require('path'); + +pathToLib = path.resolve(__dirname, '../../js/lib'); + +require('little-popo')(pathToLib, false); diff --git a/node_modules/dom-converter/scripts/js/test/domConverter.js b/node_modules/dom-converter/scripts/js/test/domConverter.js new file mode 100644 index 000000000..d52e9bfb8 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/test/domConverter.js @@ -0,0 +1,22 @@ +// Generated by CoffeeScript 1.6.3 +var domConverter; + +require('./_prepare'); + +domConverter = mod('domConverter'); + +describe("input types"); + +it("should work with objects", function() { + return domConverter.objectToDom({}); +}); + +it("should work with arrays", function() { + return domConverter.objectToDom([]); +}); + +it("should not work with other types", function() { + return (function() { + return domConverter.objectToDom('a'); + }).should["throw"](Error); +}); diff --git a/node_modules/dom-converter/scripts/js/test/objectToSaneObject.js b/node_modules/dom-converter/scripts/js/test/objectToSaneObject.js new file mode 100644 index 000000000..b86f707e6 --- /dev/null +++ b/node_modules/dom-converter/scripts/js/test/objectToSaneObject.js @@ -0,0 +1,108 @@ +// Generated by CoffeeScript 1.6.3 +var objectToSaneObject; + +require('./_prepare'); + +objectToSaneObject = mod('objectToSaneObject'); + +describe("sanitize()"); + +test("case: 'text'", function() { + var expectation, input, ret; + input = 'text'; + expectation = ['text']; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); + +test("case: ['text']", function() { + var expectation, input, ret; + input = ['text']; + expectation = ['text']; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); + +test("case: {a:b}", function() { + var expectation, input, ret; + input = { + a: 'b' + }; + expectation = [ + { + a: ['b'] + } + ]; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); + +test("case: {a:[b: 'c']}", function() { + var expectation, input, ret; + input = { + a: [ + { + b: 'c' + } + ] + }; + expectation = [ + { + a: [ + { + b: ['c'] + } + ] + } + ]; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); + +test("case: {a:b: 'c'}", function() { + var expectation, input, ret; + input = { + a: { + b: 'c' + } + }; + expectation = [ + { + a: [ + { + b: ['c'] + } + ] + } + ]; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); + +test("case: {a:b: ['c', d: 'e']}", function() { + var expectation, input, ret; + input = { + a: { + b: [ + 'c', { + d: 'e' + } + ] + } + }; + expectation = [ + { + a: [ + { + b: [ + 'c', { + d: ['e'] + } + ] + } + ] + } + ]; + ret = objectToSaneObject.sanitize(input); + return ret.should.be.like(expectation); +}); diff --git a/node_modules/dom-converter/scripts/js/test/saneObjectToDom.js b/node_modules/dom-converter/scripts/js/test/saneObjectToDom.js new file mode 100644 index 000000000..2562dd26a --- /dev/null +++ b/node_modules/dom-converter/scripts/js/test/saneObjectToDom.js @@ -0,0 +1,73 @@ +// Generated by CoffeeScript 1.6.3 +var s2d; + +require('./_prepare'); + +s2d = mod('saneObjectToDom'); + +describe("_arrayToChildren()"); + +it("should work", function() { + var a, aChild, b, bChildren, node, ret, _i, _len; + ret = s2d._arrayToChildren([ + { + a: 'text' + }, { + 'b.someClass': ['b1', 'b2'] + }, { + c: [ + { + d: 'text' + }, { + e: [] + } + ] + } + ]); + ret.should.be.an('array'); + ret.should.have.length.of(3); + for (_i = 0, _len = ret.length; _i < _len; _i++) { + node = ret[_i]; + node.should.be.an('object'); + node.should.have.keys(['type', 'name', 'attribs', 'children', 'next', 'prev', 'parent']); + } + a = ret[0]; + a.children.should.be.an('array'); + a.children.should.have.length.of(1); + aChild = a.children[0]; + aChild.should.be.an('object'); + aChild.should.be.like({ + type: 'text', + data: 'text' + }); + expect(a.prev).to.equal(null); + expect(a.parent).to.equal(null); + b = ret[1]; + a.next.should.equal(b); + b.prev.should.equal(a); + b.attribs.should.be.like({ + "class": 'someClass' + }); + bChildren = b.children; + bChildren[0].should.be.like({ + type: 'text', + data: 'b1' + }); + bChildren[1].should.be.like({ + type: 'text', + data: 'b2' + }); + return ret.should.have.deep.property('[2].children[1].name', 'e'); +}); + +describe("_parseTag"); + +it("should work", function() { + return s2d._parseTag('tagName#id.c1.c2[a=b, d="1 2 3"]').should.be.like({ + name: 'tagName', + attribs: { + id: 'id', + "class": 'c1 c2' + } + }); +}); |