src/pyams_skin/resources/js/ext/tinymce/dev/classes/dom/DomQuery.js
changeset 69 a361355b55c7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_skin/resources/js/ext/tinymce/dev/classes/dom/DomQuery.js	Wed Jun 17 10:00:10 2015 +0200
@@ -0,0 +1,1568 @@
+/**
+ * DomQuery.js
+ *
+ * Copyright, Moxiecode Systems AB
+ * Released under LGPL License.
+ *
+ * License: http://www.tinymce.com/license
+ * Contributing: http://www.tinymce.com/contributing
+ */
+
+/**
+ * This class mimics most of the jQuery API:
+ *
+ * This is whats currently implemented:
+ * - Utility functions
+ * - DOM traversial
+ * - DOM manipulation
+ * - Event binding
+ *
+ * This is not currently implemented:
+ * - Dimension
+ * - Ajax
+ * - Animation
+ * - Advanced chaining
+ *
+ * @example
+ * var $ = tinymce.dom.DomQuery;
+ * $('p').attr('attr', 'value').addClass('class');
+ *
+ * @class tinymce.dom.DomQuery
+ */
+define("tinymce/dom/DomQuery", [
+	"tinymce/dom/EventUtils",
+	"tinymce/dom/Sizzle",
+	"tinymce/util/Tools",
+	"tinymce/Env"
+], function(EventUtils, Sizzle, Tools, Env) {
+	var doc = document, push = Array.prototype.push, slice = Array.prototype.slice;
+	var rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/;
+	var Event = EventUtils.Event, undef;
+
+	function isDefined(obj) {
+		return typeof obj !== 'undefined';
+	}
+
+	function isString(obj) {
+		return typeof obj === 'string';
+	}
+
+	function isWindow(obj) {
+		return obj && obj == obj.window;
+	}
+
+	function createFragment(html, fragDoc) {
+		var frag, node, container;
+
+		fragDoc = fragDoc || doc;
+		container = fragDoc.createElement('div');
+		frag = fragDoc.createDocumentFragment();
+		container.innerHTML = html;
+
+		while ((node = container.firstChild)) {
+			frag.appendChild(node);
+		}
+
+		return frag;
+	}
+
+	function domManipulate(targetNodes, sourceItem, callback, reverse) {
+		var i;
+
+		if (isString(sourceItem)) {
+			sourceItem = createFragment(sourceItem, getElementDocument(targetNodes[0]));
+		} else if (sourceItem.length && !sourceItem.nodeType) {
+			sourceItem = DomQuery.makeArray(sourceItem);
+
+			if (reverse) {
+				for (i = sourceItem.length - 1; i >= 0; i--) {
+					domManipulate(targetNodes, sourceItem[i], callback, reverse);
+				}
+			} else {
+				for (i = 0; i < sourceItem.length; i++) {
+					domManipulate(targetNodes, sourceItem[i], callback, reverse);
+				}
+			}
+
+			return targetNodes;
+		}
+
+		if (sourceItem.nodeType) {
+			i = targetNodes.length;
+			while (i--) {
+				callback.call(targetNodes[i], sourceItem);
+			}
+		}
+
+		return targetNodes;
+	}
+
+	function hasClass(node, className) {
+		return node && className && (' ' + node.className + ' ').indexOf(' ' + className + ' ') !== -1;
+	}
+
+	function wrap(elements, wrapper, all) {
+		var lastParent, newWrapper;
+
+		wrapper = DomQuery(wrapper)[0];
+
+		elements.each(function() {
+			var self = this;
+
+			if (!all || lastParent != self.parentNode) {
+				lastParent = self.parentNode;
+				newWrapper = wrapper.cloneNode(false);
+				self.parentNode.insertBefore(newWrapper, self);
+				newWrapper.appendChild(self);
+			} else {
+				newWrapper.appendChild(self);
+			}
+		});
+
+		return elements;
+	}
+
+	var numericCssMap = Tools.makeMap('fillOpacity fontWeight lineHeight opacity orphans widows zIndex zoom', ' ');
+	var booleanMap = Tools.makeMap('checked compact declare defer disabled ismap multiple nohref noshade nowrap readonly selected', ' ');
+	var propFix = {
+		'for': 'htmlFor',
+		'class': 'className',
+		'readonly': 'readOnly'
+	};
+	var cssFix = {
+		'float': 'cssFloat'
+	};
+
+	var attrHooks = {}, cssHooks = {};
+
+	function DomQuery(selector, context) {
+		/*eslint new-cap:0 */
+		return new DomQuery.fn.init(selector, context);
+	}
+
+	function inArray(item, array) {
+		var i;
+
+		if (array.indexOf) {
+			return array.indexOf(item);
+		}
+
+		i = array.length;
+		while (i--) {
+			if (array[i] === item) {
+				return i;
+			}
+		}
+
+		return -1;
+	}
+
+	var whiteSpaceRegExp = /^\s*|\s*$/g;
+
+	function trim(str) {
+		return (str === null || str === undef) ? '' : ("" + str).replace(whiteSpaceRegExp, '');
+	}
+
+	function each(obj, callback) {
+		var length, key, i, undef, value;
+
+		if (obj) {
+			length = obj.length;
+
+			if (length === undef) {
+				// Loop object items
+				for (key in obj) {
+					if (obj.hasOwnProperty(key)) {
+						value = obj[key];
+						if (callback.call(value, key, value) === false) {
+							break;
+						}
+					}
+				}
+			} else {
+				// Loop array items
+				for (i = 0; i < length; i++) {
+					value = obj[i];
+					if (callback.call(value, i, value) === false) {
+						break;
+					}
+				}
+			}
+		}
+
+		return obj;
+	}
+
+	function grep(array, callback) {
+		var out = [];
+
+		each(array, function(i, item) {
+			if (callback(item, i)) {
+				out.push(item);
+			}
+		});
+
+		return out;
+	}
+
+	function getElementDocument(element) {
+		if (!element) {
+			return doc;
+		}
+
+		if (element.nodeType == 9) {
+			return element;
+		}
+
+		return element.ownerDocument;
+	}
+
+	DomQuery.fn = DomQuery.prototype = {
+		constructor: DomQuery,
+
+		/**
+		 * Selector for the current set.
+		 *
+		 * @property selector
+		 * @type String
+		 */
+		selector: "",
+
+		/**
+		 * Context used to create the set.
+		 *
+		 * @property context
+		 * @type Element
+		 */
+		context: null,
+
+		/**
+		 * Number of items in the current set.
+		 *
+		 * @property length
+		 * @type Number
+		 */
+		length: 0,
+
+		/**
+		 * Constructs a new DomQuery instance with the specified selector or context.
+		 *
+		 * @constructor
+		 * @method init
+		 * @param {String/Array/DomQuery} selector Optional CSS selector/Array or array like object or HTML string.
+		 * @param {Document/Element} context Optional context to search in.
+		 */
+		init: function(selector, context) {
+			var self = this, match, node;
+
+			if (!selector) {
+				return self;
+			}
+
+			if (selector.nodeType) {
+				self.context = self[0] = selector;
+				self.length = 1;
+
+				return self;
+			}
+
+			if (context && context.nodeType) {
+				self.context = context;
+			} else {
+				if (context) {
+					return DomQuery(selector).attr(context);
+				} else {
+					self.context = context = document;
+				}
+			}
+
+			if (isString(selector)) {
+				self.selector = selector;
+
+				if (selector.charAt(0) === "<" && selector.charAt(selector.length - 1) === ">" && selector.length >= 3) {
+					match = [null, selector, null];
+				} else {
+					match = rquickExpr.exec(selector);
+				}
+
+				if (match) {
+					if (match[1]) {
+						node = createFragment(selector, getElementDocument(context)).firstChild;
+
+						while (node) {
+							push.call(self, node);
+							node = node.nextSibling;
+						}
+					} else {
+						node = getElementDocument(context).getElementById(match[2]);
+
+						if (!node) {
+							return self;
+						}
+
+						if (node.id !== match[2]) {
+							return self.find(selector);
+						}
+
+						self.length = 1;
+						self[0] = node;
+					}
+				} else {
+					return DomQuery(context).find(selector);
+				}
+			} else {
+				this.add(selector, false);
+			}
+
+			return self;
+		},
+
+		/**
+		 * Converts the current set to an array.
+		 *
+		 * @method toArray
+		 * @param {Array} Array of all nodes in set.
+		 */
+		toArray: function() {
+			return Tools.toArray(this);
+		},
+
+		/**
+		 * Adds new nodes to the set.
+		 *
+		 * @method add
+		 * @param {Array/tinymce.dom.DomQuery} items Array of all nodes to add to set.
+		 * @return {tinymce.dom.DomQuery} New instance with nodes added.
+		 */
+		add: function(items, sort) {
+			var self = this, nodes, i;
+
+			if (isString(items)) {
+				return self.add(DomQuery(items));
+			}
+
+			if (sort !== false) {
+				nodes = DomQuery.unique(self.toArray().concat(DomQuery.makeArray(items)));
+				self.length = nodes.length;
+				for (i = 0; i < nodes.length; i++) {
+					self[i] = nodes[i];
+				}
+			} else {
+				push.apply(self, DomQuery.makeArray(items));
+			}
+
+			return self;
+		},
+
+		/**
+		 * Sets/gets attributes on the elements in the current set.
+		 *
+		 * @method attr
+		 * @param {String/Object} name Name of attribute to get or an object with attributes to set.
+		 * @param {String} value Optional value to set.
+		 * @return {tinymce.dom.DomQuery/String} Current set or the specified attribute when only the name is specified.
+		 */
+		attr: function(name, value) {
+			var self = this, hook;
+
+			if (typeof name === "object") {
+				each(name, function(name, value) {
+					self.attr(name, value);
+				});
+			} else if (isDefined(value)) {
+				this.each(function() {
+					var hook;
+
+					if (this.nodeType === 1) {
+						hook = attrHooks[name];
+						if (hook && hook.set) {
+							hook.set(this, value);
+							return;
+						}
+
+						if (value === null) {
+							this.removeAttribute(name, 2);
+						} else {
+							this.setAttribute(name, value, 2);
+						}
+					}
+				});
+			} else {
+				if (self[0] && self[0].nodeType === 1) {
+					hook = attrHooks[name];
+					if (hook && hook.get) {
+						return hook.get(self[0], name);
+					}
+
+					if (booleanMap[name]) {
+						return self.prop(name) ? name : undef;
+					}
+
+					value = self[0].getAttribute(name, 2);
+
+					if (value === null) {
+						value = undef;
+					}
+				}
+
+				return value;
+			}
+
+			return self;
+		},
+
+		/**
+		 * Removes attributse on the elements in the current set.
+		 *
+		 * @method removeAttr
+		 * @param {String/Object} name Name of attribute to remove.
+		 * @return {tinymce.dom.DomQuery/String} Current set.
+		 */
+		removeAttr: function(name) {
+			return this.attr(name, null);
+		},
+
+		/**
+		 * Sets/gets properties on the elements in the current set.
+		 *
+		 * @method attr
+		 * @param {String/Object} name Name of property to get or an object with properties to set.
+		 * @param {String} value Optional value to set.
+		 * @return {tinymce.dom.DomQuery/String} Current set or the specified property when only the name is specified.
+		 */
+		prop: function(name, value) {
+			var self = this;
+
+			name = propFix[name] || name;
+
+			if (typeof name === "object") {
+				each(name, function(name, value) {
+					self.prop(name, value);
+				});
+			} else if (isDefined(value)) {
+				this.each(function() {
+					if (this.nodeType == 1) {
+						this[name] = value;
+					}
+				});
+			} else {
+				if (self[0] && self[0].nodeType && name in self[0]) {
+					return self[0][name];
+				}
+
+				return value;
+			}
+
+			return self;
+		},
+
+		/**
+		 * Sets/gets styles on the elements in the current set.
+		 *
+		 * @method css
+		 * @param {String/Object} name Name of style to get or an object with styles to set.
+		 * @param {String} value Optional value to set.
+		 * @return {tinymce.dom.DomQuery/String} Current set or the specified style when only the name is specified.
+		 */
+		css: function(name, value) {
+			var self = this, elm, hook;
+
+			function camel(name) {
+				return name.replace(/-(\D)/g, function(a, b) {
+					return b.toUpperCase();
+				});
+			}
+
+			function dashed(name) {
+				return name.replace(/[A-Z]/g, function(a) {
+					return '-' + a;
+				});
+			}
+
+			if (typeof name === "object") {
+				each(name, function(name, value) {
+					self.css(name, value);
+				});
+			} else {
+				if (isDefined(value)) {
+					name = camel(name);
+
+					// Default px suffix on these
+					if (typeof value === 'number' && !numericCssMap[name]) {
+						value += 'px';
+					}
+
+					self.each(function() {
+						var style = this.style;
+
+						hook = cssHooks[name];
+						if (hook && hook.set) {
+							hook.set(this, value);
+							return;
+						}
+
+						try {
+							this.style[cssFix[name] || name] = value;
+						} catch (ex) {
+							// Ignore
+						}
+
+						if (value === null || value === '') {
+							if (style.removeProperty) {
+								style.removeProperty(dashed(name));
+							} else {
+								style.removeAttribute(name);
+							}
+						}
+					});
+				} else {
+					elm = self[0];
+
+					hook = cssHooks[name];
+					if (hook && hook.get) {
+						return hook.get(elm);
+					}
+
+					if (elm.ownerDocument.defaultView) {
+						try {
+							return elm.ownerDocument.defaultView.getComputedStyle(elm, null).getPropertyValue(dashed(name));
+						} catch (ex) {
+							return undef;
+						}
+					} else if (elm.currentStyle) {
+						return elm.currentStyle[camel(name)];
+					}
+				}
+			}
+
+			return self;
+		},
+
+		/**
+		 * Removes all nodes in set from the document.
+		 *
+		 * @method remove
+		 * @return {tinymce.dom.DomQuery} Current set with the removed nodes.
+		 */
+		remove: function() {
+			var self = this, node, i = this.length;
+
+			while (i--) {
+				node = self[i];
+				Event.clean(node);
+
+				if (node.parentNode) {
+					node.parentNode.removeChild(node);
+				}
+			}
+
+			return this;
+		},
+
+		/**
+		 * Empties all elements in set.
+		 *
+		 * @method empty
+		 * @return {tinymce.dom.DomQuery} Current set with the empty nodes.
+		 */
+		empty: function() {
+			var self = this, node, i = this.length;
+
+			while (i--) {
+				node = self[i];
+				while (node.firstChild) {
+					node.removeChild(node.firstChild);
+				}
+			}
+
+			return this;
+		},
+
+		/**
+		 * Sets or gets the HTML of the current set or first set node.
+		 *
+		 * @method html
+		 * @param {String} value Optional innerHTML value to set on each element.
+		 * @return {tinymce.dom.DomQuery/String} Current set or the innerHTML of the first element.
+		 */
+		html: function(value) {
+			var self = this, i;
+
+			if (isDefined(value)) {
+				i = self.length;
+
+				try {
+					while (i--) {
+						self[i].innerHTML = value;
+					}
+				} catch (ex) {
+					// Workaround for "Unknown runtime error" when DIV is added to P on IE
+					DomQuery(self[i]).empty().append(value);
+				}
+
+				return self;
+			}
+
+			return self[0] ? self[0].innerHTML : '';
+		},
+
+		/**
+		 * Sets or gets the text of the current set or first set node.
+		 *
+		 * @method text
+		 * @param {String} value Optional innerText value to set on each element.
+		 * @return {tinymce.dom.DomQuery/String} Current set or the innerText of the first element.
+		 */
+		text: function(value) {
+			var self = this, i;
+
+			if (isDefined(value)) {
+				i = self.length;
+				while (i--) {
+					if ("innerText" in self[i]) {
+						self[i].innerText = value;
+					} else {
+						self[0].textContent = value;
+					}
+				}
+
+				return self;
+			}
+
+			return self[0] ? (self[0].innerText || self[0].textContent) : '';
+		},
+
+		/**
+		 * Appends the specified node/html or node set to the current set nodes.
+		 *
+		 * @method append
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to append to each element in set.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		append: function() {
+			return domManipulate(this, arguments, function(node) {
+				if (this.nodeType === 1) {
+					this.appendChild(node);
+				}
+			});
+		},
+
+		/**
+		 * Prepends the specified node/html or node set to the current set nodes.
+		 *
+		 * @method prepend
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to prepend to each element in set.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		prepend: function() {
+			return domManipulate(this, arguments, function(node) {
+				if (this.nodeType === 1) {
+					this.insertBefore(node, this.firstChild);
+				}
+			}, true);
+		},
+
+		/**
+		 * Adds the specified elements before current set nodes.
+		 *
+		 * @method before
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to add before to each element in set.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		before: function() {
+			var self = this;
+
+			if (self[0] && self[0].parentNode) {
+				return domManipulate(self, arguments, function(node) {
+					this.parentNode.insertBefore(node, this);
+				});
+			}
+
+			return self;
+		},
+
+		/**
+		 * Adds the specified elements after current set nodes.
+		 *
+		 * @method after
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to add after to each element in set.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		after: function() {
+			var self = this;
+
+			if (self[0] && self[0].parentNode) {
+				return domManipulate(self, arguments, function(node) {
+					this.parentNode.insertBefore(node, this.nextSibling);
+				}, true);
+			}
+
+			return self;
+		},
+
+		/**
+		 * Appends the specified set nodes to the specified selector/instance.
+		 *
+		 * @method appendTo
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} val Item to append the current set to.
+		 * @return {tinymce.dom.DomQuery} Current set with the appended nodes.
+		 */
+		appendTo: function(val) {
+			DomQuery(val).append(this);
+
+			return this;
+		},
+
+		/**
+		 * Prepends the specified set nodes to the specified selector/instance.
+		 *
+		 * @method prependTo
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} val Item to prepend the current set to.
+		 * @return {tinymce.dom.DomQuery} Current set with the prepended nodes.
+		 */
+		prependTo: function(val) {
+			DomQuery(val).prepend(this);
+
+			return this;
+		},
+
+		/**
+		 * Replaces the nodes in set with the specified content.
+		 *
+		 * @method replaceWith
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to replace nodes with.
+		 * @return {tinymce.dom.DomQuery} Set with replaced nodes.
+		 */
+		replaceWith: function(content) {
+			return this.before(content).remove();
+		},
+
+		/**
+		 * Wraps all elements in set with the specified wrapper.
+		 *
+		 * @method wrap
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with.
+		 * @return {tinymce.dom.DomQuery} Set with wrapped nodes.
+		 */
+		wrap: function(wrapper) {
+			return wrap(this, wrapper);
+		},
+
+		/**
+		 * Wraps all nodes in set with the specified wrapper. If the nodes are siblings all of them
+		 * will be wrapped in the same wrapper.
+		 *
+		 * @method wrapAll
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with.
+		 * @return {tinymce.dom.DomQuery} Set with wrapped nodes.
+		 */
+		wrapAll: function(wrapper) {
+			return wrap(this, wrapper, true);
+		},
+
+		/**
+		 * Wraps all elements inner contents in set with the specified wrapper.
+		 *
+		 * @method wrapInner
+		 * @param {String/Element/Array/tinymce.dom.DomQuery} content Content to wrap nodes with.
+		 * @return {tinymce.dom.DomQuery} Set with wrapped nodes.
+		 */
+		wrapInner: function(wrapper) {
+			this.each(function() {
+				DomQuery(this).contents().wrapAll(wrapper);
+			});
+
+			return this;
+		},
+
+		/**
+		 * Unwraps all elements by removing the parent element of each item in set.
+		 *
+		 * @method unwrap
+		 * @return {tinymce.dom.DomQuery} Set with unwrapped nodes.
+		 */
+		unwrap: function() {
+			return this.parent().each(function() {
+				DomQuery(this).replaceWith(this.childNodes);
+			});
+		},
+
+		/**
+		 * Clones all nodes in set.
+		 *
+		 * @method clone
+		 * @return {tinymce.dom.DomQuery} Set with cloned nodes.
+		 */
+		clone: function() {
+			var result = [];
+
+			this.each(function() {
+				result.push(this.cloneNode(true));
+			});
+
+			return DomQuery(result);
+		},
+
+		/**
+		 * Adds the specified class name to the current set elements.
+		 *
+		 * @method addClass
+		 * @param {String} className Class name to add.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		addClass: function(className) {
+			return this.toggleClass(className, true);
+		},
+
+		/**
+		 * Removes the specified class name to the current set elements.
+		 *
+		 * @method removeClass
+		 * @param {String} className Class name to remove.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		removeClass: function(className) {
+			return this.toggleClass(className, false);
+		},
+
+		/**
+		 * Toggles the specified class name on the current set elements.
+		 *
+		 * @method toggleClass
+		 * @param {String} className Class name to add/remove.
+		 * @param {Boolean} state Optional state to toggle on/off.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		toggleClass: function(className, state) {
+			var self = this;
+
+			// Functions are not supported
+			if (typeof className != 'string') {
+				return self;
+			}
+
+			if (className.indexOf(' ') !== -1) {
+				each(className.split(' '), function() {
+					self.toggleClass(this, state);
+				});
+			} else {
+				self.each(function(index, node) {
+					var existingClassName, classState;
+
+					classState = hasClass(node, className);
+					if (classState !== state) {
+						existingClassName = node.className;
+
+						if (classState) {
+							node.className = trim((" " + existingClassName + " ").replace(' ' + className + ' ', ' '));
+						} else {
+							node.className += existingClassName ? ' ' + className : className;
+						}
+					}
+				});
+			}
+
+			return self;
+		},
+
+		/**
+		 * Returns true/false if the first item in set has the specified class.
+		 *
+		 * @method hasClass
+		 * @param {String} className Class name to check for.
+		 * @return {Boolean} True/false if the set has the specified class.
+		 */
+		hasClass: function(className) {
+			return hasClass(this[0], className);
+		},
+
+		/**
+		 * Executes the callback function for each item DomQuery collection. If you return false in the
+		 * callback it will break the loop.
+		 *
+		 * @method each
+		 * @param {function} callback Callback function to execute for each item.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		each: function(callback) {
+			return each(this, callback);
+		},
+
+		/**
+		 * Binds an event with callback function to the elements in set.
+		 *
+		 * @method on
+		 * @param {String} name Name of the event to bind.
+		 * @param {function} callback Callback function to execute when the event occurs.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		on: function(name, callback) {
+			return this.each(function() {
+				Event.bind(this, name, callback);
+			});
+		},
+
+		/**
+		 * Unbinds an event with callback function to the elements in set.
+		 *
+		 * @method off
+		 * @param {String} name Optional name of the event to bind.
+		 * @param {function} callback Optional callback function to execute when the event occurs.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		off: function(name, callback) {
+			return this.each(function() {
+				Event.unbind(this, name, callback);
+			});
+		},
+
+		/**
+		 * Triggers the specified event by name or event object.
+		 *
+		 * @method trigger
+		 * @param {String/Object} name Name of the event to trigger or event object.
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		trigger: function(name) {
+			return this.each(function() {
+				if (typeof name == 'object') {
+					Event.fire(this, name.type, name);
+				} else {
+					Event.fire(this, name);
+				}
+			});
+		},
+
+		/**
+		 * Shows all elements in set.
+		 *
+		 * @method show
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		show: function() {
+			return this.css('display', '');
+		},
+
+		/**
+		 * Hides all elements in set.
+		 *
+		 * @method hide
+		 * @return {tinymce.dom.DomQuery} Current set.
+		 */
+		hide: function() {
+			return this.css('display', 'none');
+		},
+
+		/**
+		 * Slices the current set.
+		 *
+		 * @method slice
+		 * @param {Number} start Start index to slice at.
+		 * @param {Number} end Optional ened index to end slice at.
+		 * @return {tinymce.dom.DomQuery} Sliced set.
+		 */
+		slice: function() {
+			return new DomQuery(slice.apply(this, arguments));
+		},
+
+		/**
+		 * Makes the set equal to the specified index.
+		 *
+		 * @method eq
+		 * @param {Number} index Index to set it equal to.
+		 * @return {tinymce.dom.DomQuery} Single item set.
+		 */
+		eq: function(index) {
+			return index === -1 ? this.slice(index) : this.slice(index, +index + 1);
+		},
+
+		/**
+		 * Makes the set equal to first element in set.
+		 *
+		 * @method first
+		 * @return {tinymce.dom.DomQuery} Single item set.
+		 */
+		first: function() {
+			return this.eq(0);
+		},
+
+		/**
+		 * Makes the set equal to last element in set.
+		 *
+		 * @method last
+		 * @return {tinymce.dom.DomQuery} Single item set.
+		 */
+		last: function() {
+			return this.eq(-1);
+		},
+
+		/**
+		 * Finds elements by the specified selector for each element in set.
+		 *
+		 * @method find
+		 * @param {String} selector Selector to find elements by.
+		 * @return {tinymce.dom.DomQuery} Set with matches elements.
+		 */
+		find: function(selector) {
+			var i, l, ret = [];
+
+			for (i = 0, l = this.length; i < l; i++) {
+				DomQuery.find(selector, this[i], ret);
+			}
+
+			return DomQuery(ret);
+		},
+
+		/**
+		 * Filters the current set with the specified selector.
+		 *
+		 * @method filter
+		 * @param {String/function} selector Selector to filter elements by.
+		 * @return {tinymce.dom.DomQuery} Set with filtered elements.
+		 */
+		filter: function(selector) {
+			if (typeof selector == 'function') {
+				return DomQuery(grep(this.toArray(), function(item, i) {
+					return selector(i, item);
+				}));
+			}
+
+			return DomQuery(DomQuery.filter(selector, this.toArray()));
+		},
+
+		/**
+		 * Gets the current node or any partent matching the specified selector.
+		 *
+		 * @method closest
+		 * @param {String/Element/tinymce.dom.DomQuery} selector Selector or element to find.
+		 * @return {tinymce.dom.DomQuery} Set with closest elements.
+		 */
+		closest: function(selector) {
+			var result = [];
+
+			if (selector instanceof DomQuery) {
+				selector = selector[0];
+			}
+
+			this.each(function(i, node) {
+				while (node) {
+					if (typeof selector == 'string' && DomQuery(node).is(selector)) {
+						result.push(node);
+						break;
+					} else if (node == selector) {
+						result.push(node);
+						break;
+					}
+
+					node = node.parentNode;
+				}
+			});
+
+			return DomQuery(result);
+		},
+
+		/**
+		 * Returns the offset of the first element in set or sets the top/left css properties of all elements in set.
+		 *
+		 * @method offset
+		 * @param {Object} offset Optional offset object to set on each item.
+		 * @return {Object/tinymce.dom.DomQuery} Returns the first element offset or the current set if you specified an offset.
+		 */
+		offset: function(offset) {
+			var elm, doc, docElm;
+			var x = 0, y = 0, pos;
+
+			if (!offset) {
+				elm = this[0];
+
+				if (elm) {
+					doc = elm.ownerDocument;
+					docElm = doc.documentElement;
+
+					if (elm.getBoundingClientRect) {
+						pos = elm.getBoundingClientRect();
+						x = pos.left + (docElm.scrollLeft || doc.body.scrollLeft) - docElm.clientLeft;
+						y = pos.top + (docElm.scrollTop || doc.body.scrollTop) - docElm.clientTop;
+					}
+				}
+
+				return {
+					left: x,
+					top: y
+				};
+			}
+
+			return this.css(offset);
+		},
+
+		push: push,
+		sort: [].sort,
+		splice: [].splice
+	};
+
+	// Static members
+	Tools.extend(DomQuery, {
+		/**
+		 * Extends the specified object with one or more objects.
+		 *
+		 * @static
+		 * @method extend
+		 * @param {Object} target Target object to extend with new items.
+		 * @param {Object..} object Object to extend the target with.
+		 * @return {Object} Extended input object.
+		 */
+		extend: Tools.extend,
+
+		/**
+		 * Creates an array out of an array like object.
+		 *
+		 * @static
+		 * @method makeArray
+		 * @param {Object} object Object to convert to array.
+		 * @return {Arrau} Array produced from object.
+		 */
+		makeArray: function(array) {
+			if (isWindow(array) || array.nodeType) {
+				return [array];
+			}
+
+			return Tools.toArray(array);
+		},
+
+		/**
+		 * Returns the index of the specified item inside the array.
+		 *
+		 * @static
+		 * @method inArray
+		 * @param {Object} item Item to look for.
+		 * @param {Array} array Array to look for item in.
+		 * @return {Number} Index of the item or -1.
+		 */
+		inArray: inArray,
+
+		/**
+		 * Returns true/false if the specified object is an array or not.
+		 *
+		 * @static
+		 * @method isArray
+		 * @param {Object} array Object to check if it's an array or not.
+		 * @return {Boolean} True/false if the object is an array.
+		 */
+		isArray: Tools.isArray,
+
+		/**
+		 * Executes the callback function for each item in array/object. If you return false in the
+		 * callback it will break the loop.
+		 *
+		 * @static
+		 * @method each
+		 * @param {Object} obj Object to iterate.
+		 * @param {function} callback Callback function to execute for each item.
+		 */
+		each: each,
+
+		/**
+		 * Removes whitespace from the beginning and end of a string.
+		 *
+		 * @static
+		 * @method trim
+		 * @param {String} str String to remove whitespace from.
+		 * @return {String} New string with removed whitespace.
+		 */
+		trim: trim,
+
+		/**
+		 * Filters out items from the input array by calling the specified function for each item.
+		 * If the function returns false the item will be excluded if it returns true it will be included.
+		 *
+		 * @static
+		 * @method grep
+		 * @param {Array} array Array of items to loop though.
+		 * @param {function} callback Function to call for each item. Include/exclude depends on it's return value.
+		 * @return {Array} New array with values imported and filtered based in input.
+		 * @example
+		 * // Filter out some items, this will return an array with 4 and 5
+		 * var items = DomQuery.grep([1, 2, 3, 4, 5], function(v) {return v > 3;});
+		 */
+		grep: grep,
+
+		// Sizzle
+		find: Sizzle,
+		expr: Sizzle.selectors,
+		unique: Sizzle.uniqueSort,
+		text: Sizzle.getText,
+		contains: Sizzle.contains,
+		filter: function(expr, elems, not) {
+			var i = elems.length;
+
+			if (not) {
+				expr = ":not(" + expr + ")";
+			}
+
+			while (i--) {
+				if (elems[i].nodeType != 1) {
+					elems.splice(i, 1);
+				}
+			}
+
+			if (elems.length === 1) {
+				elems = DomQuery.find.matchesSelector(elems[0], expr) ? [elems[0]] : [];
+			} else {
+				elems = DomQuery.find.matches(expr, elems);
+			}
+
+			return elems;
+		}
+	});
+
+	function dir(el, prop, until) {
+		var matched = [], cur = el[prop];
+
+		if (typeof until != 'string' && until instanceof DomQuery) {
+			until = until[0];
+		}
+
+		while (cur && cur.nodeType !== 9) {
+			if (until !== undefined) {
+				if (cur === until) {
+					break;
+				}
+
+				if (typeof until == 'string' && DomQuery(cur).is(until)) {
+					break;
+				}
+			}
+
+			if (cur.nodeType === 1) {
+				matched.push(cur);
+			}
+
+			cur = cur[prop];
+		}
+
+		return matched;
+	}
+
+	function sibling(node, siblingName, nodeType, until) {
+		var result = [];
+
+		if (until instanceof DomQuery) {
+			until = until[0];
+		}
+
+		for (; node; node = node[siblingName]) {
+			if (nodeType && node.nodeType !== nodeType) {
+				continue;
+			}
+
+			if (until !== undefined) {
+				if (node === until) {
+					break;
+				}
+
+				if (typeof until == 'string' && DomQuery(node).is(until)) {
+					break;
+				}
+			}
+
+			result.push(node);
+		}
+
+		return result;
+	}
+
+	function firstSibling(node, siblingName, nodeType) {
+		for (node = node[siblingName]; node; node = node[siblingName]) {
+			if (node.nodeType == nodeType) {
+				return node;
+			}
+		}
+
+		return null;
+	}
+
+	each({
+		/**
+		 * Returns a new collection with the parent of each item in current collection matching the optional selector.
+		 *
+		 * @method parent
+		 * @param {String} selector Selector to match parents agains.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents.
+		 */
+		parent: function(node) {
+			var parent = node.parentNode;
+
+			return parent && parent.nodeType !== 11 ? parent : null;
+		},
+
+		/**
+		 * Returns a new collection with the all the parents of each item in current collection matching the optional selector.
+		 *
+		 * @method parents
+		 * @param {String} selector Selector to match parents agains.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents.
+		 */
+		parents: function(node) {
+			return dir(node, "parentNode");
+		},
+
+		/**
+		 * Returns a new collection with next sibling of each item in current collection matching the optional selector.
+		 *
+		 * @method next
+		 * @param {String} selector Selector to match the next element against.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		next: function(node) {
+			return firstSibling(node, 'nextSibling', 1);
+		},
+
+		/**
+		 * Returns a new collection with previous sibling of each item in current collection matching the optional selector.
+		 *
+		 * @method prev
+		 * @param {String} selector Selector to match the previous element against.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		prev: function(node) {
+			return firstSibling(node, 'previousSibling', 1);
+		},
+
+		/**
+		 * Returns all child elements matching the optional selector.
+		 *
+		 * @method children
+		 * @param {String} selector Selector to match the elements against.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		children: function(node) {
+			return sibling(node.firstChild, 'nextSibling', 1);
+		},
+
+		/**
+		 * Returns all child nodes matching the optional selector.
+		 *
+		 * @method contents
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		contents: function(node) {
+			return Tools.toArray((node.nodeName === "iframe" ? node.contentDocument || node.contentWindow.document : node).childNodes);
+		}
+	}, function(name, fn) {
+		DomQuery.fn[name] = function(selector) {
+			var self = this, result = [];
+
+			self.each(function() {
+				var nodes = fn.call(result, this, selector, result);
+
+				if (nodes) {
+					if (DomQuery.isArray(nodes)) {
+						result.push.apply(result, nodes);
+					} else {
+						result.push(nodes);
+					}
+				}
+			});
+
+			// If traversing on multiple elements we might get the same elements twice
+			if (this.length > 1) {
+				result = DomQuery.unique(result);
+
+				if (name.indexOf('parents') === 0) {
+					result = result.reverse();
+				}
+			}
+
+			result = DomQuery(result);
+
+			if (selector) {
+				return result.filter(selector);
+			}
+
+			return result;
+		};
+	});
+
+	each({
+		/**
+		 * Returns a new collection with the all the parents until the matching selector/element
+		 * of each item in current collection matching the optional selector.
+		 *
+		 * @method parentsUntil
+		 * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching parents.
+		 */
+		parentsUntil: function(node, until) {
+			return dir(node, "parentNode", until);
+		},
+
+		/**
+		 * Returns a new collection with all next siblings of each item in current collection matching the optional selector.
+		 *
+		 * @method nextUntil
+		 * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		nextUntil: function(node, until) {
+			return sibling(node, 'nextSibling', 1, until).slice(1);
+		},
+
+		/**
+		 * Returns a new collection with all previous siblings of each item in current collection matching the optional selector.
+		 *
+		 * @method prevUntil
+		 * @param {String/Element/tinymce.dom.DomQuery} until Until the matching selector or element.
+		 * @return {tinymce.dom.DomQuery} New DomQuery instance with all matching elements.
+		 */
+		prevUntil: function(node, until) {
+			return sibling(node, 'previousSibling', 1, until).slice(1);
+		}
+	}, function(name, fn) {
+		DomQuery.fn[name] = function(selector, filter) {
+			var self = this, result = [];
+
+			self.each(function() {
+				var nodes = fn.call(result, this, selector, result);
+
+				if (nodes) {
+					if (DomQuery.isArray(nodes)) {
+						result.push.apply(result, nodes);
+					} else {
+						result.push(nodes);
+					}
+				}
+			});
+
+			// If traversing on multiple elements we might get the same elements twice
+			if (this.length > 1) {
+				result = DomQuery.unique(result);
+
+				if (name.indexOf('parents') === 0 || name === 'prevUntil') {
+					result = result.reverse();
+				}
+			}
+
+			result = DomQuery(result);
+
+			if (filter) {
+				return result.filter(filter);
+			}
+
+			return result;
+		};
+	});
+
+	/**
+	 * Returns true/false if the current set items matches the selector.
+	 *
+	 * @method is
+	 * @param {String} selector Selector to match the elements against.
+	 * @return {Boolean} True/false if the current set matches the selector.
+	 */
+	DomQuery.fn.is = function(selector) {
+		return !!selector && this.filter(selector).length > 0;
+	};
+
+	DomQuery.fn.init.prototype = DomQuery.fn;
+
+	DomQuery.overrideDefaults = function(callback) {
+		var defaults;
+
+		function sub(selector, context) {
+			defaults = defaults || callback();
+
+			if (arguments.length === 0) {
+				selector = defaults.element;
+			}
+
+			if (!context) {
+				context = defaults.context;
+			}
+
+			return new sub.fn.init(selector, context);
+		}
+
+		DomQuery.extend(sub, this);
+
+		return sub;
+	};
+
+	function appendHooks(targetHooks, prop, hooks) {
+		each(hooks, function(name, func) {
+			targetHooks[name] = targetHooks[name] || {};
+			targetHooks[name][prop] = func;
+		});
+	}
+
+	if (Env.ie && Env.ie < 8) {
+		appendHooks(attrHooks, 'get', {
+			maxlength: function(elm) {
+				var value = elm.maxLength;
+
+				if (value === 0x7fffffff) {
+					return undef;
+				}
+
+				return value;
+			},
+
+			size: function(elm) {
+				var value = elm.size;
+
+				if (value === 20) {
+					return undef;
+				}
+
+				return value;
+			},
+
+			'class': function(elm) {
+				return elm.className;
+			},
+
+			style: function(elm) {
+				var value = elm.style.cssText;
+
+				if (value.length === 0) {
+					return undef;
+				}
+
+				return value;
+			}
+		});
+
+		appendHooks(attrHooks, 'set', {
+			'class': function(elm, value) {
+				elm.className = value;
+			},
+
+			style: function(elm, value) {
+				elm.style.cssText = value;
+			}
+		});
+	}
+
+	if (Env.ie && Env.ie < 9) {
+		/*jshint sub:true */
+		/*eslint dot-notation: 0*/
+		cssFix['float'] = 'styleFloat';
+
+		appendHooks(cssHooks, 'set', {
+			opacity: function(elm, value) {
+				var style = elm.style;
+
+				if (value === null || value === '') {
+					style.removeAttribute('filter');
+				} else {
+					style.zoom = 1;
+					style.filter = 'alpha(opacity=' + (value * 100) + ')';
+				}
+			}
+		});
+	}
+
+	DomQuery.attrHooks = attrHooks;
+	DomQuery.cssHooks = cssHooks;
+
+	return DomQuery;
+});