angularjs-rails 1.0.6.2 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
  }