## TinyMCE_DOMUtils.class.js

#### Summary

No overview generated for 'TinyMCE_DOMUtils.class.js'

    /**
     * $RCSfile: overview-summary-TinyMCE_DOMUtils.class.js.html,v $
     * $Revision: 1.42 $
     * $Date: 2006/04/14 20:00:29 $
     *
     * @author Moxiecode
     * @copyright Copyright © 2004-2006, Moxiecode Systems AB, All rights reserved.
     *
     * The contents of this file will be wrapped in a class later on.
     */

    /**
     * Returns a element by a specific attribute and it's value.
     *
     * @param {HTMLElement} n Element to search in.
     * @param {string} e Element name to search for.
     * @param {string} a Attribute name to search for.
     * @param {string} v Attribute value to search for.
     * @return HTML element that matched the criterias or null on failure.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype.getElementByAttributeValue = function(n, e, a, v) {
    	return (n = this.getElementsByAttributeValue(n, e, a, v)).length == 0 ? null : n[0];
    };

    /**
     * Returns a element array by a specific attribute and it's value.
     *
     * @param {HTMLElement} n Element to search in.
     * @param {string} e Element name to search for.
     * @param {string} a Attribute name to search for.
     * @param {string} v Attribute value to search for.
     * @return HTML element array that matched the criterias or null on failure.
     * @type Array
     */
    TinyMCE_Engine.prototype.getElementsByAttributeValue = function(n, e, a, v) {
    	var i, nl = n.getElementsByTagName(e), o = new Array();

    	for (i=0; i<nl.length; i++) {
    		if (tinyMCE.getAttrib(nl[i], a).indexOf(v) != -1)
    			o[o.length] = nl[i];
    	}

    	return o;
    };

    /**
     * Returns true/false if the specified node is a block element or not.
     *
     * @param {HTMLNode} n Node to verify.
     * @return true/false if the specified node is a block element or not.
     * @type boolean
     */
    TinyMCE_Engine.prototype.isBlockElement = function(n) {
    	return n != null && n.nodeType == 1 && this.blockRegExp.test(n.nodeName);
    };

    /**
     * Returns the first block element parent of the specified node.
     *
     * @param {HTMLNode} n Node get parent block element for.
     * @return First block element parent of the specified node or null if it wasn't found.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype.getParentBlockElement = function(n) {
    	while (n) {
    		if (this.isBlockElement(n))
    			return n;

    		n = n.parentNode;
    	}

    	return null;
    };

    /**
     * Inserts a node after the specific node.
     *
     * @param {HTMLNode} n New node to insert.
     * @param {HTMLNode} r Reference node to insert after.
     */
    TinyMCE_Engine.prototype.insertAfter = function(n, r){
    	if (r.nextSibling)
    		r.parentNode.insertBefore(n, r.nextSibling);
    	else
    		r.parentNode.appendChild(n);
    };

    /**
     * Sets the innerHTML property of a element, this function also
     * fixes a MSIE bug where the first comment is removed.
     *
     * @param {HTMLElement} e Element to insert HTML in.
     * @param {string} h HTML code to insert into innerHTML.
     */
    TinyMCE_Engine.prototype.setInnerHTML = function(e, h) {
    	var i, nl, n;

    	if (tinyMCE.isMSIE && !tinyMCE.isOpera) {
    		// Since MSIE handles invalid HTML better that valid XHTML we
    		// need to make some things invalid. <hr /> gets converted to <hr>.
    		h = h.replace(/\s\/>/g, '>');

    		// Since MSIE auto generated emtpy P tags some times we must tell it to keep the real ones
    		h = h.replace(/<p([^>]*)>\u00A0?<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    		h = h.replace(/<p([^>]*)>\s*&nbsp;\s*<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs
    		h = h.replace(/<p([^>]*)>\s+<\/p>/gi, '<p$1 mce_keep="true">&nbsp;</p>'); // Keep empty paragraphs

    		// Remove first comment
    		e.innerHTML = tinyMCE.uniqueTag + h;
    		e.firstChild.removeNode(true);

    		// Remove weird auto generated empty paragraphs unless it's supposed to be there
    		nl = e.getElementsByTagName("p");
    		for (i=nl.length-1; i>=0; i--) {
    			n = nl[i];

    			if (n.nodeName == 'P' && !n.hasChildNodes() && !n.mce_keep)
    				n.parentNode.removeChild(n);
    		}
    	} else {
    		h = this.fixGeckoBaseHREFBug(1, e, h);
    		e.innerHTML = h;
    		this.fixGeckoBaseHREFBug(2, e, h);
    	}
    };

    /**
     * Returns the outer HTML of a element, this uses the outerHTML
     * property in MSIE and Opera and a workaround for Gecko.
     *
     * @param {HTMLElement} e HTML element to get outerHTML from.
     * @return HTML content string.
     * @type string
     */
    TinyMCE_Engine.prototype.getOuterHTML = function(e) {
    	if (tinyMCE.isMSIE)
    		return e.outerHTML;

    	var d = e.ownerDocument.createElement("body");
    	d.appendChild(e);
    	return d.innerHTML;
    };

    /**
     * Sets the outer HTML of a element, this uses the outerHTML
     * property in MSIE and Opera and a workaround for Gecko.
     *
     * @param {HTMLElement} e HTML element to set outerHTML on.
     * @param {string} h HTML string to set in property.
     */
    TinyMCE_Engine.prototype.setOuterHTML = function(e, h) {
    	if (tinyMCE.isMSIE) {
    		e.outerHTML = h;
    		return;
    	}

    	var d = e.ownerDocument.createElement("body");
    	d.innerHTML = h;
    	e.parentNode.replaceChild(d.firstChild, e);
    };

    /**
     * Returns a element by id, this will also search the form names to match the id.
     *
     * @param {string} id Id of element.
     * @param {DOMDocument} d Optional document.
     * @return HTML element that matches the id.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype._getElementById = function(id, d) {
    	var e, i, j, f;

    	if (typeof(d) == "undefined")
    		d = document;

    	e = d.getElementById(id);
    	if (!e) {
    		f = d.forms;

    		for (i=0; i<f.length; i++) {
    			for (j=0; j<f[i].elements.length; j++) {
    				if (f[i].elements[j].name == id) {
    					e = f[i].elements[j];
    					break;
    				}
    			}
    		}
    	}

    	return e;
    };

    /**
     * Returns a array of nodes selected retrived from the child nodes of the specified node.
     *
     * @param {HTMLNode} n Node to get children from.
     * @param {Array} na Array to fill with children.
     * @param {int} t Node type to get.
     * @param {string} nn Node name of items to retrive.
     * @return Node array.
     * @type Array
     */
    TinyMCE_Engine.prototype.getNodeTree = function(n, na, t, nn) {
    	var i;

    	if (typeof(t) == "undefined" || n.nodeType == t && (typeof(nn) == "undefined" || n.nodeName == nn))
    		na[na.length] = n;

    	if (n.hasChildNodes()) {
    		for (i=0; i<n.childNodes.length; i++)
    			tinyMCE.getNodeTree(n.childNodes[i], na, t, nn);
    	}

    	return na;
    };

    /**
     * Returns the parent element of the specified node based on the search criteria.
     *
     * @param {HTMLNode} node Node to get parent element of.
     * @param {string} names Comma separated list of element names to get.
     * @param {string} attrib_name Optional attribute name to match.
     * @param {string} attrib_value Optional attribute value to match.
     * @return HTMLElement or null based on search criteras.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype.getParentElement = function(node, names, attrib_name, attrib_value) {
    	if (typeof(names) == "undefined") {
    		if (node.nodeType == 1)
    			return node;

    		// Find parent node that is a element
    		while ((node = node.parentNode) != null && node.nodeType != 1) ;

    		return node;
    	}

    	if (node == null)
    		return null;

    	var namesAr = names.toUpperCase().split(',');

    	do {
    		for (var i=0; i<namesAr.length; i++) {
    			if (node.nodeName == namesAr[i] || names == "*") {
    				if (typeof(attrib_name) == "undefined")
    					return node;
    				else if (node.getAttribute(attrib_name)) {
    					if (typeof(attrib_value) == "undefined") {
    						if (node.getAttribute(attrib_name) != "")
    							return node;
    					} else if (node.getAttribute(attrib_name) == attrib_value)
    						return node;
    				}
    			}
    		}
    	} while ((node = node.parentNode) != null);

    	return null;
    };

    /**
     * Returns a node by the specified selector function. This function will
     * loop through all parent nodes and call the specified function for each node.
     * If the function then returns true it will stop the execution and return that node.
     *
     * @param {DOMNode} n HTML node to search parents on.
     * @param {function} f Selection function to execute on each node.
     * @return DOMNode or null if it wasn't found.
     * @type DOMNode
     */
    TinyMCE_Engine.prototype.getParentNode = function(n, f) {
    	while (n) {
    		if (f(n))
    			return n;

    		n = n.parentNode;
    	}

    	return null;
    };

    /**
     * Returns the attribute value of a element or the default value if it wasn't found.
     *
     * @param {HTMLElement} elm HTML element to get attribute from.
     * @param {string} name Attribute name to retrive.
     * @param {string} default_value Optional default value to return, this value defaults to a empty string.
     * @return Attribute value or default value if it wasn't found in element.
     * @type string
     */
    TinyMCE_Engine.prototype.getAttrib = function(elm, name, default_value) {
    	if (typeof(default_value) == "undefined")
    		default_value = "";

    	// Not a element
    	if (!elm || elm.nodeType != 1)
    		return default_value;

    	var v = elm.getAttribute(name);

    	// Try className for class attrib
    	if (name == "class" && !v)
    		v = elm.className;

    	// Workaround for a issue with Firefox 1.5rc2+
    	if (tinyMCE.isGecko && name == "src" && elm.src != null && elm.src != "")
    		v = elm.src;

    	// Workaround for a issue with Firefox 1.5rc2+
    	if (tinyMCE.isGecko && name == "href" && elm.href != null && elm.href != "")
    		v = elm.href;

    	if (name == "http-equiv" && tinyMCE.isMSIE)
    		v = elm.httpEquiv;

    	if (name == "style" && !tinyMCE.isOpera)
    		v = elm.style.cssText;

    	return (v && v != "") ? v : default_value;
    };

    /**
     * Sets the attribute value for a specific attribute.
     *
     * @param {HTMLElement} element HTML element to set attribute on.
     * @param {string} name Attribute name to set.
     * @param {string} value Attribute value to set.
     * @param {boolean} fix_value Optional fix value state, if true only number data will be accepted.
     */
    TinyMCE_Engine.prototype.setAttrib = function(element, name, value, fix_value) {
    	if (typeof(value) == "number" && value != null)
    		value = "" + value;

    	if (fix_value) {
    		if (value == null)
    			value = "";

    		var re = new RegExp('[^0-9%]', 'g');
    		value = value.replace(re, '');
    	}

    	if (name == "style")
    		element.style.cssText = value;

    	if (name == "class")
    		element.className = value;

    	if (value != null && value != "" && value != -1)
    		element.setAttribute(name, value);
    	else
    		element.removeAttribute(name);
    };

    /**
     * Sets a style attribute item value.
     *
     * @param {HTMLElement} elm HTML element to set style attribute item on.
     * @param {string} name Style item name to set.
     * @param {string} value Style item value to set.
     */
    TinyMCE_Engine.prototype.setStyleAttrib = function(elm, name, value) {
    	eval('elm.style.' + name + '=value;');

    	// Style attrib deleted
    	if (tinyMCE.isMSIE && value == null || value == '') {
    		var str = tinyMCE.serializeStyle(tinyMCE.parseStyle(elm.style.cssText));
    		elm.style.cssText = str;
    		elm.setAttribute("style", str);
    	}
    };

    /**
     * Switches the CSS class of the specified element. This method also caches the
     * elements in a lookup table for performance. This should only be used for TinyMCE main UI controls
     * like buttons or select elements.
     *
     * @param {HTMLElement} ei Element to set CSS class on.
     * @param {string} c CSS class to set.
     */
    TinyMCE_Engine.prototype.switchClass = function(ei, c) {
    	var e;

    	if (tinyMCE.switchClassCache[ei])
    		e = tinyMCE.switchClassCache[ei];
    	else
    		e = tinyMCE.switchClassCache[ei] = document.getElementById(ei);

    	if (e) {
    		// Keep tile mode
    		if (tinyMCE.settings.button_tile_map && e.className && e.className.indexOf('mceTiledButton') == 0)
    			c = 'mceTiledButton ' + c;

    		e.className = c;
    	}
    };

    /**
     * Returns the absolute x, y position of a node. The position will be returned in a object with
     * two properties absLeft and absTop.
     *
     * @param {HTMLNode} n HTML element to get x, y position from.
     * @return Absolute position of the specified element.
     * @type TinyMCE_ElementPosition
     */
    TinyMCE_Engine.prototype.getAbsPosition = function(n) {
    	var p = {absLeft : 0, absTop : 0};

    	while (n) {
    		p.absLeft += n.offsetLeft;
    		p.absTop += n.offsetTop;
    		n = n.offsetParent;
    	}

    	return p;
    };

    /**
     * Finds any previous element by name. This will loop through the siblings
     * inorder to find the specified element by name. If the element wasn't found
     * it will return a null value.
     *
     * @param {HTMLNode} e HTML node to search from.
     * @param {string} n Comma separated list of element names to search for.
     * @return HTML Element or null if it wasn't found.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype.prevNode = function(e, n) {
    	var a = n.split(','), i;

    	while ((e = e.previousSibling) != null) {
    		for (i=0; i<a.length; i++) {
    			if (e.nodeName == a[i])
    				return e;
    		}
    	}

    	return null;
    };

    /**
     * Finds any element after the current one by name. This will loop through the siblings
     * inorder to find the specified element by name. If the element wasn't found
     * it will return a null value.
     *
     * @param {HTMLNode} e HTML node to search from.
     * @param {string} n Comma separated list of element names to search for.
     * @return HTML Element or null if it wasn't found.
     * @type HTMLElement
     */
    TinyMCE_Engine.prototype.nextNode = function(e, n) {
    	var a = n.split(','), i;

    	while ((e = e.nextSibling) != null) {
    		for (i=0; i<a.length; i++) {
    			if (e.nodeName == a[i])
    				return e;
    		}
    	}

    	return null;
    };

    /**
     * Returns a array of nodes when the specified function matches a node.
     *
     * @param {DOMNode} n Node to select children from.
     * @param {function} f Function that returns true/false if the node is to be added or not.
     * @param {Array} a Optional array to fill with nodes.
     * @return Array with selected nodes.
     * @type Array
     */
    TinyMCE_Engine.prototype.selectNodes = function(n, f, a) {
    	var i;

    	if (!a)
    		a = new Array();

    	if (f(n))
    		a[a.length] = n;

    	if (n.hasChildNodes()) {
    		for (i=0; i<n.childNodes.length; i++)
    			tinyMCE.selectNodes(n.childNodes[i], f, a);
    	}

    	return a;
    };

    /**
     * Adds a CSS class to the specified element. It will remove any previous item with the same name
     * so adding a class that already exists will move it to the end.
     *
     * @param {HTMLElement} e HTML element to add CSS class to.
     * @param {string] c CSS class to add to HTML element.
     * @param {boolean] b Optional parameter, if set to true, class will be added to the beginning.
     * @return Returns the new class attribute value.
     * @type string
     */
    TinyMCE_Engine.prototype.addCSSClass = function(e, c, b) {
    	var o = this.removeCSSClass(e, c);

    	return e.className = b ? c + (o != '' ? (' ' + o) : '') : (o != '' ? (o + ' ') : '') + c;
    };

    /**
     * Removes the specified CSS class from the element.
     *
     * @param {HTMLElement} e HTML element to remove CSS class to.
     * @param {string] c CSS class to remove to HTML element.
     * @return Returns the new class attribute value.
     * @type string
     */
    TinyMCE_Engine.prototype.removeCSSClass = function(e, c) {
    	var a = this.explode(' ', e.className), i;

    	for (i=0; i<a.length; i++) {
    		if (a[i] == c)
    			a[i] = '';
    	}

    	return e.className = a.join(' ');
    };

    /**
     * Renames the specified element to the specified name.
     *
     * @param {HTMLElement} e Element to rename.
     * @param {string} n New name of the element.
     * @param {DOMDocument} d Optional document reference.
     */
    TinyMCE_Engine.prototype.renameElement = function(e, n, d) {
    	var ne, i, ar;

    	d = typeof(d) == "undefined" ? tinyMCE.selectedInstance.getDoc() : d;

    	if (e) {
    		ne = d.createElement(n);

    		ar = e.attributes;
    		for (i=ar.length-1; i>-1; i--) {
    			if (ar[i].specified && ar[i].nodeValue)
    				ne.setAttribute(ar[i].nodeName.toLowerCase(), ar[i].nodeValue);
    		}

    		ar = e.childNodes;
    		for (i=0; i<ar.length; i++)
    			ne.appendChild(ar[i].cloneNode(true));

    		e.parentNode.replaceChild(ne, e);
    	}
    };

Documentation generated by JSDoc on Fri Apr 14 21:59:23 2006