/** * @requires javelin-magical-init * javelin-install * javelin-util * javelin-vector * javelin-stratcom * @provides javelin-dom * * @javelin-installs JX.$ * @javelin-installs JX.$N * @javelin-installs JX.$H * * @javelin */ /** * Select an element by its "id" attribute, like ##document.getElementById()##. * For example: * * var node = JX.$('some_id'); * * This will select the node with the specified "id" attribute: * * LANG=HTML *
...
* * If the specified node does not exist, @{JX.$()} will throw an exception. * * For other ways to select nodes from the document, see @{JX.DOM.scry()} and * @{JX.DOM.find()}. * * @param string "id" attribute to select from the document. * @return Node Node with the specified "id" attribute. * * @group dom */ JX.$ = function(id) { if (__DEV__) { if (!id) { JX.$E('Empty ID passed to JX.$()!'); } } var node = document.getElementById(id); if (!node || (node.id != id)) { if (__DEV__) { if (node && (node.id != id)) { JX.$E( 'JX.$("'+id+'"): '+ 'document.getElementById() returned an element without the '+ 'correct ID. This usually means that the element you are trying '+ 'to select is being masked by a form with the same value in its '+ '"name" attribute.'); } } JX.$E("JX.$('" + id + "') call matched no nodes."); } return node; }; /** * Upcast a string into an HTML object so it is treated as markup instead of * plain text. See @{JX.$N} for discussion of Javelin's security model. Every * time you call this function you potentially open up a security hole. Avoid * its use wherever possible. * * This class intentionally supports only a subset of HTML because many browsers * named "Internet Explorer" have awkward restrictions around what they'll * accept for conversion to document fragments. Alter your datasource to emit * valid HTML within this subset if you run into an unsupported edge case. All * the edge cases are crazy and you should always be reasonably able to emit * a cohesive tag instead of an unappendable fragment. * * You may use @{JX.$H} as a shortcut for creating new JX.HTML instances: * * JX.$N('div', {}, some_html_blob); // Treat as string (safe) * JX.$N('div', {}, JX.$H(some_html_blob)); // Treat as HTML (unsafe!) * * @task build String into HTML * @task nodes HTML into Nodes * * @group dom */ JX.install('HTML', { construct : function(str) { if (str instanceof JX.HTML) { this._content = str._content; return; } if (__DEV__) { if ((typeof str !== 'string') && (!str || !str.match)) { JX.$E( 'new JX.HTML(): ' + 'call initializes an HTML object with an empty value.'); } var tags = ['legend', 'thead', 'tbody', 'tfoot', 'column', 'colgroup', 'caption', 'tr', 'th', 'td', 'option']; var evil_stuff = new RegExp('^\\s*<(' + tags.join('|') + ')\\b', 'i'); var match = str.match(evil_stuff); if (match) { JX.$E( 'new JX.HTML("<' + match[1] + '>..."): ' + 'call initializes an HTML object with an invalid partial fragment ' + 'and can not be converted into DOM nodes. The enclosing tag of an ' + 'HTML content string must be appendable to a document fragment. ' + 'For example, is allowed but or are not.'); } var really_evil = /..."): ' + 'call initializes an HTML object with an embedded script tag! ' + 'Are you crazy?! Do NOT do this!!!'); } var wont_work = /..."): ' + 'call initializes an HTML object with an embedded tag. IE ' + 'will not do the right thing with this.'); } // TODO(epriestley): May need to deny