3 jQuery.support = (function() {
18 div = document.createElement( "div" ),
19 documentElement = document.documentElement;
22 div.setAttribute("className", "t");
23 div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
25 all = div.getElementsByTagName( "*" );
26 a = div.getElementsByTagName( "a" )[ 0 ];
28 // Can't get basic test support
29 if ( !all || !all.length || !a ) {
33 // First batch of supports tests
34 select = document.createElement( "select" );
35 opt = select.appendChild( document.createElement("option") );
36 input = div.getElementsByTagName( "input" )[ 0 ];
39 // IE strips leading whitespace when .innerHTML is used
40 leadingWhitespace: ( div.firstChild.nodeType === 3 ),
42 // Make sure that tbody elements aren't automatically inserted
43 // IE will insert them into empty tables
44 tbody: !div.getElementsByTagName("tbody").length,
46 // Make sure that link elements get serialized correctly by innerHTML
47 // This requires a wrapper element in IE
48 htmlSerialize: !!div.getElementsByTagName("link").length,
50 // Get the style information from getAttribute
51 // (IE uses .cssText instead)
52 style: /top/.test( a.getAttribute("style") ),
54 // Make sure that URLs aren't manipulated
55 // (IE normalizes it by default)
56 hrefNormalized: ( a.getAttribute("href") === "/a" ),
58 // Make sure that element opacity exists
59 // (IE uses filter instead)
60 // Use a regex to work around a WebKit issue. See #5145
61 opacity: /^0.55/.test( a.style.opacity ),
63 // Verify style float existence
64 // (IE uses styleFloat instead of cssFloat)
65 cssFloat: !!a.style.cssFloat,
67 // Make sure that if no value is specified for a checkbox
68 // that it defaults to "on".
69 // (WebKit defaults to "" instead)
70 checkOn: ( input.value === "on" ),
72 // Make sure that a selected-by-default option has a working selected property.
73 // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
74 optSelected: opt.selected,
76 // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
77 getSetAttribute: div.className !== "t",
79 // Tests for enctype support on a form(#6743)
80 enctype: !!document.createElement("form").enctype,
82 // Makes sure cloning an html5 element does not cause problems
83 // Where outerHTML is undefined, this still works
84 html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav></:nav>",
86 // Will be defined later
89 focusinBubbles: false,
92 inlineBlockNeedsLayout: false,
93 shrinkWrapBlocks: false,
94 reliableMarginRight: true,
98 // Make sure checked status is properly cloned
100 support.noCloneChecked = input.cloneNode( true ).checked;
102 // Make sure that the options inside disabled selects aren't marked as disabled
103 // (WebKit marks them as disabled)
104 select.disabled = true;
105 support.optDisabled = !opt.disabled;
107 // Test to see if it's possible to delete an expando from an element
108 // Fails in Internet Explorer
112 support.deleteExpando = false;
115 if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
116 div.attachEvent( "onclick", function() {
117 // Cloning a node shouldn't copy over any
118 // bound event handlers (IE does this)
119 support.noCloneEvent = false;
121 div.cloneNode( true ).fireEvent( "onclick" );
124 // Check if a radio maintains its value
125 // after being appended to the DOM
126 input = document.createElement("input");
128 input.setAttribute("type", "radio");
129 support.radioValue = input.value === "t";
131 input.setAttribute("checked", "checked");
132 div.appendChild( input );
133 fragment = document.createDocumentFragment();
134 fragment.appendChild( div.lastChild );
136 // WebKit doesn't clone checked state correctly in fragments
137 support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
139 // Check if a disconnected checkbox will retain its checked
140 // value of true after appended to the DOM (IE6/7)
141 support.appendChecked = input.checked;
143 fragment.removeChild( input );
144 fragment.appendChild( div );
148 // Check if div with explicit width and no margin-right incorrectly
149 // gets computed margin-right based on width of container. For more
150 // info see bug #3333
151 // Fails in WebKit before Feb 2011 nightlies
152 // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
153 if ( window.getComputedStyle ) {
154 marginDiv = document.createElement( "div" );
155 marginDiv.style.width = "0";
156 marginDiv.style.marginRight = "0";
157 div.style.width = "2px";
158 div.appendChild( marginDiv );
159 support.reliableMarginRight =
160 ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
163 // Technique from Juriy Zaytsev
164 // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
165 // We only care about the case where non-standard event systems
166 // are used, namely in IE. Short-circuiting here helps us to
167 // avoid an eval call (in setAttribute) which can cause CSP
168 // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
169 if ( div.attachEvent ) {
175 eventName = "on" + i;
176 isSupported = ( eventName in div );
177 if ( !isSupported ) {
178 div.setAttribute( eventName, "return;" );
179 isSupported = ( typeof div[ eventName ] === "function" );
181 support[ i + "Bubbles" ] = isSupported;
185 fragment.removeChild( div );
187 // Null elements to avoid leaks in IE
188 fragment = select = opt = marginDiv = div = input = null;
190 // Run tests that need a body at doc ready
192 var container, outer, inner, table, td, offsetSupport,
193 conMarginTop, ptlm, vb, style, html,
194 body = document.getElementsByTagName("body")[0];
197 // Return for frameset docs that don't have a body
202 ptlm = "position:absolute;top:0;left:0;width:1px;height:1px;margin:0;";
203 vb = "visibility:hidden;border:0;";
204 style = "style='" + ptlm + "border:5px solid #000;padding:0;'";
205 html = "<div " + style + "><div></div></div>" +
206 "<table " + style + " cellpadding='0' cellspacing='0'>" +
207 "<tr><td></td></tr></table>";
209 container = document.createElement("div");
210 container.style.cssText = vb + "width:0;height:0;position:static;top:0;margin-top:" + conMarginTop + "px";
211 body.insertBefore( container, body.firstChild );
213 // Construct the test element
214 div = document.createElement("div");
215 container.appendChild( div );
217 // Check if table cells still have offsetWidth/Height when they are set
218 // to display:none and there are still other visible table cells in a
219 // table row; if so, offsetWidth/Height are not reliable for use when
220 // determining if an element has been hidden directly using
221 // display:none (it is still safe to use offsets if a parent element is
222 // hidden; don safety goggles and see bug #4512 for more information).
223 // (only IE 8 fails this test)
224 div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
226 tds = div.getElementsByTagName( "td" );
227 isSupported = ( tds[ 0 ].offsetHeight === 0 );
229 tds[ 0 ].style.display = "";
230 tds[ 1 ].style.display = "none";
232 // Check if empty table cells still have offsetWidth/Height
233 // (IE <= 8 fail this test)
234 support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
236 // Figure out if the W3C box model works as expected
238 div.style.width = div.style.paddingLeft = "1px";
239 jQuery.boxModel = support.boxModel = div.offsetWidth === 2;
241 if ( typeof div.style.zoom !== "undefined" ) {
242 // Check if natively block-level elements act like inline-block
243 // elements when setting their display to 'inline' and giving
245 // (IE < 8 does this)
246 div.style.display = "inline";
248 support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
250 // Check if elements with layout shrink-wrap their children
252 div.style.display = "";
253 div.innerHTML = "<div style='width:4px;'></div>";
254 support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
257 div.style.cssText = ptlm + vb;
258 div.innerHTML = html;
260 outer = div.firstChild;
261 inner = outer.firstChild;
262 td = outer.nextSibling.firstChild.firstChild;
265 doesNotAddBorder: ( inner.offsetTop !== 5 ),
266 doesAddBorderForTableAndCells: ( td.offsetTop === 5 )
269 inner.style.position = "fixed";
270 inner.style.top = "20px";
272 // safari subtracts parent border width here which is 5px
273 offsetSupport.fixedPosition = ( inner.offsetTop === 20 || inner.offsetTop === 15 );
274 inner.style.position = inner.style.top = "";
276 outer.style.overflow = "hidden";
277 outer.style.position = "relative";
279 offsetSupport.subtractsBorderForOverflowNotVisible = ( inner.offsetTop === -5 );
280 offsetSupport.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== conMarginTop );
282 if ( window.getComputedStyle ) {
283 div.style.marginTop = "1%";
284 support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
287 if ( typeof container.style.zoom !== "undefined" ) {
288 container.style.zoom = 1;
291 body.removeChild( container );
292 div = container = null;
294 jQuery.extend( support, offsetSupport );