aboutsummaryrefslogtreecommitdiffstats
path: root/src/service/cookies.js
blob: 16e1484756023e9c7fb6f4b6062038cfe9884c5a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'use strict';

/**
 * @ngdoc service
 * @name angular.service.$cookies
 * @requires $browser
 *
 * @description
 * Provides read/write access to browser's cookies.
 *
 * Only a simple Object is exposed and by adding or removing properties to/from
 * this object, new cookies are created/deleted at the end of current $eval.
 *
 * @example
 */
function $CookiesProvider() {
  this.$get = ['$rootScope', '$browser', function ($rootScope, $browser) {
    var cookies = {},
        lastCookies = {},
        lastBrowserCookies,
        runEval = false;

    //creates a poller fn that copies all cookies from the $browser to service & inits the service
    $browser.addPollFn(function() {
      var currentCookies = $browser.cookies();
      if (lastBrowserCookies != currentCookies) { //relies on browser.cookies() impl
        lastBrowserCookies = currentCookies;
        copy(currentCookies, lastCookies);
        copy(currentCookies, cookies);
        if (runEval) $rootScope.$apply();
      }
    })();

    runEval = true;

    //at the end of each eval, push cookies
    //TODO: this should happen before the "delayed" watches fire, because if some cookies are not
    //      strings or browser refuses to store some cookies, we update the model in the push fn.
    $rootScope.$watch(push);

    return cookies;


    /**
     * Pushes all the cookies from the service to the browser and verifies if all cookies were stored.
     */
    function push() {
      var name,
          value,
          browserCookies,
          updated;

      //delete any cookies deleted in $cookies
      for (name in lastCookies) {
        if (isUndefined(cookies[name])) {
          $browser.cookies(name, undefined);
        }
      }

      //update all cookies updated in $cookies
      for(name in cookies) {
        value = cookies[name];
        if (!isString(value)) {
          if (isDefined(lastCookies[name])) {
            cookies[name] = lastCookies[name];
          } else {
            delete cookies[name];
          }
        } else if (value !== lastCookies[name]) {
          $browser.cookies(name, value);
          updated = true;
        }
      }

      //verify what was actually stored
      if (updated){
        updated = false;
        browserCookies = $browser.cookies();

        for (name in cookies) {
          if (cookies[name] !== browserCookies[name]) {
            //delete or reset all cookies that the browser dropped from $cookies
            if (isUndefined(browserCookies[name])) {
              delete cookies[name];
            } else {
              cookies[name] = browserCookies[name];
            }
            updated = true;
          }
        }
      }
    }
  }];
}