1
/* ***** BEGIN LICENSE BLOCK *****
4
* The contents of this file are subject to the Mozilla Public License Version
5
* 1.1 (the "License"); you may not use this file except in compliance with
6
* the License. You may obtain a copy of the License at
7
* http://www.mozilla.org/MPL/
9
* Software distributed under the License is distributed on an "AS IS" basis,
10
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11
* for the specific language governing rights and limitations under the
14
* The Original Code is Adblock Plus.
16
* The Initial Developer of the Original Code is
18
* Portions created by the Initial Developer are Copyright (C) 2006-2010
19
* the Initial Developer. All Rights Reserved.
23
* ***** END LICENSE BLOCK ***** */
25
let newInstall = true;
30
let initialized = false;
33
* Suppresses window resizing while the window is loading or if the window is loaded in a browser tab.
36
let suppressResize = true;
39
let subscriptionListLoading = false;
40
let appLocale = "en-US";
42
let adblockID = "{34274bf4-1d97-a289-e984-17e546307e4f}";
43
let filtersetG = "filtersetg@updater";
47
if (window.arguments && window.arguments.length)
49
// In K-Meleon we might get the arguments wrapped
50
for (var i = 0; i < window.arguments.length; i++)
51
if (window.arguments[i] && "wrappedJSObject" in window.arguments[i])
52
window.arguments[i] = window.arguments[i].wrappedJSObject;
55
[source, result] = window.arguments;
56
if (window.arguments.length > 2 && window.arguments[2])
57
window.hasSubscription = window.arguments[2];
68
source = {title: "", url: "", disabled: false, external: false, autoDownload: true, mainSubscriptionTitle: null, mainSubscriptionURL: null};
72
if (typeof source.mainSubscriptionURL == "undefined")
73
source.mainSubscriptionURL = source.mainSubscriptionTitle = null;
76
E("description-newInstall").hidden = !newInstall;
78
document.documentElement.setAttribute("newInstall", "true");
80
E("subscriptionsBox").hidden = E("all-subscriptions-container").hidden
81
= E("subscriptionInfo").hidden = editMode;
83
E("fromWebText").hidden = !editMode || source instanceof abp.Subscription;
84
E("editText").hidden = !(source instanceof abp.Subscription) || source instanceof abp.ExternalSubscription;
85
E("externalText").hidden = !(source instanceof abp.ExternalSubscription);
86
E("differentSubscription").hidden = !editMode;
87
document.documentElement.getButton("extra2").hidden = editMode;
89
setCustomSubscription(source.title, source.url,
90
source.mainSubscriptionTitle, source.mainSubscriptionURL);
92
if (source instanceof abp.Subscription)
94
document.title = document.documentElement.getAttribute("edittitle");
95
document.documentElement.getButton("accept").setAttribute("label", document.documentElement.getAttribute("buttonlabelacceptedit"))
98
if (source instanceof abp.ExternalSubscription)
100
E("location").setAttribute("disabled", "true");
101
E("autoDownload").setAttribute("disabled", "true");
102
E("autoDownload").checked = true;
105
E("autoDownload").checked = source.autoDownload;
107
// Find filter subscription suggestion based on user's browser locale
110
appLocale = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).getSelectedLocale("adblockplus");
121
let list = E("subscriptions");
122
let items = list.menupopup.childNodes;
123
let selectedItem = null;
124
let selectedPrefix = null;
126
for (let i = 0; i < items.length; i++)
129
let prefixes = item.getAttribute("_prefixes");
136
let prefix = checkPrefixMatch(prefixes, appLocale);
139
item.setAttribute("class", "localeMatch");
140
if (!selectedPrefix || selectedPrefix.length < prefix.length)
143
selectedPrefix = prefix;
146
else if (selectedPrefix && selectedPrefix.length == prefix.length)
150
// If multiple items have a matching prefix of the same length:
151
// Select one of the items randomly, probability should be the same
152
// for all items. So we replace the previous match here with
153
// probability 1/N (N being the number of matches).
154
if (Math.random() * matchCount < 1)
157
selectedPrefix = prefix;
162
list.selectedItem = selectedItem;
164
// Warn if Adblock or Filterset.G Updater are installed
165
if (isExtensionActive(adblockID))
166
E("adblock-warning").hidden = false;
168
if (isExtensionActive(filtersetG))
169
E("filtersetg-warning").hidden = false;
171
if ("Filterset.G" in filterStorage.knownSubscriptions &&
172
!filterStorage.knownSubscriptions["Filterset.G"].disabled)
174
E("filtersetg-warning").hidden = false;
178
// Only resize if we are a chrome window (not loaded into a browser tab)
179
if (window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).itemType == Ci.nsIDocShellTreeItem.typeChrome)
180
suppressResize = false;
183
function checkPrefixMatch(prefixes, appLocale)
188
for each (let prefix in prefixes.split(/,/))
189
if (new RegExp("^" + prefix + "\\b").test(appLocale))
195
function collapseElements()
197
if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL)
200
for (let i = 0; i < arguments.length; i++)
201
diff -= arguments[i].boxObject.height;
202
window.resizeBy(0, diff);
203
window.moveBy(0, -diff/2);
205
for (let i = 0; i < arguments.length; i++)
206
arguments[i].hidden = true;
209
function showElements()
211
for (let i = 0; i < arguments.length; i++)
212
arguments[i].hidden = false;
214
let scrollBox = E("content-scroll").boxObject;
215
if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL && scrollBox instanceof Ci.nsIScrollBoxObject)
218
for (let i = 0; i < arguments.length; i++)
219
arguments[i].boxObject.height;
221
let scrollHeight = {};
222
scrollBox.getScrolledSize({}, scrollHeight);
223
if (scrollHeight.value > scrollBox.height)
225
let diff = scrollHeight.value - scrollBox.height;
226
window.resizeBy(0, diff);
227
window.moveBy(0, -diff/2);
232
function onSelectionChange()
237
let selectedSubscription = E("subscriptions").value;
239
// Show/hide extra UI widgets for custom subscriptions, resize window appropriately
240
let container = E("all-subscriptions-container");
241
let inputFields = E("differentSubscription");
242
if (container.hidden && !selectedSubscription)
243
showElements(container, inputFields);
244
else if (!container.hidden && selectedSubscription)
245
collapseElements(container, inputFields);
247
// Make sure to hide "Add different subscription button" if we are already in that mode
248
document.documentElement.getButton("extra2").hidden = !selectedSubscription;
250
if (!selectedSubscription)
252
loadSubscriptionList();
256
updateSubscriptionInfo();
259
function updateSubscriptionInfo()
261
let selectedSubscription = E("subscriptions").selectedItem;
262
if (!selectedSubscription.value)
263
selectedSubscription = E("all-subscriptions").selectedItem;
265
E("subscriptionInfo").setAttribute("invisible", !selectedSubscription);
266
if (selectedSubscription)
268
let url = selectedSubscription.getAttribute("_url");
269
let homePage = selectedSubscription.getAttribute("_homepage")
271
let viewLink = E("view-list");
272
viewLink.setAttribute("_url", url);
273
viewLink.setAttribute("tooltiptext", url);
275
let homePageLink = E("visit-homepage");
276
homePageLink.hidden = !homePage;
279
homePageLink.setAttribute("_url", homePage);
280
homePageLink.setAttribute("tooltiptext", homePage);
285
function reloadSubscriptionList()
287
subscriptionListLoading = false;
288
loadSubscriptionList();
291
function loadSubscriptionList()
293
if (subscriptionListLoading)
296
E("all-subscriptions-container").selectedIndex = 0;
298
let request = new XMLHttpRequest();
299
let errorHandler = function()
301
E("all-subscriptions-container").selectedIndex = 2;
303
let successHandler = function()
305
if (!request.responseXML || request.responseXML.documentElement.localName != "subscriptions")
313
processSubscriptionList(request.responseXML);
322
request.open("GET", abp.prefs.subscriptions_listurl);
323
request.onerror = errorHandler;
324
request.onload = successHandler;
327
subscriptionListLoading = true;
330
function processSubscriptionList(doc)
332
let list = E("all-subscriptions");
333
while (list.firstChild)
334
list.removeChild(list.firstChild);
336
addSubscriptions(list, doc.documentElement, 0, null, null);
337
E("all-subscriptions-container").selectedIndex = 1;
340
function addSubscriptions(list, parent, level, parentTitle, parentURL)
342
for (let i = 0; i < parent.childNodes.length; i++)
344
let node = parent.childNodes[i];
345
if (node.nodeType != Node.ELEMENT_NODE || node.localName != "subscription")
348
if (node.getAttribute("type") != "ads" || node.getAttribute("deprecated") == "true")
351
let variants = node.getElementsByTagName("variants");
352
if (!variants.length || !variants[0].childNodes.length)
354
variants = variants[0].childNodes;
357
let mainTitle = null;
359
for (let j = 0; j < variants.length; j++)
361
let variant = variants[j];
362
if (variant.nodeType != Node.ELEMENT_NODE || variant.localName != "variant")
365
let item = document.createElement("richlistitem");
366
item.setAttribute("_title", variant.getAttribute("title"));
367
item.setAttribute("_url", variant.getAttribute("url"));
368
if (parentTitle && parentURL && variant.getAttribute("complete") != "true")
370
item.setAttribute("_supplementForTitle", parentTitle);
371
item.setAttribute("_supplementForURL", parentURL);
373
item.setAttribute("tooltiptext", variant.getAttribute("url"));
374
item.setAttribute("_homepage", node.getAttribute("homepage"));
376
let title = document.createElement("description");
379
if (checkPrefixMatch(node.getAttribute("prefixes"), appLocale))
380
title.setAttribute("class", "title localeMatch");
382
title.setAttribute("class", "title");
383
title.textContent = node.getAttribute("title");
384
mainTitle = variant.getAttribute("title");
385
mainURL = variant.getAttribute("url");
388
title.setAttribute("flex", "1");
389
title.style.marginLeft = (20 * level) + "px";
390
item.appendChild(title);
392
let variantTitle = document.createElement("description");
393
variantTitle.setAttribute("class", "variant");
394
variantTitle.textContent = variant.getAttribute("title");
395
variantTitle.setAttribute("crop", "end");
396
item.appendChild(variantTitle);
398
list.appendChild(item);
401
let supplements = node.getElementsByTagName("supplements");
402
if (supplements.length)
403
addSubscriptions(list, supplements[0], level + 1, mainTitle, mainURL);
407
function onAllSelectionChange()
409
let selectedItem = E("all-subscriptions").selectedItem;
413
setCustomSubscription(selectedItem.getAttribute("_title"), selectedItem.getAttribute("_url"),
414
selectedItem.getAttribute("_supplementForTitle"), selectedItem.getAttribute("_supplementForURL"));
416
updateSubscriptionInfo();
419
function setCustomSubscription(title, url, mainSubscriptionTitle, mainSubscriptionURL)
421
E("title").value = title;
422
E("location").value = url;
424
let messageElement = E("supplementMessage");
425
let addMainCheckbox = E("addMainSubscription");
426
if (mainSubscriptionURL && !hasSubscription(mainSubscriptionURL))
428
if (messageElement.hidden)
429
showElements(messageElement, addMainCheckbox);
431
let beforeLink, afterLink;
432
if (/(.*)\?1\?(.*)/.test(messageElement.getAttribute("_textTemplate")))
433
[beforeLink, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
435
[beforeLink, afterLink] = [messageElement.getAttribute("_textTemplate"), ""];
437
while (messageElement.firstChild)
438
messageElement.removeChild(messageElement.firstChild);
439
messageElement.appendChild(document.createTextNode(beforeLink));
440
let link = document.createElement("label");
441
link.className = "text-link";
442
link.setAttribute("tooltiptext", mainSubscriptionURL);
443
link.addEventListener("click", function() abp.loadInBrowser(mainSubscriptionURL), false);
444
link.textContent = mainSubscriptionTitle;
445
messageElement.appendChild(link);
446
messageElement.appendChild(document.createTextNode(afterLink));
448
addMainCheckbox.value = mainSubscriptionURL;
449
addMainCheckbox.setAttribute("_mainSubscriptionTitle", mainSubscriptionTitle)
450
addMainCheckbox.label = addMainCheckbox.getAttribute("_labelTemplate").replace(/\?1\?/g, mainSubscriptionTitle);
451
addMainCheckbox.accessKey = addMainCheckbox.accessKey;
453
else if (!messageElement.hidden)
454
collapseElements(messageElement, addMainCheckbox);
457
function selectCustomSubscription()
459
let list = E("subscriptions")
460
list.selectedItem = list.menupopup.lastChild;
463
function validateURL(url)
465
url = url.replace(/^\s+/, "").replace(/\s+$/, "");
467
// Is this a file path?
469
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
470
file.initWithPath(url);
471
return Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newFileURI(file).spec;
474
// Is this a valid URL?
475
let uri = abp.makeURL(url);
482
function addSubscription()
484
let list = E("subscriptions");
496
url = E("location").value;
497
if (!(source instanceof abp.ExternalSubscription))
498
url = validateURL(url);
501
abp.alert(window, abp.getString("subscription_invalid_location"));
502
E("location").focus();
506
title = E("title").value.replace(/^\s+/, "").replace(/\s+$/, "");
510
autoDownload = E("autoDownload").checked;
514
result.title = title;
515
result.autoDownload = autoDownload;
516
result.disabled = source.disabled;
518
let addMainCheckbox = E("addMainSubscription")
519
if (!addMainCheckbox.hidden && addMainCheckbox.checked)
521
result.mainSubscriptionTitle = addMainCheckbox.getAttribute("_mainSubscriptionTitle");
522
result.mainSubscriptionURL = addMainCheckbox.value;
527
abp.addSubscription(result.url, result.title, result.autoDownload, result.disabled);
528
if ("mainSubscriptionURL" in result)
529
abp.addSubscription(result.mainSubscriptionURL, result.mainSubscriptionTitle, result.autoDownload, result.disabled);
536
function hasSubscription(url)
538
return abp.filterStorage.subscriptions.some(function(subscription) subscription instanceof abp.DownloadableSubscription && subscription.url == url);
541
function checkUnload()
543
if (newInstall && !closing)
544
return abp.getString("subscription_notAdded_warning");
549
function onDialogCancel()
551
let message = checkUnload();
555
message += " " + abp.getString("subscription_notAdded_warning_addendum");
556
closing = abp.confirm(window, message);
560
function uninstallExtension(id)
562
let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
563
if (extensionManager.getItemForID(id))
565
let location = extensionManager.getInstallLocation(id);
566
if (location && !location.canAccess)
568
// Cannot uninstall, need to disable
569
extensionManager.disableItem(id);
573
extensionManager.uninstallItem(id);
578
function isExtensionActive(id)
580
if (!("@mozilla.org/extensions/manager;1" in Cc))
583
let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
585
// First check whether the extension is installed
586
if (!extensionManager.getItemForID(id))
589
let ds = extensionManager.datasource;
590
let rdfService = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
591
let source = rdfService.GetResource("urn:mozilla:item:" + id);
593
// Check whether extension is disabled
594
let link = rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#isDisabled");
595
let target = ds.GetTarget(source, link, true);
596
if (target instanceof Ci.nsIRDFLiteral && target.Value == "true")
599
// Check whether an operation is pending for the extension
600
link = rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#opType");
601
if (ds.GetTarget(source, link, false))
607
function uninstallAdblock()
609
uninstallExtension(adblockID);
610
E("adblock-warning").hidden = true;
613
function uninstallFiltersetG()
615
// Disable further updates
616
abp.denyFiltersetG = true;
618
// Uninstall extension
619
uninstallExtension(filtersetG);
621
// Remove filter subscription
622
if ("Filterset.G" in filterStorage.knownSubscriptions)
623
filterStorage.removeSubscription(filterStorage.knownSubscriptions["Filterset.G"]);
625
E("filtersetg-warning").hidden = true;