put-selector
Advanced tools
Comparing version 0.2.0 to 0.3.6
@@ -11,3 +11,3 @@ "use strict"; | ||
}); | ||
var prototype = Element.prototype = []; | ||
var prototype = Element.prototype; | ||
var currentIndentation = ''; | ||
@@ -171,5 +171,12 @@ prototype.nodeType = 1; | ||
}); | ||
function DocumentFragment(){ | ||
} | ||
DocumentFragment.prototype = new Element(); | ||
DocumentFragment.prototype.toString = function(){ | ||
return this.children ? this.children.join('') : ''; | ||
}; | ||
var lessThanRegex = /</g, ampersandRegex = /&/g; | ||
module.exports = function(putModule, putFactory){ | ||
put = putModule.exports = putFactory().forDocument({ | ||
put = putModule.exports = putFactory({ | ||
// setup a document for string-based HTML creation, using our classes | ||
@@ -179,4 +186,10 @@ createElement: function(tag){ | ||
}, | ||
createElementNS: function(uri, tag){ | ||
return new Element(namespacePrefixes[uri] + ':' + tag); | ||
}, | ||
createTextNode: function(value){ | ||
return (typeof value == 'string' ? value : ('' + value)).replace(lessThanRegex, "<").replace(ampersandRegex, "&"); | ||
}, | ||
createDocumentFragment: function(){ | ||
return new DocumentFragment(); | ||
} | ||
@@ -192,2 +205,8 @@ }, { // fragment heuristic, don't use this fragments here, it only slows things down | ||
}; | ||
var namespacePrefixes = {}; | ||
var addNamespace = put.addNamespace; | ||
put.addNamespace = function(name, uri){ | ||
namespacePrefixes[uri] = name; | ||
addNamespace(name, uri); | ||
} | ||
}; |
@@ -5,2 +5,8 @@ var miniExcludes = { | ||
}, | ||
amdExcludes = { | ||
}, | ||
copyOnly = { | ||
"put-selector/node-html": 1 | ||
}, | ||
isJsRe = /\.js$/, | ||
isTestRe = /\/test\//; | ||
@@ -19,5 +25,9 @@ | ||
amd: function(filename, mid){ | ||
return /\.js$/.test(filename); | ||
return isJsRe.test(filename) && !(mid in amdExcludes); | ||
}, | ||
copyOnly: function(filename, mid){ | ||
return mid in copyOnly; | ||
} | ||
} | ||
}; | ||
}; |
{ | ||
"name": "put-selector", | ||
"author": "Kris Zyp", | ||
"version": "0.2.0", | ||
"version": "0.3.6", | ||
"description": "A high-performance, lightweight function for creating and manipulating DOM elements with succinct, elegant, familiar CSS selector-based syntax", | ||
@@ -6,0 +6,0 @@ "licenses": [ |
68
put.js
@@ -15,11 +15,6 @@ (function(define){ | ||
fragmentFasterHeuristic = newFragmentFasterHeuristic || fragmentFasterHeuristic; | ||
try{ | ||
var selectorParse = /(?:\s*([-+ ,<>]))?\s*(\.|!\.?|#)?([-\w%$]+)?(?:\[([^\]=]+)=?['"]?([^\]'"]*)['"]?\])?/g, | ||
undefined, | ||
doc = doc || document, | ||
ieCreateElement = 1; | ||
put('i', {name:'a'}); | ||
}catch(e){ | ||
ieCreateElement = 0; | ||
} | ||
var selectorParse = /(?:\s*([-+ ,<>]))?\s*(\.|!\.?|#)?([-\w\u00A0-\uFFFF%$|]+)?(?:\[([^\]=]+)=?['"]?([^\]'"]*)['"]?\])?/g, | ||
undefined, namespaceIndex, namespaces = false, | ||
doc = doc || document, | ||
ieCreateElement = typeof doc.createElement == "object"; // telltale sign of the old IE behavior with createElement that does not support later addition of name | ||
function insertTextNode(element, text){ | ||
@@ -29,4 +24,5 @@ element.appendChild(doc.createTextNode(text)); | ||
function put(topReferenceElement){ | ||
var fragment, returnValue, lastSelectorArg, nextSibling, referenceElement, current, | ||
args = arguments; | ||
var fragment, lastSelectorArg, nextSibling, referenceElement, current, | ||
args = arguments, | ||
returnValue = args[0]; // use the first argument as the default return value in case only an element is passed in | ||
function insertLastElement(){ | ||
@@ -46,3 +42,3 @@ // we perform insertBefore actions after the element is fully created to work properly with | ||
// any of the above fails just use the referenceElement | ||
|| referenceElement). | ||
? fragment : referenceElement). | ||
insertBefore(current, nextSibling || null); // do the actual insertion | ||
@@ -57,7 +53,7 @@ } | ||
// an array | ||
returnValue = doc.createDocumentFragment(); | ||
current = doc.createDocumentFragment(); | ||
for(var key = 0; key < argument.length; key++){ | ||
returnValue.appendChild(put(argument[key])); | ||
current.appendChild(put(argument[key])); | ||
} | ||
argument = returnValue; | ||
argument = current; | ||
} | ||
@@ -132,3 +128,6 @@ if(argument.nodeType){ | ||
} | ||
current = doc.createElement(tag); | ||
// we swtich between creation methods based on namespace usage | ||
current = namespaces && ~(namespaceIndex = tag.indexOf('|')) ? | ||
doc.createElementNS(namespaces[tag.slice(0, namespaceIndex)], tag.slice(namespaceIndex + 1)) : | ||
doc.createElement(tag); | ||
} | ||
@@ -155,5 +154,11 @@ } | ||
if(argument == "!"){ | ||
var parentNode; | ||
// special signal to delete this element | ||
// use the ol' innerHTML trick to get IE to do some cleanup | ||
put("div", current, '<').innerHTML = ""; | ||
if(ieCreateElement){ | ||
// use the ol' innerHTML trick to get IE to do some cleanup | ||
put("div", current, '<').innerHTML = ""; | ||
}else if(parentNode = current.parentNode){ // intentional assigment | ||
// use a faster, and more correct (for namespaced elements) removal (http://jsperf.com/removechild-innerhtml) | ||
parentNode.removeChild(current); | ||
} | ||
}else{ | ||
@@ -180,3 +185,8 @@ // we already have removed the class, just need to trim | ||
}else{ | ||
current[attrName.charAt(0) == "!" ? (attrName = attrName.substring(1)) && 'removeAttribute' : 'setAttribute'](attrName, attrValue === '' ? attrName : attrValue); | ||
var method = attrName.charAt(0) == "!" ? (attrName = attrName.substring(1)) && 'removeAttribute' : 'setAttribute'; | ||
attrValue = attrValue === '' ? attrName : attrValue; | ||
// determine if we need to use a namespace | ||
namespaces && ~(namespaceIndex = attrName.indexOf('|')) ? | ||
current[method + "NS"](namespaces[attrName.slice(0, namespaceIndex)], attrName.slice(namespaceIndex + 1), attrValue) : | ||
current[method](attrName, attrValue); | ||
} | ||
@@ -199,2 +209,10 @@ } | ||
} | ||
put.addNamespace = function(name, uri){ | ||
if(doc.createElementNS){ | ||
(namespaces || (namespaces = {}))[name] = uri; | ||
}else{ | ||
// for old IE | ||
doc.namespaces.add(name, uri); | ||
} | ||
}; | ||
put.defaultTag = "div"; | ||
@@ -204,4 +222,10 @@ put.forDocument = forDocument; | ||
}); | ||
})(typeof define == "undefined" ? function(deps, factory){ | ||
if(typeof window == "undefined"){ | ||
})(function(id, deps, factory){ | ||
factory = factory || deps; | ||
if(typeof define === "function"){ | ||
// AMD loader | ||
define([], function(){ | ||
return factory(); | ||
}); | ||
}else if(typeof window == "undefined"){ | ||
// server side JavaScript, probably (hopefully) NodeJS | ||
@@ -213,2 +237,2 @@ require("./node-html")(module, factory); | ||
} | ||
} : define); | ||
}); |
This put-selector/put module/package provides a high-performance, lightweight | ||
(~1.5KB minified, ~0.7KB gzipped with other code) function for creating | ||
(~2KB minified, ~1KB gzipped with other code) function for creating | ||
and manipulating DOM elements with succinct, elegant, familiar CSS selector-based | ||
@@ -57,4 +57,7 @@ syntax across all browsers and platforms (including HTML generation on NodeJS). | ||
The put function returns the last top level element created or referenced. In the | ||
examples above, the newly create element would be returned. | ||
The put function returns the last top level element created or referenced from a selector. | ||
In the examples above, the newly create element would be returned. Note that passing | ||
in an existing node will not change the return value (as it is assumed you already have | ||
a reference to it). Also note that if you only pass existing nodes reference, the first | ||
passed reference will be returned. | ||
@@ -96,4 +99,18 @@ Modifying Elements | ||
This will destroy the element from the DOM (using parent innerHTML destruction that reduces memory leaks in IE). | ||
This will destroy the element from the DOM, using either parent innerHTML destruction (IE only, that | ||
reduces memory leaks in IE), or removeChild (for all other browsers). | ||
Creating/Modifying Elements with XML Namespaces | ||
----------- | ||
To work with elements and attributes that are XML namespaced, start by adding the namespace using addNamespace: | ||
put.addNamespace("svg", "http://www.w3.org/2000/svg"); | ||
put.addNamespace("xlink", "http://www.w3.org/1999/xlink"); | ||
From there, you can use the CSS3 selector syntax to work with elements and attributes: | ||
var surface = put("svg|svg[width='100'][height='100']"); | ||
var img = put(surface, "svg|image[xlink|href='path/to/my/image.png']"); | ||
Text Content | ||
@@ -174,6 +191,12 @@ ----------- | ||
put(parent, child); | ||
We could also do this more explicitly by using a child descendant, '>' (which has the | ||
same meaning as a space operator, and is the default action between arguments in put-selector): | ||
put(parent, ">", child); | ||
We could also use sibling combinators to place the referenced element. We could place | ||
the "second" element after (as the next sibling) the "first" element: | ||
the "second" element after (as the next sibling) the "first" element (which needs a parent | ||
in order to have a sibling): | ||
@@ -304,2 +327,10 @@ put(first, "+", second); | ||
put2("div") <- creates a div element that belongs to the document in the second frame. | ||
put("div") <- the original put still functions on the main document for this window/context | ||
put("div") <- the original put still functions on the main document for this window/context | ||
# License | ||
put-selector is freely available under *either* the terms of the modified BSD license *or* the | ||
Academic Free License version 2.1. More details can be found in the [LICENSE](LICENSE). | ||
The put-selector project follows the IP guidelines of Dojo foundation packages and all contributions require a Dojo CLA. | ||
If you feel compelled to make a monetary contribution, consider some of the author's [favorite | ||
charities](http://thezyps.com/2012-giving-guide/) like [Innovations for Poverty Action](http://www.poverty-action.org/). |
@@ -0,0 +0,0 @@ var http = require('http'); |
@@ -5,2 +5,3 @@ var assert = require("assert"), | ||
assert.equal(put('div span.test<').toString(), '\n<div>\n <span class="test"></span>\n</div>'); | ||
assert.equal(put('div', ['header', 'section']).toString(), '\n<div>\n <header></header>\n <section></section>\n</div>'); | ||
}; | ||
@@ -14,4 +15,6 @@ exports.testPage = function() { | ||
put(content, 'div.left', 'Left'); | ||
put.addNamespace('foo', 'http://foo.com/foo'); | ||
put(content, 'foo|bar'); | ||
put(content, 'div.right', {innerHTML: 'Right <b>text</b>'}); | ||
assert.equal(page.toString(), '<!DOCTYPE html>\n<html><head><script src=\"test.js\"></script><link href=\"test.css\"><link href=\"test2.css\"></head><body><div class=\"header\">Hello World</div><div class=\"content\"><div class=\"left\">Left</div><div class=\"right\">Right <b>text</b></div></div></body></html>'); | ||
assert.equal(page.toString(), '<!DOCTYPE html>\n<html><head><script src=\"test.js\"></script><link href=\"test.css\"><link href=\"test2.css\"></head><body><div class=\"header\">Hello World</div><div class=\"content\"><div class=\"left\">Left</div><foo:bar></foo:bar><div class=\"right\">Right <b>text</b></div></div></body></html>'); | ||
}; | ||
@@ -18,0 +21,0 @@ exports.testStream = function() { |
var div = put("div"); | ||
console.assert(div.tagName.toLowerCase() == "div"); | ||
console.assert(put(div) === div); | ||
@@ -70,3 +71,3 @@ var body = document.body; | ||
var arrayFrag = put(div, ["span.c1", "span.c2", "span.c3"]); | ||
console.assert(arrayFrag.nodeType == 11); | ||
console.assert(arrayFrag.tagName.toLowerCase() == "div"); | ||
console.assert(div.firstChild.className == "c1"); | ||
@@ -78,2 +79,26 @@ console.assert(div.lastChild.className == "c3"); | ||
put(body, "div", {innerHTML: "finished tests, check console for errors"}); | ||
var styled = put("div.someClass[style=color:green;margin-left:10px]"); | ||
console.assert(styled.style.marginLeft.slice(0,2) == "10"); | ||
put.addNamespace("put", "http://github.com/kriszyp/dgrid"); | ||
var namespaced = put("put|foo[bar=test1][put|bar=test2]"); | ||
console.assert((namespaced.namespaceURI || namespaced.tagUrn) == "http://github.com/kriszyp/dgrid"); | ||
console.assert(namespaced.tagName == "foo"); | ||
console.assert(namespaced.getAttribute("bar") == "test1"); | ||
if(document.createElementNS){ | ||
console.assert(namespaced.getAttributeNS("http://github.com/kriszyp/dgrid","bar") == "test2"); | ||
} | ||
put.addNamespace("svg", "http://www.w3.org/2000/svg"); | ||
var svg = put(document.body, "svg|svg#svg-test"); | ||
put(svg, "!"); | ||
console.assert(document.getElementById("svg-test") == null); | ||
var unicode = put("div.unicode-你好"); | ||
console.assert(unicode.className === "unicode-你好"); | ||
put(body, "div", {innerHTML: "finished tests, check console for errors"}); | ||
var unicodeId = put(body, "div#ÅÄÖ"); | ||
console.assert(unicodeId.id === "ÅÄÖ"); |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
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
Non-existent author
Supply chain riskThe package was published by an npm account that no longer exists.
Found 1 instance in 1 package
49802
10
589
332
0
2