~vono22/cookiekeeper/1.9.0

« back to all changes in this revision

Viewing changes to cookiekeeper/chrome/content/cookiekeeper.observer.js

  • Committer: Yvon TANGUY
  • Date: 2014-01-23 12:08:35 UTC
  • Revision ID: vono@vono.zsh.jp-20140123120835-btzrqyhypbvf3nll
initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 *
 
3
 * This Source Code Form is subject to the terms of the Mozilla Public
 
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
6
 *
 
7
 * ***** END LICENSE BLOCK ***** */
 
8
 
 
9
/*----------------------
 
10
 CookieKeeper 1.5.0
 
11
 Yvon Tanguy
 
12
 Original code from Mozilla Firefox v24.0
 
13
 Entirely re-written.
 
14
 
 
15
 CookieCuller 1.4.0
 
16
 Dan Yamaoka
 
17
 Original CookieManager code is from Mozilla Firefox v0.8, CookieViewer.js
 
18
 Modified original code is commented with "//DY" (I hope)
 
19
 
 
20
 History:
 
21
 1.00 Original release for Firefox v0.8
 
22
 1.01 No code changed
 
23
 1.02 Updated for Firefox v0.9:removed cookie Policy & Status props,changed Secure strings
 
24
 1.1.0 New code for deleting unprotected cookies at browser startup
 
25
 1.2.0 Updated Tree code for Mozilla 1.8 Trunk Code Support
 
26
 1.5.0 Rewrite for mozilla 24 support, resync code with the Firefox one.
 
27
 ----------------------*/
 
28
 
 
29
 
 
30
gCookieKeeper._blockDeleteEvent = false;
 
31
 
 
32
gCookieKeeper.observe = function(aCookie, aTopic, aData) {
 
33
 
 
34
  if (aTopic == OBS_PCOOKIE_TOPIC) {
 
35
    // somewhat a strange object: wrappedJSObject ...
 
36
    this.onProtCookieRemove(aCookie.wrappedJSObject.pcookie);
 
37
    return;
 
38
  }
 
39
 
 
40
  if (aTopic != "cookie-changed") {
 
41
    return;
 
42
  }
 
43
 
 
44
  if (aCookie instanceof Ci.nsICookie2) {
 
45
    var strippedHost = this._makeStrippedHost(aCookie.host);
 
46
    if (aData == "changed") {
 
47
      this._handleCookieChanged(aCookie, strippedHost);
 
48
    } else if (aData == "added") {
 
49
      this._handleCookieAdded(aCookie, strippedHost);
 
50
    } else if (aData == "deleted" && !this._blockDeleteEvent) {
 
51
      this._handleCookieDeleted(aCookie, strippedHost);
 
52
    }
 
53
  } else if (aData == "cleared") {
 
54
    this._hosts = {};
 
55
    this._hostOrder = [];
 
56
 
 
57
    this._view.rowCount = 0;
 
58
    this._view.selection.clearSelection();
 
59
    this._updateButtons();
 
60
  } else if (aData == "reload") {
 
61
    // first, clear any existing entries
 
62
    this.observe(aCookie, aTopic, "cleared");
 
63
 
 
64
    // then, reload the list
 
65
    this._populateList(false);
 
66
  }
 
67
}
 
68
 
 
69
gCookieKeeper._handleCookieChanged = function(changedCookie, strippedHost) {
 
70
  var rowIndex = -1;
 
71
  var cookieItem = null;
 
72
  if (this._view.mode == VIEW_TREE) {
 
73
    for (let i = 0; i < this._hostOrder.length; i++) {
 
74
      rowIndex++;
 
75
      var hostItem = this._hosts[this._hostOrder[i]];
 
76
      if (this._hostOrder[i] == strippedHost) {
 
77
        // Host matches, look for the cookie within this Host collection
 
78
        // and update its data
 
79
        for (let j = 0; j < hostItem.cookies.length; j++) {
 
80
          rowIndex++;
 
81
          var currCookie = hostItem.cookies[j];
 
82
          if (this._cookieEquals(currCookie, changedCookie, strippedHost)) {
 
83
            currCookie.value    = changedCookie.value;
 
84
            currCookie.isSecure = changedCookie.isSecure;
 
85
            currCookie.isDomain = changedCookie.isDomain;
 
86
            currCookie.expires  = changedCookie.expires;
 
87
            cookieItem = currCookie;
 
88
            break;
 
89
          }
 
90
        }
 
91
      } else if (hostItem.open) {
 
92
        rowIndex += hostItem.cookies.length;
 
93
      }
 
94
    }
 
95
  } else {
 
96
    // Just walk the filter list to find the item. It doesn't matter that
 
97
    // we don't update the main Host collection when we do this, because
 
98
    // when the filter is reset the Host collection is rebuilt anyway.
 
99
    for (rowIndex = 0; rowIndex < this._view._flatSet.length; rowIndex++) {
 
100
      currCookie = this._view._flatSet[rowIndex];
 
101
      if (this._cookieEquals(currCookie, changedCookie, strippedHost)) {
 
102
        currCookie.value    = changedCookie.value;
 
103
        currCookie.isSecure = changedCookie.isSecure;
 
104
        currCookie.isDomain = changedCookie.isDomain;
 
105
        currCookie.expires  = changedCookie.expires;
 
106
        cookieItem = currCookie;
 
107
        break;
 
108
      }
 
109
    }
 
110
  }
 
111
 
 
112
  // Make sure the tree display is up to date...
 
113
  this._tree.treeBoxObject.invalidateRow(rowIndex);
 
114
  // ... and if the cookie is selected, update the displayed metadata too
 
115
  if (cookieItem != null && this._view.selection.currentIndex == rowIndex) {
 
116
    this._updateCookieData();
 
117
  }
 
118
}
 
119
 
 
120
gCookieKeeper._handleCookieAdded = function(addedCookie, strippedHost) {
 
121
  var rowCountImpact = 0;
 
122
  var addedHost = { value: 0 };
 
123
  var cookie = this._addCookie(strippedHost, addedCookie, addedHost, false);
 
124
  if (this._view.mode == VIEW_TREE) {
 
125
    // The Host collection for this cookie already exists, and it's not open,
 
126
    // so don't increment the rowCountImpact becaues the user is not going to
 
127
    // see the additional rows as they're hidden.
 
128
    if (addedHost.value || this._hosts[strippedHost].open) {
 
129
      rowCountImpact++;
 
130
    }
 
131
  } else if (this._view.mode == VIEW_FLAT || this._cookieMatchesFilter(cookie)) {
 
132
    rowCountImpact++;
 
133
    this._view._flatSet.push(cookie);
 
134
  }
 
135
 
 
136
  if (rowCountImpact > 0) {
 
137
    // Now update the tree display at the end
 
138
    var oldRowCount = this._rowCount;
 
139
    this._view._rowCount += rowCountImpact;
 
140
    this._tree.treeBoxObject.rowCountChanged(oldRowCount - 1, rowCountImpact);
 
141
    // Sort the list
 
142
    this._lastSortAscending = !this._lastSortAscending;
 
143
    this.sort(this._lastSortProperty);
 
144
    // Update buttons status
 
145
    this._updateButtons();
 
146
  }
 
147
}
 
148
 
 
149
gCookieKeeper._handleCookieDeleted = function(aCookie, strippedHost) {
 
150
  // Search for the cookie:
 
151
  var currHost = this._hosts[strippedHost];
 
152
  if (typeof(currHost) == "undefined" || currHost == null) {
 
153
    log.e("_handleCookieDeleted: Cookie host " + strippedHost + " not found");
 
154
    return;
 
155
  }
 
156
  var cookie  = null;
 
157
  var cCookie = 0;
 
158
  const nCookies = currHost.cookies.length;
 
159
  for (; cCookie<nCookies; cCookie++) {
 
160
    var c = currHost.cookies[cCookie];
 
161
    if (c != null && c.host == aCookie.host && c.name == aCookie.name && c.path == aCookie.path) {
 
162
      cookie = c;
 
163
      break;
 
164
    }
 
165
  }
 
166
 
 
167
  if (cookie == null) {
 
168
    log.e("_handleCookieDeleted: Cookie not found: " + aCookie.host + ":" + aCookie.name);
 
169
    return;
 
170
  }
 
171
  const cookieViewIndex = this._view._getIndexOfItem(cookie);
 
172
 
 
173
  var idxHO = -1;
 
174
  if (nCookies == 1) {
 
175
    // Remote the host from _hostOrder
 
176
    idxHO = this._hostOrder.indexOf(strippedHost);
 
177
    if (idxHO > -1) {
 
178
      this._hostOrder.splice(idxHO, 1);
 
179
    } // else it is an error
 
180
    // Remove the host from the _hosts list
 
181
    delete this._hosts[strippedHost];
 
182
  } else {
 
183
    currHost.cookies.splice(cCookie, 1);
 
184
  }
 
185
 
 
186
  var tbo = this._tree.treeBoxObject;
 
187
  var seln = this._view.selection;
 
188
  const curSelIndex = seln.currentIndex;
 
189
 
 
190
  switch (this._view.mode) {
 
191
  case VIEW_TREE:
 
192
    // log.d("idxHO=" + idxHO);
 
193
    // log.d("cookieViewIndex=" + cookieViewIndex);
 
194
    if (cookieViewIndex == -1 && idxHO == -1) {
 
195
      // not displayed
 
196
      return;
 
197
    }
 
198
    this._blockSelectEvent++;
 
199
    // TODO: a more fine update?
 
200
    var rowCountImpact = 0;
 
201
    var rowCount = this._view.rowCount;
 
202
 
 
203
    if (currHost.open) {
 
204
      rowCountImpact--;
 
205
    }
 
206
    if (idxHO > -1) {
 
207
      rowCountImpact--;
 
208
    }
 
209
    // log.d("rowCountImpact=" + rowCountImpact);
 
210
 
 
211
    if (rowCountImpact != 0) {
 
212
      rowCount += rowCountImpact;
 
213
      this._view.rowCount = rowCount;
 
214
      // Update selection:
 
215
      seln.clearSelection();
 
216
      this._view._invalidateCache(0);
 
217
      tbo.invalidate();
 
218
      this._blockSelectEvent--;
 
219
 
 
220
      var newSelIndex = curSelIndex;
 
221
      if (cookieViewIndex != curSelIndex) {
 
222
        // The host is selected, not the cookie itself
 
223
      } else if (!currHost.open || (currHost.open && (nCookies == 1 || (nCookies > 1 && cCookie == (nCookies - 1))))) {
 
224
        // very complicated if ...
 
225
        newSelIndex--;
 
226
      }
 
227
 
 
228
      // Check limits:
 
229
      newSelIndex = (newSelIndex >= rowCount) ? rowCount - 1 : newSelIndex;
 
230
      newSelIndex = (newSelIndex < 0) ? 0 : newSelIndex;
 
231
      log.d("curSelIndex=" + curSelIndex + " newSelIndex=" + newSelIndex + " cookieViewIndex=" + cookieViewIndex);
 
232
      if (rowCount >= 0) {
 
233
        seln.select(newSelIndex);
 
234
        tbo.ensureRowIsVisible(newSelIndex);
 
235
      }
 
236
    } else {
 
237
      this._blockSelectEvent--;
 
238
    }
 
239
    break;
 
240
  case VIEW_FILTER:
 
241
    if (!this._cookieMatchesFilter(cookie)) {
 
242
      // not displayed
 
243
      break;
 
244
    }
 
245
    // pass through
 
246
  case VIEW_FLAT:
 
247
    this._blockSelectEvent++;
 
248
 
 
249
    this._view._flatSet.splice(cookieViewIndex, 1);
 
250
    this._view._rowCount--;
 
251
    tbo.invalidateRow(cookieViewIndex);
 
252
    tbo.rowCountChanged(cookieViewIndex, -1);
 
253
 
 
254
    // Update selection
 
255
    if (curSelIndex >= cookieViewIndex) {
 
256
      seln.clearSelection();
 
257
      this._blockSelectEvent--;
 
258
      if (curSelIndex >= this._view._flatSet.length) {
 
259
        seln.select(curSelIndex - 1);
 
260
      } else {
 
261
        seln.select(curSelIndex);
 
262
      }
 
263
    } else {
 
264
      this._blockSelectEvent--;
 
265
    }
 
266
    break;
 
267
  }
 
268
}
 
269
 
 
270
gCookieKeeper.onProtCookieRemove = function(pCookie) {
 
271
  // Call from gCookieKeeperProtCookiesPrefs.remove()
 
272
  if (!pCookie) {
 
273
    return;
 
274
  }
 
275
  var strippedHost = this._makeStrippedHost(pCookie.host);
 
276
  var host = this._hosts[strippedHost];
 
277
  if (typeof(host) != "undefined") {
 
278
    const nCookies = host.cookies.length;
 
279
    for (let i=0; i<nCookies; i++) {
 
280
      var cookie = host.cookies[i];
 
281
      if (cookie.host == pCookie.host && cookie.name == pCookie.name && cookie.path == pCookie.path) {
 
282
        cookie.isProtected = false;
 
283
 
 
284
        // Update ui:
 
285
        var index = this._view._getIndexOfItem(cookie);
 
286
        if (index > -1) {
 
287
          this._tree.treeBoxObject.invalidateRow(index);
 
288
          if (this._view.selection.currentIndex == index) {
 
289
            this.onCookieSelected();
 
290
          }
 
291
        }
 
292
        i = nCookies;
 
293
      }
 
294
    }
 
295
  }
 
296
}