| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- var Cache = require('../cache')
- var templateCache = new Cache(100)
- var map = {
- _default : [0, '', ''],
- legend : [1, '<fieldset>', '</fieldset>'],
- tr : [2, '<table><tbody>', '</tbody></table>'],
- col : [
- 2,
- '<table><tbody></tbody><colgroup>',
- '</colgroup></table>'
- ]
- }
- map.td =
- map.th = [
- 3,
- '<table><tbody><tr>',
- '</tr></tbody></table>'
- ]
- map.option =
- map.optgroup = [
- 1,
- '<select multiple="multiple">',
- '</select>'
- ]
- map.thead =
- map.tbody =
- map.colgroup =
- map.caption =
- map.tfoot = [1, '<table>', '</table>']
- map.g =
- map.defs =
- map.symbol =
- map.use =
- map.image =
- map.text =
- map.circle =
- map.ellipse =
- map.line =
- map.path =
- map.polygon =
- map.polyline =
- map.rect = [
- 1,
- '<svg ' +
- 'xmlns="http://www.w3.org/2000/svg" ' +
- 'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
- 'xmlns:ev="http://www.w3.org/2001/xml-events"' +
- 'version="1.1">',
- '</svg>'
- ]
- var TAG_RE = /<([\w:]+)/
- /**
- * Convert a string template to a DocumentFragment.
- * Determines correct wrapping by tag types. Wrapping
- * strategy found in jQuery & component/domify.
- *
- * @param {String} templateString
- * @return {DocumentFragment}
- */
- function stringToFragment (templateString) {
- // try a cache hit first
- var hit = templateCache.get(templateString)
- if (hit) {
- return hit
- }
- var frag = document.createDocumentFragment()
- var tagMatch = TAG_RE.exec(templateString)
- if (!tagMatch) {
- // text only, return a single text node.
- frag.appendChild(
- document.createTextNode(templateString)
- )
- } else {
- var tag = tagMatch[1]
- var wrap = map[tag] || map._default
- var depth = wrap[0]
- var prefix = wrap[1]
- var suffix = wrap[2]
- var node = document.createElement('div')
- node.innerHTML = prefix + templateString.trim() + suffix
- while (depth--) {
- node = node.lastChild
- }
- var child
- /* jshint boss:true */
- while (child = node.firstChild) {
- frag.appendChild(child)
- }
- }
- templateCache.put(templateString, frag)
- return frag
- }
- /**
- * Convert a template node to a DocumentFragment.
- *
- * @param {Node} node
- * @return {DocumentFragment}
- */
- function nodeToFragment (node) {
- var tag = node.tagName
- // if its a template tag and the browser supports it,
- // its content is already a document fragment.
- if (
- tag === 'TEMPLATE' &&
- node.content instanceof DocumentFragment
- ) {
- return node.content
- }
- return tag === 'SCRIPT'
- ? stringToFragment(node.textContent)
- : stringToFragment(node.innerHTML)
- }
- /**
- * Process the template option and normalizes it into a
- * a DocumentFragment that can be used as a partial or a
- * instance template.
- *
- * @param {*} template
- * Possible values include:
- * - DocumentFragment object
- * - Node object of type Template
- * - id selector: '#some-template-id'
- * - template string: '<div><span>{{msg}}</span></div>'
- * @param {Boolean} clone
- * @return {DocumentFragment|undefined}
- */
- exports.parse = function (template, clone) {
- var node, frag
- // if the template is already a document fragment,
- // do nothing
- if (template instanceof DocumentFragment) {
- return clone
- ? template.cloneNode(true)
- : template
- }
- if (typeof template === 'string') {
- // id selector
- if (template.charAt(0) === '#') {
- // id selector can be cached too
- frag = templateCache.get(template)
- if (!frag) {
- node = document.getElementById(template.slice(1))
- if (node) {
- frag = nodeToFragment(node)
- // save selector to cache
- templateCache.put(template, frag)
- }
- }
- } else {
- // normal string template
- frag = stringToFragment(template)
- }
- } else if (template.nodeType) {
- // a direct node
- frag = nodeToFragment(template)
- }
- return frag && clone
- ? frag.cloneNode(true)
- : frag
- }
|