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