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.
16 * @class Ext.core.Element
21 isCSS1 = doc.compatMode == "CSS1Compat",
22 ELEMENT = Ext.core.Element,
25 _fly = new Ext.core.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 getXY : function(el) {
172 bd = (doc.body || doc.documentElement),
178 hasAbsolute = fly(el).isStyle("position", "absolute");
180 if (el.getBoundingClientRect) {
181 b = el.getBoundingClientRect();
182 scroll = fly(document).getScroll();
183 ret = [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)];
192 hasAbsolute = hasAbsolute || pe.isStyle("position", "absolute");
195 y += bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
196 x += bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
198 if (p != el && !pe.isStyle('overflow','visible')) {
206 if (Ext.isSafari && hasAbsolute) {
211 if (Ext.isGecko && !hasAbsolute) {
213 x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
214 y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
218 while (p && p != bd) {
219 if (!Ext.isOpera || (p.tagName != 'TR' && !fly(p).isStyle("display", "inline"))) {
231 setXY : function(el, xy) {
232 (el = Ext.fly(el, '_setXY')).position();
234 var pts = el.translatePoints(xy),
235 style = el.dom.style,
239 if (!isNaN(pts[pos])) {
240 style[pos] = pts[pos] + "px";
245 setX : function(el, x) {
246 ELEMENT.setXY(el, [x, false]);
249 setY : function(el, y) {
250 ELEMENT.setXY(el, [false, y]);
254 * Serializes a DOM form into a url encoded string
255 * @param {Object} form The form
256 * @return {String} The url encoded form
258 serializeForm: function(form) {
259 var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
261 encoder = encodeURIComponent,
267 Ext.each(fElements, function(element){
271 if (!element.disabled && name) {
272 if (/select-(one|multiple)/i.test(type)) {
273 Ext.each(element.options, function(opt){
275 hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
276 data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
279 } else if (!(/file|undefined|reset|button/i.test(type))) {
280 if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {
281 data += encoder(name) + '=' + encoder(element.value) + '&';
282 hasSubmit = /submit/i.test(type);
287 return data.substr(0, data.length - 1);