• Jump To … +
    elements.js render.js scanner.js view.js
  • elements.js

  • ¶
    steal('can/util', "can/view",function (can) {
    
    	var doc = typeof document !== "undefined" ? document: null;
    
    	var selectsCommentNodes = doc && (function(){
    		return can.$(document.createComment('~')).length === 1;
    	})();
    
    	/**
    	 * @property {Object} can.view.elements
    	 * @parent can.view
    	 *
    	 * Provides helper methods for and information about the behavior
    	 * of DOM elements.
    	 */
    	var elements = {
    		tagToContentPropMap: {
    			option: ( doc && "textContent" in document.createElement("option") ) ? "textContent" : "innerText",
    			textarea: 'value'
    		},
    		/**
    		 * @property {Object.<String,(String|Boolean|function)>} can.view.elements.attrMap
    		 * @parent can.view.elements
    		 *
    		 *
    		 * A mapping of
    		 * special attributes to their JS property. For example:
    		 *
    		 *     "class" : "className"
    		 *
    		 * means get or set `element.className`. And:
    		 *
    		 *      "checked" : true
    		 *
    		 * means set `element.checked = true`.
    		 *
    		 *
    		 * If the attribute name is not found, it's assumed to use
    		 * `element.getAttribute` and `element.setAttribute`.
    		 */
  • ¶

    3.0 TODO: remove

    		attrMap: can.attr.map,
  • ¶

    matches the attrName of a regexp

    		attrReg: /([^\s=]+)[\s]*=[\s]*/,
  • ¶

    3.0 TODO: remove

    		defaultValue: can.attr.defaultValue,
  • ¶

    a map of parent element to child elements

    		/**
    		 * @property {Object.<String,String>} can.view.elements.tagMap
    		 * @parent can.view.elements
    		 *
    		 * A mapping of parent node names to child node names that can be inserted within
    		 * the parent node name.  For example: `table: "tbody"` means that
    		 * if you want a placeholder element within a `table`, a `tbody` will be
    		 * created.
    		 */
    		tagMap: {
    			'': 'span',
    			colgroup: 'col',
    			table: 'tbody',
    			tr: 'td',
    			ol: 'li',
    			ul: 'li',
    			tbody: 'tr',
    			thead: 'tr',
    			tfoot: 'tr',
    			select: 'option',
    			optgroup: 'option'
    		},
  • ¶

    a tag’s parent element

    		reverseTagMap: {
    			col: 'colgroup',
    			tr: 'tbody',
    			option: 'select',
    			td: 'tr',
    			th: 'tr',
    			li: 'ul'
    		},
  • ¶

    tags that should be handled as self-closing and should not have content in them when generated as part of binding hookup

    		selfClosingTags: {
    			col: true
    		},
  • ¶

    Used to determine the parentNode if el is directly within a documentFragment

    		getParentNode: function (el, defaultParentNode) {
    			return defaultParentNode && el.parentNode.nodeType === 11 ? defaultParentNode : el.parentNode;
    		},
  • ¶

    3.0 TODO: remove

    		setAttr: can.attr.set,
  • ¶

    3.0 TODO: remove

    		getAttr: can.attr.get,
  • ¶

    3.0 TODO: remove

    		removeAttr: can.attr.remove,
  • ¶

    Gets a “pretty” value for something

    		contentText: function (text) {
    			if (typeof text === 'string') {
    				return text;
    			}
  • ¶

    If has no value, return an empty string.

    			if (!text && text !== 0) {
    				return '';
    			}
    			return '' + text;
    		},
    		/**
    		 * @function can.view.elements.after
    		 * @parent can.view.elements
    		 *
    		 * Inserts newFrag after oldElements.
    		 *
    		 * @param {Array.<HTMLElement>} oldElements
    		 * @param {DocumentFragment} newFrag
    		 */
    		after: function (oldElements, newFrag) {
    			var last = oldElements[oldElements.length - 1];
  • ¶

    Insert it in the document or documentFragment

    			if (last.nextSibling) {
    				can.insertBefore(last.parentNode, newFrag, last.nextSibling, can.document);
    			} else {
    				can.appendChild(last.parentNode, newFrag, can.document);
    			}
    		},
    		/**
    		 * @function can.view.elements.replace
    		 * @parent can.view.elements
    		 *
    		 * Replaces `oldElements` with `newFrag`
    		 *
    		 * @param {Array.<HTMLElement>} oldElements
    		 * @param {DocumentFragment} newFrag
    		 */
    		replace: function (oldElements, newFrag) {
  • ¶

    The following helps make sure that a selected

    			var selectedValue,
    				parentNode = oldElements[0].parentNode;
    				
    			if(parentNode.nodeName.toUpperCase() === "SELECT" && parentNode.selectedIndex >= 0) {
    				selectedValue = parentNode.value;
    			}
    			
    			
    			elements.after(oldElements, newFrag);
    			if(can.remove(can.$(oldElements)).length < oldElements.length && !selectsCommentNodes) {
    				can.each(oldElements, function(el) {
    					if(el.nodeType === 8) {
    						el.parentNode.removeChild(el);
    					}
    				});
    			}
    			if(selectedValue !== undefined) {
    				parentNode.value = selectedValue;
    			}
    		}
    	};
    
    	can.view.elements = elements;
    
    	return elements;
    });