//@tag dom,core //@define Ext.Element-all //@define Ext.Element-static //@require Ext.Element /** * @class Ext.dom.Element */ Ext.dom.Element.addStatics({ numberRe: /\d+$/, unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i, camelRe: /(-[a-z])/gi, cssRe: /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi, opacityRe: /alpha\(opacity=(.*)\)/i, propertyCache: {}, defaultUnit: "px", borders: {l: 'border-left-width', r: 'border-right-width', t: 'border-top-width', b: 'border-bottom-width'}, paddings: {l: 'padding-left', r: 'padding-right', t: 'padding-top', b: 'padding-bottom'}, margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'}, /** * Test if size has a unit, otherwise appends the passed unit string, or the default for this Element. * @param {Object} size The size to set. * @param {String} units The units to append to a numeric size value. * @return {String} * @private * @static */ addUnits: function(size, units) { // Size set to a value which means "auto" if (size === "" || size == "auto" || size === undefined || size === null) { return size || ''; } // Otherwise, warn if it's not a valid CSS measurement if (Ext.isNumber(size) || this.numberRe.test(size)) { return size + (units || this.defaultUnit || 'px'); } else if (!this.unitRe.test(size)) { //<debug> Ext.Logger.warn("Warning, size detected (" + size + ") not a valid property value on Element.addUnits."); //</debug> return size || ''; } return size; }, /** * @static * @return {Boolean} * @private */ isAncestor: function(p, c) { var ret = false; p = Ext.getDom(p); c = Ext.getDom(c); if (p && c) { if (p.contains) { return p.contains(c); } else if (p.compareDocumentPosition) { return !!(p.compareDocumentPosition(c) & 16); } else { while ((c = c.parentNode)) { ret = c == p || ret; } } } return ret; }, /** * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result) * @static * @param {Number/String} box The encoded margins * @return {Object} An object with margin sizes for top, right, bottom and left containing the unit */ parseBox: function(box) { if (typeof box != 'string') { box = box.toString(); } var parts = box.split(' '), ln = parts.length; if (ln == 1) { parts[1] = parts[2] = parts[3] = parts[0]; } else if (ln == 2) { parts[2] = parts[0]; parts[3] = parts[1]; } else if (ln == 3) { parts[3] = parts[1]; } return { top: parts[0] || 0, right: parts[1] || 0, bottom: parts[2] || 0, left: parts[3] || 0 }; }, /** * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result) * @static * @param {Number/String} box The encoded margins * @param {String} units The type of units to add * @return {String} An string with unitized (px if units is not specified) metrics for top, right, bottom and left */ unitizeBox: function(box, units) { var me = this; box = me.parseBox(box); return me.addUnits(box.top, units) + ' ' + me.addUnits(box.right, units) + ' ' + me.addUnits(box.bottom, units) + ' ' + me.addUnits(box.left, units); }, // @private camelReplaceFn: function(m, a) { return a.charAt(1).toUpperCase(); }, /** * Normalizes CSS property keys from dash delimited to camel case JavaScript Syntax. * For example: * * - border-width -> borderWidth * - padding-top -> paddingTop * * @static * @param {String} prop The property to normalize * @return {String} The normalized string */ normalize: function(prop) { // TODO: Mobile optimization? // if (prop == 'float') { // prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat'; // } return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn)); }, /** * Returns the top Element that is located at the passed coordinates * @static * @param {Number} x The x coordinate * @param {Number} y The y coordinate * @return {String} The found Element */ fromPoint: function(x, y) { return Ext.get(document.elementFromPoint(x, y)); }, /** * Converts a CSS string into an object with a property for each style. * * The sample code below would return an object with 2 properties, one * for background-color and one for color. * * var css = 'background-color: red;color: blue; '; * console.log(Ext.dom.Element.parseStyles(css)); * * @static * @param {String} styles A CSS string * @return {Object} styles */ parseStyles: function(styles) { var out = {}, cssRe = this.cssRe, matches; if (styles) { // Since we're using the g flag on the regex, we need to set the lastIndex. // This automatically happens on some implementations, but not others, see: // http://stackoverflow.com/questions/2645273/javascript-regular-expression-literal-persists-between-function-calls // http://blog.stevenlevithan.com/archives/fixing-javascript-regexp cssRe.lastIndex = 0; while ((matches = cssRe.exec(styles))) { out[matches[1]] = matches[2]; } } return out; } }); //<deprecated product=touch since=2.0> Ext.dom.Element.addStatics({ /** * Serializes a DOM form into a url encoded string * @deprecated 2.0.0 Please see {@link Ext.form.Panel#getValues} instead * @param {Object} form The form * @return {String} The url encoded form */ serializeForm: function(form) { var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements, hasSubmit = false, encoder = encodeURIComponent, name, data = '', type, hasValue; Ext.each(fElements, function(element) { name = element.name; type = element.type; if (!element.disabled && name) { if (/select-(one|multiple)/i.test(type)) { Ext.each(element.options, function(opt) { if (opt.selected) { hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified; data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text)); } }); } else if (!(/file|undefined|reset|button/i.test(type))) { if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) { data += encoder(name) + '=' + encoder(element.value) + '&'; hasSubmit = /submit/i.test(type); } } } }); return data.substr(0, data.length - 1); }, /** * Retrieves the document height * @deprecated 2.0.0 Please use {@link Ext.Viewport#getWindowHeight} instead * @static * @return {Number} documentHeight */ getDocumentHeight: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getDocumentHeight() is no longer supported. " + "Please use Ext.Viewport#getWindowHeight() instead", this); //</debug> return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight()); }, /** * Retrieves the document width * @deprecated 2.0.0 Please use {@link Ext.Viewport#getWindowWidth} instead * @static * @return {Number} documentWidth */ getDocumentWidth: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getDocumentWidth() is no longer supported. " + "Please use Ext.Viewport#getWindowWidth() instead", this); //</debug> return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth()); }, /** * Retrieves the viewport height of the window. * @deprecated 2.0.0 Please use {@link Ext.Viewport#getWindowHeight} instead * @static * @return {Number} viewportHeight */ getViewportHeight: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getDocumentHeight() is no longer supported. " + "Please use Ext.Viewport#getWindowHeight() instead", this); //</debug> return window.innerHeight; }, /** * Retrieves the viewport width of the window. * @deprecated 2.0.0 Please use {@link Ext.Viewport#getWindowWidth} instead * @static * @return {Number} viewportWidth */ getViewportWidth: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getDocumentWidth() is no longer supported. " + "Please use Ext.Viewport#getWindowWidth() instead", this); //</debug> return window.innerWidth; }, /** * Retrieves the viewport size of the window. * @deprecated 2.0.0 Please use {@link Ext.Viewport#getSize} instead * @static * @return {Object} object containing width and height properties */ getViewSize: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getViewSize() is no longer supported. " + "Please use Ext.Viewport#getSize() instead", this); //</debug> return { width: window.innerWidth, height: window.innerHeight }; }, /** * Retrieves the current orientation of the window. This is calculated by * determining if the height is greater than the width. * @deprecated 2.0.0 Please use {@link Ext.Viewport#getOrientation} instead * @static * @return {String} Orientation of window: 'portrait' or 'landscape' */ getOrientation: function() { //<debug warn> Ext.Logger.deprecate("Ext.Element.getOrientation() is no longer supported. " + "Please use Ext.Viewport#getOrientation() instead", this); //</debug> if (Ext.supports.OrientationChange) { return (window.orientation == 0) ? 'portrait' : 'landscape'; } return (window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape'; } }); //</deprecated>