Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9dcb16f
Showing
5 changed files
with
577 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
language: node_js | ||
node_js: | ||
- "0.8" | ||
- "0.10" | ||
before_script: | ||
- npm install istanbul coveralls | ||
- npm install --dev | ||
script: npm run travis-test | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
[1]: https://secure.travis-ci.org/litejs/dom-lite.png | ||
[2]: https://travis-ci.org/litejs/dom-lite | ||
[3]: https://coveralls.io/repos/litejs/dom-lite/badge.png | ||
[4]: https://coveralls.io/r/litejs/dom-lite | ||
[npm package]: https://npmjs.org/package/dom-lite | ||
[GitHub repo]: https://github.com/litejs/dom-lite | ||
|
||
|
||
@version 0.0.1 | ||
@date 2014-03-21 | ||
@stability 2 - Unstable | ||
|
||
|
||
DOM lite – [![Build][1]][2] [![Coverage][3]][4] | ||
======== | ||
|
||
A minimal DOM implementation | ||
|
||
|
||
Examples | ||
-------- | ||
|
||
```javascript | ||
var document = require("dom-lite").document; | ||
|
||
var el = document.createElement("h1"); | ||
el.id = 123; | ||
el.className = "large"; | ||
|
||
var fragment = document.createDocumentFragment(); | ||
var text1 = document.createTextNode("hello"); | ||
var text2 = document.createTextNode(" world"); | ||
|
||
fragment.appendChild(text1); | ||
fragment.appendChild(text2); | ||
el.appendChild(fragment); | ||
|
||
el.toString(); | ||
// <h1 id="123" class="large">hello world</h1> | ||
``` | ||
|
||
|
||
|
||
External links | ||
-------------- | ||
|
||
- [GitHub repo][] | ||
- [npm package][] | ||
|
||
|
||
|
||
### Licence | ||
|
||
Copyright (c) 2012 Lauri Rooden <lauri@rooden.ee> | ||
[The MIT License](http://lauri.rooden.ee/mit-license.txt) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,289 @@ | ||
/* | ||
* Object | ||
* |- Node | ||
* |- DocumentFragment | ||
* |- Element // skip | ||
* | |- HTMLElement | ||
* | |- HTML*Element // skip | ||
* |- CharacterData // skip | ||
* | |- Text | ||
*/ | ||
|
||
|
||
|
||
function extend(obj, _super, extras) { | ||
obj.prototype = Object.create(_super.prototype) | ||
for (var key in extras) { | ||
obj.prototype[key] = extras[key] | ||
} | ||
obj.prototype.constructor = obj | ||
} | ||
|
||
|
||
|
||
/* | ||
* http://dom.spec.whatwg.org/#node | ||
*/ | ||
function Node(){} | ||
|
||
Node.prototype = { | ||
__fake: true, | ||
textContent: "", | ||
nodeName: null, | ||
parentNode: null, | ||
childNodes: null, | ||
firstChild: null, | ||
lastChild: null, | ||
previousSibling: null, | ||
nextSibling: null, | ||
get outerHTML() { | ||
return this.toString() | ||
}, | ||
appendChild: function(el) { | ||
return this.insertBefore(el) | ||
}, | ||
insertBefore: function(el, ref) { | ||
var t = this | ||
, childs = t.childNodes | ||
|
||
if (el.parentNode) el.parentNode.removeChild(el) | ||
el.parentNode = t | ||
|
||
// If ref is null, insert el at the end of the list of children. | ||
childs.splice(ref ? childs.indexOf(ref) : childs.length, 0, el) | ||
t._updateLinks(el, ref, ref && ref.previousSibling) | ||
return el | ||
}, | ||
removeChild: function(el) { | ||
var t = this | ||
, index = t.childNodes.indexOf(el) | ||
if (index == -1) throw new Error("NOT_FOUND_ERR") | ||
|
||
t.childNodes.splice(index, 1) | ||
el.parentNode = null | ||
t._updateLinks(el.previousSibling, el.nextSibling, el) | ||
return el | ||
}, | ||
replaceChild: function(el, ref) { | ||
this.insertBefore(el, ref) | ||
return this.removeChild(ref) | ||
}, | ||
cloneNode: function(deep) { | ||
var key | ||
, t = this | ||
, node = new t.constructor(t.tagName || t.textContent) | ||
|
||
if (t.hasAttribute) { | ||
for (key in t) if (t.hasAttribute(key)) node[key] = t[key] | ||
for (key in t.style) node.style[key] = t.style[key] | ||
} | ||
|
||
if (deep && t.childNodes) { | ||
node.childNodes = t.childNodes.map(function(child){ | ||
return child.cloneNode(deep) | ||
}) | ||
} | ||
return node | ||
}, | ||
hasChildNodes: function() { | ||
return this.childNodes && this.childNodes.length > 0 | ||
}, | ||
_updateLinks: function() { | ||
var el, index | ||
, t = this | ||
, childs = t.childNodes | ||
, len = arguments.length | ||
|
||
t.firstChild = childs[0] || null | ||
t.lastChild = childs[ childs.length - 1 ] || null | ||
|
||
if (len) while (len--) { | ||
el = arguments[len] | ||
if (!el) continue | ||
childs = el.parentNode && el.parentNode.childNodes | ||
index = childs && childs.indexOf(el) || 0 | ||
el.nextSibling = childs && childs[ index + 1 ] || null | ||
if (el.nextSibling) el.nextSibling.previousSibling = el | ||
el.previousSibling = index > 0 && childs[ index - 1 ] || null | ||
if (el.previousSibling) el.previousSibling.nextSibling = el | ||
} | ||
}, | ||
toString: function() { | ||
var result = this.textContent || "" | ||
|
||
if (this.childNodes) return this.childNodes.reduce(function (memo, node) { | ||
return memo + node | ||
}, result) | ||
|
||
return result | ||
} | ||
} | ||
|
||
|
||
function DocumentFragment() { | ||
this.childNodes = [] | ||
} | ||
|
||
extend(DocumentFragment, Node, { | ||
nodeType: 11, | ||
nodeName: "#document-fragment" | ||
}) | ||
|
||
|
||
function HTMLElement(tag) { | ||
var t = this | ||
t.nodeName = t.tagName = tag.toLowerCase() | ||
t.childNodes = [] | ||
t.style = {} | ||
} | ||
|
||
var el_re = /([.#:[])([-\w]+)(?:=([-\w]+)])?]?/g | ||
|
||
extend(HTMLElement, Node, { | ||
nodeType: 1, | ||
tagName: null, | ||
style: null, | ||
className: "", | ||
/* | ||
* Void elements: | ||
* http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements | ||
*/ | ||
_voidElements: { AREA:1, BASE:1, BR:1, COL:1, EMBED:1, HR:1, IMG:1, INPUT:1, | ||
KEYGEN:1, LINK:1, MENUITEM:1, META:1, PARAM:1, SOURCE:1, TRACK:1, WBR:1 }, | ||
hasAttribute: function(name) { | ||
return this.hasOwnProperty(name) && !(name in HTMLElement.prototype) | ||
}, | ||
getAttribute: function(name) { | ||
return this.hasAttribute(name) ? this[name] : null | ||
}, | ||
setAttribute: function(name, value) { | ||
this[name] = value | ||
}, | ||
removeAttribute: function(name) { | ||
delete this.name | ||
}, | ||
getElementById: function(id) { | ||
if (this.id == id) return this | ||
for (var el, found, i = 0; !found && (el = this.childNodes[i++]);) { | ||
if (el.nodeType == 1) found = el.getElementById(id) | ||
} | ||
return found || null | ||
}, | ||
getElementsByTagName: function(tag) { | ||
var el, els = [], next = this.firstChild | ||
tag = tag === "*" ? 1 : tag.toLowerCase() | ||
for (var i = 0, key = tag === 1 ? "nodeType" : "nodeName"; (el = next); ) { | ||
if (el[key] === tag) els[i++] = el | ||
next = el.firstChild || el.nextSibling | ||
while (!next && (el = el.parentNode)) next = el.nextSibling | ||
} | ||
return els | ||
}, | ||
querySelector: function(sel) { | ||
return this._find(sel, 1) | ||
}, | ||
querySelectorAll: function(sel) { | ||
return this._find(sel) | ||
}, | ||
_find: function(sel, first) { | ||
var el | ||
, i = 0 | ||
, out = [] | ||
, rules = ["_"] | ||
, tag = sel.replace(el_re, function(_, o, s, v) { | ||
rules.push( | ||
o == "." ? "(' '+_.className+' ').indexOf(' "+s+" ')>-1" : | ||
o == "#" ? "_.id=='"+s+"'" : | ||
"_.getAttribute('"+s+"')"+(v?"=='"+v+"'":"") | ||
) | ||
return "" | ||
}) || "*" | ||
, els = this.getElementsByTagName(tag) | ||
, fn = Function("_", "return " + rules.join("&&")) | ||
|
||
for (; el = els[i++]; ) if (fn(el)) { | ||
if (first) return el | ||
out.push(el) | ||
} | ||
return first ? null : out | ||
}, | ||
_getAttributesString: function() { | ||
var key | ||
, t = this | ||
, attrs = [] | ||
|
||
for (key in t) if (t.hasAttribute(key)) { | ||
attrs.push(key + '="' + t[key] + '"') | ||
} | ||
|
||
if (t.className) { | ||
attrs.push('class="' + t.className + '"') | ||
} | ||
|
||
var style = Object.keys(t.style).reduce(function (str, key) { | ||
return str + key + ":" + t.style[key] + ";" | ||
}, "") | ||
if (style) attrs.push('style="' + style + '"') | ||
|
||
return attrs.length ? " " + attrs.join(" ") : "" | ||
}, | ||
toString: function() { | ||
var t = this, result = "<" + t.tagName + t._getAttributesString() | ||
|
||
if (t._voidElements[t.tagName]) { | ||
return result + "/>" | ||
} | ||
|
||
return result + ">" + | ||
Node.prototype.toString.call(t) + | ||
"</" + t.tagName + ">" | ||
} | ||
}) | ||
|
||
|
||
function Text(value) { | ||
this.textContent = value | ||
} | ||
|
||
extend(Text, Node, { | ||
nodeType: 3, | ||
nodeName: "#text" | ||
}) | ||
|
||
function Document(){ | ||
this.body = this.createElement("body") | ||
} | ||
|
||
extend(Document, Node, { | ||
nodeType: 9, | ||
nodeName: "#document", | ||
createElement: function(tag) { | ||
return new HTMLElement(tag) | ||
}, | ||
createTextNode: function(value) { | ||
return new Text(value) | ||
}, | ||
createDocumentFragment: function() { | ||
return new DocumentFragment() | ||
}, | ||
getElementById: function(id) { | ||
return this.body.getElementById(id) | ||
}, | ||
getElementsByTagName: function(tag) { | ||
return this.body.getElementsByTagName(tag) | ||
}, | ||
querySelector: function(sel) { | ||
return this.body.querySelector(sel) | ||
}, | ||
querySelectorAll: function(sel) { | ||
return this.body.querySelectorAll(sel) | ||
} | ||
}) | ||
|
||
module.exports = { | ||
document: new Document, | ||
Document: Document, | ||
HTMLElement: HTMLElement | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"name": "dom-lite", | ||
"version": "0.0.1", | ||
"stability": 2, | ||
"license": "MIT", | ||
"author": "Lauri Rooden <lauri@rooden.ee>", | ||
"description": "A minimal DOM implementation", | ||
"keywords": [ | ||
"dom" | ||
], | ||
"main": "index.js", | ||
"readmeFilename": "README.md", | ||
"scripts": { | ||
"build": "node node_modules/buildman/index.js --all", | ||
"travis-test": "istanbul cover ./tests/index.js && (coveralls < coverage/lcov.info || exit 0)", | ||
"test": "node tests/index.js" | ||
}, | ||
"repository": "git://github.com/litejs/dom-lite.git", | ||
"bugs": { | ||
"url": "https://github.com/litejs/dom-lite/issues" | ||
}, | ||
"devDependencies": { | ||
"tape": "~1.0.2" | ||
} | ||
} |
Oops, something went wrong.