Skip to content
Permalink
Browse files

Transform $.bindReady into $.ready.promise. It is now possible to use…

… $.ready.promise or $.when( $.ready ) to get the ready promise. Costs *1* byte min/gzipped. Unit test added.
  • Loading branch information...
jaubourg committed May 5, 2012
1 parent 714b8ff commit e3cf0e220c6cfaac18642f3d4db96698ea601791
Showing with 68 additions and 50 deletions.
  1. +46 −50 src/core.js
  2. +17 −0 test/data/event/promiseReady.html
  3. +5 −0 test/unit/event.js
@@ -251,11 +251,8 @@ jQuery.fn = jQuery.prototype = {
},

ready: function( fn ) {
// Attach the listeners
jQuery.bindReady();

// Add the callback
readyList.add( fn );
jQuery.ready.promise().done( fn );

return this;
},
@@ -412,7 +409,7 @@ jQuery.extend({
}

// If there are functions bound, to execute
readyList.fireWith( document, [ jQuery ] );
readyList.resolveWith( document, [ jQuery ] );

// Trigger any bound ready events
if ( jQuery.fn.trigger ) {
@@ -421,51 +418,6 @@ jQuery.extend({
}
},

bindReady: function() {
if ( readyList ) {
return;
}

readyList = jQuery.Callbacks( "once memory" );

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState !== "loading" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
return setTimeout( jQuery.ready, 1 );
}

// Mozilla, Opera and webkit nightlies currently support this event
if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );

// If IE event model is used
} else if ( document.attachEvent ) {
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );

// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );

// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;

try {
toplevel = window.frameElement == null;
} catch(e) {}

if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
},

// See test/unit/core.js for details concerning isFunction.
// Since version 1.3, DOM methods and functions like alert
// aren't supported. They return false on IE (#2968).
@@ -897,6 +849,50 @@ jQuery.extend({
browser: {}
});

jQuery.ready.promise = function( object ) {
if ( !readyList ) {

readyList = jQuery.Deferred();

// Catch cases where $(document).ready() is called after the
// browser event has already occurred.
if ( document.readyState !== "loading" ) {
// Handle it asynchronously to allow scripts the opportunity to delay ready
setTimeout( jQuery.ready, 1 );

This comment has been minimized.

@mikesherov

mikesherov May 7, 2012

Member

return setTimeout here.

This comment has been minimized.

@jaubourg

jaubourg May 7, 2012

Author Member

nope, we return the promise now.


// Mozilla, Opera and webkit nightlies currently support this event
} else if ( document.addEventListener ) {
// Use the handy event callback
document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

// A fallback to window.onload, that will always work
window.addEventListener( "load", jQuery.ready, false );

// If IE event model is used
} else if ( document.attachEvent ) {

This comment has been minimized.

@rwaldron

rwaldron May 7, 2012

Member

@mikesherov I think this is why we didn't have the document.addEventListener condition inside the DOMContentLoaded definition.

f925c7a#L0R65

This comment has been minimized.

@mikesherov

mikesherov May 7, 2012

Member

Right, but no need for an elseif here either. Just use an else.

This comment has been minimized.

@jaubourg

jaubourg May 7, 2012

Author Member

Right.

This comment has been minimized.

@jaubourg
// ensure firing before onload,
// maybe late but safe also for iframes
document.attachEvent( "onreadystatechange", DOMContentLoaded );

// A fallback to window.onload, that will always work
window.attachEvent( "onload", jQuery.ready );

// If IE and not a frame
// continually check to see if the document is ready
var toplevel = false;

try {
toplevel = window.frameElement == null;
} catch(e) {}

if ( document.documentElement.doScroll && toplevel ) {
doScrollCheck();
}
}
}
return readyList.promise( object );
};

// Populate the class2type map
jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
@@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Test case for jQuery ticket #11470</title>
<script type="text/javascript" src="../include_js.php"></script>
<script type="text/javascript">
jQuery.when( jQuery.ready ).done(function() {
jQuery("body").append("<div>modifying DOM</div>");
window.parent.iframeCallback( $("div").text() === "modifying DOM" );
});
</script>
</head>
<body>
<!-- long loading iframe -->
</body>
</html>
@@ -2800,6 +2800,11 @@ test("fixHooks extensions", function() {
// which breaks order of execution on async loaded files
// also need PHP to make the incepted IFRAME hang
if ( hasPHP ) {
testIframeWithCallback( "jQuery.ready promise", "event/promiseReady", function( isOk ) {
expect(1);
ok( isOk, "$.when( $.ready ) works" );
});

testIframeWithCallback( "jQuery.ready synchronous load with long loading iframe", "event/syncReady", function( isOk ) {
expect(1);
ok( isOk, "jQuery loaded synchronously fires ready before all sub-resources are loaded" );

0 comments on commit e3cf0e2

Please sign in to comment.
You can’t perform that action at this time.