3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
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.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
21 isCSS1 = doc.compatMode == "CSS1Compat",
22 ELEMENT = Ext.Element,
25 _fly = new Ext.Element.Flyweight();
31 // If the browser does not support document.activeElement we need some assistance.
32 // This covers old Safari 3.2 (4.0 added activeElement along with just about all
33 // other browsers). We need this support to handle issues with old Safari.
34 if (!('activeElement' in doc) && doc.addEventListener) {
35 doc.addEventListener('focus',
37 if (ev && ev.target) {
38 activeElement = (ev.target == doc) ? null : ev.target;
44 * Helper function to create the function that will restore the selection.
46 function makeSelectionRestoreFn (activeEl, start, end) {
48 activeEl.selectionStart = start;
49 activeEl.selectionEnd = end;
54 isAncestor : function(p, c) {
62 } else if (p.compareDocumentPosition) {
63 return !!(p.compareDocumentPosition(c) & 16);
65 while ((c = c.parentNode)) {
74 * Returns the active element in the DOM. If the browser supports activeElement
75 * on the document, this is returned. If not, the focus is tracked and the active
76 * element is maintained internally.
77 * @return {HTMLElement} The active (focused) element in the document.
79 getActiveElement: function () {
80 return doc.activeElement || activeElement;
84 * Creates a function to call to clean up problems with the work-around for the
85 * WebKit RightMargin bug. The work-around is to add "display: 'inline-block'" to
86 * the element before calling getComputedStyle and then to restore its original
87 * display value. The problem with this is that it corrupts the selection of an
88 * INPUT or TEXTAREA element (as in the "I-beam" goes away but ths focus remains).
89 * To cleanup after this, we need to capture the selection of any such element and
90 * then restore it after we have restored the display style.
92 * @param target {Element} The top-most element being adjusted.
95 getRightMarginFixCleaner: function (target) {
96 var supports = Ext.supports,
97 hasInputBug = supports.DisplayChangeInputSelectionBug,
98 hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug;
100 if (hasInputBug || hasTextAreaBug) {
101 var activeEl = doc.activeElement || activeElement, // save a call
102 tag = activeEl && activeEl.tagName,
106 if ((hasTextAreaBug && tag == 'TEXTAREA') ||
107 (hasInputBug && tag == 'INPUT' && activeEl.type == 'text')) {
108 if (ELEMENT.isAncestor(target, activeEl)) {
109 start = activeEl.selectionStart;
110 end = activeEl.selectionEnd;
112 if (Ext.isNumber(start) && Ext.isNumber(end)) { // to be safe...
113 // We don't create the raw closure here inline because that
114 // will be costly even if we don't want to return it (nested
115 // function decls and exprs are often instantiated on entry
116 // regardless of whether execution ever reaches them):
117 return makeSelectionRestoreFn(activeEl, start, end);
123 return Ext.emptyFn; // avoid special cases, just return a nop
126 getViewWidth : function(full) {
127 return full ? ELEMENT.getDocumentWidth() : ELEMENT.getViewportWidth();
130 getViewHeight : function(full) {
131 return full ? ELEMENT.getDocumentHeight() : ELEMENT.getViewportHeight();
134 getDocumentHeight: function() {
135 return Math.max(!isCSS1 ? doc.body.scrollHeight : doc.documentElement.scrollHeight, ELEMENT.getViewportHeight());
138 getDocumentWidth: function() {
139 return Math.max(!isCSS1 ? doc.body.scrollWidth : doc.documentElement.scrollWidth, ELEMENT.getViewportWidth());
142 getViewportHeight: function(){
144 (Ext.isStrict ? doc.documentElement.clientHeight : doc.body.clientHeight) :
148 getViewportWidth : function() {
149 return (!Ext.isStrict && !Ext.isOpera) ? doc.body.clientWidth :
150 Ext.isIE ? doc.documentElement.clientWidth : self.innerWidth;
153 getY : function(el) {
154 return ELEMENT.getXY(el)[1];
157 getX : function(el) {
158 return ELEMENT.getXY(el)[0];
161 getOffsetParent: function (el) {
164 // accessing offsetParent can throw "Unspecified Error" in IE6-8 (not 9)
165 return el.offsetParent;
167 var body = document.body; // safe bet, unless...
168 return (el == body) ? null : body;
172 getXY : function(el) {
183 bd = (doc.body || doc.documentElement),
189 hasAbsolute = fly(el).isStyle("position", "absolute");
191 if (el.getBoundingClientRect) {
193 b = el.getBoundingClientRect();
194 scroll = fly(document).getScroll();
195 ret = [ Math.round(b.left + scroll.left), Math.round(b.top + scroll.top) ];
197 // IE6-8 can also throw from getBoundingClientRect...
202 for (p = el; p; p = ELEMENT.getOffsetParent(p)) {
207 hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");
210 y += bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
211 x += bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
213 if (p != el && !pe.isStyle('overflow','visible')) {
220 if (Ext.isSafari && hasAbsolute) {
225 if (Ext.isGecko && !hasAbsolute) {
227 x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
228 y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
232 while (p && p != bd) {
233 if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
245 setXY : function(el, xy) {
246 (el = Ext.fly(el, '_setXY')).position();
248 var pts = el.translatePoints(xy),
249 style = el.dom.style,
253 if (!isNaN(pts[pos])) {
254 style[pos] = pts[pos] + "px";
259 setX : function(el, x) {
260 ELEMENT.setXY(el, [x, false]);
263 setY : function(el, y) {
264 ELEMENT.setXY(el, [false, y]);
268 * Serializes a DOM form into a url encoded string
269 * @param {Object} form The form
270 * @return {String} The url encoded form
272 serializeForm: function(form) {
273 var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
275 encoder = encodeURIComponent,
281 Ext.each(fElements, function(element){
285 if (!element.disabled && name) {
286 if (/select-(one|multiple)/i.test(type)) {
287 Ext.each(element.options, function(opt){
289 hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
290 data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
293 } else if (!(/file|undefined|reset|button/i.test(type))) {
294 if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {
295 data += encoder(name) + '=' + encoder(element.value) + '&';
296 hasSubmit = /submit/i.test(type);
301 return data.substr(0, data.length - 1);