[
  {
    "path": "LICENSE",
    "content": "put-selector is available under *either* the terms of the modified BSD license *or* the\nAcademic Free License version 2.1. As a recipient of put-selector, you may choose which\nlicense to receive this code under.\n\nThe text of the AFL and BSD licenses is reproduced below. \n\n-------------------------------------------------------------------------------\nThe \"New\" BSD License:\n**********************\n\nCopyright (c) 2010-2011, The Dojo Foundation\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n  * Redistributions of source code must retain the above copyright notice, this\n    list of conditions and the following disclaimer.\n  * Redistributions in binary form must reproduce the above copyright notice,\n    this list of conditions and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n  * Neither the name of the Dojo Foundation nor the names of its contributors\n    may be used to endorse or promote products derived from this software\n    without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-------------------------------------------------------------------------------\nThe Academic Free License, v. 2.1:\n**********************************\n\nThis Academic Free License (the \"License\") applies to any original work of\nauthorship (the \"Original Work\") whose owner (the \"Licensor\") has placed the\nfollowing notice immediately following the copyright notice for the Original\nWork:\n\nLicensed under the Academic Free License version 2.1\n\n1) Grant of Copyright License. Licensor hereby grants You a world-wide,\nroyalty-free, non-exclusive, perpetual, sublicenseable license to do the\nfollowing:\n\na) to reproduce the Original Work in copies;\n\nb) to prepare derivative works (\"Derivative Works\") based upon the Original\nWork;\n\nc) to distribute copies of the Original Work and Derivative Works to the\npublic;\n\nd) to perform the Original Work publicly; and\n\ne) to display the Original Work publicly.\n\n2) Grant of Patent License. Licensor hereby grants You a world-wide,\nroyalty-free, non-exclusive, perpetual, sublicenseable license, under patent\nclaims owned or controlled by the Licensor that are embodied in the Original\nWork as furnished by the Licensor, to make, use, sell and offer for sale the\nOriginal Work and Derivative Works.\n\n3) Grant of Source Code License. The term \"Source Code\" means the preferred\nform of the Original Work for making modifications to it and all available\ndocumentation describing how to modify the Original Work. Licensor hereby\nagrees to provide a machine-readable copy of the Source Code of the Original\nWork along with each copy of the Original Work that Licensor distributes.\nLicensor reserves the right to satisfy this obligation by placing a\nmachine-readable copy of the Source Code in an information repository\nreasonably calculated to permit inexpensive and convenient access by You for as\nlong as Licensor continues to distribute the Original Work, and by publishing\nthe address of that information repository in a notice immediately following\nthe copyright notice that applies to the Original Work.\n\n4) Exclusions From License Grant. Neither the names of Licensor, nor the names\nof any contributors to the Original Work, nor any of their trademarks or\nservice marks, may be used to endorse or promote products derived from this\nOriginal Work without express prior written permission of the Licensor. Nothing\nin this License shall be deemed to grant any rights to trademarks, copyrights,\npatents, trade secrets or any other intellectual property of Licensor except as\nexpressly stated herein. No patent license is granted to make, use, sell or\noffer to sell embodiments of any patent claims other than the licensed claims\ndefined in Section 2. No right is granted to the trademarks of Licensor even if\nsuch marks are included in the Original Work. Nothing in this License shall be\ninterpreted to prohibit Licensor from licensing under different terms from this\nLicense any Original Work that Licensor otherwise would have a right to\nlicense.\n\n5) This section intentionally omitted.\n\n6) Attribution Rights. You must retain, in the Source Code of any Derivative\nWorks that You create, all copyright, patent or trademark notices from the\nSource Code of the Original Work, as well as any notices of licensing and any\ndescriptive text identified therein as an \"Attribution Notice.\" You must cause\nthe Source Code for any Derivative Works that You create to carry a prominent\nAttribution Notice reasonably calculated to inform recipients that You have\nmodified the Original Work.\n\n7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that\nthe copyright in and to the Original Work and the patent rights granted herein\nby Licensor are owned by the Licensor or are sublicensed to You under the terms\nof this License with the permission of the contributor(s) of those copyrights\nand patent rights. Except as expressly stated in the immediately proceeding\nsentence, the Original Work is provided under this License on an \"AS IS\" BASIS\nand WITHOUT WARRANTY, either express or implied, including, without limitation,\nthe warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR\nPURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU.\nThis DISCLAIMER OF WARRANTY constitutes an essential part of this License. No\nlicense to Original Work is granted hereunder except under this disclaimer.\n\n8) Limitation of Liability. Under no circumstances and under no legal theory,\nwhether in tort (including negligence), contract, or otherwise, shall the\nLicensor be liable to any person for any direct, indirect, special, incidental,\nor consequential damages of any character arising as a result of this License\nor the use of the Original Work including, without limitation, damages for loss\nof goodwill, work stoppage, computer failure or malfunction, or any and all\nother commercial damages or losses. This limitation of liability shall not\napply to liability for death or personal injury resulting from Licensor's\nnegligence to the extent applicable law prohibits such limitation. Some\njurisdictions do not allow the exclusion or limitation of incidental or\nconsequential damages, so this exclusion and limitation may not apply to You.\n\n9) Acceptance and Termination. If You distribute copies of the Original Work or\na Derivative Work, You must make a reasonable effort under the circumstances to\nobtain the express assent of recipients to the terms of this License. Nothing\nelse but this License (or another written agreement between Licensor and You)\ngrants You permission to create Derivative Works based upon the Original Work\nor to exercise any of the rights granted in Section 1 herein, and any attempt\nto do so except under the terms of this License (or another written agreement\nbetween Licensor and You) is expressly prohibited by U.S. copyright law, the\nequivalent laws of other countries, and by international treaty. Therefore, by\nexercising any of the rights granted to You in Section 1 herein, You indicate\nYour acceptance of this License and all of its terms and conditions.\n\n10) Termination for Patent Action. This License shall terminate automatically\nand You may no longer exercise any of the rights granted to You by this License\nas of the date You commence an action, including a cross-claim or counterclaim,\nagainst Licensor or any licensee alleging that the Original Work infringes a\npatent. This termination provision shall not apply for an action alleging\npatent infringement by combinations of the Original Work with other software or\nhardware.\n\n11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this\nLicense may be brought only in the courts of a jurisdiction wherein the\nLicensor resides or in which Licensor conducts its primary business, and under\nthe laws of that jurisdiction excluding its conflict-of-law provisions. The\napplication of the United Nations Convention on Contracts for the International\nSale of Goods is expressly excluded. Any use of the Original Work outside the\nscope of this License or after its termination shall be subject to the\nrequirements and penalties of the U.S. Copyright Act, 17 U.S.C. Â§ 101 et\nseq., the equivalent laws of other countries, and international treaty. This\nsection shall survive the termination of this License.\n\n12) Attorneys Fees. In any action to enforce the terms of this License or\nseeking damages relating thereto, the prevailing party shall be entitled to\nrecover its costs and expenses, including, without limitation, reasonable\nattorneys' fees and costs incurred in connection with such action, including\nany appeal of such action. This section shall survive the termination of this\nLicense.\n\n13) Miscellaneous. This License represents the complete agreement concerning\nthe subject matter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent necessary to\nmake it enforceable.\n\n14) Definition of \"You\" in This License. \"You\" throughout this License, whether\nin upper or lower case, means an individual or a legal entity exercising rights\nunder, and complying with all of the terms of, this License. For legal\nentities, \"You\" includes any entity that controls, is controlled by, or is\nunder common control with you. For purposes of this definition, \"control\" means\n(i) the power, direct or indirect, to cause the direction or management of such\nentity, whether by contract or otherwise, or (ii) ownership of fifty percent\n(50%) or more of the outstanding shares, or (iii) beneficial ownership of such\nentity.\n\n15) Right to Use. You may use the Original Work in all ways not otherwise\nrestricted or conditioned by this License or by law, and Licensor promises not\nto interfere with or be responsible for such uses by You.\n\nThis license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved.\nPermission is hereby granted to copy and distribute this license without\nmodification. This license may not be modified without the express written\npermission of its copyright owner.\n"
  },
  {
    "path": "README.md",
    "content": "This put-selector/put module/package provides a high-performance, lightweight \n(~2KB minified, ~1KB gzipped with other code) function for creating \nand manipulating DOM elements with succinct, elegant, familiar CSS selector-based \nsyntax across all browsers and platforms (including HTML generation on NodeJS). \nThe single function from the module creates or updates DOM elements by providing\na series of arguments that can include reference elements, selector strings, properties,\nand text content. The put() function utilizes the proven techniques for optimal performance\non modern browsers to ensure maximum speed.\n\nInstallation/Usage\n----------------\n\nThe put.js module can be simply downloaded and used a plain script (creates a global \nput() function), as an AMD module (exports the put() function), or as a NodeJS (or any\nserver side JS environment) module.\nIt can also be installed with <a href=\"https://github.com/kriszyp/cpm\">CPM</a>:\n\n\tcpm install put-selector\n\nand then reference the \"put-selector\" module as a dependency.\nor installed for Node with NPM:\n\n\tnpm install put-selector\n\nand then:\n\n\tput = require(\"put-selector\");\n\nCreating Elements\n----------------\n\nType selector syntax (no prefix) can be used to indicate the type of element to be created. For example:\n\n\tnewDiv = put(\"div\");\n\t\nwill create a new &lt;div> element. We can put a reference element in front of the selector\nstring and the &lt;div> will be appended as a child to the provided element: \n\n\tput(parent, \"div\"); \n\t\nThe selector .class-name can be used to assign the class name. For example:\n\n\tput(\"div.my-class\") \n\t\nwould create an element &lt;div class=\"my-class\"> (an element with a class of \"my-class\").\n\nThe selector #id can be used to assign an id and [name=value] can be used to \nassign additional attributes to the element. For example:\n\n\tnewInput = put(parent, \"input.my-input#address[type=checkbox]\");\n\nWould create an input element with a class name of \"my-input\", an id of \"address\",\nand the type attribute set to \"checkbox\". The attribute assignment will always use \nsetAttribute to assign the attribute to the element. Multiple attributes and classes\ncan be assigned to a single element. \n\nThe put function returns the last top level element created or referenced from a selector. \nIn the examples above, the newly create element would be returned. Note that passing \nin an existing node will not change the return value (as it is assumed you already have \na reference to it). Also note that if you only pass existing nodes reference, the first \npassed reference will be returned.\n\nModifying Elements\n----------------\n\nOne can also modify elements with selectors. If the tag name is omitted (and no\ncombinators have been used), the reference element will be modified by the selector.\nFor example, to add the class \"foo\" to element, we could write:\n\n\tput(element, \".foo\"); \n\nLikewise, we could set attributes, here we set the \"role\" attribute to \"presentation\":\n\n\tput(element, \"[role=presentation]\");\n\nAnd these can be combined also. For example, we could set the id and an attribute in\none statement:\n\n\tput(element, \"#id[tabIndex=2]\");\n\nOne can also remove classes from elements by using the \"!\" operator in place of a \".\". \nTo remove the \"foo\" class from an element, we could write:\n\n\tput(element, \"!foo\");\n\nWe can also use the \"!\" operator to remove attributes as well. Prepending an attribute name\nwith \"!\" within brackets will remove it. To remove the \"role\" attribute, we could write:\n\n\tput(element, \"[!role]\");\n\nDeleting Elements\n--------------\n\nTo delete an element, we can simply use the \"!\" operator by itself as the entire selector:\n\n\tput(elementToDelete, \"!\");\n\nThis will destroy the element from the DOM, using either parent innerHTML destruction (IE only, that \nreduces memory leaks in IE), or removeChild (for all other browsers).\n\nCreating/Modifying Elements with XML Namespaces\n-----------\n\nTo work with elements and attributes that are XML namespaced, start by adding the namespace using addNamespace:\n\n\tput.addNamespace(\"svg\", \"http://www.w3.org/2000/svg\");\n\tput.addNamespace(\"xlink\", \"http://www.w3.org/1999/xlink\");\n\nFrom there, you can use the CSS3 selector syntax to work with elements and attributes:\n\n\tvar surface = put(\"svg|svg[width='100'][height='100']\");\n\tvar img = put(surface, \"svg|image[xlink|href='path/to/my/image.png']\");\n\nText Content\n-----------\n\nThe put() arguments may also include a subsequent string (or any primitive value including\nboolean and numbers) argument immediately \nfollowing a selector, in which case it is used as the text inside of the new/referenced element.\nFor example, here we could create a new &lt;div> with the text \"Hello, World\" inside.\n\n\tnewDiv = put(parent, \"div\", \"Hello, World\");\n\nThe text is escaped, so any string will show up as is, and will not be parsed as HTML.\n\nChildren and Combinators\n-----------------------\n\nCSS combinators can be used to create child elements and sibling elements. For example,\nwe can use the child operator (or the descendant operator, it acts the same here) to \ncreate nested elements:\n\n\tspanInsideOfDiv = put(reference, \"div.outer span.inner\");\n\nThis would create a new span element (with a class name of \"inner\") as a child of a\nnew div element (with a class name of \"outer\") as a child of the reference element. The\nspan element would be returned. We can also use the sibling operator to reference\nthe last created element or the reference element. In the example we indicate that\nwe want to create sibling of the reference element:\n\n\tnewSpan = put(reference, \"+span\");\n\nWould create a new span element directly after the reference element (reference and \nnewSpan would be siblings.) We can also use the \"-\" operator to indicate that the new element\nshould go before: \n\n\tnewSpan = put(reference, \"-span\");\n\nThis new span element will be inserted before the reference element in the DOM order.\nNote that \"-\" is valid character in tags and classes, so it will only be interpreted as a\ncombinator if it is the first character or if it is preceded by a space.\n\nThe sibling operator can reference the last created element as well. For example\nto add two td element to a table row:\n\n\tput(tableRow, \"td+td\");\n\nThe last created td will be returned.\n\nThe parent operator, \"<\" can be used to reference the parent of the last created \nelement or reference element. In this example, we go crazy, and create a full table,\nusing the parent operator (applied twice) to traverse back up the DOM to create another table row\nafter creating a td element:\n\n\tnewTable = put(referenceElement, \"table.class-name#id tr td[colSpan=2]<<tr td+td<<\");\n\nWe also use a parent operator twice at the end, so that we move back up two parents \nto return the table element (instead of the td element).\n\nFinally, we can use the comma operator to create multiple elements, each basing their selector \nscope on the reference element. For example we could add two more rows to our table\nwithout having to use the double parent operator:\n\n\tput(newTable, \"tr td,tr td+td\");\n\nAppending/Inserting Existing Elements\n---------------------------------\n\nExisting elements may be referenced in the arguments after selectors as well as before.\nIf an existing element is included in the arguments after a selector, the existing element will\nbe appended to the last create/referenced element or it will be inserted according to\na trailing combinator. For example, we could create a &lt;div> and then append \nthe \"child\" element to the new &lt;div>: \n\n\tput(\"div\", child);\n\nOr we can do a simple append of an existing element to another element:\n\n\tput(parent, child);\n\nWe could also do this more explicitly by using a child descendant, '>' (which has the\nsame meaning as a space operator, and is the default action between arguments in put-selector):\n\n\tput(parent, \">\", child);\n\nWe could also use sibling combinators to place the referenced element. We could place\nthe \"second\" element after (as the next sibling) the \"first\" element (which needs a parent\nin order to have a sibling):\n \n\tput(first, \"+\", second);\n\nOr we could create a &lt;div> and place \"first\" before it using the previous sibling combinator:\n\n\tput(parent, \"div.second -\", first);\n\nThe put() function takes an unlimited number of arguments, so we could combine as\nmany selectors and elements as we want: \n\n\tput(parent, \"div.child\", grandchild, \"div.great-grandchild\", gggrandchild);\n\t\nVariable Substitution\n-------------------\n\nThe put() function also supports variable substitution, by using the \"$\" symbol in selectors.\nThe \"$\" can be used for attribute values and to represent text content. When a \"$\"\nis encountered in a selector, the next argument value is consumed and used in it's\nplace. To create an element with a title that comes from the variable \"title\", we could write:\n\n\tput(\"div[title=$]\", title);\n\nThe value of title may have any characters (including ']'), no escaping is needed. \nThis approach can simplify selector string construction and avoids the need for complicated\nescaping mechanisms.\n\nThe \"$\" may be used as a child entity to indicate text content. For example, we could\ncreate a set of &lt;span> element that each have content to be substituted:\n\n\tput(\"span.first-name $, span.last-name $, span.age $\", firstName, lastName, age);\n\nAssigning Properties\n------------------\n\nThe put() function can also take an object with properties to be set on the new/referenced\nelement. For example, we could write:\n\n\tnewDiv = put(parent, \"div\", {\n\t\ttabIndex: 1,\n\t\tinnerHTML: \"Hello, World\"\n\t});\n\nWhich is identical to writing (all the properties are set using direct property access, not setAttribute):\n\n\tnewDiv = put(parent, \"div\");\n\tnewDiv.tabIndex = 1;\n\tnewDiv.innerHTML = \"Hello, World\";\n\nNodeJS/Server Side HTML Generation\n----------------------------\n\nWhile the put() function directly creates DOM elements in the browser, the put() function\ncan be used to generate HTML on the server, in NodeJS. When no DOM is available, \na fast lightweight pseudo-DOM is created that can generate HTML as a string or into a stream.\nThe API is still the same, but the put() function returns pseudo-elements with a \ntoString() method that can be called to return the HTML and sendTo method to direct\ngenerated elements to a stream on the fly. For example:\n\n\tput(\"div.test\").toString() -> '<div class=\"test\"></div>' \n\nTo use put() streaming, we create and element and call sendTo with a target stream.\nIn streaming mode, the elements are written to the stream as they are added to the\nparent DOM structure. This approach is much more efficient because very little\nneeds to be kept in memory, the HTML can be immediately flushed to the network as it is created.\nOnce an element is added to the streamed DOM structure,\nit is immediately sent to the stream, and it's attributes and classes can no longer be\naltered. There are two methods on elements available for streaming purposes:\n\n\telement.sendTo(stream)\n\t\nThe sendTo(stream) method will begin streaming the element to the target stream,\nand any children that are added to the element will be streamed as well.\n\n\telement.end(leaveOpen) \n\nThe end(leaveOpen) method will end the current streaming, closing all the necessary\ntags and closing the stream (unless the argument is true). \n\nThe returned elements also include a put() method so you can directly add to or apply\nCSS selector-based additions to elements, for example:\n\n\telement.put('div.test'); // create a &lt;div class=\"test\">&lt;/div> as a child of element\n\nHere is an example of how we could create a full page in NodeJS that is streamed to \nthe response:\n\n\tvar http = require('http');\n\tvar put = require('put-selector');\n\thttp.createServer(function (req, res) {\n\t\tres.writeHead(200, {'Content-Type': 'text/html'});\n\t\tvar page = put('html').sendTo(res); // create an HTML page, and pipe to the response \n\t\tpage.put('head script[src=app.js]'); // each element is sent immediately\n\t\tpage.put('body div.content', 'Hello, World');\n\t\tpage.end(); // close all the tags, and end the stream\n\t}).listen(80);\n\nOn the server, there are some limitations to put(). The server side DOM emulation\nis designed to be very fast and light and therefore omits much of the standard DOM\nfunctionality, and only what is needed for put() is implemented. Elements can\nnot be moved or removed. DOM creation and updating is still supported in string\ngeneration mode, but only creation is supported in streaming mode. Also, setting \nobject properties is mostly ignored (because only attributes are part of HTML), except\nyou can set the innerHTML of an element. \n\nProper Creation of Inputs\n-------------------------\n\nOlder versions of Internet Explorer have a bug in assigning a \"name\" attribute to input after it\nhas been created, and requires a special creation technique. The put() function handles\nthis for you as long as you specify the name of the input in the property assignment\nobject after the selector string. For example, this input creation will properly work\non all browsers, including IE:\n\n\tnewInput = put(\"input[type=checkbox]\", {name: \"works\"});\n\nUsing on Different document\n-------------------------\n\nIf you are using multiple frames in your web page, you may encounter a situation where\nyou want to use put-selector to make DOM changes on a different HTML document.\nYou can create a separate instance of the put() function for a separate document by\ncalling the put.forDocument(document) function. For example:\n\n\tput2 = put.forDocument(frames[1].document);\n\tput2(\"div\") <- creates a div element that belongs to the document in the second frame.\n\tput(\"div\") <- the original put still functions on the main document for this window/context \n\n# License\n\nput-selector is freely available under *either* the terms of the modified BSD license *or* the\nAcademic Free License version 2.1. More details can be found in the [LICENSE](LICENSE).\nThe put-selector project follows the IP guidelines of Dojo foundation packages and all contributions require a Dojo CLA. \nIf you feel compelled to make a monetary contribution, consider some of the author's [favorite\ncharities](http://thezyps.com/2012-giving-guide/) like [Innovations for Poverty Action](http://www.poverty-action.org/)."
  },
  {
    "path": "node-html.js",
    "content": "\"use strict\";\nvar put;\nfunction Element(tag){\n\tthis.tag = tag;\n}\n// create set of elements with an empty content model, so we now to skip their closing tag\nvar emptyElements = {};\n[\"base\", \"link\", \"meta\", \"hr\", \"br\", \"wbr\", \"img\", \"embed\", \"param\", \"source\", \"track\", \"area\", \"col\", \"input\", \"keygen\", \"command\"].forEach(function(tag){\n\temptyElements[tag] = true;\n});\nvar prototype = Element.prototype;\nvar currentIndentation = '';\nprototype.nodeType = 1;\nprototype.put = function(){\n\tvar args = [this];\n\targs.push.apply(args, arguments);\n\treturn put.apply(null, args);\n}\nprototype.toString = function(noClose){\n\tvar tag = this.tag;\n\tvar emptyElement = emptyElements[tag];\n\tif(put.indentation && !noClose){\n\t\t// using pretty printing with indentation\n\t\tvar lastIndentation = currentIndentation;\n\t\tcurrentIndentation += put.indentation;\n\t\tvar html = (tag == 'html' ? '<!DOCTYPE html>\\n<html' : '\\n' + lastIndentation + '<' + tag) +\n\t\t\t(this.attributes ? this.attributes.join('') : '') + \n\t\t\t(this.className ? ' class=\"' + this.className + '\"' : '') + '>' +  \n\t\t\t(this.children ? this.children.join('') : '') +  \n\t\t\t(!this.mixed && !emptyElement  && this.children ? '\\n' +lastIndentation : '') +\n\t\t\t(emptyElement ? '' : ('</' + tag + '>'));\n\t\t\n\t\tcurrentIndentation = lastIndentation;\n\t\treturn html;\n\t}\n\treturn (this.tag == 'html' ? '<!DOCTYPE html>\\n<html' : '<' + this.tag) +\n\t\t(this.attributes ? this.attributes.join('') : '') + \n\t\t(this.className ? ' class=\"' + this.className + '\"' : '') + '>' +  \n\t\t(this.children ? this.children.join('') : '') +  \n\t\t((noClose || emptyElement) ? '' : ('</' + tag + '>')); \n};\nprototype.sendTo = function(stream){\n\tif(typeof stream == 'function'){ // write function itself\n\t\tstream = {write: stream, end: stream};\n\t}\n\tvar active = this;\n\tvar streamIndentation = '';\n\tfunction pipe(element){\n\t\t// TODO: Perhaps consider buffering if it is any faster and having a non-indentation version that is faster\n\t\tvar closing = returnTo(this);\n\t\tif(closing){\n\t\t\tstream.write(closing);\n\t\t}\n\t\tvar tag = element.tag;\n\t\tif(element.tag){\n\t\t\tif(put.indentation){\n\t\t\t\tstream.write('\\n' + streamIndentation + element.toString(true));\n\t\t\t\tstreamIndentation += put.indentation;\n\t\t\t}else{\n\t\t\t\tstream.write(element.toString(true));\n\t\t\t}\n\t\t\tthis.children = true;\n\t\t\tactive = element;\n\t\t\telement.pipe = pipe;\n\t\t}else{\n\t\t\tstream.write(element.toString());\n\t\t}\n\t}\n\tfunction returnTo(element){\n\t\tvar output = '';\n\t\twhile(active != element){\n\t\t\tif(!active){\n\t\t\t\tthrow new Error(\"Can not add to an element that has already been streamed\");\n\t\t\t}\n\t\t\tvar tag = active.tag;\n\t\t\tvar emptyElement = emptyElements[tag];\n\t\t\tif(put.indentation){\n\t\t\t\tstreamIndentation = streamIndentation.slice(put.indentation.length);\n\t\t\t\tif(!emptyElement){\n\t\t\t\t\toutput += ((active.mixed || !active.children) ? '' : '\\n' + streamIndentation) + '</' + tag + '>';\t\n\t\t\t\t}\n\t\t\t}else if(!emptyElement){\n\t\t\t\toutput += '</' + tag + '>';\n\t\t\t}\n\t\t\tactive = active.parentNode;\n\t\t}\n\t\treturn output;\t\t\n\t}\n\tpipe.call(this, this);\n\t// add on end() function to close all the tags and close the stream\n\tthis.end = function(leaveStreamOpen){\n\t\tstream[leaveStreamOpen ? 'write' : 'end'](returnTo(this) + '\\n</' + this.tag + '>');\n\t}\n\treturn this;\n};\nprototype.children = false;\nprototype.attributes = false;\nprototype.insertBefore = function(child, reference){\n\tchild.parentNode = this;\n\tif(this.pipe){\n\t\treturn this.pipe(child);\n\t\t//return this.s(child);\n\t}\n\tvar children = this.children;\n\tif(!children){\n\t\tchildren = this.children = [];\n\t}\n\tif(reference){\n\t\tfor(var i = 0, l = children.length; i < l; i++){\n\t\t\tif(reference == children[i]){\n\t\t\t\tchild.nextSibling = reference;\n\t\t\t\tif(i > 0){\n\t\t\t\t\tchildren[i-1].nextSibling = child;\n\t\t\t\t}\n\t\t\t\treturn children.splice(i, 0, child);\n\t\t\t}\n\t\t}\n\t}\n\tif(children.length > 0){\n\t\tchildren[children.length-1].nextSibling = child;\n\t}\n\tchildren.push(child);\n};\nprototype.appendChild = function(child){\n\tif(typeof child == \"string\"){\n\t\tthis.mixed = true;\n\t}\n\tif(this.pipe){\n\t\treturn this.pipe(child);\n\t}\n\tvar children = this.children;\n\tif(!children){\n\t\tchildren = this.children = [];\n\t}\n\tchildren.push(child);\n};\nprototype.setAttribute = function(name, value, escape){\n\tvar attributes = this.attributes; \n\tif(!attributes){\n\t\tattributes = this.attributes = [];\n\t}\n\tattributes.push(' ' + name + '=\"' + value + '\"');\n};\nprototype.removeAttribute = function(name, value){\n\tvar attributes = this.attributes; \n\tif(!attributes){\n\t\treturn;\n\t}\n\tvar match = ' ' + name + '=', matchLength = match.length;\n\tfor(var i = 0, l = attributes.length; i < l; i++){\n\t\tif(attributes[i].slice(0, matchLength) == match){\n\t\t\treturn attributes.splice(i, 1);\n\t\t}\n\t}\n};\nObject.defineProperties(prototype, {\n\tinnerHTML: {\n\t\tget: function(){\n\t\t\treturn this.children.join('');\n\t\t},\n\t\tset: function(value){\n\t\t\tthis.mixed = true;\n\t\t\tif(this.pipe){\n\t\t\t\treturn this.pipe(value);\n\t\t\t}\n\t\t\tthis.children = [value];\n\t\t}\n\t}\n});\nfunction DocumentFragment(){\n}\nDocumentFragment.prototype = new Element();\nDocumentFragment.prototype.toString = function(){\n\treturn this.children ? this.children.join('') : '';\n};\n\nvar lessThanRegex = /</g, ampersandRegex = /&/g;\nmodule.exports = function(putModule, putFactory){\n\tput = putModule.exports = putFactory({\n\t// setup a document for string-based HTML creation, using our classes \n\t\tcreateElement: function(tag){\n\t\t\treturn new Element(tag);\n\t\t},\n\t\tcreateElementNS: function(uri, tag){\n\t\t\treturn new Element(namespacePrefixes[uri] + ':' + tag);\n\t\t},\n\t\tcreateTextNode: function(value){\n\t\t\treturn (typeof value == 'string' ? value : ('' + value)).replace(lessThanRegex, \"&lt;\").replace(ampersandRegex, \"&amp;\");\n\t\t},\n\t\tcreateDocumentFragment: function(){\n\t\t\treturn new DocumentFragment(); \n\t\t}\n\t}, { // fragment heuristic, don't use this fragments here, it only slows things down\n\t\ttest: function(){\n\t\t\treturn false;\n\t\t}\n\t});\n\tput.indentation = '  ';\n\tput.Page = function(stream){\n\t\treturn put('html').sendTo(stream);\n\t};\n\tvar namespacePrefixes = {};\n\tvar addNamespace = put.addNamespace;\n\tput.addNamespace = function(name, uri){\n\t\tnamespacePrefixes[uri] = name;\n\t\taddNamespace(name, uri);\n\t}\n};"
  },
  {
    "path": "package.js",
    "content": "var miniExcludes = {\n\t\t\"put-selector/README.md\": 1,\n\t\t\"put-selector/package\": 1\n\t},\n\tamdExcludes = {\n\t},\n\tcopyOnly = {\n\t\t\"put-selector/node-html\": 1\n\t},\n\tisJsRe = /\\.js$/,\n\tisTestRe = /\\/test\\//;\n\nvar profile = {\n\tresourceTags: {\n\t\ttest: function(filename, mid){\n\t\t\treturn isTestRe.test(filename);\n\t\t},\n\n\t\tminiExclude: function(filename, mid){\n\t\t\treturn isTestRe.test(filename) || mid in miniExcludes;\n\t\t},\n\n\t\tamd: function(filename, mid){\n\t\t\treturn isJsRe.test(filename) && !(mid in amdExcludes);\n\t\t},\n\n\t\tcopyOnly: function(filename, mid){\n\t\t\treturn mid in copyOnly;\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"put-selector\",\n  \"author\": \"Kris Zyp\",\n  \"version\": \"0.3.6\",\n  \"description\": \"A high-performance, lightweight function for creating and manipulating DOM elements with succinct, elegant, familiar CSS selector-based syntax\",\n  \"licenses\": [\n     {\n         \"type\": \"AFLv2.1\",\n         \"url\": \"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L43\"\n     },\n     {\n         \"type\": \"BSD\",\n         \"url\": \"http://trac.dojotoolkit.org/browser/dojo/trunk/LICENSE#L13\"\n     }\n  ],\n \"maintainers\": [\n  \t{\n  \t\t\"name\": \"Kris Zyp\",\n  \t\t\"email\": \"kriszyp@gmail.com\"\n  \t}\n  ],\n  \"repository\": {\n    \"type\":\"git\",\n    \"url\":\"http://github.com/kriszyp/put-selector\"\n  },\n  \"directories\": {\n    \"lib\": \".\"\n  },\n  \"main\": \"./put\",\n  \"icon\": \"http://packages.dojofoundation.org/images/xstyle.jpg\",\n  \"dojoBuild\": \"package.js\"\n}\n"
  },
  {
    "path": "put.js",
    "content": "(function(localDefine){\nvar forDocument, fragmentFasterHeuristic = /[-+,> ]/; // if it has any of these combinators, it is probably going to be faster with a document fragment \nlocalDefine([], forDocument = function(doc, newFragmentFasterHeuristic){\n\"use strict\";\n\t// module:\n\t//\t\tput-selector/put\n\t// summary:\n\t//\t\tThis module defines a fast lightweight function for updating and creating new elements\n\t//\t\tterse, CSS selector-based syntax. The single function from this module creates\n\t// \t\tnew DOM elements and updates existing elements. See README.md for more information.\n\t//\texamples:\n\t//\t\tTo create a simple div with a class name of \"foo\":\n\t//\t\t|\tput(\"div.foo\");\n\tfragmentFasterHeuristic = newFragmentFasterHeuristic || fragmentFasterHeuristic;\n\tvar selectorParse = /(?:\\s*([-+ ,<>]))?\\s*(\\.|!\\.?|#)?([-\\w\\u00A0-\\uFFFF%$|]+)?(?:\\[([^\\]=]+)=?('(?:\\\\.|[^'])*'|\"(?:\\\\.|[^\"])*\"|[^\\]]*)\\])?/g,\n\t\tundefined, namespaceIndex, namespaces = false,\n\t\tdoc = doc || document,\n\t\tieCreateElement = typeof doc.createElement == \"object\"; // telltale sign of the old IE behavior with createElement that does not support later addition of name \n\tfunction insertTextNode(element, text){\n\t\telement.appendChild(doc.createTextNode(text));\n\t}\n\tfunction put(topReferenceElement){\n\t\tvar fragment, lastSelectorArg, nextSibling, referenceElement, current,\n\t\t\targs = arguments,\n\t\t\treturnValue = args[0]; // use the first argument as the default return value in case only an element is passed in\n\t\tfunction insertLastElement(){\n\t\t\t// we perform insertBefore actions after the element is fully created to work properly with \n\t\t\t// <input> tags in older versions of IE that require type attributes\n\t\t\t//\tto be set before it is attached to a parent.\n\t\t\t// We also handle top level as a document fragment actions in a complex creation \n\t\t\t// are done on a detached DOM which is much faster\n\t\t\t// Also if there is a parse error, we generally error out before doing any DOM operations (more atomic) \n\t\t\tif(current && referenceElement && current != referenceElement){\n\t\t\t\t(referenceElement == topReferenceElement &&\n\t\t\t\t\t// top level, may use fragment for faster access \n\t\t\t\t\t(fragment || \n\t\t\t\t\t\t// fragment doesn't exist yet, check to see if we really want to create it \n\t\t\t\t\t\t(fragment = fragmentFasterHeuristic.test(argument) && doc.createDocumentFragment()))\n\t\t\t\t\t\t\t// any of the above fails just use the referenceElement  \n\t\t\t\t\t\t\t ? fragment : referenceElement).\n\t\t\t\t\t\t\t\tinsertBefore(current, nextSibling || null); // do the actual insertion\n\t\t\t}\n\t\t}\n\t\tfor(var i = 0; i < args.length; i++){\n\t\t\tvar argument = args[i];\n\t\t\tif(typeof argument == \"object\"){\n\t\t\t\tlastSelectorArg = false;\n\t\t\t\tif(argument instanceof Array){\n\t\t\t\t\t// an array\n\t\t\t\t\tcurrent = doc.createDocumentFragment();\n\t\t\t\t\tfor(var key = 0; key < argument.length; key++){\n\t\t\t\t\t\tcurrent.appendChild(put(argument[key]));\n\t\t\t\t\t}\n\t\t\t\t\targument = current;\n\t\t\t\t}\n\t\t\t\tif(argument.nodeType){\n\t\t\t\t\tcurrent = argument;\n\t\t\t\t\tinsertLastElement();\n\t\t\t\t\treferenceElement = argument;\n\t\t\t\t\tnextSibling = 0;\n\t\t\t\t}else{\n\t\t\t\t\t// an object hash\n\t\t\t\t\tfor(var key in argument){\n\t\t\t\t\t\tcurrent[key] = argument[key];\n\t\t\t\t\t}\t\t\t\t\n\t\t\t\t}\n\t\t\t}else if(lastSelectorArg){\n\t\t\t\t// a text node should be created\n\t\t\t\t// take a scalar value, use createTextNode so it is properly escaped\n\t\t\t\t// createTextNode is generally several times faster than doing an escaped innerHTML insertion: http://jsperf.com/createtextnode-vs-innerhtml/2\n\t\t\t\tlastSelectorArg = false;\n\t\t\t\tinsertTextNode(current, argument);\n\t\t\t}else{\n\t\t\t\tif(i < 1){\n\t\t\t\t\t// if we are starting with a selector, there is no top element\n\t\t\t\t\ttopReferenceElement = null;\n\t\t\t\t}\n\t\t\t\tlastSelectorArg = true;\n\t\t\t\tvar leftoverCharacters = argument.replace(selectorParse, function(t, combinator, prefix, value, attrName, attrValue){\n\t\t\t\t\tif(combinator){\n\t\t\t\t\t\t// insert the last current object\n\t\t\t\t\t\tinsertLastElement();\n\t\t\t\t\t\tif(combinator == '-' || combinator == '+'){\n\t\t\t\t\t\t\t// + or - combinator, \n\t\t\t\t\t\t\t// TODO: add support for >- as a means of indicating before the first child?\n\t\t\t\t\t\t\treferenceElement = (nextSibling = (current || referenceElement)).parentNode;\n\t\t\t\t\t\t\tcurrent = null;\n\t\t\t\t\t\t\tif(combinator == \"+\"){\n\t\t\t\t\t\t\t\tnextSibling = nextSibling.nextSibling;\n\t\t\t\t\t\t\t}// else a - operator, again not in CSS, but obvious in it's meaning (create next element before the current/referenceElement)\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tif(combinator == \"<\"){\n\t\t\t\t\t\t\t\t// parent combinator (not really in CSS, but theorized, and obvious in it's meaning)\n\t\t\t\t\t\t\t\treferenceElement = current = (current || referenceElement).parentNode;\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\tif(combinator == \",\"){\n\t\t\t\t\t\t\t\t\t// comma combinator, start a new selector\n\t\t\t\t\t\t\t\t\treferenceElement = topReferenceElement;\n\t\t\t\t\t\t\t\t}else if(current){\n\t\t\t\t\t\t\t\t\t// else descendent or child selector (doesn't matter, treated the same),\n\t\t\t\t\t\t\t\t\treferenceElement = current;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcurrent = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnextSibling = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(current){\n\t\t\t\t\t\t\treferenceElement = current;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar tag = !prefix && value;\n\t\t\t\t\tif(tag || (!current && (prefix || attrName))){\n\t\t\t\t\t\tif(tag == \"$\"){\n\t\t\t\t\t\t\t// this is a variable to be replaced with a text node\n\t\t\t\t\t\t\tinsertTextNode(referenceElement, args[++i]);\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t// Need to create an element\n\t\t\t\t\t\t\ttag = tag || put.defaultTag;\n\t\t\t\t\t\t\tvar ieInputName = ieCreateElement && args[i +1] && args[i +1].name;\n\t\t\t\t\t\t\tif(ieInputName){\n\t\t\t\t\t\t\t\t// in IE, we have to use the crazy non-standard createElement to create input's that have a name \n\t\t\t\t\t\t\t\ttag = '<' + tag + ' name=\"' + ieInputName + '\">';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// we swtich between creation methods based on namespace usage\n\t\t\t\t\t\t\tcurrent = namespaces && ~(namespaceIndex = tag.indexOf('|')) ?\n\t\t\t\t\t\t\t\tdoc.createElementNS(namespaces[tag.slice(0, namespaceIndex)], tag.slice(namespaceIndex + 1)) : \n\t\t\t\t\t\t\t\tdoc.createElement(tag);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(prefix){\n\t\t\t\t\t\tif(value == \"$\"){\n\t\t\t\t\t\t\tvalue = args[++i];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(prefix == \"#\"){\n\t\t\t\t\t\t\t// #id was specified\n\t\t\t\t\t\t\tcurrent.id = value;\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t// we are in the className addition and removal branch\n\t\t\t\t\t\t\tvar currentClassName = current.className;\n\t\t\t\t\t\t\t// remove the className (needed for addition or removal)\n\t\t\t\t\t\t\t// see http://jsperf.com/remove-class-name-algorithm/2 for some tests on this\n\t\t\t\t\t\t\tvar removed = currentClassName && (\" \" + currentClassName + \" \").replace(\" \" + value + \" \", \" \");\n\t\t\t\t\t\t\tif(prefix == \".\"){\n\t\t\t\t\t\t\t\t// addition, add the className\n\t\t\t\t\t\t\t\tcurrent.className = currentClassName ? (removed + value).substring(1) : value;\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\t// else a '!' class removal\n\t\t\t\t\t\t\t\tif(argument == \"!\"){\n\t\t\t\t\t\t\t\t\tvar parentNode;\n\t\t\t\t\t\t\t\t\t// special signal to delete this element\n\t\t\t\t\t\t\t\t\tif(ieCreateElement){\n\t\t\t\t\t\t\t\t\t\t// use the ol' innerHTML trick to get IE to do some cleanup\n\t\t\t\t\t\t\t\t\t\tput(\"div\", current, '<').innerHTML = \"\";\n\t\t\t\t\t\t\t\t\t}else if(parentNode = current.parentNode){ // intentional assigment\n\t\t\t\t\t\t\t\t\t\t// use a faster, and more correct (for namespaced elements) removal (http://jsperf.com/removechild-innerhtml)\n\t\t\t\t\t\t\t\t\t\tparentNode.removeChild(current);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\t\t// we already have removed the class, just need to trim\n\t\t\t\t\t\t\t\t\tremoved = removed.substring(1, removed.length - 1);\n\t\t\t\t\t\t\t\t\t// only assign if it changed, this can save a lot of time\n\t\t\t\t\t\t\t\t\tif(removed != currentClassName){\n\t\t\t\t\t\t\t\t\t\tcurrent.className = removed;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// CSS class removal\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(attrName){\n\t\t\t\t\t\tif(attrValue && (attrValue.charAt(0) === '\"' || attrValue.charAt(0) === \"'\")) {\n\t\t\t\t\t\t\t// quoted string\n\t\t\t\t\t\t\tattrValue = attrValue.slice(1, -1).replace(/\\\\/g, '')\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(attrValue == \"$\"){\n\t\t\t\t\t\t\tattrValue = args[++i];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// [name=value]\n\t\t\t\t\t\tif(attrName == \"style\"){\n\t\t\t\t\t\t\t// handle the special case of setAttribute not working in old IE\n\t\t\t\t\t\t\tcurrent.style.cssText = attrValue;\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tvar method = attrName.charAt(0) == \"!\" ? (attrName = attrName.substring(1)) && 'removeAttribute' : 'setAttribute';\n\t\t\t\t\t\t\t// determine if we need to use a namespace\n\t\t\t\t\t\t\tnamespaces && ~(namespaceIndex = attrName.indexOf('|')) ?\n\t\t\t\t\t\t\t\tcurrent[method + \"NS\"](namespaces[attrName.slice(0, namespaceIndex)], attrName.slice(namespaceIndex + 1), attrValue) :\n\t\t\t\t\t\t\t\tcurrent[method](attrName, attrValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn '';\n\t\t\t\t});\n\t\t\t\tif(leftoverCharacters){\n\t\t\t\t\tthrow new SyntaxError(\"Unexpected char \" + leftoverCharacters + \" in \" + argument);\n\t\t\t\t}\n\t\t\t\tinsertLastElement();\n\t\t\t\treferenceElement = returnValue = current || referenceElement;\n\t\t\t}\n\t\t}\n\t\tif(topReferenceElement && fragment){\n\t\t\t// we now insert the top level elements for the fragment if it exists\n\t\t\ttopReferenceElement.appendChild(fragment);\n\t\t}\n\t\treturn returnValue;\n\t}\n\tput.addNamespace = function(name, uri){\n\t\tif(doc.createElementNS){\n\t\t\t(namespaces || (namespaces = {}))[name] = uri;\n\t\t}else{\n\t\t\t// for old IE\n\t\t\tdoc.namespaces.add(name, uri);\n\t\t}\n\t};\n\tput.defaultTag = \"div\";\n\tput.forDocument = forDocument;\n\treturn put;\n});\n})(function(id, deps, factory){\n\tfactory = factory || deps;\n\tif(typeof define === \"function\"){\n\t\t// AMD loader\n\t\tdefine([], function(){\n\t\t\treturn factory();\n\t\t});\n\t}else if(typeof window == \"undefined\"){\n\t\t// server side JavaScript, probably (hopefully) NodeJS\n\t\trequire(\"./node-html\")(module, factory);\n\t}else{\n\t\t// plain script in a browser\n\t\tput = factory();\n\t}\n});\n"
  },
  {
    "path": "test/example-server.js",
    "content": "\tvar http = require('http');\n\tvar put = require('put-selector');\n\thttp.createServer(function (req, res) {\n\t\tres.writeHead(200, {'Content-Type': 'text/html'});\n\t\tvar page = put('html').sendTo(res); // create an HTML page, and pipe to the response \n\t\tput(page, 'head script[src=app.js]'); // each are sent immediately\n\t\tput(page, 'body div.content', 'Hello, World');\n\t\tpage.end(); // close all the tags, and end the stream\n\t}).listen(81);"
  },
  {
    "path": "test/node-put.js",
    "content": "var assert = require(\"assert\"),\n\tput = require(\"../put\");\nexports.testSimple = function() {\n\tassert.equal(put('div span.test<').toString(), '\\n<div>\\n  <span class=\"test\"></span>\\n</div>');\n\tassert.equal(put('div', ['header', 'section']).toString(), '\\n<div>\\n  <header></header>\\n  <section></section>\\n</div>');\n};\nexports.testPage = function() {\n\tput.indentation = false;\n\tvar page = put('html');\n\tput(page, 'head script[src=test.js]+link[href=test.css]+link[href=test2.css]');\n\tvar content = put(page, 'body div.header $\\\n\t\t\t+div.content', 'Hello World');\n\tput(content, 'div.left', 'Left');\n\tput.addNamespace('foo', 'http://foo.com/foo');\n\tput(content, 'foo|bar');\n\tput(content, 'div.right', {innerHTML: 'Right <b>text</b>'});\n\tassert.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>');\n};\nexports.testStream = function() {\n\t//put.indentation = '  ';\n\tvar output = '';\n\tvar stream = {\n\t\twrite: function(str){\n\t\t\toutput += str;\n\t\t},\n\t\tend: function(str){\n\t\t\toutput += str;\n\t\t}\n\t}\n\tvar page = put('html').sendTo(stream);\n\tput(page, 'head script[src=test.js]+link[href=test.css]+link[href=test2.css]');\n\tvar content = put(page, 'body div.header $\\\n\t\t\t+div.content', 'Hello World');\n\tcontent.put('div.left', 'Left');\n\tcontent.put('div.right', {innerHTML: 'Right <b>text</b>'});\n\tpage.end();\n\tassert.equal(output, '<!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>\\n</html>');\n};\nif (require.main === module)\n    require(\"patr/runner\").run(exports);"
  },
  {
    "path": "test/put.js",
    "content": "var div = put(\"div\");\nconsole.assert(div.tagName.toLowerCase() == \"div\");\nconsole.assert(put(div) === div);\n\nvar body = document.body;\nput(body, \"h1 $\", \"Running put() tests\");\n\nvar parentDiv = div;\n\nvar span1 = put(parentDiv, \"span.class-name-1.class-name-2[name=span1]\");\nconsole.assert(span1.className == \"class-name-1 class-name-2\");\nconsole.assert(span1.getAttribute(\"name\") == \"span1\");\nconsole.assert(span1.parentNode == div);\nput(span1, \"!class-name-1.class-name-3[!name]\");\nconsole.assert(span1.className == \"class-name-2 class-name-3\");\nput(span1, \"!.class-name-3\");\nconsole.assert(span1.className == \"class-name-2\");\nconsole.assert(span1.getAttribute(\"name\") == null);\nput(span1, \"[name=span1]\"); // readd the attribute\n\nvar defaultTag = put(parentDiv, \" .class\");\nconsole.assert(defaultTag.tagName.toLowerCase() == \"div\");\nvar span2, span3 = put(span1, \"+span[name=span2] + span[name=span3]\");\nconsole.assert(span3.getAttribute(\"name\") == \"span3\");\nconsole.assert((span2 = span3.previousSibling).getAttribute(\"name\") == \"span2\");\nconsole.assert(span3.previousSibling.previousSibling.getAttribute(\"name\") == \"span1\");\nvar span4 = put(span2, \">\", span3, \"span.$[name=$]\", \"span3-child\", \"span4\");\nconsole.assert(span3.parentNode == span2);\nconsole.assert(span4.parentNode == span3);\nconsole.assert(span4.className == \"span3-child\");\nconsole.assert(span4.getAttribute('name') == \"span4\");\nput(span2, \"+\", span3, \"+\", span4);\nconsole.assert(span2.nextSibling == span3);\nconsole.assert(span3.nextSibling == span4);\n\nvar div = put('div[title=$]', 4)\nconsole.assert(div.title, '4')\n\nvar parentDiv = put(\"div.parent span.first $ + span.second $<\", \"inside first\", \"inside second\");\nconsole.assert(parentDiv.firstChild.innerHTML, \"inside first\");\nconsole.assert(parentDiv.lastChild.innerHTML, \"inside second\");\n\nput(span3, \"!\"); // destroy span3\nconsole.assert(span2.nextSibling != span3); // make sure span3 is gone\n\nvar span0 = put(span1, \"-span[name=span0]\");\nconsole.assert(span0.getAttribute(\"name\") == \"span0\");\n\nvar spanMinusTwo = put(span0, \"-span -span\");\nconsole.assert(spanMinusTwo.nextSibling.nextSibling == span0);\n\n\nvar spanWithId = put(parentDiv, \"span#with-id\");\nconsole.assert(spanWithId.id == \"with-id\");\n\nvar table = put(parentDiv, \"table.class-name#id tr.class-name td[colSpan=2]<<tr.class-name td+td<<\");\nconsole.assert(table.tagName.toLowerCase() == \"table\");\nconsole.assert(table.childNodes.length == 2);\nconsole.assert(table.firstChild.className == \"class-name\");\nconsole.assert(table.firstChild.childNodes.length == 1);\nconsole.assert(table.lastChild.className == \"class-name\");\nconsole.assert(table.lastChild.childNodes.length == 2);\n\nput(table, \"tr>td,tr>td+td\");\nconsole.assert(table.childNodes.length == 4);\nconsole.assert(table.lastChild.childNodes.length == 2);\n\nvar checkbox = put(div, \"input[type=checkbox][checked]\");\nconsole.assert(checkbox.type == \"checkbox\");\nconsole.assert(checkbox.hasAttribute(\"checked\"));\n\ndiv = put(\"div\");\nvar arrayFrag = put(div, [\"span.c1\", \"span.c2\", \"span.c3\"]);\nconsole.assert(arrayFrag.tagName.toLowerCase() == \"div\");\nconsole.assert(div.firstChild.className == \"c1\");\nconsole.assert(div.lastChild.className == \"c3\");\n\nput(div, \"#encode%3A%20d\");\nconsole.assert(div.id == \"encode%3A%20d\");\n\nput(div, \"[title='with single \\\\' quote']\");\nconsole.assert(div.title, \"with single ' quote\");\n\nput(div, \"[title='[brackets]']\");\nconsole.assert(div.title, \"[brackets]\");\n\nvar styled = put(\"div.someClass[style=color:green;margin-left:10px]\");\nconsole.assert(styled.style.marginLeft.slice(0,2) == \"10\");\n\n\nput.addNamespace(\"put\", \"http://github.com/kriszyp/dgrid\");\nvar namespaced = put(\"put|foo[bar=test1][put|bar=test2]\");\nconsole.assert((namespaced.namespaceURI || namespaced.tagUrn) == \"http://github.com/kriszyp/dgrid\");\nconsole.assert(namespaced.tagName == \"foo\");\nconsole.assert(namespaced.getAttribute(\"bar\") == \"test1\");\nif(document.createElementNS){\n\tconsole.assert(namespaced.getAttributeNS(\"http://github.com/kriszyp/dgrid\",\"bar\") == \"test2\");\n}\n\nput.addNamespace(\"svg\", \"http://www.w3.org/2000/svg\");\nvar svg = put(document.body, \"svg|svg#svg-test\");\nput(svg, \"!\");\nconsole.assert(document.getElementById(\"svg-test\") == null);\n\nvar unicode = put(\"div.unicode-你好\");\nconsole.assert(unicode.className === \"unicode-你好\");\n\nput(body, \"div\", {innerHTML: \"finished tests, check console for errors\"});\n\nvar unicodeId = put(body, \"div#ÅÄÖ\");\nconsole.assert(unicodeId.id === \"ÅÄÖ\");\n"
  },
  {
    "path": "test/testPut.html",
    "content": "<!DOCTYPE HTML>\n<html lang=\"en-US\">\n<head>\n<meta charset=\"UTF-8\">\n<title>Test put-selector/put</title>\n\n<script src=\"../put.js\"></script>\n</head>\n<body>\n<script src=\"put.js\"></script>\n</body>\n</html>\n"
  }
]