Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / core / src / dom / Element.static.js
1 /**
2  * @class Ext.core.Element
3  */
4 Ext.applyIf(Ext.core.Element, {
5     unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
6     camelRe: /(-[a-z])/gi,
7     opacityRe: /alpha\(opacity=(.*)\)/i,
8     cssRe: /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
9     propertyCache: {},
10     defaultUnit : "px",
11     borders: {l: 'border-left-width', r: 'border-right-width', t: 'border-top-width', b: 'border-bottom-width'},
12     paddings: {l: 'padding-left', r: 'padding-right', t: 'padding-top', b: 'padding-bottom'},
13     margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'},
14
15     // Reference the prototype's version of the method. Signatures are identical.
16     addUnits : Ext.core.Element.prototype.addUnits,
17
18     /**
19      * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
20      * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
21      * @static
22      * @param {Number|String} box The encoded margins
23      * @return {Object} An object with margin sizes for top, right, bottom and left
24      */
25     parseBox : function(box) {
26         if (Ext.isObject(box)) {
27             return {
28                 top: box.top || 0,
29                 right: box.right || 0,
30                 bottom: box.bottom || 0,
31                 left: box.left || 0
32             };
33         } else {
34             if (typeof box != 'string') {
35                 box = box.toString();
36             }
37             var parts  = box.split(' '),
38                 ln = parts.length;
39     
40             if (ln == 1) {
41                 parts[1] = parts[2] = parts[3] = parts[0];
42             }
43             else if (ln == 2) {
44                 parts[2] = parts[0];
45                 parts[3] = parts[1];
46             }
47             else if (ln == 3) {
48                 parts[3] = parts[1];
49             }
50     
51             return {
52                 top   :parseFloat(parts[0]) || 0,
53                 right :parseFloat(parts[1]) || 0,
54                 bottom:parseFloat(parts[2]) || 0,
55                 left  :parseFloat(parts[3]) || 0
56             };
57         }
58         
59     },
60     
61     /**
62      * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
63      * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
64      * @static
65      * @param {Number|String} box The encoded margins
66      * @param {String} units The type of units to add
67      * @return {String} An string with unitized (px if units is not specified) metrics for top, right, bottom and left
68      */
69     unitizeBox : function(box, units) {
70         var A = this.addUnits,
71             B = this.parseBox(box);
72             
73         return A(B.top, units) + ' ' +
74                A(B.right, units) + ' ' +
75                A(B.bottom, units) + ' ' +
76                A(B.left, units);
77         
78     },
79
80     // private
81     camelReplaceFn : function(m, a) {
82         return a.charAt(1).toUpperCase();
83     },
84
85     /**
86      * Normalizes CSS property keys from dash delimited to camel case JavaScript Syntax.
87      * For example:
88      * <ul>
89      *  <li>border-width -> borderWidth</li>
90      *  <li>padding-top -> paddingTop</li>
91      * </ul>
92      * @static
93      * @param {String} prop The property to normalize
94      * @return {String} The normalized string
95      */
96     normalize : function(prop) {
97         if (prop == 'float') {
98             prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
99         }
100         return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn));
101     },
102
103     /**
104      * Retrieves the document height
105      * @static
106      * @return {Number} documentHeight
107      */
108     getDocumentHeight: function() {
109         return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight());
110     },
111
112     /**
113      * Retrieves the document width
114      * @static
115      * @return {Number} documentWidth
116      */
117     getDocumentWidth: function() {
118         return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth());
119     },
120
121     /**
122      * Retrieves the viewport height of the window.
123      * @static
124      * @return {Number} viewportHeight
125      */
126     getViewportHeight: function(){
127         return window.innerHeight;
128     },
129
130     /**
131      * Retrieves the viewport width of the window.
132      * @static
133      * @return {Number} viewportWidth
134      */
135     getViewportWidth : function() {
136         return window.innerWidth;
137     },
138
139     /**
140      * Retrieves the viewport size of the window.
141      * @static
142      * @return {Object} object containing width and height properties
143      */
144     getViewSize : function() {
145         return {
146             width: window.innerWidth,
147             height: window.innerHeight
148         };
149     },
150
151     /**
152      * Retrieves the current orientation of the window. This is calculated by
153      * determing if the height is greater than the width.
154      * @static
155      * @return {String} Orientation of window: 'portrait' or 'landscape'
156      */
157     getOrientation : function() {
158         if (Ext.supports.OrientationChange) {
159             return (window.orientation == 0) ? 'portrait' : 'landscape';
160         }
161         
162         return (window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape';
163     },
164
165     /** 
166      * Returns the top Element that is located at the passed coordinates
167      * @static
168      * @param {Number} x The x coordinate
169      * @param {Number} x The y coordinate
170      * @return {String} The found Element
171      */
172     fromPoint: function(x, y) {
173         return Ext.get(document.elementFromPoint(x, y));
174     },
175     
176     /**
177      * Converts a CSS string into an object with a property for each style.
178      * <p>
179      * The sample code below would return an object with 2 properties, one
180      * for background-color and one for color.</p>
181      * <pre><code>
182 var css = 'background-color: red;color: blue; ';
183 console.log(Ext.core.Element.parseStyles(css));
184      * </code></pre>
185      * @static
186      * @param {String} styles A CSS string
187      * @return {Object} styles
188      */
189     parseStyles: function(styles){
190         var out = {},
191             cssRe = this.cssRe,
192             matches;
193             
194         if (styles) {
195             // Since we're using the g flag on the regex, we need to set the lastIndex.
196             // This automatically happens on some implementations, but not others, see:
197             // http://stackoverflow.com/questions/2645273/javascript-regular-expression-literal-persists-between-function-calls
198             // http://blog.stevenlevithan.com/archives/fixing-javascript-regexp
199             cssRe.lastIndex = 0;
200             while ((matches = cssRe.exec(styles))) {
201                 out[matches[1]] = matches[2];
202             }
203         }
204         return out;
205     }
206 });