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...
1 parent c1cf053 commit 09ee82d84dcbea4a6e8d85903af82dcd087a78a7 @mboudreau mboudreau committed with lgalfaso Jan 15, 2015
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.