Permalink
Browse files

feat(ng-jq): adds the ability to force jqLite or a specific jQuery ve…

…rsion

Adds the ability to specify that jqLite should be used or to use a specific jQuery version
  • Loading branch information...
mboudreau authored and lgalfaso committed Jan 15, 2015
1 parent c1cf053 commit 09ee82d84dcbea4a6e8d85903af82dcd087a78a7
Showing with 150 additions and 1 deletion.
  1. +61 −1 src/Angular.js
  2. +1 −0 test/.jshintrc
  3. +88 −0 test/AngularSpec.js
View
@@ -58,6 +58,7 @@
shallowCopy: true,
equals: true,
csp: true,
jq: true,
concat: true,
sliceArgs: true,
bind: true,
@@ -901,7 +902,61 @@ var csp = function() {
return (csp.isActive_ = active);
};
/**
* @ngdoc directive
* @module ng
* @name ngJq
*
* @element ANY
* @param {string=} the name of the library available under `window`
* to be used for angular.element
* @description
* Use this directive to force the angular.element library. This should be
* used to force either jqLite by leaving ng-jq blank or setting the name of
* the jquery variable under window (eg. jQuery).
*
* Since this directive is global for the angular library, it is recommended
* that it's added to the same element as ng-app or the HTML element, but it is not mandatory.
* It needs to be noted that only the first instance of `ng-jq` will be used and all others
* ignored.
*
* @example
* This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
```html
<!doctype html>
<html ng-app ng-jq>
...
...
</html>
```
* @example
* This example shows how to use a jQuery based library of a different name.
* The library name must be available at the top most 'window'.
```html
<!doctype html>
<html ng-app ng-jq="jQueryLib">
...
...
</html>
```
*/
var jq = function() {
if (isDefined(jq.name_)) return jq.name_;
var el;
var i, ii = ngAttrPrefixes.length;
for (i = 0; i < ii; ++i) {
if (el = document.querySelector('[' + ngAttrPrefixes[i].replace(':', '\\:') + 'jq]')) {
break;
}
}
var name;
if (el) {
name = getNgAttribute(el, "jq");
}
return (jq.name_ = name);
};
function concat(array1, array2, index) {
return array1.concat(slice.call(array2, index));
@@ -1474,7 +1529,12 @@ function bindJQuery() {
}
// bind to jQuery if present;
jQuery = window.jQuery;
var jqName = jq();
jQuery = window.jQuery; // use default jQuery.
if (isDefined(jqName)) { // `ngJq` present
jQuery = jqName === null ? undefined : window[jqName]; // if empty; use jqLite. if not empty, use jQuery specified by `ngJq`.
}
// Use jQuery if it exists with proper functionality, otherwise default to us.
// Angular 1.2+ requires jQuery 1.7+ for on()/off() support.
// Angular 1.3+ technically requires at least jQuery 2.1+ but it may work with older
View
@@ -60,6 +60,7 @@
"shallowCopy": false,
"equals": false,
"csp": false,
"jq": false,
"concat": false,
"sliceArgs": false,
"bind": false,
View
@@ -615,6 +615,94 @@ describe('angular', function() {
});
describe('jq', function() {
var element;
beforeEach(function() {
element = document.createElement('html');
});
afterEach(function() {
delete jq.name_;
});
it('should return undefined when jq is not set, no jQuery found (the default)', function() {
expect(jq()).toBe(undefined);
});
it('should return empty string when jq is enabled manually via [ng-jq] with empty string', function() {
element.setAttribute('ng-jq', '');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[ng-jq]') return element;
});
expect(jq()).toBe('');
});
it('should return empty string when jq is enabled manually via [data-ng-jq] with empty string', function() {
element.setAttribute('data-ng-jq', '');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[data-ng-jq]') return element;
});
expect(jq()).toBe('');
expect(document.querySelector).toHaveBeenCalledWith('[data-ng-jq]');
});
it('should return empty string when jq is enabled manually via [x-ng-jq] with empty string', function() {
element.setAttribute('x-ng-jq', '');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[x-ng-jq]') return element;
});
expect(jq()).toBe('');
expect(document.querySelector).toHaveBeenCalledWith('[x-ng-jq]');
});
it('should return empty string when jq is enabled manually via [ng:jq] with empty string', function() {
element.setAttribute('ng:jq', '');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[ng\\:jq]') return element;
});
expect(jq()).toBe('');
expect(document.querySelector).toHaveBeenCalledWith('[ng\\:jq]');
});
it('should return "jQuery" when jq is enabled manually via [ng-jq] with value "jQuery"', function() {
element.setAttribute('ng-jq', 'jQuery');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[ng-jq]') return element;
});
expect(jq()).toBe('jQuery');
expect(document.querySelector).toHaveBeenCalledWith('[ng-jq]');
});
it('should return "jQuery" when jq is enabled manually via [data-ng-jq] with value "jQuery"', function() {
element.setAttribute('data-ng-jq', 'jQuery');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[data-ng-jq]') return element;
});
expect(jq()).toBe('jQuery');
expect(document.querySelector).toHaveBeenCalledWith('[data-ng-jq]');
});
it('should return "jQuery" when jq is enabled manually via [x-ng-jq] with value "jQuery"', function() {
element.setAttribute('x-ng-jq', 'jQuery');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[x-ng-jq]') return element;
});
expect(jq()).toBe('jQuery');
expect(document.querySelector).toHaveBeenCalledWith('[x-ng-jq]');
});
it('should return "jQuery" when jq is enabled manually via [ng:jq] with value "jQuery"', function() {
element.setAttribute('ng:jq', 'jQuery');
spyOn(document, 'querySelector').andCallFake(function(selector) {
if (selector === '[ng\\:jq]') return element;
});
expect(jq()).toBe('jQuery');
expect(document.querySelector).toHaveBeenCalledWith('[ng\\:jq]');
});
});
describe('parseKeyValue', function() {
it('should parse a string into key-value pairs', function() {
expect(parseKeyValue('')).toEqual({});

0 comments on commit 09ee82d

Please sign in to comment.