~ubuntu-branches/ubuntu/natty/adblock-plus/natty

« back to all changes in this revision

Viewing changes to chrome/content/ui/sidebar.js

  • Committer: Bazaar Package Importer
  • Author(s): Benjamin Drung
  • Date: 2010-11-05 18:42:36 UTC
  • mto: (25.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 27.
  • Revision ID: james.westby@ubuntu.com-20101105184236-h7dnu8mbfjaoya62
Tags: upstream-1.3.1
ImportĀ upstreamĀ versionĀ 1.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 *
23
23
 * ***** END LICENSE BLOCK ***** */
24
24
 
25
 
var effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
26
 
var RequestList = abp.RequestList;
 
25
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
27
26
 
28
27
// Main browser window
29
28
var mainWin = parent;
30
29
 
31
30
// The window handler currently in use
32
 
var wndData = null;
 
31
var requestNotifier = null;
33
32
 
34
33
var cacheSession = null;
35
34
var noFlash = false;
36
35
 
37
 
// Matchers for disabled filters
38
 
var disabledBlacklistMatcher = new abp.Matcher();
39
 
var disabledWhitelistMatcher = new abp.Matcher();
 
36
// Matcher for disabled filters
 
37
var disabledMatcher = new CombinedMatcher();
 
38
 
 
39
// Cached string values
 
40
var docDomainThirdParty = null;
 
41
var docDomainFirstParty = null;
40
42
 
41
43
var abpHooks = null;
42
44
 
43
 
/**
44
 
 * Cached value of "enabled" preference, for onPrefChange.
45
 
 */
46
 
var oldEnabled = abp.prefs.enabled;
 
45
let lastSelectionProp = "abpSelected" + RequestNotifier.getDataSeed();
47
46
 
48
47
function init() {
 
48
  docDomainThirdParty = document.documentElement.getAttribute("docDomainThirdParty");
 
49
  docDomainFirstParty = document.documentElement.getAttribute("docDomainFirstParty");
 
50
 
49
51
  var list = E("list");
50
52
  list.view = treeView;
51
53
 
52
54
  // Restore previous state
53
 
  var params = abp.getParams();
 
55
  var params = Utils.getParams();
54
56
  if (params && params.filter)
55
57
  {
56
58
    E("searchField").value = params.filter;
88
90
  abpHooks = mainWin.document.getElementById("abp-hooks");
89
91
  window.__defineGetter__("content", function() {return abpHooks.getBrowser().contentWindow;});
90
92
 
91
 
  // Install item listener
92
 
  RequestList.addListener(handleItemChange);
93
 
 
94
 
  // Initialize matchers for disabled filters
 
93
  // Initialize matcher for disabled filters
95
94
  reloadDisabledFilters();
96
 
  filterStorage.addFilterObserver(reloadDisabledFilters);
97
 
  filterStorage.addSubscriptionObserver(reloadDisabledFilters);
98
 
  abp.prefs.addListener(onPrefChange);
 
95
  FilterStorage.addFilterObserver(reloadDisabledFilters);
 
96
  FilterStorage.addSubscriptionObserver(reloadDisabledFilters);
 
97
  Prefs.addListener(onPrefChange);
99
98
 
100
99
  // Activate flasher
101
100
  list.addEventListener("select", onSelectionChange, false);
102
101
 
103
 
  // Retrieve data for the window
104
 
  wndData = RequestList.getDataForWindow(window.content);
105
 
  treeView.setData(wndData.getAllLocations());
106
 
  if (wndData.lastSelection) {
107
 
    noFlash = true;
108
 
    treeView.selectItem(wndData.lastSelection);
109
 
    noFlash = false;
110
 
  }
 
102
  // Initialize data
 
103
  handleLocationChange();
111
104
 
112
 
  // Install a handler for tab changes
113
 
  abpHooks.getBrowser().addEventListener("select", handleTabChange, false);
 
105
  // Install a progress listener to catch location changes
 
106
  abpHooks.getBrowser().addProgressListener(progressListener);
114
107
}
115
108
 
116
109
// To be called for a detached window when the main window has been closed
120
113
 
121
114
// To be called on unload
122
115
function cleanUp() {
123
 
  if (!abp)
124
 
    return;
125
 
 
126
116
  flasher.stop();
127
 
  RequestList.removeListener(handleItemChange);
128
 
  filterStorage.removeFilterObserver(reloadDisabledFilters);
129
 
  filterStorage.removeSubscriptionObserver(reloadDisabledFilters);
130
 
  abp.prefs.removeListener(onPrefChange);
 
117
  requestNotifier.shutdown();
 
118
  FilterStorage.removeFilterObserver(reloadDisabledFilters);
 
119
  FilterStorage.removeSubscriptionObserver(reloadDisabledFilters);
 
120
  Prefs.removeListener(onPrefChange);
131
121
 
132
 
  abpHooks.getBrowser().removeEventListener("select", handleTabChange, false);
 
122
  abpHooks.getBrowser().removeProgressListener(progressListener);
133
123
  mainWin.removeEventListener("unload", mainUnload, false);
134
124
}
135
125
 
137
127
 * Tracks preference changes, calls reloadDisabledFilters whenever Adblock Plus
138
128
 * is enabled/disabled.
139
129
 */
140
 
function onPrefChange()
 
130
function onPrefChange(name)
141
131
{
142
 
  if (abp.prefs.enabled != oldEnabled)
143
 
  {
144
 
    oldEnabled = abp.prefs.enabled;
 
132
  if (name == "enabled")
145
133
    reloadDisabledFilters();
146
 
  }
147
134
}
148
135
 
149
136
/**
150
 
 * Updates matchers for disabled filters (global disabledBlacklistMatcher and
151
 
 * disabledWhitelistMatcher variables), called on each filter change.
 
137
 * Updates matcher for disabled filters (global disabledMatcher variable),
 
138
 * called on each filter change.
152
139
 */
153
140
function reloadDisabledFilters()
154
141
{
155
 
  disabledBlacklistMatcher.clear();
156
 
  disabledWhitelistMatcher.clear();
 
142
  disabledMatcher.clear();
157
143
 
158
 
  if (abp.prefs.enabled)
 
144
  if (Prefs.enabled)
159
145
  {
160
 
    for each (let subscription in filterStorage.subscriptions)
 
146
    for each (let subscription in FilterStorage.subscriptions)
161
147
    {
162
148
      if (subscription.disabled)
163
149
        continue;
164
150
  
165
151
      for each (let filter in subscription.filters)
166
 
        if (filter instanceof abp.RegExpFilter && filter.disabled)
167
 
          (filter instanceof abp.BlockingFilter ? disabledBlacklistMatcher : disabledWhitelistMatcher).add(filter);
 
152
        if (filter instanceof RegExpFilter && filter.disabled)
 
153
          disabledMatcher.add(filter);
168
154
    }
169
155
  }
170
156
 
171
 
  treeView.setData(treeView.allData);
 
157
  treeView.updateFilters();
172
158
}
173
159
 
174
160
// Called whenever list selection changes - triggers flasher
178
164
    E("copy-command").removeAttribute("disabled");
179
165
  else
180
166
    E("copy-command").setAttribute("disabled", "true");
181
 
  if (item && wndData)
182
 
    wndData.lastSelection = item;
 
167
 
 
168
  if (item && window.content)
 
169
  {
 
170
    let key = item.location + " " + item.type + " " + item.docDomain;
 
171
    window.content.document.setUserData(lastSelectionProp, key, null);
 
172
    treeView.itemToSelect = null;
 
173
  }
183
174
 
184
175
  if (!noFlash)
185
176
    flasher.flash(item ? item.nodes : null);
186
177
}
187
178
 
188
 
function handleItemChange(wnd, type, data, item) {
189
 
  // Check whether this applies to us
190
 
  if (wnd != window.content)
191
 
    return;
192
 
 
193
 
  // Maybe we got called twice
194
 
  if (type == "select" && data == wndData)
195
 
    return;
196
 
 
197
 
  // If adding something from a new data container - select it
198
 
  if (type == "add" && data != wndData)
199
 
    type = "select";
200
 
 
201
 
  var i;
202
 
  var filterSuggestions = E("suggestionsList");
203
 
  if (type == "clear") {
204
 
    // Current document has been unloaded, clear list
205
 
    wndData = null;
206
 
    treeView.setData([]);
207
 
  }
208
 
  else if (type == "select" || type == "refresh") {
209
 
    // We moved to a different document, reload list
210
 
    wndData = data;
211
 
    treeView.setData(wndData.getAllLocations());
212
 
  }
213
 
  else if (type == "invalidate")
214
 
    treeView.boxObject.invalidate();
215
 
  else if (type == "add")
216
 
    treeView.addItem(item);
217
 
}
218
 
 
219
 
function handleTabChange() {
220
 
  wndData = RequestList.getDataForWindow(window.content);
221
 
  treeView.setData(wndData.getAllLocations());
222
 
  if (wndData.lastSelection) {
223
 
    noFlash = true;
224
 
    treeView.selectItem(wndData.lastSelection);
225
 
    noFlash = false;
226
 
  }
 
179
function handleLocationChange()
 
180
{
 
181
  if (requestNotifier)
 
182
    requestNotifier.shutdown();
 
183
 
 
184
  treeView.clearData();
 
185
  treeView.itemToSelect = window.content.document.getUserData(lastSelectionProp);
 
186
  requestNotifier = new RequestNotifier(window.content, function(wnd, node, item, scanComplete)
 
187
  {
 
188
    if (item)
 
189
      treeView.addItem(node, item, scanComplete);
 
190
  });
227
191
}
228
192
 
229
193
// Fills a box with text splitting it up into multiple lines if necessary
252
216
  if (!item)
253
217
    return false;
254
218
 
255
 
  let filter = ("filter" in item && item.filter && !item.filter.disabled ? item.filter : null);
 
219
  let filter = ("filter" in item && item.filter ? item.filter : null);
256
220
  let size = ("tooltip" in item ? null : getItemSize(item));
257
221
  let subscriptions = (filter ? filter.subscriptions.filter(function(subscription) { return !subscription.disabled; }) : []);
258
222
 
272
236
    setMultilineContent(E("tooltipAddress"), item.location);
273
237
  
274
238
    var type = item.localizedDescr;
275
 
    if (filter && filter instanceof abp.WhitelistFilter)
 
239
    if (filter && filter instanceof WhitelistFilter)
276
240
      type += " " + E("tooltipType").getAttribute("whitelisted");
277
241
    else if (filter && item.typeDescr != "ELEMHIDE")
278
242
      type += " " + E("tooltipType").getAttribute("filtered");
281
245
    if (size)
282
246
      E("tooltipSize").setAttribute("value", size.join(" x "));
283
247
 
284
 
    E("tooltipDocDomain").setAttribute("value", item.docDomain);
 
248
    E("tooltipDocDomain").setAttribute("value", item.docDomain + " " + (item.thirdParty ? docDomainThirdParty : docDomainFirstParty));
285
249
  }
286
250
 
287
251
  if (filter)
288
252
  {
289
 
    setMultilineContent(E("tooltipFilter"), filter.text);
 
253
    let filterField = E("tooltipFilter");
 
254
    setMultilineContent(filterField, filter.text);
 
255
    if (filter.disabled)
 
256
    {
 
257
      let disabledText = document.createElement("description");
 
258
      disabledText.className = "disabledTextLabel";
 
259
      disabledText.textContent = filterField.getAttribute("disabledText");
 
260
      filterField.appendChild(disabledText);
 
261
    }
 
262
 
290
263
    if (subscriptions.length)
291
264
    {
292
265
      let sourceElement = E("tooltipFilterSource");
293
266
      while (sourceElement.firstChild)
294
267
        sourceElement.removeChild(sourceElement.firstChild);
295
 
      for each (let subscription in subscriptions)
296
 
        setMultilineContent(sourceElement, subscription.title, true);
 
268
      for (let i = 0; i < subscriptions.length; i++)
 
269
        setMultilineContent(sourceElement, subscriptions[i].title, true);
297
270
    }
298
271
  }
299
272
 
300
 
  var showPreview = prefs.previewimages && !("tooltip" in item);
301
 
  showPreview = showPreview && (item.typeDescr == "IMAGE" || item.typeDescr == "BACKGROUND");
302
 
  showPreview = showPreview && (!item.filter || item.filter instanceof abp.WhitelistFilter);
 
273
  var showPreview = Prefs.previewimages && !("tooltip" in item);
 
274
  showPreview = showPreview && item.typeDescr == "IMAGE";
 
275
  showPreview = showPreview && (!item.filter || item.filter instanceof WhitelistFilter);
303
276
  if (showPreview) {
304
277
    // Check whether image is in cache (stolen from ImgLikeOpera)
305
278
    if (!cacheSession) {
364
337
    menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, filter.text));
365
338
    menuItem.hidden = false;
366
339
 
367
 
    if (filter instanceof abp.ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(function(subscription) !(subscription instanceof abp.SpecialSubscription)))
 
340
    if (filter instanceof ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription)))
368
341
    {
369
342
      let domain = null;
370
343
      try {
371
344
        domain = content.location.host;
372
 
        domain = effectiveTLD.getBaseDomainFromHost(domain);
 
345
        domain = Utils.effectiveTLD.getBaseDomainFromHost(domain);
373
346
      } catch (e) {}
374
347
 
375
348
      if (domain && !filter.isActiveOnlyOnDomain(domain))
384
357
    }
385
358
  }
386
359
 
387
 
  E("contextWhitelist").hidden = ("tooltip" in item || !item.filter || item.filter.disabled || item.filter instanceof abp.WhitelistFilter || item.typeDescr == "ELEMHIDE");
 
360
  E("contextWhitelist").hidden = ("tooltip" in item || !item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter || item.typeDescr == "ELEMHIDE");
388
361
  E("contextBlock").hidden = !E("contextWhitelist").hidden;
389
362
  E("contextBlock").setAttribute("disabled", "filter" in item && item.filter && !item.filter.disabled);
390
363
  E("contextEditFilter").setAttribute("disabled", !("filter" in item && item.filter));
391
364
  E("contextOpen").setAttribute("disabled", "tooltip" in item || item.typeDescr == "ELEMHIDE");
392
 
  E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.typeDescr in visual) || (item.filter && !item.filter.disabled && !(item.filter instanceof abp.WhitelistFilter)));
 
365
  E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.typeDescr in visual) || (item.filter && !item.filter.disabled && !(item.filter instanceof WhitelistFilter)));
393
366
  E("contextCopyFilter").setAttribute("disabled", !allItems.some(function(item) {return "filter" in item && item.filter}));
394
367
 
395
368
  return true;
432
405
 */
433
406
function openInTab(item, /**Event*/ event)
434
407
{
435
 
  if (!item)
436
 
    item = treeView.getSelectedItem();
437
 
  if (!item || item.typeDescr == "ELEMHIDE")
438
 
    return;
439
 
 
440
 
  abp.loadInBrowser(item.location, mainWin, event);
 
408
  let items = (item ? [item] : treeView.getAllSelectedItems());
 
409
  for each (let item in items)
 
410
  {
 
411
    if (item && item.typeDescr != "ELEMHIDE")
 
412
      Utils.loadInBrowser(item.location, mainWin, event);
 
413
  }
441
414
}
442
415
 
443
416
function doBlock() {
444
 
  if (!abp)
445
 
    return;
446
 
 
447
417
  var item = treeView.getSelectedItem();
448
418
  if (!item || item.typeDescr == "ELEMHIDE")
449
419
    return;
450
420
 
451
421
  var filter = null;
452
 
  if ("filter" in item && item.filter && !item.filter.disabled)
 
422
  if (item.filter && !item.filter.disabled)
453
423
    filter = item.filter;
454
424
 
455
 
  if (filter && filter instanceof abp.WhitelistFilter)
 
425
  if (filter && filter instanceof WhitelistFilter)
456
426
    return;
457
427
 
458
 
  openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", window.content, item);
 
428
  openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", item.nodes, item.orig);
459
429
}
460
430
 
461
431
function editFilter() {
462
 
  if (!abp)
463
 
    return;
464
 
 
465
432
  var item = treeView.getSelectedItem();
466
433
  if (treeView.data && !treeView.data.length)
467
434
    item = treeView.getDummyTooltip();
472
439
  if (!("location") in item)
473
440
    item.location = undefined
474
441
 
475
 
  abp.openSettingsDialog(item.location, item.filter);
 
442
  Utils.openSettingsDialog(item.location, item.filter);
476
443
}
477
444
 
478
445
function enableFilter(filter, enable) {
479
 
  if (!abp)
480
 
    return;
481
 
 
482
446
  filter.disabled = !enable;
483
 
  filterStorage.triggerFilterObservers(enable ? "enable" : "disable", [filter]);
484
 
  filterStorage.saveToDisk();
 
447
  FilterStorage.triggerFilterObservers(enable ? "enable" : "disable", [filter]);
 
448
  FilterStorage.saveToDisk();
485
449
 
486
450
  treeView.boxObject.invalidate();
487
451
}
494
458
  // Generate text for new filter that excludes current domain
495
459
  domain = domain.toUpperCase();
496
460
  let text = filter.text;
497
 
  if (filter instanceof abp.RegExpFilter)
 
461
  if (filter instanceof RegExpFilter)
498
462
  {
499
 
    if (abp.Filter.optionsRegExp.test(text))
 
463
    if (Filter.optionsRegExp.test(text))
500
464
    {
501
465
      let found = false;
502
466
      let options = RegExp.$1.toUpperCase().split(",");
514
478
      if (!found)
515
479
        options.push("DOMAIN=~" + domain);
516
480
 
517
 
      text = text.replace(abp.Filter.optionsRegExp, "$" + options.join(",").toLowerCase());
 
481
      text = text.replace(Filter.optionsRegExp, "$" + options.join(",").toLowerCase());
518
482
    }
519
483
    else
520
484
      text += "$domain=~" + domain.toLowerCase();
521
485
  }
522
 
  else if (filter instanceof abp.ElemHideFilter)
 
486
  else if (filter instanceof ElemHideFilter)
523
487
  {
524
488
    if (/^([^#]+)(#.*)/.test(text))
525
489
    {
536
500
    return;   // Just in case, shouldn't happen
537
501
 
538
502
  // Insert new filter before the old one and remove the old one then
539
 
  let newFilter = abp.Filter.fromText(text);
 
503
  let newFilter = Filter.fromText(text);
540
504
  if (newFilter.disabled && newFilter.subscriptions.length)
541
505
  {
542
506
    newFilter.disabled = false;
543
 
    filterStorage.triggerFilterObservers("enable", [newFilter]);
 
507
    FilterStorage.triggerFilterObservers("enable", [newFilter]);
544
508
  }
545
509
  else if (!newFilter.subscriptions.length)
546
510
  {
547
511
    newFilter.disabled = false;
548
 
    filterStorage.addFilter(newFilter, filter);
 
512
    FilterStorage.addFilter(newFilter, filter);
549
513
  }
550
 
  filterStorage.removeFilter(filter);
551
 
  filterStorage.saveToDisk();
 
514
  FilterStorage.removeFilter(filter);
 
515
  FilterStorage.saveToDisk();
552
516
 
553
517
  // Update display
554
518
  item.filter = null;
556
520
}
557
521
 
558
522
function copyToClipboard() {
559
 
  if (!abp)
560
 
    return;
561
 
 
562
523
  var items = treeView.getAllSelectedItems();
563
524
  if (!items.length)
564
525
    return;
565
526
 
566
527
  var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
567
 
  clipboardHelper.copyString(items.map(function(item) {return item.location}).join(abp.getLineBreak()));
 
528
  clipboardHelper.copyString(items.map(function(item) {return item.location}).join(Utils.getLineBreak()));
568
529
}
569
530
 
570
531
function copyFilter() {
571
 
  if (!abp)
572
 
    return;
573
 
 
574
532
  var items = treeView.getAllSelectedItems().filter(function(item) {return item.filter});
575
533
  if (treeView.data && !treeView.data.length)
576
534
    items = [treeView.getDummyTooltip()];
579
537
    return;
580
538
 
581
539
  var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
582
 
  clipboardHelper.copyString(items.map(function(item) {return item.filter.text}).join(abp.getLineBreak()));
 
540
  clipboardHelper.copyString(items.map(function(item) {return item.filter.text}).join(Utils.getLineBreak()));
583
541
}
584
542
 
585
543
function selectAll() {
586
 
  if (!abp)
587
 
    return;
588
 
 
589
544
  treeView.selectAll();
590
545
}
591
546
 
604
559
    focus: (focused ? focused.id : null),
605
560
    position: position
606
561
  };
607
 
  abp.setParams(params);
 
562
  Utils.setParams(params);
608
563
}
609
564
 
610
565
// closes the sidebar
616
571
// detaches/reattaches the sidebar
617
572
function detach(doDetach)
618
573
{
619
 
  if (!abp)
620
 
    return;
621
 
 
622
574
  saveState();
623
575
 
624
576
  // Store variables locally, global variables will go away when we are closed
625
 
  let myPrefs = prefs;
 
577
  let myPrefs = Prefs;
626
578
  let myMainWin = mainWin;
627
579
 
628
580
  // Close sidebar and open detached window
629
581
  myMainWin.document.getElementById("abp-command-sidebar").doCommand();
630
582
  myPrefs.detachsidebar = doDetach;
631
583
  myMainWin.document.getElementById("abp-command-sidebar").doCommand();
632
 
 
633
 
  // Save setting
634
 
  myPrefs.save();
635
584
}
636
585
 
637
586
// Returns items size in the document if available
638
587
function getItemSize(item)
639
588
{
640
 
  if (item.filter && !item.filter.disabled && item.filter instanceof abp.BlockingFilter)
 
589
  if (item.filter && !item.filter.disabled && item.filter instanceof BlockingFilter)
641
590
    return null;
642
591
 
643
592
  for each (let node in item.nodes)
687
636
}
688
637
 
689
638
function compareState(item1, item2) {
690
 
  var state1 = (!item1.filter ? 0 : (item1.filter.disabled ? 1 : (item1.filter instanceof abp.WhitelistFilter ? 2 : 3)));
691
 
  var state2 = (!item2.filter ? 0 : (item2.filter.disabled ? 1 : (item2.filter instanceof abp.WhitelistFilter ? 2 : 3)));
 
639
  var state1 = (!item1.filter ? 0 : (item1.filter.disabled ? 1 : (item1.filter instanceof WhitelistFilter ? 2 : 3)));
 
640
  var state2 = (!item2.filter ? 0 : (item2.filter.disabled ? 1 : (item2.filter instanceof WhitelistFilter ? 2 : 3)));
692
641
  return state1 - state2;
693
642
}
694
643
 
707
656
    return -1;
708
657
  else if (item1.docDomain > item2.docDomain)
709
658
    return 1;
 
659
  else if (item1.thirdParty && !item2.thirdParty)
 
660
    return -1;
 
661
  else if (!item1.thirdParty && item2.thirdParty)
 
662
    return 1;
710
663
  else
711
664
    return 0;
712
665
}
723
676
  }
724
677
}
725
678
 
 
679
var progressListener =
 
680
{
 
681
  onLocationChange: function() handleLocationChange(),
 
682
  onProgressChange: function() {},
 
683
  onSecurityChange: function() {},
 
684
  onStateChange: function() {},
 
685
  onStatusChange: function() {},
 
686
  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference])
 
687
};
 
688
 
726
689
// Item list's tree view object
727
690
var treeView = {
728
691
  //
766
729
      this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false");
767
730
    }
768
731
 
769
 
    this.itemsDummyTooltip = abp.getString("no_blocking_suggestions");
770
 
    this.whitelistDummyTooltip = abp.getString("whitelisted_page");
 
732
    this.itemsDummyTooltip = Utils.getString("no_blocking_suggestions");
 
733
    this.whitelistDummyTooltip = Utils.getString("whitelisted_page");
771
734
 
772
735
    // Check current sort direction
773
736
    var cols = document.getElementsByTagName("treecol");
834
797
        return (size ? size.join(" x ") : "");
835
798
      }
836
799
      else if (col == "docDomain")
837
 
        return this.data[row].docDomain;
 
800
        return this.data[row].docDomain + " " + (this.data[row].thirdParty ? docDomainThirdParty : docDomainFirstParty);
838
801
      else
839
802
        return this.data[row].location;
840
803
    }
844
807
        return "";
845
808
 
846
809
      if (col == "filter") {
847
 
        var filter = abp.policy.isWindowWhitelisted(window.content);
 
810
        var filter = Policy.isWindowWhitelisted(window.content);
848
811
        return filter ? filter.text : "";
849
812
      }
850
813
 
851
 
      return (abp.policy.isWindowWhitelisted(window.content) ? this.whitelistDummy : this.itemsDummy);
 
814
      return (Policy.isWindowWhitelisted(window.content) ? this.whitelistDummy : this.itemsDummy);
852
815
    }
853
816
  },
854
817
 
876
839
      state = "state-regular";
877
840
      if (filter && !filter.disabled)
878
841
      {
879
 
        if (filter instanceof abp.WhitelistFilter)
 
842
        if (filter instanceof WhitelistFilter)
880
843
          state = "state-whitelisted";
881
 
        else if (filter instanceof abp.BlockingFilter)
 
844
        else if (filter instanceof BlockingFilter)
882
845
          state = "state-filtered";
883
 
        else if (filter instanceof abp.ElemHideFilter)
 
846
        else if (filter instanceof ElemHideFilter)
884
847
          state = "state-hidden";
885
848
      }
886
849
    }
888
851
      properties.AppendElement(this.atoms["dummy-true"]);
889
852
 
890
853
      state = "state-filtered";
891
 
      if (this.data && abp.policy.isWindowWhitelisted(window.content))
 
854
      if (this.data && Policy.isWindowWhitelisted(window.content))
892
855
        state = "state-whitelisted";
893
856
    }
894
857
    properties.AppendElement(this.atoms[state]);
968
931
  filter: "",
969
932
  data: null,
970
933
  allData: [],
 
934
  dataMap: {__proto__: null},
971
935
  sortColumn: null,
972
936
  sortProc: null,
973
937
  resortTimeout: null,
975
939
  whitelistDummy: null,
976
940
  itemsDummyTooltip: null,
977
941
  whitelistDummyTooltip: null,
 
942
  itemToSelect: null,
978
943
 
979
944
  sortProcs: {
980
945
    address: sortByAddress,
991
956
    docDomainDesc: createSortWithFallback(compareDocDomain, sortByAddress, true)
992
957
  },
993
958
 
994
 
  setData: function(data) {
 
959
  clearData: function(data) {
995
960
    var oldRows = this.rowCount;
996
961
 
997
 
    this.allData = data;
998
 
    for each (let item in this.allData)
999
 
    {
1000
 
      if (item.filter instanceof abp.RegExpFilter && item.filter.disabled)
1001
 
        item.filter = null;
1002
 
      if (!item.filter)
1003
 
        item.filter = disabledWhitelistMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
1004
 
      if (!item.filter)
1005
 
        item.filter = disabledBlacklistMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
1006
 
    }
 
962
    this.allData = [];
 
963
    this.dataMap = {__proto__: null};
1007
964
    this.refilter();
1008
965
 
1009
966
    this.boxObject.rowCountChanged(0, -oldRows);
1010
967
    this.boxObject.rowCountChanged(0, this.rowCount);
1011
968
  },
1012
969
 
1013
 
  addItem: function(item) {
 
970
  addItem: function(/**Node*/ node, /**RequestEntry*/ item, /**Boolean*/ scanComplete)
 
971
  {
 
972
    // Merge duplicate entries
 
973
    let key = item.location + " " + item.type + " " + item.docDomain;
 
974
    if (key in this.dataMap)
 
975
    {
 
976
      // We know this item already - take over the filter if any and be done with it
 
977
      let existing = this.dataMap[key];
 
978
      if (item.filter)
 
979
        existing.filter = item.filter;
 
980
 
 
981
      existing.nodes.push(node);
 
982
      this.invalidateItem(existing);
 
983
      return;
 
984
    }
 
985
 
 
986
    // Add new item to the list
 
987
    // Store original item in orig property - reading out prototype is messed up in Gecko 1.9.2
 
988
    item = {__proto__: item, orig: item, nodes: [node]};
1014
989
    this.allData.push(item);
1015
 
    if (!item.filter)
1016
 
      item.filter = disabledWhitelistMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
1017
 
    if (!item.filter)
1018
 
      item.filter = disabledBlacklistMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
 
990
    this.dataMap[key] = item;
 
991
 
 
992
    // Show disabled filters if no other filter applies
 
993
    if (!item.filter)
 
994
      item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
1019
995
 
1020
996
    if (!this.matchesFilter(item))
1021
997
      return;
1022
998
 
1023
 
    var index = -1;
 
999
    let index = -1;
1024
1000
    if (this.sortProc && this.sortColumn && this.sortColumn.id == "size")
1025
1001
    {
1026
1002
      // Sorting by size requires accessing content document, and that's
1052
1028
      this.boxObject.invalidateRow(0);
1053
1029
    else
1054
1030
      this.boxObject.rowCountChanged(index, 1);
 
1031
 
 
1032
    if (this.itemToSelect == key)
 
1033
    {
 
1034
      this.selection.select(index);
 
1035
      this.boxObject.ensureRowIsVisible(index);
 
1036
      this.itemToSelect = null;
 
1037
    }
 
1038
    else if (!scanComplete && this.selection.currentIndex >= 0) // Keep selected row visible while scanning
 
1039
      this.boxObject.ensureRowIsVisible(this.selection.currentIndex);
 
1040
  },
 
1041
 
 
1042
  updateFilters: function()
 
1043
  {
 
1044
    for each (let item in this.allData)
 
1045
    {
 
1046
      if (item.filter instanceof RegExpFilter && item.filter.disabled)
 
1047
        delete item.filter;
 
1048
      if (!item.filter)
 
1049
        item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
 
1050
    }
 
1051
    this.refilter();
1055
1052
  },
1056
1053
 
1057
1054
  /**
1079
1076
 
1080
1077
    return (item.location.toLowerCase().indexOf(this.filter) >= 0 ||
1081
1078
            (item.filter && item.filter.text.toLowerCase().indexOf(this.filter) >= 0) ||
1082
 
            item.localizedDescr.toLowerCase().indexOf(this.filter) >= 0);
 
1079
            item.localizedDescr.toLowerCase().indexOf(this.filter) >= 0 ||
 
1080
            (item.docDomain && item.docDomain.toLowerCase().indexOf(this.filter) >= 0) ||
 
1081
            (item.docDomain && item.thirdParty && docDomainThirdParty.toLowerCase().indexOf(this.filter) >= 0) ||
 
1082
            (item.docDomain && !item.thirdParty && docDomainFirstParty.toLowerCase().indexOf(this.filter) >= 0));
1083
1083
  },
1084
1084
 
1085
1085
  setFilter: function(filter) {
1152
1152
    if (!this.data || this.data.length)
1153
1153
      return null;
1154
1154
 
1155
 
    var filter = abp.policy.isWindowWhitelisted(window.content);
 
1155
    var filter = Policy.isWindowWhitelisted(window.content);
1156
1156
    if (filter)
1157
1157
      return {tooltip: this.whitelistDummyTooltip, filter: filter};
1158
1158
    else
1159
1159
      return {tooltip: this.itemsDummyTooltip};
1160
1160
  },
1161
1161
 
1162
 
  selectItem: function(item) {
1163
 
    var row = -1;
1164
 
    for (var i = 0; row < 0 && i < this.data.length; i++)
1165
 
      if (this.data[i] == item)
1166
 
        row = i;
1167
 
 
1168
 
    if (row < 0 )
1169
 
      return;
1170
 
 
1171
 
    this.selection.select(row);
1172
 
    this.boxObject.ensureRowIsVisible(row);
 
1162
  invalidateItem: function(item)
 
1163
  {
 
1164
    let row = this.data.indexOf(item);
 
1165
    if (row >= 0)
 
1166
      this.boxObject.invalidateRow(row);
1173
1167
  }
1174
1168
}