angularjs-rails 1.0.6.2 → 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.1.4
2
+ * @license AngularJS v1.1.5
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -145,7 +145,8 @@ angular.module('ngCookies', ['ng']).
145
145
  * @returns {Object} Deserialized cookie value.
146
146
  */
147
147
  get: function(key) {
148
- return angular.fromJson($cookies[key]);
148
+ var value = $cookies[key];
149
+ return value ? angular.fromJson(value) : value;
149
150
  },
150
151
 
151
152
  /**
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.1.4
2
+ * @license AngularJS v1.1.5
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.1.4
2
+ * @license AngularJS v1.1.5
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  */
@@ -10,23 +10,28 @@
10
10
  * @ngdoc overview
11
11
  * @name ngMobile
12
12
  * @description
13
- */
14
-
15
- /*
16
- * Touch events and other mobile helpers by Braden Shepherdson (braden.shepherdson@gmail.com)
13
+ * Touch events and other mobile helpers.
17
14
  * Based on jQuery Mobile touch event handling (jquerymobile.com)
18
15
  */
19
16
 
20
- // define ngSanitize module and register $sanitize service
17
+ // define ngMobile module
21
18
  var ngMobile = angular.module('ngMobile', []);
22
19
 
23
20
  /**
24
21
  * @ngdoc directive
25
- * @name ngMobile.directive:ngTap
22
+ * @name ngMobile.directive:ngClick
26
23
  *
27
24
  * @description
28
- * Specify custom behavior when element is tapped on a touchscreen device.
29
- * A tap is a brief, down-and-up touch without much motion.
25
+ * A more powerful replacement for the default ngClick designed to be used on touchscreen
26
+ * devices. Most mobile browsers wait about 300ms after a tap-and-release before sending
27
+ * the click event. This version handles them immediately, and then prevents the
28
+ * following click event from propagating.
29
+ *
30
+ * This directive can fall back to using an ordinary click event, and so works on desktop
31
+ * browsers as well as mobile.
32
+ *
33
+ * This directive also sets the CSS class `ng-click-active` while the element is being held
34
+ * down (by a mouse click or touch) so you can restyle the depressed element if you wish.
30
35
  *
31
36
  * @element ANY
32
37
  * @param {expression} ngClick {@link guide/expression Expression} to evaluate
@@ -35,7 +40,7 @@ var ngMobile = angular.module('ngMobile', []);
35
40
  * @example
36
41
  <doc:example>
37
42
  <doc:source>
38
- <button ng-tap="count = count + 1" ng-init="count=0">
43
+ <button ng-click="count = count + 1" ng-init="count=0">
39
44
  Increment
40
45
  </button>
41
46
  count: {{ count }}
@@ -57,6 +62,8 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
57
62
  var MOVE_TOLERANCE = 12; // 12px seems to work in most mobile browsers.
58
63
  var PREVENT_DURATION = 2500; // 2.5 seconds maximum from preventGhostClick call to click
59
64
  var CLICKBUSTER_THRESHOLD = 25; // 25 pixels in any dimension is the limit for busting clicks.
65
+
66
+ var ACTIVE_CLASS_NAME = 'ng-click-active';
60
67
  var lastPreventedTime;
61
68
  var touchCoordinates;
62
69
 
@@ -183,7 +190,7 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
183
190
 
184
191
  // Actual linking function.
185
192
  return function(scope, element, attr) {
186
- var expressionFn = $parse(attr.ngClick),
193
+ var clickHandler = $parse(attr.ngClick),
187
194
  tapping = false,
188
195
  tapElement, // Used to blur the element after a tap.
189
196
  startTime, // Used to check if the tap was held too long.
@@ -192,6 +199,7 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
192
199
 
193
200
  function resetState() {
194
201
  tapping = false;
202
+ element.removeClass(ACTIVE_CLASS_NAME);
195
203
  }
196
204
 
197
205
  element.bind('touchstart', function(event) {
@@ -202,6 +210,8 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
202
210
  tapElement = tapElement.parentNode;
203
211
  }
204
212
 
213
+ element.addClass(ACTIVE_CLASS_NAME);
214
+
205
215
  startTime = Date.now();
206
216
 
207
217
  var touches = event.touches && event.touches.length ? event.touches : [event];
@@ -241,10 +251,11 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
241
251
 
242
252
  scope.$apply(function() {
243
253
  // TODO(braden): This is sending the touchend, not a tap or click. Is that kosher?
244
- expressionFn(scope, {$event: event});
254
+ clickHandler(scope, {$event: event});
245
255
  });
246
256
  }
247
- tapping = false;
257
+
258
+ resetState();
248
259
  });
249
260
 
250
261
  // Hack for iOS Safari's benefit. It goes searching for onclick handlers and is liable to click
@@ -256,12 +267,194 @@ ngMobile.directive('ngClick', ['$parse', '$timeout', '$rootElement',
256
267
  // desktop as well, to allow more portable sites.
257
268
  element.bind('click', function(event) {
258
269
  scope.$apply(function() {
259
- expressionFn(scope, {$event: event});
270
+ clickHandler(scope, {$event: event});
260
271
  });
261
272
  });
273
+
274
+ element.bind('mousedown', function(event) {
275
+ element.addClass(ACTIVE_CLASS_NAME);
276
+ });
277
+
278
+ element.bind('mousemove mouseup', function(event) {
279
+ element.removeClass(ACTIVE_CLASS_NAME);
280
+ });
281
+
262
282
  };
263
283
  }]);
264
284
 
285
+ /**
286
+ * @ngdoc directive
287
+ * @name ngMobile.directive:ngSwipeLeft
288
+ *
289
+ * @description
290
+ * Specify custom behavior when an element is swiped to the left on a touchscreen device.
291
+ * A leftward swipe is a quick, right-to-left slide of the finger.
292
+ * Though ngSwipeLeft is designed for touch-based devices, it will work with a mouse click and drag too.
293
+ *
294
+ * @element ANY
295
+ * @param {expression} ngSwipeLeft {@link guide/expression Expression} to evaluate
296
+ * upon left swipe. (Event object is available as `$event`)
297
+ *
298
+ * @example
299
+ <doc:example>
300
+ <doc:source>
301
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
302
+ Some list content, like an email in the inbox
303
+ </div>
304
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
305
+ <button ng-click="reply()">Reply</button>
306
+ <button ng-click="delete()">Delete</button>
307
+ </div>
308
+ </doc:source>
309
+ </doc:example>
310
+ */
311
+
312
+ /**
313
+ * @ngdoc directive
314
+ * @name ngMobile.directive:ngSwipeRight
315
+ *
316
+ * @description
317
+ * Specify custom behavior when an element is swiped to the right on a touchscreen device.
318
+ * A rightward swipe is a quick, left-to-right slide of the finger.
319
+ * Though ngSwipeRight is designed for touch-based devices, it will work with a mouse click and drag too.
320
+ *
321
+ * @element ANY
322
+ * @param {expression} ngSwipeRight {@link guide/expression Expression} to evaluate
323
+ * upon right swipe. (Event object is available as `$event`)
324
+ *
325
+ * @example
326
+ <doc:example>
327
+ <doc:source>
328
+ <div ng-show="!showActions" ng-swipe-left="showActions = true">
329
+ Some list content, like an email in the inbox
330
+ </div>
331
+ <div ng-show="showActions" ng-swipe-right="showActions = false">
332
+ <button ng-click="reply()">Reply</button>
333
+ <button ng-click="delete()">Delete</button>
334
+ </div>
335
+ </doc:source>
336
+ </doc:example>
337
+ */
338
+
339
+ function makeSwipeDirective(directiveName, direction) {
340
+ ngMobile.directive(directiveName, ['$parse', function($parse) {
341
+ // The maximum vertical delta for a swipe should be less than 75px.
342
+ var MAX_VERTICAL_DISTANCE = 75;
343
+ // Vertical distance should not be more than a fraction of the horizontal distance.
344
+ var MAX_VERTICAL_RATIO = 0.3;
345
+ // At least a 30px lateral motion is necessary for a swipe.
346
+ var MIN_HORIZONTAL_DISTANCE = 30;
347
+ // The total distance in any direction before we make the call on swipe vs. scroll.
348
+ var MOVE_BUFFER_RADIUS = 10;
349
+
350
+ function getCoordinates(event) {
351
+ var touches = event.touches && event.touches.length ? event.touches : [event];
352
+ var e = (event.changedTouches && event.changedTouches[0]) ||
353
+ (event.originalEvent && event.originalEvent.changedTouches &&
354
+ event.originalEvent.changedTouches[0]) ||
355
+ touches[0].originalEvent || touches[0];
356
+
357
+ return {
358
+ x: e.clientX,
359
+ y: e.clientY
360
+ };
361
+ }
362
+
363
+ return function(scope, element, attr) {
364
+ var swipeHandler = $parse(attr[directiveName]);
365
+ var startCoords, valid;
366
+ var totalX, totalY;
367
+ var lastX, lastY;
368
+
369
+ function validSwipe(event) {
370
+ // Check that it's within the coordinates.
371
+ // Absolute vertical distance must be within tolerances.
372
+ // Horizontal distance, we take the current X - the starting X.
373
+ // This is negative for leftward swipes and positive for rightward swipes.
374
+ // After multiplying by the direction (-1 for left, +1 for right), legal swipes
375
+ // (ie. same direction as the directive wants) will have a positive delta and
376
+ // illegal ones a negative delta.
377
+ // Therefore this delta must be positive, and larger than the minimum.
378
+ if (!startCoords) return false;
379
+ var coords = getCoordinates(event);
380
+ var deltaY = Math.abs(coords.y - startCoords.y);
381
+ var deltaX = (coords.x - startCoords.x) * direction;
382
+ return valid && // Short circuit for already-invalidated swipes.
383
+ deltaY < MAX_VERTICAL_DISTANCE &&
384
+ deltaX > 0 &&
385
+ deltaX > MIN_HORIZONTAL_DISTANCE &&
386
+ deltaY / deltaX < MAX_VERTICAL_RATIO;
387
+ }
388
+
389
+ element.bind('touchstart mousedown', function(event) {
390
+ startCoords = getCoordinates(event);
391
+ valid = true;
392
+ totalX = 0;
393
+ totalY = 0;
394
+ lastX = startCoords.x;
395
+ lastY = startCoords.y;
396
+ });
397
+
398
+ element.bind('touchcancel', function(event) {
399
+ valid = false;
400
+ });
401
+
402
+ element.bind('touchmove mousemove', function(event) {
403
+ if (!valid) return;
404
+
405
+ // Android will send a touchcancel if it thinks we're starting to scroll.
406
+ // So when the total distance (+ or - or both) exceeds 10px in either direction,
407
+ // we either:
408
+ // - On totalX > totalY, we send preventDefault() and treat this as a swipe.
409
+ // - On totalY > totalX, we let the browser handle it as a scroll.
410
+
411
+ // Invalidate a touch while it's in progress if it strays too far away vertically.
412
+ // We don't want a scroll down and back up while drifting sideways to be a swipe just
413
+ // because you happened to end up vertically close in the end.
414
+ if (!startCoords) return;
415
+ var coords = getCoordinates(event);
416
+
417
+ if (Math.abs(coords.y - startCoords.y) > MAX_VERTICAL_DISTANCE) {
418
+ valid = false;
419
+ return;
420
+ }
421
+
422
+ totalX += Math.abs(coords.x - lastX);
423
+ totalY += Math.abs(coords.y - lastY);
424
+
425
+ lastX = coords.x;
426
+ lastY = coords.y;
427
+
428
+ if (totalX < MOVE_BUFFER_RADIUS && totalY < MOVE_BUFFER_RADIUS) {
429
+ return;
430
+ }
431
+
432
+ // One of totalX or totalY has exceeded the buffer, so decide on swipe vs. scroll.
433
+ if (totalY > totalX) {
434
+ valid = false;
435
+ return;
436
+ } else {
437
+ event.preventDefault();
438
+ }
439
+ });
440
+
441
+ element.bind('touchend mouseup', function(event) {
442
+ if (validSwipe(event)) {
443
+ // Prevent this swipe from bubbling up to any other elements with ngSwipes.
444
+ event.stopPropagation();
445
+ scope.$apply(function() {
446
+ swipeHandler(scope, {$event:event});
447
+ });
448
+ }
449
+ });
450
+ };
451
+ }]);
452
+ }
453
+
454
+ // Left is negative X-coordinate, right is positive.
455
+ makeSwipeDirective('ngSwipeLeft', -1);
456
+ makeSwipeDirective('ngSwipeRight', 1);
457
+
265
458
 
266
459
 
267
460
  })(window, window.angular);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license AngularJS v1.1.4
2
+ * @license AngularJS v1.1.5
3
3
  * (c) 2010-2012 Google, Inc. http://angularjs.org
4
4
  * License: MIT
5
5
  *
@@ -241,7 +241,7 @@ angular.mock.$ExceptionHandlerProvider = function() {
241
241
  *
242
242
  * @param {string} mode Mode of operation, defaults to `rethrow`.
243
243
  *
244
- * - `rethrow`: If any errors are are passed into the handler in tests, it typically
244
+ * - `rethrow`: If any errors are passed into the handler in tests, it typically
245
245
  * means that there is a bug in the application or test, so this mock will
246
246
  * make these tests fail.
247
247
  * - `log`: Sometimes it is desirable to test that an error is thrown, for this case the `log` mode stores an
@@ -322,7 +322,13 @@ angular.mock.$LogProvider = function() {
322
322
  * @propertyOf ngMock.$log
323
323
  *
324
324
  * @description
325
- * Array of logged messages.
325
+ * Array of messages logged using {@link ngMock.$log#log}.
326
+ *
327
+ * @example
328
+ * <pre>
329
+ * $log.log('Some Log');
330
+ * var first = $log.log.logs.unshift();
331
+ * </pre>
326
332
  */
327
333
  $log.log.logs = [];
328
334
  /**
@@ -331,7 +337,13 @@ angular.mock.$LogProvider = function() {
331
337
  * @propertyOf ngMock.$log
332
338
  *
333
339
  * @description
334
- * Array of logged messages.
340
+ * Array of messages logged using {@link ngMock.$log#warn}.
341
+ *
342
+ * @example
343
+ * <pre>
344
+ * $log.warn('Some Warning');
345
+ * var first = $log.warn.logs.unshift();
346
+ * </pre>
335
347
  */
336
348
  $log.warn.logs = [];
337
349
  /**
@@ -340,7 +352,13 @@ angular.mock.$LogProvider = function() {
340
352
  * @propertyOf ngMock.$log
341
353
  *
342
354
  * @description
343
- * Array of logged messages.
355
+ * Array of messages logged using {@link ngMock.$log#info}.
356
+ *
357
+ * @example
358
+ * <pre>
359
+ * $log.info('Some Info');
360
+ * var first = $log.info.logs.unshift();
361
+ * </pre>
344
362
  */
345
363
  $log.info.logs = [];
346
364
  /**
@@ -349,7 +367,13 @@ angular.mock.$LogProvider = function() {
349
367
  * @propertyOf ngMock.$log
350
368
  *
351
369
  * @description
352
- * Array of logged messages.
370
+ * Array of messages logged using {@link ngMock.$log#error}.
371
+ *
372
+ * @example
373
+ * <pre>
374
+ * $log.log('Some Error');
375
+ * var first = $log.error.logs.unshift();
376
+ * </pre>
353
377
  */
354
378
  $log.error.logs = [];
355
379
  };
@@ -628,7 +652,9 @@ angular.mock.createMockWindow = function() {
628
652
  if (setTimeoutQueue.length > 0) {
629
653
  return {
630
654
  process: function() {
631
- setTimeoutQueue.shift().fn();
655
+ var tick = setTimeoutQueue.shift();
656
+ expect(tick.delay).toEqual(delay);
657
+ tick.fn();
632
658
  }
633
659
  };
634
660
  } else {
@@ -709,10 +735,10 @@ angular.mock.dump = function(object) {
709
735
  * @ngdoc object
710
736
  * @name ngMock.$httpBackend
711
737
  * @description
712
- * Fake HTTP backend implementation suitable for unit testing application that use the
738
+ * Fake HTTP backend implementation suitable for unit testing applications that use the
713
739
  * {@link ng.$http $http service}.
714
740
  *
715
- * *Note*: For fake http backend implementation suitable for end-to-end testing or backend-less
741
+ * *Note*: For fake HTTP backend implementation suitable for end-to-end testing or backend-less
716
742
  * development please see {@link ngMockE2E.$httpBackend e2e $httpBackend mock}.
717
743
  *
718
744
  * During unit testing, we want our unit tests to run quickly and have no external dependencies so
@@ -911,7 +937,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
911
937
  }
912
938
 
913
939
  // TODO(vojta): change params to: method, url, data, headers, callback
914
- function $httpBackend(method, url, data, callback, headers) {
940
+ function $httpBackend(method, url, data, callback, headers, timeout) {
915
941
  var xhr = new MockXhr(),
916
942
  expectation = expectations[0],
917
943
  wasExpected = false;
@@ -922,6 +948,28 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
922
948
  : angular.toJson(data);
923
949
  }
924
950
 
951
+ function wrapResponse(wrapped) {
952
+ if (!$browser && timeout && timeout.then) timeout.then(handleTimeout);
953
+
954
+ return handleResponse;
955
+
956
+ function handleResponse() {
957
+ var response = wrapped.response(method, url, data, headers);
958
+ xhr.$$respHeaders = response[2];
959
+ callback(response[0], response[1], xhr.getAllResponseHeaders());
960
+ }
961
+
962
+ function handleTimeout() {
963
+ for (var i = 0, ii = responses.length; i < ii; i++) {
964
+ if (responses[i] === handleResponse) {
965
+ responses.splice(i, 1);
966
+ callback(-1, undefined, '');
967
+ break;
968
+ }
969
+ }
970
+ }
971
+ }
972
+
925
973
  if (expectation && expectation.match(method, url)) {
926
974
  if (!expectation.matchData(data))
927
975
  throw Error('Expected ' + expectation + ' with different data\n' +
@@ -935,11 +983,7 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
935
983
  expectations.shift();
936
984
 
937
985
  if (expectation.response) {
938
- responses.push(function() {
939
- var response = expectation.response(method, url, data, headers);
940
- xhr.$$respHeaders = response[2];
941
- callback(response[0], response[1], xhr.getAllResponseHeaders());
942
- });
986
+ responses.push(wrapResponse(expectation));
943
987
  return;
944
988
  }
945
989
  wasExpected = true;
@@ -950,13 +994,9 @@ function createHttpBackendMock($rootScope, $delegate, $browser) {
950
994
  if (definition.match(method, url, data, headers || {})) {
951
995
  if (definition.response) {
952
996
  // if $browser specified, we do auto flush all requests
953
- ($browser ? $browser.defer : responsesPush)(function() {
954
- var response = definition.response(method, url, data, headers);
955
- xhr.$$respHeaders = response[2];
956
- callback(response[0], response[1], xhr.getAllResponseHeaders());
957
- });
997
+ ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
958
998
  } else if (definition.passThrough) {
959
- $delegate(method, url, data, callback, headers);
999
+ $delegate(method, url, data, callback, headers, timeout);
960
1000
  } else throw Error('No response defined !');
961
1001
  return;
962
1002
  }