Skip to content

Commit

Permalink
Allows jQuery to integrate with the require() provided by RequireJS, …
Browse files Browse the repository at this point in the history
…if it is available. Exposes jQuery as a module that can be required and makes sure jQuery ready callbacks are not fired if scripts are still being loaded by require(). Includes unit tests.
  • Loading branch information
jrburke committed Jun 22, 2010
1 parent 6a0942c commit 0178972
Show file tree
Hide file tree
Showing 19 changed files with 1,782 additions and 22 deletions.
81 changes: 59 additions & 22 deletions src/core.js
Expand Up @@ -40,7 +40,13 @@ var jQuery = function( selector, context ) {

// For matching the engine and version of the browser
browserMatch,


// Should require integration be used?
useRequire = !!( typeof require !== "undefined" && require.def ),

// require could have page load logic built in so remember its function
requireReadyCallback = useRequire && require.callReady,

// Has the ready events already been bound?
readyBound = false,

Expand Down Expand Up @@ -236,15 +242,24 @@ jQuery.fn = jQuery.prototype = {
// Attach the listeners
jQuery.bindReady();

// If the DOM is already ready
if ( jQuery.isReady ) {
// If the DOM is already ready, and if require is in use
// all scripts have finished loading
if ( jQuery.isReady && ( !useRequire || require.s.isDone ) ) {
// Execute the function immediately
fn.call( document, jQuery );

// Otherwise, remember the function for later
} else if ( readyList ) {
// Add the function to the wait list
readyList.push( fn );
} else {
// readyList could have been cleared for the initial
// page load, but if scripts are loaded via require after
// page load, then need to allow for other ready callbacks
// to be registered that indicate those scripts after page
// load have finished loading.
if ( !readyList ) {
readyList = [];
}
// Add the function to the wait list
readyList.push( fn );
}

return this;
Expand Down Expand Up @@ -371,24 +386,31 @@ jQuery.extend({
// Remember that the DOM is ready
jQuery.isReady = true;

// If there are functions bound, to execute
if ( readyList ) {
// Execute all of them
var fn, i = 0;
while ( (fn = readyList[ i++ ]) ) {
fn.call( document, jQuery );
}

// Reset the list of functions
readyList = null;
}

// Trigger any bound ready events
if ( jQuery.fn.triggerHandler ) {
jQuery( document ).triggerHandler( "ready" );
}
jQuery.callReady();
}
},

// Calls ready callbacks, can be triggered by require script loading.
callReady: function() {
if ( jQuery.isReady && (!useRequire || require.s.isDone) ) {
// If there are functions bound, to execute
if ( readyList ) {
// Execute all of them
var fn, i = 0;
while ( (fn = readyList[ i++ ]) ) {
fn.call( document, jQuery );
}

// Reset the list of functions
readyList = null;
}

// Trigger any bound ready events
if ( jQuery.fn.triggerHandler ) {
jQuery( document ).triggerHandler( "ready" );
}
}
},

bindReady: function() {
if ( readyBound ) {
Expand Down Expand Up @@ -817,4 +839,19 @@ function doScrollCheck() {
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;

// Integrate with require
if (useRequire) {
// Register script load completion callback
require.callReady = function() {
// If require has its own ready callback functionality, call it.
if ( requireReadyCallback ) {
requireReadyCallback();
}
jQuery.callReady();
};

// Register jQuery as a module
require.def("jquery", function() { return jQuery; });
}

})();
5 changes: 5 additions & 0 deletions test/require/data/dimple.js
@@ -0,0 +1,5 @@
require.def("dimple",
{
color: "dimple-blue"
}
);
13 changes: 13 additions & 0 deletions test/require/data/dos.js
@@ -0,0 +1,13 @@
require.def("dos",
["tres"],
function(tres) {
return {
name: "dos",
doSomething: function() {
return {
tresName: tres.name
};
}
};
}
);
7 changes: 7 additions & 0 deletions test/require/data/epsilon.js
@@ -0,0 +1,7 @@
"use strict";
/*global require: false */
require.def("epsilon",
{
name: "epsilon"
}
);
7 changes: 7 additions & 0 deletions test/require/data/func.js
@@ -0,0 +1,7 @@
require.def("func",
function () {
return function () {
return "You called a function";
}
}
);
14 changes: 14 additions & 0 deletions test/require/data/funcFour.js
@@ -0,0 +1,14 @@
require.def("funcFour",
["require", "funcThree"],
function (require) {
var four = function (arg) {
return "FOUR called with " + arg;
};

four.suffix = function () {
return require("funcThree").suffix();
};

return four;
}
);
15 changes: 15 additions & 0 deletions test/require/data/funcOne.js
@@ -0,0 +1,15 @@
require.def("funcOne",
["require", "funcTwo"],
function (require) {
var one = function (name) {
this.name = name;
};

one.prototype.getName = function () {
var inst = new (require("funcTwo"))("-NESTED");
return this.name + inst.name;
};

return one;
}
);
14 changes: 14 additions & 0 deletions test/require/data/funcThree.js
@@ -0,0 +1,14 @@
require.def("funcThree",
["funcFour"],
function (four) {
var three = function (arg) {
return arg + "-" + require("funcFour").suffix();
};

three.suffix = function () {
return "THREE_SUFFIX";
};

return three;
}
);
15 changes: 15 additions & 0 deletions test/require/data/funcTwo.js
@@ -0,0 +1,15 @@
require.def("funcTwo",
["funcOne"],
function () {
var two = function (name) {
this.name = name;
this.one = new (require("funcOne"))("ONE");
};

two.prototype.oneName = function () {
return this.one.getName();
};

return two;
}
);
38 changes: 38 additions & 0 deletions test/require/data/layer1.js
@@ -0,0 +1,38 @@
//Example layer file.

"use strict";
/*global require: false */

require.pause();

require.def("alpha",
["beta", "gamma"],
function (beta, gamma) {
return {
name: "alpha",
betaName: beta.name
};
}
);

require.def("beta",
["gamma"],
function (gamma) {
return {
name: "beta",
gammaName: gamma.name
};
}
);

require.def("gamma",
["epsilon"],
function (epsilon) {
return {
name: "gamma",
epsilonName: epsilon.name
};
}
);

require.resume();
13 changes: 13 additions & 0 deletions test/require/data/one.js
@@ -0,0 +1,13 @@
require.def("one",
["require", "two"],
function(require) {
var one = {
size: "large",
doSomething: function() {
return require("two");
}
};

return one;
}
);
7 changes: 7 additions & 0 deletions test/require/data/simple.js
@@ -0,0 +1,7 @@
require.def("simple",
function() {
return {
color: "blue"
};
}
);
7 changes: 7 additions & 0 deletions test/require/data/tres.js
@@ -0,0 +1,7 @@
require.def("tres",
function() {
return {
name: "tres"
};
}
);
12 changes: 12 additions & 0 deletions test/require/data/two.js
@@ -0,0 +1,12 @@
require.def("two",
["one"],
function(one) {
return {
size: "small",
color: "redtwo",
doSomething: function() {
return require("one").doSomething();
}
};
}
);
14 changes: 14 additions & 0 deletions test/require/data/uno.js
@@ -0,0 +1,14 @@
require.def("uno",
["dos", "tres"],
function(dos, tres) {
return {
name: "uno",
doSomething: function() {
return {
dosName: dos.name,
tresName: tres.name
};
}
};
}
);
27 changes: 27 additions & 0 deletions test/require/index.html
@@ -0,0 +1,27 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr" id="html">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>jQuery+RequireJS Test Suite</title>
<link rel="Stylesheet" media="screen" href="../qunit/qunit/qunit.css" />
<link rel="Stylesheet" media="screen" href="../data/testsuite.css" />

<script src="../data/testinit.js"></script>

<script src="require.js"></script>
<script src="../../dist/jquery.js"></script>

<script src="../qunit/qunit/qunit.js"></script>
<script src="data/testrunner.js"></script>

<script src="tests.js"></script>
</head>

<body id="body">
<h1 id="qunit-header">jQuery+RequireJS Test Suite</h1>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
</body>
</html>
31 changes: 31 additions & 0 deletions test/require/readyrequire.html
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<title>requireready test</title>

<script src='../dist/jquery.js' type='text/javascript'></script>
<script type="text/javascript">
require({
baseUrl: "./data/require/"
},
["require", "simple", "dimple", "func"],
function(require, simple, dimple, func) {
console.log('Color is "blue" ? ' + simple.color);
console.log('Color is "dimple-blue" ? ' + dimple.color);
console.log('Function return is "You called a function" ? ' + func());
}
);

jQuery(function() {
console.log('Color is "dimple-blue" after ready ? ' + require("dimple").color);
});
</script>
</head>
<body>
<h1>requireready test</h1>
<p>Tests interaction between require() and jQuery.ready() to make sure
jQuery.ready() does not fire its callbacks before the modules finish loading.</p>

<p>There should be 4 console log calls.</p>
</body>
</html>

0 comments on commit 0178972

Please sign in to comment.