Permalink
Comparing changes
Open a pull request
- 4 commits
- 8 files changed
- 0 commit comments
- 1 contributor
Commits on Oct 12, 2016
jQuery has supported this form for a long time. As of jQuery 3.0 this form is the preferred one and all others are deprecated so jqLite(f) is now also supported. All internal invocations of jqLite(document).ready(f) (& equivalent) have been replaced by jqLite(f). Tests for these methods have been added as jqLite#ready had no explicit tests so far.
Unified
Split
Showing
with
104 additions
and 30 deletions.
- +2 −2 docs/content/guide/bootstrap.ngdoc
- +3 −4 src/angular.bind.js
- +1 −1 src/angular.suffix
- +27 −22 src/jqLite.js
- +1 −1 src/ngScenario/angular.suffix
- +13 −0 test/e2e/fixtures/ready/index.html
- +32 −0 test/e2e/fixtures/ready/script.js
- +25 −0 test/e2e/tests/ready.spec.js
| @@ -115,7 +115,7 @@ Here is an example of manually initializing Angular: | ||
| $scope.greetMe = 'World'; | ||
| }]); | ||
|
|
||
| angular.element(document).ready(function() { | ||
| angular.element(function() { | ||
| angular.bootstrap(document, ['myApp']); | ||
| }); | ||
| </script> | ||
| @@ -167,4 +167,4 @@ until `angular.resumeBootstrap()` is called. | ||
|
|
||
| `angular.resumeBootstrap()` takes an optional array of modules that | ||
| should be added to the original list of modules that the app was | ||
| about to be bootstrapped with. | ||
| about to be bootstrapped with. | ||
| @@ -1,12 +1,11 @@ | ||
| if (window.angular.bootstrap) { | ||
| //AngularJS is already loaded, so we can return here... | ||
| // AngularJS is already loaded, so we can return here... | ||
| if (window.console) { | ||
| console.log('WARNING: Tried to load angular more than once.'); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| //try to bind to jquery now so that one can write jqLite(document).ready() | ||
| //but we will rebind on bootstrap again. | ||
| // try to bind to jquery now so that one can write jqLite(fn) | ||
| // but we will rebind on bootstrap again. | ||
| bindJQuery(); | ||
|
|
| @@ -1,4 +1,4 @@ | ||
| jqLite(window.document).ready(function() { | ||
| jqLite(function() { | ||
| angularInit(window.document, bootstrap); | ||
| }); | ||
|
|
||
| @@ -56,7 +56,7 @@ | ||
| * - [`after()`](http://api.jquery.com/after/) | ||
| * - [`append()`](http://api.jquery.com/append/) | ||
| * - [`attr()`](http://api.jquery.com/attr/) - Does not support functions as parameters | ||
| * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_ - to be removed in 1.7.0, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData | ||
| * - [`bind()`](http://api.jquery.com/bind/) (_deprecated_, use [`on()`](http://api.jquery.com/on/)) - Does not support namespaces, selectors or eventData | ||
| * - [`children()`](http://api.jquery.com/children/) - Does not support selectors | ||
| * - [`clone()`](http://api.jquery.com/clone/) | ||
| * - [`contents()`](http://api.jquery.com/contents/) | ||
| @@ -76,7 +76,7 @@ | ||
| * - [`parent()`](http://api.jquery.com/parent/) - Does not support selectors | ||
| * - [`prepend()`](http://api.jquery.com/prepend/) | ||
| * - [`prop()`](http://api.jquery.com/prop/) | ||
| * - [`ready()`](http://api.jquery.com/ready/) | ||
| * - [`ready()`](http://api.jquery.com/ready/) (_deprecated_, use `angular.element(callback)` instead of `angular.element(document).ready(callback)`) | ||
| * - [`remove()`](http://api.jquery.com/remove/) | ||
| * - [`removeAttr()`](http://api.jquery.com/removeAttr/) - Does not support multiple attributes | ||
| * - [`removeClass()`](http://api.jquery.com/removeClass/) - Does not support a function as first argument | ||
| @@ -85,7 +85,7 @@ | ||
| * - [`text()`](http://api.jquery.com/text/) | ||
| * - [`toggleClass()`](http://api.jquery.com/toggleClass/) - Does not support a function as first argument | ||
| * - [`triggerHandler()`](http://api.jquery.com/triggerHandler/) - Passes a dummy event object to handlers | ||
| * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_ - to be removed in 1.7.0, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter | ||
| * - [`unbind()`](http://api.jquery.com/unbind/) (_deprecated_, use [`off()`](http://api.jquery.com/off/)) - Does not support namespaces or event object as parameter | ||
| * - [`val()`](http://api.jquery.com/val/) | ||
| * - [`wrap()`](http://api.jquery.com/wrap/) | ||
| * | ||
| @@ -288,6 +288,8 @@ function JQLite(element) { | ||
|
|
||
| if (argIsString) { | ||
| jqLiteAddNodes(this, jqLiteParseHTML(element)); | ||
| } else if (isFunction(element)) { | ||
| jqLiteReady(element); | ||
| } else { | ||
| jqLiteAddNodes(this, element); | ||
| } | ||
| @@ -519,29 +521,32 @@ function jqLiteDocumentLoaded(action, win) { | ||
| } | ||
| } | ||
|
|
||
| function jqLiteReady(fn) { | ||
| function trigger() { | ||
| window.document.removeEventListener('DOMContentLoaded', trigger); | ||
| window.removeEventListener('load', trigger); | ||
| fn(); | ||
| } | ||
|
|
||
| // check if document is already loaded | ||
| if (window.document.readyState === 'complete') { | ||
| window.setTimeout(fn); | ||
| } else { | ||
| // We can not use jqLite since we are not done loading and jQuery could be loaded later. | ||
|
|
||
| // Works for modern browsers and IE9 | ||
| window.document.addEventListener('DOMContentLoaded', trigger); | ||
|
|
||
| // Fallback to window.onload for others | ||
| window.addEventListener('load', trigger); | ||
| } | ||
| } | ||
|
|
||
| ////////////////////////////////////////// | ||
| // Functions which are declared directly. | ||
| ////////////////////////////////////////// | ||
| var JQLitePrototype = JQLite.prototype = { | ||
| ready: function(fn) { | ||
| var fired = false; | ||
|
|
||
| function trigger() { | ||
| if (fired) return; | ||
| fired = true; | ||
| fn(); | ||
| } | ||
|
|
||
| // check if document is already loaded | ||
| if (window.document.readyState === 'complete') { | ||
| window.setTimeout(trigger); | ||
| } else { | ||
| this.on('DOMContentLoaded', trigger); // works for modern browsers and IE9 | ||
| // we can not use jqLite since we are not done loading and jQuery could be loaded later. | ||
| // eslint-disable-next-line new-cap | ||
| JQLite(window).on('load', trigger); // fallback to window.onload for others | ||
| } | ||
| }, | ||
| ready: jqLiteReady, | ||
| toString: function() { | ||
| var value = []; | ||
| forEach(this, function(e) { value.push('' + e);}); | ||
| @@ -14,7 +14,7 @@ angular.forEach(script.attributes, function(attr) { | ||
| }); | ||
|
|
||
| if (config.autotest) { | ||
| JQLite(window.document).ready(function() { | ||
| JQLite(function() { | ||
| angular.scenario.setUpAndRun(config); | ||
| }); | ||
| } | ||
| @@ -0,0 +1,13 @@ | ||
| <!DOCTYPE html> | ||
| <html ng-app="test" ng-jq> | ||
| <body> | ||
| <span class="before-ready">{{beforeReady}}</span> | ||
| <span class="after-ready">{{afterReady}}</span> | ||
| <span class="after-ready-sync">{{afterReadySync}}</span> | ||
| <span class="after-ready-method">{{afterReadyMethod}}</span> | ||
| <span class="after-ready-method-sync">{{afterReadyMethodSync}}</span> | ||
| <script src="angular.js"></script> | ||
| <script src="script.js"></script> | ||
| <div id="div-after-scripts">This div is loaded after scripts.</div> | ||
| </body> | ||
| </html> |
| @@ -0,0 +1,32 @@ | ||
| 'use strict'; | ||
|
|
||
| var beforeReady; | ||
| (function() { | ||
| var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
| beforeReady = divAfterScripts && divAfterScripts.textContent; | ||
| })(); | ||
|
|
||
| var afterReady; | ||
| angular.element(function() { | ||
| var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
| afterReady = divAfterScripts && divAfterScripts.textContent; | ||
| }); | ||
|
|
||
| var afterReadyMethod; | ||
| angular.element(window.document).ready(function() { | ||
| var divAfterScripts = window.document.getElementById('div-after-scripts'); | ||
| afterReadyMethod = divAfterScripts && divAfterScripts.textContent; | ||
| }); | ||
|
|
||
| var afterReadySync = afterReady; | ||
| var afterReadyMethodSync = afterReadyMethod; | ||
|
|
||
| angular | ||
| .module('test', []) | ||
| .run(function($rootScope) { | ||
| $rootScope.beforeReady = beforeReady; | ||
| $rootScope.afterReady = afterReady; | ||
| $rootScope.afterReadySync = afterReadySync; | ||
| $rootScope.afterReadyMethod = afterReadyMethod; | ||
| $rootScope.afterReadyMethodSync = afterReadyMethodSync; | ||
| }); |
| @@ -0,0 +1,25 @@ | ||
| 'use strict'; | ||
|
|
||
| describe('Firing a callback on ready', function() { | ||
| it('should not have the div available immediately', function() { | ||
| loadFixture('ready'); | ||
| expect(element(by.className('before-ready')).getText()) | ||
| .toBe(''); | ||
| }); | ||
|
|
||
| it('should wait for document ready', function() { | ||
| loadFixture('ready'); | ||
| expect(element(by.className('after-ready')).getText()) | ||
| .toBe('This div is loaded after scripts.'); | ||
| expect(element(by.className('after-ready-method')).getText()) | ||
| .toBe('This div is loaded after scripts.'); | ||
| }); | ||
|
|
||
| it('should be asynchronous', function() { | ||
| loadFixture('ready'); | ||
| expect(element(by.className('after-ready-sync')).getText()) | ||
| .toBe(''); | ||
| expect(element(by.className('after-ready-method-sync')).getText()) | ||
| .toBe(''); | ||
| }); | ||
| }); |