aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleg <markelog@gmail.com>2012-12-17 18:17:39 +0400
committerDave Methvin <dave.methvin@gmail.com>2012-12-20 22:08:32 -0500
commitc8c6ab6924b48832bfc2b94d40887b2f1b6c891e (patch)
tree9185c82c268d03c84da96ef7773594c562774d5c
parent00bbbe207555d3aa9d7716bb9fc6d4e4f4bcbf1e (diff)
downloadjquery-c8c6ab6924b48832bfc2b94d40887b2f1b6c891e.tar.gz
jquery-c8c6ab6924b48832bfc2b94d40887b2f1b6c891e.zip
Fix #12569. Improve feature detect for event bubbling. Close gh-1076.
-rw-r--r--src/support.js112
-rw-r--r--test/csp.php5
-rw-r--r--test/unit/event.js28
-rw-r--r--test/unit/support.js121
4 files changed, 180 insertions, 86 deletions
diff --git a/src/support.js b/src/support.js
index 70f5f114d..c99bb3922 100644
--- a/src/support.js
+++ b/src/support.js
@@ -1,16 +1,6 @@
jQuery.support = (function() {
- var support,
- all,
- a,
- select,
- opt,
- input,
- fragment,
- eventName,
- i,
- isSupported,
- clickFn,
+ var support, all, a, select, opt, input, fragment, eventName, isSupported, i,
div = document.createElement("div");
// Setup
@@ -80,9 +70,6 @@ jQuery.support = (function() {
boxModel: document.compatMode === "CSS1Compat",
// Will be defined later
- submitBubbles: true,
- changeBubbles: true,
- focusinBubbles: false,
deleteExpando: true,
noCloneEvent: true,
inlineBlockNeedsLayout: false,
@@ -101,24 +88,13 @@ jQuery.support = (function() {
select.disabled = true;
support.optDisabled = !opt.disabled;
- // Test to see if it's possible to delete an expando from an element
- // Fails in Internet Explorer
+ // Support: IE<9
try {
delete div.test;
} catch( e ) {
support.deleteExpando = false;
}
- if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
- div.attachEvent( "onclick", clickFn = function() {
- // Cloning a node shouldn't copy over any
- // bound event handlers (IE does this)
- support.noCloneEvent = false;
- });
- div.cloneNode( true ).fireEvent("onclick");
- div.detachEvent( "onclick", clickFn );
- }
-
// Check if we can trust getAttribute("value")
input = document.createElement("input");
input.setAttribute( "value", "" );
@@ -130,49 +106,42 @@ jQuery.support = (function() {
support.radioValue = input.value === "t";
// #11217 - WebKit loses check when the name is after the checked attribute
- input.setAttribute( "checked", "checked" );
+ input.setAttribute( "checked", "t" );
input.setAttribute( "name", "t" );
- div.appendChild( input );
fragment = document.createDocumentFragment();
- fragment.appendChild( div.lastChild );
-
- // WebKit doesn't clone checked state correctly in fragments
- support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+ fragment.appendChild( input );
// Check if a disconnected checkbox will retain its checked
// value of true after appended to the DOM (IE6/7)
support.appendChecked = input.checked;
- fragment.removeChild( input );
- fragment.appendChild( div );
+ // WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
- // Technique from Juriy Zaytsev
- // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/
- // We only care about the case where non-standard event systems
- // are used, namely in IE. Short-circuiting here helps us to
- // avoid an eval call (in setAttribute) which can cause CSP
- // to go haywire. See: https://developer.mozilla.org/en/Security/CSP
+ // Support: IE<9
+ // Opera does not clone events (and typeof div.attachEvent === undefined).
+ // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
if ( div.attachEvent ) {
- for ( i in {
- submit: true,
- change: true,
- focusin: true
- }) {
- eventName = "on" + i;
- isSupported = ( eventName in div );
- if ( !isSupported ) {
- div.setAttribute( eventName, "return;" );
- isSupported = ( typeof div[ eventName ] === "function" );
- }
- support[ i + "Bubbles" ] = isSupported;
- }
+ div.attachEvent( "onclick", function() {
+ support.noCloneEvent = false;
+ });
+
+ div.cloneNode( true ).click();
+ }
+
+ // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+ // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
+ for ( i in { submit: true, change: true, focusin: true }) {
+ div.setAttribute( eventName = "on" + i, "t" );
+
+ support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
}
// Run tests that need a body at doc ready
jQuery(function() {
- var container, div, tds, marginDiv,
- divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+ var container, marginDiv, tds,
+ divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
body = document.getElementsByTagName("body")[0];
if ( !body ) {
@@ -181,20 +150,17 @@ jQuery.support = (function() {
}
container = document.createElement("div");
- container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px";
- body.insertBefore( container, body.firstChild );
+ container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
- // Construct the test element
- div = document.createElement("div");
- container.appendChild( div );
+ body.appendChild( container ).appendChild( div );
+ // Support: IE8
// Check if table cells still have offsetWidth/Height when they are set
// to display:none and there are still other visible table cells in a
// table row; if so, offsetWidth/Height are not reliable for use when
// determining if an element has been hidden directly using
// display:none (it is still safe to use offsets if a parent element is
// hidden; don safety goggles and see bug #4512 for more information).
- // (only IE 8 fails this test)
div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
tds = div.getElementsByTagName("td");
tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none";
@@ -203,8 +169,8 @@ jQuery.support = (function() {
tds[ 0 ].style.display = "";
tds[ 1 ].style.display = "none";
+ // Support: IE8
// Check if empty table cells still have offsetWidth/Height
- // (IE <= 8 fail this test)
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
// Check box-sizing and margin behavior
@@ -213,39 +179,36 @@ jQuery.support = (function() {
support.boxSizing = ( div.offsetWidth === 4 );
support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 );
- // NOTE: To any future maintainer, we've window.getComputedStyle
- // because jsdom on node.js will break without it.
+ // Use window.getComputedStyle because jsdom on node.js will break without it.
if ( window.getComputedStyle ) {
support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%";
support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px";
// Check if div with explicit width and no margin-right incorrectly
- // gets computed margin-right based on width of container. For more
- // info see bug #3333
+ // gets computed margin-right based on width of container. (#3333)
// Fails in WebKit before Feb 2011 nightlies
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
- marginDiv = document.createElement("div");
+ marginDiv = div.appendChild( document.createElement("div") );
marginDiv.style.cssText = div.style.cssText = divReset;
marginDiv.style.marginRight = marginDiv.style.width = "0";
div.style.width = "1px";
- div.appendChild( marginDiv );
+
support.reliableMarginRight =
!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
}
if ( typeof div.style.zoom !== "undefined" ) {
+ // Support: IE<8
// Check if natively block-level elements act like inline-block
// elements when setting their display to 'inline' and giving
// them layout
- // (IE < 8 does this)
div.innerHTML = "";
div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+ // Support: IE6
// Check if elements with layout shrink-wrap their children
- // (IE 6 does this)
div.style.display = "block";
- div.style.overflow = "visible";
div.innerHTML = "<div></div>";
div.firstChild.style.width = "5px";
support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
@@ -255,14 +218,15 @@ jQuery.support = (function() {
body.style.zoom = 1;
}
- // Null elements to avoid leaks in IE
body.removeChild( container );
+
+ // Null elements to avoid leaks in IE
container = div = tds = marginDiv = null;
});
// Null elements to avoid leaks in IE
- fragment.removeChild( div );
- all = a = select = opt = input = fragment = div = null;
+ all = select = fragment = opt = a = input = null;
return support;
})();
+
diff --git a/test/csp.php b/test/csp.php
index e3245149c..9ab18f392 100644
--- a/test/csp.php
+++ b/test/csp.php
@@ -1,4 +1,7 @@
-<?php header("X-Content-Security-Policy-Report-Only: allow *"); ?>
+<?php
+ header("X-Content-Security-Policy: default-src localhost 'self';");
+ header("X-WebKit-CSP: script-src 'self'; style-src 'self' 'unsafe-inline'");
+?>
<!DOCTYPE html>
<html>
<head>
diff --git a/test/unit/event.js b/test/unit/event.js
index 32355c9ad..ff2ea1dd5 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -2601,3 +2601,31 @@ test( "make sure events cloned correctly", 18, function() {
clone.find("p:first").click(); // 0 should be fired
clone.find("#check1").change(); // 0 events should fire
});
+
+test( "Check order of focusin/focusout events", 2, function() {
+ var focus, blur,
+ input = jQuery("#name");
+
+ input.on("focus", function() {
+ focus = true;
+
+ }).on("focusin", function() {
+ ok( !focus, "Focusin event should fire before focus does" );
+
+ }).on("blur", function() {
+ blur = true;
+
+ }).on("focusout", function() {
+ ok( !blur, "Focusout event should fire before blur does" );
+ });
+
+ // gain focus
+ input.focus();
+
+ // then lose it
+ jQuery("#search").focus();
+
+ // cleanup
+ input.off();
+});
+
diff --git a/test/unit/support.js b/test/unit/support.js
index 8d4ac21bc..94a871ee9 100644
--- a/test/unit/support.js
+++ b/test/unit/support.js
@@ -7,7 +7,7 @@ test("boxModel", function() {
});
if ( jQuery.css ) {
- testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9238)", "support/bodyBackground.html", function( color, support ) {
+ testIframeWithCallback( "body background is not lost if set prior to loading jQuery (#9239)", "support/bodyBackground.html", function( color, support ) {
expect( 2 );
var i,
passed = true,
@@ -29,6 +29,7 @@ if ( jQuery.css ) {
strictEqual( jQuery.support[ i ], support[ i ], "Unexpected property: " + i );
}
}
+
ok( passed, "Same support properties" );
});
}
@@ -44,13 +45,12 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
});
(function() {
-
- var userAgent = window.navigator.userAgent,
- expected;
+ var expected,
+ userAgent = window.navigator.userAgent;
// These tests do not have to stay
// They are here to help with upcoming support changes for 1.8
- if ( /chrome\/19\.0/i.test(userAgent) ) {
+ if ( /chrome/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
@@ -83,7 +83,106 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
- } else if ( /msie 8\.0/i.test(userAgent) ) {
+ } else if ( /opera/i.test( userAgent ) ) {
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":true,
+ "optSelected":true,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":false,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":true,
+ "optDisabled":true,
+ "radioValue":false,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":true,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ } else if ( /msie 10\.0/i.test( userAgent ) ) {
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":true,
+ "optSelected":false,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":true,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":false,
+ "optDisabled":true,
+ "radioValue":false,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":true,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ } else if ( /msie 9\.0/i.test( userAgent ) ) {
+ expected = {
+ "leadingWhitespace":true,
+ "tbody":true,
+ "htmlSerialize":true,
+ "style":true,
+ "hrefNormalized":true,
+ "opacity":true,
+ "cssFloat":true,
+ "checkOn":true,
+ "optSelected":false,
+ "getSetAttribute":true,
+ "enctype":true,
+ "html5Clone":true,
+ "submitBubbles":true,
+ "changeBubbles":true,
+ "focusinBubbles":true,
+ "deleteExpando":true,
+ "noCloneEvent":true,
+ "inlineBlockNeedsLayout":false,
+ "shrinkWrapBlocks":false,
+ "reliableMarginRight":true,
+ "noCloneChecked":false,
+ "optDisabled":true,
+ "radioValue":false,
+ "checkClone":true,
+ "appendChecked":true,
+ "boxModel":true,
+ "reliableHiddenOffsets":true,
+ "ajax":true,
+ "cors":false,
+ "doesNotIncludeMarginInBodyOffset":true
+ };
+ } else if ( /msie 8\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":false,
"tbody":true,
@@ -116,7 +215,7 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"cors":false,
"doesNotIncludeMarginInBodyOffset":true
};
- } else if ( /msie 7\.0/i.test(userAgent) ) {
+ } else if ( /msie 7\.0/i.test( userAgent ) ) {
expected = {
"ajax": true,
"appendChecked": false,
@@ -149,7 +248,7 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"tbody": false,
"style": false
};
- } else if ( /msie 6\.0/i.test(userAgent) ) {
+ } else if ( /msie 6\.0/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":false,
"tbody":false,
@@ -182,7 +281,7 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"cors":false,
"doesNotIncludeMarginInBodyOffset":true
};
- } else if ( /5\.1\.1 safari/i.test(userAgent) ) {
+ } else if ( /5\.1\.1 safari/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
@@ -215,7 +314,7 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"cors":true,
"doesNotIncludeMarginInBodyOffset":true
};
- } else if ( /firefox\/3\.6/i.test(userAgent) ) {
+ } else if ( /firefox/i.test( userAgent ) ) {
expected = {
"leadingWhitespace":true,
"tbody":true,
@@ -227,7 +326,7 @@ testIframeWithCallback( "box-sizing does not affect jQuery.support.shrinkWrapBlo
"checkOn":true,
"optSelected":true,
"getSetAttribute":true,
- "enctype":false,
+ "enctype":true,
"html5Clone":true,
"submitBubbles":true,
"changeBubbles":true,
ption> Nextcloud server, a safe home for all your data: https://github.com/nextcloud/serverwww-data
summaryrefslogtreecommitdiffstats
path: root/lib/private/hooks/basicemitter.php
blob: 9ffe1af23144f6aae36841e3fbc3c689f5c272a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89