[Pkg-mozext-commits] [SCM] Advertisement filter extension for the Iceweasel/Iceape branch, master, updated. debian/1.3.3-2-38-gefa7fbb
Andrea Veri
av at src.gnome.org
Thu Sep 29 23:01:23 UTC 2011
The following commit has been merged in the master branch:
commit efa7fbbad3967523d5c2d1d4788f2afa47a944ee
Author: Andrea Veri <av at src.gnome.org>
Date: Fri Sep 30 01:01:27 2011 +0200
New upstream release. (1.3.10)
diff --git a/META-INF/manifest.mf b/META-INF/manifest.mf
new file mode 100644
index 0000000..c06d8c0
--- /dev/null
+++ b/META-INF/manifest.mf
@@ -0,0 +1,141 @@
+Manifest-Version: 1.0
+
+Name: chrome.manifest
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: O3qmW0EIitSjDCNQOfPeTQ==
+SHA1-Digest: G+hcO7+wZkom6p2I8CYIHnZgGaA=
+
+Name: chrome/adblockplus.jar
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: GFTBdv/NRwHXeeJAReNjBA==
+SHA1-Digest: pJ0QWOPgjQtBEC0zHoW4C2hn/nY=
+
+Name: components/Initializer.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 5QPWDDkX6xES5i2ijNmezQ==
+SHA1-Digest: c863HtNQXl+yQMKglsoaODf4EAI=
+
+Name: defaults/patterns.ini
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: /NdLKO98x9Y1mw4vxxPmrA==
+SHA1-Digest: 3v8WC1VjhTrIsZXC0gGLh7e1l8E=
+
+Name: defaults/preferences/adblockplus.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: mQ93Q22nRIq5iBvsbUk8zw==
+SHA1-Digest: yGNl6bo/1mf/0BcBNtb4d+7XvpE=
+
+Name: icon.png
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: gDyjcgDrPtc5KIdB5+6ocg==
+SHA1-Digest: hclnMh9v51FmeJI25Tkc/ZH3IwI=
+
+Name: icon64.png
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: p31nZUiXu5Cn+EtnDF2Fiw==
+SHA1-Digest: 0Njp3F/pdQ8Ne3KwBsgvLA4vaso=
+
+Name: install.rdf
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 9U21SV4+oE+seGLCSQUEVQ==
+SHA1-Digest: /IyM9J719HdzZGhTXowo8kSoLIU=
+
+Name: modules/AppIntegration.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: RDc11X7/hVEEHDxAQIsHcQ==
+SHA1-Digest: rkyEHMmrNEw8k6jVOTE7CvUYp5M=
+
+Name: modules/AppIntegrationFennec.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 76XG7CqYwCWSFjwOnZoQhQ==
+SHA1-Digest: RgpgdWwUWWZFJrWH1I81FgcML+k=
+
+Name: modules/Bootstrap.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: OgioNUFGJi4RdbtkDHN2MA==
+SHA1-Digest: o9ZaI7zpgABLP1ElhouE/M0ifds=
+
+Name: modules/ContentPolicy.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: SRVKOLce1aDFRxDtBgzAuA==
+SHA1-Digest: R1ghPR4sKofS6plI231Xx6R11i4=
+
+Name: modules/ContentPolicyRemote.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 5kbTz5IY7zKoPcrjvGgziw==
+SHA1-Digest: Wh8GX1SuqwjkbNMOTdP7URKdd3k=
+
+Name: modules/ElemHide.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: QYNsBNt67KOVEEI3SYgxOw==
+SHA1-Digest: gUxEfSaIk1/J2JTmhtHku5hxfv8=
+
+Name: modules/ElemHideRemote.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: jw8ynYVX5HUT4oyo2EY0uw==
+SHA1-Digest: Tdgp8YqXNGmIygdL1Uy9PkR4cWI=
+
+Name: modules/FilterClasses.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: gvyyo5aPUiswshNsXjqGOg==
+SHA1-Digest: k8SUoDOBpUu5+Wqdyv0KE7Elh3U=
+
+Name: modules/FilterListener.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: NmSXLFE8zb9yME/bSRxDaA==
+SHA1-Digest: xjN0VcYOIsGpZ+YbkqsolqsiSkE=
+
+Name: modules/FilterStorage.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 4zX5TLXUWewNNyCvFzxDFw==
+SHA1-Digest: V8OyHVACt5uh3ny6uk9fzrSmZZo=
+
+Name: modules/Matcher.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: TDcz42uHH+NNiFwWQY19NQ==
+SHA1-Digest: WhixRgdzWSMyBdifWYHvw8KDUJo=
+
+Name: modules/ObjectTabs.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: aZ/G5HUuj0gW7IC88dXDVw==
+SHA1-Digest: YNJJZdyELuo3Z+OK3bkxSRxRt/s=
+
+Name: modules/Prefs.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: fTLfd/hxT7lFp5x0VZ0rxw==
+SHA1-Digest: YEC8b+zZjqizrYfpTLH1oseLUNc=
+
+Name: modules/Public.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 1h10Es1zIrljo0dErcFjGQ==
+SHA1-Digest: DHUnA8tU1nmVtAJWTHDovbtcnzo=
+
+Name: modules/RequestNotifier.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: mLsXYOEMVG2dBwpqDMO/GQ==
+SHA1-Digest: vYvYHjA7p7xK+fnwPh0X9LxeF6A=
+
+Name: modules/SubscriptionClasses.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: mAPCNJtsRzIY+tXlQrEdfg==
+SHA1-Digest: HnuC/+jvaN9RAvggmfiTLSkCDcw=
+
+Name: modules/Survey.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: G59EbZLvLEQ7bePEdXxgVQ==
+SHA1-Digest: bQ9reRn1LBs6sZD53jIncmIxFUo=
+
+Name: modules/Sync.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: WaMz7CE4vuXlKz0Um6KiDA==
+SHA1-Digest: MN38NkeNXza3hQxva8ag8dVCqxM=
+
+Name: modules/Synchronizer.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: SM33g1K4RA8ewpYfHUqiNw==
+SHA1-Digest: 1Qdhb4hnIMiRmhD0z4GsnS5fpGI=
+
+Name: modules/Utils.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: gW1qZQQyX+kSm67pNVqn7A==
+SHA1-Digest: 33TfcP/KplJNyGLpOzehhVL6Wjc=
diff --git a/META-INF/zigbert.rsa b/META-INF/zigbert.rsa
new file mode 100644
index 0000000..3df22f1
Binary files /dev/null and b/META-INF/zigbert.rsa differ
diff --git a/META-INF/zigbert.sf b/META-INF/zigbert.sf
new file mode 100644
index 0000000..5a4f392
--- /dev/null
+++ b/META-INF/zigbert.sf
@@ -0,0 +1,144 @@
+Signature-Version: 1.0
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: eFYI3OJFwJR3tmcPfUASxg==
+SHA1-Digest: d/6Z68ulBRyiureYHLr1x/FPYaw=
+
+Name: chrome.manifest
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: kfaQZ23OwNbv6GhyWel6uw==
+SHA1-Digest: doSJ37I+Dm/ndmEsL+xvhPLlcVc=
+
+Name: chrome/adblockplus.jar
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: B13NCSSoq6Lt+VTOpvJ0yA==
+SHA1-Digest: LVYWeeji3wVQ8UZgProbtIoUurc=
+
+Name: components/Initializer.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: xfe1phN0+gx9AygJbUB8Hw==
+SHA1-Digest: p0sefJp5YnkWhXxyKz6HYBzwxaE=
+
+Name: defaults/patterns.ini
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: bHLVG0rZ4eUVUl42mETI7w==
+SHA1-Digest: zHbdOGE2NgdnJH8L4Po6LJMw/DQ=
+
+Name: defaults/preferences/adblockplus.js
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: zBv33BC/rhAeWN04Mphy6A==
+SHA1-Digest: xUkcXZ4kn6ZTMeORQoiHfS3Mj+E=
+
+Name: icon.png
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: fZPHrD6Y+2b95AeP/kJBNA==
+SHA1-Digest: aQtfuHqCs+Ued35wLE62GJ8OWhQ=
+
+Name: icon64.png
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: oyB49s66PSIVwrgK3m8Qow==
+SHA1-Digest: 58A+zTLVHgiVDIwvL8+7Sah6vLI=
+
+Name: install.rdf
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: dLgVBuzmGh7TRbg6dH9x+Q==
+SHA1-Digest: oaKH7T39IBfVl2iUqHzjDpYhrvc=
+
+Name: modules/AppIntegration.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: At7AD2dMw0lOLSgDCiWOmg==
+SHA1-Digest: 1ms6s+kfLgHXh/idLEbZPKcX6JQ=
+
+Name: modules/AppIntegrationFennec.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: /85uF+KMMDS77fK+e1HnZg==
+SHA1-Digest: A0TzRYSxhIbhx+mM79jgMlrU3Tk=
+
+Name: modules/Bootstrap.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: vckH9m6DOCSQlGOoHNzxug==
+SHA1-Digest: 0LFmjjMpu2MT6siwz4JSt6zchJQ=
+
+Name: modules/ContentPolicy.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 33ooQN+7f/c3PS+u1FuxgA==
+SHA1-Digest: 7sjr2BQ6FCNEOHCBpn5faTjr25c=
+
+Name: modules/ContentPolicyRemote.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: yp4odxslcDwqEkalpKohwA==
+SHA1-Digest: kgedsTfeAr2qx7jLsYITihRMdr4=
+
+Name: modules/ElemHide.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 5//11wSLprRcLTCqFyuDjw==
+SHA1-Digest: H1x+4CsO5B91e+ubJ9zJPxPIiAk=
+
+Name: modules/ElemHideRemote.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 5hQQWf+/aVmtxREuUWgbIw==
+SHA1-Digest: EaD3Gjiq56Z0Y02AGJgFjYO/UkI=
+
+Name: modules/FilterClasses.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: F2wTOSHDnImjk1afTkz20Q==
+SHA1-Digest: IQjEBHi+IgLvezQKp/E5IZJ1K5o=
+
+Name: modules/FilterListener.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: JAU4yBUZXpCFKmC35EHeJg==
+SHA1-Digest: 16suCVbxPJoA5DTU5a/d/x164Ew=
+
+Name: modules/FilterStorage.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: ZZSKtayGBZo1Js2fuJa7cg==
+SHA1-Digest: 5QTkjTC4bAzs72E+9wqUTRqjjvA=
+
+Name: modules/Matcher.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: twgujedIQlaH8EcpwmcX9w==
+SHA1-Digest: FOmLnwjDV4X12DyEV93CmwJAfsI=
+
+Name: modules/ObjectTabs.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: DsJ7es4YxIrzvJAxztZUxQ==
+SHA1-Digest: FHt2jSKEa01gjDztqK0gA0A+7+0=
+
+Name: modules/Prefs.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: Z5GnRjvJ8nELO6P8ERLtbA==
+SHA1-Digest: 0b/cHL5xID052/bhgTuOw+CSAsc=
+
+Name: modules/Public.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 4gSDA2M5XGxZj8zvSuCqbA==
+SHA1-Digest: WPyuVKrs7Ay8EpcxwdFzlcjRISw=
+
+Name: modules/RequestNotifier.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: FleKaHxJ5YYCfmU7kjYcyg==
+SHA1-Digest: g89JT/Fu1Prwy9pWplddk1CGFEE=
+
+Name: modules/SubscriptionClasses.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 9liHz198v1SuUbpTPqGS3A==
+SHA1-Digest: 5uR2AjscE7FPZ1l5zi4ju2DxKf0=
+
+Name: modules/Survey.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: 8yywBJ8zX1bXY0DNSD663g==
+SHA1-Digest: 5erEtMll9pFh2069+k47w2jgQkE=
+
+Name: modules/Sync.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: xm7gtp61b3liEs+Y0sI/4w==
+SHA1-Digest: 8XHGrNSOeMrLYqJypZA0djGnQvg=
+
+Name: modules/Synchronizer.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: fErqzGG8+7kivYcAvJrd4A==
+SHA1-Digest: zQPd28Iw1Vl+NhwgZm1WvQxXHNM=
+
+Name: modules/Utils.jsm
+Digest-Algorithms: MD5 SHA1
+MD5-Digest: wbikb37TqLVpVLXNC2BNwQ==
+SHA1-Digest: 4R3idMpW1uu+TgStvCmfmyTSVjs=
diff --git a/addChecksum.pl b/addChecksum.pl
deleted file mode 100755
index 49658b8..0000000
--- a/addChecksum.pl
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/perl
-
-# Copyright 2011 Wladimir Palant
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#############################################################################
-# This is a reference script to add checksums to downloadable #
-# subscriptions. The checksum will be validated by Adblock Plus on download #
-# and checksum mismatches (broken downloads) will be rejected. #
-# #
-# To add a checksum to a subscription file, run the script like this: #
-# #
-# perl addChecksum.pl subscription.txt #
-# #
-# Note: your subscription file should be saved in UTF-8 encoding, otherwise #
-# the generated checksum might be incorrect. #
-# #
-#############################################################################
-
-use strict;
-use warnings;
-use Digest::MD5 qw(md5_base64);
-
-die "Usage: $^X $0 subscription.txt\n" unless @ARGV;
-
-my $file = $ARGV[0];
-my $data = readFile($file);
-
-# Remove already existing checksum
-$data =~ s/^.*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n//gmi;
-
-# Calculate new checksum: remove all CR symbols and empty
-# lines and get an MD5 checksum of the result (base64-encoded,
-# without the trailing = characters).
-my $checksumData = $data;
-$checksumData =~ s/\r//g;
-$checksumData =~ s/\n+/\n/g;
-
-# Calculate new checksum
-my $checksum = md5_base64($checksumData);
-
-# Insert checksum into the file
-$data =~ s/(\r?\n)/$1! Checksum: $checksum$1/;
-
-writeFile($file, $data);
-
-sub readFile
-{
- my $file = shift;
-
- open(local *FILE, "<", $file) || die "Could not read file '$file'";
- binmode(FILE);
- local $/;
- my $result = <FILE>;
- close(FILE);
-
- return $result;
-}
-
-sub writeFile
-{
- my ($file, $contents) = @_;
-
- open(local *FILE, ">", $file) || die "Could not write file '$file'";
- binmode(FILE);
- print FILE $contents;
- close(FILE);
-}
diff --git a/build.py b/build.py
deleted file mode 100644
index c9ab4ab..0000000
--- a/build.py
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/env python
-# coding: utf-8
-
-import os, sys, subprocess
-
-if not os.path.exists('buildtools'):
- subprocess.Popen(['hg', 'clone', 'https://hg.adblockplus.org/buildtools/']).communicate()
-
-import buildtools.build
-buildtools.build.processArgs('.', sys.argv)
diff --git a/buildtools/.hg_archival.txt b/buildtools/.hg_archival.txt
deleted file mode 100644
index a63c24d..0000000
--- a/buildtools/.hg_archival.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-repo: 3926c055e81d4c11d3249479e18a92ce1bebb5cc
-node: a0ba2a9a53af62f151e0cbafa9126e02bb94c7cf
-branch: default
-latesttag: ABP_WATCHER_1_1_5_RELEASE
-latesttagdistance: 1
diff --git a/buildtools/LocaleTester.pm b/buildtools/LocaleTester.pm
deleted file mode 100644
index 062fee3..0000000
--- a/buildtools/LocaleTester.pm
+++ /dev/null
@@ -1,316 +0,0 @@
-package LocaleTester;
-
-use strict;
-use warnings;
-
-my %keepAccessKeys = map {$_ => $_} (
- 'ja-JP',
- 'ja',
- 'ko-KR',
- 'ko',
- 'zh-CN',
- 'zh-TW',
-);
-
-my @placeholders = (
- '?1?',
- '?2?',
- '?3?',
- '?4?',
- '?5?',
- '?6?',
- '?7?',
- '?8?',
- '?9?',
- '--',
- '%S',
- '[link]',
- '[/link]',
-);
-
-sub testLocales
-{
- my %params = @_;
- die "Need at least one locale path to work on" unless exists($params{paths}) && %{$params{paths}};
- $params{mustDiffer} = [] unless exists($params{mustDiffer});
- $params{mustEqual} = [] unless exists($params{mustEqual});
- $params{ignoreUntranslated} = [] unless exists($params{ignoreUntranslated});
- $params{lengthRestrictions} = {} unless exists($params{lengthRestrictions});
-
- my @locales = sort {$a cmp $b} (exists($params{locales}) && @{$params{locales}} ? @{$params{locales}} : makeLocaleList($params{paths}));
-
- my $referenceLocale = readLocaleFiles($params{paths}, "en-US");
-
- foreach my $locale (@locales)
- {
- my $currentLocale = $locale eq "en-US" ? $referenceLocale : readLocaleFiles($params{paths}, $locale);
-
- compareLocales($locale, $currentLocale, $referenceLocale) unless $currentLocale == $referenceLocale;
-
- foreach my $entry (@{$params{mustDiffer}})
- {
- my %values = ();
- foreach my $key (@$entry)
- {
- my ($dir, $file, $name) = split(/:/, $key);
- next unless exists($currentLocale->{"$dir:$file"}) && exists($currentLocale->{"$dir:$file"}{$name}) && $currentLocale->{"$dir:$file"}{$name};
- my $value = lc($currentLocale->{"$dir:$file"}{$name});
-
- print "$locale: Values for '$values{$value}' and '$key' are identical, must differ\n" if exists $values{$value};
- $values{$value} = $key;
- }
- }
-
- foreach my $entry (@{$params{mustEqual}})
- {
- my $stdValue;
- my $stdName;
- foreach my $key (@$entry)
- {
- my ($dir, $file, $name) = split(/:/, $key);
- next unless exists($currentLocale->{"$dir:$file"}) && exists($currentLocale->{"$dir:$file"}{$name});
- my $value = lc($currentLocale->{"$dir:$file"}{$name});
-
- $stdValue = $value unless defined $stdValue;
- $stdName = $key unless defined $stdName;
- print "$locale: Values for '$stdName' and '$key' differ, must be equal\n" if $value ne $stdValue;
- }
- }
-
- foreach my $key (keys %{$params{lengthRestrictions}})
- {
- my $maxLength = $params{lengthRestrictions}{$key};
- my ($dir, $file, $name) = split(/:/, $key);
- print "$locale: Value of '$key' is too long, must not be longer than $maxLength characters\n" if exists($currentLocale->{"$dir:$file"}) && exists($currentLocale->{"$dir:$file"}{$name}) && length($currentLocale->{"$dir:$file"}{$name}) > $maxLength;
- }
-
- foreach my $file (keys %$currentLocale)
- {
- my $fileData = $currentLocale->{$file};
- foreach my $key (keys %$fileData)
- {
- if (($key =~ /\.accesskey$/ || $key =~ /\.key$/) && length($fileData->{$key}) != 1)
- {
- print "$locale: Length of accesskey '$file:$key' isn't 1 character\n";
- }
-
- if ($key =~ /\.accesskey$/)
- {
- if (exists($keepAccessKeys{$locale}))
- {
- if (exists($referenceLocale->{$file}{$key}) && lc($fileData->{$key}) ne lc($referenceLocale->{$file}{$key}))
- {
- print "$locale: Accesskey '$file:$key' should be the same as in the reference locale\n";
- }
- }
- else
- {
- my $labelKey = $key;
- $labelKey =~ s/\.accesskey$/.label/;
- if (exists($fileData->{$labelKey}) && $fileData->{$labelKey} !~ /\Q$fileData->{$key}/i)
- {
- print "$locale: Accesskey '$file:$key' not found in the corresponding label '$file:$labelKey'\n";
- }
- }
- }
-
- if ($currentLocale != $referenceLocale && $locale ne "en-GB" && exists($referenceLocale->{$file}{$key}) && length($fileData->{$key}) > 1 && $fileData->{$key} eq $referenceLocale->{$file}{$key})
- {
- my $ignore = 0;
- foreach my $re (@{$params{ignoreUntranslated}})
- {
- $ignore = 1 if "$file:$key" =~ $re;
- }
- print "$locale: Value of '$file:$key' is the same as in the reference locale, probably an untranslated string\n" unless $ignore;
- }
-
- if ($currentLocale != $referenceLocale && exists($referenceLocale->{$file}{$key}))
- {
- foreach my $placeholder (@placeholders)
- {
- print "$locale: Placeholder '$placeholder' missing in '$file:$key'\n" if index($referenceLocale->{$file}{$key}, $placeholder) >= 0 && index($currentLocale->{$file}{$key}, $placeholder) < 0;
- }
- }
- }
- }
- }
-}
-
-sub makeLocaleList
-{
- my $paths = shift;
-
- my %locales = ();
- foreach my $dir (keys %$paths)
- {
- opendir(local* DIR, $paths->{$dir}) or next;
- my @locales = grep {!/[^\w\-]/ && !-e("$paths->{$dir}/$_/.incomplete")} readdir(DIR);
- $locales{$_} = 1 foreach @locales;
- closedir(DIR);
- }
- return keys %locales;
-}
-
-sub readFile
-{
- my $file = shift;
-
- open(local *FILE, "<", $file) || die "Could not read file '$file'";
- binmode(FILE);
- local $/;
- my $result = <FILE>;
- close(FILE);
-
- print "Byte Order Mark found in file '$file'\n" if $result =~ /\xEF\xBB\xBF/;
- print "File '$file' is not valid UTF-8\n" unless (utf8::decode($result));
-
- return $result;
-}
-
-sub parseDTDFile
-{
- my $file = shift;
-
- my %result = ();
-
- my $data = readFile($file);
-
- my $S = qr/[\x20\x09\x0D\x0A]/;
- my $Name = qr/[A-Za-z_:][\w.\-:]*/;
- my $Reference = qr/&$Name;|&#\d+;|&#x[\da-fA-F]+;/;
- my $PEReference = qr/%$Name;/;
- my $EntityValue = qr/\"((?:[^%&\"]|$PEReference|$Reference)*)\"|'((?:[^%&']|$PEReference|$Reference)*)'/;
-
- sub processEntityValue
- {
- my $text = shift;
- $text =~ s/&#(\d+);/chr($1)/ge;
- $text =~ s/&#x([\da-fA-F]+);/chr(hex($1))/ge;
- $text =~ s/'/'/g;
- return $text;
- }
-
- # Remove comments
- $data =~ s/<!--([^\-]|-[^\-])*-->//gs;
-
- # Process entities
- while ($data =~ /<!ENTITY$S+($Name)$S+$EntityValue$S*>/gs)
- {
- my ($name, $value) = ($1, $2 || $3);
- $result{$name} = processEntityValue($value);
- }
-
- # Remove entities
- $data =~ s/<!ENTITY$S+$Name$S+$EntityValue$S*>//gs;
-
- # Remove spaces
- $data =~ s/^\s+//gs;
- $data =~ s/\s+$//gs;
- $data =~ s/\s+/ /gs;
-
- print "Unrecognized data in file '$file': $data\n" if $data ne '';
-
- return \%result;
-}
-
-sub parsePropertiesFile
-{
- my $file = shift;
-
- my %result = ();
-
- my $data = readFile($file);
- while ($data =~ /^(.*)$/mg)
- {
- my $line = $1;
-
- # ignore comments
- next if $line =~ /^\s*[#!]/;
-
- if ($line =~ /=/)
- {
- my ($key, $value) = split(/=/, $line, 2);
- $result{$key} = $value;
- }
- elsif ($line =~ /\S/)
- {
- print "Unrecognized data in file '$file': $line\n";
- }
- }
- close(FILE);
-
- return \%result;
-}
-
-sub readLocaleFiles
-{
- my $paths = shift;
- my $locale = shift;
-
- my %result = ();
- foreach my $dir (keys %$paths)
- {
- opendir(local *DIR, "$paths->{$dir}/$locale") or next;
- foreach my $file (readdir(DIR))
- {
- if ($file =~ /(.*)\.dtd$/)
- {
- $result{"$dir:$1"} = parseDTDFile("$paths->{$dir}/$locale/$file");
- }
- elsif ($file =~ /(.*)\.properties$/)
- {
- $result{"$dir:$1"} = parsePropertiesFile("$paths->{$dir}/$locale/$file");
- }
- }
- closedir(DIR);
- }
-
- return \%result;
-}
-
-sub compareLocales
-{
- my ($locale, $current, $reference) = @_;
-
- my %hasFile = ();
- foreach my $file (keys %$current)
- {
- unless (exists($reference->{$file}))
- {
- print "$locale: Extra file '$file'\n";
- next;
- }
- $hasFile{$file} = 1;
-
- my %hasValue = ();
- foreach my $key (keys %{$current->{$file}})
- {
- unless (exists($reference->{$file}{$key}))
- {
- print "$locale: Extra value '$file:$key'\n";
- next;
- }
- $hasValue{$key} = 1;
- }
-
- foreach my $key (keys %{$reference->{$file}})
- {
- unless (exists($current->{$file}{$key}))
- {
- print "$locale: Missing value '$file:$key'\n";
- next;
- }
- }
- }
-
- foreach my $file (keys %$reference)
- {
- unless (exists($current->{$file}))
- {
- print "$locale: Missing file '$file'\n";
- next;
- }
- }
-}
-
-1;
diff --git a/buildtools/__init__.py b/buildtools/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/buildtools/build.py b/buildtools/build.py
deleted file mode 100644
index 0f2ddd8..0000000
--- a/buildtools/build.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import os, sys, re, buildtools
-from getopt import getopt, GetoptError
-
-class Command(object):
- name = property(lambda self: self._name)
- shortDescription = property(lambda self: self._shortDescription,
- lambda self, value: self.__dict__.update({'_shortDescription': value}))
- description = property(lambda self: self._description,
- lambda self, value: self.__dict__.update({'_description': value}))
- params = property(lambda self: self._params,
- lambda self, value: self.__dict__.update({'_params': value}))
- supportedTypes = property(lambda self: self._supportedTypes,
- lambda self, value: self.__dict__.update({'_supportedTypes': value}))
- options = property(lambda self: self._options)
-
- def __init__(self, handler, name):
- self._handler = handler
- self._name = name
- self._shortDescription = ''
- self._description = ''
- self._params = ''
- self._supportedTypes = None
- self._options = []
- self.addOption('Show this message and exit', short='h', long='help')
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_value, traceback):
- pass
-
- def __call__(self, baseDir, scriptName, opts, args, type):
- return self._handler(baseDir, scriptName, opts, args, type)
-
- def isSupported(self, type):
- return self._supportedTypes == None or type in self._supportedTypes
-
- def addOption(self, description, short=None, long=None, value=None):
- self._options.append((description, short, long, value))
-
- def parseArgs(self, args):
- shortOptions = map(lambda o: o[1]+':' if o[3] != None else o[1], filter(lambda o: o[1] != None, self._options))
- longOptions = map(lambda o: o[2]+'=' if o[3] != None else o[2], filter(lambda o: o[2] != None, self._options))
- return getopt(args, ''.join(shortOptions), longOptions)
-
-
-commandsList = []
-commands = {}
-def addCommand(handler, name):
- if isinstance(name, basestring):
- aliases = ()
- else:
- name, aliases = (name[0], name[1:])
-
- global commandsList, commands
- command = Command(handler, name)
- commandsList.append(command)
- commands[name] = command
- for alias in aliases:
- commands[alias] = command
- return command
-
-def splitByLength(string, maxLen):
- parts = []
- currentPart = ''
- for match in re.finditer(r'\s*(\S+)', string):
- if len(match.group(0)) + len(currentPart) < maxLen:
- currentPart += match.group(0)
- else:
- parts.append(currentPart)
- currentPart = match.group(1)
- if len(currentPart):
- parts.append(currentPart)
- return parts
-
-def usage(scriptName, type, commandName=None):
- if commandName == None:
- global commandsList
- descriptions = []
- for command in commandsList:
- if not command.isSupported(type):
- continue
- commandText = ('%s %s' % (command.name, command.params)).ljust(39)
- descriptionParts = splitByLength(command.shortDescription, 29)
- descriptions.append(' %s %s %s' % (scriptName, commandText, descriptionParts[0]))
- for part in descriptionParts[1:]:
- descriptions.append(' %s %s %s' % (' ' * len(scriptName), ' ' * len(commandText), part))
- print '''Usage:
-
-%(descriptions)s
-
-For details on a command run:
-
- %(scriptName)s <command> --help
-''' % {
- 'scriptName': scriptName,
- 'descriptions': '\n'.join(descriptions)
- }
- else:
- global commands
- command = commands[commandName]
- description = '\n'.join(map(lambda s: '\n'.join(splitByLength(s, 80)), command.description.split('\n')))
- options = []
- for descr, short, long, value in command.options:
- if short == None:
- shortText = ''
- elif value == None:
- shortText = '-%s' % short
- else:
- shortText = '-%s %s' % (short, value)
- if long == None:
- longText = ''
- elif value == None:
- longText = '--%s' % long
- else:
- longText = '--%s=%s' % (long, value)
- descrParts = splitByLength(descr, 46)
- options.append(' %s %s %s' % (shortText.ljust(11), longText.ljust(19), descrParts[0]))
- for part in descrParts[1:]:
- options.append(' %s %s %s' % (' ' * 11, ' ' * 19, part))
- print '''%(scriptName)s %(name)s %(params)s
-
-%(description)s
-
-Options:
-%(options)s
-''' % {
- 'scriptName': scriptName,
- 'name': command.name,
- 'params': command.params,
- 'description': description,
- 'options': '\n'.join(options)
- }
-
-
-def runBuild(baseDir, scriptName, opts, args, type):
- locales = None
- buildNum = None
- releaseBuild = False
- keyFile = None
- limitMetadata = False
- for option, value in opts:
- if option in ('-l', '--locales'):
- locales = value.split(',')
- elif option in ('-b', '--build'):
- buildNum = int(value)
- elif option in ('-k', '--key'):
- keyFile = value
- elif option in ('-r', '--release'):
- releaseBuild = True
- elif option == '--babelzilla':
- locales = 'all'
- limitMetadata = True
- outFile = args[0] if len(args) > 0 else None
-
- if type == 'gecko':
- import buildtools.packager as packager
- packager.createBuild(baseDir, outFile=outFile, locales=locales, buildNum=buildNum,
- releaseBuild=releaseBuild, keyFile=keyFile,
- limitMetadata=limitMetadata)
- elif type == 'kmeleon':
- import buildtools.packagerKMeleon as packagerKMeleon
- packagerKMeleon.createBuild(baseDir, outFile=outFile, locales=locales,
- buildNum=buildNum, releaseBuild=releaseBuild)
-
-def setupTestEnvironment(baseDir, scriptName, opts, args, type):
- dirsFile = '.profileDirs'
- for option, value in opts:
- if option in ('-d', '--dirs'):
- dirsFile = value
-
- profileDirs = args
- if len(profileDirs) == 0:
- handle = open(dirsFile, 'rb')
- profileDirs = map(str.strip, handle.readlines())
- handle.close()
- import buildtools.packager as packager
- packager.setupTestEnvironment(baseDir, profileDirs)
-
-
-def showDescriptions(baseDir, scriptName, opts, args, type):
- locales = None
- for option, value in opts:
- if option in ('-l', '--locales'):
- locales = value.split(',')
-
- import buildtools.packager as packager
- if locales == None:
- locales = packager.getLocales(baseDir)
- elif locales == 'all':
- locales = packager.getLocales(baseDir, True)
-
- data = packager.readLocaleMetadata(baseDir, locales)
- localeCodes = data.keys()
- localeCodes.sort()
- for localeCode in localeCodes:
- locale = data[localeCode]
- print ('''%s
-%s
-%s
-%s
-%s
-''' % (localeCode,
- locale['name'] if 'name' in locale else 'None',
- locale['description'] if 'description' in locale else 'None',
- locale['description.short'] if 'description.short' in locale else 'None',
- locale['description.long'] if 'description.long' in locale else 'None',
- )).encode('utf-8')
-
-
-def runReleaseAutomation(baseDir, scriptName, opts, args, type):
- buildtoolsRepo = buildtools.__path__[0]
- keyFile = None
- downloadsRepo = os.path.join(baseDir, '..', 'downloads')
- for option, value in opts:
- if option in ('-k', '--key'):
- keyFile = value
- elif option in ('-d', '--downloads'):
- downloadsRepo = value
-
- if type == 'gecko':
- if len(args) == 0:
- print 'No version number specified for the release'
- usage(scriptName, type, 'release')
- return
- version = args[0]
- if re.search(r'[^\w\.]', version):
- print 'Wrong version number format'
- usage(scriptName, type, 'release')
- return
-
- if keyFile == None:
- print 'Warning: no key file specified, creating an unsigned release build\n'
-
- import buildtools.releaseAutomation as releaseAutomation
- releaseAutomation.run(baseDir, version, keyFile, downloadsRepo, buildtoolsRepo)
- else:
- import buildtools.releaseAutomationKMeleon as releaseAutomationKMeleon
- releaseAutomationKMeleon.run(baseDir, downloadsRepo, buildtoolsRepo)
-
-with addCommand(lambda baseDir, scriptName, opts, args, type: usage(scriptName, type), ('help', '-h', '--help')) as command:
- command.shortDescription = 'Show this message'
-
-with addCommand(runBuild, 'build') as command:
- command.shortDescription = 'Create a build'
- command.description = 'Creates an extension build with given file name. If output_file is missing a default name will be chosen.'
- command.params = '[options] [output_file]'
- command.addOption('Only include the given locales (if omitted: all locales not marked as incomplete)', short='l', long='locales', value='l1,l2,l3')
- command.addOption('Use given build number (if omitted the build number will be retrieved from Mercurial)', short='b', long='build', value='num')
- command.addOption('File containing private key and certificates required to sign the package', short='k', long='key', value='file')
- command.addOption('Create a release build', short='r', long='release')
- command.addOption('Create a build for Babelzilla', long='babelzilla')
- command.supportedTypes = ('gecko', 'kmeleon')
-
-with addCommand(setupTestEnvironment, 'testenv') as command:
- command.shortDescription = 'Set up test environment'
- command.description = 'Sets up the extension in given profiles in such a way '\
- 'that most files are read from the current directory. Changes in the files '\
- 'here will be available to these profiles immediately after a restart '\
- 'without having to reinstall the extension. If no directories are given the '\
- 'list of directories is read from a file.'
- command.addOption('File listing profile directories to set up if none are given on command line (default is .profileDirs)', short='d', long='dirs', value='file')
- command.params = '[options] [profile_dir] ...'
- command.supportedTypes = ('gecko')
-
-with addCommand(showDescriptions, 'showdesc') as command:
- command.shortDescription = 'Print description strings for all locales'
- command.description = 'Display description strings for all locales as specified in the corresponding meta.properties files.'
- command.addOption('Only include the given locales', short='l', long='locales', value='l1,l2,l3')
- command.params = '[options]'
- command.supportedTypes = ('gecko')
-
-with addCommand(runReleaseAutomation, 'release') as command:
- command.shortDescription = 'Run release automation'
- command.description = 'Note: If you are not the project owner then you '\
- 'probably don\'t want to run this!\n\n'\
- 'Runs release automation: creates downloads for the new version, tags '\
- 'source code repository as well as downloads and buildtools repository.'
- command.addOption('File containing private key and certificates required to sign the release', short='k', long='key', value='file')
- command.addOption('Directory containing downloads repository (if omitted ../downloads is assumed)', short='d', long='downloads', value='dir')
- command.params = '[options] <version>'
- command.supportedTypes = ('gecko', 'kmeleon')
-
-def processArgs(baseDir, args, type='gecko'):
- global commands
-
- scriptName = os.path.basename(args[0])
- args = args[1:]
- if len(args) == 0:
- args = ['build']
- print '''
-No command given, assuming "build". For a list of commands run:
-
- %s help
-''' % scriptName
-
- command = args[0]
- if command in commands:
- if commands[command].isSupported(type):
- try:
- opts, args = commands[command].parseArgs(args[1:])
- except GetoptError, e:
- print str(e)
- usage(scriptName, type, command)
- sys.exit(2)
- for option, value in opts:
- if option in ('-h', '--help'):
- usage(scriptName, type, command)
- sys.exit()
- commands[command](baseDir, scriptName, opts, args, type)
- else:
- print 'Command %s is not supported for this application type' % command
- usage(scriptName, type)
- else:
- print 'Command %s is unrecognized' % command
- usage(scriptName, type)
diff --git a/buildtools/install.rdf.tmpl b/buildtools/install.rdf.tmpl
deleted file mode 100644
index 63a6602..0000000
--- a/buildtools/install.rdf.tmpl
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0"?>
-
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
- <Description about="urn:mozilla:install-manifest">
- <em:id>{{metadata.get('general', 'id')}}</em:id>
- <em:version>{{version}}</em:version>
- <em:name>{{localeMetadata[defaultLocale].name}}</em:name>
- <em:description>{{localeMetadata[defaultLocale].description}}</em:description>
- <em:creator>{{metadata.get('general', 'author')}}</em:creator>
- <em:homepageURL>{{metadata.get('homepage', 'default')}}</em:homepageURL>
- <em:type>2</em:type>
-
- {%- if not releaseBuild or metadata.has_option('general', 'updateURL') %}
- <em:updateURL>
- {{- metadata.get('general', 'updateURL') if releaseBuild else 'https://adblockplus.org/devbuilds/%s/update.rdf' % metadata.get('general', 'basename') -}}
- {{- '?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%' -}}
- </em:updateURL>
- {%- endif %}
-
- {%- if metadata.has_option('general', 'icon') %}
- <em:iconURL>{{metadata.get('general', 'icon')}}</em:iconURL>
- {%- endif %}
-
- {%- if metadata.has_option('general', 'about') %}
- <em:aboutURL>{{metadata.get('general', 'about')}}</em:aboutURL>
- {%- endif %}
-
- {%- if metadata.has_option('general', 'options') %}
- <em:optionsURL>{{metadata.get('general', 'options')}}</em:optionsURL>
- {%- endif %}
-
- {%- if metadata.has_section('contributors') %}
- {%- for option in metadata.options('contributors')|sort %}
- <em:contributor>{{metadata.get('contributors', option)}}</em:contributor>
- {%- endfor %}
- {%- endif %}
-
- {%- for translator in localeMetadata|translators %}
- <em:translator>{{translator}}</em:translator>
- {%- endfor %}
-
- {%- if not limitMetadata %}
- {%- for localeCode in localeMetadata.keys()|sort %}
- {%- set locale = localeMetadata[localeCode] %}
- <em:localized>
- <Description>
- <em:locale>{{localeCode}}</em:locale>
- <em:name>
- {%- if 'name' in locale -%}
- {{locale.name}}
- {%- else -%}
- {{localeMetadata[defaultLocale].name}}
- {%- endif -%}
- </em:name>
- <em:description>
- {%- if 'description' in locale -%}
- {{locale.description}}
- {%- else -%}
- {{localeMetadata[defaultLocale].description}}
- {%- endif -%}
- </em:description>
- <em:creator>{{metadata.get('general', 'author')}}</em:creator>
- <em:homepageURL>
- {%- if metadata.has_option('homepage', localeCode) -%}
- {{- metadata.get('homepage', localeCode) -}}
- {%- elif metadata.has_option('homepage', localeCode.split('-')[0]) -%}
- {{- metadata.get('homepage', localeCode.split('-')[0]) -}}
- {%- else -%}
- {{- metadata.get('homepage', 'default') -}}
- {%- endif -%}
- </em:homepageURL>
- </Description>
- </em:localized>
- {%- endfor %}
- {%- endif %}
-
- {%- for appName in metadata.options('compat')|sort %}
- {%- if appName in KNOWN_APPS %}
- <em:targetApplication>
- <Description>
- <!-- {{appName}} -->
- <em:id>{{KNOWN_APPS[appName]}}</em:id>
- <em:minVersion>{{metadata.get('compat', appName).split('/')[0]}}</em:minVersion>
- <em:maxVersion>{{metadata.get('compat', appName).split('/')[1]}}</em:maxVersion>
- </Description>
- </em:targetApplication>
- {%- endif %}
- {%- endfor %}
- </Description>
-</RDF>
diff --git a/buildtools/localeTools.py b/buildtools/localeTools.py
deleted file mode 100644
index 36fce9b..0000000
--- a/buildtools/localeTools.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import re, sys, codecs, cgi
-from StringIO import StringIO
-from ConfigParser import SafeConfigParser
-from xml.parsers.expat import ParserCreate, XML_PARAM_ENTITY_PARSING_ALWAYS
-
-def parseDTDString(data, path):
- result = {}
- parser = ParserCreate()
- parser.UseForeignDTD(True)
- parser.SetParamEntityParsing(XML_PARAM_ENTITY_PARSING_ALWAYS)
-
- def ExternalEntityRefHandler(context, base, systemId, publicId):
- subparser = parser.ExternalEntityParserCreate(context, 'utf-8')
- subparser.Parse(data.encode('utf-8'), True)
- return 1
-
- def EntityDeclHandler(entityName, is_parameter_entity, value, base, systemId, publicId, notationName):
- result[entityName] = value
-
- parser.ExternalEntityRefHandler = ExternalEntityRefHandler
- parser.EntityDeclHandler = EntityDeclHandler
- parser.Parse('<!DOCTYPE root SYSTEM "foo"><root/>', True)
- result['_origData'] = data
- return result
-
-def parsePropertiesString(data, path):
- result = {}
- for line in data.splitlines():
- if re.search(r'^\s*[#!]', line):
- continue
- elif '=' in line:
- key, value = line.split('=', 1)
- result[key] = value
- elif re.search(r'\S', line):
- print >>sys.stderr, 'Unrecognized data in file %s: %s' % (path, line)
- result['_origData'] = data
- return result
-
-def parseString(data, path):
- if path.endswith('.dtd'):
- return parseDTDString(data, path)
- elif path.endswith('.properties'):
- return parsePropertiesString(data, path)
- else:
- return None
-
-def readFile(path):
- fileHandle = codecs.open(path, 'rb', encoding='utf-8')
- data = fileHandle.read()
- fileHandle.close()
- return parseString(data, path)
-
-def generateStringEntry(key, value, path):
- if path.endswith('.dtd'):
- return '<!ENTITY %s "%s">\n' % (cgi.escape(key, True), cgi.escape(value, True))
- else:
- return '%s=%s\n' % (key, value)
diff --git a/buildtools/packager.py b/buildtools/packager.py
deleted file mode 100644
index fca04f7..0000000
--- a/buildtools/packager.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import os, sys, re, subprocess, jinja2, buildtools, codecs, hashlib, base64, shutil
-from ConfigParser import SafeConfigParser
-from StringIO import StringIO
-from zipfile import ZipFile, ZIP_STORED, ZIP_DEFLATED
-import buildtools.localeTools as localeTools
-
-KNOWN_APPS = {
- 'conkeror': '{a79fe89b-6662-4ff4-8e88-09950ad4dfde}',
- 'emusic': 'dlm at emusic.com',
- 'fennec': '{a23983c0-fd0e-11dc-95ff-0800200c9a66}',
- 'firefox': '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}',
- 'midbrowser': '{aa5ca914-c309-495d-91cf-3141bbb04115}',
- 'prism': 'prism at developer.mozilla.org',
- 'seamonkey': '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}',
- 'songbird': 'songbird at songbirdnest.com',
- 'thunderbird': '{3550f703-e582-4d05-9a08-453d09bdfdc6}',
- 'toolkit': 'toolkit at mozilla.org',
-}
-
-defaultLocale = 'en-US'
-
-def getDefaultFileName(baseDir, metadata, version, ext='xpi'):
- return os.path.join(baseDir, '%s-%s.%s' % (metadata.get('general', 'baseName'), version, ext))
-
-def getMetadataPath(baseDir):
- return os.path.join(baseDir, 'metadata')
-
-def getChromeDir(baseDir):
- return os.path.join(baseDir, 'chrome')
-
-def getLocalesDir(baseDir):
- return os.path.join(getChromeDir(baseDir), 'locale')
-
-def getChromeSubdirs(baseDir, locales):
- result = {}
- chromeDir = getChromeDir(baseDir)
- for subdir in ('content', 'skin'):
- result[subdir] = os.path.join(chromeDir, subdir)
- for locale in locales:
- result['locale/%s' % locale] = os.path.join(chromeDir, 'locale', locale)
- return result
-
-def getXPIFiles(baseDir):
- return [os.path.join(baseDir, file) for file in ('components', 'modules', 'defaults', 'bootstrap.js', 'chrome.manifest', 'icon.png', 'icon64.png')]
-
-def getTestEnvFiles(baseDir):
- return [os.path.join(baseDir, file) for file in ('components', 'defaults', 'bootstrap.js', 'chrome.manifest', 'icon.png', 'icon64.png')]
-
-def getIgnoredFiles(params):
- result = ['.incomplete', 'meta.properties']
- if params['releaseBuild']:
- result.append('TimeLine.jsm')
- return result
-
-def isValidLocale(localesDir, dir, includeIncomplete=False):
- if re.search(r'[^\w\-]', dir):
- return False
- if not os.path.isdir(os.path.join(localesDir, dir)):
- return False
- if not includeIncomplete and os.path.exists(os.path.join(localesDir, dir, '.incomplete')):
- return False
- return True
-
-def getLocales(baseDir, includeIncomplete=False):
- global defaultLocale
- localesDir = getLocalesDir(baseDir)
- locales = filter(lambda dir: isValidLocale(localesDir, dir, includeIncomplete), os.listdir(localesDir))
- locales.sort(key=lambda x: '!' if x == defaultLocale else x)
- return locales
-
-def getBuildNum(baseDir):
- (result, dummy) = subprocess.Popen(['hg', 'id', '-n'], stdout=subprocess.PIPE).communicate()
- return re.sub(r'\W', '', result)
-
-def readMetadata(baseDir):
- metadata = SafeConfigParser()
- file = codecs.open(getMetadataPath(baseDir), 'rb', encoding='utf-8')
- metadata.readfp(file)
- file.close()
- return metadata
-
-def processFile(path, data, params):
- if not re.search(r'\.(manifest|xul|jsm?|xml|xhtml|rdf|dtd|properties|css)$', path):
- return data
-
- data = re.sub(r'\r', '', data)
- data = data.replace('{{BUILD}}', params['buildNum'])
- data = data.replace('{{VERSION}}', params['version'])
-
- whitespaceRegExp = re.compile(r'^( )+', re.M)
- data = re.sub(whitespaceRegExp, lambda match: '\t' * (len(match.group(0)) / 2), data)
-
- if path.endswith('.manifest') and data.find('{{LOCALE}}') >= 0:
- localesRegExp = re.compile(r'^(.*?){{LOCALE}}(.*?){{LOCALE}}(.*)$', re.M)
- replacement = '\n'.join(map(lambda locale: r'\1%s\2%s\3' % (locale, locale), params['locales']))
- data = re.sub(localesRegExp, replacement, data)
-
- if params['releaseBuild'] and path.endswith('.jsm'):
- # Remove timeline calls from release builds
- timelineRegExp1 = re.compile(r'^.*\b[tT]imeLine\.(\w+)\(.*', re.M)
- timelineRegExp2 = re.compile(r'^.*Cu\.import\([^()]*\bTimeLine\.jsm\"\).*', re.M)
- data = re.sub(timelineRegExp1, '', data)
- data = re.sub(timelineRegExp2, '', data)
-
- return data
-
-def readLocaleMetadata(baseDir, locales):
- result = {}
-
- # Make sure we always have fallback data even if the default locale isn't part
- # of the build
- locales = list(locales)
- if not defaultLocale in locales:
- locales.append(defaultLocale)
-
- for locale in locales:
- data = SafeConfigParser()
- try:
- result[locale] = localeTools.readFile(os.path.join(getLocalesDir(baseDir), locale, 'meta.properties'))
- except:
- result[locale] = {}
- return result
-
-def getTranslators(localeMetadata):
- translators = {}
- for locale in localeMetadata.itervalues():
- if 'translator' in locale:
- for translator in locale['translator'].split(','):
- translator = translator.strip()
- if translator:
- translators[translator] = True
- result = translators.keys()
- result.sort()
- return result
-
-def createManifest(baseDir, params):
- global KNOWN_APPS, defaultLocale
- env = jinja2.Environment(loader=jinja2.FileSystemLoader(buildtools.__path__[0]), autoescape=True, extensions=['jinja2.ext.autoescape'])
- env.filters['translators'] = getTranslators
- template = env.get_template('install.rdf.tmpl')
- templateData = dict(params)
- templateData['localeMetadata'] = readLocaleMetadata(baseDir, params['locales'])
- templateData['KNOWN_APPS'] = KNOWN_APPS
- templateData['defaultLocale'] = defaultLocale
- return template.render(templateData).encode('utf-8')
-
-def readFile(files, params, path, name):
- ignoredFiles = getIgnoredFiles(params)
- if os.path.isdir(path):
- for file in os.listdir(path):
- if file in ignoredFiles:
- continue
- readFile(files, params, os.path.join(path, file), '%s/%s' % (name, file))
- else:
- file = open(path, 'rb')
- data = processFile(path, file.read(), params)
- file.close()
- files[name] = data
-
-def fixupLocales(baseDir, files, params):
- global defaultLocale
-
- # Read in default locale data, it might not be included in files
- defaultLocaleDir = os.path.join(getLocalesDir(baseDir), defaultLocale)
- reference = {}
- ignoredFiles = getIgnoredFiles(params)
- for file in os.listdir(defaultLocaleDir):
- path = os.path.join(defaultLocaleDir, file)
- if file in ignoredFiles or not os.path.isfile(path):
- continue
- data = localeTools.readFile(path)
- if data:
- reference[file] = data
-
- for locale in params['locales']:
- for file in reference.iterkeys():
- path = 'locale/%s/%s' % (locale, file)
- if path in files:
- data = localeTools.parseString(files[path].decode('utf-8'), path)
- for key, value in reference[file].iteritems():
- if not key in data:
- files[path] += localeTools.generateStringEntry(key, value, path).encode('utf-8')
- else:
- files[path] = reference[file]['_origData'].encode('utf-8')
-
-def createChromeJar(baseDir, params, files={}):
- for name, path in getChromeSubdirs(baseDir, params['locales']).iteritems():
- if os.path.isdir(path):
- readFile(files, params, path, name)
- if not params['limitMetadata']:
- fixupLocales(baseDir, files, params)
-
- data = StringIO()
- jar = ZipFile(data, 'w', ZIP_STORED)
- for name, value in files.iteritems():
- jar.writestr(name, value)
- jar.close()
- return data.getvalue()
-
-def readXPIFiles(baseDir, params, files):
- for path in getXPIFiles(baseDir):
- if os.path.exists(path):
- readFile(files, params, path, os.path.basename(path))
-
-def signFiles(files, keyFile):
- import M2Crypto
- manifest = []
- signature = []
-
- def getDigest(data):
- md5 = hashlib.md5()
- md5.update(data)
- sha1 = hashlib.sha1()
- sha1.update(data)
- return 'Digest-Algorithms: MD5 SHA1\nMD5-Digest: %s\nSHA1-Digest: %s\n' % (base64.b64encode(md5.digest()), base64.b64encode(sha1.digest()))
-
- def addSection(manifestData, signaturePrefix):
- manifest.append(manifestData)
- signatureData = ''
- if signaturePrefix:
- signatureData += signaturePrefix
- signatureData += getDigest(manifestData)
- signature.append(signatureData)
-
- addSection('Manifest-Version: 1.0\n', 'Signature-Version: 1.0\n')
- fileNames = files.keys()
- fileNames.sort()
- for fileName in fileNames:
- addSection('Name: %s\n%s' % (fileName, getDigest(files[fileName])), 'Name: %s\n' % fileName)
- files['META-INF/manifest.mf'] = '\n'.join(manifest)
- files['META-INF/zigbert.sf'] = '\n'.join(signature)
-
- keyHandle = open(keyFile, 'rb')
- keyData = keyHandle.read()
- keyHandle.close()
- stack = M2Crypto.X509.X509_Stack()
- first = True
- for match in re.finditer(r'-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----', keyData, re.S):
- if first:
- # Skip first certificate
- first = False
- else:
- stack.push(M2Crypto.X509.load_cert_string(match.group(0)))
-
- mime = M2Crypto.SMIME.SMIME()
- mime.load_key(keyFile)
- mime.set_x509_stack(stack)
- signature = mime.sign(M2Crypto.BIO.MemoryBuffer(files['META-INF/zigbert.sf'].encode('utf-8')), M2Crypto.SMIME.PKCS7_DETACHED | M2Crypto.SMIME.PKCS7_BINARY)
-
- buffer = M2Crypto.BIO.MemoryBuffer()
- signature.write_der(buffer)
- files['META-INF/zigbert.rsa'] = buffer.read()
-
-def writeXPI(files, outFile):
- zip = ZipFile(outFile, 'w', ZIP_DEFLATED)
- names = files.keys()
- names.sort(key=lambda x: '!' if x == 'META-INF/zigbert.rsa' else x)
- for name in names:
- zip.writestr(name, files[name])
- zip.close()
-
-def createBuild(baseDir, outFile=None, locales=None, buildNum=None, releaseBuild=False, keyFile=None, limitMetadata=False):
- if buildNum == None:
- buildNum = getBuildNum(baseDir)
- if locales == None:
- locales = getLocales(baseDir)
- elif locales == 'all':
- locales = getLocales(baseDir, True)
-
- metadata = readMetadata(baseDir)
- version = metadata.get('general', 'version')
- if not releaseBuild:
- version += '.' + buildNum
-
- if limitMetadata:
- for option in metadata.options('compat'):
- if not option in ('firefox', 'thunderbird', 'seamonkey'):
- metadata.remove_option('compat', option)
-
- if outFile == None:
- outFile = getDefaultFileName(baseDir, metadata, version)
-
- params = {
- 'locales': locales,
- 'releaseBuild': releaseBuild,
- 'buildNum': buildNum,
- 'version': version.encode('utf-8'),
- 'metadata': metadata,
- 'limitMetadata': limitMetadata,
- }
- files = {}
- files['install.rdf'] = createManifest(baseDir, params)
- files['chrome/%s.jar' % metadata.get('general', 'baseName')] = createChromeJar(baseDir, params)
- readXPIFiles(baseDir, params, files)
- if keyFile:
- signFiles(files, keyFile)
- writeXPI(files, outFile)
-
-def setupTestEnvironment(baseDir, profileDirs):
- metadata = readMetadata(baseDir)
- params = {
- 'locales': getLocales(baseDir, True),
- 'releaseBuild': True,
- 'buildNum': '',
- 'version': '99.9',
- 'metadata': metadata,
- 'limitMetadata': False,
- }
- files = {}
- files['install.rdf'] = createManifest(baseDir, params)
- for path in getTestEnvFiles(baseDir):
- if os.path.exists(path):
- readFile(files, params, path, os.path.basename(path))
-
- if 'chrome.manifest' in files:
- # Redirect manifest entries to the current directory
- if sys.platform == 'win32':
- import nturl2path
- baseURL = 'file:' + nturl2path.pathname2url(os.path.abspath(baseDir))
- else:
- import urllib
- baseURL = 'file://' + urllib.quote(os.path.abspath(baseDir))
- files['chrome.manifest'] = re.sub(r'\bjar:chrome/\w+\.jar!', '%s/chrome' % baseURL, files['chrome.manifest'])
- files['chrome.manifest'] = re.sub(r'\bresource\s+\S+\s+', r'\0%s/' % baseURL, files['chrome.manifest'])
- files['chrome.manifest'] = re.sub(r'\b(content\s+\S+\s+)(\w+/)', r'\1%s/\2' % baseURL, files['chrome.manifest'])
- if os.path.exists(os.path.join(baseDir, 'mochitest')):
- files['chrome.manifest'] += 'content mochikit %s/mochitest/\n' % baseURL
-
- id = metadata.get('general', 'id')
- for dir in profileDirs:
- # Remove packed XPI file if there is one
- packedPath = os.path.join(dir, 'extensions', '%s.xpi' % id)
- if os.path.isfile(packedPath):
- os.remove(packedPath)
-
- # Replace unpacked dir by new data
- unpackedPath = os.path.join(dir, 'extensions', id)
- if os.path.isdir(unpackedPath):
- shutil.rmtree(unpackedPath)
- for file, data in files.iteritems():
- filePath = os.path.join(unpackedPath, *(file.split('/')))
- parentDir = os.path.dirname(filePath)
- if not os.path.exists(parentDir):
- os.makedirs(parentDir)
- handle = open(filePath, 'wb')
- handle.write(data)
- handle.close()
diff --git a/buildtools/packagerKMeleon.py b/buildtools/packagerKMeleon.py
deleted file mode 100644
index 3d8bbc8..0000000
--- a/buildtools/packagerKMeleon.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import os, subprocess, re, tempfile, shutil, json
-import buildtools.packager as packager
-
-libs = (
- 'libcmt.lib', 'kernel32.lib', 'user32.lib', 'gdi32.lib', 'comctl32.lib',
- 'nspr4.lib', 'plds4.lib', 'plc4.lib', 'xpcom.lib', 'xpcomglue_s.lib',
- 'embed_base_s.lib', 'unicharutil_external_s.lib', 'js3250.lib'
-)
-compileflags = ('-c', '-O1', '-W3', '-MT', '-DXP_WIN', '-Zc:wchar_t-')
-linkflags = ('-DLL', '-NODEFAULTLIB', '-NOLOGO')
-versionflag = '-DABP_VERSION="%s"'
-
-def getKMeleonSourceDir(baseDir):
- return os.path.join(baseDir, 'kmeleon_src')
-
-def getGeckoDir(baseDir):
- return os.path.join(getKMeleonSourceDir(baseDir), 'mozilla', 'mozilla', 'dist')
-
-def getBaseExtensionDir(baseDir):
- return os.path.join(baseDir, 'adblockplus')
-
-def getIncludeDirs(baseDir):
- yield os.path.join(getKMeleonSourceDir(baseDir), 'src')
- geckoIncludeDir = os.path.join(getGeckoDir(baseDir), 'include')
- for dir in ('caps', 'content', 'dom', 'gfx', 'imglib2', 'js', 'layout',
- 'necko', 'nspr', 'pref', 'string', 'webbrwsr', 'widget', 'xpcom',
- 'xpconnect'):
- yield os.path.join(geckoIncludeDir, dir)
-
-def getLibDirs(baseDir):
- yield os.path.join(getGeckoDir(baseDir), 'lib')
-
-def getFileList(baseDir, ext):
- for file in os.listdir(baseDir):
- path = os.path.join(baseDir, file)
- if os.path.isfile(path) and file.endswith(ext):
- yield path
-
-def getSourceFiles(baseDir):
- return getFileList(baseDir, '.cpp')
-
-def getXULFiles(baseDir):
- return getFileList(baseDir, '.xul')
-
-def getMacroFiles(baseDir):
- return getFileList(baseDir, '.kmm')
-
-def getInterfaceFiles(baseDir):
- return getFileList(baseDir, '.xpt')
-
-def getModuleFiles(baseDir):
- return getFileList(baseDir, '.jsm')
-
-def getPrefsFiles(baseDir):
- return getFileList(baseDir, '.js')
-
-def buildDLL(baseDir, fileName, version):
- tempDir = tempfile.mkdtemp()
- try:
- objFiles = []
- for sourceFile in getSourceFiles(baseDir):
- objFile = os.path.join(tempDir, os.path.splitext(os.path.basename(sourceFile))[0] + '.obj')
- objFiles.append(objFile)
- command = ['cl']
- command.extend(compileflags)
- command.append(versionflag % version)
- command.extend(map(lambda d: '-I%s' % d, getIncludeDirs(baseDir)))
- command.append(sourceFile)
- command.append('-Fo%s' % objFile)
- subprocess.Popen(command).communicate()
-
- outFile = os.path.join(tempDir, fileName)
- command = ['link']
- command.extend(objFiles)
- command.extend(libs)
- command.extend(linkflags)
- command.extend(map(lambda d: '-LIBPATH:%s' % d, getLibDirs(baseDir)))
- command.append('-OUT:%s' % outFile)
- subprocess.Popen(command).communicate()
-
- handle = open(outFile, 'rb')
- result = handle.read()
- handle.close()
- return result
- finally:
- shutil.rmtree(tempDir, ignore_errors=True)
-
-def createManifest(baseExtDir, params):
- localeMetadata = packager.readLocaleMetadata(baseExtDir, params['locales'])
-
- manifest = {}
- metadata = params['metadata']
- manifest['id'] = metadata.get('general', 'id')
- manifest['version'] = metadata.get('general', 'version')
- manifest['version'] = params['version']
- manifest['name'] = localeMetadata[packager.defaultLocale]['name']
- manifest['description'] = localeMetadata[packager.defaultLocale]['description']
- manifest['creator'] = metadata.get('general', 'author')
- manifest['homepage'] = metadata.get('homepage', 'default')
- if metadata.has_section('contributors'):
- manifest['contributors'] = map(lambda item: item[1], metadata.items('contributors'))
- manifest['contributors'].sort()
- else:
- manifest['contributors'] = []
- manifest['translators'] = packager.getTranslators(localeMetadata)
- return 'var EXPORTED_SYMBOLS = ["manifest"];\nvar manifest = ' + json.dumps(manifest)
-
-def processChromeManifest(data, baseName):
- # Manifest location is different in K-Meleon, update paths
- data = re.sub(r'jar:chrome/', 'jar:', data)
- data = re.sub(r'(\s)modules/', r'\1../modules/%s/' % baseName, data)
- data = re.sub(r'(\s)defaults/', r'\1../defaults/', data)
- return data
-
-def createBuild(baseDir, outFile=None, locales=None, buildNum=None, releaseBuild=False):
- if buildNum == None:
- buildNum = packager.getBuildNum(baseDir)
-
- baseExtDir = getBaseExtensionDir(baseDir)
- if locales == None:
- locales = packager.getLocales(baseExtDir)
- elif locales == 'all':
- locales = packager.getLocales(baseExtDir, True)
-
- metadata = packager.readMetadata(baseExtDir)
- version = metadata.get('general', 'version')
- if not releaseBuild:
- version += '.' + buildNum
-
- params = {
- 'locales': locales,
- 'releaseBuild': releaseBuild,
- 'buildNum': buildNum,
- 'version': version.encode('utf-8'),
- 'metadata': metadata,
- 'limitMetadata': False,
- }
- baseName = metadata.get('general', 'baseName')
-
- chromeFiles = {}
- for xulFile in getXULFiles(baseDir):
- packager.readFile(chromeFiles, params, xulFile, 'content/ui/%s' % os.path.basename(xulFile))
-
- files = {}
- files['modules/%s/Manifest.jsm' % baseName] = createManifest(baseExtDir, params)
- files['kplugins/%s.dll' % baseName] = buildDLL(baseDir, '%s.dll' % baseName, version)
- files['chrome/%s.jar' % baseName] = packager.createChromeJar(baseExtDir, params, files=chromeFiles)
-
- packager.readFile(files, params, os.path.join(baseExtDir, 'chrome.manifest'), 'chrome/%s.manifest' % baseName)
- files['chrome/%s.manifest' % baseName] = processChromeManifest(files['chrome/%s.manifest' % baseName], baseName)
-
- for macroFile in getMacroFiles(baseDir):
- packager.readFile(files, params, macroFile, 'macros/%s' % os.path.basename(macroFile))
- for interfaceFile in getInterfaceFiles(baseDir):
- packager.readFile(files, params, interfaceFile, 'components/%s' % os.path.basename(interfaceFile))
- for moduleFile in getModuleFiles(baseDir):
- packager.readFile(files, params, moduleFile, 'modules/%s/%s' % (baseName, os.path.basename(moduleFile)))
- for prefsFile in getPrefsFiles(baseDir):
- packager.readFile(files, params, prefsFile, 'defaults/pref/%s' % os.path.basename(prefsFile))
-
- packager.readFile(files, params, os.path.join(baseExtDir, 'defaults'), 'defaults')
- packager.readFile(files, params, os.path.join(baseExtDir, 'modules'), 'modules/%s' %baseName)
-
- # Correct files names (defaults/preferences/ => defaults/pref/)
- newFiles = {}
- for key, value in files.iteritems():
- if key.startswith('defaults/preferences/'):
- key = 'defaults/pref/' + key[len('defaults/preferences/'):]
- newFiles[key] = value
- files = newFiles
-
- # Allow local metadata to overrite settings from base extension
- metadata.read(packager.getMetadataPath(baseDir))
- if outFile == None:
- outFile = packager.getDefaultFileName(baseDir, metadata, version, 'zip')
-
- packager.writeXPI(files, outFile)
diff --git a/buildtools/releaseAutomation.py b/buildtools/releaseAutomation.py
deleted file mode 100644
index 2058638..0000000
--- a/buildtools/releaseAutomation.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import os, re, subprocess, tarfile
-from StringIO import StringIO
-import buildtools.packager as packager
-
-def run(baseDir, version, keyFile, downloadsRepo, buildtoolsRepo):
- # Replace version number in metadata file "manually", ConfigParser will mess
- # up the order of lines.
- handle = open(packager.getMetadataPath(baseDir), 'rb')
- rawMetadata = handle.read()
- handle.close()
- versionRegExp = re.compile(r'^(\s*version\s*=\s*).*', re.I | re.M)
- rawMetadata = re.sub(versionRegExp, r'\g<1>%s' % version, rawMetadata)
- handle = open(packager.getMetadataPath(baseDir), 'wb')
- handle.write(rawMetadata)
- handle.close()
-
- # Read extension name and branch name
- locales = packager.readLocaleMetadata(baseDir, [packager.defaultLocale])
- extensionName = locales[packager.defaultLocale]['name']
-
- metadata = packager.readMetadata(baseDir)
- branchName = metadata.get('general', 'branchname')
-
- # Now commit the change and tag it
- subprocess.Popen(['hg', 'commit', '-R', baseDir, '-m', 'Releasing %s %s' % (extensionName, version)]).communicate()
- subprocess.Popen(['hg', 'tag', '-R', baseDir, '-f', version]).communicate()
-
- # Create a release build
- buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version))
- packager.createBuild(baseDir, outFile=buildPath, releaseBuild=True, keyFile=keyFile)
-
- # Create source archive
- archivePath = os.path.splitext(buildPath)[0] + '-source.tgz'
-
- archiveHandle = open(archivePath, 'wb')
- archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz')
- (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', baseDir, '-t', 'tar', '-X', os.path.join(baseDir, '.hgtags'), '-'], stdout=subprocess.PIPE).communicate()
- repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:')
- for fileInfo in repoArchive:
- fileData = repoArchive.extractfile(fileInfo)
- fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name)
- archive.addfile(fileInfo, fileData)
- repoArchive.close()
- (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', buildtoolsRepo, '-t', 'tar', '-X', os.path.join(buildtoolsRepo, '.hgtags'), '-'], stdout=subprocess.PIPE).communicate()
- repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:')
- for fileInfo in repoArchive:
- fileData = repoArchive.extractfile(fileInfo)
- fileInfo.name = re.sub(r'^[^/]+/', 'buildtools/', fileInfo.name)
- archive.addfile(fileInfo, fileData)
- repoArchive.close()
- archive.close()
- archiveHandle.close()
-
- # Now add the downloads, commit and tag the downloads repo
- tagName = '%s_%s_RELEASE' % (branchName, version.replace('.', '_'))
- subprocess.Popen(['hg', 'add', '-R', downloadsRepo, buildPath, archivePath]).communicate()
- subprocess.Popen(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]).communicate()
- subprocess.Popen(['hg', 'tag', '-R', downloadsRepo, '-f', tagName]).communicate()
-
- # Tag buildtools repository as well
- subprocess.Popen(['hg', 'tag', '-R', buildtoolsRepo, '-f', tagName]).communicate()
-
- # Push all changes
- subprocess.Popen(['hg', 'push', '-R', baseDir]).communicate()
- subprocess.Popen(['hg', 'push', '-R', downloadsRepo]).communicate()
- subprocess.Popen(['hg', 'push', '-R', buildtoolsRepo]).communicate()
diff --git a/buildtools/releaseAutomationKMeleon.py b/buildtools/releaseAutomationKMeleon.py
deleted file mode 100644
index b1b0a65..0000000
--- a/buildtools/releaseAutomationKMeleon.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# coding: utf-8
-
-# The contents of this file are subject to the Mozilla Public License
-# Version 1.1 (the "License"); you may not use this file except in
-# compliance with the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-
-import os, re, subprocess, tarfile
-from StringIO import StringIO
-import buildtools.packager as packager
-import buildtools.packagerKMeleon as packagerKMeleon
-
-def run(baseDir, downloadsRepo, buildtoolsRepo):
- baseExtDir = packagerKMeleon.getBaseExtensionDir(baseDir)
-
- # Read extension name, version and branch name
- locales = packager.readLocaleMetadata(baseExtDir, [packager.defaultLocale])
- extensionName = locales[packager.defaultLocale]['name'] + ' for K-Meleon'
-
- metadata = packager.readMetadata(baseExtDir)
- metadata.read(packager.getMetadataPath(baseDir))
- branchName = metadata.get('general', 'branchname')
- version = metadata.get('general', 'version')
-
- # Tag our source repository
- subprocess.Popen(['hg', 'tag', '-R', baseDir, '-f', version]).communicate()
-
- # Create a release build
- buildPath = os.path.join(downloadsRepo, packager.getDefaultFileName(baseDir, metadata, version, 'zip'))
- packagerKMeleon.createBuild(baseDir, outFile=buildPath, releaseBuild=True)
-
- # Create source archive
- archivePath = os.path.splitext(buildPath)[0] + '-source.tgz'
-
- archiveHandle = open(archivePath, 'wb')
- archive = tarfile.open(fileobj=archiveHandle, name=os.path.basename(archivePath), mode='w:gz')
- (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', baseDir, '-t', 'tar', '-X', os.path.join(baseDir, '.hgtags'), '-'], stdout=subprocess.PIPE).communicate()
- repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:')
- for fileInfo in repoArchive:
- fileData = repoArchive.extractfile(fileInfo)
- fileInfo.name = re.sub(r'^[^/]+/', '', fileInfo.name)
- archive.addfile(fileInfo, fileData)
- repoArchive.close()
- (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', buildtoolsRepo, '-t', 'tar', '-X', os.path.join(buildtoolsRepo, '.hgtags'), '-'], stdout=subprocess.PIPE).communicate()
- repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:')
- for fileInfo in repoArchive:
- fileData = repoArchive.extractfile(fileInfo)
- fileInfo.name = re.sub(r'^[^/]+/', 'buildtools/', fileInfo.name)
- archive.addfile(fileInfo, fileData)
- (data, dummy) = subprocess.Popen(['hg', 'archive', '-R', baseExtDir, '-t', 'tar', '-X', os.path.join(baseExtDir, '.hgtags'), '-'], stdout=subprocess.PIPE).communicate()
- repoArchive = tarfile.open(fileobj=StringIO(data), mode='r:')
- for fileInfo in repoArchive:
- fileData = repoArchive.extractfile(fileInfo)
- fileInfo.name = re.sub(r'^[^/]+/', '%s/' % os.path.basename(baseExtDir), fileInfo.name)
- archive.addfile(fileInfo, fileData)
- repoArchive.close()
- archive.close()
- archiveHandle.close()
-
- # Now add the downloads, commit and tag the downloads repo
- tagName = '%s_%s_RELEASE' % (branchName, version.replace('.', '_'))
- subprocess.Popen(['hg', 'add', '-R', downloadsRepo, buildPath, archivePath]).communicate()
- subprocess.Popen(['hg', 'commit', '-R', downloadsRepo, '-m', 'Releasing %s %s' % (extensionName, version)]).communicate()
- subprocess.Popen(['hg', 'tag', '-R', downloadsRepo, '-f', tagName]).communicate()
-
- # Tag buildtools repository as well
- subprocess.Popen(['hg', 'tag', '-R', buildtoolsRepo, '-f', tagName]).communicate()
-
- # Push all changes
- subprocess.Popen(['hg', 'push', '-R', baseDir]).communicate()
- subprocess.Popen(['hg', 'push', '-R', downloadsRepo]).communicate()
- subprocess.Popen(['hg', 'push', '-R', buildtoolsRepo]).communicate()
diff --git a/chrome.manifest b/chrome.manifest
index bff6063..cbaf1d4 100644
--- a/chrome.manifest
+++ b/chrome.manifest
@@ -10,7 +10,55 @@ content adblockplus jar:chrome/adblockplus.jar!/content/
skin adblockplus classic/1.0 jar:chrome/adblockplus.jar!/skin/
style chrome://global/content/customizeToolbar.xul chrome://adblockplus/skin/overlay.css
style chrome://adblockplus/content/ui/subscriptionSelection.xul chrome://adblockplus/skin/subscriptionSelectionFennec.css application={a23983c0-fd0e-11dc-95ff-0800200c9a66}
-locale adblockplus {{LOCALE}} jar:chrome/adblockplus.jar!/locale/{{LOCALE}}/
+locale adblockplus en-US jar:chrome/adblockplus.jar!/locale/en-US/
+locale adblockplus ar jar:chrome/adblockplus.jar!/locale/ar/
+locale adblockplus bg jar:chrome/adblockplus.jar!/locale/bg/
+locale adblockplus ca jar:chrome/adblockplus.jar!/locale/ca/
+locale adblockplus cs jar:chrome/adblockplus.jar!/locale/cs/
+locale adblockplus da jar:chrome/adblockplus.jar!/locale/da/
+locale adblockplus de jar:chrome/adblockplus.jar!/locale/de/
+locale adblockplus el jar:chrome/adblockplus.jar!/locale/el/
+locale adblockplus en-GB jar:chrome/adblockplus.jar!/locale/en-GB/
+locale adblockplus eo jar:chrome/adblockplus.jar!/locale/eo/
+locale adblockplus es-AR jar:chrome/adblockplus.jar!/locale/es-AR/
+locale adblockplus es-ES jar:chrome/adblockplus.jar!/locale/es-ES/
+locale adblockplus es-MX jar:chrome/adblockplus.jar!/locale/es-MX/
+locale adblockplus et jar:chrome/adblockplus.jar!/locale/et/
+locale adblockplus fa jar:chrome/adblockplus.jar!/locale/fa/
+locale adblockplus fi jar:chrome/adblockplus.jar!/locale/fi/
+locale adblockplus fr jar:chrome/adblockplus.jar!/locale/fr/
+locale adblockplus fy-NL jar:chrome/adblockplus.jar!/locale/fy-NL/
+locale adblockplus gl jar:chrome/adblockplus.jar!/locale/gl/
+locale adblockplus he jar:chrome/adblockplus.jar!/locale/he/
+locale adblockplus hr jar:chrome/adblockplus.jar!/locale/hr/
+locale adblockplus hsb-DE jar:chrome/adblockplus.jar!/locale/hsb-DE/
+locale adblockplus hu jar:chrome/adblockplus.jar!/locale/hu/
+locale adblockplus hy-AM jar:chrome/adblockplus.jar!/locale/hy-AM/
+locale adblockplus is jar:chrome/adblockplus.jar!/locale/is/
+locale adblockplus it jar:chrome/adblockplus.jar!/locale/it/
+locale adblockplus ja jar:chrome/adblockplus.jar!/locale/ja/
+locale adblockplus kk-KZ jar:chrome/adblockplus.jar!/locale/kk-KZ/
+locale adblockplus ko jar:chrome/adblockplus.jar!/locale/ko/
+locale adblockplus lv jar:chrome/adblockplus.jar!/locale/lv/
+locale adblockplus mn jar:chrome/adblockplus.jar!/locale/mn/
+locale adblockplus ms-MY jar:chrome/adblockplus.jar!/locale/ms-MY/
+locale adblockplus nl jar:chrome/adblockplus.jar!/locale/nl/
+locale adblockplus pl jar:chrome/adblockplus.jar!/locale/pl/
+locale adblockplus pt-BR jar:chrome/adblockplus.jar!/locale/pt-BR/
+locale adblockplus pt-PT jar:chrome/adblockplus.jar!/locale/pt-PT/
+locale adblockplus ro jar:chrome/adblockplus.jar!/locale/ro/
+locale adblockplus ru jar:chrome/adblockplus.jar!/locale/ru/
+locale adblockplus sk jar:chrome/adblockplus.jar!/locale/sk/
+locale adblockplus sl jar:chrome/adblockplus.jar!/locale/sl/
+locale adblockplus sq jar:chrome/adblockplus.jar!/locale/sq/
+locale adblockplus sr jar:chrome/adblockplus.jar!/locale/sr/
+locale adblockplus sv-SE jar:chrome/adblockplus.jar!/locale/sv-SE/
+locale adblockplus th jar:chrome/adblockplus.jar!/locale/th/
+locale adblockplus tr jar:chrome/adblockplus.jar!/locale/tr/
+locale adblockplus uk jar:chrome/adblockplus.jar!/locale/uk/
+locale adblockplus vi jar:chrome/adblockplus.jar!/locale/vi/
+locale adblockplus zh-CN jar:chrome/adblockplus.jar!/locale/zh-CN/
+locale adblockplus zh-TW jar:chrome/adblockplus.jar!/locale/zh-TW/
content adblockplus-modules modules/
content adblockplus-defaults defaults/
diff --git a/chrome/content/errors.html b/chrome/adblockplus.jar!/content/errors.html
similarity index 100%
rename from chrome/content/errors.html
rename to chrome/adblockplus.jar!/content/errors.html
diff --git a/chrome/adblockplus.jar!/content/fennecContent.js b/chrome/adblockplus.jar!/content/fennecContent.js
new file mode 100644
index 0000000..b774d81
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/fennecContent.js
@@ -0,0 +1,50 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Fabrice Desré.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Wladimir Palant
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (!("@adblockplus.org/abp/policy;1" in Components.classes))
+ Components.utils.import("chrome://adblockplus-modules/content/ContentPolicyRemote.jsm");
+if (!("@mozilla.org/network/protocol/about;1?what=abp-elemhidehit" in Components.classes))
+ Components.utils.import("chrome://adblockplus-modules/content/ElemHideRemote.jsm");
+
+addEventListener("click", function(event)
+{
+ // Ignore right-clicks
+ if (event.button == 2)
+ return;
+
+ // Search the link associated with the click
+ let link = event.target;
+ while (link && !(link instanceof Ci.nsIDOMHTMLAnchorElement))
+ link = link.parentNode;
+
+ if (!link || !/^abp:\/*subscribe\/*\?(.*)/i.test(link.href)) /**/
+ return;
+
+ // This is our link - make sure the browser doesn't handle it
+ event.preventDefault();
+ event.stopPropagation();
+
+ sendAsyncMessage("AdblockPlus:LinkClick", link.href);
+}, true);
diff --git a/chrome/adblockplus.jar!/content/objtabs.css b/chrome/adblockplus.jar!/content/objtabs.css
new file mode 100644
index 0000000..e6dea25
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/objtabs.css
@@ -0,0 +1,89 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.w3.org/1999/xhtml");
+
+.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%%, .%%CLASSHIDDEN%%
+{
+ position: fixed !important;
+ display: block !important;
+
+ width: auto !important;
+ height: auto !important;
+ right: auto !important;
+ bottom: auto !important;
+ z-index: 65535 !important;
+ float: left !important;
+ border-color: black !important;
+ border-style: solid !important;
+ background: white !important;
+ color: black !important;
+ cursor: pointer !important;
+ white-space: nowrap !important;
+ font-family: Arial,Helvetica,Sans-Serif !important;
+ font-size: 10px !important;
+ font-style: normal !important;
+ font-variant: normal !important;
+ font-weight: normal !important;
+ letter-spacing: normal !important;
+ line-height: normal !important;
+ text-align: center !important;
+ text-decoration: none !important;
+ text-indent: 0px !important;
+ text-transform: none !important;
+ direction: ltr !important;
+ padding: 0px 5px !important;
+ -moz-binding: none !important;
+ -moz-user-focus: none !important;
+ -moz-user-input: none !important;
+ -moz-user-select: none !important;
+}
+
+.%%CLASSVISIBLETOP%%, .%%CLASSHIDDEN%%
+{
+ border-width: 1px 1px 0px 1px !important;
+ -moz-border-radius-topleft: 10px !important;
+ -moz-border-radius-topright: 10px !important;
+ -moz-border-radius-bottomleft: 0px !important;
+ -moz-border-radius-bottomright: 0px !important;
+}
+
+.%%CLASSVISIBLEBOTTOM%%
+{
+ border-width: 0px 1px 1px 1px !important;
+ -moz-border-radius-topleft: 0px !important;
+ -moz-border-radius-topright: 0px !important;
+ -moz-border-radius-bottomleft: 10px !important;
+ -moz-border-radius-bottomright: 10px !important;
+}
+
+.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%%
+{
+ visibility: visible !important;
+}
+
+.%%CLASSHIDDEN%%
+{
+ visibility: hidden !important;
+}
diff --git a/chrome/adblockplus.jar!/content/ui/about.js b/chrome/adblockplus.jar!/content/ui/about.js
new file mode 100644
index 0000000..c4e7d21
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/about.js
@@ -0,0 +1,180 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+try
+{
+ Cu.import("resource://gre/modules/AddonManager.jsm");
+}
+catch (e) {}
+
+function init()
+{
+ let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ if (typeof AddonManager != "undefined")
+ {
+ let addon = AddonManager.getAddonByID(Utils.addonID, function(addon)
+ {
+ loadInstallManifest(addon.getResourceURI("install.rdf"), addon.name, addon.homepageURL);
+ });
+ }
+ else if ("@mozilla.org/extensions/manager;1" in Cc)
+ {
+ let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
+ let rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ let root = rdf.GetResource("urn:mozilla:item:" + Utils.addonID);
+
+ function emResource(prop)
+ {
+ return rdf.GetResource("http://www.mozilla.org/2004/em-rdf#" + prop);
+ }
+
+ function getTarget(prop)
+ {
+ let target = extensionManager.datasource.GetTarget(root, emResource(prop), true);
+ if (target)
+ return target.QueryInterface(Ci.nsIRDFLiteral).Value;
+ else
+ return null;
+ }
+
+ let installLocation = extensionManager.getInstallLocation(Utils.addonID);
+ let installManifestFile = installLocation.getItemFile(Utils.addonID, "install.rdf");
+ loadInstallManifest(ioService.newFileURI(installManifestFile), getTarget("name"), getTarget("homepageURL"));
+ }
+ else
+ {
+ // No add-on manager, no extension manager - we must be running in K-Meleon.
+ // Load Manifest.jsm as last solution.
+ Cu.import(baseURL.spec + "Manifest.jsm");
+ setExtensionData(manifest.name, manifest.version, manifest.homepage, [manifest.creator], manifest.contributors, manifest.translators);
+ }
+}
+
+function loadInstallManifest(installManifestURI, name, homepage)
+{
+ let rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ let ds = rdf.GetDataSource(installManifestURI.spec);
+ let root = rdf.GetResource("urn:mozilla:install-manifest");
+
+ function emResource(prop)
+ {
+ return rdf.GetResource("http://www.mozilla.org/2004/em-rdf#" + prop);
+ }
+
+ function getTargets(prop)
+ {
+ let targets = ds.GetTargets(root, emResource(prop), true);
+ let result = [];
+ while (targets.hasMoreElements())
+ result.push(targets.getNext().QueryInterface(Ci.nsIRDFLiteral).Value);
+ return result;
+ }
+
+ function dataSourceLoaded()
+ {
+ setExtensionData(name, getTargets("version")[0],
+ homepage, getTargets("creator"),
+ getTargets("contributor"), getTargets("translator"));
+ }
+
+ if (ds instanceof Ci.nsIRDFRemoteDataSource && ds.loaded)
+ dataSourceLoaded();
+ else
+ {
+ let sink = ds.QueryInterface(Ci.nsIRDFXMLSink);
+ sink.addXMLSinkObserver({
+ onBeginLoad: function() {},
+ onInterrupt: function() {},
+ onResume: function() {},
+ onEndLoad: function() {
+ sink.removeXMLSinkObserver(this);
+ dataSourceLoaded();
+ },
+ onError: function() {},
+ });
+ }
+}
+
+function cmpNoCase(a, b)
+{
+ let aLC = a.toLowerCase();
+ let bLC = b.toLowerCase();
+ if (aLC < bLC)
+ return -1;
+ else if (aLC > bLC)
+ return 1;
+ else
+ return 0;
+}
+
+function setExtensionData(name, version, homepage, authors, contributors, translators)
+{
+ authors.sort(cmpNoCase);
+ contributors.sort(cmpNoCase);
+ translators.sort(cmpNoCase);
+
+ E("title").value = name;
+ E("version").value = version;
+ E("homepage").value = homepage;
+ E("authors").textContent = authors.join(", ");
+ E("contributors").textContent = contributors.join(", ");
+ E("translators").textContent = translators.join(", ");
+
+ let request = new XMLHttpRequest();
+ request.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml");
+ request.onload = setSubscriptionAuthors;
+ request.send(null);
+}
+
+function setSubscriptionAuthors()
+{
+ let doc = this.responseXML;
+ if (!doc || doc.documentElement.localName != "subscriptions")
+ return;
+
+ let authors = {__proto__: null};
+ for (let node = doc.documentElement.firstChild; node; node = node.nextSibling)
+ {
+ if (node.localName != "subscription" || !node.hasAttribute("author"))
+ continue;
+
+ for each (let author in node.getAttribute("author").split(","))
+ {
+ author = author.replace(/^\s+/, "").replace(/\s+$/, "");
+ if (author == "")
+ continue;
+
+ authors[author] = true;
+ }
+ }
+
+ let list = [];
+ for (let author in authors)
+ list.push(author);
+
+ list.sort(cmpNoCase)
+ E("subscriptionAuthors").textContent = list.join(", ");
+
+ E("mainBox").setAttribute("loaded", "true");
+}
diff --git a/chrome/adblockplus.jar!/content/ui/about.xul b/chrome/adblockplus.jar!/content/ui/about.xul
new file mode 100644
index 0000000..d3a09bf
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/about.xul
@@ -0,0 +1,80 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/about.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/about.dtd">
+
+<dialog
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&dialog.title;"
+ id="adblockAboutWindow"
+ windowtype="abp:about"
+ onload="init()"
+ buttons="accept">
+
+<script type="application/x-javascript;version=1.7" src="utils.js"/>
+<script type="application/x-javascript;version=1.7" src="about.js"/>
+
+<vbox id="mainBox">
+ <description id="title" value=" "/>
+ <hbox align="baseline">
+ <label control="version" value="&version.title;"/>
+ <textbox id="version" flex="1" class="plain" readonly="true" tabindex="-1"/>
+ </hbox>
+
+ <groupbox id="mainGroup" flex="1">
+ <description id="description">
+ &description;
+ </description>
+
+ <description id="homepageTitle" value="&homepage.label;"/>
+ <description id="homepage" class="text-link" onclick="Utils.loadInBrowser(this.getAttribute('value'))"/>
+
+ <vbox id="authorsBox" align="top">
+ <label id="authorsTitle" control="authors" value="&author.label;"/>
+ <description id="authors"/>
+ </vbox>
+
+ <vbox id="contributorsBox" align="top">
+ <label id="contributorsTitle" control="contributors" value="&contributors.label;"/>
+ <description id="contributors"/>
+ </vbox>
+
+ <vbox id="subscriptionAuthorsBox" align="top">
+ <label id="subscriptionAuthorsTitle" control="subscriptionAuthors" value="&subscriptionAuthors.label;"/>
+ <description id="subscriptionAuthors"/>
+ </vbox>
+
+ <vbox id="translatorsBox">
+ <label id="translatorsTitle" control="translators" value="&translators.label;"/>
+ <description id="translators"/>
+ </vbox>
+ </groupbox>
+</vbox>
+
+</dialog>
diff --git a/chrome/adblockplus.jar!/content/ui/composer.js b/chrome/adblockplus.jar!/content/ui/composer.js
new file mode 100644
index 0000000..13555ee
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/composer.js
@@ -0,0 +1,430 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let nodes = null;
+let item = null;
+let advancedMode = false;
+
+function init()
+{
+ [nodes, item] = window.arguments;
+
+ E("filterType").value = (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter ? "filterlist" : "whitelist");
+ E("customPattern").value = item.location;
+
+ let insertionPoint = E("customPatternBox");
+ let addSuggestion = function(address)
+ {
+ // Always drop protocol and www. from the suggestion
+ address = address.replace(/^[\w\-]+:\/+(?:www\.)?/, "");
+
+ let suggestion = document.createElement("radio");
+ suggestion.setAttribute("value", address);
+ suggestion.setAttribute("label", address);
+ suggestion.setAttribute("crop", "center");
+ suggestion.setAttribute("class", "suggestion");
+ insertionPoint.parentNode.insertBefore(suggestion, insertionPoint);
+
+ return address;
+ }
+
+ let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ try
+ {
+ let suggestions = [""];
+
+ let url = ioService.newURI(item.location, null, null)
+ .QueryInterface(Ci.nsIURL);
+ let suffix = (url.query ? "?*" : "");
+ url.query = "";
+ suggestions[1] = addSuggestion(url.spec + suffix);
+
+ let parentURL = ioService.newURI(url.fileName == "" ? ".." : ".", null, url);
+ if (!parentURL.equals(url))
+ suggestions[2] = addSuggestion(parentURL.spec + "*");
+ else
+ suggestions[2] = suggestions[1];
+
+ let rootURL = ioService.newURI("/", null, url);
+ if (!rootURL.equals(parentURL) && !rootURL.equals(url))
+ suggestions[3] = addSuggestion(rootURL.spec + "*");
+ else
+ suggestions[3] = suggestions[2];
+
+ try
+ {
+ suggestions[4] = addSuggestion(url.host.replace(/^www\./, "") + "^");
+
+ // Prefer example.com^ to example.com/*
+ let undesired = suggestions[4].replace(/\^$/, "/*");
+ for (let i = 0; i < suggestions.length - 1; i++)
+ if (suggestions[i] == undesired)
+ suggestions[i] = suggestions[4];
+
+ for (let child = insertionPoint.parentNode.firstChild; child; child = child.nextSibling)
+ {
+ if (child.localName == "radio" && child.getAttribute("value") == undesired)
+ {
+ child.parentNode.removeChild(child);
+ break;
+ }
+ }
+ }
+ catch (e)
+ {
+ suggestions[4] = suggestions[3];
+ }
+
+ try
+ {
+ let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
+ let host = url.host;
+ let baseDomain = effectiveTLD.getBaseDomainFromHost(host);
+ if (baseDomain != host.replace(/^www\./, ""))
+ suggestions[5] = addSuggestion(baseDomain + "^");
+ else
+ suggestions[5] = suggestions[4];
+ }
+ catch (e)
+ {
+ suggestions[5] = suggestions[4];
+ }
+
+ E("patternGroup").value = (Prefs.composer_default in suggestions ? suggestions[Prefs.composer_default] : suggestions[1]);
+ }
+ catch (e)
+ {
+ // IOService returned nsIURI - not much we can do with it
+ addSuggestion(item.location);
+ E("patternGroup").value = "";
+ }
+ if (Prefs.composer_default == 0)
+ E("customPattern").focus();
+ else
+ E("patternGroup").focus();
+
+ let types = [];
+ for (let type in Policy.localizedDescr)
+ {
+ types.push(parseInt(type));
+ }
+ types.sort(function(a, b) {
+ if (a < b)
+ return -1;
+ else if (a > b)
+ return 1;
+ else
+ return 0;
+ });
+
+ let docDomain = item.docDomain;
+ let thirdParty = item.thirdParty;
+
+ if (docDomain)
+ docDomain = docDomain.replace(/^www\./i, "").replace(/\.+$/, "");
+ if (docDomain)
+ E("domainRestriction").value = docDomain;
+
+ E("thirdParty").hidden = !thirdParty;
+ E("firstParty").hidden = thirdParty;
+
+ let typeGroup = E("typeGroup");
+ for each (let type in types)
+ {
+ if (type == Policy.type.ELEMHIDE)
+ continue;
+
+ let typeNode = document.createElement("checkbox");
+ typeNode.setAttribute("value", Policy.typeDescr[type].toLowerCase().replace(/\_/g, "-"));
+ typeNode.setAttribute("label", Policy.localizedDescr[type].toLowerCase());
+ typeNode.setAttribute("checked", "true");
+ if (item.type == type)
+ typeNode.setAttribute("disabled", "true");
+ typeNode.addEventListener("command", updateFilter, false);
+ typeGroup.appendChild(typeNode);
+ }
+
+ let collapseDefault = E("collapseDefault");
+ collapseDefault.label = collapseDefault.getAttribute(Prefs.fastcollapse ? "label_no" : "label_yes");
+ E("collapse").value = "";
+ E("collapse").setAttribute("label", collapseDefault.label);
+
+ let warning = E("disabledWarning");
+ generateLinkText(warning);
+ warning.hidden = Prefs.enabled;
+
+ updatePatternSelection();
+}
+
+function updateFilter()
+{
+ let filter = "";
+
+ let type = E("filterType").value
+ if (type == "whitelist")
+ filter += "@@";
+
+ let pattern = E("patternGroup").value;
+ if (pattern == "")
+ pattern = E("customPattern").value;
+
+ if (E("anchorStart").checked)
+ filter += E("anchorStart").flexibleAnchor ? "||" : "|";
+
+ filter += pattern;
+
+ if (E("anchorEnd").checked)
+ filter += "|";
+
+ if (advancedMode)
+ {
+ let options = [];
+
+ if (E("domainRestrictionEnabled").checked)
+ {
+ let domainRestriction = E("domainRestriction").value.replace(/[,\s]/g, "").replace(/\.+$/, "");
+ if (domainRestriction)
+ options.push("domain=" + domainRestriction);
+ }
+
+ if (E("firstParty").checked)
+ options.push("~third-party");
+ if (E("thirdParty").checked)
+ options.push("third-party");
+
+ if (E("matchCase").checked)
+ options.push("match-case");
+
+ let collapse = E("collapse");
+ disableElement(collapse, type == "whitelist", "value", "");
+ if (collapse.value != "")
+ options.push(collapse.value);
+
+ let enabledTypes = [];
+ let disabledTypes = [];
+ for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
+ {
+ let value = typeNode.getAttribute("value");
+ if (value == "document")
+ disableElement(typeNode, type != "whitelist", "checked", false);
+
+ if (value != "document" || !typeNode.disabled)
+ {
+ if (typeNode.checked)
+ enabledTypes.push(value);
+ else
+ disabledTypes.push("~" + value);
+ }
+ }
+ if (disabledTypes.length < enabledTypes.length)
+ options.push.apply(options, disabledTypes);
+ else
+ options.push.apply(options, enabledTypes);
+
+ if (options.length)
+ filter += "$" + options.join(",");
+ }
+
+ filter = Filter.normalize(filter);
+ E("regexpWarning").hidden = !Filter.regexpRegExp.test(filter);
+
+ let isSlow = false;
+ let compiledFilter = Filter.fromText(filter);
+ if (E("regexpWarning").hidden)
+ {
+ if (compiledFilter instanceof RegExpFilter && defaultMatcher.isSlowFilter(compiledFilter))
+ isSlow = true;
+ }
+ E("shortpatternWarning").hidden = !isSlow;
+
+ E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);
+
+ E("filter").value = filter;
+
+ if (E("disabledWarning").hidden)
+ {
+ let subscription = null;
+ for each (let s in FilterStorage.subscriptions)
+ if (s instanceof SpecialSubscription && s.isFilterAllowed(compiledFilter) && (!subscription || s.priority > subscription.priority))
+ subscription = s;
+
+ let warning = E("groupDisabledWarning");
+ if (subscription && subscription.disabled)
+ {
+ warning.subscription = subscription;
+ generateLinkText(warning, subscription.title);
+ warning.hidden = false;
+ }
+ else
+ warning.hidden = true;
+ }
+ else
+ E("groupDisabledWarning").hidden = true;
+}
+
+function generateLinkText(element, replacement)
+{
+ let template = element.getAttribute("textTemplate");
+ if (typeof replacement != "undefined")
+ template = template.replace(/\?1\?/g, replacement)
+
+ let beforeLink, linkText, afterLink;
+ if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
+ [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
+ else
+ [beforeLink, linkText, afterLink] = ["", template, ""];
+
+ while (element.firstChild && element.firstChild.nodeType != Node.ELEMENT_NODE)
+ element.removeChild(element.firstChild);
+ while (element.lastChild && element.lastChild.nodeType != Node.ELEMENT_NODE)
+ element.removeChild(element.lastChild);
+ if (!element.firstChild)
+ return;
+
+ element.firstChild.textContent = linkText;
+ element.insertBefore(document.createTextNode(beforeLink), element.firstChild);
+ element.appendChild(document.createTextNode(afterLink));
+}
+
+function updatePatternSelection()
+{
+ let pattern = E("patternGroup").value;
+ if (pattern == "")
+ {
+ pattern = E("customPattern").value;
+ }
+ else
+ {
+ E("anchorStart").checked = true;
+ E("anchorEnd").checked = false;
+ }
+
+ function testFilter(/**String*/ filter) /**Boolean*/
+ {
+ return RegExpFilter.fromText(filter).matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);
+ }
+
+ let anchorStartCheckbox = E("anchorStart");
+ if (!/^\*/.test(pattern) && testFilter("||" + pattern))
+ {
+ disableElement(anchorStartCheckbox, false, "checked", false);
+ anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelFlexible"));
+ anchorStartCheckbox.accessKey = anchorStartCheckbox.getAttribute("accesskeyFlexible");
+ anchorStartCheckbox.flexibleAnchor = true;
+ }
+ else
+ {
+ disableElement(anchorStartCheckbox, /^\*/.test(pattern) || !testFilter("|" + pattern), "checked", false);
+ anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelRegular"));
+ anchorStartCheckbox.accessKey = anchorStartCheckbox.getAttribute("accesskeyRegular");
+ anchorStartCheckbox.flexibleAnchor = false;
+ }
+ disableElement(E("anchorEnd"), /[\*\^]$/.test(pattern) || !testFilter(pattern + "|"), "checked", false);
+
+ updateFilter();
+ setAdvancedMode(document.documentElement.getAttribute("advancedMode") == "true");
+}
+
+function updateCustomPattern()
+{
+ E("patternGroup").value = "";
+ updatePatternSelection();
+}
+
+function addFilter() {
+ let filter = Filter.fromText(document.getElementById("filter").value);
+
+ if (filter.disabled)
+ {
+ filter.disabled = false;
+ FilterStorage.triggerObservers("filters enable", [filter]);
+ }
+
+ FilterStorage.addFilter(filter);
+ FilterStorage.saveToDisk();
+
+ if (nodes)
+ Policy.refilterNodes(nodes, item);
+
+ return true;
+}
+
+function setAdvancedMode(mode) {
+ advancedMode = mode;
+
+ var dialog = document.documentElement;
+ dialog.setAttribute("advancedMode", advancedMode);
+
+ var button = dialog.getButton("disclosure");
+ button.setAttribute("label", dialog.getAttribute(advancedMode ? "buttonlabeldisclosure_off" : "buttonlabeldisclosure_on"));
+
+ updateFilter();
+}
+
+function disableElement(element, disable, valueProperty, disabledValue) {
+ if (element.disabled == disable)
+ return;
+
+ element.disabled = disable;
+ if (disable)
+ {
+ element._abpStoredValue = element[valueProperty];
+ element[valueProperty] = disabledValue;
+ }
+ else
+ {
+ if ("_abpStoredValue" in element)
+ element[valueProperty] = element._abpStoredValue;
+ delete element._abpStoredValue;
+ }
+}
+
+function openPreferences() {
+ Utils.openSettingsDialog(item.location, E("filter").value);
+}
+
+function doEnable() {
+ Prefs.enabled = true;
+ E("disabledWarning").hidden = true;
+}
+
+function enableSubscription(subscription)
+{
+ subscription.disabled = false;
+ FilterStorage.triggerObservers("subscriptions enable", [subscription]);
+ FilterStorage.saveToDisk();
+ E("groupDisabledWarning").hidden = true;
+}
+
+/**
+ * Selects or unselects all type checkboxes except those
+ * that are disabled.
+ */
+function selectAllTypes(/**Boolean*/ select)
+{
+ for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
+ if (typeNode.getAttribute("disabled") != "true")
+ typeNode.checked = select;
+ updateFilter();
+}
diff --git a/chrome/adblockplus.jar!/content/ui/composer.xul b/chrome/adblockplus.jar!/content/ui/composer.xul
new file mode 100644
index 0000000..9822c5a
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/composer.xul
@@ -0,0 +1,129 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE overlay SYSTEM "chrome://adblockplus/locale/composer.dtd">
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/composer.css" type="text/css"?>
+
+<dialog id="abp-composer"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&dialog.title;"
+ onload="init()"
+ ondialogaccept="return addFilter()"
+ ondialogdisclosure="setAdvancedMode(!advancedMode)"
+ buttons="accept,cancel,disclosure"
+ width="800px"
+ height="400px"
+ persist="screenX screenY width height sizemode advancedMode"
+ advancedMode="false"
+ buttonlabelaccept="&accept.label;"
+ buttonlabeldisclosure="&advanced.label;"
+ buttonlabeldisclosure_on="&advanced.label;"
+ buttonlabeldisclosure_off="&basic.label;"
+ windowtype="abp:composer">
+
+ <script type="application/x-javascript;version=1.7" src="utils.js"/>
+ <script type="application/x-javascript;version=1.7" src="composer.js"/>
+
+ <popupset>
+ <tooltip id="domainRestrictionHelp" label="&domainRestriction.help;"/>
+ </popupset>
+
+ <description id="disabledWarning" hidden="true" textTemplate="&disabled.warning;">
+ <label class="text-link" onclick="doEnable()"/>
+ </description>
+
+ <description id="groupDisabledWarning" textTemplate="&groupDisabled.warning;" hidden="true">
+ <label class="text-link" onclick="enableSubscription(this.parentNode.subscription)"/>
+ </description>
+
+ <hbox id="filterBox" align="center">
+ <label control="filter" value="&filter.label;" accesskey="&filter.accesskey;"/>
+ <textbox id="filter" flex="1" tabindex="-1" readonly="true"/>
+ <button id="preferences" label="&preferences.label;" accesskey="&preferences.accesskey;" oncommand="openPreferences()"/>
+ </hbox>
+
+ <radiogroup orient="horizontal" id="filterType" oncommand="updateFilter()">
+ <radio label="&type.filter.label;" accesskey="&type.filter.accesskey;" value="filterlist" flex="1"/>
+ <radio label="&type.whitelist.label;" accesskey="&type.whitelist.accesskey;" value="whitelist" flex="1"/>
+ </radiogroup>
+
+ <hbox flex="1">
+ <groupbox id="pattern" flex="1">
+ <caption label="&pattern.label;"/>
+ <radiogroup id="patternGroup" flex="1" oncommand="updatePatternSelection()" style="overflow: auto;">
+ <description id="patternExplanation">&pattern.explanation;</description>
+ <description id="regexpWarning" hidden="true">®exp.warning;</description>
+ <description id="shortpatternWarning" hidden="true">&shortpattern.warning;</description>
+ <description id="matchWarning" hidden="true">&match.warning;</description>
+ <hbox id="customPatternBox">
+ <radio id="customPatternRadio" label="&custom.pattern.label;" accesskey="&custom.pattern.accesskey;" value="" control="customPattern"/>
+ <textbox id="customPattern" flex="1" oninput="updateCustomPattern()"/>
+ </hbox>
+ </radiogroup>
+ <hbox id="anchorGroup" pack="start" align="baseline">
+ <label value="&anchors.label;"/>
+ <description flex="1" style="margin: 0; padding: 0;">
+ <checkbox id="anchorStart" labelRegular="&anchor.start.label;" accesskeyRegular="&anchor.start.accesskey;"
+ labelFlexible="&anchor.start.flexible.label;" accesskeyFlexible="&anchor.start.flexible.accesskey;"
+ oncommand="updateFilter()"/>
+ <checkbox id="anchorEnd" label="&anchor.end.label;" accesskey="&anchor.end.accesskey;" oncommand="updateFilter()"/>
+ </description>
+ </hbox>
+ </groupbox>
+ <groupbox id="options">
+ <caption label="&options.label;"/>
+ <checkbox id="firstParty" label="&firstParty.label;" accesskey="&firstParty.accesskey;" oncommand="updateFilter()"/>
+ <checkbox id="thirdParty" label="&thirdParty.label;" accesskey="&thirdParty.accesskey;" oncommand="updateFilter()"/>
+ <checkbox id="matchCase" label="&matchCase.label;" accesskey="&matchCase.accesskey;" oncommand="updateFilter()"/>
+ <hbox align="baseline">
+ <checkbox id="domainRestrictionEnabled" label="&domainRestriction.label;" accesskey="&domainRestriction.accesskey;" oncommand="updateFilter()"/>
+ <description class="help" value="?" tooltip="domainRestrictionHelp"/>
+ </hbox>
+ <textbox id="domainRestriction" oninput="updateFilter()"/>
+
+ <label id="typeGroupLabel" value="&types.label;"/>
+ <hbox>
+ <label id="selectAllTypes" class="text-link" value="&selectAllTypes.label;" onclick="selectAllTypes(true)"/>
+ <spacer flex="1"/>
+ <label id="unselectAllTypes" class="text-link" value="&unselectAllTypes.label;" onclick="selectAllTypes(false)"/>
+ </hbox>
+ <vbox flex="1" id="typeGroup"/>
+
+ <vbox>
+ <label control="collapse" value="&collapse.label;" accesskey="&collapse.accesskey;"/>
+ <menulist id="collapse" oncommand="updateFilter()">
+ <menupopup>
+ <menuitem id="collapseDefault" value="" label_yes="&collapse.default.yes.label;" label_no="&collapse.default.no.label;" selected="true"/>
+ <menuitem label="&collapse.yes.label;" value="collapse"/>
+ <menuitem label="&collapse.no.label;" value="~collapse"/>
+ </menupopup>
+ </menulist>
+ </vbox>
+ </groupbox>
+ </hbox>
+</dialog>
diff --git a/chrome/adblockplus.jar!/content/ui/fennecOverlay.xul b/chrome/adblockplus.jar!/content/ui/fennecOverlay.xul
new file mode 100644
index 0000000..456a66e
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/fennecOverlay.xul
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Fabrice Desré.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Wladimir Palant
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="main-window">
+ <box id="abp-hooks"
+ getBrowser="return this.window.getBrowser();"
+ addTab="Utils.runAsync(this.window.BrowserUI.newTab, this.window.BrowserUI, arguments[0]);"
+ getContextMenu="return null"
+ getToolbox="return null"
+ getDefaultToolbar="return null"/>
+ </window>
+
+ <!-- Page actions container -->
+ <hbox id="pageactions-container">
+ <pageaction id="abp-site-info"/>
+ </hbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/fennecSettings.xul b/chrome/adblockplus.jar!/content/ui/fennecSettings.xul
new file mode 100644
index 0000000..2089aab
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/fennecSettings.xul
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Fabrice Desré.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Wladimir Palant
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<!DOCTYPE vbox SYSTEM "chrome://adblockplus/locale/settings.dtd">
+<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <setting pref="extensions.adblockplus.enabled" type="bool" title="&enable.label;"/>
+ <setting type="control" title="&fennec.subscription.label;">
+ <menulist id="adblockplus-subscription-list"/>
+ </setting>
+ <setting pref="extensions.adblockplus.fastcollapse" type="bool" title="&collapse.label;"
+ inverted="true"/>
+ <setting id="adblockplus-sync" type="bool" title="&sync.label;"/>
+</vbox>
diff --git a/chrome/adblockplus.jar!/content/ui/fennecSubscription.xul b/chrome/adblockplus.jar!/content/ui/fennecSubscription.xul
new file mode 100644
index 0000000..51bc4ba
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/fennecSubscription.xul
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ - Fabrice Desré
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+
+<!DOCTYPE dialog [
+<!ENTITY % subst SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
+<!ENTITY % prompts SYSTEM "chrome://browser/locale/prompt.dtd">
+%subst;
+%prompts;
+]>
+
+<dialog
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="abpEditSubscription">
+
+<keyset>
+ <key keycode="VK_RETURN" command="abp-subscription-cmd-ok"/>
+ <key keycode="VK_ESCAPE" command="abp-subscription-cmd-cancel"/>
+</keyset>
+<commandset>
+ <command id="abp-subscription-cmd-ok"/>
+ <command id="abp-subscription-cmd-cancel" oncommand="document.getElementById('abpEditSubscription').close();"/>
+</commandset>
+
+<vbox class="prompt-header">
+ <label value="&dialog.title;"/>
+
+ <grid class="prompt-message">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&title.label;" control="abp-subscription-title"/>
+ <description id="abp-subscription-title"/>
+ </row>
+ <row>
+ <label value="&location.label;" control="abp-subscription-url"/>
+ <scrollbox orient="vertical">
+ <description id="abp-subscription-url"/>
+ </scrollbox>
+ </row>
+ </rows>
+ </grid>
+</vbox>
+
+<hbox class="prompt-buttons">
+ <button id="abp-subscription-btn-ok" class="prompt-button" label="&ok.label;" command="abp-subscription-cmd-ok"/>
+ <button class="prompt-button" label="&cancel.label;" command="abp-subscription-cmd-cancel"/>
+</hbox>
+
+</dialog>
diff --git a/chrome/adblockplus.jar!/content/ui/findbar.js b/chrome/adblockplus.jar!/content/ui/findbar.js
new file mode 100644
index 0000000..16b657f
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/findbar.js
@@ -0,0 +1,79 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Fake browser implementation to make findbar widget happy - searches in
+ * the filter list.
+ */
+let fastFindBrowser =
+{
+ fastFind: {
+ searchString: null,
+ foundLink: null,
+ foundEditable: null,
+ caseSensitive: false,
+ get currentWindow() { return fastFindBrowser.contentWindow; },
+
+ find: function(searchString, linksOnly)
+ {
+ this.searchString = searchString;
+ return treeView.find(this.searchString, 0, false, this.caseSensitive);
+ },
+
+ findAgain: function(findBackwards, linksOnly)
+ {
+ return treeView.find(this.searchString, findBackwards ? -1 : 1, false, this.caseSensitive);
+ },
+
+ // Irrelevant for us
+ init: function() {},
+ setDocShell: function() {},
+ setSelectionModeAndRepaint: function() {},
+ collapseSelection: function() {}
+ },
+ currentURI: Utils.makeURI("http://example.com/"),
+ contentWindow: {
+ focus: function()
+ {
+ E("list").focus();
+ },
+ scrollByLines: function(num)
+ {
+ E("list").boxObject.scrollByLines(num);
+ },
+ scrollByPages: function(num)
+ {
+ E("list").boxObject.scrollByPages(num);
+ },
+ },
+
+ addEventListener: function(event, handler, capture)
+ {
+ E("list").addEventListener(event, handler, capture);
+ },
+ removeEventListener: function(event, handler, capture)
+ {
+ E("list").addEventListener(event, handler, capture);
+ },
+}
diff --git a/chrome/adblockplus.jar!/content/ui/firefoxOverlay.xul b/chrome/adblockplus.jar!/content/ui/firefoxOverlay.xul
new file mode 100644
index 0000000..965b899
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/firefoxOverlay.xul
@@ -0,0 +1,98 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="main-window">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks"
+ getBrowser="return this.window.gBrowser;"
+ addTab="
+ if (arguments[1] && 'openNewTabWith' in this.window)
+ this.window.openNewTabWith(arguments[0], this.window.content.document, null, arguments[1], false);
+ else
+ this.window.gBrowser.loadOneTab(arguments[0], null, null, null, false);"
+ getContextMenu="return this.E('contentAreaContextMenu');"
+ getToolbox="return this.E('navigator-toolbox')"
+ getDefaultToolbar="return this.E('addon-bar') || this.E('nav-bar');"
+ toolbarInsertBefore="return this.E('addonbar-closebutton');"
+ unhideToolbar="return this.E('addon-bar')"/>
+ </window>
+
+ <!-- Songbird window -->
+ <sb-support id="mainSupportSet">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks"
+ getBrowser="return this.window.gBrowser;"
+ addTab="this.window.gBrowser.loadOneTab(arguments[0], null, null, null, false);"
+ getContextMenu="return this.E('contentAreaContextMenu');"
+ getToolbox="return this.E('navigator-toolbox')"
+ getDefaultToolbar="return this.E('nav-bar');"/>
+ </sb-support>
+
+ <!-- Status bar -->
+ <statusbar id="status-bar">
+ <statusbarpanel id="abp-status" mousethrough="never" insertbefore="resizerBottomRight"/>
+ </statusbar>
+
+ <!-- Toolbar -->
+ <toolbarpalette id="BrowserToolbarPalette">
+ <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertbefore="print-button"
+ class="toolbarbutton-1"/>
+ </toolbarpalette>
+
+ <!-- Tools menu -->
+ <menupopup id="menu_ToolsPopup">
+ <menuitem id="abp-menuitem" insertafter="javascriptConsole"/>
+ </menupopup>
+
+ <!-- View menu -->
+ <menupopup id="menu_viewPopup">
+ <menuitem id="abp-blockableitems" insertafter="viewSidebarMenuMenu"/>
+ </menupopup>
+
+ <!-- Context menu -->
+ <menupopup id="contentAreaContextMenu">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+
+ <!-- Fake sidebar -->
+ <statuspanel id="statusbar-display" fixed="true"/> <!-- Make sure not to resize this element -->
+ <vbox id="appcontent">
+ <splitter id="abp-sidebar-splitter"/>
+ <vbox id="abp-sidebar"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/flasher.js b/chrome/adblockplus.jar!/content/ui/flasher.js
new file mode 100644
index 0000000..36d6288
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/flasher.js
@@ -0,0 +1,122 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * Draws a blinking border for a list of matching nodes.
+ */
+
+var flasher = {
+ nodes: null,
+ count: 0,
+ timer: null,
+
+ flash: function(nodes)
+ {
+ this.stop();
+ if (nodes)
+ nodes = nodes.filter(function(node) node.nodeType == Node.ELEMENT_NODE);
+ if (!nodes || !nodes.length)
+ return;
+
+ if (Prefs.flash_scrolltoitem && nodes[0].ownerDocument)
+ {
+ // Ensure that at least one node is visible when flashing
+ let wnd = nodes[0].ownerDocument.defaultView;
+ try
+ {
+ let hooks = wnd.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .document.getElementById("abp-hooks");
+ if (hooks.wrappedJSObject)
+ hooks = hooks.wrappedJSObject;
+
+ let viewer = hooks.getBrowser().markupDocumentViewer;
+ viewer.scrollToNode(nodes[0]);
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+ }
+ }
+
+ this.nodes = nodes;
+ this.count = 0;
+
+ this.doFlash();
+ },
+
+ doFlash: function() {
+ if (this.count >= 12) {
+ this.stop();
+ return;
+ }
+
+ if (this.count % 2)
+ this.switchOff();
+ else
+ this.switchOn();
+
+ this.count++;
+
+ this.timer = window.setTimeout(function() {flasher.doFlash()}, 300);
+ },
+
+ stop: function() {
+ if (this.timer) {
+ window.clearTimeout(this.timer);
+ this.timer = null;
+ }
+
+ if (this.nodes) {
+ this.switchOff();
+ this.nodes = null;
+ }
+ },
+
+ setOutline: function(outline, offset)
+ {
+ for (var i = 0; i < this.nodes.length; i++)
+ {
+ if ("style" in this.nodes[i])
+ {
+ this.nodes[i].style.outline = outline;
+ this.nodes[i].style.outlineOffset = offset;
+ }
+ }
+ },
+
+ switchOn: function()
+ {
+ this.setOutline("#CC0000 dotted 2px", "-2px");
+ },
+
+ switchOff: function()
+ {
+ this.setOutline("", "");
+ }
+};
diff --git a/chrome/adblockplus.jar!/content/ui/mailOverlay.xul b/chrome/adblockplus.jar!/content/ui/mailOverlay.xul
new file mode 100644
index 0000000..e7bd449
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/mailOverlay.xul
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="messengerWindow">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks" getBrowser="return this.window.getMessageBrowser();"
+ addTab="this.window.openNewTabWith(arguments[0], (arguments[1] ? this.window.content.document : null), (arguments[1] ? arguments[1].shiftKey : false));"
+ getContextMenu="return this.E('messagePaneContext');"
+ getToolbox="return this.E('mail-toolbox')"
+ getDefaultToolbar="return this.E('msgToolbar');" toolbarInsertBefore="return this.E('button-junk');"/>
+ </window>
+
+ <!-- Status bar -->
+ <statusbar id="status-bar">
+ <statusbarpanel id="abp-status"/>
+ </statusbar>
+
+ <!-- Toolbar -->
+ <toolbarpalette id="MailToolbarPalette">
+ <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertafter="button-junk"
+ class="toolbarbutton-1"/>
+ </toolbarpalette>
+
+ <!-- Tools menu -->
+ <menupopup id="taskPopup">
+ <menuitem id="abp-menuitem" insertafter="downloadmgr,javaScriptConsole"/>
+ </menupopup>
+
+ <!-- Context menu -->
+ <menupopup id="messagePaneContext">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+
+ <!-- Fake sidebar -->
+ <vbox id="messagepanebox">
+ <splitter id="abp-sidebar-splitter"/>
+ <vbox id="abp-sidebar"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/overlay.js b/chrome/adblockplus.jar!/content/ui/overlay.js
new file mode 100644
index 0000000..fed01e6
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/overlay.js
@@ -0,0 +1,51 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+{
+ let Cc = Components.classes;
+ let Ci = Components.interfaces;
+ let Cr = Components.results;
+ let Cu = Components.utils;
+
+ // Use UIReady event to initialize in Fennec (bug 531071)
+ let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
+ let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ let utilsURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Utils.jsm", null, null));
+ let eventName = Cu.import(utilsURL.spec, null).Utils.isFennec ? "UIReady" : "load";
+
+ window.addEventListener(eventName, function()
+ {
+ window.removeEventListener(eventName, arguments.callee, false);
+
+ if (!("@adblockplus.org/abp/private;1" in Cc))
+ {
+ // Force initialization (in Fennec we won't be initialized at this point)
+ let bootstrapURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Bootstrap.jsm", null, null));
+ Cu.import(bootstrapURL.spec, null).Bootstrap.startup();
+ }
+
+ let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
+ Cu.import(baseURL.spec + "AppIntegration.jsm", null).AppIntegration.addWindow(window);
+ }, false);
+}
diff --git a/chrome/adblockplus.jar!/content/ui/overlayGeneral.xul b/chrome/adblockplus.jar!/content/ui/overlayGeneral.xul
new file mode 100644
index 0000000..801dcc8
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/overlayGeneral.xul
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://adblockplus/skin/overlay.css" type="text/css"?>
+
+<!DOCTYPE overlay [
+<!ENTITY % overlayDTD SYSTEM "chrome://adblockplus/locale/overlay.dtd">
+%overlayDTD;
+<!ENTITY % settingsDTD SYSTEM "chrome://adblockplus/locale/settings.dtd">
+%settingsDTD;
+]>
+
+<overlay id="abp-overlay-general" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <script type="application/x-javascript;version=1.7" src="overlay.js"/>
+
+ <popupset id="abp-popupset">
+ <!-- Icon's tooltip -->
+ <tooltip id="abp-tooltip" orient="vertical">
+ <description id="abp-tooltip-action" hidden="true"/>
+ <label id="abp-tooltip-status-label" value="&status.tooltip;"/>
+ <description id="abp-tooltip-status"/>
+ <label id="abp-tooltip-blocked-label" value="&blocked.tooltip;" hidden="true"/>
+ <description id="abp-tooltip-blocked" hidden="true"/>
+ <label id="abp-tooltip-filters-label" value="&filters.tooltip;" hidden="true"/>
+ <vbox id="abp-tooltip-filters" hidden="true"/>
+ <description id="abp-tooltip-more-filters" value="â¦" hidden="true"/>
+ </tooltip>
+
+ <!-- Icon's context menu -->
+ <menupopup id="abp-status-popup">
+ <menuitem id="abp-status-sendReport" label="&sendReport.label;â¦" accesskey="&sendReport.accesskey;" key="abp-key-sendReport" command="abp-command-sendReport"/>
+ <menuitem id="abp-status-opensidebar" label="&opensidebar.label;" accesskey="&opensidebar.accesskey;" key="abp-key-sidebar" command="abp-command-sidebar"/>
+ <menuitem id="abp-status-closesidebar" label="&closesidebar.label;" accesskey="&closesidebar.accesskey;" key="abp-key-sidebar" command="abp-command-sidebar"/>
+ <menuitem id="abp-status-settings" label="&settings.label;â¦" accesskey="&settings.accesskey;" key="abp-key-settings" command="abp-command-settings"/>
+ <menuseparator id="abp-status-whitelist-sep"/>
+ <menuitem id="abp-status-whitelistsite" labeltempl="&whitelist.site.label;" type="checkbox" command="abp-command-togglesitewhitelist"/>
+ <menuitem id="abp-status-whitelistpage" label="&whitelist.page.label;" type="checkbox" command="abp-command-togglepagewhitelist"/>
+ <menuitem id="abp-status-disabled" label="&disable.label;" type="checkbox" key="abp-key-enable" command="abp-command-enable"/>
+ <menuseparator/>
+ <menu id="abp-status-options" label="&options.label;" accesskey="&options.accesskey;">
+ <menupopup id="abp-status-options-popup">
+ <menuitem id="abp-status-frameobjects" label="&objecttabs.label;" accesskey="&objecttabs.accesskey;" type="checkbox" command="abp-command-toggleobjtabs"/>
+ <menuitem id="abp-status-slowcollapse" label="&collapse.label;" accesskey="&collapse.accesskey;" type="checkbox" command="abp-command-togglecollapse"/>
+ <menuitem id="abp-status-sync" label="&sync.label;" accesskey="&sync.accesskey;" type="checkbox" command="abp-command-togglesync"/>
+ <menuseparator/>
+ <menuitem id="abp-status-showintoolbar" label="&showintoolbar.label;" accesskey="&showintoolbar.accesskey;" type="checkbox" command="abp-command-toggleshowintoolbar"/>
+ <menuitem id="abp-status-showinstatusbar" label="&showinstatusbar.label;" accesskey="&showinstatusbar.accesskey;" type="checkbox" command="abp-command-toggleshowinstatusbar"/>
+ </menupopup>
+ </menu>
+
+ <hbox class="abp-recommendbutton" id="abp-status-recommendbutton" pack="center">
+ <button class="abp-recommendbutton-btn" label="&recommend.label;" command="abp-command-recommend" flex="1"/>
+ <toolbarbutton class="abp-recommendbutton-close" command="abp-command-recommend-hide"/>
+ </hbox>
+ </menupopup>
+ </popupset>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset">
+ <!-- Dummy oncommand attributes are work-arounds for bug 371900 -->
+ <command id="abp-command-sendReport" oncommand="//"/>
+ <command id="abp-command-settings" oncommand="//"/>
+ <command id="abp-command-sidebar" oncommand="//"/>
+ <command id="abp-command-togglesitewhitelist"/>
+ <command id="abp-command-togglepagewhitelist"/>
+ <command id="abp-command-toggleobjtabs"/>
+ <command id="abp-command-togglecollapse"/>
+ <command id="abp-command-togglesync"/>
+ <command id="abp-command-toggleshowintoolbar"/>
+ <command id="abp-command-toggleshowinstatusbar"/>
+ <command id="abp-command-enable" oncommand="//"/>
+ <command id="abp-command-recommend"/>
+ <command id="abp-command-recommend-hide"/>
+ </commandset>
+
+ <statusbarpanel id="abp-status" class="statusbarpanel-iconic"
+ context="abp-status-popup" tooltip="abp-tooltip"/>
+
+ <toolbarbutton id="abp-toolbarbutton" label="&toolbarbutton.label;"
+ tooltip="abp-tooltip" context="abp-status-popup"/>
+
+ <box id="abp-hooks" objtabtext="&objecttab.title;â¦" objtabtooltip="&objecttab.tooltip;"/>
+
+ <!-- Tools menu -->
+ <menuitem id="abp-menuitem" label="&menuitem.label;â¦" accesskey="&menuitem.accesskey;" key="abp-key-settings" command="abp-command-settings"/>
+
+ <!-- View menu -->
+ <menuitem id="abp-blockableitems" label="&view.blockableItems.label;" type="checkbox" autocheck="false" key="abp-key-sidebar" command="abp-command-sidebar"/>
+
+ <!-- Context menu -->
+ <menuitem id="abp-image-menuitem" label="&context.image.label;â¦" hidden="true"/>
+ <menuitem id="abp-object-menuitem" label="&context.object.label;â¦" hidden="true"/>
+ <menuitem id="abp-media-menuitem" label="&context.media.label;â¦" hidden="true"/>
+ <menuitem id="abp-frame-menuitem" label="&context.frame.label;â¦" hidden="true"/>
+ <menuitem id="abp-removeWhitelist-menuitem" label="&context.removeWhitelist.label;" hidden="true"/>
+
+ <!-- Fake sidebar -->
+ <splitter id="abp-sidebar-splitter" hidden="true"/>
+ <vbox id="abp-sidebar" height="200" width="200" hidden="true" persist="height width">
+ <toolbox id="abp-sidebar-header">
+ <toolbar id="abp-sidebar-toolbar" align="center" grippyhidden="true" fullscreentoolbar="true">
+ <label id="abp-sidebar-title" control="abp-sidebar-browser" value="&sidebar.title;" flex="1" crop="end"/>
+ <toolbarbutton id="abp-sidebar-close" command="abp-command-sidebar" tooltiptext="&closesidebar.label;"/>
+ </toolbar>
+ </toolbox>
+ <iframe id="abp-sidebar-browser" flex="1"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/prismOverlay.xul b/chrome/adblockplus.jar!/content/ui/prismOverlay.xul
new file mode 100644
index 0000000..7e8bd58
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/prismOverlay.xul
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2008
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="webrunner">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks" getBrowser="return this.E('browser_content');"
+ getContextMenu="return this.E('popup_content');"/>
+ </window>
+
+ <!-- Status bar -->
+ <statusbar id="statusbar">
+ <statusbarpanel id="abp-status" mousethrough="never" insertbefore="button_commands"/>
+ </statusbar>
+
+ <!-- Tools menu -->
+ <menupopup id="popup_tools">
+ <menuitem id="abp-menuitem" insertbefore="menuitem_console"/>
+ </menupopup>
+
+ <!-- Context menu -->
+ <menupopup id="popup_content">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+
+ <!-- Fake sidebar -->
+ <vbox id="box_content">
+ <splitter id="abp-sidebar-splitter"/>
+ <vbox id="abp-sidebar"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/progressBar.xml b/chrome/adblockplus.jar!/content/ui/progressBar.xml
new file mode 100644
index 0000000..c87ab9f
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/progressBar.xml
@@ -0,0 +1,174 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<bindings id="progressBarBindings"
+ xmlns="http://www.mozilla.org/xbl"
+ xmlns:xbl="http://www.mozilla.org/xbl"
+ xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml">
+ <binding id="progressBar">
+ <content orient="horizontal" pack="center">
+ <xul:stack flex="1">
+ <html:canvas anonid="canvas" width="1" height="1"/>
+ <children/>
+ </xul:stack>
+ </content>
+ <implementation>
+ <field name="_gapWidth">5</field>
+ <field name="_arrowheadWidth">5</field>
+ <field name="_canvas">document.getAnonymousElementByAttribute(this, "anonid", "canvas")</field>
+
+ <constructor>
+ <![CDATA[
+ // Run _init() after window loads, correct sizes might be unknown during construction
+ let me = this;
+ let callback = function()
+ {
+ window.removeEventListener("load", callback, false);
+ window.setTimeout(function() me._init(), 0);
+ }
+ window.addEventListener("load", callback, false);
+ ]]>
+ </constructor>
+
+ <method name="_init">
+ <body>
+ <![CDATA[
+ let canvas = this._canvas;
+ let width = canvas.width = canvas.offsetWidth;
+ let height = canvas.height = canvas.offsetHeight;
+
+ let context = canvas.getContext("2d");
+ context.fillStyle = window.getComputedStyle(this, "").color;
+ context.strokeStyle = window.getComputedStyle(this, "").color;
+ context.lineWidth = 1;
+
+ let panelCount = this.childNodes.length;
+ let panelWidth = (width - this._gapWidth * (panelCount - 1) - 1) / panelCount;
+ for (let i = 0; i < panelCount; i++)
+ {
+ context.save();
+ context.translate(Math.round(i * (panelWidth + this._gapWidth)) + 0.5, 0.5);
+ context.beginPath();
+ if (i)
+ context.moveTo(-this._arrowheadWidth, 0);
+ else
+ context.moveTo(0, 0);
+ context.lineTo(panelWidth - this._arrowheadWidth, 0);
+ context.lineTo(panelWidth, (height - 1) / 2);
+ context.lineTo(panelWidth - this._arrowheadWidth, height - 1);
+ if (i)
+ {
+ context.lineTo(-this._arrowheadWidth, height - 1);
+ context.lineTo(0, (height - 1) / 2);
+ context.lineTo(-this._arrowheadWidth, 0);
+ }
+ else
+ {
+ context.lineTo(0, height - 1);
+ context.lineTo(0, 0);
+ }
+ context.stroke();
+ context.restore();
+
+ let childLeft = Math.round(i * (panelWidth + this._gapWidth) + 1);
+ let childWidth = panelWidth - this._arrowheadWidth - 2;
+ let child = this.childNodes[i];
+ child.style.marginLeft = childLeft + "px";
+ child.style.marginRight = (width - childLeft - childWidth) + "px";
+ child.style.width = childWidth + "px";
+ }
+
+ // Resize after initialization should be ignored
+ canvas.parentNode.removeAttribute("flex");
+ ]]>
+ </body>
+ </method>
+
+ <property name="activeItem">
+ <getter>
+ <![CDATA[
+ for (let i = 0; i < this.childNodes.length; i++)
+ {
+ let child = this.childNodes[i];
+ if (/\bactive\b/.test(child.className))
+ return child;
+ }
+ return null;
+ ]]>
+ </getter>
+
+ <setter>
+ <![CDATA[
+ let complete = true;
+ for (let i = 0; i < this.childNodes.length; i++)
+ {
+ let child = this.childNodes[i];
+ if (child == val)
+ complete = false;
+
+ if (!complete && child.value[0] == "â")
+ child.value = child.value.replace(/^â\s*/, "");
+ else if (complete && child.value[0] != "â")
+ child.value = "â " + child.value;
+
+ if (child != val && /\bactive\b/.test(child.className))
+ child.className = child.className.replace(/\s*\bactive\b/, "");
+ else if (child == val && !/\bactive\b/.test(child.className))
+ child.className += " active";
+ }
+ return null;
+ ]]>
+ </setter>
+ </property>
+
+ <property name="activeItemComplete">
+ <getter>
+ <![CDATA[
+ let activeItem = this.activeItem;
+ if (!activeItem)
+ return false;
+ else
+ return activeItem.value[0] == "â";
+ ]]>
+ </getter>
+
+ <setter>
+ <![CDATA[
+ let activeItem = this.activeItem;
+ if (!activeItem)
+ return;
+
+ if (!val && activeItem.value[0] == "â")
+ activeItem.value = child.value.replace(/^â\s*/, "");
+ else if (val && activeItem.value[0] != "â")
+ activeItem.value = "â " + activeItem.value;
+ ]]>
+ </setter>
+ </property>
+ </implementation>
+ </binding>
+</bindings>
diff --git a/chrome/adblockplus.jar!/content/ui/seamonkeyOverlay.xul b/chrome/adblockplus.jar!/content/ui/seamonkeyOverlay.xul
new file mode 100644
index 0000000..b26543f
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/seamonkeyOverlay.xul
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="main-window">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks"
+ getBrowser="return this.window.gBrowser;"
+ addTab="
+ if (arguments[1] && 'openNewTabWith' in this.window)
+ this.window.openNewTabWith(arguments[0], this.window.content.document, arguments[1].shiftKey);
+ else if ('loadOneTab' in this.window.gBrowser) /* SeaMonkey 2.1 */
+ this.window.gBrowser.loadOneTab(arguments[0], {inBackground: false});
+ else /* SeaMonkey 2.0 */
+ this.window.gBrowser.addTab(arguments[0], null, null, true);"
+ getContextMenu="return this.E('contentAreaContextMenu');"
+ getToolbox="return this.E('navigator-toolbox')"
+ getDefaultToolbar="return this.E('PersonalToolbar');" toolbarInsertBefore="return this.E('bookmarks-button');"/>
+ </window>
+
+ <!-- Status bar -->
+ <statusbar id="status-bar">
+ <statusbarpanel id="abp-status" mousethrough="never" insertbefore="resizerBottomRight"/>
+ </statusbar>
+
+ <!-- Toolbar -->
+ <toolbarpalette id="BrowserToolbarPalette">
+ <toolbarbutton id="abp-toolbarbutton" type="menu-button" pack="end"
+ class="toolbarbutton-1"/>
+ </toolbarpalette>
+
+ <!-- Tools menu -->
+ <menupopup id="taskPopup">
+ <menuitem id="abp-menuitem" insertafter="downloadmgr"/>
+ </menupopup>
+
+ <!-- View menu -->
+ <menupopup id="view_toolbars_popup">
+ <menuitem id="abp-blockableitems" insertafter="sidebar-menu"/>
+ </menupopup>
+
+ <!-- Context menu -->
+ <menupopup id="contentAreaContextMenu">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+
+ <!-- Fake sidebar -->
+ <vbox id="appcontent">
+ <splitter id="abp-sidebar-splitter"/>
+ <vbox id="abp-sidebar"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/sendReport.js b/chrome/adblockplus.jar!/content/ui/sendReport.js
new file mode 100644
index 0000000..21b286a
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/sendReport.js
@@ -0,0 +1,1373 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+//
+// Report data template, more data will be added during data collection
+//
+
+let reportData =
+ <report>
+ <adblock-plus version={Utils.addonVersion} build={Utils.addonBuild} locale={Utils.appLocale}/>
+ <application name={Utils.appInfo.name} vendor={Utils.appInfo.vendor} version={Utils.appInfo.version} userAgent={window.navigator.userAgent}/>
+ <platform name="Gecko" version={Utils.appInfo.platformVersion} build={Utils.appInfo.platformBuildID}/>
+ <options>
+ <option id="enabled">{Prefs.enabled}</option>
+ <option id="objecttabs">{Prefs.frameobjects}</option>
+ <option id="collapse">{!Prefs.fastcollapse}</option>
+ <option id="privateBrowsing">{Prefs.privateBrowsing}</option>
+ </options>
+ <window/>
+ <requests/>
+ <filters/>
+ <subscriptions/>
+ <errors/>
+ </report>;
+
+//
+// Data collectors
+//
+
+let reportsListDataSource =
+{
+ json: Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON),
+ list: [],
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ let data = null;
+ try
+ {
+ data = this.json.decode(Prefs.recentReports);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+
+ if (data && "length" in data)
+ {
+ for (let i = 0; i < data.length; i++)
+ {
+ let entry = data[i];
+ if (typeof entry.reportURL == "string" && entry.reportURL &&
+ typeof entry.time == "number" && Date.now() - entry.time < 30*24*60*60*1000)
+ {
+ let newEntry = {site: null, reportURL: entry.reportURL, time: entry.time};
+ if (typeof entry.site == "string" && entry.site)
+ newEntry.site = entry.site;
+ this.list.push(newEntry);
+ }
+ }
+ }
+
+ if (this.list.length > 10)
+ this.list.splice(10);
+
+ E("recentReports").hidden = !this.list.length;
+ if (this.list.length)
+ {
+ let rows = E("recentReportsRows")
+ for (let i = 0; i < this.list.length; i++)
+ {
+ let entry = this.list[i];
+ let row = document.createElement("row");
+
+ let link = document.createElement("description");
+ link.setAttribute("class", "text-link");
+ link.setAttribute("url", entry.reportURL);
+ link.textContent = entry.reportURL.replace(/^.*\/(?=[^\/])/, "");
+ row.appendChild(link);
+
+ let site = document.createElement("description");
+ if (entry.site)
+ site.textContent = entry.site;
+ row.appendChild(site);
+
+ let time = document.createElement("description");
+ time.textContent = Utils.formatTime(entry.time);
+ row.appendChild(time);
+
+ rows.appendChild(row);
+ }
+ }
+
+ callback();
+ },
+
+ addReport: function(site, reportURL)
+ {
+ this.list.unshift({site: site, reportURL: reportURL, time: Date.now()});
+ try
+ {
+ Prefs.recentReports = this.json.encode(this.list);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ },
+
+ clear: function()
+ {
+ this.list = [];
+ Prefs.recentReports = this.json.encode(this.list);
+ E("recentReports").hidden = true;
+ },
+
+ handleClick: function(event)
+ {
+ if (event.button != 0 || !event.target || !event.target.hasAttribute("url"))
+ return;
+
+ Utils.loadInBrowser(event.target.getAttribute("url"));
+ }
+};
+
+let requestsDataSource =
+{
+ requests: reportData.requests,
+ origRequests: [],
+ requestNotifier: null,
+ callback: null,
+ nodeByKey: {__proto__: null},
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ this.callback = callback;
+ this.requestNotifier = new RequestNotifier(wnd, this.onRequestFound, this);
+ },
+
+ onRequestFound: function(frame, node, entry, scanComplete)
+ {
+ if (entry)
+ {
+ let key = entry.location + " " + entry.typeDescr + " " + entry.docDomain;
+ let requestXML
+ if (key in this.nodeByKey)
+ {
+ requestXML = this.nodeByKey[key];
+ requestXML. at count = parseInt(requestXML. at count, 10) + 1;
+ }
+ else
+ {
+ requestXML = <request location={censorURL(entry.location)}
+ type={entry.typeDescr}
+ docDomain={entry.docDomain}
+ thirdParty={entry.thirdParty}
+ count="1"/>;
+ this.nodeByKey[key] = requestXML;
+ this.requests.appendChild(requestXML);
+ }
+
+ // Location is meaningless for element hiding hits
+ if (entry.filter && entry.filter instanceof ElemHideFilter)
+ delete requestXML. at location;
+
+ if (entry.filter)
+ requestXML. at filter = entry.filter.text;
+
+ if (node instanceof Element)
+ {
+ requestXML. at node = node.localName;
+ if (node.namespaceURI)
+ requestXML. at node = node.namespaceURI + "#" + requestXML. at node;
+
+ try
+ {
+ requestXML. at size = node.offsetWidth + "x" + node.offsetHeight;
+ } catch(e) {}
+ }
+ this.origRequests.push(entry);
+ }
+
+ if (scanComplete)
+ {
+ this.requestNotifier.shutdown();
+ this.requestNotifier = null;
+ this.callback();
+ }
+ }
+};
+
+let filtersDataSource =
+{
+ origFilters: [],
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ let wndStats = RequestNotifier.getWindowStatistics(wnd);
+ if (wndStats)
+ {
+ let filters = reportData.filters;
+ for (let f in wndStats.filters)
+ {
+ let filter = Filter.fromText(f)
+ let hitCount = wndStats.filters[f];
+ filters.appendChild(<filter text={filter.text} subscriptions={filter.subscriptions.filter(function(s) !s.disabled).map(function(s) s.url).join(" ")} hitCount={hitCount}/>);
+ this.origFilters.push(filter);
+ }
+ }
+ callback();
+ }
+};
+
+let subscriptionsDataSource =
+{
+ collectData: function(wnd, windowURI, callback)
+ {
+ let subscriptions = reportData.subscriptions;
+ let now = Math.round(Date.now() / 1000);
+ for (let i = 0; i < FilterStorage.subscriptions.length; i++)
+ {
+ let subscription = FilterStorage.subscriptions[i];
+ if (subscription.disabled || !(subscription instanceof RegularSubscription))
+ continue;
+
+ let subscriptionXML = <subscription id={subscription.url} disabledFilters={subscription.filters.filter(function(filter) filter instanceof ActiveFilter && filter.disabled).length}/>;
+ if (subscription.lastDownload)
+ subscriptionXML. at lastDownloadAttempt = subscription.lastDownload - now;
+ if (subscription instanceof DownloadableSubscription)
+ {
+ if (subscription.lastSuccess)
+ subscriptionXML. at lastDownloadSuccess = subscription.lastSuccess - now;
+ if (subscription.softExpiration)
+ subscriptionXML. at softExpiration = subscription.softExpiration - now;
+ if (subscription.expires)
+ subscriptionXML. at hardExpiration = subscription.expires - now;
+ subscriptionXML. at autoDownloadEnabled = subscription.autoDownload;
+ subscriptionXML. at downloadStatus = subscription.downloadStatus;
+ }
+ subscriptions.appendChild(subscriptionXML);
+ }
+ callback();
+ }
+};
+
+let screenshotDataSource =
+{
+ imageOffset: 10,
+
+ // Fields used for color reduction
+ _mapping: [0x00, 0x55, 0xAA, 0xFF],
+ _i: null,
+ _max: null,
+ _pixelData: null,
+ _callback: null,
+
+ // Fields used for user interaction
+ _enabled: true,
+ _canvas: null,
+ _context: null,
+ _selectionType: "mark",
+ _currentData: null,
+ _undoQueue: [],
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ this._callback = callback;
+ this._canvas = E("screenshotCanvas");
+ this._canvas.width = this._canvas.offsetWidth;
+
+ // Do not resize canvas any more (no idea why Gecko requires both to be set)
+ this._canvas.parentNode.style.MozBoxAlign = "center";
+ this._canvas.parentNode.align = "center";
+
+ this._context = this._canvas.getContext("2d");
+ let wndWidth = wnd.document.documentElement.scrollWidth;
+ let wndHeight = wnd.document.documentElement.scrollHeight;
+
+ // Copy scaled screenshot of the webpage. We scale the webpage by width
+ // but leave 10px on each side for easier selecting.
+
+ // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe side.
+ // Also, make sure height is at most five times the width to keep image size down.
+ let copyWidth = Math.min(wndWidth, 30000);
+ let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5);
+ let copyX = Math.max(Math.min(wnd.scrollX - copyWidth / 2, wndWidth - copyWidth), 0);
+ let copyY = Math.max(Math.min(wnd.scrollY - copyHeight / 2, wndHeight - copyHeight), 0);
+
+ let scalingFactor = (this._canvas.width - this.imageOffset * 2) / copyWidth;
+ this._canvas.height = copyHeight * scalingFactor + this.imageOffset * 2;
+
+ this._context.save();
+ this._context.translate(this.imageOffset, this.imageOffset);
+ this._context.scale(scalingFactor, scalingFactor);
+ this._context.drawWindow(wnd, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,255)");
+ this._context.restore();
+
+ // Init canvas settings
+ this._context.fillStyle = "rgb(0, 0, 0)";
+ this._context.strokeStyle = "rgba(255, 0, 0, 0.7)";
+ this._context.lineWidth = 3;
+ this._context.lineJoin = "round";
+
+ // Reduce colors asynchronously
+ this._pixelData = this._context.getImageData(this.imageOffset, this.imageOffset,
+ this._canvas.width - this.imageOffset * 2,
+ this._canvas.height - this.imageOffset * 2);
+ this._max = this._pixelData.width * this._pixelData.height * 4;
+ this._i = 0;
+ Utils.threadManager.currentThread.dispatch(this, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ },
+
+ run: function()
+ {
+ // Process only 5000 bytes at a time to prevent browser hangs
+ let endIndex = Math.min(this._i + 5000, this._max);
+ let i = this._i;
+ for (; i < endIndex; i++)
+ this._pixelData.data[i] = this._mapping[this._pixelData.data[i] >> 6];
+
+ if (i >= this._max)
+ {
+ // Save data back and we are done
+ this._context.putImageData(this._pixelData, this.imageOffset, this.imageOffset);
+ this._callback();
+ }
+ else
+ {
+ this._i = i;
+ Utils.threadManager.currentThread.dispatch(this, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ }
+ },
+
+ get enabled() this._enabled,
+ set enabled(enabled)
+ {
+ if (this._enabled == enabled)
+ return;
+
+ this._enabled = enabled;
+ this._canvas.style.opacity = this._enabled ? "" : "0.3"
+ E("screenshotMarkButton").disabled = !this._enabled;
+ E("screenshotRemoveButton").disabled = !this._enabled;
+ E("screenshotUndoButton").disabled = !this._enabled || !this._undoQueue.length;
+ },
+
+ get selectionType() this._selectionType,
+ set selectionType(type)
+ {
+ if (this._selectionType == type)
+ return;
+
+ // Abort selection already in progress
+ this.abortSelection();
+
+ this._selectionType = type;
+ },
+
+ exportData: function()
+ {
+ if (this.enabled)
+ {
+ reportData.screenshot = this._canvas.toDataURL();
+ reportData.screenshot. at edited = (this._undoQueue.length ? 'true' : 'false');
+ }
+ else
+ delete reportData.screenshot;
+ },
+
+ abortSelection: function()
+ {
+ if (this._currentData && this._currentData.data)
+ {
+ this._context.putImageData(this._currentData.data,
+ Math.min(this._currentData.anchorX, this._currentData.currentX),
+ Math.min(this._currentData.anchorY, this._currentData.currentY));
+ }
+ document.removeEventListener("keypress", this.handleKeyPress, true);
+ this._currentData = null;
+ },
+
+ handleKeyPress: function(event)
+ {
+ if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE)
+ {
+ event.stopPropagation();
+ event.preventDefault();
+ screenshotDataSource.abortSelection();
+ }
+ },
+
+ startSelection: function(event)
+ {
+ if (event.button == 2)
+ this.abortSelection(); // Right mouse button aborts selection
+
+ if (event.button != 0 || !this.enabled)
+ return;
+
+ // Abort selection already in progress
+ this.abortSelection();
+
+ let boxObject = document.getBoxObjectFor(this._canvas);
+ let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY];
+ this._currentData = {
+ data: null,
+ anchorX: x,
+ anchorY: y,
+ currentX: -1,
+ currentY: -1
+ };
+ this.updateSelection(event);
+
+ document.addEventListener("keypress", this.handleKeyPress, true);
+ },
+
+ updateSelection: function(event)
+ {
+ if (event.button != 0 || !this._currentData)
+ return;
+
+ let boxObject = document.getBoxObjectFor(this._canvas);
+ let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY];
+ if (this._currentData.currentX == x && this._currentData.currentY == y)
+ return;
+
+ if (this._currentData.data)
+ {
+ this._context.putImageData(this._currentData.data,
+ Math.min(this._currentData.anchorX, this._currentData.currentX),
+ Math.min(this._currentData.anchorY, this._currentData.currentY));
+ }
+
+ this._currentData.currentX = x;
+ this._currentData.currentY = y;
+
+ let left = Math.min(this._currentData.anchorX, this._currentData.currentX);
+ let right = Math.max(this._currentData.anchorX, this._currentData.currentX);
+ let top = Math.min(this._currentData.anchorY, this._currentData.currentY);
+ let bottom = Math.max(this._currentData.anchorY, this._currentData.currentY);
+
+ let minDiff = (this._selectionType == "mark" ? 3 : 1);
+ if (right - left >= minDiff && bottom - top >= minDiff)
+ this._currentData.data = this._context.getImageData(left, top, right - left, bottom - top);
+ else
+ this._currentData.data = null;
+
+ if (this._selectionType == "mark")
+ {
+ // all coordinates need to be moved 1.5px inwards to get the desired result
+ left += 1.5;
+ right -= 1.5;
+ top += 1.5;
+ bottom -= 1.5;
+ if (left < right && top < bottom)
+ this._context.strokeRect(left, top, right - left, bottom - top);
+ }
+ else if (this._selectionType == "remove")
+ this._context.fillRect(left, top, right - left, bottom - top);
+ },
+
+ stopSelection: function(event)
+ {
+ if (event.button != 0 || !this._currentData)
+ return;
+
+ if (this._currentData.data)
+ {
+ this._undoQueue.push(this._currentData);
+ E("screenshotUndoButton").disabled = false;
+ }
+
+ this._currentData = null;
+ document.removeEventListener("keypress", this.handleKeyPress, true);
+ },
+
+ undo: function()
+ {
+ let op = this._undoQueue.pop();
+ if (!op)
+ return;
+
+ this._context.putImageData(op.data,
+ Math.min(op.anchorX, op.currentX),
+ Math.min(op.anchorY, op.currentY));
+
+ if (!this._undoQueue.length)
+ E("screenshotUndoButton").disabled = true;
+ }
+};
+
+let framesDataSource =
+{
+ site: null,
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ try
+ {
+ this.site = windowURI.host;
+ if (this.site)
+ document.title += " (" + this.site + ")";
+ }
+ catch (e)
+ {
+ // Expected exception - not all URL schemes have a host name
+ }
+
+ reportData.window. at url = censorURL(windowURI ? windowURI.spec : wnd.location.href);
+ if (wnd.opener && wnd.opener.location.href)
+ reportData.window. at opener = censorURL(wnd.opener.location.href);
+ if (wnd.document.referrer)
+ reportData.window. at referrer = censorURL(wnd.document.referrer);
+ this.scanFrames(wnd, reportData.window);
+
+ callback();
+ },
+
+ scanFrames: function(wnd, xmlList)
+ {
+ try
+ {
+ for (let i = 0; i < wnd.frames.length; i++)
+ {
+ let frame = wnd.frames[i];
+ let frameXML = <frame url={censorURL(frame.location.href)}/>;
+ this.scanFrames(frame, frameXML);
+ xmlList.appendChild(frameXML);
+ }
+ }
+ catch (e)
+ {
+ // Don't break if something goes wrong
+ Cu.reportError(e);
+ }
+ }
+};
+
+let errorsDataSource =
+{
+ collectData: function(wnd, windowURI, callback)
+ {
+ let messages = {};
+ Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).getMessageArray(messages, {});
+ messages = messages.value || [];
+ messages = messages.filter(function(message)
+ {
+ return (message instanceof Ci.nsIScriptError &&
+ !/^https?:/i.test(message.sourceName) &&
+ (/adblock/i.test(message.errorMessage) || /adblock/i.test(message.sourceName)));
+ });
+ if (messages.length > 10) // Only the last 10 messages
+ messages = messages.slice(messages.length - 10, messages.length);
+
+ // Censor app and profile paths in error messages
+ let censored = {__proto__: null};
+ let pathList = [["ProfD", "%PROFILE%"], ["GreD", "%GRE%"], ["CurProcD", "%APP%"]];
+ for (let i = 0; i < pathList.length; i++)
+ {
+ let [pathID, placeholder] = pathList[i];
+ try
+ {
+ let file = Utils.dirService.get(pathID, Ci.nsIFile);
+ censored[file.path.replace(/[\\\/]+$/, '')] = placeholder;
+ let uri = Utils.ioService.newFileURI(file);
+ censored[uri.spec.replace(/[\\\/]+$/, '')] = placeholder;
+ } catch(e) {}
+ }
+
+ let errors = reportData.errors;
+ for (let i = 0; i < messages.length; i++)
+ {
+ let message = messages[i];
+
+ let text = message.errorMessage;
+ for (let path in censored)
+ text = text.replace(path, censored[path], "gi");
+ if (text.length > 256)
+ text = text.substr(0, 256) + "...";
+
+ let file = message.sourceName;
+ for (let path in censored)
+ file = file.replace(path, censored[path], "gi");
+ if (file.length > 256)
+ file = file.substr(0, 256) + "...";
+
+ let sourceLine = message.sourceLine;
+ if (sourceLine.length > 256)
+ sourceLine = sourceLine.substr(0, 256) + "...";
+
+ let errorXML = <error type={message.flags & Ci.nsIScriptError.warningFlag ? "warning" : "error"}
+ text={text} file={file} line={message.lineNumber} column={message.columnNumber} sourceLine={sourceLine}/>;
+ errors.appendChild(errorXML);
+ }
+
+ callback();
+ }
+};
+
+let extensionsDataSource =
+{
+ data: <extensions/>,
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ let AddonManager = null;
+ try
+ {
+ let namespace = {};
+ Cu.import("resource://gre/modules/AddonManager.jsm", namespace);
+ AddonManager = namespace.AddonManager;
+ } catch (e) {}
+
+ if (AddonManager)
+ {
+ // Gecko 2.0
+ let me = this;
+ AddonManager.getAddonsByTypes(["extension", "plugin"], function(items)
+ {
+ for (let i = 0; i < items.length; i++)
+ {
+ let item = items[i];
+ if (!item.isActive)
+ continue;
+ me.data.appendChild(<extension id={item.id} name={item.name} type={item.type} version={item.version}/>);
+ }
+ callback();
+ });
+ }
+ else if ("@mozilla.org/extensions/manager;1" in Cc)
+ {
+ // Gecko 1.9.x
+ let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
+ let ds = extensionManager.datasource;
+ let rdfService = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
+ let list = {};
+ let items = extensionManager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION | Ci.nsIUpdateItem.TYPE_PLUGIN, {});
+ for (let i = 0; i < items.length; i++)
+ {
+ let item = items[i];
+
+ // Check whether extension is disabled - yuk...
+ let source = rdfService.GetResource("urn:mozilla:item:" + item.id);
+ let link = rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#isDisabled");
+ let target = ds.GetTarget(source, link, true);
+ if (target instanceof Ci.nsIRDFLiteral && target.Value == "true")
+ continue;
+
+ this.data.appendChild(<extension id={item.id} name={item.name} type={item.type == Ci.nsIUpdateItem.TYPE_EXTENSION ? "extension" : "plugin"} version={item.version}/>);
+ }
+ callback();
+ }
+ else
+ {
+ // No add-on manager, no extension manager - we must be running in K-Meleon.
+ // Skip this step.
+ callback();
+ }
+ },
+
+ exportData: function(doExport)
+ {
+ if (doExport)
+ reportData.extensions = this.data;
+ else
+ delete reportData.extensions;
+ }
+};
+
+let issuesDataSource =
+{
+ contentWnd: null,
+ isEnabled: Prefs.enabled,
+ whitelistFilter: null,
+ disabledFilters: [],
+ disabledSubscriptions: [],
+ ownFilters: [],
+ numSubscriptions: FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription && !subscription.disabled).length,
+ numAppliedFilters: Infinity,
+
+ collectData: function(wnd, windowURI, callback)
+ {
+ this.contentWnd = wnd;
+ this.whitelistFilter = Policy.isWindowWhitelisted(wnd);
+
+ if (!this.whitelistFilter && this.isEnabled)
+ {
+ // Find disabled filters in active subscriptions matching any of the requests
+ let disabledMatcher = new CombinedMatcher();
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (subscription.disabled)
+ continue;
+
+ for each (let filter in subscription.filters)
+ if (filter instanceof BlockingFilter && filter.disabled)
+ disabledMatcher.add(filter);
+ }
+
+ let seenFilters = {__proto__: null};
+ for each (let request in requestsDataSource.origRequests)
+ {
+ if (request.filter)
+ continue;
+
+ let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty);
+ if (filter && !(filter.text in seenFilters))
+ {
+ this.disabledFilters.push(filter);
+ seenFilters[filter.text] = true;
+ }
+ }
+
+ // Find disabled subscriptions with filters matching any of the requests
+ let seenSubscriptions = {__proto__: null};
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (!subscription.disabled)
+ continue;
+
+ disabledMatcher.clear();
+ for each (let filter in subscription.filters)
+ if (filter instanceof BlockingFilter)
+ disabledMatcher.add(filter);
+
+ for each (let request in requestsDataSource.origRequests)
+ {
+ if (request.filter)
+ continue;
+
+ let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty);
+ if (filter && !(subscription.url in seenSubscriptions))
+ {
+ this.disabledSubscriptions.push(subscription);
+ seenSubscriptions[subscription.text] = true;
+ break;
+ }
+ }
+ }
+
+ this.numAppliedFilters = 0;
+ for each (let filter in filtersDataSource.origFilters)
+ {
+ if (filter instanceof WhitelistFilter)
+ continue;
+
+ this.numAppliedFilters++;
+ if (filter.subscriptions.some(function(subscription) subscription instanceof SpecialSubscription))
+ this.ownFilters.push(filter);
+ }
+ }
+
+ callback();
+ },
+
+ updateIssues: function(type)
+ {
+ if (type == "other")
+ {
+ E("typeSelectorPage").next = "typeWarning";
+ return;
+ }
+
+ E("issuesWhitelistBox").hidden = !this.whitelistFilter;
+ E("issuesDisabledBox").hidden = this.isEnabled;
+ E("issuesNoFiltersBox").hidden = (type != "false positive" || this.numAppliedFilters > 0);
+ E("issuesNoSubscriptionsBox").hidden = (type != "false negative" || this.numAppliedFilters > 0 || this.numSubscriptions > 0);
+ E("issuesSubscriptionCountBox").hidden = (this.numSubscriptions < 5);
+
+ let ownFiltersBox = E("issuesOwnFilters");
+ if (this.ownFilters.length && !ownFiltersBox.firstChild)
+ {
+ let template = E("issuesOwnFiltersTemplate");
+ for each (let filter in this.ownFilters)
+ {
+ let element = template.cloneNode(true);
+ element.removeAttribute("id");
+ element.removeAttribute("hidden");
+ element.firstChild.setAttribute("value", filter.text);
+ element.firstChild.setAttribute("tooltiptext", filter.text);
+ element.abpFilter = filter;
+ ownFiltersBox.appendChild(element);
+ }
+ }
+ E("issuesOwnFiltersBox").hidden = (type != "false positive" || this.ownFilters.length == 0);
+
+ let disabledSubscriptionsBox = E("issuesDisabledSubscriptions");
+ if (this.disabledSubscriptions.length && !disabledSubscriptionsBox.firstChild)
+ {
+ let template = E("issuesDisabledSubscriptionsTemplate");
+ for each (let subscription in this.disabledSubscriptions)
+ {
+ let element = template.cloneNode(true);
+ element.removeAttribute("id");
+ element.removeAttribute("hidden");
+ element.firstChild.setAttribute("value", subscription.title);
+ element.setAttribute("tooltiptext", subscription instanceof DownloadableSubscription ? subscription.url : subscription.title);
+ element.abpSubscription = subscription;
+ disabledSubscriptionsBox.appendChild(element);
+ }
+ }
+ E("issuesDisabledSubscriptionsBox").hidden = (type != "false negative" || this.disabledSubscriptions.length == 0);
+
+ let disabledFiltersBox = E("issuesDisabledFilters");
+ if (this.disabledFilters.length && !disabledFiltersBox.firstChild)
+ {
+ let template = E("issuesDisabledFiltersTemplate");
+ for each (let filter in this.disabledFilters)
+ {
+ let element = template.cloneNode(true);
+ element.removeAttribute("id");
+ element.removeAttribute("hidden");
+ element.firstChild.setAttribute("value", filter.text);
+ element.setAttribute("tooltiptext", filter.text);
+ element.abpFilter = filter;
+ disabledFiltersBox.appendChild(element);
+ }
+ }
+ E("issuesDisabledFiltersBox").hidden = (type != "false negative" || this.disabledFilters.length == 0);
+
+ // Don't allow sending report if the page is whitelisted - we need the data.
+ // Also disallow reports without matching filters or without subscriptions,
+ // subscription authors cannot do anything about those.
+ E("issuesOverride").hidden = !E("issuesWhitelistBox").hidden ||
+ !E("issuesDisabledBox").hidden ||
+ !E("issuesNoFiltersBox").hidden ||
+ !E("issuesNoSubscriptionsBox").hidden ||
+ !E("issuesSubscriptionCountBox").hidden;
+
+ if (E("issuesWhitelistBox").hidden && E("issuesDisabledBox").hidden &&
+ E("issuesNoFiltersBox").hidden && E("issuesNoSubscriptionsBox").hidden &&
+ E("issuesOwnFiltersBox").hidden && E("issuesDisabledFiltersBox").hidden &&
+ E("issuesDisabledSubscriptionsBox").hidden && E("issuesSubscriptionCountBox").hidden)
+ {
+ E("typeSelectorPage").next = "screenshot";
+ }
+ else
+ {
+ E("typeSelectorPage").next = "issues";
+ }
+ },
+
+ forceReload: function()
+ {
+ // User changed configuration, don't allow sending report now - page needs
+ // to be reloaded
+ E("issuesOverride").hidden = true;
+ E("issuesChangeMessage").hidden = false;
+ document.documentElement.canRewind = false;
+ document.documentElement.canAdvance = true;
+
+ let contentWnd = this.contentWnd;
+ let nextButton = document.documentElement.getButton("next");
+ nextButton.label = E("issuesPage").getAttribute("reloadButtonLabel");
+ nextButton.accessKey = E("issuesPage").getAttribute("reloadButtonAccesskey");
+ document.documentElement.addEventListener("wizardnext", function(event)
+ {
+ event.preventDefault();
+ event.stopPropagation();
+ window.close();
+ contentWnd.location.reload();
+ }, true);
+ },
+
+ removeWhitelist: function()
+ {
+ if (this.whitelistFilter && this.whitelistFilter.subscriptions.length && !this.whitelistFilter.disabled)
+ {
+ this.whitelistFilter.disabled = true;
+ FilterStorage.triggerObservers("filters disable", [this.whitelistFilter]);
+ }
+ E("issuesWhitelistBox").hidden = true;
+ this.forceReload();
+ },
+
+ enable: function()
+ {
+ Prefs.enabled = true;
+ E("issuesDisabledBox").hidden = true;
+ this.forceReload();
+ },
+
+ addSubscription: function()
+ {
+ let result = {};
+ openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", null, result);
+ if (!("url" in result))
+ return;
+
+ let subscriptionResults = [[result.url, result.title]];
+ if ("mainSubscriptionURL" in result)
+ subscriptionResults.push([result.mainSubscriptionURL, result.mainSubscriptionTitle]);
+
+ for each (let [url, title] in subscriptionResults)
+ {
+ let subscription = Subscription.fromURL(url);
+ if (!subscription)
+ continue;
+
+ FilterStorage.addSubscription(subscription);
+
+ if (subscription.disabled)
+ {
+ subscription.disabled = false;
+ FilterStorage.triggerObservers("subscriptions enable", [subscription]);
+ }
+
+ subscription.title = title;
+ if (subscription instanceof DownloadableSubscription)
+ subscription.autoDownload = result.autoDownload;
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+
+ if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
+ Synchronizer.execute(subscription);
+ }
+ FilterStorage.saveToDisk();
+
+ E("issuesNoSubscriptionsBox").hidden = true;
+ this.forceReload();
+ },
+
+ disableFilter: function(node)
+ {
+ let filter = node.abpFilter;
+ if (filter && filter.subscriptions.length && !filter.disabled)
+ {
+ filter.disabled = true;
+ FilterStorage.triggerObservers("filters disable", [filter]);
+ }
+
+ node.parentNode.removeChild(node);
+ if (!E("issuesOwnFilters").firstChild)
+ E("issuesOwnFiltersBox").hidden = true;
+ this.forceReload();
+ },
+
+ enableFilter: function(node)
+ {
+ let filter = node.abpFilter;
+ if (filter && filter.subscriptions.length && filter.disabled)
+ {
+ filter.disabled = false;
+ FilterStorage.triggerObservers("filters enable", [filter]);
+ }
+
+ node.parentNode.removeChild(node);
+ if (!E("issuesDisabledFilters").firstChild)
+ E("issuesDisabledFiltersBox").hidden = true;
+ this.forceReload();
+ },
+
+
+ enableSubscription: function(node)
+ {
+ let subscription = node.abpSubscription;
+ if (subscription && subscription.disabled)
+ {
+ subscription.disabled = false;
+ FilterStorage.triggerObservers("subscriptions enable", [subscription]);
+ }
+
+ node.parentNode.removeChild(node);
+ if (!E("issuesDisabledSubscriptions").firstChild)
+ E("issuesDisabledSubscriptionsBox").hidden = true;
+ this.forceReload();
+ }
+};
+
+let dataCollectors = [reportsListDataSource, requestsDataSource, filtersDataSource, subscriptionsDataSource,
+ screenshotDataSource, framesDataSource, errorsDataSource, extensionsDataSource,
+ issuesDataSource];
+
+//
+// Wizard logic
+//
+
+function initWizard()
+{
+ // Make sure no issue type is selected by default
+ E("typeGroup").selectedItem = null;
+ document.documentElement.addEventListener("pageshow", updateNextButton, false);
+
+ // Move privacy link
+ let extraButton = document.documentElement.getButton("extra1");
+ extraButton.parentNode.insertBefore(E("privacyLink"), extraButton);
+}
+
+function updateNextButton()
+{
+ let nextButton = document.documentElement.getButton("next");
+ if (!nextButton)
+ return;
+
+ if (document.documentElement.currentPage.id == "commentPage")
+ {
+ if (!nextButton.hasAttribute("_origLabel"))
+ {
+ nextButton.setAttribute("_origLabel", nextButton.getAttribute("label"));
+ nextButton.setAttribute("label", document.documentElement.getAttribute("sendbuttonlabel"));
+ nextButton.setAttribute("_origAccessKey", nextButton.getAttribute("accesskey"));
+ nextButton.setAttribute("accesskey", document.documentElement.getAttribute("sendbuttonaccesskey"));
+ }
+ }
+ else
+ {
+ if (nextButton.hasAttribute("_origLabel"))
+ {
+ nextButton.setAttribute("label", nextButton.getAttribute("_origLabel"));
+ nextButton.removeAttribute("_origLabel");
+ nextButton.setAttribute("accesskey", nextButton.getAttribute("_origAccessKey"));
+ nextButton.removeAttribute("_origAccessKey");
+ }
+ }
+}
+
+function initDataCollectorPage()
+{
+ document.documentElement.canAdvance = false;
+
+ let contentWindow = window.arguments[0];
+ let windowURI = (window.arguments[1] instanceof Ci.nsIURI ? window.arguments[1] : null);
+ let totalSteps = dataCollectors.length;
+ let initNextDataSource = function()
+ {
+ if (!dataCollectors.length)
+ {
+ // We are done, continue to next page
+ document.documentElement.canAdvance = true;
+ document.documentElement.advance();
+ return;
+ }
+
+ let progress = (totalSteps - dataCollectors.length) / totalSteps * 100;
+ if (progress > 0)
+ {
+ let progressMeter = E("dataCollectorProgress");
+ progressMeter.mode = "determined";
+ progressMeter.value = progress;
+ }
+
+ // Continue with the next data source, asynchronously to allow progress meter to update
+ let dataSource = dataCollectors.shift();
+ Utils.runAsync(function()
+ {
+ dataSource.collectData(contentWindow, windowURI, initNextDataSource);
+ });
+ };
+
+ initNextDataSource();
+}
+
+function initTypeSelectorPage()
+{
+ E("progressBar").activeItem = E("typeSelectorHeader");
+ let header = document.getAnonymousElementByAttribute(document.documentElement, "class", "wizard-header");
+ if (header)
+ header.setAttribute("viewIndex", "1");
+
+ document.documentElement.canRewind = false;
+ typeSelectionUpdated();
+}
+
+function typeSelectionUpdated()
+{
+ let selection = E("typeGroup").selectedItem;
+ document.documentElement.canAdvance = (selection != null);
+ if (selection)
+ {
+ if (reportData. at type != selection.value)
+ {
+ E("screenshotCheckbox").checked = (selection.value != "other");
+ E("screenshotCheckbox").doCommand();
+ E("extensionsCheckbox").checked = (selection.value == "other");
+ E("extensionsCheckbox").doCommand();
+ }
+ reportData. at type = selection.value;
+
+ issuesDataSource.updateIssues(selection.value);
+ }
+}
+
+function initIssuesPage()
+{
+ updateIssuesOverride();
+}
+
+function updateIssuesOverride()
+{
+ document.documentElement.canAdvance = E("issuesOverride").checked;
+}
+
+function initTypeWarningPage()
+{
+ updateTypeWarningOverride();
+
+ let textElement = E("typeWarningText");
+ if ("abpInitialized" in textElement)
+ return;
+
+ let template = textElement.textContent.replace(/[\r\n\s]+/g, " ");
+
+ let beforeLink, linkText, afterLink;
+ if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
+ [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
+ else
+ [beforeLink, linkText, afterLink] = ["", template, ""];
+
+ while (textElement.firstChild && textElement.firstChild.nodeType != Node.ELEMENT_NODE)
+ textElement.removeChild(textElement.firstChild);
+ while (textElement.lastChild && textElement.lastChild.nodeType != Node.ELEMENT_NODE)
+ textElement.removeChild(textElement.lastChild);
+
+ if (textElement.firstChild)
+ textElement.firstChild.textContent = linkText;
+ textElement.insertBefore(document.createTextNode(beforeLink), textElement.firstChild);
+ textElement.appendChild(document.createTextNode(afterLink));
+ textElement.abpInitialized = true;
+}
+
+function updateTypeWarningOverride()
+{
+ document.documentElement.canAdvance = E("typeWarningOverride").checked;
+}
+
+function initScreenshotPage()
+{
+ E("progressBar").activeItem = E("screenshotHeader");
+}
+
+function initCommentPage()
+{
+ E("progressBar").activeItem = E("commentPageHeader");
+
+ screenshotDataSource.exportData();
+ updateDataField();
+}
+
+function showDataField()
+{
+ E('dataDeck').selectedIndex = 1;
+ updateDataField();
+ E('data').focus();
+}
+
+let _dataFieldUpdateTimeout = null;
+
+function _updateDataField()
+{
+ let dataField = E("data");
+ let [selectionStart, selectionEnd] = [dataField.selectionStart, dataField.selectionEnd];
+ dataField.value = reportData.toXMLString();
+ dataField.setSelectionRange(selectionStart, selectionEnd);
+}
+
+function updateDataField()
+{
+ // Don't do anything if data field is hidden
+ if (E('dataDeck').selectedIndex != 1)
+ return;
+
+ if (_dataFieldUpdateTimeout)
+ {
+ window.clearTimeout(_dataFieldUpdateTimeout);
+ _dataFieldUpdateTimeout = null;
+ }
+
+ _dataFieldUpdateTimeout = window.setTimeout(_updateDataField, 200);
+}
+
+function updateComment()
+{
+ let value = E("comment").value;
+ reportData.comment = value.substr(0, 1000);
+ E("commentLengthWarning").setAttribute("visible", value.length > 1000);
+ updateDataField();
+}
+
+function updateEmail()
+{
+ reportData.email = E("email").value.replace(/\@/g, " at ").replace(/\./g, " dot ");
+ updateDataField();
+}
+
+function updateExtensions(attach)
+{
+ extensionsDataSource.exportData(attach);
+ updateDataField();
+}
+
+function initSendPage()
+{
+ E("progressBar").activeItem = E("sendPageHeader");
+
+ E("result").hidden = true;
+ E("sendReportErrorBox").hidden = true;
+ E("sendReportMessage").hidden = false;
+ E("sendReportProgress").hidden = false;
+ E("sendReportProgress").mode = "undetermined";
+
+ document.documentElement.canRewind = false;
+ document.documentElement.getButton("finish").disabled = true;
+
+ let guid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString().replace(/[\{\}]/g, "");
+ let url = Prefs.report_submiturl.replace(/%GUID%/g, guid).replace(/%LANG%/g, Utils.appLocale);
+ let request = new XMLHttpRequest();
+ request.open("POST", url);
+ request.setRequestHeader("Content-Type", "text/xml");
+ request.setRequestHeader("X-Adblock-Plus", "1");
+ request.addEventListener("load", reportSent, false);
+ request.addEventListener("error", reportSent, false);
+ if ("upload" in request && request.upload)
+ request.upload.addEventListener("progress", updateReportProgress, false);
+ request.send(reportData.toXMLString());
+}
+
+function updateReportProgress(event)
+{
+ if (!event.lengthComputable)
+ return;
+
+ let progress = Math.round(event.loaded / event.total * 100);
+ if (progress > 0)
+ {
+ let progressMeter = E("sendReportProgress");
+ progressMeter.mode = "determined";
+ progressMeter.value = progress;
+ }
+}
+
+function reportSent(event)
+{
+ let request = event.target;
+ let success = false;
+ let errorMessage = Utils.getString("synchronize_connection_error");
+ try
+ {
+ let status = request.channel.status;
+ if (Components.isSuccessCode(status))
+ {
+ success = (request.status == 200 || request.status == 0);
+ errorMessage = request.status + " " + request.statusText;
+ }
+ else
+ {
+ errorMessage = "0x" + status.toString(16);
+
+ // Try to find the name for the status code
+ let exception = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCException);
+ exception.initialize(null, status, null, null, null, null);
+ if (exception.name)
+ errorMessage = exception.name;
+ }
+ } catch (e) {}
+
+ let result = "";
+ try
+ {
+ result = request.responseText;
+ } catch (e) {}
+
+ result = result.replace(/%CONFIRMATION%/g, encodeHTML(E("result").getAttribute("confirmationMessage")));
+ result = result.replace(/%KNOWNISSUE%/g, encodeHTML(E("result").getAttribute("knownIssueMessage")));
+ result = result.replace(/(<html)\b/, '$1 dir="' + window.getComputedStyle(document.documentElement, "").direction + '"');
+
+ if (!success)
+ {
+ let errorElement = E("sendReportError");
+ let template = errorElement.getAttribute("textTemplate").replace(/[\r\n\s]+/g, " ");
+
+ let beforeLink, linkText, afterLink;
+ if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
+ [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
+ else
+ [beforeLink, linkText, afterLink] = ["", template, ""];
+
+ beforeLink = beforeLink.replace(/\?1\?/g, errorMessage);
+ afterLink = afterLink.replace(/\?1\?/g, errorMessage);
+
+ while (errorElement.firstChild && errorElement.firstChild.nodeType != Node.ELEMENT_NODE)
+ errorElement.removeChild(errorElement.firstChild);
+ while (errorElement.lastChild && errorElement.lastChild.nodeType != Node.ELEMENT_NODE)
+ errorElement.removeChild(errorElement.lastChild);
+
+ if (errorElement.firstChild)
+ errorElement.firstChild.textContent = linkText;
+ errorElement.insertBefore(document.createTextNode(beforeLink), errorElement.firstChild);
+ errorElement.appendChild(document.createTextNode(afterLink));
+
+ E("sendReportErrorBox").hidden = false;
+ }
+
+ E("sendReportProgress").hidden = true;
+
+ let frame = E("result");
+ frame.hidden = false;
+ frame.docShell.allowAuth = false;
+ frame.docShell.allowJavascript = false;
+ frame.docShell.allowMetaRedirects = false;
+ frame.docShell.allowPlugins = false;
+ frame.docShell.allowSubframes = false;
+
+ frame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIComponent(result));
+
+ E("sendReportMessage").hidden = true;
+
+ if (success)
+ {
+ try
+ {
+ let link = request.responseXML.getElementById("link").getAttribute("href");
+ let button = E("copyLink");
+ button.setAttribute("url", link);
+ button.removeAttribute("disabled");
+
+ if (!Prefs.privateBrowsing)
+ reportsListDataSource.addReport(framesDataSource.site, link);
+ } catch (e) {}
+ E("copyLinkBox").hidden = false;
+
+ document.documentElement.getButton("finish").disabled = false;
+ document.documentElement.getButton("cancel").disabled = true;
+ E("progressBar").activeItemComplete = true;
+ }
+}
+
+function processLinkClick(event)
+{
+ event.preventDefault();
+
+ let link = event.target;
+ while (link && !(link instanceof HTMLAnchorElement))
+ link = link.parentNode;
+
+ if (link && (link.protocol == "http:" || link.protocol == "https:"))
+ Utils.loadInBrowser(link.href);
+}
+
+function copyLink(url)
+{
+ let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+ clipboardHelper.copyString(url);
+}
+
+function censorURL(url)
+{
+ return url.replace(/([?;&\/#][^?;&\/#]+?=)[^?;&\/#]+/g, "$1*");
+}
+
+function encodeHTML(str)
+{
+ return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
+}
diff --git a/chrome/adblockplus.jar!/content/ui/sendReport.xul b/chrome/adblockplus.jar!/content/ui/sendReport.xul
new file mode 100644
index 0000000..d1db467
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/sendReport.xul
@@ -0,0 +1,239 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://global/skin/tree.css" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/sendReport.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/sendReport.dtd">
+
+<wizard
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&wizard.title;"
+ id="abpSendReportWizard"
+ onload="initWizard();"
+ width="800"
+ height="550"
+ sendbuttonlabel="&sendButton.label;"
+ sendbuttonaccesskey="&sendButton.accesskey;"
+ windowtype="abp:sendReport">
+
+<script type="application/x-javascript;version=1.7" src="utils.js"/>
+<script type="application/x-javascript;version=1.7" src="sendReport.js"/>
+
+<keyset id="wizardKeys">
+ <key id="undoKey" modifiers="accel" key="Z" oncommand="if (document.documentElement.currentPage.id == 'screenshotPage') screenshotDataSource.undo();"/>
+</keyset>
+
+<box hidden="true">
+ <xbl:bindings id="headerBindings" xmlns:xbl="http://www.mozilla.org/xbl">
+ <xbl:binding id="headerBinding">
+ <xbl:content orient="vertical">
+ <deck xbl:inherits="selectedIndex=viewIndex">
+ <description class="wizard-header-label" xbl:inherits="value=label"/>
+ <progressbar id="progressBar" style="-moz-binding: url(progressBar.xml#progressBar);">
+ <label id="typeSelectorHeader" class="progressLabel" value="&typeSelector.heading;" crop="end"/>
+ <label id="screenshotHeader" class="progressLabel" value="&screenshot.heading;" crop="end"/>
+ <label id="commentPageHeader" class="progressLabel" value="&commentPage.heading;" crop="end"/>
+ <label id="sendPageHeader" class="progressLabel" value="&sendPage.heading;" crop="end"/>
+ </progressbar>
+ </deck>
+ </xbl:content>
+ </xbl:binding>
+ </xbl:bindings>
+
+ <label id="privacyLink" class="text-link" value="&privacyPolicy.label;" onclick="Utils.loadDocLink('reporter_privacy');"/>
+</box>
+
+<wizardpage id="dataCollectorPage" pageid="dataCollector" next="typeSelector" label="&dataCollector.heading;" onpageshow="initDataCollectorPage();">
+ <description>&dataCollector.description;</description>
+
+ <progressmeter id="dataCollectorProgress" mode="undetermined"/>
+</wizardpage>
+
+<wizardpage id="typeSelectorPage" pageid="typeSelector" next="screenshot" label="&typeSelector.heading;" onpageshow="initTypeSelectorPage();">
+ <description>&typeSelector.description;</description>
+
+ <radiogroup id="typeGroup" oncommand="typeSelectionUpdated();">
+ <radio id="typeFalsePositive" value="false positive" label="&typeSelector.falsePositive.label;" accesskey="&typeSelector.falsePositive.accesskey;"/>
+ <description class="radioDescription">&typeSelector.falsePositive.description;</description>
+ <radio id="typeFalseNegative" value="false negative" label="&typeSelector.falseNegative.label;" accesskey="&typeSelector.falseNegative.accesskey;"/>
+ <description class="radioDescription">&typeSelector.falseNegative.description;</description>
+ <radio id="typeOther" value="other" label="&typeSelector.other.label;" accesskey="&typeSelector.other.accesskey;"/>
+ <description class="radioDescription">&typeSelector.other.description;</description>
+ </radiogroup>
+
+ <deck id="recentReports" currentIndex="0" flex="1">
+ <vbox pack="end">
+ <label class="text-link" value="&showRecentReports.label;" onclick="E('recentReports').selectedIndex = 1;"/>
+ </vbox>
+ <groupbox flex="1">
+ <caption label="&recentReports.label;"/>
+ <grid flex="1" id="recentReportsList">
+ <columns>
+ <column flex="2"/>
+ <column flex="1"/>
+ <column/>
+ </columns>
+ <rows id="recentReportsRows" onclick="reportsListDataSource.handleClick(event);"/>
+ </grid>
+
+ <hbox pack="start">
+ <button label="&recentReports.clear.label;" accesskey="&recentReports.clear.accesskey;" oncommand="reportsListDataSource.clear();"/>
+ </hbox>
+ </groupbox>
+ </deck>
+</wizardpage>
+
+<wizardpage id="issuesPage" pageid="issues" next="screenshot" onpageshow="initIssuesPage();" reloadButtonLabel="&reloadButton.label;" reloadButtonAccesskey="&reloadButton.accesskey;">
+ <description>&issues.description;</description>
+
+ <vbox id="issuesBox" flex="1">
+ <groupbox id="issuesWhitelistBox" hidden="true">
+ <description>&issues.whitelist.description;</description>
+ <hbox pack="end">
+ <button label="&issues.whitelist.remove.label;" oncommand="issuesDataSource.removeWhitelist();"/>
+ </hbox>
+ </groupbox>
+ <groupbox id="issuesDisabledBox" hidden="true">
+ <description>&issues.disabled.description;</description>
+ <hbox pack="end">
+ <button label="&issues.disabled.enable.label;" oncommand="issuesDataSource.enable();"/>
+ </hbox>
+ </groupbox>
+ <groupbox id="issuesNoFiltersBox" hidden="true">
+ <description>&issues.nofilters.description;</description>
+ </groupbox>
+ <groupbox id="issuesNoSubscriptionsBox" hidden="true">
+ <description>&issues.nosubscriptions.description;</description>
+ <hbox pack="end">
+ <button label="&issues.nosubscriptions.add.label;" oncommand="issuesDataSource.addSubscription();"/>
+ </hbox>
+ </groupbox>
+ <groupbox id="issuesSubscriptionCountBox" hidden="true">
+ <description>&issues.subscriptionCount.description;</description>
+ <hbox pack="end">
+ <button label="&issues.openPreferences.label;" oncommand="Utils.openSettingsDialog();window.close();"/>
+ </hbox>
+ </groupbox>
+ <groupbox id="issuesOwnFiltersBox" hidden="true">
+ <description>&issues.ownfilters.description;</description>
+ <hbox id="issuesOwnFiltersTemplate" align="center" hidden="true">
+ <description flex="1" crop="end"/>
+ <button label="&issues.ownfilters.disable.label;" oncommand="issuesDataSource.disableFilter(this.parentNode);"/>
+ </hbox>
+ <vbox id="issuesOwnFilters"/>
+ </groupbox>
+ <groupbox id="issuesDisabledSubscriptionsBox" hidden="true">
+ <description>&issues.disabledgroups.description;</description>
+ <hbox id="issuesDisabledSubscriptionsTemplate" align="center" hidden="true">
+ <description flex="1" crop="end"/>
+ <button label="&issues.disabledgroups.enable.label;" oncommand="issuesDataSource.enableSubscription(this.parentNode);"/>
+ </hbox>
+ <vbox id="issuesDisabledSubscriptions"/>
+ </groupbox>
+ <groupbox id="issuesDisabledFiltersBox" hidden="true">
+ <description>&issues.disabledfilters.description;</description>
+ <hbox id="issuesDisabledFiltersTemplate" align="center" hidden="true">
+ <description flex="1" crop="end"/>
+ <button label="&issues.disabledfilters.enable.label;" oncommand="issuesDataSource.enableFilter(this.parentNode);"/>
+ </hbox>
+ <vbox id="issuesDisabledFilters"/>
+ </groupbox>
+ </vbox>
+
+ <checkbox id="issuesOverride" label="&issues.override.label;" accesskey="&issues.override.accesskey;" oncommand="updateIssuesOverride();"/>
+ <description id="issuesChangeMessage" hidden="true">&issues.change.description;</description>
+</wizardpage>
+
+<wizardpage id="typeWarningPage" pageid="typeWarning" next="screenshot" onpageshow="initTypeWarningPage();">
+ <description id="typeWarningText">
+ &typeWarning.description;
+ <label id="typeWarningTextLink" class="text-link" onclick="Utils.loadDocLink('reporter_other_link');"/>
+ </description>
+
+ <checkbox id="typeWarningOverride" label="&typeWarning.override.label;" accesskey="&typeWarning.override.accesskey;" oncommand="updateTypeWarningOverride();"/>
+</wizardpage>
+
+<wizardpage id="screenshotPage" pageid="screenshot" next="comment" label="&screenshot.heading;" onpageshow="initScreenshotPage();">
+ <description>&screenshot.description;</description>
+
+ <checkbox id="screenshotCheckbox" checked="true" label="&screenshot.attach.label;" accesskey="&screenshot.attach.accesskey;" oncommand="screenshotDataSource.enabled = this.checked;"/>
+ <hbox id="screenshotButtons" pack="end">
+ <button id="screenshotMarkButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'mark';" checked="true" label="&screenshot.mark.label;" accesskey="&screenshot.mark.accesskey;"/>
+ <button id="screenshotRemoveButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'remove';" label="&screenshot.remove.label;" accesskey="&screenshot.remove.accesskey;"/>
+ <button id="screenshotUndoButton" oncommand="screenshotDataSource.undo();" disabled="true" label="&screenshot.undo.label;" accesskey="&screenshot.undo.accesskey;"/>
+ </hbox>
+ <vbox id="screenshotBox" flex="1">
+ <canvas xmlns="http://www.w3.org/1999/xhtml" id="screenshotCanvas" onmousedown="screenshotDataSource.startSelection(event);" onmouseup="screenshotDataSource.stopSelection(event);" onmouseout="screenshotDataSource.stopSelection(event);" onmousemove="screenshotDataSource.updateSelection(event);"/>
+ </vbox>
+</wizardpage>
+
+<wizardpage id="commentPage" pageid="comment" next="send" label="&commentPage.heading;" onpageshow="initCommentPage();">
+ <description>&commentPage.description;</description>
+
+ <label class="topLabel" control="comment" value="&comment.label;" accesskey="&comment.accesskey;"/>
+ <textbox id="comment" multiline="true" flex="1" oninput="updateComment();"/>
+ <hbox align="baseline">
+ <label control="email" value="&email.label;" accesskey="&email.accesskey;"/>
+ <textbox id="email" flex="1" maxlength="200" oninput="updateEmail();"/>
+ </hbox>
+ <description id="commentLengthWarning" visible="false">&comment.lengthWarning;</description>
+
+ <checkbox id="extensionsCheckbox" label="&attachExtensions.label;" accesskey="&attachExtensions.accesskey;" oncommand="updateExtensions(this.checked);"/>
+
+ <deck id="dataDeck" selectedIndex="0" flex="2">
+ <vbox pack="start">
+ <label class="text-link" value="&showData.label;" onclick="showDataField();"/>
+ </vbox>
+ <vbox>
+ <label control="data" value="&data.label;" accesskey="&data.accesskey;"/>
+ <textbox id="data" readonly="true" multiline="true" wrap="off" flex="1"/>
+ </vbox>
+ </deck>
+</wizardpage>
+
+<wizardpage id="sendPage" pageid="send" label="&sendPage.heading;" onpageshow="initSendPage();">
+ <description id="sendReportMessage">&sendPage.waitMessage;</description>
+
+ <vbox id="sendReportErrorBox" align="end" hidden="true">
+ <description id="sendReportError" textTemplate="&sendPage.errorMessage;">
+ <label id="sendReportErrorLinks" class="text-link" onclick="Utils.loadDocLink('reporter_connect_issue');"/>
+ </description>
+ <button id="sendRetryButton" label="&sendPage.retry.label;" oncommand="initSendPage();"/>
+ </vbox>
+
+ <progressmeter id="sendReportProgress" mode="undetermined"/>
+
+ <iframe id="result" type="content" flex="1" hidden="true" onclick="processLinkClick(event);"
+ confirmationMessage="&sendPage.confirmation;" knownIssueMessage="&sendPage.knownIssue;"/>
+
+ <hbox id="copyLinkBox" pack="end" hidden="true">
+ <button id="copyLink" disabled="true" label="©Link.label;" accesskey="©Link.accesskey;" oncommand="copyLink(this.getAttribute('url'));"/>
+ </hbox>
+</wizardpage>
+
+</wizard>
diff --git a/chrome/adblockplus.jar!/content/ui/settings.js b/chrome/adblockplus.jar!/content/ui/settings.js
new file mode 100644
index 0000000..d79a185
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/settings.js
@@ -0,0 +1,3049 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const altMask = 2;
+const ctrlMask = 4;
+const metaMask = 8;
+
+let accelMask = ctrlMask;
+try {
+ let accelKey = Utils.prefService.getIntPref("ui.key.accelKey");
+ if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_META)
+ accelMask = metaMask;
+ else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_ALT)
+ accelMask = altMask;
+} catch(e) {}
+
+/**
+ * Initialization function, called when the window is loaded.
+ */
+function init()
+{
+ // Insert Apply button between OK and Cancel
+ let okBtn = document.documentElement.getButton("accept");
+ let cancelBtn = document.documentElement.getButton("cancel");
+ let applyBtn = E("applyButton");
+ let insertBefore = cancelBtn;
+ for (let sibling = cancelBtn; sibling; sibling = sibling.nextSibling)
+ if (sibling == okBtn)
+ insertBefore = okBtn;
+ insertBefore.parentNode.insertBefore(applyBtn, insertBefore);
+ applyBtn.setAttribute("disabled", "true");
+ applyBtn.hidden = false;
+
+ // Convert menubar into toolbar on Mac OS X
+ let isMac = ("@mozilla.org/xre/app-info;1" in Cc && Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS == "Darwin");
+ if (isMac)
+ {
+ function copyAttributes(from, to)
+ {
+ for (let i = 0; i < from.attributes.length; i++)
+ to.setAttribute(from.attributes[i].name, from.attributes[i].value);
+ }
+
+ let menubar = E("menu");
+ let toolbar = document.createElement("toolbar");
+ copyAttributes(menubar, toolbar);
+
+ for (let menu = menubar.firstChild; menu; menu = menu.nextSibling)
+ {
+ let button = document.createElement("toolbarbutton");
+ copyAttributes(menu, button);
+ button.setAttribute("type", "menu");
+ while (menu.firstChild)
+ button.appendChild(menu.firstChild);
+ toolbar.appendChild(button);
+ }
+
+ menubar.parentNode.replaceChild(toolbar, menubar);
+ }
+
+ // Copy View menu contents into list header context menu
+ let viewMenu = E("view-popup").cloneNode(true);
+ let viewContext = E("treecols-context");
+ function replaceId(menuItem)
+ {
+ if (menuItem.id)
+ menuItem.id = "context-" + menuItem.id;
+ for (let child = menuItem.firstChild; child; child = child.nextSibling)
+ replaceId(child);
+ }
+ while (viewMenu.firstChild)
+ {
+ replaceId(viewMenu.firstChild);
+ viewContext.appendChild(viewMenu.firstChild);
+ }
+
+ // Install listener
+ FilterStorage.addObserver(onFilterStorageChange);
+
+ // Capture keypress events - need to get them before the tree does
+ E("listStack").addEventListener("keypress", onListKeyPress, true);
+
+ // Use our fake browser with the findbar - and prevent default action on Enter key
+ E("findbar").browser = fastFindBrowser;
+ E("findbar").addEventListener("keypress", function(event)
+ {
+ // Work-around for bug 490047
+ if (event.keyCode == KeyEvent.DOM_VK_RETURN)
+ event.preventDefault();
+ }, false);
+ // Hack to prevent "highlight all" from getting enabled
+ E("findbar").toggleHighlight = function() {};
+
+ // Initialize tree view
+ E("list").view = treeView;
+ treeView.setEditor(E("listEditor"), E("listEditorParent"));
+
+ // Set the focus to the input field by default
+ E("list").focus();
+
+ // Execute these actions delayed to work around bug 489881
+ Utils.runAsync(function()
+ {
+ treeView.ensureSelection(0);
+
+ let e = document.createEvent("Events");
+ e.initEvent("post-load", false, false);
+ window.dispatchEvent(e);
+ });
+}
+
+/**
+ * This should be called from "post-load" event handler to set the address that is
+ * supposed to be edited. This will initialize the editor and start the editor delayed
+ * (a subsequent call to selectFilter() will prevent the editor from opening).
+ * @param {String} location URL of the address to be taken as template of a new filter
+ */
+function setLocation(location)
+{
+ treeView.editorDummyInit = location;
+}
+
+/**
+ * This should be called from "post-load" event handler to select a particular filter
+ * in the list. If setLocation() was called before, this will also prevent the editor
+ * from opening (though it keeps editor's initial value in case the user opens the editor
+ * himself later).
+ * @param {Filter} filter filter to be selected
+ */
+function selectFilter(filter)
+{
+ treeView.selectFilter(getFilterByText(filter.text));
+ E("list").focus();
+}
+
+/**
+ * Cleanup function to remove observers, called when the window is unloaded.
+ */
+function cleanUp()
+{
+ FilterStorage.removeObserver(onFilterStorageChange);
+}
+
+/**
+ * Map of all subscription wrappers by their download location.
+ * @type Object
+ */
+let subscriptionWrappers = {__proto__: null};
+
+/**
+ * Creates a subscription wrapper that can be modified
+ * without affecting the original subscription. The properties
+ * _sortedFilters and _description are initialized immediately.
+ *
+ * @param {Subscription} subscription subscription to be wrapped
+ * @return {Subscription} subscription wrapper
+ */
+function createSubscriptionWrapper(subscription)
+{
+ if (subscription.url in subscriptionWrappers)
+ return subscriptionWrappers[subscription.url];
+
+ let wrapper =
+ {
+ __proto__: subscription,
+ _isWrapper: true,
+ _sortedFilters: subscription.filters,
+ _description: getSubscriptionDescription(subscription)
+ };
+ subscriptionWrappers[subscription.url] = wrapper;
+ return wrapper;
+}
+
+/**
+ * Retrieves a subscription wrapper by the download location.
+ *
+ * @param {String} url download location of the subscription
+ * @return Subscription subscription wrapper or null for invalid URL
+ */
+function getSubscriptionByURL(url)
+{
+ if (url in subscriptionWrappers)
+ {
+ let result = subscriptionWrappers[url];
+ if (treeView.subscriptions.indexOf(result) < 0)
+ treeView.resortSubscription(result);
+ return result;
+ }
+ else
+ {
+ let result = Subscription.fromURL(url);
+ if (!result || "_isWrapper" in result)
+ return result;
+
+ result = createSubscriptionWrapper(result);
+ result.filters = result.filters.slice();
+ for (let i = 0; i < result.filters.length; i++)
+ result.filters[i] = getFilterByText(result.filters[i].text);
+
+ treeView.resortSubscription(result);
+ return result;
+ }
+}
+
+/**
+ * Map of all filter wrappers by their text representation.
+ * @type Object
+ */
+let filterWrappers = {__proto__: null};
+
+/**
+ * Creates a filter wrapper that can be modified without affecting
+ * the original filter.
+ *
+ * @param {Filter} filter filter to be wrapped
+ * @return {Filter} filter wrapper
+ */
+function createFilterWrapper(filter)
+{
+ if (filter.text in filterWrappers)
+ return filterWrappers[filter.text];
+
+ let wrapper =
+ {
+ __proto__: filter,
+ _isWrapper: true
+ };
+ filterWrappers[filter.text] = wrapper;
+ return wrapper;
+}
+
+/**
+ * Retrieves a filter by its text (might be a filter wrapper).
+ *
+ * @param {String} text text representation of the filter
+ * @return Filter
+ */
+function getFilterByText(text)
+{
+ if (text in filterWrappers)
+ return filterWrappers[text];
+ else
+ return Filter.fromText(text);
+}
+
+/**
+ * Generates the additional rows that should be shown as description
+ * of the subscription in the list.
+ *
+ * @param {Subscription} subscription
+ * @return {Array of String}
+ */
+function getSubscriptionDescription(subscription)
+{
+ let result = [];
+
+ if (!(subscription instanceof RegularSubscription))
+ return result;
+
+ if (subscription instanceof DownloadableSubscription && subscription.upgradeRequired)
+ result.push(Utils.getString("subscription_wrong_version").replace(/\?1\?/, subscription.requiredVersion));
+
+ if (subscription instanceof DownloadableSubscription)
+ result.push(Utils.getString("subscription_source") + " " + subscription.url);
+
+ let status = "";
+ if (subscription instanceof ExternalSubscription)
+ status += Utils.getString("subscription_status_externaldownload");
+ else
+ status += (subscription.autoDownload ? Utils.getString("subscription_status_autodownload") : Utils.getString("subscription_status_manualdownload"));
+
+ status += "; " + Utils.getString("subscription_status_lastdownload") + " ";
+ if (Synchronizer.isExecuting(subscription.url))
+ status += Utils.getString("subscription_status_lastdownload_inprogress");
+ else
+ {
+ status += (subscription.lastDownload > 0 ? Utils.formatTime(subscription.lastDownload * 1000) : Utils.getString("subscription_status_lastdownload_unknown"));
+ if (subscription instanceof DownloadableSubscription && subscription.downloadStatus)
+ {
+ try {
+ status += " (" + Utils.getString(subscription.downloadStatus) + ")";
+ } catch (e) {}
+ }
+ }
+
+ result.push(Utils.getString("subscription_status") + " " + status);
+ return result;
+}
+
+/**
+ * Removes all filters from the list (after a warning).
+ */
+function clearList()
+{
+ if (Utils.confirm(window, Utils.getString("clearall_warning")))
+ treeView.removeUserFilters();
+}
+
+/**
+ * Shows a warning and resets hit statistics on the filters if the user confirms.
+ * @param {Boolean} resetAll If true, statistics of all filters will be reset. If false, only selected filters will be reset.
+ */
+function resetHitCounts(resetAll)
+{
+ if (resetAll && Utils.confirm(window, Utils.getString("resethitcounts_warning")))
+ FilterStorage.resetHitCounts(null);
+ else if (!resetAll && Utils.confirm(window, Utils.getString("resethitcounts_selected_warning")))
+ {
+ let filters = treeView.getSelectedFilters(false);
+ FilterStorage.resetHitCounts(filters.map(function(filter)
+ {
+ return ("_isWrapper" in filter ? filter.__proto__ : filter);
+ }));
+ }
+}
+
+/**
+ * Gets the default download dir, as used by the browser itself.
+ * @return {nsIFile}
+ * @see saveDefaultDir()
+ */
+function getDefaultDir()
+{
+ // Copied from Firefox: getTargetFile() in contentAreaUtils.js
+ try
+ {
+ return Utils.prefService.getComplexValue("browser.download.lastDir", Ci.nsILocalFile);
+ }
+ catch (e)
+ {
+ // No default download location. Default to desktop.
+ let fileLocator = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
+
+ return fileLocator.get("Desk", Ci.nsILocalFile);
+ }
+}
+
+/**
+ * Saves new default download dir after the user chose a different directory to
+ * save his files to.
+ * @param {nsIFile} dir
+ * @see getDefaultDir()
+ */
+function saveDefaultDir(dir)
+{
+ // Copied from Firefox: getTargetFile() in contentAreaUtils.js
+ try
+ {
+ Utils.prefService.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, dir);
+ } catch(e) {};
+}
+
+/**
+ * Adds a set of filters to the list.
+ * @param {Array of String} filters
+ * @return {Filter} last filter added (or null)
+ */
+function addFilters(filters)
+{
+ let commentQueue = [];
+ let lastAdded = null;
+ for each (let text in filters)
+ {
+ // Don't add checksum comments
+ if (/!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(text))
+ continue;
+
+ text = Filter.normalize(text);
+ if (!text)
+ continue;
+
+ let filter = getFilterByText(text);
+ if (filter instanceof CommentFilter)
+ commentQueue.push(filter);
+ else
+ {
+ lastAdded = filter;
+ let subscription = treeView.addFilter(filter, null, null, true);
+ if (subscription && commentQueue.length)
+ {
+ // Insert comments before the filter that follows them
+ for each (let comment in commentQueue)
+ treeView.addFilter(comment, subscription, filter, true);
+ commentQueue.splice(0, commentQueue.length);
+ }
+ }
+ }
+
+ for each (let comment in commentQueue)
+ {
+ lastAdded = comment;
+ treeView.addFilter(comment, null, null, true);
+ }
+
+ return lastAdded;
+}
+
+/**
+ * Lets the user choose a file and reads user-defined filters from this file.
+ */
+function importList()
+{
+ let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ picker.init(window, Utils.getString("import_filters_title"), picker.modeOpen);
+ picker.appendFilters(picker.filterText);
+ picker.appendFilters(picker.filterAll);
+
+ let dir = getDefaultDir();
+ if (dir)
+ picker.displayDirectory = dir;
+
+ if (picker.show() != picker.returnCancel)
+ {
+ saveDefaultDir(picker.file.parent.QueryInterface(Ci.nsILocalFile));
+ let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(picker.file, 0x01, 0444, 0);
+
+ let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
+ stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ stream = stream.QueryInterface(Ci.nsIUnicharLineInputStream);
+
+ let lines = [];
+ let line = {value: null};
+ while (stream.readLine(line))
+ lines.push(Filter.normalize(line.value));
+ if (line.value)
+ lines.push(Filter.normalize(line.value));
+ stream.close();
+
+ if (/\[Adblock(?:\s*Plus\s*([\d\.]+)?)?\]/i.test(lines[0]))
+ {
+ let minVersion = RegExp.$1;
+ let warning = "";
+ if (minVersion && Utils.versionComparator.compare(minVersion, Utils.addonVersion) > 0)
+ warning = Utils.getString("import_filters_wrong_version").replace(/\?1\?/, minVersion) + "\n\n";
+
+ let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
+ let flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
+ promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1 +
+ promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
+ let result = promptService.confirmEx(window, Utils.getString("import_filters_title"),
+ warning + Utils.getString("import_filters_warning"), flags, Utils.getString("overwrite"),
+ null, Utils.getString("append"), null, {});
+ if (result == 1)
+ return;
+
+ if (result == 0)
+ treeView.removeUserFilters();
+
+ lines.shift();
+ addFilters(lines);
+ treeView.ensureSelection(0);
+ }
+ else
+ Utils.alert(window, Utils.getString("invalid_filters_file"));
+ }
+}
+
+/**
+ * Lets the user choose a file and writes user-defined filters into this file.
+ */
+function exportList()
+{
+ if (!treeView.hasUserFilters())
+ return;
+
+ let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
+ picker.init(window, Utils.getString("export_filters_title"), picker.modeSave);
+ picker.defaultExtension = ".txt";
+ picker.appendFilters(picker.filterText);
+ picker.appendFilters(picker.filterAll);
+
+ let dir = getDefaultDir();
+ if (dir)
+ picker.displayDirectory = dir;
+
+ if (picker.show() != picker.returnCancel)
+ {
+ saveDefaultDir(picker.file.parent.QueryInterface(Ci.nsILocalFile));
+ let lineBreak = Utils.getLineBreak();
+
+ let list = ["[Adblock]"];
+ let minVersion = "0";
+ for each (let subscription in treeView.subscriptions)
+ {
+ if (subscription instanceof SpecialSubscription)
+ {
+ for each (let filter in subscription.filters)
+ {
+ // Skip checksums
+ if (filter instanceof CommentFilter && /!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(filter.text))
+ continue;
+
+ list.push(filter.text);
+
+ // Find version requirements of this filter
+ let filterVersion;
+ if (filter instanceof RegExpFilter)
+ {
+ if (filter.contentType & RegExpFilter.typeMap.DONOTTRACK)
+ filterVersion = "1.3.5";
+ else if (filter.contentType & RegExpFilter.typeMap.ELEMHIDE)
+ filterVersion = "1.2";
+ else if (/^(?:@@)?\|\|/.test(filter.text) || (!Filter.regexpRegExp.test(filter.text) && /\^/.test(filter.text)))
+ filterVersion = "1.1";
+ else if (filter.includeDomains != null || filter.excludeDomains != null)
+ filterVersion = "1.0.1";
+ else if (filter.thirdParty != null)
+ filterVersion = "1.0";
+ else if (filter.collapse != null)
+ filterVersion = "0.7.5";
+ else if (Filter.optionsRegExp.test(filter.text))
+ filterVersion = "0.7.1";
+ else if (/^(?:@@)?\|/.test(filter.text) || /\|$/.test(filter.text))
+ filterVersion = "0.6.1.2";
+ else
+ filterVersion = "0";
+ }
+ else if (filter instanceof ElemHideFilter)
+ {
+ if (filter.excludeDomains != null)
+ filterVersion = "1.1";
+ else if (/^#([\w\-]+|\*)(?:\(([\w\-]+)\))?$/.test(filter.text))
+ filterVersion = "0.6.1";
+ else
+ filterVersion = "0.7";
+ }
+ else
+ filterVersion = "0";
+
+ // Adjust version requirements of the complete filter set
+ if (filterVersion != "0" && Utils.versionComparator.compare(minVersion, filterVersion) < 0)
+ minVersion = filterVersion;
+ }
+ }
+ }
+
+ if (minVersion != "0")
+ {
+ if (Utils.versionComparator.compare(minVersion, "0.7.1") >= 0)
+ list[0] = "[Adblock Plus " + minVersion + "]";
+ else
+ list[0] = "(Adblock Plus " + minVersion + " or higher required) " + list[0];
+ }
+
+ list.push("");
+
+ // Insert checksum
+ let checksum = Utils.generateChecksum(list);
+ if (checksum)
+ list.splice(1, 0, "! Checksum: " + checksum);
+
+ try
+ {
+ let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ fileStream.init(picker.file, 0x02 | 0x08 | 0x20, 0644, 0);
+
+ let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
+ stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+
+ stream.writeString(list.join(lineBreak));
+
+ stream.close();
+ }
+ catch (e)
+ {
+ dump("Adblock Plus: error writing to file: " + e + "\n");
+ Utils.alert(window, Utils.getString("filters_write_error"));
+ }
+ }
+}
+
+/**
+ * Handles keypress event on the filter list
+ */
+function onListKeyPress(/**Event*/ e)
+{
+ // Ignore any keys directed to the editor
+ if (treeView.isEditing)
+ return;
+
+ let modifiers = 0;
+ if (e.altKey)
+ modifiers |= altMask;
+ if (e.ctrlKey)
+ modifiers |= ctrlMask;
+ if (e.metaKey)
+ modifiers |= metaMask;
+
+ if ((e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER) && modifiers)
+ document.documentElement.acceptDialog();
+ else if (e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER || e.keyCode == e.DOM_VK_F2)
+ {
+ e.preventDefault();
+ if (editFilter(null))
+ e.stopPropagation();
+ }
+ else if (e.keyCode == e.DOM_VK_DELETE || e.keyCode == e.DOM_VK_BACK_SPACE)
+ removeFilters(true);
+ else if (e.keyCode == e.DOM_VK_INSERT)
+ treeView.startEditor(true);
+ else if (e.charCode == e.DOM_VK_SPACE && !E("col-enabled").hidden)
+ toggleDisabled();
+ else if ((e.keyCode == e.DOM_VK_UP || e.keyCode == e.DOM_VK_DOWN) && modifiers == accelMask)
+ {
+ if (e.shiftKey)
+ treeView.moveSubscription(e.keyCode == e.DOM_VK_UP);
+ else
+ treeView.moveFilter(e.keyCode == e.DOM_VK_UP);
+ e.stopPropagation();
+ }
+ else if (String.fromCharCode(e.charCode).toLowerCase() == "t" && modifiers == accelMask)
+ synchSubscription(false);
+}
+
+/**
+ * Handles click event on the filter list
+ */
+function onListClick(/**Event*/ e)
+{
+ if (e.button != 0)
+ return;
+
+ let row = {};
+ let col = {};
+ treeView.boxObject.getCellAt(e.clientX, e.clientY, row, col, {});
+
+ if (!col.value || col.value.id != "col-enabled")
+ return;
+
+ let [subscription, filter] = treeView.getRowInfo(row.value);
+ if (subscription && !filter)
+ treeView.toggleDisabled([subscription]);
+ else if (filter instanceof ActiveFilter)
+ treeView.toggleDisabled([filter]);
+}
+
+/**
+ * Handles dblclick event on the filter list
+ */
+function onListDblClick(/**Event*/ e)
+{
+ if (e.button != 0)
+ return;
+
+ let col = {};
+ treeView.boxObject.getCellAt(e.clientX, e.clientY, {}, col, {});
+
+ if (col.value && col.value.id == "col-enabled")
+ return;
+
+ editFilter(null);
+}
+
+/**
+ * Handles dragstart event on the filter list
+ */
+function onListDragStart(/**Event*/ e)
+{
+ treeView.startDrag(treeView.boxObject.getRowAt(e.clientX, e.clientY), e);
+}
+
+/**
+ * Handles dragend event on the filter list
+ */
+function onListDragEnd(/**Event*/ e)
+{
+ treeView.finishDrag();
+}
+
+/**
+ * Observer for filter storage changes, calls onFilterChange or onSubscriptionChange
+ * @see FilterStorage.addObserver()
+ */
+function onFilterStorageChange(/**String*/ action, /**Array*/ items, additionalData)
+{
+ if (/^filters (.*)/.test(action))
+ onFilterChange(RegExp.$1, items, additionalData);
+ else if (/^subscriptions (.*)/.test(action))
+ onSubscriptionChange(RegExp.$1, items, additionalData);
+}
+
+/**
+ * Filter change observer
+ */
+function onFilterChange(/**String*/ action, /**Array of Filter*/ filters, additionalData)
+{
+ switch (action)
+ {
+ case "add":
+ // addFilter() won't invalidate if the filter is already there because
+ // the subscription didn't create its subscription.filters copy yet,
+ // an update batch makes sure that everything is invalidated.
+ treeView.boxObject.beginUpdateBatch();
+ for each (let filter in filters)
+ {
+ let insertBefore = (additionalData ? getFilterByText(additionalData.text) : null);
+ treeView.addFilter(getFilterByText(filter.text), null, insertBefore, true);
+ }
+ treeView.boxObject.endUpdateBatch();
+ return;
+ case "remove":
+ // removeFilter() won't invalidate if the filter is already removed because
+ // the subscription didn't create its subscription.filters copy yet,
+ // an update batch makes sure that everything is invalidated.
+ treeView.boxObject.beginUpdateBatch();
+ for each (let filter in filters)
+ treeView.removeFilter(null, getFilterByText(filter.text));
+ treeView.boxObject.endUpdateBatch();
+ return;
+ case "enable":
+ case "disable":
+ // Remove existing changes to "disabled" property
+ for each (let filter in filters)
+ {
+ filter = getFilterByText(filter.text);
+ if ("_isWrapper" in filter && filter.hasOwnProperty("disabled"))
+ delete filter.disabled;
+ }
+ break;
+ case "hit":
+ if (E("col-hitcount").hidden && E("col-lasthit").hidden)
+ {
+ // The data isn't visible, no need to invalidate
+ return;
+ }
+ break;
+ default:
+ return;
+ }
+
+ if (filters.length == 1)
+ treeView.invalidateFilter(getFilterByText(filters[0].text));
+ else
+ treeView.boxObject.invalidate();
+}
+
+/**
+ * Subscription change observer
+ */
+function onSubscriptionChange(/**String*/ action, /**Array of Subscription*/ subscriptions)
+{
+ for each (let subscription in subscriptions)
+ {
+ subscription = getSubscriptionByURL(subscription.url);
+ switch (action)
+ {
+ case "add":
+ treeView.addSubscription(subscription, true);
+ break;
+ case "remove":
+ treeView.removeSubscription(subscription);
+ break;
+ case "enable":
+ case "disable":
+ // Remove existing changes to "disabled" property
+ delete subscription.disabled;
+ treeView.invalidateSubscription(subscription);
+ break;
+ case "update":
+ if ("oldSubscription" in subscription)
+ {
+ treeView.removeSubscription(getSubscriptionByURL(subscription.oldSubscription.url));
+ delete subscriptionWrappers[subscription.oldSubscription.url];
+ if (treeView.subscriptions.indexOf(subscription) < 0)
+ {
+ treeView.addSubscription(subscription, true);
+ break;
+ }
+ }
+ let oldCount = treeView.getSubscriptionRowCount(subscription);
+
+ delete subscription.filters;
+ subscription.filters = subscription.filters.map(function(filter)
+ {
+ return getFilterByText(filter.text);
+ });
+
+ treeView.resortSubscription(subscription);
+ treeView.invalidateSubscription(subscription, oldCount);
+ break;
+ case "updateinfo":
+ if ("oldSubscription" in subscription)
+ {
+ treeView.removeSubscription(getSubscriptionByURL(subscription.oldSubscription.url));
+ delete subscriptionWrappers[subscription.oldSubscription.url];
+ if (treeView.subscriptions.indexOf(subscription) < 0)
+ {
+ treeView.addSubscription(subscription, true);
+ break;
+ }
+ }
+ treeView.invalidateSubscriptionInfo(subscription);
+ break;
+ }
+ }
+
+ // Date.toLocaleFormat() doesn't handle Unicode properly if called directly from XPCOM (bug 441370)
+ setTimeout(function()
+ {
+ for each (let subscription in subscriptions)
+ {
+ subscription = getSubscriptionByURL(subscription.url);
+ treeView.invalidateSubscriptionInfo(subscription);
+ }
+ }, 0);
+}
+
+/**
+ * Starts editor for filter or subscription.
+ * @param {String} type "filter", "subscription" or null (any)
+ */
+function editFilter(type) /**Boolean*/
+{
+ let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
+ if (!filter && !type)
+ {
+ // Don't do anything for group titles unless we were explicitly told what to do
+ return false;
+ }
+
+ if (type != "filter" && subscription instanceof RegularSubscription)
+ editSubscription(subscription);
+ else
+ treeView.startEditor(false);
+
+ return true;
+}
+
+/**
+ * Starts editor for a given subscription (pass null to add a new subscription).
+ */
+function editSubscription(/**Subscription*/ subscription)
+{
+ let hasSubscription = function(url) treeView.subscriptions.indexOf(getSubscriptionByURL(url)) >= 0;
+ let result = {};
+ openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", subscription, result, hasSubscription);
+
+ if (!("url" in result))
+ return;
+
+ let subscriptionResults = [[result.url, result.title]];
+ if ("mainSubscriptionURL" in result)
+ subscriptionResults.push([result.mainSubscriptionURL, result.mainSubscriptionTitle]);
+
+ let changed = false;
+ for each (let [url, title] in subscriptionResults)
+ {
+ let newSubscription = getSubscriptionByURL(url);
+ if (!newSubscription)
+ continue;
+
+ changed = true;
+ if (subscription && subscription != newSubscription)
+ treeView.removeSubscription(subscription);
+
+ treeView.addSubscription(newSubscription);
+
+ newSubscription.title = title;
+ newSubscription.disabled = result.disabled;
+ newSubscription.autoDownload = result.autoDownload;
+
+ treeView.invalidateSubscriptionInfo(newSubscription);
+
+ if (newSubscription instanceof DownloadableSubscription && !newSubscription.lastDownload)
+ Synchronizer.execute(newSubscription.__proto__, false);
+ }
+
+ if (changed)
+ onChange();
+}
+
+/**
+ * Removes the selected entries from the list and sets selection to the
+ * next item.
+ * @param {Boolean} allowSubscriptions if true, a subscription will be
+ * removed if no removable filters are selected
+ */
+function removeFilters(allowSubscriptions)
+{
+ // Retrieve selected items
+ let selected = treeView.getSelectedInfo(false);
+
+ let found = false;
+ for each (let [subscription, filter] in selected)
+ {
+ if (subscription instanceof SpecialSubscription && filter instanceof Filter)
+ {
+ treeView.removeFilter(subscription, filter);
+ found = true;
+ }
+ }
+
+ if (found)
+ return;
+
+ if (allowSubscriptions)
+ {
+ // No removable filters found, maybe we can remove a subscription?
+ let selectedSubscription = null;
+ for each (let [subscription, filter] in selected)
+ {
+ if (!selectedSubscription)
+ selectedSubscription = subscription;
+ else if (selectedSubscription != subscription)
+ return;
+ }
+
+ if (selectedSubscription && selectedSubscription instanceof RegularSubscription && Utils.confirm(window, Utils.getString("remove_subscription_warning")))
+ treeView.removeSubscription(selectedSubscription);
+ }
+}
+
+/**
+ * Enables or disables selected filters or the selected subscription
+ */
+function toggleDisabled()
+{
+ // Look for selected filters first
+ let selected = treeView.getSelectedFilters(true).filter(function(filter)
+ {
+ return filter instanceof ActiveFilter;
+ });
+
+ if (selected.length)
+ treeView.toggleDisabled(selected);
+ else
+ {
+ // No filters selected, maybe a subscription?
+ let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
+ if (subscription && !filter)
+ treeView.toggleDisabled([subscription]);
+ }
+}
+
+/**
+ * Copies selected filters to clipboard.
+ */
+function copyToClipboard()
+{
+ let selected = treeView.getSelectedFilters(false);
+ if (!selected.length)
+ return;
+
+ let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+ let lineBreak = Utils.getLineBreak();
+ clipboardHelper.copyString(selected.map(function(filter)
+ {
+ return filter.text;
+ }).join(lineBreak) + lineBreak);
+}
+
+/**
+ * Pastes text as list of filters from clipboard
+ */
+function pasteFromClipboard() {
+ let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+ let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
+ transferable.addDataFlavor("text/unicode");
+
+ try {
+ clipboard.getData(transferable, clipboard.kGlobalClipboard);
+ }
+ catch (e) {
+ return;
+ }
+
+ let data = {};
+ transferable.getTransferData("text/unicode", data, {});
+
+ try {
+ data = data.value.QueryInterface(Ci.nsISupportsString).data;
+ }
+ catch (e) {
+ return;
+ }
+
+ let lastAdded = addFilters(data.split(/[\r\n]+/));
+ if (lastAdded)
+ treeView.selectFilter(lastAdded);
+}
+
+/**
+ * Starts synchronization of the currently selected subscription
+ */
+function synchSubscription()
+{
+ let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
+ if (subscription instanceof DownloadableSubscription)
+ Synchronizer.execute(subscription.__proto__, true, true);
+}
+
+/**
+ * Starts synchronization for all subscriptions
+ */
+function synchAllSubscriptions()
+{
+ for each (let subscription in treeView.subscriptions)
+ if (subscription instanceof DownloadableSubscription)
+ Synchronizer.execute(subscription.__proto__, true, true);
+}
+
+/**
+ * Updates the contents of the Filters menu, making sure the right
+ * items are checked/enabled.
+ */
+function fillFiltersPopup()
+{
+ let empty = !treeView.hasUserFilters();
+ E("export-command").setAttribute("disabled", empty);
+ E("clearall").setAttribute("disabled", empty);
+}
+
+/**
+ * Updates the contents of the View menu, making sure the right
+ * items are checked/enabled.
+ */
+function fillViewPopup(/**String*/prefix)
+{
+ E(prefix + "view-filter").setAttribute("checked", !E("col-filter").hidden);
+ E(prefix + "view-slow").setAttribute("checked", !E("col-slow").hidden);
+ E(prefix + "view-enabled").setAttribute("checked", !E("col-enabled").hidden);
+ E(prefix + "view-hitcount").setAttribute("checked", !E("col-hitcount").hidden);
+ E(prefix + "view-lasthit").setAttribute("checked", !E("col-lasthit").hidden);
+
+ let sortColumn = treeView.sortColumn;
+ let sortColumnID = (sortColumn ? sortColumn.id : null);
+ let sortDir = (sortColumn ? sortColumn.getAttribute("sortDirection") : "natural");
+ E(prefix + "sort-none").setAttribute("checked", sortColumn == null);
+ E(prefix + "sort-filter").setAttribute("checked", sortColumnID == "col-filter");
+ E(prefix + "sort-enabled").setAttribute("checked", sortColumnID == "col-enabled");
+ E(prefix + "sort-hitcount").setAttribute("checked", sortColumnID == "col-hitcount");
+ E(prefix + "sort-lasthit").setAttribute("checked", sortColumnID == "col-lasthit");
+ E(prefix + "sort-asc").setAttribute("checked", sortDir == "ascending");
+ E(prefix + "sort-desc").setAttribute("checked", sortDir == "descending");
+}
+
+/**
+ * Toggles visibility of a column.
+ * @param {String} col ID of the column to made visible/invisible
+ */
+function toggleColumn(col)
+{
+ col = E(col);
+ col.setAttribute("hidden", col.hidden ? "false" : "true");
+}
+
+/**
+ * Switches list sorting to the specified column. Sort order is kept.
+ * @param {String} col ID of the column to sort by or null for unsorted
+ */
+function sortBy(col)
+{
+ if (col)
+ treeView.resort(E(col), treeView.sortColumn ? treeView.sortColumn.getAttribute("sortDirection") : "ascending");
+ else
+ treeView.resort(null, "natural");
+}
+
+/**
+ * Changes sort order of the list. Sorts by filter column if the list is unsorted.
+ * @param {String} order either "ascending" or "descending"
+ */
+function setSortOrder(order)
+{
+ let col = treeView.sortColumn || E("col-filter");
+ treeView.resort(col, order);
+}
+
+/**
+ * Updates the contents of the Options menu, making sure the right
+ * items are checked/enabled.
+ */
+function fillOptionsPopup()
+{
+ E("abp-enabled").setAttribute("checked", Prefs.enabled);
+ E("frameobjects").setAttribute("checked", Prefs.frameobjects);
+ E("slowcollapse").setAttribute("checked", !Prefs.fastcollapse);
+ E("showintoolbar").setAttribute("checked", Prefs.showintoolbar);
+ E("showinstatusbar").setAttribute("checked", Prefs.showinstatusbar);
+
+ let syncEngine = Sync.getEngine();
+ E("sync").hidden = !syncEngine;
+ E("sync").setAttribute("checked", syncEngine && syncEngine.enabled);
+}
+
+/**
+ * Updates the state of copy/paste commands whenever selection changes.
+ */
+function updateCommands()
+{
+ // Retrieve selected items
+ let selected = treeView.getSelectedInfo(true);
+
+ // Check whether all selected items belong to the same subscription
+ let selectedSubscription = null;
+ for each (let [subscription, filter] in selected)
+ {
+ if (!selectedSubscription)
+ selectedSubscription = subscription;
+ else if (subscription != selectedSubscription)
+ {
+ // More than one subscription selected, ignoring it
+ selectedSubscription = null;
+ break;
+ }
+ }
+
+ // Check whether any filters have been selected and whether any of them can be removed
+ let hasFilters = selected.some(function([subscription, filter]) filter instanceof Filter);
+ let hasRemovable = selected.some(function([subscription, filter]) subscription instanceof SpecialSubscription && filter instanceof Filter);
+
+ // Check whether clipboard contains text
+ let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
+ let hasFlavour = clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard);
+
+ E("copy-command").setAttribute("disabled", !hasFilters);
+ E("cut-command").setAttribute("disabled", !hasRemovable);
+ E("paste-command").setAttribute("disabled", !hasFlavour);
+ E("remove-command").setAttribute("disabled", !(hasRemovable || selectedSubscription instanceof RegularSubscription));
+}
+
+/**
+ * Updates the contents of the context menu, making sure the right
+ * items are checked/enabled.
+ */
+function fillContext()
+{
+ // Retrieve selected items
+ let selected = treeView.getSelectedInfo(true);
+
+ let currentSubscription = null;
+ let currentFilter = null;
+ if (selected.length)
+ [currentSubscription, currentFilter] = selected[0];
+
+ // Check whether all selected items belong to the same subscription
+ let selectedSubscription = null;
+ for each (let [subscription, filter] in selected)
+ {
+ if (!selectedSubscription)
+ selectedSubscription = subscription;
+ else if (subscription != selectedSubscription)
+ {
+ // More than one subscription selected, ignoring it
+ selectedSubscription = null;
+ break;
+ }
+ }
+
+ // Check whether any filters have been selected and which filters can be enabled/disabled
+ let hasFilters = selected.some(function([subscription, filter]) filter instanceof Filter);
+ let activeFilters = selected.filter(function([subscription, filter]) filter instanceof ActiveFilter);
+
+ if (selectedSubscription instanceof RegularSubscription)
+ {
+ E("context-editsubscription").hidden = false;
+ E("context-edit").hidden = true;
+ }
+ else
+ {
+ E("context-editsubscription").hidden = true;
+ E("context-edit").hidden = false;
+ E("context-edit").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter));
+ }
+
+ E("context-synchsubscription").setAttribute("disabled", !(selectedSubscription instanceof DownloadableSubscription));
+ E("context-resethitcount").setAttribute("disabled", !hasFilters);
+
+ E("context-moveup").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter && !treeView.isSorted() && currentSubscription._sortedFilters.indexOf(currentFilter) > 0));
+ E("context-movedown").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter && !treeView.isSorted() && currentSubscription._sortedFilters.indexOf(currentFilter) < currentSubscription._sortedFilters.length - 1));
+
+ E("context-movegroupup").setAttribute("disabled", !selectedSubscription || treeView.isFirstSubscription(selectedSubscription));
+ E("context-movegroupdown").setAttribute("disabled", !selectedSubscription || treeView.isLastSubscription(selectedSubscription));
+
+ if (activeFilters.length || (selectedSubscription && !currentFilter))
+ {
+ let current = activeFilters.length ? activeFilters[0][1] : selectedSubscription;
+ E("context-enable").hidden = !current.disabled;
+ E("context-disable").hidden = current.disabled;
+ E("context-disable").setAttribute("disabled", "false");
+ }
+ else
+ {
+ E("context-enable").hidden = true;
+ E("context-disable").hidden = false;
+ E("context-disable").setAttribute("disabled", "true");
+ }
+
+ return true;
+}
+
+/**
+ * Toggles the value of a boolean preference.
+ * @param {String} pref preference name (Prefs object property)
+ */
+function togglePref(pref)
+{
+ Prefs[pref] = !Prefs[pref];
+}
+
+/**
+ * Toggles the pref for the Adblock Plus sync engine.
+ */
+function toggleSync()
+{
+ let syncEngine = Sync.getEngine();
+ syncEngine.enabled = !syncEngine.enabled;
+}
+
+/**
+ * Applies filter list changes.
+ */
+function applyChanges()
+{
+ treeView.applyChanges();
+ E("applyButton").setAttribute("disabled", "true");
+}
+
+/**
+ * Checks whether a tooltip should be shown and sets tooltip text appropriately
+ */
+function showTreeTooltip(/**Event*/ event) /**Boolean*/
+{
+ let col = {};
+ let row = {};
+ let childElement = {};
+ treeView.boxObject.getCellAt(event.clientX, event.clientY, row, col, childElement);
+
+ let [subscription, filter] = treeView.getRowInfo(row.value);
+ if (row.value && col.value && col.value.id == "col-slow" && treeView.getCellText(row.value, col.value))
+ {
+ E("tree-tooltip").setAttribute("label", Utils.getString("filter_regexp_tooltip"));
+ return true;
+ }
+
+ if (filter instanceof InvalidFilter && filter.reason)
+ {
+ E("tree-tooltip").setAttribute("label", filter.reason);
+ return true;
+ }
+
+ if (row.value && col.value && treeView.boxObject.isCellCropped(row.value, col.value))
+ {
+ let text = treeView.getCellText(row.value, col.value);
+ if (text)
+ {
+ E("tree-tooltip").setAttribute("label", text);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Opens About Adblock Plus dialog
+ */
+function openAbout()
+{
+ openDialog("about.xul", "_blank", "chrome,centerscreen,modal");
+}
+
+/**
+ * Should be called after each change to the filter list that needs applying later
+ */
+function onChange() {
+ E("applyButton").removeAttribute("disabled");
+}
+
+/**
+ * Sort function for the filter list, compares two filters by their text
+ * representation.
+ */
+function compareText(/**Filter*/ filter1, /**Filter*/ filter2)
+{
+ if (filter1.text < filter2.text)
+ return -1;
+ else if (filter1.text > filter2.text)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Sort function for the filter list, compares two filters by "slow"
+ * marker.
+ */
+function compareSlow(/**Filter*/ filter1, /**Filter*/ filter2)
+{
+ let isSlow1 = filter1 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter1);
+ let isSlow2 = filter2 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter2);
+ return isSlow1 - isSlow2;
+}
+
+/**
+ * Sort function for the filter list, compares two filters by "enabled"
+ * state.
+ */
+function compareEnabled(/**Filter*/ filter1, /**Filter*/ filter2)
+{
+ let hasEnabled1 = (filter1 instanceof ActiveFilter ? 1 : 0);
+ let hasEnabled2 = (filter2 instanceof ActiveFilter ? 1 : 0);
+ if (hasEnabled1 != hasEnabled2)
+ return hasEnabled1 - hasEnabled2;
+ else if (hasEnabled1 && filter1.disabled != filter2.disabled)
+ return (filter1.disabled ? -1 : 1);
+ else
+ return 0;
+}
+
+/**
+ * Sort function for the filter list, compares two filters by their hit count.
+ */
+function compareHitCount(/**Filter*/ filter1, /**Filter*/ filter2)
+{
+ let hasHitCount1 = (filter1 instanceof ActiveFilter ? 1 : 0);
+ let hasHitCount2 = (filter2 instanceof ActiveFilter ? 1 : 0);
+ if (hasHitCount1 != hasHitCount2)
+ return hasHitCount1 - hasHitCount2;
+ else if (hasHitCount1)
+ return filter1.hitCount - filter2.hitCount;
+ else
+ return 0;
+}
+
+/**
+ * Sort function for the filter list, compares two filters by their last hit.
+ */
+function compareLastHit(/**Filter*/ filter1, /**Filter*/ filter2)
+{
+ let hasLastHit1 = (filter1 instanceof ActiveFilter ? 1 : 0);
+ let hasLastHit2 = (filter2 instanceof ActiveFilter ? 1 : 0);
+ if (hasLastHit1 != hasLastHit2)
+ return hasLastHit1 - hasLastHit2;
+ else if (hasLastHit1)
+ return filter1.lastHit - filter2.lastHit;
+ else
+ return 0;
+}
+
+/**
+ * Creates a sort function from a primary and a secondary comparison function.
+ * @param {Function} cmpFunc comparison function to be called first
+ * @param {Function} fallbackFunc (optional) comparison function to be called if primary function returns 0
+ * @param {Boolean} desc if true, the result of the primary function (not the secondary function) will be reversed - sorting in descending order
+ * @result {Function} comparison function to be used
+ */
+function createSortFunction(cmpFunc, fallbackFunc, desc)
+{
+ let factor = (desc ? -1 : 1);
+
+ return function(filter1, filter2)
+ {
+ // Comment replacements without prototype always go last
+ let isLast1 = (filter1.__proto__ == null);
+ let isLast2 = (filter2.__proto__ == null);
+ if (isLast1)
+ return (isLast2 ? 0 : 1)
+ else if (isLast2)
+ return -1;
+
+ let ret = cmpFunc(filter1, filter2);
+ if (ret == 0 && fallbackFunc)
+ return fallbackFunc(filter1, filter2);
+ else
+ return factor * ret;
+ }
+}
+
+const nsITreeView = Ci.nsITreeView;
+
+/**
+ * nsITreeView implementation used for the filters list.
+ * @class
+ */
+let treeView = {
+ //
+ // nsISupports implementation
+ //
+
+ QueryInterface: function(uuid) {
+ if (!uuid.equals(Ci.nsISupports) &&
+ !uuid.equals(Ci.nsITreeView))
+ {
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+
+ return this;
+ },
+
+ //
+ // nsITreeView implementation
+ //
+
+ setTree: function(boxObject)
+ {
+ if (!boxObject)
+ return;
+
+ this.boxObject = boxObject;
+
+ let stringAtoms = ["col-filter", "col-enabled", "col-hitcount", "col-lasthit", "type-comment", "type-filterlist", "type-whitelist", "type-elemhide", "type-invalid"];
+ let boolAtoms = ["selected", "dummy", "subscription", "description", "filter", "filter-regexp", "subscription-special", "subscription-external", "subscription-autoDownload", "subscription-disabled", "subscription-upgradeRequired", "subscription-dummy", "filter-disabled"];
+ let atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService);
+
+ this.atoms = {};
+ for each (let atom in stringAtoms)
+ this.atoms[atom] = atomService.getAtom(atom);
+ for each (let atom in boolAtoms)
+ {
+ this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true");
+ this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false");
+ }
+
+ // Copy the subscription list, we don't want to apply our changes immediately
+ this.subscriptions = FilterStorage.subscriptions.map(createSubscriptionWrapper);
+
+ this.closed = {__proto__: null};
+ let closed = this.boxObject.treeBody.parentNode.getAttribute("closedSubscriptions");
+ if (closed)
+ for each (let id in closed.split(" "))
+ if (id in FilterStorage.knownSubscriptions)
+ this.closed[id] = true;
+
+ // Check current sort direction
+ let cols = document.getElementsByTagName("treecol");
+ let sortColumn = null;
+ let sortDir = null;
+ for (let i = 0; i < cols.length; i++)
+ {
+ let col = cols[i];
+ let dir = col.getAttribute("sortDirection");
+ if (dir && dir != "natural")
+ {
+ sortColumn = col;
+ sortDir = dir;
+ }
+ }
+
+ if (sortColumn)
+ this.resort(sortColumn, sortDir);
+
+ // Make sure we stop the editor when scrolling or resizing window
+ let me = this;
+ this.boxObject.treeBody.addEventListener("DOMMouseScroll", function()
+ {
+ me.stopEditor(true);
+ }, false);
+ window.addEventListener("resize", function()
+ {
+ me.stopEditor(true);
+ }, false);
+ },
+
+ get rowCount()
+ {
+ let count = 0;
+ for each (let subscription in this.subscriptions)
+ {
+ // Special subscriptions are only shown if they aren't empty
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ continue;
+
+ count++;
+ if (!(subscription.url in this.closed))
+ count += subscription._description.length + subscription._sortedFilters.length;
+ }
+
+ return count;
+ },
+
+ getCellText: function(row, col)
+ {
+ col = col.id;
+
+ // Only three columns have text
+ if (col != "col-filter" && col != "col-slow" && col != "col-hitcount" && col != "col-lasthit")
+ return null;
+
+ // Don't show text in the edited row
+ if (col == "col-filter" && this.editedRow == row)
+ return null;
+
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription)
+ return null;
+
+ if (filter instanceof Filter)
+ {
+ if (col == "col-filter")
+ return filter.text;
+ else if (col == "col-slow")
+ return (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter) ? "!" : null);
+ else if (filter instanceof ActiveFilter)
+ {
+ if (col == "col-hitcount")
+ return filter.hitCount;
+ else
+ return (filter.lastHit ? Utils.formatTime(filter.lastHit) : null);
+ }
+ else
+ return null;
+ }
+ else if (col != "col-filter")
+ return null;
+ else if (!filter)
+ return (subscription instanceof RegularSubscription ? this.titlePrefix : "") + subscription.title;
+ else
+ return filter;
+ },
+
+ getColumnProperties: function(col, properties)
+ {
+ col = col.id;
+
+ if (col in this.atoms)
+ properties.AppendElement(this.atoms[col]);
+ },
+
+ getRowProperties: function(row, properties)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription)
+ return;
+
+ properties.AppendElement(this.atoms["selected-" + this.selection.isSelected(row)]);
+ properties.AppendElement(this.atoms["subscription-" + !filter]);
+ properties.AppendElement(this.atoms["filter-" + (filter instanceof Filter)]);
+ properties.AppendElement(this.atoms["filter-regexp-" + (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter))]);
+ properties.AppendElement(this.atoms["description-" + (typeof filter == "string")]);
+ properties.AppendElement(this.atoms["subscription-special-" + (subscription instanceof SpecialSubscription)]);
+ properties.AppendElement(this.atoms["subscription-external-" + (subscription instanceof ExternalSubscription)]);
+ properties.AppendElement(this.atoms["subscription-autoDownload-" + (subscription instanceof DownloadableSubscription && subscription.autoDownload)]);
+ properties.AppendElement(this.atoms["subscription-disabled-" + subscription.disabled]);
+ properties.AppendElement(this.atoms["subscription-upgradeRequired-" + (subscription instanceof DownloadableSubscription && subscription.upgradeRequired)]);
+ properties.AppendElement(this.atoms["subscription-dummy-" + (subscription instanceof Subscription && subscription.url == "~dummy~")]);
+ if (filter instanceof Filter)
+ {
+ if (filter instanceof ActiveFilter)
+ properties.AppendElement(this.atoms["filter-disabled-" + filter.disabled]);
+
+ if (filter instanceof CommentFilter)
+ properties.AppendElement(this.atoms["type-comment"]);
+ else if (filter instanceof BlockingFilter)
+ properties.AppendElement(this.atoms["type-filterlist"]);
+ else if (filter instanceof WhitelistFilter)
+ properties.AppendElement(this.atoms["type-whitelist"]);
+ else if (filter instanceof ElemHideFilter)
+ properties.AppendElement(this.atoms["type-elemhide"]);
+ else if (filter instanceof InvalidFilter)
+ properties.AppendElement(this.atoms["type-invalid"]);
+ }
+ },
+
+ getCellProperties: function(row, col, properties)
+ {
+ this.getColumnProperties(col, properties);
+ this.getRowProperties(row, properties);
+ },
+
+ isContainer: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ return subscription && !filter;
+ },
+
+ isContainerOpen: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ return subscription && !filter && !(subscription.url in this.closed);
+ },
+
+ isContainerEmpty: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ return subscription && !filter && subscription._description.length + subscription._sortedFilters.length == 0;
+ },
+
+ getLevel: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ return (filter ? 1 : 0);
+ },
+
+ getParentIndex: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ return (subscription && filter ? this.getSubscriptionRow(subscription) : -1);
+ },
+
+ hasNextSibling: function(row, afterRow)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!filter)
+ return false;
+
+ let startIndex = this.getSubscriptionRow(subscription);
+ if (startIndex < 0)
+ return false;
+
+ return (startIndex + subscription._description.length + subscription._sortedFilters.length > afterRow);
+ },
+
+ toggleOpenState: function(row)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription || filter)
+ return;
+
+ let count = subscription._description.length + subscription._sortedFilters.length;
+ if (subscription.url in this.closed)
+ {
+ delete this.closed[subscription.url];
+ this.boxObject.rowCountChanged(row + 1, count);
+ }
+ else
+ {
+ this.closed[subscription.url] = true;
+ this.boxObject.rowCountChanged(row + 1, -count);
+ }
+ this.boxObject.invalidateRow(row);
+
+ // Update closedSubscriptions attribute so that the state persists
+ let closed = [];
+ for (let url in this.closed)
+ closed.push(url);
+ this.boxObject.treeBody.parentNode.setAttribute("closedSubscriptions", closed.join(" "));
+ },
+
+ cycleHeader: function(col)
+ {
+ col = col.element;
+
+ let cycle =
+ {
+ natural: 'ascending',
+ ascending: 'descending',
+ descending: 'natural'
+ };
+
+ let curDirection = "natural";
+ if (this.sortColumn == col)
+ curDirection = col.getAttribute("sortDirection");
+ else if (this.sortColumn)
+ this.sortColumn.removeAttribute("sortDirection");
+
+ this.resort(col, cycle[curDirection]);
+ },
+
+ isSorted: function()
+ {
+ return (this.sortProc != null);
+ },
+
+ canDrop: function(row, orientation)
+ {
+ if (!this.dragSubscription || orientation == nsITreeView.DROP_ON)
+ return false;
+
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription)
+ return false;
+
+ if (this.dragFilter)
+ {
+ // Dragging a filter
+ return filter && subscription instanceof SpecialSubscription && subscription.isFilterAllowed(this.dragFilter);
+ }
+ else
+ {
+ // Dragging a subscription
+ return true;
+ }
+ },
+
+ drop: function(row, orientation)
+ {
+ if (!this.dragSubscription || orientation == nsITreeView.DROP_ON)
+ return;
+
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription)
+ return;
+
+ if (this.dragFilter)
+ {
+ // Dragging a filter
+ if (!(filter && subscription instanceof SpecialSubscription && subscription.isFilterAllowed(this.dragFilter)))
+ return;
+
+ let oldSubscription = this.dragSubscription;
+ let oldSortedIndex = oldSubscription._sortedFilters.indexOf(this.dragFilter);
+ let newSortedIndex = subscription._sortedFilters.indexOf(filter);
+ if (oldSortedIndex < 0 || newSortedIndex < 0)
+ return;
+ if (orientation == nsITreeView.DROP_AFTER)
+ newSortedIndex++;
+
+ let oldIndex = (oldSubscription.filters == oldSubscription._sortedFilters ? oldSortedIndex : oldSubscription.filters.indexOf(this.dragFilter));
+ let newIndex = (subscription.filters == subscription._sortedFilters || newSortedIndex >= subscription._sortedFilters.length ? newSortedIndex : subscription.filters.indexOf(subscription._sortedFilters[newSortedIndex]));
+ if (oldIndex < 0 || newIndex < 0)
+ return;
+ if (oldSubscription == subscription && (newIndex == oldIndex || newIndex == oldIndex + 1))
+ return;
+
+ {
+ if (!oldSubscription.hasOwnProperty("filters"))
+ oldSubscription.filters = oldSubscription.filters.slice();
+
+ let rowCountBefore = treeView.getSubscriptionRowCount(oldSubscription);
+ let row = treeView.getSubscriptionRow(oldSubscription) + rowCountBefore - oldSubscription._sortedFilters.length + oldSortedIndex;
+ oldSubscription.filters.splice(oldIndex, 1);
+ this.resortSubscription(oldSubscription);
+ let rowCountAfter = treeView.getSubscriptionRowCount(oldSubscription);
+ this.boxObject.rowCountChanged(row + 1 + rowCountAfter - rowCountBefore, rowCountAfter - rowCountBefore);
+ }
+
+ if (oldSubscription == subscription && newSortedIndex > oldSortedIndex)
+ newSortedIndex--;
+ if (oldSubscription == subscription && newIndex > oldIndex)
+ newIndex--;
+
+ {
+ if (!subscription.hasOwnProperty("filters"))
+ subscription.filters = subscription.filters.slice();
+
+ let rowCountBefore = treeView.getSubscriptionRowCount(subscription);
+ subscription.filters.splice(newIndex, 0, this.dragFilter);
+ this.resortSubscription(subscription);
+ let rowCountAfter = treeView.getSubscriptionRowCount(subscription);
+ let row = treeView.getSubscriptionRow(subscription) + rowCountAfter - subscription._sortedFilters.length + newSortedIndex;
+ this.boxObject.rowCountChanged(row + 1 + rowCountBefore - rowCountAfter, rowCountAfter - rowCountBefore);
+
+ treeView.selectRow(row);
+ }
+ }
+ else
+ {
+ // Dragging a subscription
+ if (subscription == this.dragSubscription)
+ return;
+
+ let rowCount = this.getSubscriptionRowCount(this.dragSubscription);
+
+ let oldIndex = this.subscriptions.indexOf(this.dragSubscription);
+ let newIndex = this.subscriptions.indexOf(subscription);
+ if (oldIndex < 0 || newIndex < 0)
+ return;
+
+ if (filter && oldIndex > newIndex)
+ orientation = nsITreeView.DROP_BEFORE;
+ else if (filter)
+ orientation = nsITreeView.DROP_AFTER;
+
+ let oldRow = this.getSubscriptionRow(this.dragSubscription);
+ this.subscriptions.splice(oldIndex, 1);
+ this.boxObject.rowCountChanged(oldRow, -rowCount);
+
+ if (orientation == nsITreeView.DROP_AFTER)
+ newIndex++;
+ if (oldIndex < newIndex)
+ newIndex--;
+
+ this.subscriptions.splice(newIndex, 0, this.dragSubscription);
+ let newRow = this.getSubscriptionRow(this.dragSubscription);
+ this.boxObject.rowCountChanged(newRow, rowCount);
+
+ treeView.selectRow(newRow);
+ }
+
+ onChange();
+ },
+
+ getCellValue: function() {return null},
+ getProgressMode: function() {return null},
+ getImageSrc: function() {return null},
+ isSeparator: function() {return false},
+ isEditable: function() {return false},
+ cycleCell: function() {},
+ performAction: function() {},
+ performActionOnRow: function() {},
+ performActionOnCell: function() {},
+ selection: null,
+ selectionChanged: function() {},
+
+ //
+ // Custom properties and methods
+ //
+
+ /**
+ * List of subscriptions displayed
+ * @type Array of Subscription
+ */
+ subscriptions: null,
+
+ /**
+ * Box object of the tree
+ * @type nsITreeBoxObject
+ */
+ boxObject: null,
+
+ /**
+ * Map containing URLs of subscriptions that are displayed collapsed
+ * @type Object
+ */
+ closed: null,
+
+ /**
+ * String to be displayed before the title of regular subscriptions
+ * @type String
+ * @const
+ */
+ titlePrefix: Utils.getString("subscription_description") + " ",
+
+ /**
+ * Map of atoms being used as col/row/cell properties, String => nsIAtom
+ * @type Object
+ */
+ atoms: null,
+
+ /**
+ * Column by which the list is sorted or null for natural order
+ * @type Element
+ */
+ sortColumn: null,
+
+ /**
+ * Comparison function used to sort the list or null for natural order
+ * @type Function
+ */
+ sortProc: null,
+
+ /**
+ * Returns the first row of a subscription in the list or -1 if the
+ * subscription isn't in the list or isn't visible.
+ */
+ getSubscriptionRow: function(/**Subscription*/ search) /**Integer*/
+ {
+ let index = 0;
+ for each (let subscription in this.subscriptions)
+ {
+ let rowCount = this.getSubscriptionRowCount(subscription);
+ if (rowCount > 0 && search == subscription)
+ return index;
+
+ index += rowCount;
+ }
+ return -1;
+ },
+
+ /**
+ * Returns the number of rows used to display the subscription in the list.
+ */
+ getSubscriptionRowCount: function(/**Subscription*/ subscription) /**Integer*/
+ {
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ return 0;
+
+ if (subscription.url in this.closed)
+ return 1;
+
+ return 1 + subscription._description.length + subscription._sortedFilters.length;
+ },
+
+ /**
+ * Returns the filter displayed in the given row and the corresponding filter subscription.
+ * @param {Integer} row row index
+ * @return {Array} array with two elements indicating the contents of the row:
+ * [null, null] - empty row
+ * [Subscription, null] - subscription title row
+ * [Subscription, String] - subscription description row (row text is second array element)
+ * [Subscription, Filter] - filter from the given subscription
+ */
+ getRowInfo: function(row)
+ {
+ for each (let subscription in this.subscriptions)
+ {
+ // Special subscriptions are only shown if they aren't empty
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ continue;
+
+ // Check whether the subscription row has been requested
+ row--;
+ if (row < 0)
+ return [subscription, null];
+
+ if (!(subscription.url in this.closed))
+ {
+ // Check whether the subscription description row has been requested
+ if (row < subscription._description.length)
+ return [subscription, subscription._description[row]];
+
+ row -= subscription._description.length;
+
+ // Check whether one of the filters has been requested
+ if (row < subscription._sortedFilters.length)
+ return [subscription, subscription._sortedFilters[row]];
+
+ row -= subscription._sortedFilters.length;
+ }
+ }
+
+ return [null, null];
+ },
+
+ /**
+ * Returns the filters currently selected.
+ * @param {Boolean} prependCurrent if true, current element will be returned first
+ * @return {Array of Filter}
+ */
+ getSelectedFilters: function(prependCurrent)
+ {
+ return this.getSelectedInfo(prependCurrent).map(function(info)
+ {
+ return info[1];
+ }).filter(function(filter)
+ {
+ return filter instanceof Filter;
+ });
+ },
+
+ /**
+ * Returns the filters/subscription currently selected.
+ * @param {Boolean} prependCurrent if true, current element will be returned first
+ * @return {Array} each array entry has the same format as treeView.getRowInfo() result
+ * @see treeView.getRowInfo()
+ */
+ getSelectedInfo: function(prependCurrent)
+ {
+ let result = [];
+ for (let i = 0; i < this.selection.getRangeCount(); i++)
+ {
+ let min = {};
+ let max = {};
+ this.selection.getRangeAt(i, min, max);
+ for (let j = min.value; j <= max.value; j++)
+ {
+ let info = this.getRowInfo(j);
+ if (info[0])
+ {
+ if (prependCurrent && j == treeView.selection.currentIndex)
+ result.unshift(info);
+ else
+ result.push(info);
+ }
+ }
+ }
+ return result;
+ },
+
+ /**
+ * Checks whether the filter already has a wrapper. If
+ * not, replaces all instances of the filter but the
+ * wrapper.
+ * @param {Filter} filter filter to be tested
+ * @return {Filter} wrapped filter
+ */
+ ensureFilterWrapper: function(filter)
+ {
+ if ("_isWrapper" in filter)
+ return filter;
+
+ let wrapper = createFilterWrapper(filter);
+ for each (let subscription in this.subscriptions)
+ {
+ // Replace filter by its wrapper in all subscriptions
+ let index = -1;
+ let found = false;
+ do
+ {
+ index = subscription.filters.indexOf(filter, index + 1);
+ if (index >= 0)
+ {
+ if (!subscription.hasOwnProperty("filters"))
+ subscription.filters = subscription.filters.slice();
+
+ subscription.filters[index] = wrapper;
+ found = true;
+ }
+ } while (index >= 0);
+
+ if (found)
+ {
+ if (treeView.sortProc)
+ {
+ // Sorted filter list needs updating as well
+ index = -1;
+ do
+ {
+ index = subscription._sortedFilters.indexOf(filter, index + 1);
+ if (index >= 0)
+ subscription._sortedFilters[index] = wrapper;
+ } while (index >= 0);
+ }
+ else
+ subscription._sortedFilters = subscription.filters;
+ }
+ }
+ return wrapper;
+ },
+
+ /**
+ * Map of comparison functions by column ID or column ID + "Desc" for
+ * descending sort order.
+ * @const
+ */
+ sortProcs:
+ {
+ filter: createSortFunction(compareText, null, false),
+ filterDesc: createSortFunction(compareText, null, true),
+ slow: createSortFunction(compareSlow, compareText, true),
+ slowDesc: createSortFunction(compareSlow, compareText, false),
+ enabled: createSortFunction(compareEnabled, compareText, false),
+ enabledDesc: createSortFunction(compareEnabled, compareText, true),
+ hitcount: createSortFunction(compareHitCount, compareText, false),
+ hitcountDesc: createSortFunction(compareHitCount, compareText, true),
+ lasthit: createSortFunction(compareLastHit, compareText, false),
+ lasthitDesc: createSortFunction(compareLastHit, compareText, true)
+ },
+
+ /**
+ * Changes sort direction of the list.
+ * @param {Element} col column (<treecol>) the list should be sorted by
+ * @param {String} direction either "natural" (unsorted), "ascending" or "descending"
+ */
+ resort: function(col, direction)
+ {
+ if (this.sortColumn)
+ this.sortColumn.removeAttribute("sortDirection");
+
+ if (direction == "natural")
+ {
+ this.sortColumn = null;
+ this.sortProc = null;
+ }
+ else
+ {
+ this.sortColumn = col;
+ this.sortProc = this.sortProcs[col.id.replace(/^col-/, "") + (direction == "descending" ? "Desc" : "")];
+ this.sortColumn.setAttribute("sortDirection", direction);
+ }
+
+ for each (let subscription in this.subscriptions)
+ this.resortSubscription(subscription);
+
+ this.boxObject.invalidate();
+ },
+
+ /**
+ * Updates subscription's _sortedFilters property (sorted index
+ * of subscription's filters).
+ */
+ resortSubscription: function(/**Subscription*/ subscription)
+ {
+ if (this.sortProc)
+ {
+ // Hide comments in the list, they should be sorted like the filter following them
+ let filters = subscription.filters.slice();
+ let followingFilter = null;
+ for (let i = filters.length - 1; i >= 0; i--)
+ {
+ if (filters[i] instanceof CommentFilter)
+ filters[i] = { __proto__: followingFilter, _origFilter: filters[i] };
+ else
+ followingFilter = filters[i];
+ }
+
+ filters.sort(this.sortProc);
+
+ // Restore comments
+ for (let i = 0; i < filters.length; i++)
+ if ("_origFilter" in filters[i])
+ filters[i] = filters[i]._origFilter;
+
+ subscription._sortedFilters = filters;
+ }
+ else
+ subscription._sortedFilters = subscription.filters;
+ },
+
+ /**
+ * Selects given tree row.
+ */
+ selectRow: function(/**Integer*/ row)
+ {
+ treeView.selection.select(row);
+ treeView.boxObject.ensureRowIsVisible(row);
+ },
+
+ /**
+ * Finds the given filter in the list and selects it.
+ */
+ selectFilter: function(/**Filter*/ filter)
+ {
+ let resultSubscription = null;
+ let resultIndex;
+ for each (let subscription in this.subscriptions)
+ {
+ let index = subscription._sortedFilters.indexOf(filter);
+ if (index >= 0)
+ {
+ [resultSubscription, resultIndex] = [subscription, index];
+
+ // If the subscription is disabled continue searching - maybe
+ // we have the same filter in an enabled subscription as well
+ if (!subscription.disabled)
+ break;
+ }
+ }
+
+ if (resultSubscription)
+ {
+ let parentRow = this.getSubscriptionRow(resultSubscription);
+ if (resultSubscription.url in this.closed)
+ this.toggleOpenState(parentRow);
+ this.selectRow(parentRow + 1 + resultSubscription._description.length + resultIndex);
+ }
+ },
+
+ /**
+ * This method will select the first row of a subscription.
+ */
+ selectSubscription: function(/**Subscription*/ subscription)
+ {
+ let row = this.getSubscriptionRow(subscription);
+ if (row < 0)
+ return;
+
+ this.selection.select(row);
+ this.boxObject.ensureRowIsVisible(row);
+ },
+
+ /**
+ * This method will make sure that the list has some selection (assuming
+ * that it has at least one entry).
+ * @param {Integer} row row to be selected if the list has no selection
+ */
+ ensureSelection: function(row)
+ {
+ if (this.selection.count == 0)
+ {
+ let rowCount = this.rowCount;
+ if (row < 0)
+ row = 0;
+ if (row >= rowCount)
+ row = rowCount - 1;
+ if (row >= 0)
+ {
+ this.selection.select(row);
+ this.boxObject.ensureRowIsVisible(row);
+ }
+ }
+ else if (this.selection.currentIndex < 0)
+ {
+ let min = {};
+ this.selection.getRangeAt(0, min, {});
+ this.selection.currentIndex = min.value;
+ }
+ },
+
+ /**
+ * Checks whether there are any user-defined filters in the list.
+ */
+ hasUserFilters: function() /**Boolean*/
+ {
+ for each (let subscription in this.subscriptions)
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length)
+ return true;
+
+ return false;
+ },
+
+ /**
+ * Checks whether the given subscription is the first one displayed.
+ */
+ isFirstSubscription: function(/**Subscription*/ search) /**Boolean*/
+ {
+ for each (let subscription in this.subscriptions)
+ {
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ continue;
+
+ return (subscription == search);
+ }
+ return false;
+ },
+
+ /**
+ * Checks whether the given subscription is the last one displayed.
+ */
+ isLastSubscription: function(/**Subscription*/ search) /**Boolean*/
+ {
+ for (let i = this.subscriptions.length - 1; i >= 0; i--)
+ {
+ let subscription = this.subscriptions[i];
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ continue;
+
+ return (subscription == search);
+ }
+ return false;
+ },
+
+ /**
+ * Adds a filter to a subscription. If no subscription is given, will
+ * find one that accepts filters of this type.
+ * @result {Subscription} the subscription this filter was added to
+ */
+ addFilter: function(/**Filter*/ filter, /**Subscription*/ subscription, /**Filter*/ insertBefore, /**Boolean*/ noSelect)
+ {
+ if (!filter)
+ return null;
+
+ if (!subscription)
+ {
+ for each (let s in this.subscriptions)
+ {
+ if (s instanceof SpecialSubscription && s.isFilterAllowed(filter))
+ {
+ if (s._sortedFilters.indexOf(filter) >= 0 || s.filters.indexOf(filter) >= 0)
+ {
+ subscription = s;
+ break;
+ }
+
+ if (!subscription || s.priority > subscription.priority)
+ subscription = s;
+ }
+ }
+ }
+ if (!subscription)
+ return null;
+
+ let insertPositionSorted = subscription._sortedFilters.indexOf(filter);
+ if (insertPositionSorted >= 0)
+ {
+ // We have that filter already, only need to select it
+ if (!noSelect)
+ {
+ let parentRow = this.getSubscriptionRow(subscription);
+ if (subscription.url in this.closed)
+ this.toggleOpenState(parentRow);
+
+ this.selectRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
+ }
+ return subscription;
+ }
+
+ let insertPosition = -1;
+ if (insertBefore)
+ insertPosition = subscription.filters.indexOf(insertBefore);
+ if (insertPosition < 0)
+ {
+ insertPosition = subscription.filters.length;
+
+ // Insert before the comments at the end
+ while (insertPosition > 0 && subscription.filters[insertPosition - 1] instanceof CommentFilter && !(filter instanceof CommentFilter))
+ insertPosition--;
+ if (insertPosition == 0)
+ insertPosition = subscription.filters.length;
+ }
+
+ // If we don't have our own filters property the filter might be there already
+ if (subscription.filters.indexOf(filter) < 0)
+ {
+ // Create a copy of the original subscription filters before modifying
+ if (!subscription.hasOwnProperty("filters"))
+ subscription.filters = subscription.filters.slice();
+
+ subscription.filters.splice(insertPosition, 0, filter);
+ }
+ this.resortSubscription(subscription);
+ insertPositionSorted = subscription._sortedFilters.indexOf(filter);
+
+ let parentRow = this.getSubscriptionRow(subscription);
+
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 1)
+ {
+ this.boxObject.rowCountChanged(parentRow, this.getSubscriptionRowCount(subscription));
+ }
+ else if (!(subscription.url in this.closed))
+ {
+ this.boxObject.rowCountChanged(parentRow + 1 + subscription._description.length + insertPositionSorted, 1);
+ this.boxObject.invalidateRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
+ }
+
+ if (!noSelect)
+ {
+ if (subscription.url in this.closed)
+ this.toggleOpenState(parentRow);
+ this.selectRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
+ }
+
+ onChange();
+ return subscription;
+ },
+
+ /**
+ * Adds a subscription to the list (if it isn't there already)
+ * and makes sure it is selected.
+ */
+ addSubscription: function(/**Subscription*/ subscription, /**Boolean*/ noSelect)
+ {
+ if (this.subscriptions.indexOf(subscription) < 0)
+ {
+ this.subscriptions.push(subscription);
+ this.boxObject.rowCountChanged(this.getSubscriptionRow(subscription), this.getSubscriptionRowCount(subscription));
+ }
+
+ if (!noSelect)
+ {
+ let [currentSelected, dummy] = this.getRowInfo(this.selection.currentIndex);
+ if (currentSelected != subscription)
+ this.selectSubscription(subscription);
+ }
+ },
+
+ /**
+ * Removes a filter from the list.
+ * @param {SpecialSubscription} subscription the subscription the filter belongs to (if null, filter will be removed from all special subscriptions)
+ * @param {Filter} filter filter to be removed
+ */
+ removeFilter: function(subscription, filter)
+ {
+ if (!subscription)
+ {
+ for each (let subscription in this.subscriptions)
+ {
+ if (!(subscription instanceof SpecialSubscription))
+ continue;
+
+ this.removeFilter(subscription, filter);
+ }
+ return;
+ }
+
+ let parentRow = this.getSubscriptionRow(subscription);
+ let rowCount = this.getSubscriptionRowCount(subscription);
+ let newSelection = parentRow;
+
+ // The filter might be removed already if we don't have our own filters property yet
+ let index = subscription.filters.indexOf(filter);
+ if (index >= 0)
+ {
+ if (!subscription.hasOwnProperty("filters"))
+ subscription.filters = subscription.filters.slice();
+
+ subscription.filters.splice(index, 1);
+ }
+
+ if (subscription.filters != subscription._sortedFilters)
+ index = subscription._sortedFilters.indexOf(filter);
+ if (index < 0)
+ return;
+
+ if (treeView.sortProc)
+ subscription._sortedFilters.splice(index, 1);
+ else
+ subscription._sortedFilters = subscription.filters;
+
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
+ {
+ // Empty special subscriptions aren't shown, remove everything
+ this.boxObject.rowCountChanged(parentRow, -rowCount);
+ newSelection -= rowCount;
+ }
+ else if (!(subscription.url in this.closed))
+ {
+ newSelection = parentRow + 1 + subscription._description.length + index;
+ this.boxObject.rowCountChanged(newSelection, -1);
+ }
+
+ this.ensureSelection(newSelection);
+ onChange();
+ },
+
+ /**
+ * Removes a filter subscription from the list.
+ * @param {RegularSubscription} subscription filter subscription to be removed
+ */
+ removeSubscription: function(subscription)
+ {
+ let index = this.subscriptions.indexOf(subscription);
+ if (index < 0)
+ return;
+
+ let firstRow = this.getSubscriptionRow(subscription);
+ let rowCount = this.getSubscriptionRowCount(subscription);
+
+ this.subscriptions.splice(index, 1);
+ this.boxObject.rowCountChanged(firstRow, -rowCount);
+
+ this.ensureSelection(firstRow);
+ onChange();
+ },
+
+ /**
+ * Moves a filter in the list up or down.
+ * @param {Boolean} up if true, the filter is moved up
+ */
+ moveFilter: function(up)
+ {
+ let oldRow = this.selection.currentIndex;
+ let [subscription, filter] = this.getRowInfo(oldRow);
+ if (this.isSorted() || !(filter instanceof Filter) || !(subscription instanceof SpecialSubscription))
+ return;
+
+ let oldIndex = subscription.filters.indexOf(filter);
+ if (oldIndex < 0)
+ return;
+
+ let newIndex = (up ? oldIndex - 1 : oldIndex + 1);
+ if (newIndex < 0 || newIndex >= subscription.filters.length)
+ return;
+
+ // Create a copy of the original subscription filters before modifying
+ if (!subscription.hasOwnProperty("filters"))
+ {
+ subscription.filters = subscription.filters.slice();
+ subscription._sortedFilters = subscription.filters;
+ }
+
+ [subscription.filters[oldIndex], subscription.filters[newIndex]] = [subscription.filters[newIndex], subscription.filters[oldIndex]];
+
+ let newRow = oldRow - oldIndex + newIndex;
+ this.boxObject.invalidateRange(Math.min(oldRow, newRow), Math.max(oldRow, newRow));
+ this.selectRow(newRow);
+
+ onChange();
+ },
+
+ /**
+ * Moves a filter in the list up or down.
+ * @param {Boolean} up if true, the filter is moved up
+ */
+ moveSubscription: function(up)
+ {
+ let [subscription, filter] = this.getRowInfo(this.selection.currentIndex);
+
+ let oldIndex = this.subscriptions.indexOf(subscription);
+ if (oldIndex < 0)
+ return;
+
+ let oldRow = this.getSubscriptionRow(subscription);
+ let offset = this.selection.currentIndex - oldRow;
+ let newIndex = oldIndex;
+ do
+ {
+ newIndex = (up ? newIndex - 1 : newIndex + 1);
+ if (newIndex < 0 || newIndex >= this.subscriptions.length)
+ return;
+ } while (this.subscriptions[newIndex] instanceof SpecialSubscription && this.subscriptions[newIndex]._sortedFilters.length == 0);
+
+ [this.subscriptions[oldIndex], this.subscriptions[newIndex]] = [this.subscriptions[newIndex], this.subscriptions[oldIndex]];
+
+ let newRow = this.getSubscriptionRow(subscription);
+ let rowCount = this.getSubscriptionRowCount(subscription);
+ this.boxObject.invalidateRange(Math.min(oldRow, newRow), Math.max(oldRow, newRow) + rowCount - 1);
+ this.selectRow(newRow + offset);
+
+ onChange();
+ },
+
+ dragSubscription: null,
+ dragFilter: null,
+ startDrag: function(row, e)
+ {
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!subscription)
+ return;
+ if (filter instanceof Filter && !(subscription instanceof SpecialSubscription))
+ return;
+ if (filter instanceof Filter && !(filter instanceof CommentFilter) && this.isSorted())
+ return;
+
+ if (!(filter instanceof Filter))
+ filter = null;
+
+ let array = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
+ let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
+ let data = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+ if (filter instanceof Filter)
+ e.dataTransfer.setData("text/plain", filter.text);
+ else
+ e.dataTransfer.setData("text/plain", subscription.title);
+
+ this.dragSubscription = subscription;
+ this.dragFilter = filter;
+
+ e.stopPropagation();
+ },
+
+ finishDrag: function()
+ {
+ this.dragSubscription = null;
+ this.dragFilter = null;
+ },
+
+ /**
+ * Toggles disabled state of the selected filters/subscriptions.
+ * @param {Array of Filter or Subscription} items
+ */
+ toggleDisabled: function(items)
+ {
+ let newValue;
+ for each (let item in items)
+ {
+ if (!(item instanceof ActiveFilter || item instanceof Subscription))
+ return;
+
+ if (item instanceof ActiveFilter)
+ item = this.ensureFilterWrapper(item);
+
+ if (typeof newValue == "undefined")
+ newValue = !item.disabled;
+
+ item.disabled = newValue;
+ }
+
+ if (typeof newValue != "undefined")
+ {
+ this.boxObject.invalidate();
+ onChange();
+ }
+ },
+
+ /**
+ * Invalidates all instances of a filter in the list, making sure changes
+ * are displayed.
+ */
+ invalidateFilter: function(/**Filter*/ search)
+ {
+ let min = this.boxObject.getFirstVisibleRow();
+ let max = this.boxObject.getLastVisibleRow();
+ for (let i = min; i <= max; i++)
+ {
+ let [subscription, filter] = this.getRowInfo(i);
+ if (filter == filter)
+ this.boxObject.invalidateRow(i);
+ }
+ },
+
+ /**
+ * Invalidates a subscription in the list, making sure changes are displayed.
+ * @param {Subscription} subscription
+ * @param {Integer} oldRowCount (optional) number of roww in the subscription before the change
+ */
+ invalidateSubscription: function(subscription, oldRowCount)
+ {
+ let row = this.getSubscriptionRow(subscription);
+ if (row < 0)
+ return;
+
+ let rowCount = this.getSubscriptionRowCount(subscription);
+ if (typeof oldRowCount != "undefined" && rowCount != oldRowCount)
+ this.boxObject.rowCountChanged(row + Math.min(rowCount, oldRowCount), rowCount - oldRowCount);
+
+ if (typeof oldRowCount != "undefined" && oldRowCount < rowCount)
+ rowCount = oldRowCount;
+ this.boxObject.invalidateRange(row, row + rowCount - 1);
+ },
+
+ /**
+ * Makes sure the description rows of the subscription are updated.
+ */
+ invalidateSubscriptionInfo: function(/**Subscription*/subscription)
+ {
+ let row = this.getSubscriptionRow(subscription);
+
+ let oldCount = subscription._description.length;
+ subscription._description = getSubscriptionDescription(subscription);
+ let newCount = subscription._description.length;
+ if (oldCount != newCount)
+ this.boxObject.rowCountChanged(row + Math.min(oldCount, newCount), newCount - oldCount);
+
+ this.boxObject.invalidateRange(row, row + newCount);
+ },
+
+ /**
+ * Removes all user-defined filters from the list.
+ */
+ removeUserFilters: function()
+ {
+ for each (let subscription in this.subscriptions)
+ {
+ if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length > 0)
+ {
+ let row = this.getSubscriptionRow(subscription);
+ let count = this.getSubscriptionRowCount(subscription);
+
+ subscription.filters = [];
+ subscription._sortedFilters = subscription.filters;
+ this.boxObject.rowCountChanged(row, -count);
+
+ onChange();
+ }
+ }
+ this.ensureSelection(0);
+ },
+
+ /**
+ * Saves all changes back to filter storage.
+ */
+ applyChanges: function()
+ {
+ try
+ {
+ FilterListener.batchMode = true;
+
+ let oldSubscriptions = {__proto__: null};
+ for each (let subscription in FilterStorage.subscriptions)
+ oldSubscriptions[subscription.url] = true;
+
+ let newSubscriptions = {__proto__: null};
+ let subscriptions = [];
+ for each (let subscription in this.subscriptions)
+ {
+ let changed = false;
+ let disableChanged = (subscription.disabled != subscription.__proto__.disabled);
+ for (let key in subscription)
+ {
+ if (subscription.hasOwnProperty(key) && key[0] != "_" && key != "filters")
+ {
+ subscription.__proto__[key] = subscription[key];
+ delete subscription[key];
+ changed = true;
+ }
+ }
+
+ let hasFilters = {__proto__: null};
+ let hadWrappers = false;
+ for (let i = 0; i < subscription.filters.length; i++)
+ {
+ let filter = subscription.filters[i];
+ if ("_isWrapper" in filter)
+ {
+ if (filter.disabled != filter.__proto__.disabled)
+ {
+ filter.__proto__.disabled = filter.disabled;
+ FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter.__proto__]);
+ }
+ subscription.filters[i] = filter.__proto__;
+ hadWrappers = true;
+ }
+ hasFilters[filter.text] = true;
+ }
+
+ let filtersChanged = (subscription.filters.length != subscription.__proto__.filters.length);
+ if (!filtersChanged)
+ {
+ for each (let filter in subscription.__proto__.filters)
+ {
+ if (!(filter.text in hasFilters))
+ {
+ filtersChanged = true;
+ break;
+ }
+ }
+ }
+
+ if (!(subscription.url in oldSubscriptions))
+ FilterStorage.addSubscription(subscription.__proto__);
+ else if (filtersChanged)
+ FilterStorage.updateSubscriptionFilters(subscription.__proto__, subscription.filters);
+ else if (changed)
+ {
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription.__proto__]);
+ if (disableChanged)
+ FilterStorage.triggerObservers(subscription.disabled ? "subscriptions disable" : "subscriptions enable", [subscription.__proto__]);
+ }
+
+ // Even if the filters didn't change, their ordering might have
+ // changed. Replace filters on the original subscription without
+ // triggering observers.
+ subscription.__proto__.filters = subscription.filters;
+ delete subscription.filters;
+
+ if (hadWrappers)
+ {
+ // Reinitialize _sortedFilters to remove wrappers from it
+ this.resortSubscription(subscription);
+ }
+
+ newSubscriptions[subscription.url] = true;
+ subscriptions.push(subscription.__proto__);
+ }
+
+ filterWrappers = {__proto__: null};
+
+ for each (let subscription in FilterStorage.subscriptions.slice())
+ if (!(subscription.url in newSubscriptions))
+ FilterStorage.removeSubscription(subscription);
+
+ // Make sure that filter storage has the subscriptions in correct order,
+ // replace subscriptions list without triggering observers.
+ FilterStorage.subscriptions = subscriptions;
+
+ FilterStorage.saveToDisk();
+ }
+ finally
+ {
+ FilterListener.batchMode = false;
+ }
+ },
+
+ /**
+ * Searches a text string in the subscription titles, subscription
+ * descriptions and filters. Selects the matches.
+ * @param {String} text text being searched
+ * @param {Integer} direction 1 for searching forwards from current position,
+ * -1 for searching backwards,
+ * 0 for searching forwards but including current position as well
+ * @param {Boolean} highlightAll if true, all matches will be selected and not only the current one
+ * @param {Boolean} caseSensitive if true, string comparisons should be case-sensitive
+ * @return {Integer} one of the nsITypeAheadFind constants
+ */
+ find: function(text, direction, highlightAll, caseSensitive)
+ {
+ function normalizeString(string)
+ {
+ return caseSensitive ? string : string.toLowerCase();
+ }
+ text = normalizeString(text);
+
+ // Matches: current row, first match, previous match, next match, last match
+ let match = [null, null, null, null, null];
+ let [currentSubscription, currentFilter] = this.getRowInfo(this.selection.currentIndex);
+ let isCurrent = false;
+ let foundCurrent = !currentSubscription;
+ let rowCache = {__proto__: null};
+ if (highlightAll)
+ this.selection.clearSelection();
+
+ let selectMatch = function(subscription, offset)
+ {
+ if (highlightAll)
+ {
+ if (!(subscription.url in rowCache))
+ rowCache[subscription.url] = treeView.getSubscriptionRow(subscription);
+
+ let row = rowCache[subscription.url];
+ if (offset && subscription.url in treeView.closed)
+ treeView.toggleOpenState(row);
+ treeView.selection.rangedSelect(row + offset, row + offset, true);
+ }
+
+ let index = (isCurrent ? 0 : (foundCurrent ? 4 : 2));
+ match[index] = [subscription, offset];
+ if (index > 0 && !match[index - 1])
+ match[index - 1] = match[index];
+ };
+
+ for each (let subscription in this.subscriptions)
+ {
+ // Skip invisible subscriptions
+ let rowCount = this.getSubscriptionRowCount(subscription);
+ if (rowCount == 0)
+ continue;
+
+ let offset = 0;
+ isCurrent = (subscription == currentSubscription && !currentFilter);
+ if (normalizeString(subscription.title).indexOf(text) >= 0)
+ selectMatch(subscription, offset);
+ if (isCurrent)
+ foundCurrent = true;
+ offset++;
+
+ for each (let description in subscription._description)
+ {
+ isCurrent = (subscription == currentSubscription && currentFilter === description);
+ if (normalizeString(description).indexOf(text) >= 0)
+ selectMatch(subscription, offset);
+ if (isCurrent)
+ foundCurrent = true;
+ offset++;
+ }
+
+ for each (let filter in subscription._sortedFilters)
+ {
+ isCurrent = (subscription == currentSubscription && filter == currentFilter);
+ if (normalizeString(filter.text).indexOf(text) >= 0)
+ selectMatch(subscription, offset);
+ if (isCurrent)
+ foundCurrent = true;
+ offset++;
+ }
+ }
+
+ let found = null;
+ let status = "";
+ if (direction == 0)
+ found = match[0] || match[3] || match[1];
+ else if (direction > 0)
+ found = match[3] || match[1] || match[0];
+ else
+ found = match[2] || match[4] || match[0];
+
+ if (!found)
+ return Ci.nsITypeAheadFind.FIND_NOTFOUND;
+
+ let [subscription, offset] = found;
+ let row = this.getSubscriptionRow(subscription);
+ if (offset && subscription.url in this.closed)
+ this.toggleOpenState(row);
+ if (highlightAll)
+ this.selection.currentIndex = row + offset;
+ else
+ this.selection.select(row + offset);
+ this.boxObject.ensureRowIsVisible(row + offset);
+
+ if (direction < 0 && found != match[2])
+ return Ci.nsITypeAheadFind.FIND_WRAPPED;
+ if ((direction > 0 && found != match[3]) || (direction == 0 && found == match[1]))
+ return Ci.nsITypeAheadFind.FIND_WRAPPED;
+
+ return Ci.nsITypeAheadFind.FIND_FOUND;
+ },
+
+ //
+ // Inline filter editor
+ //
+
+ editor: null,
+ editorParent: null,
+ editedRow: -1,
+ editorKeyPressHandler: null,
+ editorBlurHandler: null,
+ editorCancelHandler: null,
+ editorDummy: null,
+ editorDummyInit: "",
+
+ /**
+ * true if the editor is currently open
+ * @type Boolean
+ */
+ get isEditing()
+ {
+ return (this.editedRow >= 0);
+ },
+
+ /**
+ * Initializes inline editor.
+ * @param {Element} editor text field to be used as inline editor
+ * @param {Element} editorParent editor's parent node to be made visible when the editor should be shown
+ */
+ setEditor: function(editor, editorParent)
+ {
+ this.editor = editor;
+ this.editorParent = editorParent;
+
+ let me = this;
+ this.editorKeyPressHandler = function(e)
+ {
+ if (e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER)
+ {
+ me.stopEditor(true);
+ if (e.ctrlKey || e.altKey || e.metaKey)
+ document.documentElement.acceptDialog();
+ else
+ {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ }
+ else if (e.keyCode == e.DOM_VK_CANCEL || e.keyCode == e.DOM_VK_ESCAPE)
+ {
+ me.stopEditor(false);
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ };
+ this.editorBlurHandler = function(e)
+ {
+ setTimeout(function()
+ {
+ let focused = document.commandDispatcher.focusedElement;
+ if (!focused || focused != me.editor.field)
+ me.stopEditor(true, true);
+ }, 0);
+ };
+
+ // Prevent cyclic references through closures
+ editor = null;
+ editorParent = null;
+ },
+
+ /**
+ * Opens inline editor.
+ * @param {Boolean} insert if false, the editor will insert a new filter, otherwise edit currently selected filter
+ */
+ startEditor: function(insert)
+ {
+ this.stopEditor(false);
+
+ let row = this.selection.currentIndex;
+ let [subscription, filter] = this.getRowInfo(row);
+ if (!(subscription instanceof SpecialSubscription) || !(filter instanceof Filter))
+ {
+ let dummySubscription = new Subscription("~dummy~");
+ dummySubscription.title = Utils.getString("new_filter_group_title");
+ dummySubscription.filters.push(" ");
+ dummySubscription = createSubscriptionWrapper(dummySubscription);
+
+ this.subscriptions.unshift(dummySubscription);
+ this.boxObject.rowCountChanged(0, this.getSubscriptionRowCount(dummySubscription));
+
+ row = 1;
+ this.selectRow(row);
+ this.editorDummy = dummySubscription;
+ }
+ else if (insert)
+ {
+ if (subscription._sortedFilters == subscription.filters)
+ subscription._sortedFilters = subscription.filters.slice();
+
+ let index = subscription._sortedFilters.indexOf(filter);
+ subscription._sortedFilters.splice(index, 0, " ");
+ this.boxObject.rowCountChanged(row, 1);
+
+ this.selectRow(row);
+ this.editorDummy = [subscription, index];
+ }
+
+ let col = this.boxObject.columns.getPrimaryColumn();
+ let textX = {};
+ let textY = {};
+ let textWidth = {};
+ let textHeight = {};
+ this.boxObject.ensureRowIsVisible(row);
+ this.boxObject.getCoordsForCellItem(row, col, "text", textX, textY, textWidth, textHeight);
+
+ let cellX = {};
+ let cellWidth = {};
+ this.boxObject.getCoordsForCellItem(row, col, "cell", cellX, {}, cellWidth, {});
+ cellWidth.value -= textX.value - cellX.value;
+
+ // Need to translate coordinates so that they are relative to <stack>, not <treechildren>
+ let treeBody = this.boxObject.treeBody;
+ let editorStack = this.editorParent.parentNode;
+ textX.value += treeBody.boxObject.x - editorStack.boxObject.x;
+ textY.value += treeBody.boxObject.y - editorStack.boxObject.y;
+
+ this.selection.clearSelection();
+
+ let style = window.getComputedStyle(this.editor, "");
+ let topadj = parseInt(style.borderTopWidth) + parseInt(style.paddingTop);
+
+ this.editedRow = row;
+ this.editorParent.hidden = false;
+ this.editorParent.width = cellWidth.value;
+ this.editorParent.height = textHeight.value + topadj + parseInt(style.borderBottomWidth) + parseInt(style.paddingBottom);
+ this.editorParent.left = textX.value;
+ this.editorParent.top = textY.value - topadj;
+
+ let text = (this.editorDummy ? this.editorDummyInit : filter.text);
+
+ this.editor.focus();
+ this.editor.field = document.commandDispatcher.focusedElement;
+ this.editor.field.value = text;
+ this.editor.field.setSelectionRange(this.editor.value.length, this.editor.value.length);
+
+ // Need to attach handlers to the embedded html:input instead of menulist - won't catch blur otherwise
+ this.editor.field.addEventListener("keypress", this.editorKeyPressHandler, false);
+ this.editor.field.addEventListener("blur", this.editorBlurHandler, false);
+
+ this.boxObject.invalidateRow(row);
+ },
+
+ /**
+ * Closes inline editor.
+ * @param {Boolean} save if true, the editor result should be saved (user accepted changes)
+ * @param {Boolean} blur if true, editor was closed on blur and the list shouldn't be focused
+ */
+ stopEditor: function(save, blur)
+ {
+ if (this.editedRow < 0)
+ return;
+
+ this.editor.field.removeEventListener("keypress", this.editorKeyPressHandler, false);
+ this.editor.field.removeEventListener("blur", this.editorBlurHandler, false);
+
+ let insert = (this.editorDummy != null);
+ if (this.editorDummy instanceof Subscription)
+ {
+ let rowCount = this.getSubscriptionRowCount(this.editorDummy);
+ this.subscriptions.shift();
+ this.boxObject.rowCountChanged(0, -rowCount);
+ this.selectRow(0);
+ this.editedRow = -1;
+ }
+ else if (this.editorDummy)
+ {
+ let [subscription, index] = this.editorDummy;
+ subscription._sortedFilters.splice(index, 1);
+ this.boxObject.rowCountChanged(this.editedRow, -1);
+ this.selectRow(this.editedRow);
+ }
+ else
+ this.selectRow(this.editedRow);
+
+ if (typeof blur == "undefined" || !blur)
+ this.boxObject.treeBody.parentNode.focus();
+
+ let [subscription, filter] = this.getRowInfo(this.editedRow);
+ let text = Filter.normalize(this.editor.value);
+ if (save && text && (insert || !(filter instanceof Filter) || text != filter.text))
+ {
+ let newFilter = getFilterByText(text);
+ if (filter && subscription.isFilterAllowed(newFilter))
+ this.addFilter(newFilter, subscription, filter);
+ else
+ this.addFilter(newFilter);
+
+ if (!insert)
+ this.removeFilter(subscription, filter);
+
+ onChange();
+ }
+
+ this.editor.field.value = "";
+ this.editorParent.hidden = true;
+
+ this.editedRow = -1;
+ this.editorDummy = null;
+ this.editorDummyInit = (save ? "" : text);
+ }
+};
diff --git a/chrome/adblockplus.jar!/content/ui/settings.xul b/chrome/adblockplus.jar!/content/ui/settings.xul
new file mode 100644
index 0000000..e2abf64
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/settings.xul
@@ -0,0 +1,220 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://global/skin/tree.css" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/settings.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/settings.dtd">
+
+<dialog
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&dialog.title;"
+ id="abpPreferencesWindow"
+ onload="init()"
+ onunload="cleanUp()"
+ ondialogaccept="applyChanges(); return true;"
+ ondialogextra2="treeView.startEditor(true)"
+ buttons="accept,cancel,extra2"
+ buttonlabelextra2="&add.label;â¦"
+ buttonaccesskeyextra2="&add.accesskey;"
+ width="600"
+ height="450"
+ persist="screenX screenY width height sizemode"
+ windowtype="abp:settings">
+
+<script type="application/x-javascript;version=1.7" src="utils.js"/>
+<script type="application/x-javascript;version=1.7" src="settings.js"/>
+<script type="application/x-javascript;version=1.7" src="findbar.js"/>
+
+<keyset id="adblockKeys">
+ <key id="synchsubscription-key" key="t" modifiers="accel"/>
+ <key id="synchsubscriptions-key" key="t" modifiers="accel,shift" command="synchsubscriptions-command"/>
+ <key id="import-key" key="i" modifiers="accel" command="import-command"/>
+ <key id="export-key" key="e" modifiers="accel" command="export-command"/>
+ <key id="selectall-key" key="a" modifiers="accel" command="selectall-command"/>
+ <key id="copy-key" key="c" modifiers="accel" command="copy-command"/>
+ <key id="cut-key" key="x" modifiers="accel" command="cut-command"/>
+ <key id="paste-key" key="v" modifiers="accel" command="paste-command"/>
+ <key id="find-key" key="f" modifiers="accel" command="find-command"/>
+ <key id="find-again-key" key="g" modifiers="accel" command="find-again-command"/>
+ <key id="find-previous-key" key="g" modifiers="accel,shift" command="find-previous-command"/>
+ <key id="find-again-key2" keycode="VK_F3" command="find-again-command"/>
+ <key id="find-previous-key2" keycode="VK_F3" modifiers="shift" command="find-previous-command"/>
+ <key id="edit-key" keycode="VK_ENTER"/>
+ <key id="remove-key" keycode="VK_DELETE"/>
+ <key id="addfilter-key" keycode="VK_INSERT"/>
+ <key id="moveup-key" keycode="VK_UP" modifiers="accel"/>
+ <key id="movedown-key" keycode="VK_DOWN" modifiers="accel"/>
+ <key id="movegroupup-key" keycode="VK_UP" modifiers="accel,shift"/>
+ <key id="movegroupdown-key" keycode="VK_DOWN" modifiers="accel,shift"/>
+</keyset>
+
+<commandset id="abpCommands">
+ <command id="addsubscription-command" oncommand="editSubscription(null)"/>
+ <command id="synchsubscriptions-command" oncommand="synchAllSubscriptions()"/>
+ <command id="import-command" oncommand="importList()"/>
+ <command id="export-command" oncommand="exportList()"/>
+ <command id="selectall-command" oncommand="treeView.selection.selectAll()"/>
+ <command id="copy-command" oncommand="copyToClipboard()"/>
+ <command id="cut-command" oncommand="copyToClipboard(); removeFilters(false)"/>
+ <command id="paste-command" oncommand="pasteFromClipboard()"/>
+ <command id="remove-command" oncommand="removeFilters(true)"/>
+ <command id="find-command" oncommand="E('findbar').startFind(E('findbar').FIND_NORMAL)"/>
+ <command id="find-again-command" oncommand="E('findbar').onFindAgainCommand(false)"/>
+ <command id="find-previous-command" oncommand="E('findbar').onFindAgainCommand(true)"/>
+</commandset>
+
+<popupset id="abpPopups">
+ <menupopup id="listitem-context" onpopupshowing="return fillContext()">
+ <menuitem id="context-synchsubscription" label="&context.synchsubscription.label;" oncommand="synchSubscription()" key="synchsubscription-key" />
+ <menuitem id="context-editsubscription" label="&context.editsubscription.label;â¦" oncommand="editFilter('subscription')" key="edit-key"/>
+ <menuitem id="context-edit" label="&context.edit.label;" oncommand="editFilter('filter')" key="edit-key"/>
+ <menuitem id="context-resethitcount" label="&context.resethitcount.label;â¦" oncommand="resetHitCounts(false)"/>
+ <menuitem id="context-moveup" label="&context.moveup.label;" oncommand="treeView.moveFilter(true)" key="moveup-key"/>
+ <menuitem id="context-movedown" label="&context.movedown.label;" oncommand="treeView.moveFilter(false)" key="movedown-key"/>
+ <menuseparator/>
+ <menuitem id="context-cut" label="&cut.label;" accesskey="&cut.accesskey;" command="cut-command" key="cut-key"/>
+ <menuitem id="context-copy" label="©.label;" accesskey="©.accesskey;" command="copy-command" key="copy-key"/>
+ <menuitem id="context-paste" label="&paste.label;" accesskey="&paste.accesskey;" command="paste-command" key="paste-key"/>
+ <menuitem id="context-remove" label="&remove.label;" accesskey="&remove.accesskey;" command="remove-command" key="remove-key"/>
+ <menuitem id="context-enable" label="&context.enable.label;" oncommand="toggleDisabled()"/>
+ <menuitem id="context-disable" label="&context.disable.label;" oncommand="toggleDisabled()"/>
+ <menuseparator/>
+ <menuitem id="context-movegroupup" label="&context.movegroupup.label;" oncommand="treeView.moveSubscription(true)" key="movegroupup-key"/>
+ <menuitem id="context-movegroupdown" label="&context.movegroupdown.label;" oncommand="treeView.moveSubscription(false)" key="movegroupdown-key"/>
+ </menupopup>
+ <menupopup id="treecols-context" onpopupshowing="fillViewPopup('context-')"/>
+ <tooltip id="tree-tooltip" onpopupshowing="return showTreeTooltip(event);"/>
+</popupset>
+
+<toolbox id="menuToolbox">
+ <menubar id="menu" onpopupshowing="treeView.stopEditor(true, true);">
+ <menu id="filters-menu" label="&filters.label;" accesskey="&filters.accesskey;">
+ <menupopup id="filters-popup" onpopupshowing="fillFiltersPopup()">
+ <menuitem id="addfilter" label="&add.label;â¦" accesskey="&add.accesskey;" key="addfilter-key" oncommand="treeView.startEditor(true)"/>
+ <menuseparator/>
+ <menuitem id="addsubscription" label="&addsubscription.label;â¦" accesskey="&addsubscription.accesskey;" command="addsubscription-command"/>
+ <menuitem id="synchsubscriptions" label="&synchsubscriptions.label;" accesskey="&synchsubscriptions.accesskey;" key="synchsubscriptions-key" command="synchsubscriptions-command"/>
+ <menuseparator/>
+ <menuitem id="import" label="&import.label;â¦" accesskey="&import.accesskey;" key="import-key" command="import-command"/>
+ <menuitem id="export" label="&export.label;â¦" accesskey="&export.accesskey;" key="export-key" command="export-command"/>
+ <menuitem id="clearall" label="&clearall.label;â¦" accesskey="&clearall.accesskey;" oncommand="clearList()"/>
+ <menuseparator/>
+ <menuitem id="resethitcounts" label="&resethitcounts.label;â¦" accesskey="&resethitcounts.accesskey;" oncommand="resetHitCounts(true)"/>
+ </menupopup>
+ </menu>
+ <menu id="edit-menu" label="&edit.label;" accesskey="&edit.accesskey;">
+ <menupopup id="edit-popup">
+ <menuitem id="cut" label="&cut.label;" accesskey="&cut.accesskey;" command="cut-command" key="cut-key"/>
+ <menuitem id="copy" label="©.label;" accesskey="©.accesskey;" command="copy-command" key="copy-key"/>
+ <menuitem id="paste" label="&paste.label;" accesskey="&paste.accesskey;" command="paste-command" key="paste-key"/>
+ <menuitem id="remove" label="&remove.label;" accesskey="&remove.accesskey;" command="remove-command" key="remove-key"/>
+ <menuseparator/>
+ <menuitem id="find" label="&menu.find.label;â¦" accesskey="&menu.find.accesskey;" command="find-command" key="find-key"/>
+ <menuitem id="find-again" label="&menu.findagain.label;" accesskey="&menu.findagain.accesskey;" command="find-again-command" key="find-again-key"/>
+ </menupopup>
+ </menu>
+ <menu id="view-menu" label="&view.label;" accesskey="&view.accesskey;">
+ <menupopup id="view-popup" onpopupshowing="fillViewPopup('')">
+ <menuitem id="view-filter" label="&filter.column;" accesskey="&filter.accesskey;" type="checkbox" disabled="true"/>
+ <menuitem id="view-slow" label="&slow.column;" accesskey="&slow.accesskey;" type="checkbox" oncommand="toggleColumn('col-slow')"/>
+ <menuitem id="view-enabled" label="&enabled.column;" accesskey="&enabled.accesskey;" type="checkbox" oncommand="toggleColumn('col-enabled')"/>
+ <menuitem id="view-hitcount" label="&hitcount.column;" accesskey="&hitcount.accesskey;" type="checkbox" oncommand="toggleColumn('col-hitcount')"/>
+ <menuitem id="view-lasthit" label="&lasthit.column;" accesskey="&lasthit.accesskey;" type="checkbox" oncommand="toggleColumn('col-lasthit')"/>
+ <menuseparator/>
+ <menu id="sort-menu" label="&sort.label;" accesskey="&sort.accesskey;">
+ <menupopup id="sort-popup">
+ <menuitem id="sort-none" label="&sort.none.label;" accesskey="&sort.none.accesskey;" type="radio" name="sortColumn" oncommand="sortBy(null)"/>
+ <menuitem id="sort-filter" label="&filter.column;" accesskey="&filter.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-filter')"/>
+ <menuitem id="sort-slow" label="&slow.column;" accesskey="&slow.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-slow')"/>
+ <menuitem id="sort-enabled" label="&enabled.column;" accesskey="&enabled.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-enabled')"/>
+ <menuitem id="sort-hitcount" label="&hitcount.column;" accesskey="&hitcount.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-hitcount')"/>
+ <menuitem id="sort-lasthit" label="&lasthit.column;" accesskey="&lasthit.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-lasthit')"/>
+ <menuseparator/>
+ <menuitem id="sort-asc" label="&sort.ascending.label;" accesskey="&sort.ascending.accesskey;" type="radio" name="sortOrder" oncommand="setSortOrder('ascending')"/>
+ <menuitem id="sort-desc" label="&sort.descending.label;" accesskey="&sort.descending.accesskey;" type="radio" name="sortOrder" oncommand="setSortOrder('descending')"/>
+ </menupopup>
+ </menu>
+ </menupopup>
+ </menu>
+ <menu id="options-menu" label="&options.label;" accesskey="&options.accesskey;">
+ <menupopup id="options-popup" onpopupshowing="fillOptionsPopup()">
+ <menuitem id="abp-enabled" label="&enable.label;" accesskey="&enable.accesskey;" type="checkbox" oncommand="togglePref('enabled')"/>
+ <menuseparator/>
+ <menuitem id="frameobjects" label="&objecttabs.label;" accesskey="&objecttabs.accesskey;" type="checkbox" oncommand="togglePref('frameobjects')"/>
+ <menuitem id="slowcollapse" label="&collapse.label;" accesskey="&collapse.accesskey;" type="checkbox" oncommand="togglePref('fastcollapse')"/>
+ <menuitem id="sync" label="&sync.label;" accesskey="&sync.accesskey;" type="checkbox" oncommand="toggleSync();"/>
+ <menuseparator/>
+ <menuitem id="showintoolbar" label="&showintoolbar.label;" accesskey="&showintoolbar.accesskey;" type="checkbox" oncommand="togglePref('showintoolbar')"/>
+ <menuitem id="showinstatusbar" label="&showinstatusbar.label;" accesskey="&showinstatusbar.accesskey;" type="checkbox" oncommand="togglePref('showinstatusbar')"/>
+ </menupopup>
+ </menu>
+ <menu id="help-menu" label="&help.label;" accesskey="&help.accesskey;">
+ <menupopup id="help-popup">
+ <menuitem id="gettingStartedLink" label="&gettingStarted.label;" accesskey="&gettingStarted.accesskey;" oncommand="Utils.loadDocLink('gettingStarted');"/>
+ <menuitem id="faqLink" label="&faq.label;" accesskey="&faq.accesskey;" oncommand="Utils.loadDocLink('faq');"/>
+ <menuitem id="filtersLink" label="&filterdoc.label;" accesskey="&filterdoc.accesskey;" oncommand="Utils.loadDocLink('filterdoc');"/>
+ <menuseparator/>
+ <menuitem id="aboutAbp" label="&about.label;â¦" accesskey="&about.accesskey;" oncommand="openAbout()"/>
+ </menupopup>
+ </menu>
+ </menubar>
+</toolbox>
+
+<description id="introduction">
+ &description;
+</description>
+
+<button id="applyButton" class="dialog-button" hidden="true" label="&apply.label;" accesskey="&apply.accesskey;" oncommand="applyChanges()"/>
+
+<vbox id="listarea" flex="1">
+ <stack id="listStack" flex="1">
+ <tree id="list" onselect="updateCommands()" context="listitem-context" persist="closedSubscriptions" flex="1" seltype="multiple" hidecolumnpicker="true" enableColumnDrag="true">
+ <treecols context="treecols-context">
+ <treecol id="col-filter" label="&filter.column;" primary="true" flex="10" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="col-slow" label="!" flex="0" width="16" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="col-enabled" label="&enabled.column;" flex="0" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="col-hitcount" label="&hitcount.column;" flex="0" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="col-lasthit" label="&lasthit.column;" hidden="true" flex="4" persist="width ordinal sortDirection hidden"/>
+ </treecols>
+
+ <treechildren id="treechildren" tooltip="tree-tooltip" onclick="onListClick(event)" ondblclick="onListDblClick(event)" ondragstart="onListDragStart(event);" ondragend="onListDragEnd(event);"/>
+ </tree>
+ <hbox id="listEditorParent" align="center" hidden="true">
+ <textbox id="listEditor" class="tree-input" flex="1"/>
+ <image id="listEditorIcon" onclick="if (event.button == 0) treeView.stopEditor(false);" />
+ </hbox>
+ </stack>
+
+ <findbar id="findbar"/>
+</vbox>
+
+</dialog>
diff --git a/chrome/adblockplus.jar!/content/ui/sidebar.js b/chrome/adblockplus.jar!/content/ui/sidebar.js
new file mode 100644
index 0000000..9afc546
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/sidebar.js
@@ -0,0 +1,1167 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+// Main browser window
+var mainWin = parent;
+
+// The window handler currently in use
+var requestNotifier = null;
+
+var cacheSession = null;
+var noFlash = false;
+
+// Matcher for disabled filters
+var disabledMatcher = new CombinedMatcher();
+
+// Cached string values
+var docDomainThirdParty = null;
+var docDomainFirstParty = null;
+
+var abpHooks = null;
+
+let lastSelectionProp = "abpSelected" + RequestNotifier.getDataSeed();
+
+function init() {
+ docDomainThirdParty = document.documentElement.getAttribute("docDomainThirdParty");
+ docDomainFirstParty = document.documentElement.getAttribute("docDomainFirstParty");
+
+ var list = E("list");
+ list.view = treeView;
+
+ // Restore previous state
+ var params = Utils.getParams();
+ if (params && params.filter)
+ {
+ E("searchField").value = params.filter;
+ treeView.setFilter(params.filter);
+ }
+ if (params && params.focus && E(params.focus))
+ E(params.focus).focus();
+ else
+ E("searchField").focus();
+
+ var selected = null;
+ if (/sidebarDetached\.xul$/.test(parent.location.href)) {
+ mainWin = parent.opener;
+ mainWin.addEventListener("unload", mainUnload, false);
+ E("detachButton").hidden = true;
+ E("reattachButton").hidden = false;
+ if (!mainWin.document.getElementById("abp-sidebar"))
+ E("reattachButton").setAttribute("disabled", "true");
+ if (mainWin.document.getElementById("abp-key-sidebar")) {
+ var sidebarKey = mainWin.document.getElementById("abp-key-sidebar").cloneNode(true);
+ parent.document.getElementById("detached-keyset").appendChild(parent.document.importNode(sidebarKey, true));
+ }
+
+ // Set default size/position unless already persisted
+ let defaults = {screenX: 0, screenY: 0, width: 600, height: 300};
+ if (params && params.position)
+ defaults = params.position;
+
+ let wnd = parent.document.documentElement;
+ for (let attr in defaults)
+ if (!wnd.hasAttribute(attr))
+ wnd.setAttribute(attr, defaults[attr]);
+ }
+
+ abpHooks = mainWin.document.getElementById("abp-hooks");
+ window.__defineGetter__("content", function() {return abpHooks.getBrowser().contentWindow;});
+
+ // Initialize matcher for disabled filters
+ reloadDisabledFilters();
+ FilterStorage.addObserver(reloadDisabledFilters);
+ Prefs.addListener(onPrefChange);
+
+ // Activate flasher
+ list.addEventListener("select", onSelectionChange, false);
+
+ // Initialize data
+ handleLocationChange();
+
+ // Install a progress listener to catch location changes
+ abpHooks.getBrowser().addProgressListener(progressListener);
+}
+
+// To be called for a detached window when the main window has been closed
+function mainUnload() {
+ parent.close();
+}
+
+// To be called on unload
+function cleanUp() {
+ flasher.stop();
+ requestNotifier.shutdown();
+ FilterStorage.removeObserver(reloadDisabledFilters);
+ Prefs.removeListener(onPrefChange);
+ E("list").view = null;
+
+ abpHooks.getBrowser().removeProgressListener(progressListener);
+ mainWin.removeEventListener("unload", mainUnload, false);
+}
+
+/**
+ * Tracks preference changes, calls reloadDisabledFilters whenever Adblock Plus
+ * is enabled/disabled.
+ */
+function onPrefChange(name)
+{
+ if (name == "enabled")
+ reloadDisabledFilters();
+}
+
+/**
+ * Updates matcher for disabled filters (global disabledMatcher variable),
+ * called on each filter change.
+ */
+function reloadDisabledFilters()
+{
+ disabledMatcher.clear();
+
+ if (Prefs.enabled)
+ {
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (subscription.disabled)
+ continue;
+
+ for each (let filter in subscription.filters)
+ if (filter instanceof RegExpFilter && filter.disabled)
+ disabledMatcher.add(filter);
+ }
+ }
+
+ treeView.updateFilters();
+}
+
+// Called whenever list selection changes - triggers flasher
+function onSelectionChange() {
+ var item = treeView.getSelectedItem();
+ if (item)
+ E("copy-command").removeAttribute("disabled");
+ else
+ E("copy-command").setAttribute("disabled", "true");
+
+ if (item && window.content)
+ {
+ let key = item.location + " " + item.type + " " + item.docDomain;
+ window.content.document.setUserData(lastSelectionProp, key, null);
+ treeView.itemToSelect = null;
+ }
+
+ if (!noFlash)
+ flasher.flash(item ? item.nodes : null);
+}
+
+function handleLocationChange()
+{
+ if (requestNotifier)
+ requestNotifier.shutdown();
+
+ treeView.clearData();
+ treeView.itemToSelect = window.content.document.getUserData(lastSelectionProp);
+ requestNotifier = new RequestNotifier(window.content, function(wnd, node, item, scanComplete)
+ {
+ if (item)
+ treeView.addItem(node, item, scanComplete);
+ });
+}
+
+// Fills a box with text splitting it up into multiple lines if necessary
+function setMultilineContent(box, text, noRemove)
+{
+ if (!noRemove)
+ while (box.firstChild)
+ box.removeChild(box.firstChild);
+
+ for (var i = 0; i < text.length; i += 80)
+ {
+ var description = document.createElement("description");
+ description.setAttribute("value", text.substr(i, 80));
+ box.appendChild(description);
+ }
+}
+
+// Fill in tooltip data before showing it
+function fillInTooltip(e) {
+ var item;
+ if (treeView.data && !treeView.data.length)
+ item = treeView.getDummyTooltip();
+ else
+ item = treeView.getItemAt(e.clientX, e.clientY);
+
+ if (!item)
+ return false;
+
+ let filter = ("filter" in item && item.filter ? item.filter : null);
+ let size = ("tooltip" in item ? null : getItemSize(item));
+ let subscriptions = (filter ? filter.subscriptions.filter(function(subscription) { return !subscription.disabled; }) : []);
+
+ E("tooltipDummy").hidden = !("tooltip" in item);
+ E("tooltipAddressRow").hidden = ("tooltip" in item);
+ E("tooltipTypeRow").hidden = ("tooltip" in item);
+ E("tooltipSizeRow").hidden = !size;
+ E("tooltipDocDomainRow").hidden = ("tooltip" in item || !item.docDomain);
+ E("tooltipFilterRow").hidden = !filter;
+ E("tooltipFilterSourceRow").hidden = !subscriptions.length;
+
+ if ("tooltip" in item)
+ E("tooltipDummy").setAttribute("value", item.tooltip);
+ else
+ {
+ E("tooltipAddress").parentNode.hidden = (item.typeDescr == "ELEMHIDE");
+ setMultilineContent(E("tooltipAddress"), item.location);
+
+ var type = item.localizedDescr;
+ if (filter && filter instanceof WhitelistFilter)
+ type += " " + E("tooltipType").getAttribute("whitelisted");
+ else if (filter && item.typeDescr != "ELEMHIDE")
+ type += " " + E("tooltipType").getAttribute("filtered");
+ E("tooltipType").setAttribute("value", type);
+
+ if (size)
+ E("tooltipSize").setAttribute("value", size.join(" x "));
+
+ E("tooltipDocDomain").setAttribute("value", item.docDomain + " " + (item.thirdParty ? docDomainThirdParty : docDomainFirstParty));
+ }
+
+ if (filter)
+ {
+ let filterField = E("tooltipFilter");
+ setMultilineContent(filterField, filter.text);
+ if (filter.disabled)
+ {
+ let disabledText = document.createElement("description");
+ disabledText.className = "disabledTextLabel";
+ disabledText.textContent = filterField.getAttribute("disabledText");
+ filterField.appendChild(disabledText);
+ }
+
+ if (subscriptions.length)
+ {
+ let sourceElement = E("tooltipFilterSource");
+ while (sourceElement.firstChild)
+ sourceElement.removeChild(sourceElement.firstChild);
+ for (let i = 0; i < subscriptions.length; i++)
+ setMultilineContent(sourceElement, subscriptions[i].title, true);
+ }
+ }
+
+ var showPreview = Prefs.previewimages && !("tooltip" in item);
+ showPreview = showPreview && item.typeDescr == "IMAGE";
+ showPreview = showPreview && (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter);
+ if (showPreview) {
+ // Check whether image is in cache (stolen from ImgLikeOpera)
+ if (!cacheSession) {
+ var cacheService = Cc["@mozilla.org/network/cache-service;1"].getService(Ci.nsICacheService);
+ cacheSession = cacheService.createSession("HTTP", Ci.nsICache.STORE_ANYWHERE, true);
+ }
+
+ try {
+ var descriptor = cacheSession.openCacheEntry(item.location, Ci.nsICache.ACCESS_READ, false);
+ descriptor.close();
+ }
+ catch (e) {
+ showPreview = false;
+ }
+ }
+
+ if (showPreview) {
+ E("tooltipPreviewBox").hidden = false;
+ E("tooltipPreview").setAttribute("src", "");
+ E("tooltipPreview").setAttribute("src", item.location);
+ }
+ else
+ E("tooltipPreviewBox").hidden = true;
+
+ return true;
+}
+
+const visual = {
+ OTHER: true,
+ IMAGE: true,
+ SUBDOCUMENT: true
+}
+
+/**
+ * Updates context menu before it is shown.
+ */
+function fillInContext(/**Event*/ e)
+{
+ let item, allItems;
+ if (treeView.data && !treeView.data.length)
+ {
+ item = treeView.getDummyTooltip();
+ allItems = [item];
+ }
+ else
+ {
+ item = treeView.getItemAt(e.clientX, e.clientY);
+ allItems = treeView.getAllSelectedItems();
+ }
+
+ if (!item || ("tooltip" in item && !("filter" in item)))
+ return false;
+
+ E("contextDisableFilter").hidden = true;
+ E("contextEnableFilter").hidden = true;
+ E("contextDisableOnSite").hidden = true;
+ if ("filter" in item && item.filter)
+ {
+ let filter = item.filter;
+ let menuItem = E(filter.disabled ? "contextEnableFilter" : "contextDisableFilter");
+ menuItem.filter = filter;
+ menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, filter.text));
+ menuItem.hidden = false;
+
+ if (filter instanceof ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription)))
+ {
+ let domain = null;
+ try {
+ domain = content.location.host;
+ domain = Utils.effectiveTLD.getBaseDomainFromHost(domain);
+ } catch (e) {}
+
+ if (domain && !filter.isActiveOnlyOnDomain(domain))
+ {
+ menuItem = E("contextDisableOnSite");
+ menuItem.item = item;
+ menuItem.filter = filter;
+ menuItem.domain = domain;
+ menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, domain));
+ menuItem.hidden = false;
+ }
+ }
+ }
+
+ E("contextWhitelist").hidden = ("tooltip" in item || !item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter || item.typeDescr == "ELEMHIDE");
+ E("contextBlock").hidden = !E("contextWhitelist").hidden;
+ E("contextBlock").setAttribute("disabled", "filter" in item && item.filter && !item.filter.disabled);
+ E("contextEditFilter").setAttribute("disabled", !("filter" in item && item.filter));
+ E("contextOpen").setAttribute("disabled", "tooltip" in item || item.typeDescr == "ELEMHIDE");
+ E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.typeDescr in visual) || (item.filter && !item.filter.disabled && !(item.filter instanceof WhitelistFilter)));
+ E("contextCopyFilter").setAttribute("disabled", !allItems.some(function(item) {return "filter" in item && item.filter}));
+
+ return true;
+}
+
+/**
+ * Processed mouse clicks on the item list.
+ * @param {Event} event
+ */
+function handleClick(event)
+{
+ let item = treeView.getItemAt(event.clientX, event.clientY);
+ if (event.button == 0 && treeView.getColumnAt(event.clientX, event.clientY) == "state")
+ {
+ if (item.filter)
+ enableFilter(item.filter, item.filter.disabled);
+ event.preventDefault();
+ }
+ else if (event.button == 1)
+ {
+ openInTab(item, event);
+ event.preventDefault();
+ }
+}
+
+/**
+ * Processes double-clicks on the item list.
+ * @param {Event} event
+ */
+function handleDblClick(event)
+{
+ if (event.button != 0 || treeView.getColumnAt(event.clientX, event.clientY) == "state")
+ return;
+
+ doBlock();
+}
+
+/**
+ * Opens the item in a new tab.
+ */
+function openInTab(item, /**Event*/ event)
+{
+ let items = (item ? [item] : treeView.getAllSelectedItems());
+ for each (let item in items)
+ {
+ if (item && item.typeDescr != "ELEMHIDE")
+ Utils.loadInBrowser(item.location, mainWin, event);
+ }
+}
+
+function doBlock() {
+ var item = treeView.getSelectedItem();
+ if (!item || item.typeDescr == "ELEMHIDE")
+ return;
+
+ var filter = null;
+ if (item.filter && !item.filter.disabled)
+ filter = item.filter;
+
+ if (filter && filter instanceof WhitelistFilter)
+ return;
+
+ openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", item.nodes, item.orig);
+}
+
+function editFilter() {
+ var item = treeView.getSelectedItem();
+ if (treeView.data && !treeView.data.length)
+ item = treeView.getDummyTooltip();
+
+ if (!("filter" in item) || !item.filter)
+ return;
+
+ if (!("location") in item)
+ item.location = undefined
+
+ Utils.openSettingsDialog(item.location, item.filter);
+}
+
+function enableFilter(filter, enable) {
+ filter.disabled = !enable;
+ FilterStorage.triggerObservers(enable ? "filters enable" : "filters disable", [filter]);
+ FilterStorage.saveToDisk();
+
+ treeView.boxObject.invalidate();
+}
+
+/**
+ * Edits the filter to disable it on a particular domain.
+ */
+function disableOnSite(item, /**Filter*/ filter, /**String*/ domain)
+{
+ // Generate text for new filter that excludes current domain
+ domain = domain.toUpperCase();
+ let text = filter.text;
+ if (filter instanceof RegExpFilter)
+ {
+ if (Filter.optionsRegExp.test(text))
+ {
+ let found = false;
+ let options = RegExp.$1.toUpperCase().split(",");
+ for (let i = 0; i < options.length; i++)
+ {
+ if (/^DOMAIN=(.*)/.test(options[i]))
+ {
+ let domains = RegExp.$1.split("|").filter(function(d) d != domain && d != "~" + domain && (d.length <= domain.length || d.lastIndexOf("." + domain) != d.length - domain.length - 1));
+ domains.push("~" + domain);
+ options[i] = "DOMAIN=" + domains.join("|");
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ options.push("DOMAIN=~" + domain);
+
+ text = text.replace(Filter.optionsRegExp, "$" + options.join(",").toLowerCase());
+ }
+ else
+ text += "$domain=~" + domain.toLowerCase();
+ }
+ else if (filter instanceof ElemHideFilter)
+ {
+ if (/^([^#]+)(#.*)/.test(text))
+ {
+ let selector = RegExp.$2;
+ let domains = RegExp.$1.toUpperCase().split(",").filter(function(d) d != domain && (d.length <= domain.length || d != "~" + domain && d.lastIndexOf("." + domain) != d.length - domain.length - 1));
+ domains.push("~" + domain);
+ text = domains.join(",").toLowerCase() + selector;
+ }
+ else
+ text = "~" + domain.toLowerCase() + text;
+ }
+
+ if (text == filter.text)
+ return; // Just in case, shouldn't happen
+
+ // Insert new filter before the old one and remove the old one then
+ let newFilter = Filter.fromText(text);
+ if (newFilter.disabled && newFilter.subscriptions.length)
+ {
+ newFilter.disabled = false;
+ FilterStorage.triggerObservers("filters enable", [newFilter]);
+ }
+ else if (!newFilter.subscriptions.length)
+ {
+ newFilter.disabled = false;
+ FilterStorage.addFilter(newFilter, filter);
+ }
+ FilterStorage.removeFilter(filter);
+ FilterStorage.saveToDisk();
+
+ // Update display
+ item.filter = null;
+ treeView.boxObject.invalidate();
+}
+
+function copyToClipboard() {
+ var items = treeView.getAllSelectedItems();
+ if (!items.length)
+ return;
+
+ var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+ clipboardHelper.copyString(items.map(function(item) {return item.location}).join(Utils.getLineBreak()));
+}
+
+function copyFilter() {
+ var items = treeView.getAllSelectedItems().filter(function(item) {return item.filter});
+ if (treeView.data && !treeView.data.length)
+ items = [treeView.getDummyTooltip()];
+
+ if (!items.length)
+ return;
+
+ var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
+ clipboardHelper.copyString(items.map(function(item) {return item.filter.text}).join(Utils.getLineBreak()));
+}
+
+function selectAll() {
+ treeView.selectAll();
+}
+
+// Saves sidebar's state before detaching/reattaching
+function saveState() {
+ var focused = document.commandDispatcher.focusedElement;
+ while (focused && (!focused.id || !("focus" in focused)))
+ focused = focused.parentNode;
+
+ // Calculate default position for the detached window
+ var boxObject = document.documentElement.boxObject;
+ var position = {screenX: boxObject.screenX, screenY: boxObject.screenY, width: boxObject.width, height: boxObject.height};
+
+ var params = {
+ filter: treeView.filter,
+ focus: (focused ? focused.id : null),
+ position: position
+ };
+ Utils.setParams(params);
+}
+
+// closes the sidebar
+function doClose()
+{
+ mainWin.document.getElementById("abp-command-sidebar").doCommand();
+}
+
+// detaches/reattaches the sidebar
+function detach(doDetach)
+{
+ saveState();
+
+ // Store variables locally, global variables will go away when we are closed
+ let myPrefs = Prefs;
+ let myMainWin = mainWin;
+
+ // Close sidebar and open detached window
+ myMainWin.document.getElementById("abp-command-sidebar").doCommand();
+ myPrefs.detachsidebar = doDetach;
+ myMainWin.document.getElementById("abp-command-sidebar").doCommand();
+}
+
+// Returns items size in the document if available
+function getItemSize(item)
+{
+ if (item.filter && !item.filter.disabled && item.filter instanceof BlockingFilter)
+ return null;
+
+ for each (let node in item.nodes)
+ {
+ if (node instanceof HTMLImageElement && (node.naturalWidth || node.naturalHeight))
+ return [node.naturalWidth, node.naturalHeight];
+ else if (node instanceof HTMLElement && (node.offsetWidth || node.offsetHeight))
+ return [node.offsetWidth, node.offsetHeight];
+ }
+ return null;
+}
+
+// Sort functions for the item list
+function sortByAddress(item1, item2) {
+ if (item1.location < item2.location)
+ return -1;
+ else if (item1.location > item2.location)
+ return 1;
+ else
+ return 0;
+}
+
+function sortByAddressDesc(item1, item2) {
+ return -sortByAddress(item1, item2);
+}
+
+function compareType(item1, item2) {
+ if (item1.localizedDescr < item2.localizedDescr)
+ return -1;
+ else if (item1.localizedDescr > item2.localizedDescr)
+ return 1;
+ else
+ return 0;
+}
+
+function compareFilter(item1, item2) {
+ var hasFilter1 = (item1.filter ? 1 : 0);
+ var hasFilter2 = (item2.filter ? 1 : 0);
+ if (hasFilter1 != hasFilter2)
+ return hasFilter1 - hasFilter2;
+ else if (hasFilter1 && item1.filter.text < item2.filter.text)
+ return -1;
+ else if (hasFilter1 && item1.filter.text > item2.filter.text)
+ return 1;
+ else
+ return 0;
+}
+
+function compareState(item1, item2) {
+ var state1 = (!item1.filter ? 0 : (item1.filter.disabled ? 1 : (item1.filter instanceof WhitelistFilter ? 2 : 3)));
+ var state2 = (!item2.filter ? 0 : (item2.filter.disabled ? 1 : (item2.filter instanceof WhitelistFilter ? 2 : 3)));
+ return state1 - state2;
+}
+
+function compareSize(item1, item2) {
+ var size1 = getItemSize(item1);
+ size1 = size1 ? size1[0] * size1[1] : 0;
+
+ var size2 = getItemSize(item2);
+ size2 = size2 ? size2[0] * size2[1] : 0;
+ return size1 - size2;
+}
+
+function compareDocDomain(item1, item2)
+{
+ if (item1.docDomain < item2.docDomain)
+ return -1;
+ else if (item1.docDomain > item2.docDomain)
+ return 1;
+ else if (item1.thirdParty && !item2.thirdParty)
+ return -1;
+ else if (!item1.thirdParty && item2.thirdParty)
+ return 1;
+ else
+ return 0;
+}
+
+function createSortWithFallback(cmpFunc, fallbackFunc, desc) {
+ var factor = (desc ? -1 : 1);
+
+ return function(item1, item2) {
+ var ret = cmpFunc(item1, item2);
+ if (ret == 0)
+ return fallbackFunc(item1, item2);
+ else
+ return factor * ret;
+ }
+}
+
+var progressListener =
+{
+ onLocationChange: function() handleLocationChange(),
+ onProgressChange: function() {},
+ onSecurityChange: function() {},
+ onStateChange: function() {},
+ onStatusChange: function() {},
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference])
+};
+
+// Item list's tree view object
+var treeView = {
+ //
+ // nsISupports implementation
+ //
+
+ QueryInterface: function(uuid) {
+ if (!uuid.equals(Ci.nsISupports) &&
+ !uuid.equals(Ci.nsITreeView))
+ {
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ }
+
+ return this;
+ },
+
+ //
+ // nsITreeView implementation
+ //
+
+ selection: null,
+
+ setTree: function(boxObject) {
+ if (!boxObject)
+ return;
+
+ this.boxObject = boxObject;
+ this.itemsDummy = boxObject.treeBody.getAttribute("noitemslabel");
+ this.whitelistDummy = boxObject.treeBody.getAttribute("whitelistedlabel");
+
+ var stringAtoms = ["col-address", "col-type", "col-filter", "col-state", "col-size", "col-docDomain", "state-regular", "state-filtered", "state-whitelisted", "state-hidden"];
+ var boolAtoms = ["selected", "dummy", "filter-disabled"];
+ var atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService);
+
+ this.atoms = {};
+ for each (let atom in stringAtoms)
+ this.atoms[atom] = atomService.getAtom(atom);
+ for each (let atom in boolAtoms)
+ {
+ this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true");
+ this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false");
+ }
+
+ this.itemsDummyTooltip = Utils.getString("no_blocking_suggestions");
+ this.whitelistDummyTooltip = Utils.getString("whitelisted_page");
+
+ // Check current sort direction
+ var cols = document.getElementsByTagName("treecol");
+ var sortDir = null;
+ for (let i = 0; i < cols.length; i++) {
+ var col = cols[i];
+ var dir = col.getAttribute("sortDirection");
+ if (dir && dir != "natural") {
+ this.sortColumn = col;
+ sortDir = dir;
+ }
+ }
+ if (!this.sortColumn)
+ {
+ let defaultSort = E("list").getAttribute("defaultSort");
+ if (/^(\w+)\s+(ascending|descending)$/.test(defaultSort))
+ {
+ this.sortColumn = E(RegExp.$1);
+ if (this.sortColumn)
+ {
+ sortDir = RegExp.$2;
+ this.sortColumn.setAttribute("sortDirection", sortDir);
+ }
+ }
+ }
+
+ if (sortDir)
+ {
+ this.sortProc = this.sortProcs[this.sortColumn.id + (sortDir == "descending" ? "Desc" : "")];
+ E("list").setAttribute("defaultSort", " ");
+ }
+
+ // Make sure to update the dummy row every two seconds
+ setInterval(function(view) {
+ if (!view.data || !view.data.length)
+ view.boxObject.invalidateRow(0);
+ }, 2000, this);
+
+ // Prevent a reference through closures
+ boxObject = null;
+ },
+
+ get rowCount() {
+ return (this.data && this.data.length ? this.data.length : 1);
+ },
+
+ getCellText: function(row, col) {
+ col = col.id;
+
+ if (col != "type" && col != "address" && col != "filter" && col != "size" && col != "docDomain")
+ return "";
+
+ if (this.data && this.data.length) {
+ if (row >= this.data.length)
+ return "";
+
+ if (col == "type")
+ return this.data[row].localizedDescr;
+ else if (col == "filter")
+ return (this.data[row].filter ? this.data[row].filter.text : "");
+ else if (col == "size")
+ {
+ let size = getItemSize(this.data[row]);
+ return (size ? size.join(" x ") : "");
+ }
+ else if (col == "docDomain")
+ return this.data[row].docDomain + " " + (this.data[row].thirdParty ? docDomainThirdParty : docDomainFirstParty);
+ else
+ return this.data[row].location;
+ }
+ else {
+ // Empty list, show dummy
+ if (row > 0 || (col != "address" && col != "filter"))
+ return "";
+
+ if (col == "filter") {
+ var filter = Policy.isWindowWhitelisted(window.content);
+ return filter ? filter.text : "";
+ }
+
+ return (Policy.isWindowWhitelisted(window.content) ? this.whitelistDummy : this.itemsDummy);
+ }
+ },
+
+ getColumnProperties: function(col, properties) {
+ col = col.id;
+
+ if ("col-" + col in this.atoms)
+ properties.AppendElement(this.atoms["col-" + col]);
+ },
+
+ getRowProperties: function(row, properties) {
+ if (row >= this.rowCount)
+ return;
+
+ properties.AppendElement(this.atoms["selected-" + this.selection.isSelected(row)]);
+
+ var state;
+ if (this.data && this.data.length) {
+ properties.AppendElement(this.atoms["dummy-false"]);
+
+ let filter = this.data[row].filter;
+ if (filter)
+ properties.AppendElement(this.atoms["filter-disabled-" + filter.disabled]);
+
+ state = "state-regular";
+ if (filter && !filter.disabled)
+ {
+ if (filter instanceof WhitelistFilter)
+ state = "state-whitelisted";
+ else if (filter instanceof BlockingFilter)
+ state = "state-filtered";
+ else if (filter instanceof ElemHideFilter)
+ state = "state-hidden";
+ }
+ }
+ else {
+ properties.AppendElement(this.atoms["dummy-true"]);
+
+ state = "state-filtered";
+ if (this.data && Policy.isWindowWhitelisted(window.content))
+ state = "state-whitelisted";
+ }
+ properties.AppendElement(this.atoms[state]);
+ },
+
+ getCellProperties: function(row, col, properties)
+ {
+ this.getColumnProperties(col, properties);
+ this.getRowProperties(row, properties);
+ },
+
+ cycleHeader: function(col) {
+ col = col.id;
+
+ col = E(col);
+ if (!col)
+ return;
+
+ var cycle = {
+ natural: 'ascending',
+ ascending: 'descending',
+ descending: 'natural'
+ };
+
+ var curDirection = "natural";
+ if (this.sortColumn == col)
+ curDirection = col.getAttribute("sortDirection");
+ else if (this.sortColumn)
+ this.sortColumn.removeAttribute("sortDirection");
+
+ curDirection = cycle[curDirection];
+
+ if (curDirection == "natural")
+ this.sortProc = null;
+ else
+ this.sortProc = this.sortProcs[col.id + (curDirection == "descending" ? "Desc" : "")];
+
+ if (this.data)
+ this.refilter();
+
+ col.setAttribute("sortDirection", curDirection);
+ this.sortColumn = col;
+
+ this.boxObject.invalidate();
+ },
+
+ isSorted: function() {
+ return this.sortProc;
+ },
+
+ isContainer: function() {return false},
+ isContainerOpen: function() {return false},
+ isContainerEmpty: function() {return false},
+ getLevel: function() {return 0},
+ getParentIndex: function() {return -1},
+ hasNextSibling: function() {return false},
+ toggleOpenState: function() {},
+ canDrop: function() {return false},
+ drop: function() {},
+ getCellValue: function() {return null},
+ getProgressMode: function() {return null},
+ getImageSrc: function() {return null},
+ isSeparator: function() {return false},
+ isEditable: function() {return false},
+ cycleCell: function() {},
+ performAction: function() {},
+ performActionOnRow: function() {},
+ performActionOnCell: function() {},
+ selectionChanged: function() {},
+
+ //
+ // Custom properties and methods
+ //
+
+ boxObject: null,
+ atoms: null,
+ filter: "",
+ data: null,
+ allData: [],
+ dataMap: {__proto__: null},
+ sortColumn: null,
+ sortProc: null,
+ resortTimeout: null,
+ itemsDummy: null,
+ whitelistDummy: null,
+ itemsDummyTooltip: null,
+ whitelistDummyTooltip: null,
+ itemToSelect: null,
+
+ sortProcs: {
+ address: sortByAddress,
+ addressDesc: sortByAddressDesc,
+ type: createSortWithFallback(compareType, sortByAddress, false),
+ typeDesc: createSortWithFallback(compareType, sortByAddress, true),
+ filter: createSortWithFallback(compareFilter, sortByAddress, false),
+ filterDesc: createSortWithFallback(compareFilter, sortByAddress, true),
+ state: createSortWithFallback(compareState, sortByAddress, false),
+ stateDesc: createSortWithFallback(compareState, sortByAddress, true),
+ size: createSortWithFallback(compareSize, sortByAddress, false),
+ sizeDesc: createSortWithFallback(compareSize, sortByAddress, true),
+ docDomain: createSortWithFallback(compareDocDomain, sortByAddress, false),
+ docDomainDesc: createSortWithFallback(compareDocDomain, sortByAddress, true)
+ },
+
+ clearData: function(data) {
+ var oldRows = this.rowCount;
+
+ this.allData = [];
+ this.dataMap = {__proto__: null};
+ this.refilter();
+
+ this.boxObject.rowCountChanged(0, -oldRows);
+ this.boxObject.rowCountChanged(0, this.rowCount);
+ },
+
+ addItem: function(/**Node*/ node, /**RequestEntry*/ item, /**Boolean*/ scanComplete)
+ {
+ // Merge duplicate entries
+ let key = item.location + " " + item.type + " " + item.docDomain;
+ if (key in this.dataMap)
+ {
+ // We know this item already - take over the filter if any and be done with it
+ let existing = this.dataMap[key];
+ if (item.filter)
+ existing.filter = item.filter;
+
+ existing.nodes.push(node);
+ this.invalidateItem(existing);
+ return;
+ }
+
+ // Add new item to the list
+ // Store original item in orig property - reading out prototype is messed up in Gecko 1.9.2
+ item = {__proto__: item, orig: item, nodes: [node]};
+ this.allData.push(item);
+ this.dataMap[key] = item;
+
+ // Show disabled filters if no other filter applies
+ if (!item.filter)
+ item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
+
+ if (!this.matchesFilter(item))
+ return;
+
+ let index = -1;
+ if (this.sortProc && this.sortColumn && this.sortColumn.id == "size")
+ {
+ // Sorting by size requires accessing content document, and that's
+ // dangerous from a content policy (and we are likely called directly
+ // from a content policy call). Size data will be inaccurate anyway,
+ // delay sorting until later.
+ if (this.resortTimeout)
+ clearTimeout(this.resortTimeout);
+ this.resortTimeout = setTimeout(function(me)
+ {
+ if (me.sortProc)
+ me.data.sort(me.sortProc);
+ me.boxObject.invalidate();
+ }, 500, this);
+ }
+ else if (this.sortProc)
+ for (var i = 0; index < 0 && i < this.data.length; i++)
+ if (this.sortProc(item, this.data[i]) < 0)
+ index = i;
+
+ if (index >= 0)
+ this.data.splice(index, 0, item);
+ else {
+ this.data.push(item);
+ index = this.data.length - 1;
+ }
+
+ if (this.data.length == 1)
+ this.boxObject.invalidateRow(0);
+ else
+ this.boxObject.rowCountChanged(index, 1);
+
+ if (this.itemToSelect == key)
+ {
+ this.selection.select(index);
+ this.boxObject.ensureRowIsVisible(index);
+ this.itemToSelect = null;
+ }
+ else if (!scanComplete && this.selection.currentIndex >= 0) // Keep selected row visible while scanning
+ this.boxObject.ensureRowIsVisible(this.selection.currentIndex);
+ },
+
+ updateFilters: function()
+ {
+ for each (let item in this.allData)
+ {
+ if (item.filter instanceof RegExpFilter && item.filter.disabled)
+ delete item.filter;
+ if (!item.filter)
+ item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
+ }
+ this.refilter();
+ },
+
+ /**
+ * Updates the list after a filter or sorting change.
+ */
+ refilter: function()
+ {
+ if (this.resortTimeout)
+ clearTimeout(this.resortTimeout);
+
+ this.data = this.allData.filter(this.matchesFilter, this);
+
+ if (this.sortProc)
+ this.data.sort(this.sortProc);
+ },
+
+ /**
+ * Tests whether an item matches current list filter.
+ * @return {Boolean} true if the item should be shown
+ */
+ matchesFilter: function(item)
+ {
+ if (!this.filter)
+ return true;
+
+ return (item.location.toLowerCase().indexOf(this.filter) >= 0 ||
+ (item.filter && item.filter.text.toLowerCase().indexOf(this.filter) >= 0) ||
+ item.localizedDescr.toLowerCase().indexOf(this.filter) >= 0 ||
+ (item.docDomain && item.docDomain.toLowerCase().indexOf(this.filter) >= 0) ||
+ (item.docDomain && item.thirdParty && docDomainThirdParty.toLowerCase().indexOf(this.filter) >= 0) ||
+ (item.docDomain && !item.thirdParty && docDomainFirstParty.toLowerCase().indexOf(this.filter) >= 0));
+ },
+
+ setFilter: function(filter) {
+ var oldRows = this.rowCount;
+
+ this.filter = filter.toLowerCase();
+ this.refilter();
+
+ var newRows = this.rowCount;
+ if (oldRows != newRows)
+ this.boxObject.rowCountChanged(oldRows < newRows ? oldRows : newRows, this.rowCount - oldRows);
+ this.boxObject.invalidate();
+ },
+
+ selectAll: function() {
+ this.selection.selectAll();
+ },
+
+ getSelectedItem: function() {
+ if (!this.data || this.selection.currentIndex < 0 || this.selection.currentIndex >= this.data.length)
+ return null;
+
+ return this.data[this.selection.currentIndex];
+ },
+
+ getAllSelectedItems: function() {
+ let result = [];
+ if (!this.data)
+ return result;
+
+ let numRanges = this.selection.getRangeCount();
+ for (let i = 0; i < numRanges; i++)
+ {
+ let min = {};
+ let max = {};
+ let range = this.selection.getRangeAt(i, min, max);
+ for (let j = min.value; j <= max.value; j++)
+ {
+ if (j >= 0 && j < this.data.length)
+ result.push(this.data[j]);
+ }
+ }
+ return result;
+ },
+
+ getItemAt: function(x, y)
+ {
+ if (!this.data)
+ return null;
+
+ var row = this.boxObject.getRowAt(x, y);
+ if (row < 0 || row >= this.data.length)
+ return null;
+
+ return this.data[row];
+ },
+
+ getColumnAt: function(x, y)
+ {
+ if (!this.data)
+ return null;
+
+ let col = {};
+ this.boxObject.getCellAt(x, y, {}, col, {});
+ if (col.value)
+ return col.value.id;
+ },
+
+ getDummyTooltip: function() {
+ if (!this.data || this.data.length)
+ return null;
+
+ var filter = Policy.isWindowWhitelisted(window.content);
+ if (filter)
+ return {tooltip: this.whitelistDummyTooltip, filter: filter};
+ else
+ return {tooltip: this.itemsDummyTooltip};
+ },
+
+ invalidateItem: function(item)
+ {
+ let row = this.data.indexOf(item);
+ if (row >= 0)
+ this.boxObject.invalidateRow(row);
+ }
+}
diff --git a/chrome/adblockplus.jar!/content/ui/sidebar.xul b/chrome/adblockplus.jar!/content/ui/sidebar.xul
new file mode 100644
index 0000000..a5b379d
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/sidebar.xul
@@ -0,0 +1,145 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/sidebar.css" type="text/css"?>
+
+<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd">
+
+<page
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="abp-sidebar"
+ onload="init()"
+ onunload="cleanUp()"
+ docDomainThirdParty="&docDomain.thirdParty;"
+ docDomainFirstParty="&docDomain.firstParty;">
+
+ <script type="application/x-javascript;version=1.7" src="utils.js"/>
+ <script type="application/x-javascript;version=1.7" src="sidebar.js"/>
+ <script type="application/x-javascript;version=1.7" src="flasher.js"/>
+
+ <keyset id="sidebarKeys">
+ <key id="block-key" keycode="VK_ENTER"/>
+ <key id="copy-key" modifiers="accel" key="C" command="copy-command"/>
+ <key id="selectAll-key" modifiers="accel" key="A" command="selectAll-command"/>
+ </keyset>
+
+ <commandset id="sidebarCommands">
+ <command id="copy-command" oncommand="copyToClipboard()" disabled="true"/>
+ <command id="selectAll-command" oncommand="selectAll()"/>
+ </commandset>
+
+ <popupset id="sidebarPopups">
+ <tooltip id="tooltip" orient="vertical" onpopupshowing="return fillInTooltip(event);">
+ <description id="tooltipDummy"/>
+ <hbox id="tooltipPreviewBox" pack="start">
+ <image id="tooltipPreview" validate="never"/>
+ </hbox>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row id="tooltipAddressRow" align="top">
+ <label value="&tooltip.address.label;"/>
+ <vbox id="tooltipAddress"/>
+ </row>
+ <row id="tooltipTypeRow">
+ <label value="&tooltip.type.label;"/>
+ <description id="tooltipType" filtered="&tooltip.type.blocked;" whitelisted="&tooltip.type.whitelisted;"/>
+ </row>
+ <row id="tooltipSizeRow">
+ <label value="&tooltip.size.label;"/>
+ <description id="tooltipSize"/>
+ </row>
+ <row id="tooltipDocDomainRow">
+ <label value="&tooltip.docDomain.label;"/>
+ <description id="tooltipDocDomain"/>
+ </row>
+ <row id="tooltipFilterRow" align="top">
+ <label value="&tooltip.filter.label;"/>
+ <vbox id="tooltipFilter" disabledText="&tooltip.filter.disabled;"/>
+ </row>
+ <row id="tooltipFilterSourceRow" align="top">
+ <label value="&tooltip.filterSource.label;"/>
+ <vbox id="tooltipFilterSource"/>
+ </row>
+ </rows>
+ </grid>
+ </tooltip>
+
+ <menupopup id="context" onpopupshowing="return fillInContext(event)">
+ <menuitem id="contextBlock" label="&context.block.label;â¦" oncommand="doBlock()" key="block-key"/>
+ <menuitem id="contextWhitelist" label="&context.whitelist.label;â¦" oncommand="doBlock()" key="block-key"/>
+ <menuitem id="contextEditFilter" label="&context.editfilter.label;â¦" oncommand="editFilter()"/>
+ <menuitem id="contextDisableFilter" labeltempl="&context.disablefilter.label;" oncommand="enableFilter(this.filter, false)"/>
+ <menuitem id="contextEnableFilter" labeltempl="&context.enablefilter.label;" oncommand="enableFilter(this.filter, true)"/>
+ <menuitem id="contextDisableOnSite" labeltempl="&context.disablefilteronsite.label;" oncommand="disableOnSite(this.item, this.filter, this.domain)"/>
+ <menuseparator id="contextOpenSep"/>
+ <menuitem id="contextOpen" label="&context.open.label;" oncommand="openInTab(null, event)"/>
+ <menuitem id="contextFlash" label="&context.flash.label;" oncommand="onSelectionChange()"/>
+ <menuitem id="contextCopy" label="&context.copy.label;" command="copy-command" key="copy-key"/>
+ <menuitem id="contextCopyFilter" label="&context.copyFilter.label;" oncommand="copyFilter()"/>
+ <menuseparator id="contextSelectSep"/>
+ <menuitem id="contextSelectAll" label="&context.selectAll.label;" command="selectAll-command" key="selectAll-key"/>
+ </menupopup>
+ </popupset>
+
+ <hbox>
+ <hbox align="center" flex="1">
+ <label value="&search.label;" accesskey="&search.accesskey;" control="searchField"/>
+ <textbox id="searchField" flex="1" type="search" oncommand="treeView.setFilter(this.value)"/>
+ </hbox>
+ <description id="detachButton" value="&detach.label;" onclick="detach(true)"/>
+ <description id="reattachButton" value="&reattach.label;" onclick="if (this.getAttribute('disabled') != 'true') detach(false)" hidden="true"/>
+ </hbox>
+
+ <tree id="list" context="context" flex="1" seltype="multiple" enableColumnDrag="true"
+ defaultSort="state descending" persist="defaultSort"
+ onkeypress="if (event.keyCode == event.DOM_VK_RETURN || event.keyCode == event.DOM_VK_ENTER) doBlock()">
+ <treecols>
+ <treecol id="address" label="&address.label;" flex="2" crop="center" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="filter" label="&filter.label;" flex="1" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="type" label="&type.label;" width="80" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="state" label="&state.label;" width="16" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="size" label="&size.label;" width="60" hidden="true" persist="width ordinal sortDirection hidden"/>
+ <splitter class="tree-splitter"/>
+ <treecol id="docDomain" label="&docDomain.label;" width="100" hidden="true" persist="width ordinal sortDirection hidden"/>
+ </treecols>
+
+ <treechildren id="treechildren"
+ tooltip="tooltip"
+ onclick="handleClick(event)"
+ ondblclick="handleDblClick(event)"
+ noitemslabel="&noitems.label;"
+ whitelistedlabel="&whitelisted.label;"/>
+ </tree>
+</page>
diff --git a/chrome/adblockplus.jar!/content/ui/sidebarDetached.xul b/chrome/adblockplus.jar!/content/ui/sidebarDetached.xul
new file mode 100644
index 0000000..992bf42
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/sidebarDetached.xul
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+
+<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd">
+
+<window
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="abpDetachedSidebar"
+ title="&detached.title;"
+ persist="screenX screenY width height sizemode"
+ onclose="document.getElementById('abp-command-sidebar').doCommand(); return false;">
+
+ <script type="application/x-javascript">
+ // Some people actually switch off browser.frames.enabled and are surprised
+ // that things stop working...
+ window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+ .getInterface(Components.interfaces.nsIWebNavigation)
+ .QueryInterface(Components.interfaces.nsIDocShell)
+ .allowSubframes = true;
+ </script>
+
+ <keyset id="detached-keyset">
+ <key keycode="VK_ESCAPE" command="abp-command-sidebar"/>
+ <key modifiers="accel" key="w" command="abp-command-sidebar"/>
+ </keyset>
+
+ <commandset id="detached-commandset">
+ <command id="abp-command-sidebar" oncommand="document.getElementById('sidebarFrame').contentWindow.doClose()"/>
+ </commandset>
+
+ <iframe src="sidebar.xul" id="sidebarFrame" flex="1"/>
+</window>
diff --git a/chrome/adblockplus.jar!/content/ui/subscriptionSelection.js b/chrome/adblockplus.jar!/content/ui/subscriptionSelection.js
new file mode 100644
index 0000000..84b5be9
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/subscriptionSelection.js
@@ -0,0 +1,671 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+let newInstall = true;
+let savedDialogFlex = null;
+let editMode = true;
+let autoAdd = false;
+let source = null;
+let result = null;
+let initialized = false;
+
+/**
+ * Suppresses window resizing while the window is loading or if the window is loaded in a browser tab.
+ * @type Boolean
+ */
+let suppressResize = true;
+
+let closing = false;
+let subscriptionListLoading = false;
+let otherButton = null;
+
+function init()
+{
+ if (window.arguments && window.arguments.length)
+ {
+ newInstall = false;
+ [source, result] = window.arguments;
+ if (window.arguments.length > 2 && window.arguments[2])
+ window.hasSubscription = window.arguments[2];
+ }
+
+ if (newInstall && Utils.isFennec)
+ {
+ // HACK: In Fennec 4.0 menulist elements won't work "by themselves". We
+ // have to go to the top level and trigger MenuListHelperUI manually.
+ let topWnd = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+ if (topWnd.wrappedJSObject)
+ topWnd = topWnd.wrappedJSObject;
+
+ let menulist = E("subscriptions");
+ if ("MenuListHelperUI" in topWnd && menulist.parentNode.localName != "stack")
+ {
+ // Add a layer on top of the menulist to handle clicks, menulist clicks
+ // are otherwise ignored and cannot be intercepted
+ let stack = document.createElement("stack");
+ menulist.parentNode.replaceChild(stack, menulist);
+ stack.appendChild(menulist);
+
+ let clickLayer = document.createElement("hbox");
+ stack.appendChild(clickLayer);
+
+ clickLayer.addEventListener("click", function(event)
+ {
+ if (event.button == 0 && !menulist.disabled && menulist.itemCount)
+ {
+ menulist.focus();
+ topWnd.MenuListHelperUI.show(menulist);
+ }
+ }, true);
+
+ // menulist needs to be initialized after being moved, re-run init() later
+ Utils.runAsync(init);
+ return;
+ }
+
+ // The template is being displayed as a list item, remove it
+ let subscriptionsTemplate = E("subscriptionsTemplate");
+ if (subscriptionsTemplate && subscriptionsTemplate.parentNode)
+ subscriptionsTemplate.parentNode.removeChild(subscriptionsTemplate);
+
+ // window.close() closes the entire window (bug 642604), make sure to close
+ // only a single tab instead.
+ if ("BrowserUI" in topWnd)
+ {
+ window.close = function()
+ {
+ topWnd.BrowserUI.closeTab();
+ };
+ }
+ }
+
+ if (!result)
+ {
+ result = {};
+ autoAdd = true;
+ }
+ if (!source)
+ {
+ editMode = false;
+ source = {title: "", url: "", disabled: false, external: false, autoDownload: true, mainSubscriptionTitle: null, mainSubscriptionURL: null};
+ }
+ else
+ {
+ if (typeof source.mainSubscriptionURL == "undefined")
+ source.mainSubscriptionURL = source.mainSubscriptionTitle = null;
+ }
+
+ if (newInstall && !Utils.isFennec)
+ {
+ // HACK: We will remove dialog content box flex if a subscription is
+ // selected, need to find the content box and save it flex value.
+ let docContent = document.getAnonymousNodes(document.documentElement);
+ docContent = (docContent && docContent.length ? docContent[0] : null);
+ if (docContent && docContent.hasAttribute("class") &&
+ /\bdialog-content-box\b/.test(docContent.getAttribute("class")) &&
+ docContent.hasAttribute("flex"))
+ {
+ savedDialogFlex = [docContent, docContent.getAttribute("flex")]
+ }
+ }
+
+ E("description-newInstall").hidden = !newInstall;
+ if (newInstall)
+ document.documentElement.setAttribute("newInstall", "true");
+
+ E("subscriptionsBox").hidden = E("all-subscriptions-container").hidden
+ = E("subscriptionInfo").hidden = editMode;
+
+ E("fromWebText").hidden = !editMode || source instanceof Subscription;
+ E("editText").hidden = !(source instanceof Subscription) || source instanceof ExternalSubscription;
+ E("externalText").hidden = !(source instanceof ExternalSubscription);
+ E("differentSubscription").hidden = !editMode;
+
+ otherButton = document.documentElement.getButton("extra2");
+ if (!editMode)
+ {
+ // Transform the button into a text link
+ let link = document.createElement("label");
+ link.setAttribute("id", "otherButton");
+ link.setAttribute("class", "text-link");
+ link.setAttribute("value", otherButton.label);
+ link.setAttribute("accesskey", otherButton.accessKey);
+ link.setAttribute("control", "otherButton");
+ link.setAttribute("flex", "1");
+ link.setAttribute("crop", "end");
+
+ let handler = new Function("event", document.documentElement.getAttribute("ondialogextra2"));
+ link.addEventListener("command", handler, false);
+ link.addEventListener("click", handler, false);
+ link.addEventListener("keypress", function(event)
+ {
+ if (event.keyCode == event.DOM_VK_ENTER || event.keyCode == event.DOM_VK_RETURN)
+ {
+ this.doCommand();
+ event.preventDefault();
+ }
+ }, false);
+
+ otherButton.parentNode.setAttribute("align", "center");
+ otherButton.parentNode.replaceChild(link, otherButton);
+ otherButton = link;
+ }
+ otherButton.hidden = editMode;
+
+ setCustomSubscription(source.title, source.url,
+ source.mainSubscriptionTitle, source.mainSubscriptionURL);
+
+ if (source instanceof Subscription)
+ {
+ document.title = document.documentElement.getAttribute("edittitle");
+ document.documentElement.getButton("accept").setAttribute("label", document.documentElement.getAttribute("buttonlabelacceptedit"))
+ }
+
+ if (source instanceof ExternalSubscription)
+ {
+ E("location").setAttribute("disabled", "true");
+ E("autoDownload").setAttribute("disabled", "true");
+ E("autoDownload").checked = true;
+ }
+ else
+ E("autoDownload").checked = source.autoDownload;
+
+ initialized = true;
+
+ if (!editMode)
+ {
+ let list = E("subscriptions");
+ let items = list.menupopup.childNodes;
+ let selectedItem = null;
+ let selectedPrefix = null;
+ let matchCount = 0;
+ for (let i = 0; i < items.length; i++)
+ {
+ let item = items[i];
+ let prefixes = item.getAttribute("_prefixes");
+ if (!prefixes)
+ continue;
+
+ if (!selectedItem)
+ selectedItem = item;
+
+ let prefix = checkPrefixMatch(prefixes, Utils.appLocale);
+ if (prefix)
+ {
+ item.setAttribute("class", "localeMatch");
+ if (!selectedPrefix || selectedPrefix.length < prefix.length)
+ {
+ selectedItem = item;
+ selectedPrefix = prefix;
+ matchCount = 1;
+ }
+ else if (selectedPrefix && selectedPrefix.length == prefix.length)
+ {
+ matchCount++;
+
+ // If multiple items have a matching prefix of the same length:
+ // Select one of the items randomly, probability should be the same
+ // for all items. So we replace the previous match here with
+ // probability 1/N (N being the number of matches).
+ if (Math.random() * matchCount < 1)
+ {
+ selectedItem = item;
+ selectedPrefix = prefix;
+ }
+ }
+ }
+ }
+ list.selectedItem = selectedItem;
+ }
+
+ // Only resize if we are a chrome window (not loaded into a browser tab)
+ if (window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).itemType == Ci.nsIDocShellTreeItem.typeChrome)
+ suppressResize = false;
+}
+
+function checkPrefixMatch(prefixes, appLocale)
+{
+ if (!prefixes)
+ return null;
+
+ for each (let prefix in prefixes.split(/,/))
+ if (new RegExp("^" + prefix + "\\b").test(appLocale))
+ return prefix;
+
+ return null;
+}
+
+function collapseElements()
+{
+ if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL)
+ {
+ let diff = 0;
+ for (let i = 0; i < arguments.length; i++)
+ diff -= arguments[i].boxObject.height;
+ window.resizeBy(0, diff);
+ window.moveBy(0, -diff/2);
+ }
+ for (let i = 0; i < arguments.length; i++)
+ arguments[i].hidden = true;
+}
+
+function showElements()
+{
+ for (let i = 0; i < arguments.length; i++)
+ arguments[i].hidden = false;
+
+ let scrollBox = E("content-scroll").boxObject;
+ if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL && scrollBox instanceof Ci.nsIScrollBoxObject)
+ {
+ // Force reflow
+ for (let i = 0; i < arguments.length; i++)
+ arguments[i].boxObject.height;
+
+ let scrollHeight = {};
+ scrollBox.getScrolledSize({}, scrollHeight);
+ if (scrollHeight.value > scrollBox.height)
+ {
+ let diff = scrollHeight.value - scrollBox.height;
+ window.resizeBy(0, diff);
+ window.moveBy(0, -diff/2);
+ }
+ }
+}
+
+function onSelectionChange()
+{
+ if (!initialized)
+ return;
+
+ let selectedSubscription = E("subscriptions").value;
+
+ // Show/hide extra UI widgets for custom subscriptions, resize window appropriately
+ let container = E("all-subscriptions-container");
+ let inputFields = E("differentSubscription");
+ if (container.hidden && !selectedSubscription)
+ showElements(container, inputFields);
+ else if (!container.hidden && selectedSubscription)
+ collapseElements(container, inputFields);
+
+ // Make sure to hide "Add different subscription button" if we are already in that mode
+ otherButton.hidden = !selectedSubscription;
+
+ if (!selectedSubscription)
+ {
+ loadSubscriptionList();
+ E("title").focus();
+ }
+
+ if (savedDialogFlex)
+ {
+ let [docContent, flex] = savedDialogFlex;
+ if (selectedSubscription)
+ docContent.removeAttribute("flex");
+ else
+ docContent.setAttribute("flex", flex);
+ }
+
+ updateSubscriptionInfo();
+}
+
+function updateSubscriptionInfo()
+{
+ let selectedSubscription = E("subscriptions").selectedItem;
+ if (!selectedSubscription.value)
+ selectedSubscription = E("all-subscriptions").selectedItem;
+
+ E("subscriptionInfo").setAttribute("invisible", !selectedSubscription);
+ if (selectedSubscription)
+ {
+ let url = selectedSubscription.getAttribute("_url");
+ let homePage = selectedSubscription.getAttribute("_homepage")
+
+ let viewLink = E("view-list");
+ viewLink.setAttribute("_url", url);
+ viewLink.setAttribute("tooltiptext", url);
+
+ let homePageLink = E("visit-homepage");
+ homePageLink.hidden = !homePage;
+ if (homePage)
+ {
+ homePageLink.setAttribute("_url", homePage);
+ homePageLink.setAttribute("tooltiptext", homePage);
+ }
+ }
+}
+
+function reloadSubscriptionList()
+{
+ subscriptionListLoading = false;
+ loadSubscriptionList();
+}
+
+function loadSubscriptionList()
+{
+ if (subscriptionListLoading)
+ return;
+
+ E("all-subscriptions-container").selectedIndex = 0;
+ E("all-subscriptions-loading").hidden = false;
+
+ let request = new XMLHttpRequest();
+ let errorHandler = function()
+ {
+ E("all-subscriptions-container").selectedIndex = 2;
+ E("all-subscriptions-loading").hidden = true;
+ };
+ let successHandler = function()
+ {
+ if (!request.responseXML || request.responseXML.documentElement.localName != "subscriptions")
+ {
+ errorHandler();
+ return;
+ }
+
+ try
+ {
+ processSubscriptionList(request.responseXML);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ errorHandler();
+ }
+ };
+
+ request.open("GET", Prefs.subscriptions_listurl);
+ request.onerror = errorHandler;
+ request.onload = successHandler;
+ request.send(null);
+
+ subscriptionListLoading = true;
+}
+
+function processSubscriptionList(doc)
+{
+ let list = E("all-subscriptions");
+ while (list.firstChild)
+ list.removeChild(list.firstChild);
+
+ addSubscriptions(list, doc.documentElement, 0, null, null);
+ E("all-subscriptions-container").selectedIndex = 1;
+ E("all-subscriptions-loading").hidden = true;
+}
+
+function addSubscriptions(list, parent, level, parentTitle, parentURL)
+{
+ for (let i = 0; i < parent.childNodes.length; i++)
+ {
+ let node = parent.childNodes[i];
+ if (node.nodeType != Node.ELEMENT_NODE || node.localName != "subscription")
+ continue;
+
+ if (node.getAttribute("type") != "ads" || node.getAttribute("deprecated") == "true")
+ continue;
+
+ let variants = node.getElementsByTagName("variants");
+ if (!variants.length || !variants[0].childNodes.length)
+ continue;
+ variants = variants[0].childNodes;
+
+ let isFirst = true;
+ let mainTitle = null;
+ let mainURL = null;
+ for (let j = 0; j < variants.length; j++)
+ {
+ let variant = variants[j];
+ if (variant.nodeType != Node.ELEMENT_NODE || variant.localName != "variant")
+ continue;
+
+ let item = document.createElement("richlistitem");
+ item.setAttribute("_title", variant.getAttribute("title"));
+ item.setAttribute("_url", variant.getAttribute("url"));
+ if (parentTitle && parentURL && variant.getAttribute("complete") != "true")
+ {
+ item.setAttribute("_supplementForTitle", parentTitle);
+ item.setAttribute("_supplementForURL", parentURL);
+ }
+ item.setAttribute("tooltiptext", variant.getAttribute("url"));
+ item.setAttribute("_homepage", node.getAttribute("homepage"));
+
+ let title = document.createElement("description");
+ if (isFirst)
+ {
+ if (checkPrefixMatch(node.getAttribute("prefixes"), Utils.appLocale))
+ title.setAttribute("class", "subscriptionTitle localeMatch");
+ else
+ title.setAttribute("class", "subscriptionTitle");
+ title.textContent = node.getAttribute("title");
+ mainTitle = variant.getAttribute("title");
+ mainURL = variant.getAttribute("url");
+ isFirst = false;
+ }
+ title.setAttribute("flex", "1");
+ title.style.marginLeft = (20 * level) + "px";
+ item.appendChild(title);
+
+ let variantTitle = document.createElement("description");
+ variantTitle.setAttribute("class", "variant");
+ variantTitle.textContent = variant.getAttribute("title");
+ variantTitle.setAttribute("crop", "end");
+ item.appendChild(variantTitle);
+
+ list.appendChild(item);
+ }
+
+ let supplements = node.getElementsByTagName("supplements");
+ if (supplements.length)
+ addSubscriptions(list, supplements[0], level + 1, mainTitle, mainURL);
+ }
+}
+
+function onAllSelectionChange()
+{
+ let selectedItem = E("all-subscriptions").selectedItem;
+ if (!selectedItem)
+ return;
+
+ setCustomSubscription(selectedItem.getAttribute("_title"), selectedItem.getAttribute("_url"),
+ selectedItem.getAttribute("_supplementForTitle"), selectedItem.getAttribute("_supplementForURL"));
+
+ updateSubscriptionInfo();
+}
+
+function setCustomSubscription(title, url, mainSubscriptionTitle, mainSubscriptionURL)
+{
+ E("title").value = title;
+ E("location").value = url;
+
+ let messageElement = E("supplementMessage");
+ let addMainCheckbox = E("addMainSubscription");
+ if (mainSubscriptionURL && !hasSubscription(mainSubscriptionURL))
+ {
+ if (messageElement.hidden)
+ showElements(messageElement, addMainCheckbox);
+
+ let beforeLink, afterLink;
+ if (/(.*)\?1\?(.*)/.test(messageElement.getAttribute("_textTemplate")))
+ [beforeLink, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
+ else
+ [beforeLink, afterLink] = [messageElement.getAttribute("_textTemplate"), ""];
+
+ while (messageElement.firstChild)
+ messageElement.removeChild(messageElement.firstChild);
+ messageElement.appendChild(document.createTextNode(beforeLink));
+ let link = document.createElement("label");
+ link.className = "text-link";
+ link.setAttribute("tooltiptext", mainSubscriptionURL);
+ link.addEventListener("click", function() Utils.loadInBrowser(mainSubscriptionURL), false);
+ link.textContent = mainSubscriptionTitle;
+ messageElement.appendChild(link);
+ messageElement.appendChild(document.createTextNode(afterLink));
+
+ addMainCheckbox.value = mainSubscriptionURL;
+ addMainCheckbox.setAttribute("_mainSubscriptionTitle", mainSubscriptionTitle)
+ addMainCheckbox.label = addMainCheckbox.getAttribute("_labelTemplate").replace(/\?1\?/g, mainSubscriptionTitle);
+ addMainCheckbox.accessKey = addMainCheckbox.accessKey;
+ }
+ else if (!messageElement.hidden)
+ collapseElements(messageElement, addMainCheckbox);
+}
+
+function selectCustomSubscription()
+{
+ let list = E("subscriptions")
+ list.selectedItem = list.menupopup.lastChild;
+}
+
+function validateURL(url)
+{
+ url = url.replace(/^\s+/, "").replace(/\s+$/, "");
+
+ // Is this a file path?
+ try {
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(url);
+ return Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newFileURI(file).spec;
+ } catch (e) {}
+
+ // Is this a valid URL?
+ let uri = Utils.makeURI(url);
+ if (uri)
+ return uri.spec;
+
+ return null;
+}
+
+function addSubscription()
+{
+ let list = E("subscriptions");
+ let url;
+ let title;
+ let autoDownload;
+ if (list.value)
+ {
+ url = list.value;
+ title = list.label;
+ autoDownload = true;
+ }
+ else
+ {
+ url = E("location").value;
+ if (!(source instanceof ExternalSubscription))
+ url = validateURL(url);
+ if (!url)
+ {
+ Utils.alert(window, Utils.getString("subscription_invalid_location"));
+ E("location").focus();
+ return false;
+ }
+
+ title = E("title").value.replace(/^\s+/, "").replace(/\s+$/, "");
+ if (!title)
+ title = url;
+
+ autoDownload = E("autoDownload").checked;
+ }
+
+ result.url = url;
+ result.title = title;
+ result.autoDownload = autoDownload;
+ result.disabled = source.disabled;
+
+ let addMainCheckbox = E("addMainSubscription")
+ if (!addMainCheckbox.hidden && addMainCheckbox.checked)
+ {
+ result.mainSubscriptionTitle = addMainCheckbox.getAttribute("_mainSubscriptionTitle");
+ result.mainSubscriptionURL = addMainCheckbox.value;
+ }
+
+ if (autoAdd)
+ {
+ doAddSubscription(result.url, result.title, result.autoDownload, result.disabled);
+ if ("mainSubscriptionURL" in result)
+ doAddSubscription(result.mainSubscriptionURL, result.mainSubscriptionTitle, result.autoDownload, result.disabled);
+ }
+
+ closing = true;
+ return true;
+}
+
+/**
+ * Adds a new subscription to the list.
+ */
+function doAddSubscription(/**String*/ url, /**String*/ title, /**Boolean*/ autoDownload, /**Boolean*/ disabled)
+{
+ if (typeof autoDownload == "undefined")
+ autoDownload = true;
+ if (typeof disabled == "undefined")
+ disabled = false;
+
+ let subscription = Subscription.fromURL(url);
+ if (!subscription)
+ return;
+
+ FilterStorage.addSubscription(subscription);
+
+ if (disabled != subscription.disabled)
+ {
+ subscription.disabled = disabled;
+ FilterStorage.triggerObservers(disabled ? "subscriptions disable" : "subscriptions enable", [subscription]);
+ }
+
+ subscription.title = title;
+ if (subscription instanceof DownloadableSubscription)
+ subscription.autoDownload = autoDownload;
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+
+ if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
+ Synchronizer.execute(subscription);
+ FilterStorage.saveToDisk();
+}
+
+function hasSubscription(url)
+{
+ return FilterStorage.subscriptions.some(function(subscription) subscription instanceof DownloadableSubscription && subscription.url == url);
+}
+
+function checkUnload()
+{
+ if (newInstall && !closing)
+ return Utils.getString("subscription_notAdded_warning");
+
+ return undefined;
+}
+
+function onDialogCancel()
+{
+ let message = checkUnload();
+ if (!message)
+ return true;
+
+ message += " " + Utils.getString("subscription_notAdded_warning_addendum");
+ closing = Utils.confirm(window, message);
+ return closing;
+}
diff --git a/chrome/adblockplus.jar!/content/ui/subscriptionSelection.xul b/chrome/adblockplus.jar!/content/ui/subscriptionSelection.xul
new file mode 100644
index 0000000..67e98b2
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/subscriptionSelection.xul
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://adblockplus/skin/subscriptionSelection.css" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
+
+<dialog
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ buttons="accept,cancel,extra2"
+ buttonlabelaccept="&addSubscription.label;"
+ buttonlabelacceptedit="&saveSubscription.label;"
+ buttonlabelextra2="&other.label;"
+ buttonaccesskeyextra2="&other.accesskey;"
+ title="&dialog.title;"
+ edittitle="&dialog.title.edit;"
+ id="abpSubscriptionSelection"
+ windowtype="abp:subscriptionSelection"
+ onload="init()"
+ onbeforeunload="return checkUnload()"
+ ondialogcancel="return onDialogCancel()"
+ ondialogaccept="return addSubscription()"
+ ondialogextra2="selectCustomSubscription()">
+
+<script type="application/x-javascript;version=1.7" src="utils.js"/>
+<script type="application/x-javascript;version=1.7" src="subscriptionSelection.js"/>
+
+<scrollbox id="content-scroll" orient="vertical" flex="1">
+ <description id="description-newInstall">&description.newInstall;</description>
+
+ <vbox id="subscriptionsBox">
+ <label control="subscriptions">&subscriptionSelector.label;</label>
+ <menulist id="subscriptions" label=" " onselect="onSelectionChange()">
+ <menupopup datasources="subscriptions.xml" ref="*" querytype="xml">
+ <template id="subscriptionsTemplate">
+ <menuitem uri="?" label="?title" value="?url" _url="?url" _homepage="?homepage" _prefixes="?prefixes"/>
+ </template>
+ </menupopup>
+ </menulist>
+ </vbox>
+
+ <deck id="all-subscriptions-container" selectedIndex="0" flex="1" hidden="true">
+ <vbox pack="center">
+ <progressmeter id="all-subscriptions-loading" mode="undetermined"/>
+ </vbox>
+ <richlistbox id="all-subscriptions" onselect="onAllSelectionChange()"/>
+ <vbox pack="center" align="center">
+ <description value="&list.download.failed;"/>
+ <hbox>
+ <button label="&list.download.retry;" oncommand="reloadSubscriptionList()"/>
+ <button label="&list.download.website;" oncommand="Utils.loadDocLink('subscriptions')"/>
+ </hbox>
+ </vbox>
+ </deck>
+
+ <hbox id="subscriptionInfo" invisible="true">
+ <label id="view-list" class="text-link" value="&viewList.label;" onclick="Utils.loadInBrowser(this.getAttribute('_url'))"/>
+ <spacer flex="1"/>
+ <label id="visit-homepage" class="text-link" value="&visitHomepage.label;" onclick="Utils.loadInBrowser(this.getAttribute('_url'))"/>
+ </hbox>
+
+ <description id="fromWebText" hidden="true">&fromWeb.description;</description>
+ <description id="editText" hidden="true">&edit.description;</description>
+ <description id="externalText" hidden="true">&external.description;</description>
+
+ <groupbox id="differentSubscription" hidden="true">
+ <label value="&title.label;" accesskey="&title.accesskey;" control="title"/>
+ <textbox id="title"/>
+
+ <label value="&location.label;" accesskey="&location.accesskey;" control="location"/>
+ <textbox id="location"/>
+
+ <checkbox id="autoDownload" label="&autodownload.label;" accesskey="&autodownload.accesskey;"/>
+ </groupbox>
+
+ <description id="supplementMessage" hidden="true" _textTemplate="&supplementMessage;">&supplementMessage;</description>
+ <checkbox id="addMainSubscription" hidden="true" checked="true" _labelTemplate="&addMain.label;" label="&addMain.label;" accesskey="&addMain.accesskey;"/>
+</scrollbox>
+
+</dialog>
diff --git a/chrome/adblockplus.jar!/content/ui/subscriptions.xml b/chrome/adblockplus.jar!/content/ui/subscriptions.xml
new file mode 100644
index 0000000..458b150
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/subscriptions.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE subscriptions SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
+
+<subscriptions>
+ <subscription title="EasyList (English)"
+ url="https://easylist-downloads.adblockplus.org/easylist.txt"
+ homepage="http://easylist.adblockplus.org/"
+ prefixes="en"
+ author="MonztA, Ares2, Famlam, Khrin"/>
+ <subscription title="ABPindo+EasyList (Bahasa Indonesia)"
+ url="https://easylist-downloads.adblockplus.org/abpindo+easylist.txt"
+ homepage="http://indonesianfilter.blogspot.com/"
+ prefixes="id"
+ author="heradhis"/>
+ <subscription title="Bulgarian list+EasyList (бÑлгаÑÑки)"
+ url="https://easylist-downloads.adblockplus.org/bulgarian_list+easylist.txt"
+ homepage="http://stanev.org/abp/"
+ prefixes="bg"
+ author="ÐлекÑандÑÑ Ð¡Ñанев"/>
+ <subscription title="ChinaList+EasyList (䏿)"
+ url="https://easylist-downloads.adblockplus.org/chinalist+easylist.txt"
+ homepage="http://code.google.com/p/adblock-chinalist/"
+ prefixes="zh"
+ author="Gythialy"/>
+ <subscription title="DutchAdblockList+EasyList (Nederlands)"
+ url="https://easylist-downloads.adblockplus.org/dutchadblocklist+easylist.txt"
+ homepage="http://sites.google.com/site/dutchadblockfilters/"
+ prefixes="nl"
+ author="Famlam"/>
+ <subscription title="EasyList Germany+EasyList (Deutsch)"
+ url="https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt"
+ homepage="http://easylist.adblockplus.org/"
+ prefixes="de"
+ author="MonztA, Ares2, Famlam"/>
+ <subscription title="Fanboy's List (English)"
+ url="https://secure.fanboy.co.nz/fanboy-adblock.txt"
+ homepage="http://www.fanboy.co.nz/adblock/"
+ prefixes="en"
+ author="fanboy, Nitrox"/>
+ <subscription title="Liste FR+EasyList (français)"
+ url="https://easylist-downloads.adblockplus.org/liste_fr+easylist.txt"
+ homepage="http://adblock-listefr.com/"
+ prefixes="fr"
+ author="Lian"/>
+ <subscription title="ROList+EasyList (românesc)"
+ url="https://easylist-downloads.adblockplus.org/rolist+easylist.txt"
+ homepage="http://www.zoso.ro/rolist"
+ prefixes="ro"
+ author="MenetZ, Zoso"/>
+ <subscription title="RuAdList+EasyList (ÑÑÑÑкий, ÑкÑаÑнÑÑка)"
+ url="https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt"
+ homepage="http://code.google.com/p/ruadlist/"
+ prefixes="ru,uk"
+ author="Lain_13"/>
+ <subscription title="&other.label;â¦"
+ url=""
+ homepage=""
+ prefixes=""
+ author=""/>
+</subscriptions>
\ No newline at end of file
diff --git a/chrome/adblockplus.jar!/content/ui/thunderbirdOverlay.xul b/chrome/adblockplus.jar!/content/ui/thunderbirdOverlay.xul
new file mode 100644
index 0000000..5257a66
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/thunderbirdOverlay.xul
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!-- ***** BEGIN LICENSE BLOCK *****
+ - Version: MPL 1.1
+ -
+ - The contents of this file are subject to the Mozilla Public License Version
+ - 1.1 (the "License"); you may not use this file except in compliance with
+ - the License. You may obtain a copy of the License at
+ - http://www.mozilla.org/MPL/
+ -
+ - Software distributed under the License is distributed on an "AS IS" basis,
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ - for the specific language governing rights and limitations under the
+ - License.
+ -
+ - The Original Code is Adblock Plus.
+ -
+ - The Initial Developer of the Original Code is
+ - Wladimir Palant.
+ - Portions created by the Initial Developer are Copyright (C) 2006-2011
+ - the Initial Developer. All Rights Reserved.
+ -
+ - Contributor(s):
+ -
+ - ***** END LICENSE BLOCK ***** -->
+
+<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
+
+<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+ <!-- Window extensions -->
+ <window id="messengerWindow">
+ <popupset id="abp-popupset"/>
+ <keyset id="abp-keyset"/>
+ <commandset id="abp-commandset"/>
+ <box id="abp-hooks" getBrowser="return ('getBrowser' in this.window ? this.window.getBrowser() : this.window.messageContent);"
+ addTab="this.E('tabmail').openTab('contentTab', {contentPage: arguments[0]});"
+ getContextMenu="return this.E('mailContext') || this.E('messagePaneContext');"
+ getToolbox="return this.E('mail-toolbox')"
+ getDefaultToolbar="return this.E('mail-bar3');" toolbarInsertBefore="return this.E('button-tag');"/>
+ </window>
+
+ <!-- Status bar -->
+ <statusbar id="status-bar">
+ <statusbarpanel id="abp-status"/>
+ </statusbar>
+
+ <!-- Toolbar -->
+ <toolbar id="header-view-toolbar">
+ <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertbefore="hdrReplyButton"
+ class="toolbarbutton-1 msgHeaderView-button"/>
+ </toolbar>
+
+ <!-- Tools menu -->
+ <menupopup id="taskPopup">
+ <menuitem id="abp-menuitem" insertafter="downloadmgr,javaScriptConsole"/>
+ </menupopup>
+
+ <!-- Context menu -->
+ <menupopup id="mailContext">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+ <menupopup id="messagePaneContext">
+ <menuitem id="abp-image-menuitem"/>
+ <menuitem id="abp-object-menuitem"/>
+ <menuitem id="abp-media-menuitem"/>
+ <menuitem id="abp-frame-menuitem"/>
+ <menuitem id="abp-removeWhitelist-menuitem"/>
+ </menupopup>
+
+ <!-- Fake sidebar -->
+ <vbox id="messagepanebox">
+ <splitter id="abp-sidebar-splitter"/>
+ <vbox id="abp-sidebar"/>
+ </vbox>
+</overlay>
diff --git a/chrome/adblockplus.jar!/content/ui/utils.js b/chrome/adblockplus.jar!/content/ui/utils.js
new file mode 100644
index 0000000..ae5d5e3
--- /dev/null
+++ b/chrome/adblockplus.jar!/content/ui/utils.js
@@ -0,0 +1,49 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
+Cu.import(baseURL.spec + "ContentPolicy.jsm");
+Cu.import(baseURL.spec + "FilterClasses.jsm");
+Cu.import(baseURL.spec + "FilterListener.jsm");
+Cu.import(baseURL.spec + "FilterStorage.jsm");
+Cu.import(baseURL.spec + "Matcher.jsm");
+Cu.import(baseURL.spec + "Prefs.jsm");
+Cu.import(baseURL.spec + "RequestNotifier.jsm");
+Cu.import(baseURL.spec + "SubscriptionClasses.jsm");
+Cu.import(baseURL.spec + "Synchronizer.jsm");
+Cu.import(baseURL.spec + "Sync.jsm");
+Cu.import(baseURL.spec + "Utils.jsm");
+
+/**
+ * Shortcut for document.getElementById(id)
+ */
+function E(id)
+{
+ return document.getElementById(id);
+}
diff --git a/chrome/locale/ar/about.dtd b/chrome/adblockplus.jar!/locale/ar/about.dtd
similarity index 100%
rename from chrome/locale/ar/about.dtd
rename to chrome/adblockplus.jar!/locale/ar/about.dtd
diff --git a/chrome/locale/ar/composer.dtd b/chrome/adblockplus.jar!/locale/ar/composer.dtd
similarity index 100%
rename from chrome/locale/ar/composer.dtd
rename to chrome/adblockplus.jar!/locale/ar/composer.dtd
diff --git a/chrome/adblockplus.jar!/locale/ar/global.properties b/chrome/adblockplus.jar!/locale/ar/global.properties
new file mode 100644
index 0000000..024bc1e
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ar/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=اضغط ÙØªØ¸Ùر اÙÙØ§Ø¦Ù
Ø© اÙÙ
راÙÙØ©Ø اضغط Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/Ø§ÙØªØ¹Ø·ÙÙ
+action1_tooltip=اضغط ÙÙØªØ/Ø¥ØºÙØ§Ù Ø§ÙØ¹Ùاصر اÙÙ
ØØ¬ÙØ¨Ø©Ø Ø§Ø¶ØºØ· Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/ Ø§ÙØªØ¹Ø·ÙÙ
+action2_tooltip=اضغط ÙÙØªØ Ø§ÙØ®ÙØ§Ø±Ø§ØªØ Ø§Ø¶ØºØ· Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/Ø§ÙØªØ¹Ø·ÙÙ
+action3_tooltip=اضغط ÙØªØ´ØºÙÙ/تعطÙ٠آدبÙÙÙ Ø¨ÙØ§Ø³
+disabled_tooltip=آدبÙÙÙ Ø¨ÙØ§Ø³ Ù
Ø¹Ø·Ù Ø§ÙØ¢Ù
+active_tooltip=إ٠آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù. ÙÙØ§Ù ?1? اشترا٠ÙÙØªØ± Ù ?2? ÙÙØ§ØªØ± Ù
خصصة ÙÙØ¯ Ø§ÙØ§Ø³ØªØ¹Ù
اÙ
+whitelisted_tooltip=آدبÙÙÙ Ø¨ÙØ§Ø³ ÙØ¹Ø§Ù Ø§ÙØ¢ÙØ Ù ÙÙÙÙ Ù
عط٠باÙÙØ³Ø¨Ø© ÙÙØ°Ù Ø§ÙØµÙØØ©
+blocked_count_tooltip=?1? خارج ع٠?2?
+blocked_count_addendum=اÙÙ
سÙ
ÙØ ب٠?1? ÙØ§ÙÙ
Ø®ÙÙ ?2?
+no_blocking_suggestions=ÙØ§ ÙÙØ¬Ø¯ Ø¹ÙØ§ØµØ± ÙÙØØ¬Ø¨ ÙÙ ÙØ°Ù Ø§ÙØµÙØØ©
+whitelisted_page=تÙ
تعطÙ٠آدبÙÙÙ Ø¨ÙØ§Ø³ ÙÙ Ø§ÙØµÙØØ© Ø§ÙØØ§ÙÙØ©
+whitelist_description=ÙÙØ§ÙÙÙ Ø§ÙØ§Ø³ØªØ«Ùاءات
+filterlist_description=ÙÙØ§ØªØ± Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª
+invalid_description=ÙÙØ§ØªØ± خاطئة
+elemhide_description=ÙÙØ§ÙÙÙ Ø¥Ø®ÙØ§Ø¡ Ø§ÙØ¹Ùصر
+subscription_description=اشترا٠ÙÙØªØ±
+subscription_wrong_version=بعض اÙÙÙØ§ØªØ± اÙÙ
ÙØ¬Ùدة ÙÙ ÙØ°Ø§ Ø§ÙØ§Ø´ØªØ±Ø§Ù ØªØªØ·ÙØ¨ آدبÙÙÙ Ø¨ÙØ³ ?1? ÙØªØ¹Ù
ÙÙ Ø¬ÙØ¯Ø§Ù
+subscription_source=اÙÙ
صدر
+subscription_status=Ø§ÙØØ§ÙØ©
+subscription_status_autodownload=ØªØØ¯ÙØ« Ø£ÙØªÙÙ
اتÙÙÙ
+subscription_status_manualdownload=ØªØØ¯ÙØ« ÙØ¯ÙÙ
+subscription_status_externaldownload=ØªØØ¯ÙØ« خارج٠(Ø¥Ø¶Ø§ÙØ© أخرÙ)
+subscription_status_lastdownload=آخر تØÙ
ÙÙ
+subscription_status_lastdownload_inprogress=Ø¬Ø§Ø±Ù Ø§ÙØªØÙ
ÙÙ
+subscription_status_lastdownload_unknown=ØºÙØ± Ù
تاØ
+remove_subscription_warning=ÙÙ Ø£ÙØª ØÙا٠راغب Ø¨Ø¥Ø²Ø§ÙØ© ÙØ°Ø§ Ø§ÙØ§Ø´ØªØ±Ø§ÙØ
+import_filters_wrong_version=ØªØØ°Ùر : بعض اÙÙÙØ§ØªØ± ÙÙ ÙØ°Ù اÙÙØ§Ø¦Ù
Ø© ØªØªØ·ÙØ¨ آدبÙÙÙ Ø¨ÙØ³ ?1? ÙØªØ¹Ù
ÙÙ Ø¬ÙØ¯Ø§Ù. ÙØ¬Ø¨ عÙÙÙ Ø§ÙØªØØ¯ÙØ« Ø¥Ù٠آخر إصدار Ù
٠آدبÙÙÙ Ø¨ÙØ§Ø³ ÙØ¨Ù Ø§Ø³ØªÙØ±Ø§Ø¯ ÙØ°Ù اÙÙØ§Ø¦Ù
Ø©.
+import_filters_warning=ÙÙ ØªØ±ÙØ¯ استبدا٠ÙÙØ§ØªØ±Ù Ø§ÙØØ§ÙÙØ© Ø£Ù
Ø¥Ø¶Ø§ÙØ© اÙÙÙØ§ØªØ± Ø§ÙØ¬Ø¯Ùدة ÙÙ ÙÙØ§ÙØ© اÙÙØ§Ø¦Ù
Ø©Ø
+import_filters_title=Ø§Ø³ØªÙØ±Ø§Ø¯ ÙÙØ§ØªØ±
+export_filters_title=ØªØµØ¯ÙØ± ÙÙØ§ØªØ±
+invalid_filters_file=ÙÙØ³ Ù
ÙÙ ØµØ§ÙØ ÙÙÙØªØ± ÙØ¢Ø¯Ø¨ÙÙÙ Ø¨ÙØ§Ø³
+filters_write_error=ÙØ§Ù ÙÙØ§Ù خطأ ÙÙ ÙØªØ§Ø¨Ø© اÙÙÙØ§ØªØ± Ø¥Ù٠اÙÙ
ÙÙ. ØªØ£ÙØ¯ Ù
٠أ٠اÙÙ
ÙÙ ØºÙØ± Ù
ØÙ
٠ضد اÙÙØªØ§Ø¨Ø© Ø£Ù ÙØªÙ
استعÙ
اÙÙ Ù
Ù Ø¨Ø±ÙØ§Ù
ج آخر
+clearall_warning=ÙÙ Ø£ÙØª راغب ÙØ¹Ùا٠ÙÙ Ø¥Ø²Ø§ÙØ© Ù٠اÙÙÙØ§ØªØ± Ù
٠اÙÙØ§Ø¦Ù
Ø©Ø
+resethitcounts_warning=Ø£ÙØª راغب ÙØ¹Ùا٠Ù٠إعادة ضبط عداد Ø§ÙØ¶ØºØ·Ø§Øª ÙÙ٠اÙÙÙØ§ØªØ± Ø¥ÙÙ Ø§ÙØµÙØ±Ø ÙØ°Ù Ø§ÙØ¹Ù
ÙÙØ© ÙØ§ ÙÙ
ÙÙ Ø§ÙØªØ±Ø§Ø¬Ø¹ عÙÙØ§!
+resethitcounts_selected_warning=ÙÙ Ø£ÙØª راغب ÙØ¹Ùا٠Ù٠إعادة ضبط عداد Ø§ÙØ¶ØºØ·Ø§Øª ÙÙÙÙØ§ØªØ± اÙÙ
ختارة Ø¥ÙÙ Ø§ÙØµÙØ±Ø ÙØ°Ù Ø§ÙØ¹Ù
ÙÙØ© ÙØ§ ÙÙ
ÙÙ Ø§ÙØªØ±Ø§Ø¬Ø¹ عÙÙØ§!
+filter_regexp_tooltip=ÙØ°Ø§ اÙÙÙØªØ± Ø¥Ù
ا "تعبر Ù
ÙØ·ÙÙ" Ø£Ù Ø£ÙØµØ± Ù
٠أ٠تتÙ
ØªØØ³ÙÙÙ. اÙÙØ«Ùر Ù
Ù ÙØ°Ù اÙÙÙØ§ØªØ± ÙØ¯ تؤد٠إÙ٠بطء ÙÙ Ø§ÙØªØµÙØ
+filter_elemhide_duplicate_id=ÙÙØ· ID ÙØ§ØØ¯ ÙÙØ¹Ùصر Ø§ÙØ°Ù Ø³ÙØªÙ
Ø¥Ø®ÙØ§Ø¤Ù ÙÙ
ÙÙ Ø£Ù ÙØØ¯Ø¯
+filter_elemhide_nocriteria=ÙÙ
ÙØªÙ
ØªØØ¯Ùد ØµÙØºØ© ÙÙØªØ¹Ø±Ù عÙÙ Ø§ÙØ¹Ùصر ÙØ¥Ø®ÙاؤÙ
+subscription_notAdded_warning=ÙÙ
تÙÙ
Ø¨Ø¥Ø¶Ø§ÙØ© أ٠اشترا٠ÙÙØªØ±. بدÙ٠اشترا٠ÙÙØªØ± ستضطر ÙØ¥Ø¶Ø§ÙØ© اÙÙÙØ§ØªØ± ÙØ¯ÙÙØ§Ù
+subscription_notAdded_warning_addendum=ÙÙ ØªØ±ÙØ¯ اÙÙ
تابعةØ
+subscription_invalid_location=Ù
ÙÙØ¹ ÙØ§Ø¦Ù
Ø© اÙÙÙØªØ± ÙÙØ³ صØÙØ ÙØ¹ÙÙØ§Ù ÙÙØ¨ Ù ÙØ§ ÙØ§Ø³Ù
Ù
ÙÙ
+synchronize_invalid_url=ÙØ´Ù Ø§ÙØ£Ù
Ø±Ø ÙÙØ³ عÙÙØ§Ù صØÙØ
+synchronize_connection_error=ÙØ´Ù Ø§ÙØ£Ù
ر بسبب ÙØ´Ù Ø§ÙØªØÙ
ÙÙ
+synchronize_invalid_data=ÙØ´Ù Ø§ÙØ£Ù
Ø±Ø ÙÙØ³Øª ÙØ§Ø¦Ù
Ø© ÙÙØ§ØªØ± صØÙØØ©
+synchronize_checksum_mismatch=ÙØ´ÙØ Ø¹Ø¯Ù
تطاب٠checksum
+synchronize_ok=ÙØ¬Ø§Ø
+overwrite=Ø§Ø³ØªØ¨Ø¯Ø§Ù Ø§ÙØØ§ÙÙ Ø¨Ø§ÙØ¬Ø¯Ùد
+append=Ø¥ÙØØ§Ù
+new_filter_group_title=ÙÙØªØ± Ø¬Ø¯ÙØ¯
+type_label_other=أخرÙ
+type_label_script=Ø³ÙØ±Ùبت
+type_label_image=ØµÙØ±Ø©
+type_label_stylesheet=جدÙÙ Ø§ÙØ£ÙÙ
اط
+type_label_object=Ø¹ÙØµØ±
+type_label_subdocument=إطار
+type_label_document=Ù
Ø³ØªÙØ¯
+type_label_elemhide=Ù
Ø®ÙÙ
+type_label_xbl=ربط XBL
+type_label_ping=Ping ÙÙØ±Ø§Ø¨Ø·
+type_label_xmlhttprequest=Ø·ÙØ¨ XML
+type_label_object_subrequest=Ø·ÙØ¨ ÙØ±Ø¹Ù ÙÙØ¹Ùصر
+type_label_dtd=DTD
+type_label_media=ØµÙØªÙÙØ¯ÙÙ
+type_label_font=Ø§ÙØ®Ø·
+fennec_status_enabled=آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù
+fennec_status_disabled=آدبÙÙÙ Ø¨ÙØ³ Ù
عطÙ
+fennec_status_enabled_site=آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù عÙÙ ?1?
+fennec_status_disabled_site=آدبÙÙÙ Ø¨ÙØ³ Ù
عط٠عÙÙ ?1?
+sync_engine_title=Ø¨ÙØ§Ùات آدبÙÙÙ Ø¨ÙØ³
diff --git a/chrome/locale/ar/overlay.dtd b/chrome/adblockplus.jar!/locale/ar/overlay.dtd
similarity index 100%
rename from chrome/locale/ar/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ar/overlay.dtd
diff --git a/chrome/locale/ar/sendReport.dtd b/chrome/adblockplus.jar!/locale/ar/sendReport.dtd
similarity index 100%
rename from chrome/locale/ar/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/ar/sendReport.dtd
diff --git a/chrome/locale/ar/settings.dtd b/chrome/adblockplus.jar!/locale/ar/settings.dtd
similarity index 100%
rename from chrome/locale/ar/settings.dtd
rename to chrome/adblockplus.jar!/locale/ar/settings.dtd
diff --git a/chrome/locale/ar/sidebar.dtd b/chrome/adblockplus.jar!/locale/ar/sidebar.dtd
similarity index 100%
rename from chrome/locale/ar/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ar/sidebar.dtd
diff --git a/chrome/locale/ar/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ar/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ar/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ar/subscriptionSelection.dtd
diff --git a/chrome/locale/bg/about.dtd b/chrome/adblockplus.jar!/locale/bg/about.dtd
similarity index 100%
rename from chrome/locale/bg/about.dtd
rename to chrome/adblockplus.jar!/locale/bg/about.dtd
diff --git a/chrome/locale/bg/composer.dtd b/chrome/adblockplus.jar!/locale/bg/composer.dtd
similarity index 100%
rename from chrome/locale/bg/composer.dtd
rename to chrome/adblockplus.jar!/locale/bg/composer.dtd
diff --git a/chrome/locale/bg/global.properties b/chrome/adblockplus.jar!/locale/bg/global.properties
similarity index 100%
rename from chrome/locale/bg/global.properties
rename to chrome/adblockplus.jar!/locale/bg/global.properties
diff --git a/chrome/locale/bg/overlay.dtd b/chrome/adblockplus.jar!/locale/bg/overlay.dtd
similarity index 100%
rename from chrome/locale/bg/overlay.dtd
rename to chrome/adblockplus.jar!/locale/bg/overlay.dtd
diff --git a/chrome/locale/bg/sendReport.dtd b/chrome/adblockplus.jar!/locale/bg/sendReport.dtd
similarity index 100%
rename from chrome/locale/bg/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/bg/sendReport.dtd
diff --git a/chrome/locale/bg/settings.dtd b/chrome/adblockplus.jar!/locale/bg/settings.dtd
similarity index 100%
rename from chrome/locale/bg/settings.dtd
rename to chrome/adblockplus.jar!/locale/bg/settings.dtd
diff --git a/chrome/locale/bg/sidebar.dtd b/chrome/adblockplus.jar!/locale/bg/sidebar.dtd
similarity index 100%
rename from chrome/locale/bg/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/bg/sidebar.dtd
diff --git a/chrome/locale/bg/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/bg/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/bg/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/bg/subscriptionSelection.dtd
diff --git a/chrome/locale/ca/about.dtd b/chrome/adblockplus.jar!/locale/ca/about.dtd
similarity index 100%
rename from chrome/locale/ca/about.dtd
rename to chrome/adblockplus.jar!/locale/ca/about.dtd
diff --git a/chrome/locale/ca/composer.dtd b/chrome/adblockplus.jar!/locale/ca/composer.dtd
similarity index 100%
rename from chrome/locale/ca/composer.dtd
rename to chrome/adblockplus.jar!/locale/ca/composer.dtd
diff --git a/chrome/locale/ca/global.properties b/chrome/adblockplus.jar!/locale/ca/global.properties
similarity index 100%
rename from chrome/locale/ca/global.properties
rename to chrome/adblockplus.jar!/locale/ca/global.properties
diff --git a/chrome/locale/ca/overlay.dtd b/chrome/adblockplus.jar!/locale/ca/overlay.dtd
similarity index 100%
rename from chrome/locale/ca/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ca/overlay.dtd
diff --git a/chrome/locale/ca/sendReport.dtd b/chrome/adblockplus.jar!/locale/ca/sendReport.dtd
similarity index 100%
rename from chrome/locale/ca/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/ca/sendReport.dtd
diff --git a/chrome/locale/ca/settings.dtd b/chrome/adblockplus.jar!/locale/ca/settings.dtd
similarity index 100%
rename from chrome/locale/ca/settings.dtd
rename to chrome/adblockplus.jar!/locale/ca/settings.dtd
diff --git a/chrome/locale/ca/sidebar.dtd b/chrome/adblockplus.jar!/locale/ca/sidebar.dtd
similarity index 100%
rename from chrome/locale/ca/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ca/sidebar.dtd
diff --git a/chrome/locale/ca/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ca/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ca/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ca/subscriptionSelection.dtd
diff --git a/chrome/locale/cs/about.dtd b/chrome/adblockplus.jar!/locale/cs/about.dtd
similarity index 100%
rename from chrome/locale/cs/about.dtd
rename to chrome/adblockplus.jar!/locale/cs/about.dtd
diff --git a/chrome/locale/cs/composer.dtd b/chrome/adblockplus.jar!/locale/cs/composer.dtd
similarity index 100%
rename from chrome/locale/cs/composer.dtd
rename to chrome/adblockplus.jar!/locale/cs/composer.dtd
diff --git a/chrome/locale/cs/global.properties b/chrome/adblockplus.jar!/locale/cs/global.properties
similarity index 100%
rename from chrome/locale/cs/global.properties
rename to chrome/adblockplus.jar!/locale/cs/global.properties
diff --git a/chrome/locale/cs/overlay.dtd b/chrome/adblockplus.jar!/locale/cs/overlay.dtd
similarity index 100%
rename from chrome/locale/cs/overlay.dtd
rename to chrome/adblockplus.jar!/locale/cs/overlay.dtd
diff --git a/chrome/locale/cs/sendReport.dtd b/chrome/adblockplus.jar!/locale/cs/sendReport.dtd
similarity index 100%
rename from chrome/locale/cs/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/cs/sendReport.dtd
diff --git a/chrome/adblockplus.jar!/locale/cs/settings.dtd b/chrome/adblockplus.jar!/locale/cs/settings.dtd
new file mode 100644
index 0000000..8de4d26
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/cs/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "PÅedvolby Adblock Plus">
+<!ENTITY filters.label "Filtry">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "PÅidat filtr">
+<!ENTITY add.accesskey "P">
+<!ENTITY addsubscription.label "PÅidat cizà filtry">
+<!ENTITY addsubscription.accesskey "c">
+<!ENTITY synchsubscriptions.label "Aktualizovat všechny cizà sady filtrů">
+<!ENTITY synchsubscriptions.accesskey "A">
+<!ENTITY import.label "Importovat filtry ze souboru">
+<!ENTITY import.accesskey "I">
+<!ENTITY export.label "Exportovat vlastnà filtry do souboru">
+<!ENTITY export.accesskey "x">
+<!ENTITY clearall.label "Odstranit všechny vlastnà filtry">
+<!ENTITY clearall.accesskey "O">
+<!ENTITY resethitcounts.label "Vynulovat poÄÃtadla zásahů">
+<!ENTITY resethitcounts.accesskey "V">
+<!ENTITY edit.label "Ãpravy">
+<!ENTITY edit.accesskey "A">
+<!ENTITY cut.label "Vyjmout">
+<!ENTITY cut.accesskey "j">
+<!ENTITY copy.label "KopÃrovat">
+<!ENTITY copy.accesskey "K">
+<!ENTITY paste.label "Vložit">
+<!ENTITY paste.accesskey "l">
+<!ENTITY remove.label "Smazat">
+<!ENTITY remove.accesskey "z">
+<!ENTITY menu.find.label "NajÃt">
+<!ENTITY menu.find.accesskey "N">
+<!ENTITY menu.findagain.label "NajÃt dalÅ¡Ã">
+<!ENTITY menu.findagain.accesskey "d">
+<!ENTITY view.label "Zobrazit">
+<!ENTITY view.accesskey "Z">
+<!ENTITY sort.label "SeÅadit podle">
+<!ENTITY sort.accesskey "S">
+<!ENTITY sort.none.label "NeÅadit">
+<!ENTITY sort.none.accesskey "N">
+<!ENTITY sort.ascending.label "VzestupnÄ (A-Z)">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "SestupnÄ (Z-A)">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Možnosti">
+<!ENTITY options.accesskey "M">
+<!ENTITY enable.label "Aktivovat Adblock Plus">
+<!ENTITY enable.accesskey "k">
+<!ENTITY showintoolbar.label "Zobrazit v nástrojové liÅ¡tÄ">
+<!ENTITY showintoolbar.accesskey "b">
+<!ENTITY showinstatusbar.label "Zobrazit ve stavovém Åádku">
+<!ENTITY showinstatusbar.accesskey "r">
+<!ENTITY objecttabs.label "Zobrazovat ouška u objektů Java a Flash">
+<!ENTITY objecttabs.accesskey "o">
+<!ENTITY collapse.label "Minimalizovat blokované objekty">
+<!ENTITY collapse.accesskey "i">
+<!ENTITY sync.label "Synchronizovat nastavenà Adbloku Plus">
+<!ENTITY sync.accesskey "s">
+<!ENTITY help.label "NápovÄda">
+<!ENTITY help.accesskey "v">
+<!ENTITY gettingStarted.label "ZaÄÃnáme">
+<!ENTITY gettingStarted.accesskey "Z">
+<!ENTITY faq.label "Äasto kladené dotazy (FAQ)">
+<!ENTITY faq.accesskey "q">
+<!ENTITY filterdoc.label "Psanà Adblock Plus filtrů">
+<!ENTITY filterdoc.accesskey "f">
+<!ENTITY about.label "O doplÅku Adblock Plus">
+<!ENTITY about.accesskey "o">
+<!ENTITY description "NásledujÃcà filtry rozhodujÃ, které adresy budou blokovány a které budou povoleny:">
+<!ENTITY filter.column "Pravidlo filtru">
+<!ENTITY filter.accesskey "P">
+<!ENTITY slow.column "Pomalé filtry">
+<!ENTITY slow.accesskey "m">
+<!ENTITY enabled.column "AktivnÃ">
+<!ENTITY enabled.accesskey "k">
+<!ENTITY hitcount.column "Zásahy">
+<!ENTITY hitcount.accesskey "h">
+<!ENTITY lasthit.column "Poslednà zásah">
+<!ENTITY lasthit.accesskey "l">
+<!ENTITY context.edit.label "PÅidat filtr">
+<!ENTITY context.resethitcount.label "Vynulovat poÄÃtadlo zásahů tohoto filtru">
+<!ENTITY context.synchsubscription.label "Aktualizovat seznam cizÃch filtrů">
+<!ENTITY context.editsubscription.label "Upravit cizà filtry">
+<!ENTITY context.moveup.label "Posunout filtr nahoru">
+<!ENTITY context.movedown.label "Posunout filtr dolů">
+<!ENTITY context.movegroupup.label "Posunout skupinu nahoru">
+<!ENTITY context.movegroupdown.label "Posunout skupinu dolů">
+<!ENTITY context.enable.label "Povolit">
+<!ENTITY context.disable.label "Zakázat">
+<!ENTITY apply.label "PoužÃt">
+<!ENTITY apply.accesskey "U">
+<!ENTITY fennec.subscription.label "Cizà sada filtrů">
diff --git a/chrome/locale/cs/sidebar.dtd b/chrome/adblockplus.jar!/locale/cs/sidebar.dtd
similarity index 100%
rename from chrome/locale/cs/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/cs/sidebar.dtd
diff --git a/chrome/locale/cs/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/cs/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/cs/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/cs/subscriptionSelection.dtd
diff --git a/chrome/locale/da/about.dtd b/chrome/adblockplus.jar!/locale/da/about.dtd
similarity index 100%
rename from chrome/locale/da/about.dtd
rename to chrome/adblockplus.jar!/locale/da/about.dtd
diff --git a/chrome/locale/da/composer.dtd b/chrome/adblockplus.jar!/locale/da/composer.dtd
similarity index 100%
rename from chrome/locale/da/composer.dtd
rename to chrome/adblockplus.jar!/locale/da/composer.dtd
diff --git a/chrome/locale/da/global.properties b/chrome/adblockplus.jar!/locale/da/global.properties
similarity index 100%
rename from chrome/locale/da/global.properties
rename to chrome/adblockplus.jar!/locale/da/global.properties
diff --git a/chrome/locale/da/overlay.dtd b/chrome/adblockplus.jar!/locale/da/overlay.dtd
similarity index 100%
rename from chrome/locale/da/overlay.dtd
rename to chrome/adblockplus.jar!/locale/da/overlay.dtd
diff --git a/chrome/locale/da/sendReport.dtd b/chrome/adblockplus.jar!/locale/da/sendReport.dtd
similarity index 100%
rename from chrome/locale/da/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/da/sendReport.dtd
diff --git a/chrome/locale/da/settings.dtd b/chrome/adblockplus.jar!/locale/da/settings.dtd
similarity index 100%
rename from chrome/locale/da/settings.dtd
rename to chrome/adblockplus.jar!/locale/da/settings.dtd
diff --git a/chrome/locale/da/sidebar.dtd b/chrome/adblockplus.jar!/locale/da/sidebar.dtd
similarity index 100%
rename from chrome/locale/da/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/da/sidebar.dtd
diff --git a/chrome/locale/da/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/da/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/da/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/da/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/de/about.dtd b/chrome/adblockplus.jar!/locale/de/about.dtd
new file mode 100644
index 0000000..bbe31e9
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/de/about.dtd
@@ -0,0 +1,15 @@
+<!ENTITY dialog.title "Ãber Adblock Plus">
+
+<!ENTITY version.title "Version">
+<!ENTITY description "
+ Mit Adblock Plus können Sie entscheiden, was Sie im Internet sehen möchten
+ und was nicht. Sie brauchen die ganze Werbung nicht mehr herunterzuladen,
+ wenn Sie sie nicht sehen möchten - Adblock Plus regelt dies für Sie!
+">
+
+<!ENTITY homepage.label "Adblock Plus im Internet:">
+<!ENTITY author.label "Entwickler:">
+<!ENTITY contributors.label "Beteiligte:">
+
+<!ENTITY subscriptionAuthors.label "Autoren von Filterabonnements:">
+<!ENTITY translators.label "Ãbersetzer:">
diff --git a/chrome/adblockplus.jar!/locale/de/composer.dtd b/chrome/adblockplus.jar!/locale/de/composer.dtd
new file mode 100644
index 0000000..65cff84
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/de/composer.dtd
@@ -0,0 +1,49 @@
+<!ENTITY dialog.title "Neuen Filter hinzufügen">
+<!ENTITY accept.label "Filter hinzufügen">
+<!ENTITY advanced.label "Erweiterte Ansicht">
+<!ENTITY basic.label "Standardansicht">
+
+<!ENTITY disabled.warning "Adblock Plus ist deaktiviert. Sie können trotzdem den Filter hinzufügen, dieser wird jedoch erst angewandt, wenn Sie [link]Adblock Plus aktivieren[/link].">
+<!ENTITY groupDisabled.warning "Die Filtergruppe "?1?", in die dieser Filter eingefügt wird, ist derzeit deaktiviert. Sie können den Filter trotzdem hinzufügen, dieser wird jedoch erst angewandt, wenn Sie [link]diese Filtergruppe aktivieren[/link].">
+<!ENTITY filter.label "Neuer Filter:">
+<!ENTITY filter.accesskey "r">
+<!ENTITY preferences.label "Existierende Filter anzeigen...">
+<!ENTITY preferences.accesskey "z">
+<!ENTITY type.filter.label "Blockierregel">
+<!ENTITY type.filter.accesskey "B">
+<!ENTITY type.whitelist.label "Ausnahmeregel">
+<!ENTITY type.whitelist.accesskey "A">
+<!ENTITY pattern.label "Muster suchen">
+<!ENTITY pattern.explanation "Das Muster kann ein beliebiger Teil der Adresse sein, das Zeichen '*' kann dabei als Jokerzeichen verwendet werden. Der Filter wird nur auf Adressen angewandt, die auf das Muster passen.">
+<!ENTITY regexp.warning "Das Muster, das Sie eingegeben haben, wird als regulärer Ausdruck interpretiert. Zu viele reguläre Ausdrücke könnten Ihren Browser verlangsamen. Falls Sie nicht beabsichtigt haben, reguläre Ausdrücke zu verwenden, fügen Sie einfach das Symbol '*' am Ende des Musters an.">
+<!ENTITY shortpattern.warning "Das Muster, das Sie eingegeben haben, ist zu kurz zum Optimieren. Zu viele solche Muster könnten Ihren Browser verlangsamen. Es ist deshalb empfehlenswert, nach Möglichkeit ein längeres Muster für diesen Filter zu verwenden.">
+<!ENTITY match.warning "Das Muster, das Sie eingegeben haben, passt nicht mehr zu der Adresse, für die der Filter erstellt werden soll. Es wird keinen Einfluss mehr auf diese Adresse haben.">
+<!ENTITY custom.pattern.label "Benutzerdefiniert:">
+<!ENTITY custom.pattern.accesskey "n">
+<!ENTITY anchors.label "Muster nur akzeptieren:">
+<!ENTITY anchor.start.label "am Anfang der Adresse">
+<!ENTITY anchor.start.accesskey "f">
+<!ENTITY anchor.start.flexible.label "am Anfang des Domain-Namens">
+<!ENTITY anchor.start.flexible.accesskey "f">
+<!ENTITY anchor.end.label "am Ende der Adresse">
+<!ENTITY anchor.end.accesskey "d">
+<!ENTITY options.label "Optionen">
+<!ENTITY domainRestriction.label "Auf Domain beschränken:">
+<!ENTITY domainRestriction.accesskey "m">
+<!ENTITY domainRestriction.help "Geben Sie eine oder mehrere Domains an (Trennzeichen ist "|"), der Filter wird dann nur auf diesen Domains angewandt. Das Zeichen "~" vor einem Domainnamen bedeutet, dass der Filter auf dieser Domain nicht angewandt werden sollte.">
+<!ENTITY firstParty.label "Nur für Elemente der Ursprungsseite">
+<!ENTITY firstParty.accesskey "p">
+<!ENTITY thirdParty.label "Nur für Elemente von Drittseiten">
+<!ENTITY thirdParty.accesskey "t">
+<!ENTITY matchCase.label "GroÃ-/Kleinschreibung beachten">
+<!ENTITY matchCase.accesskey "K">
+<!ENTITY types.label "Auf Elementtypen anwenden:">
+<!ENTITY selectAllTypes.label "Alle auswählen">
+<!ENTITY unselectAllTypes.label "Keine auswählen">
+
+<!ENTITY collapse.label "Platz freigeben:">
+<!ENTITY collapse.accesskey "g">
+<!ENTITY collapse.default.yes.label "Standardeinstellung (ja)">
+<!ENTITY collapse.default.no.label "Standardeinstellung (nein)">
+<!ENTITY collapse.yes.label "Ja">
+<!ENTITY collapse.no.label "Nein">
diff --git a/chrome/locale/de/global.properties b/chrome/adblockplus.jar!/locale/de/global.properties
similarity index 100%
rename from chrome/locale/de/global.properties
rename to chrome/adblockplus.jar!/locale/de/global.properties
diff --git a/chrome/locale/de/overlay.dtd b/chrome/adblockplus.jar!/locale/de/overlay.dtd
similarity index 100%
rename from chrome/locale/de/overlay.dtd
rename to chrome/adblockplus.jar!/locale/de/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/de/sendReport.dtd b/chrome/adblockplus.jar!/locale/de/sendReport.dtd
new file mode 100644
index 0000000..0bee085
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/de/sendReport.dtd
@@ -0,0 +1,183 @@
+<!ENTITY wizard.title "Fehler melden">
+<!ENTITY privacyPolicy.label "Datenschutzerklärung">
+
+<!ENTITY dataCollector.heading "Willkommen zum Fehlerberichts-Assistenten">
+<!ENTITY dataCollector.description "Bitte warten Sie einige Augenblicke, während Adblock Plus die benötigten Daten sammelt.">
+
+<!-- Please keep typeSelector.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY typeSelector.heading "Fehlerart wählen">
+
+<!ENTITY typeSelector.description "
+ Dieser Assistent wird Sie durch die nötigen Schritte zum Melden eines Adblock Plus-Fehlers
+ leiten. Zuerst wählen Sie bitte die Art des Fehlers, den Sie auf dieser Seite
+ beobachten:
+">
+
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus blockiert zu viel">
+<!ENTITY typeSelector.falsePositive.accesskey "v">
+<!ENTITY typeSelector.falsePositive.description "
+ Wählen Sie diese Option, falls auf der Seite wichtige Inhalte fehlen, die Seite
+ falsch angezeigt wird oder nicht korrekt funktioniert. Sie können feststellen,
+ ob Adblock Plus das Problem verursacht, indem Sie es vorübergehend deaktivieren.
+">
+
+<!ENTITY typeSelector.falseNegative.label "Eine Werbeeinblendung wird von Adblock Plus nicht blockiert">
+<!ENTITY typeSelector.falseNegative.accesskey "W">
+<!ENTITY typeSelector.falseNegative.description "
+ Wählen Sie diese Option, falls Werbung auf der Seite angezeigt wird, obwohl
+ Adblock Plus aktiviert ist.
+">
+
+<!ENTITY typeSelector.other.label "Anderer Fehler">
+<!ENTITY typeSelector.other.accesskey "d">
+<!ENTITY typeSelector.other.description "
+ Wählen Sie diese Option, falls Sie ein Problem mit Adblock Plus selber und nicht
+ mit dessen Filtern vermuten.
+">
+
+<!ENTITY showRecentReports.label "Zuletzt gesendeten Fehlerberichte anzeigen">
+<!ENTITY recentReports.label "Ihre zuletzt gesendeten Fehlerberichte">
+<!ENTITY recentReports.clear.label "Alle Berichte löschen">
+<!ENTITY recentReports.clear.accesskey "r">
+
+<!ENTITY issues.description "
+ Adblock Plus hat Probleme in Ihren Einstellungen gefunden, die für das vorliegende
+ Problem verantwortlich sein könnten oder eine Untersuchung des Problems behindern
+ würden.
+">
+
+<!ENTITY issues.whitelist.description "
+ Adblock Plus ist derzeit deaktiviert auf der Seite, für die Ihr Bericht gesendet werden
+ soll. Bitte aktivieren Sie Adblock Plus wieder und laden Sie die Seite neu, bevor Sie
+ den Fehler melden. Das wird die Untersuchung des Problems vereinfachen.
+">
+<!ENTITY issues.whitelist.remove.label "Adblock Plus auf dieser Seite wieder aktivieren">
+
+<!ENTITY issues.disabled.description "
+ Adblock Plus ist deaktiviert, in diesem Zustand wird es nichts blockieren.
+">
+<!ENTITY issues.disabled.enable.label "Adblock Plus aktivieren">
+
+<!ENTITY issues.nofilters.description "
+ Adblock Plus blockiert auf dieser Seite nichts. Das Problem, das Sie sehen, wurde
+ wahrscheinlich nicht von Adblock Plus verursacht.
+">
+
+<!ENTITY issues.nosubscriptions.description "
+ Es scheint, dass sie keine der fertigen Filterlisten abonniert haben. Ein solches
+ kostenloses Abonnement ist jedoch erforderlich, um automatisch Werbung zu entfernen.
+">
+<!ENTITY issues.nosubscriptions.add.label "Filterabonnement hinzufügen">
+
+<!ENTITY issues.subscriptionCount.description "
+ Es scheint, dass Sie zu viele Filterlisten abonniert haben. Das ist nicht
+ empfohlen, weil die Wahrscheinlichkeit von Problemen dadurch sehr stark
+ ansteigt. Wir können auÃerdem Ihren Fehlerbericht nicht annehmen, weil unklar
+ ist, welche Filterliste für das Problem verantwortlich ist. Bitte entfernen
+ Sie alle bis auf die wirklich notwendigen Filterabonnements und überprüfen
+ Sie dann, ob das Problem immer noch auftritt.
+">
+<!ENTITY issues.openPreferences.label "Filtereinstellungen öffnen">
+
+<!ENTITY issues.ownfilters.description "
+ Einige der Filter, die auf dieser Seite angewandt wurden, sind benutzerdefiniert.
+ Bitte deaktivieren Sie Filter, die das Problem verursacht haben könnten:
+">
+<!ENTITY issues.ownfilters.disable.label "Filter deaktivieren">
+
+<!ENTITY issues.disabledgroups.description "
+ Die folgenden Filterabonnements / Filtergruppen sind deaktiviert, hätten jedoch
+ einen Einfluss auf diese Webseite:
+">
+<!ENTITY issues.disabledgroups.enable.label "Filterabonnement / Filtergruppe aktivieren">
+
+<!ENTITY issues.disabledfilters.description "
+ Die folgenden Filter sind deaktiviert, hätten jedoch einen Einfluss auf diese Webseite:
+">
+<!ENTITY issues.disabledfilters.enable.label "Filter aktivieren">
+
+<!ENTITY issues.override.label "Die Einstellungen sind so korrekt, mit dem Fehlerbericht fortfahren">
+<!ENTITY issues.override.accesskey "k">
+<!ENTITY issues.change.description "
+ Ihre Einstellungen wurden geändert. Bitte laden Sie die Seite neu, um die Ãnderungen
+ jetzt zu testen. Bitte melden Sie den Fehler, falls das Problem durch die
+ Ãnderungen nicht gelöst wurde.
+">
+
+<!ENTITY typeWarning.description "
+ Sie haben angedeutet, dass Sie ein allgemeines Problem mit Adblock Plus melden wollen
+ und kein Filterproblem. Bitte beachten Sie, dass solche Probleme am besten im
+ [link]Adblock Plus Forum[/link] gemeldet werden sollten. Den Fehlerberichts-Assistenten
+ sollte man nur als Ergänzung zu einer vorhandenen Diskussion verwenden. Sie müssen
+ den Link zu Ihrem Fehlerbericht angeben, weil ihn sonst niemand sehen wird.
+ Diesen automatisch generierten Link bekommen Sie nach dem Senden des Berichts.
+">
+
+<!ENTITY typeWarning.override.label "Ich verstehe und will trotzdem einen Fehlerbericht einsenden">
+<!ENTITY typeWarning.override.accesskey "v">
+
+<!ENTITY reloadButton.label "Seite neu laden">
+<!ENTITY reloadButton.accesskey "n">
+
+<!-- Please keep screenshot.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY screenshot.heading "Screenshot hinzufügen">
+
+<!ENTITY screenshot.description "
+ Dieselbe Seite kann bei verschiedenen Leuten verschieden aussehen. Deswegen könnte es
+ hilfreich sein, wenn Sie zu Ihrem Bericht ein Bild der Webseite hinzufügen. Sie können
+ Teile der Seite entfernen, falls sie private Informationen enthalten. Ebenso können
+ Sie Stellen markieren, wo das Problem deutlich wird. Klicken Sie dafür die entsprechende
+ Taste und markieren Sie den Bereich auf dem Bild mit der Maus.
+">
+
+<!ENTITY screenshot.attach.label "Dieses Bild meinem Bericht hinzufügen">
+<!ENTITY screenshot.attach.accesskey "B">
+<!ENTITY screenshot.mark.label "Problem markieren">
+<!ENTITY screenshot.mark.accesskey "m">
+<!ENTITY screenshot.remove.label "Private Informationen löschen">
+<!ENTITY screenshot.remove.accesskey "P">
+<!ENTITY screenshot.undo.label "Rückgängig">
+<!ENTITY screenshot.undo.accesskey "R">
+
+<!-- Please keep commentPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY commentPage.heading "Kommentar eingeben">
+
+<!ENTITY commentPage.description "
+ Unten können Sie einen Kommentar eingeben, um uns zu helfen, das Problem zu verstehen.
+ Das ist zwar optional, ist jedoch empfohlen, falls das Problem nicht offensichtlich ist.
+ Sie können auch die Daten Ihres Berichts überprüfen, bevor sie gesendet werden.
+">
+
+<!ENTITY comment.label "Kommentar (optional):">
+<!ENTITY comment.accesskey "K">
+<!ENTITY comment.lengthWarning "Ihr Kommentar ist länger als 1000 Zeichen. Nur die ersten 1000 Zeichen werden gesendet.">
+<!ENTITY email.label "Email-Adresse für zusätzliche Nachfragen (optional):">
+<!ENTITY email.accesskey "m">
+
+<!ENTITY attachExtensions.label "Liste aktiver Erweiterungen anhängen für den Fall, dass das Problem von einer anderen Erweiterung verursacht wird">
+<!ENTITY attachExtensions.accesskey "w">
+
+<!ENTITY sendButton.label "Bericht absenden">
+<!ENTITY sendButton.accesskey "s">
+
+<!ENTITY showData.label "Berichtdaten anzeigen">
+<!ENTITY data.label "Berichtdaten:">
+<!ENTITY data.accesskey "d">
+
+<!-- Please keep sendPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY sendPage.heading "Bericht absenden">
+<!ENTITY sendPage.waitMessage "Bitte warten Sie, während Adblock Plus Ihren Bericht sendet.">
+<!ENTITY sendPage.confirmation "Ihr Bericht wurde gespeichert. Sie können Ihn unter der folgenden Adresse aufrufen:">
+<!ENTITY sendPage.knownIssue "Das Problem, das Sie berichtet haben, ist möglicherweise bereits bekannt. Zusätzliche Information:">
+
+<!-- Note: the placeholder ?1? will be replaced by the error code -->
+<!ENTITY sendPage.errorMessage "
+ Beim Senden des Berichts ist ein Fehler aufgetreten (Fehlercode "?1?").
+ Bitte stellen Sie sicher, dass Sie mit dem Internet verbunden sind, und versuchen
+ Sie, den Bericht noch einmal zu senden. Falls das Problem bestehen bleibt, wenden
+ Sie sich an das [link]Adblock Plus Forum[/link].
+">
+<!ENTITY sendPage.retry.label "Noch einmal senden">
+
+<!ENTITY copyLink.label "Link zum Bericht kopieren">
+<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/locale/de/settings.dtd b/chrome/adblockplus.jar!/locale/de/settings.dtd
similarity index 100%
rename from chrome/locale/de/settings.dtd
rename to chrome/adblockplus.jar!/locale/de/settings.dtd
diff --git a/chrome/locale/de/sidebar.dtd b/chrome/adblockplus.jar!/locale/de/sidebar.dtd
similarity index 100%
rename from chrome/locale/de/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/de/sidebar.dtd
diff --git a/chrome/adblockplus.jar!/locale/de/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/de/subscriptionSelection.dtd
new file mode 100644
index 0000000..979e629
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/de/subscriptionSelection.dtd
@@ -0,0 +1,38 @@
+<!ENTITY dialog.title "Filterabonnement für Adblock Plus hinzufügen">
+<!ENTITY dialog.title.edit "Filterabonnement bearbeiten">
+
+<!ENTITY description.newInstall "
+ Adblock Plus funktioniert am besten, wenn ein Filterabonnement hinzugefügt wird.
+ Filterabonnements werden von anderen Adblock Plus Nutzern kostenfrei zur
+ Verfügung gestellt. Das Filterabonnement, das zu Ihrer Sprache am besten passt,
+ ist bereits voreingestellt.
+">
+
+<!ENTITY subscriptionSelector.label "Bitte wählen Sie ein Filterabonnement aus der Liste aus:">
+
+<!ENTITY viewList.label "Filter ansehen">
+<!ENTITY visitHomepage.label "Webseite der Filterliste besuchen">
+
+<!ENTITY addSubscription.label "Filterabonnement hinzufügen">
+<!ENTITY saveSubscription.label "Ãnderungen speichern">
+
+<!ENTITY other.label "Anderes Abonnement hinzufügen">
+<!ENTITY other.accesskey "d">
+
+<!ENTITY list.download.failed "Adblock Plus konnte die Liste der Filterabonnements nicht herunterladen.">
+<!ENTITY list.download.retry "Nochmal versuchen">
+<!ENTITY list.download.website "Zur Webseite wechseln">
+<!ENTITY fromWeb.description "Bitte bestätigen Sie, dass Sie dieses Filterabonnement hinzufügen möchten. Die Bezeichnung und Adresse der Abonnements können vor dem Hinzufügen geändert werden.">
+<!ENTITY edit.description "Bitte ändern Sie die Bezeichnung und Adresse der Abonnements wie erforderlich.">
+<!ENTITY external.description "Das ist ein externes Filterabonnement, es wird von der Erweiterung aktualisiert, die es erstellt hat.">
+
+<!ENTITY title.label "Bezeichnung des Abonnements:">
+<!ENTITY title.accesskey "z">
+<!ENTITY location.label "Adresse der Filterliste:">
+<!ENTITY location.accesskey "r">
+<!ENTITY autodownload.label "Automatisch aktualisieren">
+<!ENTITY autodownload.accesskey "t">
+
+<!ENTITY supplementMessage "Dieses Filterabonnement sollte in Verbindung mit dem Filterabonnement "?1?" verwendet werden.">
+<!ENTITY addMain.label "Filterabonnement "?1?" auch hinzufügen">
+<!ENTITY addMain.accesskey "h">
diff --git a/chrome/locale/el/about.dtd b/chrome/adblockplus.jar!/locale/el/about.dtd
similarity index 100%
rename from chrome/locale/el/about.dtd
rename to chrome/adblockplus.jar!/locale/el/about.dtd
diff --git a/chrome/locale/el/composer.dtd b/chrome/adblockplus.jar!/locale/el/composer.dtd
similarity index 100%
rename from chrome/locale/el/composer.dtd
rename to chrome/adblockplus.jar!/locale/el/composer.dtd
diff --git a/chrome/locale/el/global.properties b/chrome/adblockplus.jar!/locale/el/global.properties
similarity index 100%
rename from chrome/locale/el/global.properties
rename to chrome/adblockplus.jar!/locale/el/global.properties
diff --git a/chrome/locale/el/overlay.dtd b/chrome/adblockplus.jar!/locale/el/overlay.dtd
similarity index 100%
rename from chrome/locale/el/overlay.dtd
rename to chrome/adblockplus.jar!/locale/el/overlay.dtd
diff --git a/chrome/locale/el/sendReport.dtd b/chrome/adblockplus.jar!/locale/el/sendReport.dtd
similarity index 100%
rename from chrome/locale/el/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/el/sendReport.dtd
diff --git a/chrome/locale/el/settings.dtd b/chrome/adblockplus.jar!/locale/el/settings.dtd
similarity index 100%
rename from chrome/locale/el/settings.dtd
rename to chrome/adblockplus.jar!/locale/el/settings.dtd
diff --git a/chrome/locale/el/sidebar.dtd b/chrome/adblockplus.jar!/locale/el/sidebar.dtd
similarity index 100%
rename from chrome/locale/el/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/el/sidebar.dtd
diff --git a/chrome/locale/el/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/el/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/el/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/el/subscriptionSelection.dtd
diff --git a/chrome/locale/en-GB/about.dtd b/chrome/adblockplus.jar!/locale/en-GB/about.dtd
similarity index 100%
rename from chrome/locale/en-GB/about.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/about.dtd
diff --git a/chrome/locale/en-GB/composer.dtd b/chrome/adblockplus.jar!/locale/en-GB/composer.dtd
similarity index 100%
rename from chrome/locale/en-GB/composer.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/composer.dtd
diff --git a/chrome/locale/en-GB/global.properties b/chrome/adblockplus.jar!/locale/en-GB/global.properties
similarity index 100%
rename from chrome/locale/en-GB/global.properties
rename to chrome/adblockplus.jar!/locale/en-GB/global.properties
diff --git a/chrome/locale/en-GB/overlay.dtd b/chrome/adblockplus.jar!/locale/en-GB/overlay.dtd
similarity index 100%
rename from chrome/locale/en-GB/overlay.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/overlay.dtd
diff --git a/chrome/locale/en-GB/sendReport.dtd b/chrome/adblockplus.jar!/locale/en-GB/sendReport.dtd
similarity index 100%
rename from chrome/locale/en-GB/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/sendReport.dtd
diff --git a/chrome/locale/en-GB/settings.dtd b/chrome/adblockplus.jar!/locale/en-GB/settings.dtd
similarity index 100%
rename from chrome/locale/en-GB/settings.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/settings.dtd
diff --git a/chrome/locale/en-GB/sidebar.dtd b/chrome/adblockplus.jar!/locale/en-GB/sidebar.dtd
similarity index 100%
rename from chrome/locale/en-GB/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/sidebar.dtd
diff --git a/chrome/locale/en-GB/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/en-GB/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/en-GB/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/en-GB/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/en-US/about.dtd b/chrome/adblockplus.jar!/locale/en-US/about.dtd
new file mode 100644
index 0000000..208768e
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/en-US/about.dtd
@@ -0,0 +1,14 @@
+<!ENTITY dialog.title "About Adblock Plus">
+
+<!ENTITY version.title "Version">
+<!ENTITY description "
+ Adblock Plus allows you to decide what you want to see on the web.
+ You don't need to download adverts and banners any more; if you
+ don't want them - remove them with Adblock Plus!
+">
+
+<!ENTITY homepage.label "Adblock Plus homepage:">
+<!ENTITY author.label "Author:">
+<!ENTITY contributors.label "Contributors:">
+<!ENTITY subscriptionAuthors.label "Filter subscription authors:">
+<!ENTITY translators.label "Translators:">
diff --git a/chrome/locale/en-US/composer.dtd b/chrome/adblockplus.jar!/locale/en-US/composer.dtd
similarity index 100%
rename from chrome/locale/en-US/composer.dtd
rename to chrome/adblockplus.jar!/locale/en-US/composer.dtd
diff --git a/chrome/locale/en-US/global.properties b/chrome/adblockplus.jar!/locale/en-US/global.properties
similarity index 100%
rename from chrome/locale/en-US/global.properties
rename to chrome/adblockplus.jar!/locale/en-US/global.properties
diff --git a/chrome/locale/en-US/overlay.dtd b/chrome/adblockplus.jar!/locale/en-US/overlay.dtd
similarity index 100%
rename from chrome/locale/en-US/overlay.dtd
rename to chrome/adblockplus.jar!/locale/en-US/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/en-US/sendReport.dtd b/chrome/adblockplus.jar!/locale/en-US/sendReport.dtd
new file mode 100644
index 0000000..d1a1809
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/en-US/sendReport.dtd
@@ -0,0 +1,180 @@
+<!ENTITY wizard.title "Issue reporter">
+<!ENTITY privacyPolicy.label "Privacy policy">
+
+<!ENTITY dataCollector.heading "Welcome to the issue reporter">
+<!ENTITY dataCollector.description "Please wait a few moments while Adblock Plus gathers the required data.">
+
+<!-- Please keep typeSelector.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY typeSelector.heading "Select issue type">
+
+<!ENTITY typeSelector.description "
+ This window will guide you through the steps required for the submission of an Adblock
+ Plus issue report. First, please select the type of issue that you are experiencing
+ on this page:
+">
+
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus is blocking too much">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "
+ Select this option if the page lacks important content, displays incorrectly or
+ fails to function properly. You can determine whether Adblock Plus is the cause
+ of the problem by disabling it temporarily.
+">
+
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus doesn't block an advertisement">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "
+ Select this option if an advertisement is displayed despite
+ Adblock Plus being enabled.
+">
+
+<!ENTITY typeSelector.other.label "Other issue">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY typeSelector.other.description "
+ Select this option if you suspect an issue with Adblock Plus itself rather
+ than its filters.
+">
+
+<!ENTITY showRecentReports.label "Show recently submitted reports">
+<!ENTITY recentReports.label "Your recently submitted reports">
+<!ENTITY recentReports.clear.label "Remove all reports">
+<!ENTITY recentReports.clear.accesskey "R">
+
+<!ENTITY issues.description "
+ Adblock Plus has detected issues with your configuration that might be responsible
+ for this issue or will make investigating the report difficult.
+">
+
+<!ENTITY issues.whitelist.description "
+ Adblock Plus is currently disabled on the page you are reporting. Please re-enable
+ it and reload the page before submitting the report to assist the investigation of
+ this issue.
+">
+<!ENTITY issues.whitelist.remove.label "Re-enable Adblock Plus on this page">
+
+<!ENTITY issues.disabled.description "
+ Adblock Plus is disabled, it will not block anything in its current state.
+">
+<!ENTITY issues.disabled.enable.label "Enable Adblock Plus">
+
+<!ENTITY issues.nofilters.description "
+ Adblock Plus isn't blocking anything on the current page. The issue you are
+ observing is most likely unrelated to Adblock Plus.
+">
+
+<!ENTITY issues.nosubscriptions.description "
+ You do not appear to be subscribed to any of the pre-made filter lists that
+ automatically remove unwanted content from websites.
+">
+<!ENTITY issues.nosubscriptions.add.label "Add filter subscription">
+
+<!ENTITY issues.subscriptionCount.description "
+ It seems that you are subscribed to too many filter subscriptions. This
+ setup is not recommended because it will make the likeliness
+ of issues much higher. We also cannot accept your issue report because it
+ is unclear which filter subscription author needs to take action. Please
+ remove all but the really necessary filter subscriptions and test whether
+ the issue still occurs then.
+">
+<!ENTITY issues.openPreferences.label "Open filter preferences">
+
+<!ENTITY issues.ownfilters.description "
+ Some of the filters applied on this page are user-defined. Please disable
+ the filters that might have caused the issue:
+">
+<!ENTITY issues.ownfilters.disable.label "Disable filter">
+
+<!ENTITY issues.disabledgroups.description "
+ The following filter subscriptions / filter groups are disabled, yet they might have
+ an effect on this page:
+">
+<!ENTITY issues.disabledgroups.enable.label "Enable filter subscription / filter group">
+
+<!ENTITY issues.disabledfilters.description "
+ The following filters are disabled, yet they might have an effect on this page:
+">
+<!ENTITY issues.disabledfilters.enable.label "Enable filter">
+
+<!ENTITY issues.override.label "The configuration is correct, continue with the report">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY issues.change.description "
+ Your configuration has been changed. Please reload the page to test the changes
+ and submit a report if the issue hasn't been resolved by the alterations.
+">
+
+<!ENTITY typeWarning.description "
+ You have indicated that you want to report a general issue with Adblock Plus rather
+ than a problem with the filters. Please note that such issues are best reported
+ in the [link]Adblock Plus forum[/link]. You should only use the issue reporter to
+ supplement an existing discussion, as nobody will notice your report
+ unless you provide them with the link to it. The automatically generated link
+ will be provided after submitting the report.
+">
+
+<!ENTITY typeWarning.override.label "I understand and want to submit the report anyway">
+<!ENTITY typeWarning.override.accesskey "s">
+
+<!ENTITY reloadButton.label "Reload page">
+<!ENTITY reloadButton.accesskey "R">
+
+<!-- Please keep screenshot.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY screenshot.heading "Attach screenshot">
+
+<!ENTITY screenshot.description "
+ The same page can look different for different people. It may help us to
+ understand the problem if you attach a screenshot to your report. You can remove
+ sections containing sensitive information as well as mark areas where the
+ problem is noticeable. To do that click the corresponding button and select
+ a section of the image with your mouse.
+">
+
+<!ENTITY screenshot.attach.label "Attach a page image to the report">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY screenshot.mark.label "Mark the problem">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "Remove sensitive data">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY screenshot.undo.label "Undo">
+<!ENTITY screenshot.undo.accesskey "U">
+
+<!-- Please keep commentPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY commentPage.heading "Enter comment">
+
+<!ENTITY commentPage.description "
+ The text field below allows you to enter a comment to help us understand the issue.
+ This step is optional but recommended if the problem isn't obvious.
+ You can also review the report data before it is sent.
+">
+
+<!ENTITY comment.label "Comment (optional):">
+<!ENTITY comment.accesskey "C">
+<!ENTITY comment.lengthWarning "The length of your comment exceeds 1000 characters. Only the first 1000 characters will be sent.">
+<!ENTITY email.label "Email for further inquiries (optional):">
+<!ENTITY email.accesskey "m">
+
+<!ENTITY attachExtensions.label "Attach a list of active extensions to the report in case add-on conflict is the cause of the problem">
+<!ENTITY attachExtensions.accesskey "x">
+
+<!ENTITY sendButton.label "Send report">
+<!ENTITY sendButton.accesskey "n">
+
+<!ENTITY showData.label "Show report data">
+<!ENTITY data.label "Report data:">
+<!ENTITY data.accesskey "p">
+
+<!-- Please keep sendPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY sendPage.heading "Send report">
+<!ENTITY sendPage.waitMessage "Please wait while Adblock Plus is submitting your report.">
+<!ENTITY sendPage.confirmation "Your report has been saved. You can access it at the following address:">
+<!ENTITY sendPage.knownIssue "The issue you reported is probably already known. More information:">
+
+<!-- Note: the placeholder ?1? will be replaced by the error code -->
+<!ENTITY sendPage.errorMessage "
+ An attempt to send the report failed with error code "?1?". Please ensure you are
+ connected to the Internet and retry. If the problem persists please request
+ assistance in the [link]Adblock Plus forum[/link].
+">
+<!ENTITY sendPage.retry.label "Send again">
+
+<!ENTITY copyLink.label "Copy report link">
+<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/en-US/settings.dtd b/chrome/adblockplus.jar!/locale/en-US/settings.dtd
similarity index 100%
rename from chrome/locale/en-US/settings.dtd
rename to chrome/adblockplus.jar!/locale/en-US/settings.dtd
diff --git a/chrome/locale/en-US/sidebar.dtd b/chrome/adblockplus.jar!/locale/en-US/sidebar.dtd
similarity index 100%
rename from chrome/locale/en-US/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/en-US/sidebar.dtd
diff --git a/chrome/adblockplus.jar!/locale/en-US/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/en-US/subscriptionSelection.dtd
new file mode 100644
index 0000000..83bfa6e
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/en-US/subscriptionSelection.dtd
@@ -0,0 +1,41 @@
+<!ENTITY dialog.title "Add Adblock Plus filter subscription">
+<!ENTITY dialog.title.edit "Edit filter subscription">
+
+<!ENTITY description.newInstall "
+ Adblock Plus will be most effective if you add a filter subscription.
+ Filter subscriptions are provided by other Adblock Plus users free of
+ charge. The most suitable subscription for your language is already
+ selected.
+">
+
+<!ENTITY subscriptionSelector.label "Please choose a filter subscription from the list:">
+
+<!ENTITY viewList.label "View filters">
+<!ENTITY visitHomepage.label "Visit home page">
+
+<!ENTITY addSubscription.label "Add subscription">
+<!ENTITY saveSubscription.label "Save subscription">
+
+<!ENTITY other.label "Add a different subscription">
+<!ENTITY other.accesskey "f">
+
+<!ENTITY list.download.failed "Adblock Plus failed to retrieve the list of subscriptions.">
+<!ENTITY list.download.retry "Try again">
+<!ENTITY list.download.website "View website">
+
+<!ENTITY fromWeb.description "Please confirm that you want to add this filter subscription. You can change the subscription title or location before adding it.">
+<!ENTITY edit.description "You can change the subscription title or location as necessary.">
+<!ENTITY external.description "This is an external filter subscription; it will be updated by the extension that created this subscription.">
+
+<!ENTITY title.label "Subscription title:">
+<!ENTITY title.accesskey "t">
+<!ENTITY location.label "Filter list location:">
+<!ENTITY location.accesskey "l">
+<!ENTITY autodownload.label "Update filters automatically">
+<!ENTITY autodownload.accesskey "p">
+
+<!-- Note: the placeholder (?1?) will be replaced by the name of the filter subscription required -->
+<!ENTITY supplementMessage "This filter subscription is meant to be used with the filter subscription "?1?" which you are not using yet.">
+<!-- Note: the placeholder (?1?) will be replaced by the name of the filter subscription required -->
+<!ENTITY addMain.label "Add filter subscription "?1?" as well">
+<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/eo/about.dtd b/chrome/adblockplus.jar!/locale/eo/about.dtd
similarity index 100%
rename from chrome/locale/eo/about.dtd
rename to chrome/adblockplus.jar!/locale/eo/about.dtd
diff --git a/chrome/locale/eo/composer.dtd b/chrome/adblockplus.jar!/locale/eo/composer.dtd
similarity index 100%
rename from chrome/locale/eo/composer.dtd
rename to chrome/adblockplus.jar!/locale/eo/composer.dtd
diff --git a/chrome/locale/eo/global.properties b/chrome/adblockplus.jar!/locale/eo/global.properties
similarity index 100%
rename from chrome/locale/eo/global.properties
rename to chrome/adblockplus.jar!/locale/eo/global.properties
diff --git a/chrome/locale/eo/overlay.dtd b/chrome/adblockplus.jar!/locale/eo/overlay.dtd
similarity index 100%
rename from chrome/locale/eo/overlay.dtd
rename to chrome/adblockplus.jar!/locale/eo/overlay.dtd
diff --git a/chrome/locale/eo/sendReport.dtd b/chrome/adblockplus.jar!/locale/eo/sendReport.dtd
similarity index 100%
rename from chrome/locale/eo/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/eo/sendReport.dtd
diff --git a/chrome/locale/eo/settings.dtd b/chrome/adblockplus.jar!/locale/eo/settings.dtd
similarity index 100%
rename from chrome/locale/eo/settings.dtd
rename to chrome/adblockplus.jar!/locale/eo/settings.dtd
diff --git a/chrome/locale/eo/sidebar.dtd b/chrome/adblockplus.jar!/locale/eo/sidebar.dtd
similarity index 100%
rename from chrome/locale/eo/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/eo/sidebar.dtd
diff --git a/chrome/locale/eo/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/eo/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/eo/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/eo/subscriptionSelection.dtd
diff --git a/chrome/locale/es-AR/about.dtd b/chrome/adblockplus.jar!/locale/es-AR/about.dtd
similarity index 100%
rename from chrome/locale/es-AR/about.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/about.dtd
diff --git a/chrome/locale/es-AR/composer.dtd b/chrome/adblockplus.jar!/locale/es-AR/composer.dtd
similarity index 100%
rename from chrome/locale/es-AR/composer.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/composer.dtd
diff --git a/chrome/locale/es-AR/global.properties b/chrome/adblockplus.jar!/locale/es-AR/global.properties
similarity index 100%
rename from chrome/locale/es-AR/global.properties
rename to chrome/adblockplus.jar!/locale/es-AR/global.properties
diff --git a/chrome/locale/es-AR/overlay.dtd b/chrome/adblockplus.jar!/locale/es-AR/overlay.dtd
similarity index 100%
rename from chrome/locale/es-AR/overlay.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/overlay.dtd
diff --git a/chrome/locale/es-AR/sendReport.dtd b/chrome/adblockplus.jar!/locale/es-AR/sendReport.dtd
similarity index 100%
rename from chrome/locale/es-AR/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/sendReport.dtd
diff --git a/chrome/locale/es-AR/settings.dtd b/chrome/adblockplus.jar!/locale/es-AR/settings.dtd
similarity index 100%
rename from chrome/locale/es-AR/settings.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/settings.dtd
diff --git a/chrome/locale/es-AR/sidebar.dtd b/chrome/adblockplus.jar!/locale/es-AR/sidebar.dtd
similarity index 100%
rename from chrome/locale/es-AR/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/sidebar.dtd
diff --git a/chrome/locale/es-AR/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/es-AR/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/es-AR/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/es-AR/subscriptionSelection.dtd
diff --git a/chrome/locale/es-ES/about.dtd b/chrome/adblockplus.jar!/locale/es-ES/about.dtd
similarity index 100%
rename from chrome/locale/es-ES/about.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/about.dtd
diff --git a/chrome/locale/es-ES/composer.dtd b/chrome/adblockplus.jar!/locale/es-ES/composer.dtd
similarity index 100%
rename from chrome/locale/es-ES/composer.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/composer.dtd
diff --git a/chrome/locale/es-ES/global.properties b/chrome/adblockplus.jar!/locale/es-ES/global.properties
similarity index 100%
rename from chrome/locale/es-ES/global.properties
rename to chrome/adblockplus.jar!/locale/es-ES/global.properties
diff --git a/chrome/locale/es-ES/overlay.dtd b/chrome/adblockplus.jar!/locale/es-ES/overlay.dtd
similarity index 100%
rename from chrome/locale/es-ES/overlay.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/overlay.dtd
diff --git a/chrome/locale/es-ES/sendReport.dtd b/chrome/adblockplus.jar!/locale/es-ES/sendReport.dtd
similarity index 100%
rename from chrome/locale/es-ES/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/sendReport.dtd
diff --git a/chrome/locale/es-ES/settings.dtd b/chrome/adblockplus.jar!/locale/es-ES/settings.dtd
similarity index 100%
rename from chrome/locale/es-ES/settings.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/settings.dtd
diff --git a/chrome/locale/es-ES/sidebar.dtd b/chrome/adblockplus.jar!/locale/es-ES/sidebar.dtd
similarity index 100%
rename from chrome/locale/es-ES/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/sidebar.dtd
diff --git a/chrome/locale/es-ES/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/es-ES/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/es-ES/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/es-ES/subscriptionSelection.dtd
diff --git a/chrome/locale/es-MX/about.dtd b/chrome/adblockplus.jar!/locale/es-MX/about.dtd
similarity index 100%
rename from chrome/locale/es-MX/about.dtd
rename to chrome/adblockplus.jar!/locale/es-MX/about.dtd
diff --git a/chrome/locale/es-MX/composer.dtd b/chrome/adblockplus.jar!/locale/es-MX/composer.dtd
similarity index 100%
rename from chrome/locale/es-MX/composer.dtd
rename to chrome/adblockplus.jar!/locale/es-MX/composer.dtd
diff --git a/chrome/locale/es-MX/global.properties b/chrome/adblockplus.jar!/locale/es-MX/global.properties
similarity index 100%
rename from chrome/locale/es-MX/global.properties
rename to chrome/adblockplus.jar!/locale/es-MX/global.properties
diff --git a/chrome/adblockplus.jar!/locale/es-MX/overlay.dtd b/chrome/adblockplus.jar!/locale/es-MX/overlay.dtd
new file mode 100644
index 0000000..cdc8d08
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/es-MX/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "Estado:">
+<!ENTITY blocked.tooltip "Elementos bloqueados en esta pagina:">
+<!ENTITY filters.tooltip "Filtros mas activos:">
+<!ENTITY menuitem.label "Preferencias de Adblock Plus">
+<!ENTITY menuitem.accesskey "e">
+<!ENTITY toolbarbutton.label "Adblock plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: Elementos bloqueables">
+<!ENTITY context.image.label "Adblock Plus: Bloquear imagen">
+<!ENTITY context.object.label "Adblock Plus: Bloquear objeto">
+<!ENTITY context.frame.label "Adblock Plus: Bloquear marco">
+<!ENTITY context.media.label "Adblock Plus: Bloquear sonido/video">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: Re-habilitar en esta pagina">
+<!ENTITY sidebar.title "Elementos bloqueables en la pagina actual">
+<!ENTITY sendReport.label "Reportar problema en esta pagina">
+<!ENTITY sendReport.accesskey "a">
+<!ENTITY settings.label "Preferencias">
+<!ENTITY settings.accesskey "P">
+<!ENTITY opensidebar.label "Abrir elementos bloqueables">
+<!ENTITY opensidebar.accesskey "r">
+<!ENTITY closesidebar.label "Cerrar elementos bloqueables">
+<!ENTITY closesidebar.accesskey "r">
+<!ENTITY whitelist.site.label "Deshabilitar en ?1?">
+<!ENTITY whitelist.page.label "Deshabilitar solo en esta pagina">
+<!ENTITY objecttab.title "Bloquear">
+<!ENTITY objecttab.tooltip "Clicke aquà para bloquear este objecto con Adblock Plus">
+<!ENTITY disable.label "Disable everywhere">
+<!ENTITY recommend.label "Recommend us on Facebook">
diff --git a/chrome/adblockplus.jar!/locale/es-MX/sendReport.dtd b/chrome/adblockplus.jar!/locale/es-MX/sendReport.dtd
new file mode 100644
index 0000000..f6809f5
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/es-MX/sendReport.dtd
@@ -0,0 +1,82 @@
+<!ENTITY wizard.title "Reportero de problemas">
+<!ENTITY privacyPolicy.label "PolÃtica de Privacidad">
+<!ENTITY dataCollector.heading "Bienvenido al reportero de problemas">
+<!ENTITY dataCollector.description "Por favor espere un momento mientras Adblock Plus reúne los datos necesarios.">
+<!ENTITY typeSelector.heading "Elija tipo de error">
+<!ENTITY typeSelector.description "Esta ventana lo guiara con pasos, necesarios para el envio de un reporte de problemas de Adblock Plus. Primero, por favor seleccione el tipo de problema que esta experimentando en esta pagina:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus esta bloqueando demasiado">
+<!ENTITY typeSelector.falsePositive.accesskey "A">
+<!ENTITY typeSelector.falsePositive.description "Seleccione esta opción si la pagina carece de contenido importante, muestra incorrectamente o falla al funcionar como debe. Puede determinar si Adblock Plus es el causante del problema deshabilitandolo temporalmente.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus no bloquea una publicidad">
+<!ENTITY typeSelector.falseNegative.accesskey "b">
+<!ENTITY typeSelector.falseNegative.description "Seleccione esta opción si una publicidad continua mostrandose a pesar que Adblock Plus se encuentra habilitado.">
+<!ENTITY typeSelector.other.label "Otro problema">
+<!ENTITY typeSelector.other.accesskey "O">
+<!ENTITY typeSelector.other.description "Seleccione esta opción si usted sospecha un problema con Adblock Plus especificamente en lugar de sus filtros.">
+<!ENTITY showRecentReports.label "Mostrar reportes enviados recientemente">
+<!ENTITY recentReports.label "Tus reportes recientemente enviados">
+<!ENTITY recentReports.clear.label "Quitar todos los reportes">
+<!ENTITY recentReports.clear.accesskey "Q">
+<!ENTITY issues.description "Adblock Plus ha detectado problemas con su configuración que puede ser la causa de este problema o que podria dificultar la investigación del problema.">
+<!ENTITY issues.whitelist.description "Adblock Plus se encuentra deshabilitado en la pagina que esta reportando. Por favor vuelva a habilitarlo y recargue la pagina antes de presentar el el informe para ayudar a la investigación de este tema.">
+<!ENTITY issues.whitelist.remove.label "Re-habilitar Adblock Plus en esta pagina">
+<!ENTITY issues.disabled.description "Adblock Plus esta deshabilitado, no bloqueara nada en su estado actual.">
+<!ENTITY issues.disabled.enable.label "Habilitar Adblock Plus">
+<!ENTITY issues.nofilters.description "Adblock Plus no esta bloqueando nada en la pagina actual. El problema que esta observando es probable que no se encuentre relacionado a Adblock Plus.">
+<!ENTITY issues.nosubscriptions.description "Usted no parece estar suscrito a ninguna lista de filtro pre-desarrollado que automáticamente remueve contenido no deseado de los sitios web.">
+<!ENTITY issues.nosubscriptions.add.label "Agregar filtro de suscripción">
+<!ENTITY issues.ownfilters.description "Alguno de los filtros aplicados en esta pagina se encuentran definidos por el usuarios. Por favor deshabilite los filtros que pueden causar el problema.">
+<!ENTITY issues.ownfilters.disable.label "Deshablitar filtro">
+<!ENTITY issues.disabledgroups.description "La siguiente subscripcion/Grupo de filtros se encuentra deshabilitada, aun asi pueden tener efectos en esta pagina:">
+<!ENTITY issues.disabledgroups.enable.label "Habilitar subscripcion/Grupo de filtros">
+<!ENTITY issues.disabledfilters.description "Los siguientes filtros estan deshabilitados, aun asi pueden tener efectos en esta pagina:">
+<!ENTITY issues.disabledfilters.enable.label "Habilitar filtro">
+<!ENTITY issues.override.label "La configuración es correcta, continue con el reporte">
+<!ENTITY issues.override.accesskey "L">
+<!ENTITY issues.change.description "Su configuración ha sido cambiada. Por favor recargue la pagina para probar los cambios y presentar un reporte si el problema no ha sido resuelto por las alteraciones.">
+<!ENTITY typeWarning.description "Ha indicado que desea reportar un problema general con Adblock Plus en lugar de un problema con los filtros. Por favor tenga en cuenta que estos problemas son mejor reportados en el [link]Foro de Adblock Plus[/link]. Solo deberia usar el reportero de problemas para complementar una discución existente, ya que nadie se percatara de su informe a menos que se les proporcione el enlace a la misma. El enlace generado automáticamente sera proporcionado despues de presentar el reporte respectivo.">
+<!ENTITY typeWarning.override.label "Entiendo y deseo presentar el reporte de todos modos">
+<!ENTITY typeWarning.override.accesskey "E">
+<!ENTITY reloadButton.label "Recargar pagina">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "Adjuntar captura de pantalla">
+<!ENTITY screenshot.description "La misma pagina puede parecer diferente para cada persona. Puede ayudarnos a entender el problema si adjunta una captura de pantalla a su reporte. Puede quitar partes que contengan informacion sensitiva/privada asi mismo marcar areas donde el problema se note. Para hacerlo clicke el botón correspondiente y seleccione una parte de la imagen con su cursor/puntero.">
+<!ENTITY screenshot.attach.label "Adjuntar una imagen de la pagina al reporte">
+<!ENTITY screenshot.attach.accesskey "i">
+<!ENTITY screenshot.mark.label "Marcar el problema">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "Quitar datos sensitivos/privados">
+<!ENTITY screenshot.remove.accesskey "u">
+<!ENTITY screenshot.undo.label "Deshacer">
+<!ENTITY screenshot.undo.accesskey "D">
+<!ENTITY commentPage.heading "Comentar">
+<!ENTITY commentPage.description "El campo de texto a continuación le permite escribir un comentario para ayudarnos a entender el problema. Este paso es opcional pero recomendado si el problema no es obvio. Puede tambien revisar el reporte de datos antes de que sea enviado.">
+<!ENTITY comment.label "Comentario (opcional):">
+<!ENTITY comment.accesskey "n">
+<!ENTITY comment.lengthWarning "El tamaño de su comentario excede los 1000 caracteres. Solo los primeros 1000 caracteres seran enviados.">
+<!ENTITY email.label "Correo Electrónico para futuras investigaciones (opcional):">
+<!ENTITY email.accesskey "r">
+<!ENTITY attachExtensions.label "Adjuntar una lista de extensiones activas a el repote en caso de que un conflicto de complementos sea la causa del problema">
+<!ENTITY attachExtensions.accesskey "d">
+<!ENTITY sendButton.label "Enviar reporte">
+<!ENTITY sendButton.accesskey "v">
+<!ENTITY showData.label "Mostrar datos del reporte">
+<!ENTITY data.label "Datos de Reporte">
+<!ENTITY data.accesskey "t">
+<!ENTITY sendPage.heading "Enviar reporte">
+<!ENTITY sendPage.waitMessage "Por favor espere mientras Adblock Plus envÃa su reporte.">
+<!ENTITY sendPage.confirmation "Su reporte ha sido salvado. Puede acceder al mismo en la siguiente direccion:">
+<!ENTITY sendPage.knownIssue "El problema que ha reportado probablemente ya sea conocido. Mas información:">
+<!ENTITY sendPage.errorMessage "Un intento de enviar el reporte ha fallado con el código de error "?1?". Por favor asegúrese de que se encuentra conectado a internet y vuelva a intentarlo. Si el problema persiste por favor solicite asistencia en el [link]Foro de Adblock Plus[/link].">
+<!ENTITY sendPage.retry.label "Enviar otra vez">
+<!ENTITY copyLink.label "Copiar dirección del reporte">
+<!ENTITY copyLink.accesskey "C">
+<!ENTITY issues.openPreferences.label "Open filter preferences">
+<!ENTITY issues.subscriptionCount.description "
+ It seems that you are subscribed to too many filter subscriptions. This
+ setup is not recommended because it will make the likeliness
+ of issues much higher. We also cannot accept your issue report because it
+ is unclear which filter subscription author needs to take action. Please
+ remove all but the really necessary filter subscriptions and test whether
+ the issue still occurs then.
+">
diff --git a/chrome/adblockplus.jar!/locale/es-MX/settings.dtd b/chrome/adblockplus.jar!/locale/es-MX/settings.dtd
new file mode 100644
index 0000000..ed2cbce
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/es-MX/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Preferencia de Adblock Plus">
+<!ENTITY filters.label "Filtros">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "Agregar filtro">
+<!ENTITY add.accesskey "g">
+<!ENTITY addsubscription.label "Agregar suscripción de filtro">
+<!ENTITY addsubscription.accesskey "l">
+<!ENTITY synchsubscriptions.label "Actualizar todas las suscripciones">
+<!ENTITY synchsubscriptions.accesskey "z">
+<!ENTITY import.label "Importar filtros">
+<!ENTITY import.accesskey "I">
+<!ENTITY export.label "Exportar filtros personalizados">
+<!ENTITY export.accesskey "x">
+<!ENTITY clearall.label "Quitar todos los filtros personalizados">
+<!ENTITY clearall.accesskey "Q">
+<!ENTITY resethitcounts.label "Restablecer contador de filtros">
+<!ENTITY resethitcounts.accesskey "R">
+<!ENTITY edit.label "Editar">
+<!ENTITY edit.accesskey "d">
+<!ENTITY cut.label "Cortar">
+<!ENTITY cut.accesskey "t">
+<!ENTITY copy.label "Copiar">
+<!ENTITY copy.accesskey "C">
+<!ENTITY paste.label "Pegar">
+<!ENTITY paste.accesskey "P">
+<!ENTITY remove.label "Eliminar">
+<!ENTITY remove.accesskey "E">
+<!ENTITY menu.find.label "Buscar">
+<!ENTITY menu.find.accesskey "B">
+<!ENTITY menu.findagain.label "Buscar de nuevo">
+<!ENTITY menu.findagain.accesskey "u">
+<!ENTITY view.label "Ver">
+<!ENTITY view.accesskey "V">
+<!ENTITY sort.label "Ordenar por">
+<!ENTITY sort.accesskey "p">
+<!ENTITY sort.none.label "Sin clasificar">
+<!ENTITY sort.none.accesskey "S">
+<!ENTITY sort.ascending.label "Ordernar de la A > Z">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Ordernar de la Z > A">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Opciones">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "Habilitar Adblock Plus">
+<!ENTITY enable.accesskey "k">
+<!ENTITY showintoolbar.label "Mostrar barra de herramientas">
+<!ENTITY showintoolbar.accesskey "h">
+<!ENTITY showinstatusbar.label "Mostrar en la barra de estado">
+<!ENTITY showinstatusbar.accesskey "M">
+<!ENTITY objecttabs.label "Mostrar pestañas sobre Flash y Java">
+<!ENTITY objecttabs.accesskey "ñ">
+<!ENTITY collapse.label "Colapsar elementos bloqueados">
+<!ENTITY collapse.accesskey "b">
+<!ENTITY help.label "Ayuda">
+<!ENTITY help.accesskey "y">
+<!ENTITY gettingStarted.label "Primeros pasos">
+<!ENTITY gettingStarted.accesskey "P">
+<!ENTITY faq.label "Preguntas y Respuestas frecuentes">
+<!ENTITY faq.accesskey "f">
+<!ENTITY filterdoc.label "Escribiendo filtros de Adblock Plus">
+<!ENTITY filterdoc.accesskey "n">
+<!ENTITY about.label "Acerca de Adblock Plus">
+<!ENTITY about.accesskey "k">
+<!ENTITY description "El siguiente filtro determina que dirección debe ser bloqueada y cuales deben ser permitidas:">
+<!ENTITY filter.column "Regla de filtro">
+<!ENTITY filter.accesskey "f">
+<!ENTITY slow.column "Filtros lentos">
+<!ENTITY slow.accesskey "e">
+<!ENTITY enabled.column "Habilitado">
+<!ENTITY enabled.accesskey "o">
+<!ENTITY hitcount.column "Contador">
+<!ENTITY hitcount.accesskey "C">
+<!ENTITY lasthit.column "Ultima visita">
+<!ENTITY lasthit.accesskey "U">
+<!ENTITY context.edit.label "Editar filtro">
+<!ENTITY context.resethitcount.label "Restablecer contador de visitas del filtro">
+<!ENTITY context.synchsubscription.label "Actualizar suscripción ahora">
+<!ENTITY context.editsubscription.label "Editar suscripción">
+<!ENTITY context.moveup.label "Mover filtro arriba">
+<!ENTITY context.movedown.label "Mover filtro abajo">
+<!ENTITY context.movegroupup.label "Mover grupo arriba">
+<!ENTITY context.movegroupdown.label "Mover grupo abajo">
+<!ENTITY context.enable.label "Habilitar">
+<!ENTITY context.disable.label "Deshabilitar">
+<!ENTITY apply.label "Aplicar">
+<!ENTITY apply.accesskey "l">
+<!ENTITY fennec.subscription.label "Subscripción de filtros">
+<!ENTITY sync.accesskey "c">
+<!ENTITY sync.label "Sync Adblock Plus settings">
diff --git a/chrome/locale/es-MX/sidebar.dtd b/chrome/adblockplus.jar!/locale/es-MX/sidebar.dtd
similarity index 100%
rename from chrome/locale/es-MX/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/es-MX/sidebar.dtd
diff --git a/chrome/locale/es-MX/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/es-MX/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/es-MX/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/es-MX/subscriptionSelection.dtd
diff --git a/chrome/locale/et/about.dtd b/chrome/adblockplus.jar!/locale/et/about.dtd
similarity index 100%
rename from chrome/locale/et/about.dtd
rename to chrome/adblockplus.jar!/locale/et/about.dtd
diff --git a/chrome/locale/et/composer.dtd b/chrome/adblockplus.jar!/locale/et/composer.dtd
similarity index 100%
rename from chrome/locale/et/composer.dtd
rename to chrome/adblockplus.jar!/locale/et/composer.dtd
diff --git a/chrome/locale/et/global.properties b/chrome/adblockplus.jar!/locale/et/global.properties
similarity index 100%
rename from chrome/locale/et/global.properties
rename to chrome/adblockplus.jar!/locale/et/global.properties
diff --git a/chrome/locale/et/overlay.dtd b/chrome/adblockplus.jar!/locale/et/overlay.dtd
similarity index 100%
rename from chrome/locale/et/overlay.dtd
rename to chrome/adblockplus.jar!/locale/et/overlay.dtd
diff --git a/chrome/locale/et/sendReport.dtd b/chrome/adblockplus.jar!/locale/et/sendReport.dtd
similarity index 100%
rename from chrome/locale/et/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/et/sendReport.dtd
diff --git a/chrome/locale/et/settings.dtd b/chrome/adblockplus.jar!/locale/et/settings.dtd
similarity index 100%
rename from chrome/locale/et/settings.dtd
rename to chrome/adblockplus.jar!/locale/et/settings.dtd
diff --git a/chrome/locale/et/sidebar.dtd b/chrome/adblockplus.jar!/locale/et/sidebar.dtd
similarity index 100%
rename from chrome/locale/et/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/et/sidebar.dtd
diff --git a/chrome/locale/et/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/et/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/et/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/et/subscriptionSelection.dtd
diff --git a/chrome/locale/fa/about.dtd b/chrome/adblockplus.jar!/locale/fa/about.dtd
similarity index 100%
rename from chrome/locale/fa/about.dtd
rename to chrome/adblockplus.jar!/locale/fa/about.dtd
diff --git a/chrome/locale/fa/composer.dtd b/chrome/adblockplus.jar!/locale/fa/composer.dtd
similarity index 100%
rename from chrome/locale/fa/composer.dtd
rename to chrome/adblockplus.jar!/locale/fa/composer.dtd
diff --git a/chrome/locale/fa/global.properties b/chrome/adblockplus.jar!/locale/fa/global.properties
similarity index 100%
rename from chrome/locale/fa/global.properties
rename to chrome/adblockplus.jar!/locale/fa/global.properties
diff --git a/chrome/locale/fa/overlay.dtd b/chrome/adblockplus.jar!/locale/fa/overlay.dtd
similarity index 100%
rename from chrome/locale/fa/overlay.dtd
rename to chrome/adblockplus.jar!/locale/fa/overlay.dtd
diff --git a/chrome/locale/fa/sendReport.dtd b/chrome/adblockplus.jar!/locale/fa/sendReport.dtd
similarity index 100%
rename from chrome/locale/fa/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/fa/sendReport.dtd
diff --git a/chrome/locale/fa/settings.dtd b/chrome/adblockplus.jar!/locale/fa/settings.dtd
similarity index 100%
rename from chrome/locale/fa/settings.dtd
rename to chrome/adblockplus.jar!/locale/fa/settings.dtd
diff --git a/chrome/locale/fa/sidebar.dtd b/chrome/adblockplus.jar!/locale/fa/sidebar.dtd
similarity index 100%
rename from chrome/locale/fa/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/fa/sidebar.dtd
diff --git a/chrome/locale/fa/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/fa/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/fa/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/fa/subscriptionSelection.dtd
diff --git a/chrome/locale/fi/about.dtd b/chrome/adblockplus.jar!/locale/fi/about.dtd
similarity index 100%
rename from chrome/locale/fi/about.dtd
rename to chrome/adblockplus.jar!/locale/fi/about.dtd
diff --git a/chrome/locale/fi/composer.dtd b/chrome/adblockplus.jar!/locale/fi/composer.dtd
similarity index 100%
rename from chrome/locale/fi/composer.dtd
rename to chrome/adblockplus.jar!/locale/fi/composer.dtd
diff --git a/chrome/locale/fi/global.properties b/chrome/adblockplus.jar!/locale/fi/global.properties
similarity index 100%
rename from chrome/locale/fi/global.properties
rename to chrome/adblockplus.jar!/locale/fi/global.properties
diff --git a/chrome/locale/fi/overlay.dtd b/chrome/adblockplus.jar!/locale/fi/overlay.dtd
similarity index 100%
rename from chrome/locale/fi/overlay.dtd
rename to chrome/adblockplus.jar!/locale/fi/overlay.dtd
diff --git a/chrome/locale/fi/sendReport.dtd b/chrome/adblockplus.jar!/locale/fi/sendReport.dtd
similarity index 100%
rename from chrome/locale/fi/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/fi/sendReport.dtd
diff --git a/chrome/locale/fi/settings.dtd b/chrome/adblockplus.jar!/locale/fi/settings.dtd
similarity index 100%
rename from chrome/locale/fi/settings.dtd
rename to chrome/adblockplus.jar!/locale/fi/settings.dtd
diff --git a/chrome/locale/fi/sidebar.dtd b/chrome/adblockplus.jar!/locale/fi/sidebar.dtd
similarity index 100%
rename from chrome/locale/fi/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/fi/sidebar.dtd
diff --git a/chrome/locale/fi/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/fi/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/fi/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/fi/subscriptionSelection.dtd
diff --git a/chrome/locale/fr/about.dtd b/chrome/adblockplus.jar!/locale/fr/about.dtd
similarity index 100%
rename from chrome/locale/fr/about.dtd
rename to chrome/adblockplus.jar!/locale/fr/about.dtd
diff --git a/chrome/locale/fr/composer.dtd b/chrome/adblockplus.jar!/locale/fr/composer.dtd
similarity index 100%
rename from chrome/locale/fr/composer.dtd
rename to chrome/adblockplus.jar!/locale/fr/composer.dtd
diff --git a/chrome/locale/fr/global.properties b/chrome/adblockplus.jar!/locale/fr/global.properties
similarity index 100%
rename from chrome/locale/fr/global.properties
rename to chrome/adblockplus.jar!/locale/fr/global.properties
diff --git a/chrome/locale/fr/overlay.dtd b/chrome/adblockplus.jar!/locale/fr/overlay.dtd
similarity index 100%
rename from chrome/locale/fr/overlay.dtd
rename to chrome/adblockplus.jar!/locale/fr/overlay.dtd
diff --git a/chrome/locale/fr/sendReport.dtd b/chrome/adblockplus.jar!/locale/fr/sendReport.dtd
similarity index 100%
rename from chrome/locale/fr/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/fr/sendReport.dtd
diff --git a/chrome/locale/fr/settings.dtd b/chrome/adblockplus.jar!/locale/fr/settings.dtd
similarity index 100%
rename from chrome/locale/fr/settings.dtd
rename to chrome/adblockplus.jar!/locale/fr/settings.dtd
diff --git a/chrome/locale/fr/sidebar.dtd b/chrome/adblockplus.jar!/locale/fr/sidebar.dtd
similarity index 100%
rename from chrome/locale/fr/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/fr/sidebar.dtd
diff --git a/chrome/locale/fr/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/fr/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/fr/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/fr/subscriptionSelection.dtd
diff --git a/chrome/locale/fy-NL/about.dtd b/chrome/adblockplus.jar!/locale/fy-NL/about.dtd
similarity index 100%
rename from chrome/locale/fy-NL/about.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/about.dtd
diff --git a/chrome/locale/fy-NL/composer.dtd b/chrome/adblockplus.jar!/locale/fy-NL/composer.dtd
similarity index 100%
rename from chrome/locale/fy-NL/composer.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/composer.dtd
diff --git a/chrome/locale/fy-NL/global.properties b/chrome/adblockplus.jar!/locale/fy-NL/global.properties
similarity index 100%
rename from chrome/locale/fy-NL/global.properties
rename to chrome/adblockplus.jar!/locale/fy-NL/global.properties
diff --git a/chrome/locale/fy-NL/overlay.dtd b/chrome/adblockplus.jar!/locale/fy-NL/overlay.dtd
similarity index 100%
rename from chrome/locale/fy-NL/overlay.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/overlay.dtd
diff --git a/chrome/locale/fy-NL/sendReport.dtd b/chrome/adblockplus.jar!/locale/fy-NL/sendReport.dtd
similarity index 100%
rename from chrome/locale/fy-NL/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/sendReport.dtd
diff --git a/chrome/locale/fy-NL/settings.dtd b/chrome/adblockplus.jar!/locale/fy-NL/settings.dtd
similarity index 100%
rename from chrome/locale/fy-NL/settings.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/settings.dtd
diff --git a/chrome/locale/fy-NL/sidebar.dtd b/chrome/adblockplus.jar!/locale/fy-NL/sidebar.dtd
similarity index 100%
rename from chrome/locale/fy-NL/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/sidebar.dtd
diff --git a/chrome/locale/fy-NL/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/fy-NL/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/fy-NL/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/fy-NL/subscriptionSelection.dtd
diff --git a/chrome/locale/gl/about.dtd b/chrome/adblockplus.jar!/locale/gl/about.dtd
similarity index 100%
rename from chrome/locale/gl/about.dtd
rename to chrome/adblockplus.jar!/locale/gl/about.dtd
diff --git a/chrome/locale/gl/composer.dtd b/chrome/adblockplus.jar!/locale/gl/composer.dtd
similarity index 100%
rename from chrome/locale/gl/composer.dtd
rename to chrome/adblockplus.jar!/locale/gl/composer.dtd
diff --git a/chrome/locale/gl/global.properties b/chrome/adblockplus.jar!/locale/gl/global.properties
similarity index 100%
rename from chrome/locale/gl/global.properties
rename to chrome/adblockplus.jar!/locale/gl/global.properties
diff --git a/chrome/locale/gl/overlay.dtd b/chrome/adblockplus.jar!/locale/gl/overlay.dtd
similarity index 100%
rename from chrome/locale/gl/overlay.dtd
rename to chrome/adblockplus.jar!/locale/gl/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/gl/sendReport.dtd b/chrome/adblockplus.jar!/locale/gl/sendReport.dtd
new file mode 100644
index 0000000..c28ace9
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/gl/sendReport.dtd
@@ -0,0 +1,132 @@
+<!ENTITY wizard.title "Informador de problemas">
+<!ENTITY privacyPolicy.label "PolÃtica de privacidade">
+<!ENTITY dataCollector.heading "Benvinda ao Informador de problemas">
+<!ENTITY dataCollector.description "Agarde uns intres mentres Adblock Plus reúne os datos necesarios.">
+<!ENTITY typeSelector.heading "Seleccione o tipo de problema">
+<!ENTITY typeSelector.description "Esta xanela vai guiarlle a través dos pasos necesarios para a presentación dun informe de problema Adblock Plus. Primeiro, seleccione o tipo de problema que atopou nesta páxina:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus está bloqueado demais">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "Seleccione esta opción se a páxina non ten contido importante, se amosa incorrectamente ou non funciona correctamente. Pode determinar se Adblock Plus é a causa do problema desactivándoo temporalmente.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus non bloquea a publicidade">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "Escolla esta opción se aparece un anuncio, a pesar de estar activado Adblock Plus.">
+<!ENTITY typeSelector.other.label "Outro problema">
+<!ENTITY screenshot.undo.label "Undo">
+<!ENTITY issues.disabledgroups.description "
+ The following filter subscriptions / filter groups are disabled, yet they might have
+ an effect on this page:
+">
+<!ENTITY attachExtensions.accesskey "x">
+<!ENTITY showData.label "Show report data">
+<!ENTITY recentReports.clear.accesskey "R">
+<!ENTITY email.accesskey "m">
+<!ENTITY issues.change.description "
+ Your configuration has been changed. Please reload the page to test the changes
+ and submit a report if the issue hasn't been resolved by the alterations.
+">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY issues.openPreferences.label "Open filter preferences">
+<!ENTITY sendPage.confirmation "Your report has been saved. You can access it at the following address:">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY copyLink.label "Copy report link">
+<!ENTITY issues.nofilters.description "
+ Adblock Plus isn't blocking anything on the current page. The issue you are
+ observing is most likely unrelated to Adblock Plus.
+">
+<!ENTITY sendPage.knownIssue "The issue you reported is probably already known. More information:">
+<!ENTITY sendPage.retry.label "Send again">
+<!ENTITY typeSelector.other.description "
+ Select this option if you suspect an issue with Adblock Plus itself rather
+ than its filters.
+">
+<!ENTITY issues.disabledgroups.enable.label "Enable filter subscription / filter group">
+<!ENTITY typeWarning.override.label "I understand and want to submit the report anyway">
+<!ENTITY issues.disabled.enable.label "Enable Adblock Plus">
+<!ENTITY email.label "Email for further inquiries (optional):">
+<!ENTITY reloadButton.label "Reload page">
+<!ENTITY recentReports.clear.label "Remove all reports">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY screenshot.undo.accesskey "U">
+<!ENTITY data.accesskey "p">
+<!ENTITY data.label "Report data:">
+<!ENTITY sendPage.heading "Send report">
+<!ENTITY recentReports.label "Your recently submitted reports">
+<!ENTITY typeWarning.description "
+ You have indicated that you want to report a general issue with Adblock Plus rather
+ than a problem with the filters. Please note that such issues are best reported
+ in the [link]Adblock Plus forum[/link]. You should only use the issue reporter to
+ supplement an existing discussion, as nobody will notice your report
+ unless you provide them with the link to it. The automatically generated link
+ will be provided after submitting the report.
+">
+<!ENTITY issues.disabled.description "
+ Adblock Plus is disabled, it will not block anything in its current state.
+">
+<!ENTITY attachExtensions.label "Attach a list of active extensions to the report in case add-on conflict is the cause of the problem">
+<!ENTITY issues.nosubscriptions.add.label "Add filter subscription">
+<!ENTITY issues.disabledfilters.enable.label "Enable filter">
+<!ENTITY issues.override.label "The configuration is correct, continue with the report">
+<!ENTITY issues.nosubscriptions.description "
+ You do not appear to be subscribed to any of the pre-made filter lists that
+ automatically remove unwanted content from websites.
+">
+<!ENTITY issues.whitelist.remove.label "Re-enable Adblock Plus on this page">
+<!ENTITY sendButton.label "Send report">
+<!ENTITY comment.label "Comment (optional):">
+<!ENTITY sendPage.errorMessage "
+ An attempt to send the report failed with error code "?1?". Please ensure you are
+ connected to the Internet and retry. If the problem persists please request
+ assistance in the [link]Adblock Plus forum[/link].
+">
+<!ENTITY showRecentReports.label "Show recently submitted reports">
+<!ENTITY commentPage.heading "Enter comment">
+<!ENTITY issues.disabledfilters.description "
+ The following filters are disabled, yet they might have an effect on this page:
+">
+<!ENTITY screenshot.description "
+ The same page can look different for different people. It may help us to
+ understand the problem if you attach a screenshot to your report. You can remove
+ sections containing sensitive information as well as mark areas where the
+ problem is noticeable. To do that click the corresponding button and select
+ a section of the image with your mouse.
+">
+<!ENTITY screenshot.attach.label "Attach a page image to the report">
+<!ENTITY issues.whitelist.description "
+ Adblock Plus is currently disabled on the page you are reporting. Please re-enable
+ it and reload the page before submitting the report to assist the investigation of
+ this issue.
+">
+<!ENTITY sendButton.accesskey "n">
+<!ENTITY copyLink.accesskey "C">
+<!ENTITY issues.ownfilters.disable.label "Disable filter">
+<!ENTITY commentPage.description "
+ The text field below allows you to enter a comment to help us understand the issue.
+ This step is optional but recommended if the problem isn't obvious.
+ You can also review the report data before it is sent.
+">
+<!ENTITY comment.lengthWarning "The length of your comment exceeds 1000 characters. Only the first 1000 characters will be sent.">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY sendPage.waitMessage "Please wait while Adblock Plus is submitting your report.">
+<!ENTITY screenshot.remove.label "Remove sensitive data">
+<!ENTITY screenshot.heading "Attach screenshot">
+<!ENTITY comment.accesskey "C">
+<!ENTITY issues.ownfilters.description "
+ Some of the filters applied on this page are user-defined. Please disable
+ the filters that might have caused the issue:
+">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY issues.subscriptionCount.description "
+ It seems that you are subscribed to too many filter subscriptions. This
+ setup is not recommended because it will make the likeliness
+ of issues much higher. We also cannot accept your issue report because it
+ is unclear which filter subscription author needs to take action. Please
+ remove all but the really necessary filter subscriptions and test whether
+ the issue still occurs then.
+">
+<!ENTITY screenshot.mark.label "Mark the problem">
+<!ENTITY issues.description "
+ Adblock Plus has detected issues with your configuration that might be responsible
+ for this issue or will make investigating the report difficult.
+">
diff --git a/chrome/locale/gl/settings.dtd b/chrome/adblockplus.jar!/locale/gl/settings.dtd
similarity index 100%
rename from chrome/locale/gl/settings.dtd
rename to chrome/adblockplus.jar!/locale/gl/settings.dtd
diff --git a/chrome/adblockplus.jar!/locale/gl/sidebar.dtd b/chrome/adblockplus.jar!/locale/gl/sidebar.dtd
new file mode 100644
index 0000000..69983f2
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/gl/sidebar.dtd
@@ -0,0 +1,35 @@
+<!ENTITY detached.title "Adblock Plus: Temas bloqueables (separados)">
+<!ENTITY detach.label "Separar">
+<!ENTITY reattach.label "Unir de novo">
+<!ENTITY search.label "Procurar:">
+<!ENTITY search.accesskey "P">
+<!ENTITY type.label "Tipo">
+<!ENTITY address.label "Enderezo">
+<!ENTITY filter.label "Filtro">
+<!ENTITY state.label "Estado">
+<!ENTITY size.label "Tamaño">
+<!ENTITY docDomain.label "Documento fonte">
+<!ENTITY noitems.label "Non hai temas bloqueables">
+<!ENTITY whitelisted.label "Páxina da Lista Branca">
+<!ENTITY tooltip.address.label "Enderezo:">
+<!ENTITY tooltip.type.label "Tipo">
+<!ENTITY tooltip.type.blocked "(bloqueado)">
+<!ENTITY tooltip.type.whitelisted "(engadido á lista branca)">
+<!ENTITY tooltip.size.label "Tamaño:">
+<!ENTITY tooltip.docDomain.label "Documento fonte:">
+<!ENTITY tooltip.filter.label "Filtro en vigor:">
+<!ENTITY tooltip.filter.disabled "(Desactivado)">
+<!ENTITY tooltip.filterSource.label "Fonte do filtro:">
+<!ENTITY context.block.label "Bloquear este tema">
+<!ENTITY context.editfilter.label "Editar o filtro en vigor">
+<!ENTITY context.whitelist.label "Engadir excepción para o tema">
+<!ENTITY context.disablefilter.label "Desactivar filtro ?1?">
+<!ENTITY context.enablefilter.label "Activar filtro ?1?">
+<!ENTITY context.disablefilteronsite.label "Desactivar este filtro en ?1?">
+<!ENTITY context.open.label "Abrir nun novo separador">
+<!ENTITY context.flash.label "Bordos do tema Flash">
+<!ENTITY context.copy.label "Copiar o enderezo do tema">
+<!ENTITY context.copyFilter.label "Copiar o filtro">
+<!ENTITY context.selectAll.label "Seleccionar todo">
+<!ENTITY docDomain.thirdParty "(third party)">
+<!ENTITY docDomain.firstParty "(first party)">
diff --git a/chrome/locale/gl/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/gl/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/gl/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/gl/subscriptionSelection.dtd
diff --git a/chrome/locale/he/about.dtd b/chrome/adblockplus.jar!/locale/he/about.dtd
similarity index 100%
rename from chrome/locale/he/about.dtd
rename to chrome/adblockplus.jar!/locale/he/about.dtd
diff --git a/chrome/locale/he/composer.dtd b/chrome/adblockplus.jar!/locale/he/composer.dtd
similarity index 100%
rename from chrome/locale/he/composer.dtd
rename to chrome/adblockplus.jar!/locale/he/composer.dtd
diff --git a/chrome/locale/he/global.properties b/chrome/adblockplus.jar!/locale/he/global.properties
similarity index 100%
rename from chrome/locale/he/global.properties
rename to chrome/adblockplus.jar!/locale/he/global.properties
diff --git a/chrome/locale/he/overlay.dtd b/chrome/adblockplus.jar!/locale/he/overlay.dtd
similarity index 100%
rename from chrome/locale/he/overlay.dtd
rename to chrome/adblockplus.jar!/locale/he/overlay.dtd
diff --git a/chrome/locale/he/sendReport.dtd b/chrome/adblockplus.jar!/locale/he/sendReport.dtd
similarity index 100%
rename from chrome/locale/he/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/he/sendReport.dtd
diff --git a/chrome/locale/he/settings.dtd b/chrome/adblockplus.jar!/locale/he/settings.dtd
similarity index 100%
rename from chrome/locale/he/settings.dtd
rename to chrome/adblockplus.jar!/locale/he/settings.dtd
diff --git a/chrome/locale/he/sidebar.dtd b/chrome/adblockplus.jar!/locale/he/sidebar.dtd
similarity index 100%
rename from chrome/locale/he/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/he/sidebar.dtd
diff --git a/chrome/locale/he/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/he/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/he/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/he/subscriptionSelection.dtd
diff --git a/chrome/locale/hr/about.dtd b/chrome/adblockplus.jar!/locale/hr/about.dtd
similarity index 100%
rename from chrome/locale/hr/about.dtd
rename to chrome/adblockplus.jar!/locale/hr/about.dtd
diff --git a/chrome/adblockplus.jar!/locale/hr/composer.dtd b/chrome/adblockplus.jar!/locale/hr/composer.dtd
new file mode 100644
index 0000000..d7abbce
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/hr/composer.dtd
@@ -0,0 +1,47 @@
+<!ENTITY dialog.title "Dodaj Adblock Plus pravilo za filter">
+<!ENTITY accept.label "Dodaj filet">
+<!ENTITY advanced.label "Napredni pregled">
+<!ENTITY basic.label "osnovni pregled">
+<!ENTITY disabled.warning "Adblock Plus je trenutno onemoguÄen. Možete dodavati filtere ali se oni neÄe primjenjivati ako ne [link]omoguÄite Adblock Plus[/link].">
+<!ENTITY groupDisabled.warning "Grupa filtera "?1?" kojoj Äe ovaj filter biti dodan je trenutno onemoguÄena. Sveedno možete dodati filter ali on neÄe biti primjenjen ako ne [link]omoguÄite grupu filtera[/link].">
+<!ENTITY filter.label "Novi filter">
+<!ENTITY filter.accesskey "f">
+<!ENTITY preferences.label "Prikaži postojeÄe filtere">
+<!ENTITY preferences.accesskey "k">
+<!ENTITY type.filter.label "Blokirani filter">
+<!ENTITY type.filter.accesskey "B">
+<!ENTITY type.whitelist.label "Iznimka">
+<!ENTITY type.whitelist.accesskey "m">
+<!ENTITY pattern.label "Traži ponavljajuÄi uzorak">
+<!ENTITY pattern.explanation "uzorak može biti bilo koji dio adrese, asterisk (*) služi kao zamjena. Filter Äe biti primjenjen na adrese koje se poklapaju sa naznaÄenim uzorkom.">
+<!ENTITY regexp.warning "Uzorak koji ste unijeli biti Äe protumaÄen kao obiÄni izraz kojeg Adblock Plus ne može efikasno obraditi i može usporiti vaÅ¡e surfanje. Ako niste namjeravali koristiti obiÄni izra, dodajte asterisk (*) na kraju uzorka.">
+<!ENTITY shortpattern.warning "Uneseni uzorak je prekratak za optimizaciju i može usporiti vaÅ¡e surfanje. PreporuÄamo da odaberete duži niz za ovaj filter kako biste omoguÄili da Adblock Plus efikasnije obradi taj filter.">
+<!ENTITY custom.pattern.label "PrilagoÄeno:">
+<!ENTITY custom.pattern.accesskey "l">
+<!ENTITY anchors.label "Prihvati samo uzorak:">
+<!ENTITY anchor.start.label "na poÄetku adrese">
+<!ENTITY anchor.start.accesskey "p">
+<!ENTITY anchor.start.flexible.label "na poÄetku naziva domene">
+<!ENTITY anchor.start.flexible.accesskey "p">
+<!ENTITY anchor.end.label "na kraju adrese">
+<!ENTITY anchor.end.accesskey "n">
+<!ENTITY options.label "Postavke">
+<!ENTITY domainRestriction.label "OgraniÄiti na domenu:">
+<!ENTITY domainRestriction.accesskey "d">
+<!ENTITY domainRestriction.help "Koristite ovu opciju da odabir jedne ili viÅ¡e domena odvojenih okomitom linijom (|). Filter Äe biti primjenjen samo na odabrane domene. Tilda (~) prije naziva domene pokazuje da filter neÄe biti primjenjen na toj domeni.">
+<!ENTITY firstParty.label "Samo first-party">
+<!ENTITY firstParty.accesskey "r">
+<!ENTITY thirdParty.label "Samo third-party">
+<!ENTITY thirdParty.accesskey "T">
+<!ENTITY matchCase.label "ToÄan izraz">
+<!ENTITY matchCase.accesskey "z">
+<!ENTITY types.label "Primjeniti na tipove:">
+<!ENTITY selectAllTypes.label "Odabrati sve">
+<!ENTITY unselectAllTypes.label "Nijedan odabrati">
+<!ENTITY collapse.label "Sažeti blokirano:">
+<!ENTITY collapse.accesskey "S">
+<!ENTITY collapse.default.yes.label "Koristiti opÄenito (da)">
+<!ENTITY collapse.default.no.label "Koriatiti opÄenito (ne)">
+<!ENTITY collapse.yes.label "Da">
+<!ENTITY collapse.no.label "Ne">
+<!ENTITY match.warning "The pattern you entered no longer matches the address to be blocked/whitelisted and will have no effect on it.">
diff --git a/chrome/adblockplus.jar!/locale/hr/global.properties b/chrome/adblockplus.jar!/locale/hr/global.properties
new file mode 100644
index 0000000..32b6b91
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/hr/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=Kliknite da bi se otvorio kontekstni izbornik, srednji klik za omoguÄavanje/onemoguÄavanje.
+action1_tooltip=Kliknite da bi se otvorile/zatvorile stavke koje se mogu blokirati, srednji klik za omoguÄavanje/onemoguÄavanje.
+action2_tooltip=Kliknite da bi se otvorila svojstva, srednji klik za omoguÄavanje/onemoguÄavanje.
+action3_tooltip=Kliknite da bi omoguÄili/onemoguÄili Adblock Plus.
+disabled_tooltip=Adblock Plus je onemoguÄen.
+active_tooltip=Adblock Plus je aktivan, ?1? pretplata na filtere i ?2? vlastitih filtera u uporabi.
+whitelisted_tooltip=Adblock Plus je aktivan, ali onemoguÄen za trenutnu stranicu.
+blocked_count_tooltip=?1? od ?2?
+blocked_count_addendum=dopušteni: ?1?, skriveni: ?2?)
+no_blocking_suggestions=Na trenutnoj stranici nema stavki koje se mogu blokirati
+whitelisted_page=Adblock Plus je onemoguÄen za trenutnu stranicu
+whitelist_description=Pravila izuzimanja
+filterlist_description=Filteri oglašavanja
+invalid_description=NevažeÄi filteri
+elemhide_description=Temeljna pravila skrivanja
+subscription_description=Pretplata na filter:
+subscription_wrong_version=Neki filteri u ovoj pretplati zahtijevaju Adblock Plus ?1? da bi ispravno radili!
+subscription_source=Izvor:
+subscription_status=Status:
+subscription_status_autodownload=Automatsko ažuriranje
+subscription_status_manualdownload=RuÄno ažuriranje
+subscription_status_externaldownload=Vanjsko ažuriranje (drugo proširenje)
+subscription_status_lastdownload=Zadnje preuzimanje:
+subscription_status_lastdownload_inprogress=Preuzimanje...
+subscription_status_lastdownload_unknown=N/A
+remove_subscription_warning=Želite li zbilja ukloniti ovu pretplatu?
+import_filters_wrong_version=Upozorenje: neki od filtera u ovom popisu zahtjevaju Adblock Plus ?1? da bi ispravno radili. Vjerojatno biste trebali nadograditi na zadnju inaÄicu Adblock Plus prije uvoza ovog popisa.
+import_filters_warning=Želite li zamijeniti Vaše trenutne filtere ili nove filtere želite dodati na kraj popisa?
+import_filters_title=Uvezi filtere
+export_filters_title=Izvezi filtere
+invalid_filters_file=NevažeÄa Adblock Plus datoteka filtera.
+filters_write_error=GreÅ¡ka prilikom zapisivanja filtera u datoteku. Provjerite da datoteka nije zaÅ¡tiÄena protiv pisanja ili u upotrebi od strane nekog drugog programa.
+clearall_warning=Želite li stvarno ukloniti sve filtere s popisa?
+resethitcounts_warning=Želite li doista ponovno postaviti brojanje pogodaka za sve filtere natrag na nulu? Ova operacija ne može biti opozvana!
+resethitcounts_selected_warning=Želite li doista ponovno postaviti brojanje pogodaka za odabrani filter natrag na nulu? Ova operacija ne može biti opozvana!
+filter_regexp_tooltip=Ovaj filter je ili regularan izraz ili je prekatak za optimizacju. Previše ovakvih filtera vam može usporiti surfanje.
+filter_elemhide_duplicate_id=Samo jedan ID elementa za skrivanje može biti odabran.
+filter_elemhide_nocriteria=Nijedan kriterij za prepoznavanje elementa koji Äe biti skriven
+subscription_notAdded_warning=Niste dodali pretplatu za filter. Bez pretplate za filter morate dodavati filtere za Adblock Plus ruÄno.
+subscription_notAdded_warning_addendum=Želite li nastaviti?
+subscription_invalid_location=Mjesto popisa filtera nije niti valjana web adresa niti naziv datoteke.
+synchronize_invalid_url=Neuspjeh, neispravna adresa
+synchronize_connection_error=Neuspjeh, neuspjelo preuzimanje
+synchronize_invalid_data=Neuspjeh, neispravan popis filtera
+synchronize_checksum_mismatch=NeuspjeÅ¡no, neusklaÄenost checksum-a.
+synchronize_ok=Uspjeh
+overwrite=Prepiši
+append=Dodaj na kraj
+new_filter_group_title=Novi filter
+type_label_other=drugi
+type_label_script=skripta
+type_label_image=slika
+type_label_stylesheet=stylesheet
+type_label_object=objekt
+type_label_subdocument=okvir
+type_label_document=dokument
+type_label_elemhide=skriveno
+type_label_xbl=XBL vezanje
+type_label_ping=ping linka
+type_label_xmlhttprequest=XML zahtjev
+type_label_object_subrequest=podzahtjev objekta
+type_label_dtd=DTD
+type_label_media=audio/video
+type_label_font=font
+fennec_status_enabled=Adblock Plus je omoguÄen.
+fennec_status_disabled=Adblock Plus je onemoguÄen.
+fennec_status_enabled_site=Adblock Plus je omoguÄen na ?1?.
+fennec_status_disabled_site=Adblock Plus je onemoguÄen na ?1?.
+sync_engine_title=Adblock Plus data
diff --git a/chrome/adblockplus.jar!/locale/hr/overlay.dtd b/chrome/adblockplus.jar!/locale/hr/overlay.dtd
new file mode 100644
index 0000000..658a1bc
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/hr/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "Status:">
+<!ENTITY blocked.tooltip "Blokirane stavke na ovoj stranici:">
+<!ENTITY filters.tooltip "Najaktivniji filteri:">
+<!ENTITY menuitem.label "Adblock Plus">
+<!ENTITY menuitem.accesskey "b">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: Stavke koje se mogu blokirati">
+<!ENTITY context.image.label "Blokiraj sliku s Adblock">
+<!ENTITY context.object.label "Blokiraj objekt s Adblock">
+<!ENTITY context.frame.label "Blokiraj okvir s Adblock">
+<!ENTITY context.media.label "Adblock Plus: Blokirati audio/video">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: Ponovno omoguÄiti na ovoj stranici">
+<!ENTITY sidebar.title "Stavke koje se mogu blokirati na trenutnoj stranici">
+<!ENTITY settings.label "Postavke">
+<!ENTITY settings.accesskey "t">
+<!ENTITY opensidebar.label "Otvori stavke koje se mogu blokirati">
+<!ENTITY opensidebar.accesskey "b">
+<!ENTITY closesidebar.label "Zatvori stavke koje se mogu blokirati">
+<!ENTITY closesidebar.accesskey "b">
+<!ENTITY whitelist.site.label "OnemoguÄi na ?1?">
+<!ENTITY whitelist.page.label "OnemoguÄi samo na ovoj stranici">
+<!ENTITY objecttab.title "Blokiraj">
+<!ENTITY objecttab.tooltip "Kliknite ovdje da biste ovaj objekt blokirali s Adblock Plus">
+<!ENTITY disable.label "Disable everywhere">
+<!ENTITY recommend.label "Recommend us on Facebook">
+<!ENTITY sendReport.accesskey "R">
+<!ENTITY sendReport.label "Report issue on this page">
diff --git a/chrome/locale/en-US/sendReport.dtd b/chrome/adblockplus.jar!/locale/hr/sendReport.dtd
similarity index 100%
copy from chrome/locale/en-US/sendReport.dtd
copy to chrome/adblockplus.jar!/locale/hr/sendReport.dtd
diff --git a/chrome/adblockplus.jar!/locale/hr/settings.dtd b/chrome/adblockplus.jar!/locale/hr/settings.dtd
new file mode 100644
index 0000000..1188dc3
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/hr/settings.dtd
@@ -0,0 +1,90 @@
+<!ENTITY dialog.title "Adblock Plus Postavke">
+<!ENTITY filters.label "Filteri">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "Dodaj filter">
+<!ENTITY add.accesskey "j">
+<!ENTITY addsubscription.label "Dodaj pretplatu na filter">
+<!ENTITY addsubscription.accesskey "D">
+<!ENTITY synchsubscriptions.label "Ažuriraj sve pretplate">
+<!ENTITY synchsubscriptions.accesskey "ž">
+<!ENTITY import.label "Uvezi filtere">
+<!ENTITY import.accesskey "v">
+<!ENTITY export.label "Izvezi filtere">
+<!ENTITY export.accesskey "z">
+<!ENTITY clearall.label "Ukloni sve filtere">
+<!ENTITY clearall.accesskey "k">
+<!ENTITY resethitcounts.label "Vrati izvornu statistiku pogodaka">
+<!ENTITY resethitcounts.accesskey "r">
+<!ENTITY edit.label "Uredi">
+<!ENTITY edit.accesskey "r">
+<!ENTITY cut.label "Izreži">
+<!ENTITY cut.accesskey "z">
+<!ENTITY copy.label "Kopiraj">
+<!ENTITY copy.accesskey "o">
+<!ENTITY paste.label "Zalijepi">
+<!ENTITY paste.accesskey "l">
+<!ENTITY remove.label "Obriši">
+<!ENTITY remove.accesskey "b">
+<!ENTITY menu.find.label "Traži">
+<!ENTITY menu.find.accesskey "T">
+<!ENTITY menu.findagain.label "Ponovno traži">
+<!ENTITY menu.findagain.accesskey "n">
+<!ENTITY view.label "Pogledati">
+<!ENTITY view.accesskey "g">
+<!ENTITY sort.label "Posložiti po">
+<!ENTITY sort.accesskey "S">
+<!ENTITY sort.none.label "Neposloženo">
+<!ENTITY sort.none.accesskey "N">
+<!ENTITY sort.ascending.label "A > Z red slaganja">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Z > A red slaganja">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Opcije">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "OmoguÄi Adblock Plus">
+<!ENTITY enable.accesskey "m">
+<!ENTITY showintoolbar.label "Prikaži u alatnoj traci">
+<!ENTITY showintoolbar.accesskey "a">
+<!ENTITY showinstatusbar.label "Prikaži u statusnoj traci">
+<!ENTITY showinstatusbar.accesskey "s">
+<!ENTITY objecttabs.label "Prikaži kartice s Flashom i Javom">
+<!ENTITY objecttabs.accesskey "k">
+<!ENTITY collapse.label "Sažmi blokirane elemente">
+<!ENTITY collapse.accesskey "e">
+<!ENTITY help.label "PomoÄ">
+<!ENTITY help.accesskey "Ä">
+<!ENTITY gettingStarted.label "Kako poÄeti">
+<!ENTITY gettingStarted.accesskey "p">
+<!ENTITY faq.label "Äesto postavljana pitanja">
+<!ENTITY faq.accesskey "t">
+<!ENTITY filterdoc.label "Pisanje Adblock Plus filtera">
+<!ENTITY filterdoc.accesskey "i">
+<!ENTITY about.label "O Adblock Plus">
+<!ENTITY about.accesskey "O">
+<!ENTITY description "Dodajte adrese koje želite blokirati, za prijedloge provjerite padajuÄi popis.
+Možete koristiti * kao joker da bi kreirali joÅ¡ opÄenitije filtere. Napredni korisnici mogu koristiti regularne izraze kao /banner\d+\.gif$/.">
+<!ENTITY filter.column "Pravilo filtera">
+<!ENTITY filter.accesskey "F">
+<!ENTITY slow.column "Spori filteri">
+<!ENTITY slow.accesskey "w">
+<!ENTITY enabled.column "OmoguÄeno">
+<!ENTITY enabled.accesskey "m">
+<!ENTITY hitcount.column "Pogoci">
+<!ENTITY hitcount.accesskey "H">
+<!ENTITY lasthit.column "Posljednji pogodak">
+<!ENTITY lasthit.accesskey "L">
+<!ENTITY context.edit.label "Uredi filter">
+<!ENTITY context.resethitcount.label "Vrati izvornu statistiku pogodaka za filter">
+<!ENTITY context.synchsubscription.label "Ažuriraj pretplatu sada">
+<!ENTITY context.editsubscription.label "Uredi pretplatu">
+<!ENTITY context.moveup.label "Pomakni prema gore">
+<!ENTITY context.movedown.label "Pomakni prema dolje">
+<!ENTITY context.movegroupup.label "Pomakni grupu prema gore">
+<!ENTITY context.movegroupdown.label "Pomakni grupu prema dolje">
+<!ENTITY context.enable.label "OmoguÄiti">
+<!ENTITY context.disable.label "OnemoguÄiti">
+<!ENTITY apply.label "Primijeni">
+<!ENTITY apply.accesskey "P">
+<!ENTITY fennec.subscription.label "Pretplate na filtere">
+<!ENTITY sync.accesskey "c">
+<!ENTITY sync.label "Sync Adblock Plus settings">
diff --git a/chrome/adblockplus.jar!/locale/hr/sidebar.dtd b/chrome/adblockplus.jar!/locale/hr/sidebar.dtd
new file mode 100644
index 0000000..d034159
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/hr/sidebar.dtd
@@ -0,0 +1,35 @@
+<!ENTITY detached.title "Adblock Plus: Stavke koje se mogu blokirati (odvojene)">
+<!ENTITY detach.label "Odvoji">
+<!ENTITY reattach.label "Ponovno spoji">
+<!ENTITY search.label "Traži:">
+<!ENTITY search.accesskey "T">
+<!ENTITY type.label "Tip">
+<!ENTITY address.label "Adresa">
+<!ENTITY filter.label "Filter">
+<!ENTITY state.label "Status">
+<!ENTITY size.label "VeliÄina">
+<!ENTITY docDomain.label "Izvor dokumenta">
+<!ENTITY noitems.label "Nema stavki koje se mogu blokirati">
+<!ENTITY whitelisted.label "Stranica koja je na dopuštenom popisu">
+<!ENTITY tooltip.address.label "Adresa:">
+<!ENTITY tooltip.type.label "Tip:">
+<!ENTITY tooltip.type.blocked "(blokiran)">
+<!ENTITY tooltip.type.whitelisted "(na dozvoljenom popisu)">
+<!ENTITY tooltip.size.label "VeliÄina:">
+<!ENTITY tooltip.docDomain.label "Izvor dokumenta:">
+<!ENTITY tooltip.filter.label "Filter u upotrebi:">
+<!ENTITY tooltip.filterSource.label "Izvor filtera:">
+<!ENTITY context.block.label "Blokiraj ovu stavku">
+<!ENTITY context.editfilter.label "Uredi filter u upotrebi">
+<!ENTITY context.whitelist.label "Dodaj pravilo izuzimanja za stavku">
+<!ENTITY context.disablefilter.label "OnemoguÄiti filter ?1?">
+<!ENTITY context.enablefilter.label "Ponovno omoguÄiti filter ?1?">
+<!ENTITY context.disablefilteronsite.label "OnemoguÄiti ovaj filter na ?1?">
+<!ENTITY context.open.label "Otvori u novoj kartici">
+<!ENTITY context.flash.label "Osvijetli granice stavke">
+<!ENTITY context.copy.label "Kopiraj adresu stavke">
+<!ENTITY context.copyFilter.label "Kopirati filter">
+<!ENTITY context.selectAll.label "Odabrati sve">
+<!ENTITY docDomain.thirdParty "(third party)">
+<!ENTITY docDomain.firstParty "(first party)">
+<!ENTITY tooltip.filter.disabled "(disabled)">
diff --git a/chrome/locale/hr/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/hr/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/hr/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/hr/subscriptionSelection.dtd
diff --git a/chrome/locale/hsb-DE/about.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/about.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/about.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/about.dtd
diff --git a/chrome/locale/hsb-DE/composer.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/composer.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/composer.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/composer.dtd
diff --git a/chrome/locale/hsb-DE/global.properties b/chrome/adblockplus.jar!/locale/hsb-DE/global.properties
similarity index 100%
rename from chrome/locale/hsb-DE/global.properties
rename to chrome/adblockplus.jar!/locale/hsb-DE/global.properties
diff --git a/chrome/locale/hsb-DE/overlay.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/overlay.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/overlay.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/overlay.dtd
diff --git a/chrome/locale/hsb-DE/sendReport.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/sendReport.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/sendReport.dtd
diff --git a/chrome/locale/hsb-DE/settings.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/settings.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/settings.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/settings.dtd
diff --git a/chrome/locale/hsb-DE/sidebar.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/sidebar.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/sidebar.dtd
diff --git a/chrome/locale/hsb-DE/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/hsb-DE/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/hsb-DE/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/hsb-DE/subscriptionSelection.dtd
diff --git a/chrome/locale/hu/about.dtd b/chrome/adblockplus.jar!/locale/hu/about.dtd
similarity index 100%
rename from chrome/locale/hu/about.dtd
rename to chrome/adblockplus.jar!/locale/hu/about.dtd
diff --git a/chrome/locale/hu/composer.dtd b/chrome/adblockplus.jar!/locale/hu/composer.dtd
similarity index 100%
rename from chrome/locale/hu/composer.dtd
rename to chrome/adblockplus.jar!/locale/hu/composer.dtd
diff --git a/chrome/locale/hu/global.properties b/chrome/adblockplus.jar!/locale/hu/global.properties
similarity index 100%
rename from chrome/locale/hu/global.properties
rename to chrome/adblockplus.jar!/locale/hu/global.properties
diff --git a/chrome/locale/hu/overlay.dtd b/chrome/adblockplus.jar!/locale/hu/overlay.dtd
similarity index 100%
rename from chrome/locale/hu/overlay.dtd
rename to chrome/adblockplus.jar!/locale/hu/overlay.dtd
diff --git a/chrome/locale/hu/sendReport.dtd b/chrome/adblockplus.jar!/locale/hu/sendReport.dtd
similarity index 100%
rename from chrome/locale/hu/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/hu/sendReport.dtd
diff --git a/chrome/locale/hu/settings.dtd b/chrome/adblockplus.jar!/locale/hu/settings.dtd
similarity index 100%
rename from chrome/locale/hu/settings.dtd
rename to chrome/adblockplus.jar!/locale/hu/settings.dtd
diff --git a/chrome/locale/hu/sidebar.dtd b/chrome/adblockplus.jar!/locale/hu/sidebar.dtd
similarity index 100%
rename from chrome/locale/hu/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/hu/sidebar.dtd
diff --git a/chrome/locale/hu/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/hu/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/hu/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/hu/subscriptionSelection.dtd
diff --git a/chrome/locale/hy-AM/about.dtd b/chrome/adblockplus.jar!/locale/hy-AM/about.dtd
similarity index 100%
rename from chrome/locale/hy-AM/about.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/about.dtd
diff --git a/chrome/locale/hy-AM/composer.dtd b/chrome/adblockplus.jar!/locale/hy-AM/composer.dtd
similarity index 100%
rename from chrome/locale/hy-AM/composer.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/composer.dtd
diff --git a/chrome/locale/hy-AM/global.properties b/chrome/adblockplus.jar!/locale/hy-AM/global.properties
similarity index 100%
rename from chrome/locale/hy-AM/global.properties
rename to chrome/adblockplus.jar!/locale/hy-AM/global.properties
diff --git a/chrome/locale/hy-AM/overlay.dtd b/chrome/adblockplus.jar!/locale/hy-AM/overlay.dtd
similarity index 100%
rename from chrome/locale/hy-AM/overlay.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/overlay.dtd
diff --git a/chrome/locale/hy-AM/sendReport.dtd b/chrome/adblockplus.jar!/locale/hy-AM/sendReport.dtd
similarity index 100%
rename from chrome/locale/hy-AM/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/sendReport.dtd
diff --git a/chrome/locale/hy-AM/settings.dtd b/chrome/adblockplus.jar!/locale/hy-AM/settings.dtd
similarity index 100%
rename from chrome/locale/hy-AM/settings.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/settings.dtd
diff --git a/chrome/locale/hy-AM/sidebar.dtd b/chrome/adblockplus.jar!/locale/hy-AM/sidebar.dtd
similarity index 100%
rename from chrome/locale/hy-AM/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/sidebar.dtd
diff --git a/chrome/locale/hy-AM/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/hy-AM/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/hy-AM/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/hy-AM/subscriptionSelection.dtd
diff --git a/chrome/locale/is/about.dtd b/chrome/adblockplus.jar!/locale/is/about.dtd
similarity index 100%
rename from chrome/locale/is/about.dtd
rename to chrome/adblockplus.jar!/locale/is/about.dtd
diff --git a/chrome/locale/is/composer.dtd b/chrome/adblockplus.jar!/locale/is/composer.dtd
similarity index 100%
rename from chrome/locale/is/composer.dtd
rename to chrome/adblockplus.jar!/locale/is/composer.dtd
diff --git a/chrome/locale/is/global.properties b/chrome/adblockplus.jar!/locale/is/global.properties
similarity index 100%
rename from chrome/locale/is/global.properties
rename to chrome/adblockplus.jar!/locale/is/global.properties
diff --git a/chrome/locale/is/overlay.dtd b/chrome/adblockplus.jar!/locale/is/overlay.dtd
similarity index 100%
rename from chrome/locale/is/overlay.dtd
rename to chrome/adblockplus.jar!/locale/is/overlay.dtd
diff --git a/chrome/locale/is/sendReport.dtd b/chrome/adblockplus.jar!/locale/is/sendReport.dtd
similarity index 100%
rename from chrome/locale/is/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/is/sendReport.dtd
diff --git a/chrome/locale/is/settings.dtd b/chrome/adblockplus.jar!/locale/is/settings.dtd
similarity index 100%
rename from chrome/locale/is/settings.dtd
rename to chrome/adblockplus.jar!/locale/is/settings.dtd
diff --git a/chrome/locale/is/sidebar.dtd b/chrome/adblockplus.jar!/locale/is/sidebar.dtd
similarity index 100%
rename from chrome/locale/is/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/is/sidebar.dtd
diff --git a/chrome/locale/is/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/is/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/is/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/is/subscriptionSelection.dtd
diff --git a/chrome/locale/it/about.dtd b/chrome/adblockplus.jar!/locale/it/about.dtd
similarity index 100%
rename from chrome/locale/it/about.dtd
rename to chrome/adblockplus.jar!/locale/it/about.dtd
diff --git a/chrome/locale/it/composer.dtd b/chrome/adblockplus.jar!/locale/it/composer.dtd
similarity index 100%
rename from chrome/locale/it/composer.dtd
rename to chrome/adblockplus.jar!/locale/it/composer.dtd
diff --git a/chrome/locale/it/global.properties b/chrome/adblockplus.jar!/locale/it/global.properties
similarity index 100%
rename from chrome/locale/it/global.properties
rename to chrome/adblockplus.jar!/locale/it/global.properties
diff --git a/chrome/locale/it/overlay.dtd b/chrome/adblockplus.jar!/locale/it/overlay.dtd
similarity index 100%
rename from chrome/locale/it/overlay.dtd
rename to chrome/adblockplus.jar!/locale/it/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/it/sendReport.dtd b/chrome/adblockplus.jar!/locale/it/sendReport.dtd
new file mode 100644
index 0000000..44ddafd
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/it/sendReport.dtd
@@ -0,0 +1,143 @@
+<!ENTITY wizard.title "Configurazione guidata per segnalare problemi in una pagina web">
+<!ENTITY privacyPolicy.label "Informativa sulla privacy">
+<!ENTITY dataCollector.heading "Benvenuti alla configurazione guidata per segnalare problemi in una pagina web">
+<!ENTITY dataCollector.description "Attendere mentre vengono raccolti i dati necessari per la segnalazione di Adblock Plus di problemi in una pagina web">
+<!ENTITY typeSelector.heading "Selezione del problema">
+<!ENTITY typeSelector.description "
+ La configurazione guidata permette passo a passo di raccogliere ed inviare i dati necessari per effettuare la
+ segnalazione di Adblock Plus di problemi in una pagina web. Come primo passo, selezionare il tipo di problema
+ che si è verificato
+">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus sta bloccando troppi elementi">
+<!ENTITY typeSelector.falsePositive.accesskey "P">
+<!ENTITY typeSelector.falsePositive.description "
+ Selezionare questa opzione se nella pagina web manca parte del contenuto importante, se la pagina web viene
+ visualizzata non correttamente oppure se non funziona come dovrebbe. Ã possibile determinare se sia Adblock Plus
+ la causa del problema disattivando temporaneamente l'estensione
+">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus non sta bloccando alcun elemento">
+<!ENTITY typeSelector.falseNegative.accesskey "n">
+<!ENTITY typeSelector.falseNegative.description "
+ Selezionare questa opzione se nella pagina web vengono visualizzati banner e/o pubblicità nonostante
+ Adblock Plus sia attiva
+">
+<!ENTITY typeSelector.other.label "Si è verificato un problema di altro tipo">
+<!ENTITY typeSelector.other.accesskey "S">
+<!ENTITY typeSelector.other.description "
+ Selezionare questa opzione se nella pagina web si sta verificando un problema di altro tipo
+ che si sospetta relativo all'estensione stessa piuttosto che ai suoi filtri
+">
+<!ENTITY showRecentReports.label "Mostra le segnalazioni recentemente inviate">
+<!ENTITY recentReports.label "Segnalazioni recentemente inviate">
+<!ENTITY recentReports.clear.label "Elimina tutte le segnalazioni">
+<!ENTITY recentReports.clear.accesskey "t">
+<!ENTITY issues.description "
+ Sono stati rilevati dei problemi con le impostazioni di Adblock Plus che potrebbero essere responsabili
+ del problema da segnalare oppure potrebbero rendere difficile rinvenirne le cause
+">
+<!ENTITY issues.whitelist.description "
+ Adblock Plus è attualmente disattivata per la pagina web che si sta segnalando. Riattivare
+ l'estensione e ricaricare la pagina prima di inviare la segnalazione del problema per
+ rinvenirne le cause
+">
+<!ENTITY issues.whitelist.remove.label "Riattiva Adblock Plus nella pagina attuale">
+<!ENTITY issues.disabled.description "
+ Adblock Plus è attualmente disattivata e quindi non bloccherà alcun elemento
+">
+<!ENTITY issues.disabled.enable.label "Attiva Adblock Plus">
+<!ENTITY issues.nofilters.description "
+ Adblock Plus attualmente non sta bloccando alcun elemento. Il problema che si è
+ verificato è più probabile che non sia relativo ad Adblock Plus
+">
+<!ENTITY issues.nosubscriptions.description "
+ Non sembra essere attiva alcuna sottoscrizione di filtri che permette l'eliminazione
+ automatica di banner e/o pubblicità presenti nei siti web
+">
+<!ENTITY issues.nosubscriptions.add.label "Aggiungi una sottoscrizione di filtriâ¦">
+<!ENTITY issues.subscriptionCount.description "
+ Sembra che siano state aggiunte troppe sottoscrizioni di filtri. Ciò non è
+ raccomandato poiché aumenta considerevolmente la possibilità che si verifichino
+ dei problemi. Ã inoltre impossibile accettare tale segnalazione in quanto non
+ è chiaro quale autore di sottoscrizioni di filtri debba controllare; eliminare
+ tutte le sottoscrizioni superflue lasciando solo quella necessaria e verificare
+ se il problema persiste ancora
+">
+<!ENTITY issues.openPreferences.label "Apri la finestra delle impostazioniâ¦">
+<!ENTITY issues.ownfilters.description "
+ Alcuni dei filtri che vengono applicati nella pagina web attuale sono personalizzati;
+ disattivare tali filtri che potrebbero essere la causa del seguente problema:
+">
+<!ENTITY issues.ownfilters.disable.label "Disattiva i filtri">
+<!ENTITY issues.disabledgroups.description "
+ Gruppi/sottoscrizioni di filtri sono stati disattivati, ma potrebbero avere effetto
+ nella seguente pagina web:
+">
+<!ENTITY issues.disabledgroups.enable.label "Attiva gruppi/sottoscrizioni di filtri">
+<!ENTITY issues.disabledfilters.description "
+ I filtri sono stati disattivati, ma potrebbero avere effetto nella seguente pagina web:
+">
+<!ENTITY issues.disabledfilters.enable.label "Attiva i filtri">
+<!ENTITY issues.override.label "Le impostazioni di Adblock Plus sono corrette, proseguire con la raccolta dei dati per la segnalazione">
+<!ENTITY issues.override.accesskey "L">
+<!ENTITY issues.change.description "
+ Le impostazioni di Adblock Plus sono state modificate. Ricaricare la pagina web per testare le
+ modifiche e se il problema dovesse persistere inviare la segnalazione
+">
+<!ENTITY typeWarning.description "
+ Ã stato indicato che si vuole segnalare un problema generico relativo all'estensione
+ stessa piuttosto che ai suoi filtri. Poiché tali problemi sono riportati meglio sul
+ [link]forum di Adblock Plus[/link], si suggerisce di utilizzare la segnalazione di
+ problemi solo come integrazione di una discussione già esistente, visto che nessuno noterÃ
+ una segnalazione priva di relativo link alla pagina web dove si verifica appunto il problema.
+ Il link generato automaticamente verrà fornito dopo l'invio della segnalazione
+">
+<!ENTITY typeWarning.override.label "Comprendo e voglio inviare la segnalazione comunque">
+<!ENTITY typeWarning.override.accesskey "v">
+<!ENTITY reloadButton.label "Ricarica la pagina">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "Immagine da allegare">
+<!ENTITY screenshot.description "
+ Una stessa pagina web può apparire in modo differente a più persone. Potrebbe essere di aiuto per
+ meglio comprendere il problema allegare un'immagine della pagina web alla segnalazione. Ã
+ possibile eliminare le sezioni contenenti dati sensibili nonché contrassegnare le aree dove il
+ problema è evidente facendo prima clic sui relativi pulsanti ed in seguito selezionando le parti
+ interessate dell'immagine della pagina web con il mouse
+">
+<!ENTITY screenshot.attach.label "Allega un'immagine della pagina alla segnalazione">
+<!ENTITY screenshot.attach.accesskey "u">
+<!ENTITY screenshot.mark.label "Contrassegna l'area del problema">
+<!ENTITY screenshot.mark.accesskey "C">
+<!ENTITY screenshot.remove.label "Elimina i dati sensibili">
+<!ENTITY screenshot.remove.accesskey "E">
+<!ENTITY screenshot.undo.label "Annulla">
+<!ENTITY screenshot.undo.accesskey "A">
+<!ENTITY commentPage.heading "Invio di un commento">
+<!ENTITY commentPage.description "
+ Ã possibile digitare nel relativo campo di testo qui sotto un commento per comprendere meglio
+ il problema segnalato. Questo passo è opzionale ma raccomandato se il problema non è ovvio.
+ Ã inoltre possibile visualizzare i dati della segnalazione prima di inviarla
+">
+<!ENTITY comment.label "Commento (opzionale):">
+<!ENTITY comment.accesskey "o">
+<!ENTITY comment.lengthWarning "La lunghezza massima del testo del commento è di 1000 caratteri; quelli eccedenti non verranno inviati">
+<!ENTITY email.label "E-mail per ulteriori richieste di informazioni (opzionale):">
+<!ENTITY email.accesskey "m">
+<!ENTITY attachExtensions.label "Allega la lista di estensioni e plugin attivi">
+<!ENTITY attachExtensions.accesskey "l">
+<!ENTITY sendButton.label "Invia la segnalazione">
+<!ENTITY sendButton.accesskey "z">
+<!ENTITY showData.label "Mostra i dati della segnalazione">
+<!ENTITY data.label "Dati della segnalazione:">
+<!ENTITY data.accesskey "D">
+<!ENTITY sendPage.heading "Invio della segnalazione">
+<!ENTITY sendPage.waitMessage "Attendere mentre la segnalazione di Adblock Plus viene inviata">
+<!ENTITY sendPage.confirmation "Segnalazione inviata correttamente, per visualizzarne i dati fare clic sul seguente link:">
+<!ENTITY sendPage.knownIssue "Problema segnalato precedentemente noto. Ulteriori informazioni:">
+<!ENTITY sendPage.errorMessage "
+ Il tentativo di inviare la segnalazione non è riuscito a causa del seguente errore: "?1?".
+ Accertarsi di essere collegati ad internet e riprovare. Se il problema persiste inviare una richiesta
+ di assistenza nel [link]forum di Adblock Plus[/link]
+">
+<!ENTITY sendPage.retry.label "Riprova ad inviare">
+<!ENTITY copyLink.label "Copia il link della segnalazione">
+<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/locale/it/settings.dtd b/chrome/adblockplus.jar!/locale/it/settings.dtd
similarity index 100%
rename from chrome/locale/it/settings.dtd
rename to chrome/adblockplus.jar!/locale/it/settings.dtd
diff --git a/chrome/locale/it/sidebar.dtd b/chrome/adblockplus.jar!/locale/it/sidebar.dtd
similarity index 100%
rename from chrome/locale/it/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/it/sidebar.dtd
diff --git a/chrome/locale/it/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/it/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/it/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/it/subscriptionSelection.dtd
diff --git a/chrome/locale/ja/about.dtd b/chrome/adblockplus.jar!/locale/ja/about.dtd
similarity index 100%
rename from chrome/locale/ja/about.dtd
rename to chrome/adblockplus.jar!/locale/ja/about.dtd
diff --git a/chrome/locale/ja/composer.dtd b/chrome/adblockplus.jar!/locale/ja/composer.dtd
similarity index 100%
rename from chrome/locale/ja/composer.dtd
rename to chrome/adblockplus.jar!/locale/ja/composer.dtd
diff --git a/chrome/locale/ja/global.properties b/chrome/adblockplus.jar!/locale/ja/global.properties
similarity index 100%
rename from chrome/locale/ja/global.properties
rename to chrome/adblockplus.jar!/locale/ja/global.properties
diff --git a/chrome/adblockplus.jar!/locale/ja/overlay.dtd b/chrome/adblockplus.jar!/locale/ja/overlay.dtd
new file mode 100644
index 0000000..357fd64
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ja/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "ã¹ãã¼ã¿ã¹:">
+<!ENTITY blocked.tooltip "ãããã¯æ¸ã¿é
ç®:">
+<!ENTITY filters.tooltip "æå¹ãªãã£ã«ã¿:">
+<!ENTITY menuitem.label "Adblock Plus è¨å®">
+<!ENTITY menuitem.accesskey "b">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus:ãããã¯å¯è½é
ç®">
+<!ENTITY context.image.label "Adblock Plus:ç»åããããã¯">
+<!ENTITY context.object.label "Adblock Plus:ãªãã¸ã§ã¯ãããããã¯">
+<!ENTITY context.frame.label "Adblock Plus:ãã¬ã¼ã ããããã¯">
+<!ENTITY context.media.label "Adblock Plus:ãããªï¼ãªã¼ãã£ãªããããã¯">
+<!ENTITY context.removeWhitelist.label "Adblock Plus:ãã®ãã¼ã¸ã§æå¹ã«æ»ã">
+<!ENTITY sidebar.title "ãã®ãã¼ã¸ã§ãããã¯å¯è½ãªé
ç®">
+<!ENTITY sendReport.label "ãã®ãã¼ã¸ã®ä¸å
·åãå ±å">
+<!ENTITY sendReport.accesskey "R">
+<!ENTITY settings.label "è¨å®">
+<!ENTITY settings.accesskey "f">
+<!ENTITY opensidebar.label "ãããã¯å¯è½é
ç®ä¸è¦§ãéã">
+<!ENTITY opensidebar.accesskey "b">
+<!ENTITY closesidebar.label "ãããã¯å¯è½é
ç®ä¸è¦§ãéãã">
+<!ENTITY closesidebar.accesskey "b">
+<!ENTITY whitelist.site.label "?1? ã§ç¡å¹">
+<!ENTITY whitelist.page.label "ãã®ãã¼ã¸ã®ã¿ã§ç¡å¹">
+<!ENTITY disable.label "å
¨ãã¼ã¸ã§ç¡å¹">
+<!ENTITY recommend.label "Facebook ã§å§ãã">
+<!ENTITY objecttab.title "ãããã¯ãã">
+<!ENTITY objecttab.tooltip "ã¯ãªãã¯ã㦠Adblock Plus ã§ãªãã¸ã§ã¯ãããããã¯">
diff --git a/chrome/adblockplus.jar!/locale/ja/sendReport.dtd b/chrome/adblockplus.jar!/locale/ja/sendReport.dtd
new file mode 100644
index 0000000..4d6ce7e
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ja/sendReport.dtd
@@ -0,0 +1,75 @@
+<!ENTITY wizard.title "ä¸å
·åã¬ãã¼ãæ©è½">
+<!ENTITY privacyPolicy.label "ãã©ã¤ãã·ã¼ ããªã·ã¼">
+<!ENTITY dataCollector.heading "ä¸å
·åã¬ãã¼ãæ©è½ã¸ãããã">
+<!ENTITY dataCollector.description "Adblock Plus ãå¿
è¦ãªãã¼ã¿ãéããã¾ã§ããã°ãããå¾
ã¡ãã ãã">
+<!ENTITY typeSelector.heading "ä¸å
·å種å¥ã鏿">
+<!ENTITY typeSelector.description "ä¸å
·åã¬ãã¼ãã®æåºã«å¿
è¦ãªã¹ããããæ¡å
ãã¾ããã¾ãæåã«ãééããä¸å
·åã®ç¨®å¥ã鏿ãã¦ãã ãã:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus ã®ãããã¯ãéã">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "ããã¹ãã³ã³ãã³ãããªãã表示ãä¸é©åããããã¯ãã£ã«ã¿ãæ£ããæ©è½ãã¦ããªãå ´åã¯ãã®ãªãã·ã§ã³ã鏿ãã¦ãã ããã䏿çã« Adblock Plus ãç¡å¹ã«ãã¦ã¿ããã¨ã§ãåå ã Adblock Plus ã«ãããã©ãã確ããããã¨ãã§ãã¾ãã">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus ãåºåããããã¯ãã¦ããªã">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "Adblock Plus ãæå¹ã§ãåºåã表示ãããå ´åããã®ãªãã·ã§ã³ã鏿">
+<!ENTITY typeSelector.other.label "ãã®ä»ã®ä¸å
·å">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY typeSelector.other.description "ãã£ã«ã¿ã§ã¯ãªã Adblock Plus èªä½ã®ä¸å
·åãçãããå ´åããã®ãªãã·ã§ã³ã鏿">
+<!ENTITY showRecentReports.label "æè¿éä¿¡ããã¬ãã¼ãã表示">
+<!ENTITY recentReports.label "æè¿éä¿¡ããã¬ãã¼ã">
+<!ENTITY recentReports.clear.label "ãã¹ã¦ã®ã¬ãã¼ããåé¤">
+<!ENTITY recentReports.clear.accesskey "R">
+<!ENTITY issues.description "Adblock Plus ã¯ãã®ä¸å
·åã«é¢ä¿ããããããã¯èª¿æ»ãå°é£ã«ããè¨å®ãçºè¦ãã¾ãã">
+<!ENTITY issues.whitelist.description "å ±åãããã¨ãã¦ãããã¼ã¸ã§ Adblock Plus ãç¡å¹ã«ãªã£ã¦ãã¾ããä¸å
·å調æ»ãæ¯æ´ããããã«ã¯ Adblock Plus ãæå¹ã«æ»ããåèªã¿è¾¼ã¿ãã¦ããã¬ãã¼ããæåºãã¦ãã ããã">
+<!ENTITY issues.whitelist.remove.label "ãã®ãã¼ã¸ã§ Adblock Plus ãæå¹ã«æ»ã">
+<!ENTITY issues.disabled.description "Adblock Plus ãç¡å¹ãªã®ã§ãä½ããããã¯ããã¾ãã">
+<!ENTITY issues.disabled.enable.label "Adblock Plus ãæå¹ã«ãã">
+<!ENTITY issues.nofilters.description "Adblock Plus ã¯ç¾å¨ã®ãã¼ã¸ã§ä½ããããã¯ãã¦ããªãã®ã§ããæ°ä»ãã®ä¸å
·åã¯æãã Adblock Plus ã¨é¢ä¿ããã¾ãã">
+<!ENTITY issues.nosubscriptions.description "ã¦ã§ããµã¤ãã®ä¸è¦ãªã³ã³ãã³ããèªååé¤ããè³¼èªãã£ã«ã¿ããã¾ã è³¼èªããã¦ããªãããã§ã">
+<!ENTITY issues.nosubscriptions.add.label "è³¼èªãã£ã«ã¿ã追å ">
+<!ENTITY issues.subscriptionCount.description "è³¼èªãã£ã«ã¿ãå¤éãã§ããã©ã®è³¼èªãã£ã«ã¿ä½è
ããã®ä¸å
·åã«å¯¾å¦ãã¹ãã䏿ãªã®ã§ãã¬ãã¼ããåçã§ãã¾ãããæ¬å½ã«å¿
è¦ãªè³¼èªãã£ã«ã¿ä»¥å¤ãåé¤ããä¸å
·åãåç¾ããã確èªãã¦ãã ããã">
+<!ENTITY issues.openPreferences.label "è¨å®ç»é¢">
+<!ENTITY issues.ownfilters.description "ãã®ãã¼ã¸ã«é©ç¨ããã¦ãããã£ã«ã¿ã«èªä½ãã£ã«ã¿ãå«ã¾ãã¦ãã¾ããããããã£ã«ã¿ãä¸å
·åãèµ·ããã¦ããå¯è½æ§ãããã®ã§ç¡å¹ã«ãã¦ãã ãã:">
+<!ENTITY issues.ownfilters.disable.label "ãã£ã«ã¿ãç¡å¹ã«ãã">
+<!ENTITY issues.disabledgroups.description "次ã®è³¼èªãã£ã«ã¿ï¼ã°ã«ã¼ããã£ã«ã¿ã¯ç¡å¹ã«ãªã£ã¦ãã¾ããããã®ãã¼ã¸ã«å½±é¿ããã£ãããããã¾ãã:">
+<!ENTITY issues.disabledgroups.enable.label "è³¼èªãã£ã«ã¿ï¼ã°ã«ã¼ããã£ã«ã¿ãæå¹ã«ãã">
+<!ENTITY issues.disabledfilters.description "次ã®ãã£ã«ã¿ã¯ç¡å¹ã«ãªã£ã¦ãã¾ããããã®ãã¼ã¸ã«å½±é¿ããã£ãããããã¾ãã:">
+<!ENTITY issues.disabledfilters.enable.label "ãã£ã«ã¿ãæå¹ã«ãã">
+<!ENTITY issues.override.label "è¨å®ã¯æ£ããã®ã§ãã¬ãã¼ã使ãç¶ç¶ãã¾ã">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY issues.change.description "è¨å®ã夿´ããã¾ããã夿´ã確èªããçºã«ãã¼ã¸ãåèªã¿è¾¼ã¿ããããä¸å
·åã解決ããªããã°ã¬ãã¼ããæåºãã¦ãã ãã">
+<!ENTITY typeWarning.description "ãã£ã«ã¿ã«ã¤ãã¦ã§ã¯ãªã Adblock Plus å
¨è¬ã®ä¸å
·åãå ±åãããã¨ãã¦ãã¾ããæ¬æ¥ãã®ãããªä¸å
·å㯠[link]Adblock Plus ãã©ã¼ã©ã [/link] ã§å ±åãã¹ãã§ããã¾ããä¸å
·åã¬ãã¼ãã¸ã®ãªã³ã¯ã¯ï¼èªãæä¾ããªãéãï¼èª°ãæ°ä»ããªãã®ã§ãè°è«ãè£å®ããããã ãã«ä½¿ç¨ãã¦ãã ãããã¬ãã¼ãã¸ã®ãªã³ã¯ã¯éä¿¡å¾ã«èªåçæããã¾ãã">
+<!ENTITY typeWarning.override.label "çè§£ããä¸ã§ãã¬ãã¼ããæåºãã">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "ãã¼ã¸ãåèªã¿è¾¼ã¿ãã">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "ã¹ã¯ãªã¼ã³ã·ã§ãããæ·»ä»">
+<!ENTITY screenshot.description "åããã¼ã¸ã§ãå¥ã®äººã«ã¯ç°ãªã£ã¦è¡¨ç¤ºããããã¨ãããã®ã§ãã¹ã¯ãªã¼ã³ã·ã§ããã¯ä¸å
·åã®ææ¡ã«å½¹ç«ã¤ã¡ã¾ãã対å¿ãã¿ã³ãã¯ãªãã¯ãã¦ããã¹ã¯ãªã¼ã³ã·ã§ããä¸ã§ãã©ãã°ãããã¨ã«ãã£ã¦ä¸å
·åçºçç®æãæ°ä»ããããããªå°ãã¤ããããå人æ
å ±ãé ããããããã¨ãã§ãã¾ãã">
+<!ENTITY screenshot.attach.label "ã¬ãã¼ãã«ãã¼ã¸ã®ã¹ã¯ãªã¼ã³ã·ã§ãããæ·»ä»">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY screenshot.mark.label "ä¸å
·åãçºçãã¦ããå ´æãå°ãã¤ãã¦ç¹å®">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "å人æ
å ±ãé ã">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY screenshot.undo.label "å
ã«æ»ã">
+<!ENTITY screenshot.undo.accesskey "U">
+<!ENTITY commentPage.heading "ã³ã¡ã³ããå
¥å">
+<!ENTITY commentPage.description "è³¼èªãã£ã«ã¿ä½è
ãä¸å
·åãææ¡ã§ãããã説æãã¦ãã ãããéä¿¡åã«ã¬ãã¼ãã®ãã¼ã¿ã忤è¨ãããã¨ãã§ãã¾ãã">
+<!ENTITY comment.label "ã³ã¡ã³ãï¼ãABP Japanese Filterãå©ç¨è
ã¯å¿
ãå
¥åããã以å¤ã¯ãªãã·ã§ã³ï¼:">
+<!ENTITY comment.accesskey "C">
+<!ENTITY comment.lengthWarning "ã³ã¡ã³ãã 1000 æåãè¶
ãã¦ããã®ã§å
é ãã 1000 æåã ãéä¿¡ããã¾ã">
+<!ENTITY email.label "ãã詳細ãªè³ªåãå¿
è¦ãªå ´åã«ä½¿ãã¡ã¼ã«ã¢ãã¬ã¹ï¼ãªãã·ã§ã³ï¼:">
+<!ENTITY email.accesskey "m">
+<!ENTITY attachExtensions.label "åå ãã¢ããªã³ã®è¡çªã«ããå ´åã®çºã«ãæå¹ãªã¢ããªã³ã®ãªã¹ããã¬ãã¼ãã«æ·»ä»">
+<!ENTITY attachExtensions.accesskey "x">
+<!ENTITY sendButton.label "ã¬ãã¼ããéä¿¡">
+<!ENTITY sendButton.accesskey "n">
+<!ENTITY showData.label "ã¬ãã¼ããã¼ã¿ã表示">
+<!ENTITY data.label "ã¬ãã¼ããã¼ã¿:">
+<!ENTITY data.accesskey "p">
+<!ENTITY sendPage.heading "ã¬ãã¼ããéä¿¡">
+<!ENTITY sendPage.waitMessage "Adblock Plus ãã¬ãã¼ããæåºããéããã°ãããå¾
ã¡ãã ãã">
+<!ENTITY sendPage.confirmation "ããªãã®ã¬ãã¼ãã¯ä¿åããã¾ãããæ¬¡ã®ã¢ãã¬ã¹ã§ã¢ã¯ã»ã¹ã§ãã¾ã:">
+<!ENTITY sendPage.knownIssue "ããªãã®ã¬ãã¼ãã¯ããããæ¢ç¥ã®ä¸å
·åã§ãã詳ããæ
å ±:">
+<!ENTITY sendPage.errorMessage "ã¬ãã¼ãéä¿¡ãã¨ã©ã¼ã³ã¼ã "?1?" ã§å¤±æãã¾ãããã¤ã³ã¿ã¼ãããã«æ¥ç¶ããã¦ããã確èªãå試è¡ãã¦ãã ãããåé¡ã解決ããªãå ´å㯠[link]Adblock Plus ãã©ã¼ã©ã [/link] ã§å©ããæ±ãã¦ãã ããã">
+<!ENTITY sendPage.retry.label "åéä¿¡">
+<!ENTITY copyLink.label "ã¬ãã¼ãã¸ã®ãªã³ã¯ãã³ãã¼">
+<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/adblockplus.jar!/locale/ja/settings.dtd b/chrome/adblockplus.jar!/locale/ja/settings.dtd
new file mode 100644
index 0000000..8e34ca7
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ja/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Adblock Plus è¨å®">
+<!ENTITY filters.label "ãã£ã«ã¿">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "ãã£ã«ã¿ã追å ">
+<!ENTITY add.accesskey "A">
+<!ENTITY addsubscription.label "è³¼èªãã£ã«ã¿ã追å ">
+<!ENTITY addsubscription.accesskey "s">
+<!ENTITY synchsubscriptions.label "å
¨è³¼èªãã£ã«ã¿ãæ´æ°">
+<!ENTITY synchsubscriptions.accesskey "d">
+<!ENTITY import.label "ãã£ã«ã¿ãã¤ã³ãã¼ã">
+<!ENTITY import.accesskey "m">
+<!ENTITY export.label "ãã£ã«ã¿ãã¨ã¯ã¹ãã¼ã">
+<!ENTITY export.accesskey "x">
+<!ENTITY clearall.label "å
¨ã¦ã®èªä½ãã£ã«ã¿ãåé¤">
+<!ENTITY clearall.accesskey "l">
+<!ENTITY resethitcounts.label "ãããæ°ããªã»ãã">
+<!ENTITY resethitcounts.accesskey "R">
+<!ENTITY edit.label "ç·¨é">
+<!ENTITY edit.accesskey "E">
+<!ENTITY cut.label "åãåã">
+<!ENTITY cut.accesskey "t">
+<!ENTITY copy.label "ã³ãã¼">
+<!ENTITY copy.accesskey "C">
+<!ENTITY paste.label "è²¼ãä»ã">
+<!ENTITY paste.accesskey "P">
+<!ENTITY remove.label "åé¤">
+<!ENTITY remove.accesskey "D">
+<!ENTITY menu.find.label "æ¤ç´¢">
+<!ENTITY menu.find.accesskey "F">
+<!ENTITY menu.findagain.label "åæ¤ç´¢">
+<!ENTITY menu.findagain.accesskey "g">
+<!ENTITY view.label "表示">
+<!ENTITY view.accesskey "V">
+<!ENTITY sort.label "ã½ã¼ã">
+<!ENTITY sort.accesskey "S">
+<!ENTITY sort.none.label "ã½ã¼ããªã">
+<!ENTITY sort.none.accesskey "U">
+<!ENTITY sort.ascending.label "A > Z é ã«ã½ã¼ã">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Z > A é ã«ã½ã¼ã">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "ãªãã·ã§ã³">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "Adblock Plus ãæå¹ã«ãã">
+<!ENTITY enable.accesskey "n">
+<!ENTITY showintoolbar.label "ãã¼ã«ãã¼ã«è¡¨ç¤º">
+<!ENTITY showintoolbar.accesskey "b">
+<!ENTITY showinstatusbar.label "ã¹ãã¼ã¿ã¹ãã¼ã«è¡¨ç¤º">
+<!ENTITY showinstatusbar.accesskey "s">
+<!ENTITY objecttabs.label "Flash 㨠Java ã§ã¿ãã表示">
+<!ENTITY objecttabs.accesskey "t">
+<!ENTITY collapse.label "ãããã¯å¾ã®ç©ºãã¹ãã¼ã¹ãæ®ããã«è©°ãã">
+<!ENTITY collapse.accesskey "l">
+<!ENTITY sync.label "Adblock Plus ã®è¨å®ãåæãã">
+<!ENTITY sync.accesskey "c">
+<!ENTITY help.label "ãã«ã">
+<!ENTITY help.accesskey "H">
+<!ENTITY gettingStarted.label "éå§">
+<!ENTITY gettingStarted.accesskey "s">
+<!ENTITY faq.label "ãããã質åã¨åçï¼ï¼¦ï¼¡ï¼±ï¼">
+<!ENTITY faq.accesskey "F">
+<!ENTITY filterdoc.label "Adblock Plus ãã£ã«ã¿è¨è¿°ã¬ã¤ã">
+<!ENTITY filterdoc.accesskey "r">
+<!ENTITY about.label "Adblock Plus ã«ã¤ãã¦">
+<!ENTITY about.accesskey "b">
+<!ENTITY description "以ä¸ã®ãã£ã«ã¿ã§ãããã¯å¯¾è±¡ãå®ç¾©ãã¾ã:">
+<!ENTITY filter.column "ãã£ã«ã¿ã®ã«ã¼ã«">
+<!ENTITY filter.accesskey "F">
+<!ENTITY slow.column "ä½éãã£ã«ã¿">
+<!ENTITY slow.accesskey "w">
+<!ENTITY enabled.column "æå¹">
+<!ENTITY enabled.accesskey "n">
+<!ENTITY hitcount.column "ãããæ°">
+<!ENTITY hitcount.accesskey "H">
+<!ENTITY lasthit.column "æçµãããæ¥æ">
+<!ENTITY lasthit.accesskey "L">
+<!ENTITY context.edit.label "ãã£ã«ã¿ç·¨é">
+<!ENTITY context.resethitcount.label "ãã®ãã£ã«ã¿ã®ãããæ°ããªã»ãã">
+<!ENTITY context.synchsubscription.label "ä»ããè³¼èªãã£ã«ã¿ãæ´æ°">
+<!ENTITY context.editsubscription.label "è³¼èªãã£ã«ã¿è¨å®">
+<!ENTITY context.moveup.label "ä¸ã¸">
+<!ENTITY context.movedown.label "ä¸ã¸">
+<!ENTITY context.movegroupup.label "ä¸ã®ã°ã«ã¼ãã¸">
+<!ENTITY context.movegroupdown.label "ä¸ã®ã°ã«ã¼ãã¸">
+<!ENTITY context.enable.label "æå¹">
+<!ENTITY context.disable.label "ç¡å¹">
+<!ENTITY apply.label "é©ç¨">
+<!ENTITY apply.accesskey "p">
+<!ENTITY fennec.subscription.label "è³¼èªãã£ã«ã¿">
diff --git a/chrome/locale/ja/sidebar.dtd b/chrome/adblockplus.jar!/locale/ja/sidebar.dtd
similarity index 100%
rename from chrome/locale/ja/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ja/sidebar.dtd
diff --git a/chrome/locale/ja/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ja/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ja/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ja/subscriptionSelection.dtd
diff --git a/chrome/locale/kk-KZ/about.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/about.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/about.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/about.dtd
diff --git a/chrome/locale/kk-KZ/composer.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/composer.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/composer.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/composer.dtd
diff --git a/chrome/locale/kk-KZ/global.properties b/chrome/adblockplus.jar!/locale/kk-KZ/global.properties
similarity index 100%
rename from chrome/locale/kk-KZ/global.properties
rename to chrome/adblockplus.jar!/locale/kk-KZ/global.properties
diff --git a/chrome/locale/kk-KZ/overlay.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/overlay.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/overlay.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/overlay.dtd
diff --git a/chrome/locale/kk-KZ/sendReport.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/sendReport.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/sendReport.dtd
diff --git a/chrome/locale/kk-KZ/settings.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/settings.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/settings.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/settings.dtd
diff --git a/chrome/locale/kk-KZ/sidebar.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/sidebar.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/sidebar.dtd
diff --git a/chrome/locale/kk-KZ/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/kk-KZ/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/kk-KZ/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/kk-KZ/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/ko/about.dtd b/chrome/adblockplus.jar!/locale/ko/about.dtd
new file mode 100644
index 0000000..fca21c8
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ko/about.dtd
@@ -0,0 +1,8 @@
+<!ENTITY dialog.title "ì ëë¸ë¡ íë¬ì¤ ì ë³´">
+<!ENTITY version.title "ë²ì ">
+<!ENTITY description "ì ëë¸ë¡ íë¬ì¤ë ì½í
ì¸ ì´ì©ì ë°©í´íê³ ë¶ê±´ì í ê´ê³ 를 ì°¨ë¨íì¬ ë¹ ë¥´ê³ ì¾ì í ì¸í°ë·ì ë§ë¤ì´ì¤ëë¤. ì ëë¸ë¡ íë¬ì¤ íë¡ì í¸ì 목ì ì ê´ê³ 를 ì°¨ë¨/íì©íì¬ ì¸í°ë·ì ë³íìí¤ë ê²ì
ëë¤!">
+<!ENTITY homepage.label "ííì´ì§">
+<!ENTITY author.label "ê°ë°ì">
+<!ENTITY contributors.label "ê³µíì">
+<!ENTITY subscriptionAuthors.label "구ë
íí° ì ì§ì">
+<!ENTITY translators.label "ë²ìê°">
diff --git a/chrome/adblockplus.jar!/locale/ko/composer.dtd b/chrome/adblockplus.jar!/locale/ko/composer.dtd
new file mode 100644
index 0000000..2b33dfd
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ko/composer.dtd
@@ -0,0 +1,47 @@
+<!ENTITY dialog.title "íí° ì¶ê°">
+<!ENTITY accept.label "ì¶ê°">
+<!ENTITY advanced.label "ê³ ê¸ ë³´ê¸°">
+<!ENTITY basic.label "기본 보기">
+<!ENTITY disabled.warning "ì ëë¸ë¡ íë¬ì¤ê° ì¬ì© ì¤ì§ë¨ : íí° ì¶ê° ê°ë¥ + íí° ì ì© ì¤ì§ [link]â ì ëë¸ë¡ íë¬ì¤ ì¬ì©[/link]">
+<!ENTITY groupDisabled.warning ""?1?" íí° ê·¸ë£¹ì´ ì¬ì© ì¤ì§ë¨ : íí° ì¶ê° ê°ë¥ + íí° ê·¸ë£¹ ì ì© ì¤ì§ [link]â íí° ê·¸ë£¹ ì¬ì©[/link]">
+<!ENTITY filter.label "ì íí°">
+<!ENTITY filter.accesskey "f">
+<!ENTITY preferences.label "íí° ëª©ë¡">
+<!ENTITY preferences.accesskey "S">
+<!ENTITY type.filter.label "ì°¨ë¨ íí°">
+<!ENTITY type.filter.accesskey "B">
+<!ENTITY type.whitelist.label "íì© íí°">
+<!ENTITY type.whitelist.accesskey "x">
+<!ENTITY pattern.label "ì í 찾기">
+<!ENTITY pattern.explanation "ì íì ì¼ì¹íë 주ì를 ê²ìíë í
ì¤í¸ 문ìì´ì´ë©°, ìì 문ì(*)ë¡ ì ì© ë²ì를 ì¡°ì í ì ììµëë¤.">
+<!ENTITY regexp.warning "[ë린 íí°] í¨í´ ëì ìì 문ì(*)ê° ìì¼ë©´ ì ê· ííìì¼ë¡ í´ìëë©°, ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ëë ¤ì§.">
+<!ENTITY shortpattern.warning "[ë린 íí°] í¨í´ì 길ì´ê° ë무 ì§§ì¼ë©´ íí°ê° ë¹í¨ì¨ì ì¼ë¡ ì²ë¦¬ëë©°, ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ëë ¤ì§.">
+<!ENTITY match.warning "ì
ë ¥í í¨í´ê³¼ ì¼ì¹íë 주ìê° ìì¼ë©°, ì°¨ë¨/íì©í 주ìì ìí¥ì 미ì¹ì§ ìì.">
+<!ENTITY custom.pattern.label "ì¬ì©ì ì§ì (C)">
+<!ENTITY custom.pattern.accesskey "C">
+<!ENTITY anchors.label "ì í ì¼ì¹ ì¡°ê±´ :">
+<!ENTITY anchor.start.label "주ì ìì ë¶ë¶ì ì¼ì¹">
+<!ENTITY anchor.start.accesskey "g">
+<!ENTITY anchor.start.flexible.label "ëë©ì¸ ìì ë¶ë¶ì ì¼ì¹">
+<!ENTITY anchor.start.flexible.accesskey "g">
+<!ENTITY anchor.end.label "주ì ë ë¶ë¶ì ì¼ì¹">
+<!ENTITY anchor.end.accesskey "n">
+<!ENTITY options.label "ìµì
">
+<!ENTITY domainRestriction.label "ì§ì ë ëë©ì¸ìë§ ì ì©(D) :">
+<!ENTITY domainRestriction.accesskey "d">
+<!ENTITY domainRestriction.help "1. íì´í 기í¸(|)를 ì´ì©í´ ì¬ë¬ ëë©ì¸ì ì ì© (ìì : site1.com|site2.net). 2. 물결 기í¸(~)를 ì´ì©í´ íí°ë¥¼ ì ì©íì§ ìì ëë©ì¸ ì§ì (ìì : ~site.com)">
+<!ENTITY firstParty.label "ë´ë¶ ìì²ìë§ ì ì©">
+<!ENTITY firstParty.accesskey "r">
+<!ENTITY thirdParty.label "ì¸ë¶ ìì²ìë§ ì ì©">
+<!ENTITY thirdParty.accesskey "T">
+<!ENTITY matchCase.label "ë/ì문ì 구ë¶">
+<!ENTITY matchCase.accesskey "M">
+<!ENTITY types.label "ì ì© íì">
+<!ENTITY selectAllTypes.label "모ë ì í">
+<!ENTITY unselectAllTypes.label "ì í í´ì ">
+<!ENTITY collapse.label "ì°¨ë¨ë ììì ìì ì¨ê¸°ê¸°">
+<!ENTITY collapse.accesskey "l">
+<!ENTITY collapse.default.yes.label "ê¸°ë³¸ê° (ì)">
+<!ENTITY collapse.default.no.label "ê¸°ë³¸ê° (ìëì¤)">
+<!ENTITY collapse.yes.label "ì">
+<!ENTITY collapse.no.label "ìëì¤">
diff --git a/chrome/adblockplus.jar!/locale/ko/global.properties b/chrome/adblockplus.jar!/locale/ko/global.properties
new file mode 100644
index 0000000..a46d0c7
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ko/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=ì ëë¸ë¡ íë¬ì¤
+action0_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
+action1_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
+action2_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
+action3_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
+disabled_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
+active_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© [구ë
íí° : ?1?ê°, ì¬ì©ì íí° : ?2?ê° ]
+whitelisted_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© (íì©ë íì´ì§)
+blocked_count_tooltip=ì°¨ë¨ : ?1?ê°, ì ì²´ í목 : ?2?ê°
+blocked_count_addendum=(íì© : ?1?ê°, ìì ì¨ê¹ : ?2?ê°)
+no_blocking_suggestions=íì¬ íì´ì§ì ì°¨ë¨ ê°ë¥í íëª©ì´ ììµëë¤.
+whitelisted_page=íì©ë íì´ì§
+whitelist_description=íì© íí°
+filterlist_description=ì°¨ë¨ íí°
+invalid_description=ì¬ë°ë¥´ì§ ìì íí°
+elemhide_description=ìì ì¨ê¹ íí°
+subscription_description=구ë
íí° :
+subscription_wrong_version=구ë
íí° ì¤ ì¼ë¶ íí°ê° ì ìì ì¼ë¡ ìëí기 ìí´ì ìµìí ì ëë¸ë¡ íë¬ì¤ ?1? ë²ì ì ì¤ì¹í´ì¼ í©ëë¤.
+subscription_source=ìì¹ :
+subscription_status=ìí :
+subscription_status_autodownload=ìë ì
ë°ì´í¸
+subscription_status_manualdownload=ìë ì
ë°ì´í¸
+subscription_status_externaldownload=ì¸ë¶ ì
ë°ì´í¸ (ë¤ë¥¸ ë¶ê° 기ë¥)
+subscription_status_lastdownload=ë§ì§ë§ ë¤ì´ë¡ë :
+subscription_status_lastdownload_inprogress=ë¤ì´ë¡ë ì¤...
+subscription_status_lastdownload_unknown=ì ì ìì
+remove_subscription_warning=ì´ êµ¬ë
íí°ë¥¼ ì ê±°íìê² ìµëê¹?
+import_filters_wrong_version=ê²½ê³ : ì¼ë¶ íí°ê° ì ìì ì¼ë¡ ìëí기 ìí´ ìµìí ì ëë¸ë¡ íë¬ì¤ ?1? ë²ì ì ì¤ì¹í´ì¼ í©ëë¤. ì´ íí° ëª©ë¡ì ê°ì ¸ì¤ê¸° ì ì ì ëë¸ë¡ íë¬ì¤ë¥¼ ìµì ë²ì ì¼ë¡ ì
ê·¸ë ì´ëíììì¤.
+import_filters_warning=ê°ì ¸ì¨ íí°ë¥¼ íì¬ì ì¬ì©ì íí°ì ë®ì´ì°ê±°ë íí° ê·¸ë£¹ë³ë¡ ëª©ë¡ ëì ì¶ê°íìê² ìµëê¹?
+import_filters_title=íí° ê°ì ¸ì¤ê¸°
+export_filters_title=ì¬ì©ì íí° ë´ë³´ë´ê¸°
+invalid_filters_file=ì ëë¸ë¡ íë¬ì¤ì íí° íì¼ì´ ìëëë¤.
+filters_write_error=íí°ë¥¼ íì¼ë¡ ì ì¥íë ì¤ ì¤ë¥ê° ë°ìíìµëë¤. ì°ê¸° ê¸ì§ íì¼ì´ê±°ë ë¤ë¥¸ íë¡ê·¸ë¨ìì ì¬ì© ì¤ì¸ íì¼ì¸ì§ íì¸íììì¤.
+clearall_warning=íí° ëª©ë¡ìì 모ë ì¬ì©ì íí°ë¥¼ ì ê±°íìê² ìµëê¹?
+resethitcounts_warning=íí° ì ì© íì를 ì´ê¸°ííìê² ìµëê¹? ì´ ê¸°ë¥ì ëë릴 ì ììµëë¤!
+resethitcounts_selected_warning=ì íí íí°ì ì ì© íì를 ì´ê¸°ííìê² ìµëê¹? ì´ ê¸°ë¥ì ëë릴 ì ììµëë¤!
+filter_regexp_tooltip=ì´ íí°ë ì ê· ííìì´ê±°ë ìµì íí기ì 길ì´ê° ë무 ì§§ì¼ë¯ë¡ ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ì íë©ëë¤.
+filter_elemhide_duplicate_id=ì¨ê¸°ë ¤ë ììì IDë í ê°ë§ ì§ì í ì ììµëë¤.
+filter_elemhide_nocriteria=ì¨ê¸°ë ¤ë ìì를 ì¸ìí기 ìí 기ì¤ì´ ì§ì ëì§ ìììµëë¤.
+subscription_notAdded_warning=구ë
íí°ë¥¼ ì¶ê°íì§ ìììµëë¤. 구ë
íí°ê° ìì¼ë©´ íí°ë¥¼ ì§ì ì¶ê°í´ì¼ í©ëë¤.
+subscription_notAdded_warning_addendum=ê³ì ì§ííìê² ìµëê¹?
+subscription_invalid_location=구ë
íí°ì ìì¹ì ì
ë ¥íë URL ëë íì¼ëª
ì´ ì¬ë°ë¥´ì§ ììµëë¤.
+synchronize_invalid_url=ì¤í¨í¨ : ì¬ë°ë¥´ì§ ìì 주ì
+synchronize_connection_error=ì¤í¨í¨ : ë¤ì´ë¡ë ì¤í¨
+synchronize_invalid_data=ì¤í¨í¨ : ì¬ë°ë¥´ì§ ìì íí°
+synchronize_checksum_mismatch=ì¤í¨í¨ : ê²ì¬í© ë¶ì¼ì¹
+synchronize_ok=ë기í ì±ê³µ
+overwrite=ë®ì´ì°ê¸°
+append=ì¶ê°
+new_filter_group_title=ì íí°
+type_label_other=기í
+type_label_script=ì¤í¬ë¦½í¸
+type_label_image=ì´ë¯¸ì§
+type_label_stylesheet=ì¤íì¼ìí¸
+type_label_object=ê°ì²´
+type_label_subdocument=íë ì
+type_label_document=문ì
+type_label_elemhide=ì¨ê²¨ì§ ìì
+type_label_xbl=XBL ë°ì¸ë©
+type_label_ping=ë§í¬ í
+type_label_xmlhttprequest=XML ìì²
+type_label_object_subrequest=ê°ì²´ íì ìì²
+type_label_dtd=DTD
+type_label_media=ì¤ëì¤/ë¹ëì¤
+type_label_font=ê¸ê¼´
+fennec_status_enabled=ì ëë¸ë¡ íë¬ì¤ ì¬ì©
+fennec_status_disabled=ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
+fennec_status_enabled_site=?1?ìì ì ëë¸ë¡ íë¬ì¤ ì¬ì©
+fennec_status_disabled_site=?1?ìì ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
+sync_engine_title=ì ëë¸ë¡ íë¬ì¤ ë°ì´í°
diff --git a/chrome/locale/ko/overlay.dtd b/chrome/adblockplus.jar!/locale/ko/overlay.dtd
similarity index 100%
rename from chrome/locale/ko/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ko/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/ko/sendReport.dtd b/chrome/adblockplus.jar!/locale/ko/sendReport.dtd
new file mode 100644
index 0000000..681a1a0
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ko/sendReport.dtd
@@ -0,0 +1,75 @@
+<!ENTITY wizard.title "문ì ë³´ê³ ë§ë²ì¬">
+<!ENTITY privacyPolicy.label "ê°ì¸ ì ë³´ ë³´í¸ ì ì±
">
+<!ENTITY dataCollector.heading "문ì ë³´ê³ ë§ë²ì¬ë¥¼ ì´ì©í´ì£¼ì
ì ê³ ë§ìµëë¤!">
+<!ENTITY dataCollector.description "íìí ìë£ë¥¼ ìì§íë ëì ì ìë§ ê¸°ë¤ë ¤ì£¼ììì¤.">
+<!ENTITY typeSelector.heading "문ì ì í ì í">
+<!ENTITY typeSelector.description "문ì ë³´ê³ ë§ë²ì¬ë ì ëë¸ë¡ íë¬ì¤ì 문ì 를 íí° ì ì§ììê² ë³´ê³ í기 ìí´ íìí ë¨ê³ë¥¼ ìë´í©ëë¤. 먼ì íì¬ íì´ì§ì 문ì ì íì ì ííììì¤.">
+<!ENTITY typeSelector.falsePositive.label "ì ëë¸ë¡ íë¬ì¤ê° ì½í
ì¸ ë¥¼ ê³¼ëíê² ì°¨ë¨í¨">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "ì¤ìí ì½í
ì¸ ëë½, ì¹ íì´ì§ê° ì못 íìë¨, ì¤ìë ë± ì°¨ë¨ ì¤ë¥ê° ìì¼ë©´ ì´ ìµì
ì ì ííììì¤. ì ëë¸ë¡ íë¬ì¤ì ì¬ì©ì ììë¡ ì¤ì§íì¬ ì ëë¸ë¡ íë¬ì¤ê° 문ì ì ìì¸ì¸ì§ 먼ì íì¸íììì¤.">
+<!ENTITY typeSelector.falseNegative.label "ì ëë¸ë¡ íë¬ì¤ê° ê´ê³ 를 ì°¨ë¨ ì í¨">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¬ì©í¨ìë ë¶êµ¬íê³ ê´ê³ ê° ë³´ì´ë©´ ì´ ìµì
ì ì ííììì¤.">
+<!ENTITY typeSelector.other.label "ë¤ë¥¸ 문ì ">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY typeSelector.other.description "íí° ë¬¸ì ê° ìë ì ëë¸ë¡ íë¬ì¤ ìì²´ì 문ì ë¡ ìì¬íë¤ë©´ ì´ ìµì
ì ì ííììì¤.">
+<!ENTITY showRecentReports.label "ìµê·¼ì ì ì¶í ë³´ê³ ì 보기">
+<!ENTITY recentReports.label "ìµê·¼ì ì ì¶í ë³´ê³ ì">
+<!ENTITY recentReports.clear.label "모ë ë³´ê³ ì ì ê±°">
+<!ENTITY recentReports.clear.accesskey "R">
+<!ENTITY issues.description "ì´ ë¬¸ì ì ìí¥ì ì¤ ì ìë ì¤ì ëë ìë£ ì¡°ì¬ë¥¼ ì´ë µê² íë ìì¸ì íì§íìµëë¤.">
+<!ENTITY issues.whitelist.description "íì¬ íì´ì§ì íì© íí°ë¥¼ ì ì©íì¬ ì½í
ì¸ ê° ì°¨ë¨ëì§ ìììµëë¤. íì¬ íì´ì§ì ì ì©ë íì© íí°ì ì¬ì©ì ì¤ì§í ìíìì ì¹ íì´ì§ë¥¼ ë¤ì ë¶ë¬ì¤ììì¤.">
+<!ENTITY issues.whitelist.remove.label "ì¬ì´í¸/íì´ì§ íì© íí°ë¥¼ ì¬ì© ì¤ì§">
+<!ENTITY issues.disabled.description "ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¬ì©íì§ ìë ìíì´ë¯ë¡ ì무ê²ë ì°¨ë¨íì§ ììµëë¤.">
+<!ENTITY issues.disabled.enable.label "ì ëë¸ë¡ íë¬ì¤ ì¬ì©">
+<!ENTITY issues.nofilters.description "ì´ ë¬¸ì ë ì ëë¸ë¡ íë¬ì¤ê° ì무ê²ë ì°¨ë¨íì§ ìì ìíìì ë°ìí´ì ì ëë¸ë¡ íë¬ì¤ì ê´ë ¨ì´ ììµëë¤.">
+<!ENTITY issues.nosubscriptions.description "ì¹ ì¬ì´í¸ì ìíì§ ìë ê´ê³ 를 ìë ì°¨ë¨íë 구ë
íí°ë¥¼ ì¶ê°íì§ ìììµëë¤.">
+<!ENTITY issues.nosubscriptions.add.label "구ë
íí° ì¶ê°">
+<!ENTITY issues.subscriptionCount.description "ë무 ë§ì 구ë
íí°ë¥¼ 구ë
íê³ ììµëë¤. ì´ ì¤ì ì ë ë§ì 문ì 를 ë°ììí¬ ì ì기 ë문ì ê¶ì¥íì§ ììµëë¤. ëí íìí ì¡°ì¹ë¥¼ ì·¨í 구ë
íí° ì ì§ìê° ëª
ííì§ ì기 ë문ì ì´ ë¬¸ì ë³´ê³ ë¥¼ ë°ìë¤ì¼ ì ììµëë¤. ì¤ì ë¡ íìí 구ë
íí°ë¥¼ ì ì¸í 모ë 구ë
íí°ë¥¼ ì ê±°íê³ , ê·¸ë° íìë 문ì ê° ë°ìíëì§ë¥¼ í
ì¤í¸íììì¤.">
+<!ENTITY issues.openPreferences.label "íí° ì¤ì ì´ê¸°">
+<!ENTITY issues.ownfilters.description "íì¬ íì´ì§ì ì ì©ë íí°ì ì¼ë¶ë ì¬ì©ìê° ì§ì íìµëë¤. ì´ ë¬¸ì ì ìí¥ì ì¤ ì ìë ì¬ì©ì íí°ë ì¬ì©íì§ ë§ììì¤.">
+<!ENTITY issues.ownfilters.disable.label "íí° ì¬ì© ì¤ì§">
+<!ENTITY issues.disabledgroups.description "ë¤ì 구ë
íí°/íí° ê·¸ë£¹ì ì¬ì©íì§ ìì§ë§ ì´ íì´ì§ì ìí¥ì ì¤ ì ììµëë¤.">
+<!ENTITY issues.disabledgroups.enable.label "구ë
íí°/íí° ê·¸ë£¹ ì¬ì©">
+<!ENTITY issues.disabledfilters.description "ë¤ì íí°ë ì¬ì©íì§ ìì§ë§ íì¬ íì´ì§ì ìí¥ì ì¤ ì ììµëë¤.">
+<!ENTITY issues.disabledfilters.enable.label "íí° ì¬ì©">
+<!ENTITY issues.override.label "ì¤ì ìë ì´ìì´ ìì¼ë©°, ë³´ê³ ì ìì±ì ê³ì ì§íí¨">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY issues.change.description "ì¤ì ì´ ë³ê²½ëììµëë¤. ì¹ íì´ì§ë¥¼ ë¤ì ë¶ë¬ì¨ í 문ì ê° í´ê²°ëì§ ìëë¤ë©´ ë³´ê³ ì를 ì ì¶íììì¤.">
+<!ENTITY typeWarning.description "íí° ë¬¸ì ê° ìë ì ëë¸ë¡ íë¬ì¤ì ì¼ë°ì ì¸ ë¬¸ì ë [link]ì ëë¸ë¡ íë¬ì¤ í¬ë¼[/link]ì ë³´ê³ íë ê²ì´ ìµì ì±
ì
ëë¤. í¬ë¼ìì ì´ë¯¸ ë
¼ìë 문ì 를 ë³´ì¶©í기 ìí´ ë¬¸ì ë³´ê³ ë§ë²ì¬ë¥¼ ì´ì©í´ì¼ í©ëë¤. ë³´ê³ ì를 íì¸í ì ìë ë§í¬ë¥¼ ì ê³µíì§ ìì¼ë©´ ì무ë ë³´ê³ ë¥¼ íì¸í ì ì기 ë문ì
ëë¤. ë³´ê³ ì를 ì ì¶íë©´ ìëì¼ë¡ ìì±ë ë§í¬ê° ì ê³µë©ëë¤.">
+<!ENTITY typeWarning.override.label "ìì ë´ì©ì ì´í´íì¼ë©°, ë³´ê³ ì ìì±ì ê³ì ì§íí¨">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "íì´ì§ ìë¡ê³ 침">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "íë©´ê°ë¬´ë¦¬ 첨ë¶">
+<!ENTITY screenshot.description "문ì ë³´ê³ ìì íë©´ê°ë¬´ë¦¬ë¥¼ 첨ë¶íë©´ 문ì 를 ì´í´íëë° ëìì´ ë©ëë¤. 문ì ììì ë¶ê°í기 ìí´ íì´ì§ ì´ë¯¸ì§ì íì를 íê³ , 민ê°í ì ë³´ ììì ì¨ê¸¸ ì ììµëë¤. ìíë ë²í¼ì ëë¥´ê³ , ì´ë¯¸ì§ì ë§ì°ì¤ë¡ ììì íìíììì¤.">
+<!ENTITY screenshot.attach.label "ë³´ê³ ìì íì´ì§ ì´ë¯¸ì§ 첨ë¶">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY screenshot.mark.label "문ì ìì íì">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "민ê°í ìì ì¨ê¹">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY screenshot.undo.label "ëë리기">
+<!ENTITY screenshot.undo.accesskey "U">
+<!ENTITY commentPage.heading "ë³´ê³ ë´ì© ì
ë ¥">
+<!ENTITY commentPage.description "ë°ëì 주ì ì
ë ¥ì¤ì ì¹ íì´ì§ 주ì(URL)ì íí° ë¬¸ì ì ì¤ëª
ì ë³´ê³ ë´ì©ì ì
ë ¥íììì¤. ì´ ìê±´ì ê°ì¶ì§ ìì 문ì ë³´ê³ ìë ì ìì ì¼ë¡ ì²ë¦¬ëì§ ìì ì ììµëë¤.">
+<!ENTITY comment.label "ë³´ê³ ë´ì© (íì í목 - ì¹ íì´ì§ 주ì + íí° ë¬¸ì ì¤ëª
) :">
+<!ENTITY comment.accesskey "C">
+<!ENTITY comment.lengthWarning "ì¤ëª
ì 길ì´ê° 1000ì를 ì´ê³¼íì¬ 1000ìê¹ì§ë§ ì ì¡ë©ëë¤.">
+<!ENTITY email.label "ì´ë©ì¼ 주ì (ì¶ê° 문ì ë° ì²ë¦¬ ìí íµë³´) :">
+<!ENTITY email.accesskey "m">
+<!ENTITY attachExtensions.label "ì¬ì©íê³ ìë ë¶ê° íë¡ê·¸ë¨ 목ë¡ì ë³´ê³ ìì ì¶ê° (ë¤ë¥¸ ë¶ê° íë¡ê·¸ë¨ê³¼ ì¶©ëì´ ìì¸ì¸ ê²½ì°)">
+<!ENTITY attachExtensions.accesskey "x">
+<!ENTITY sendButton.label "ë³´ê³ ì ì ì¡">
+<!ENTITY sendButton.accesskey "n">
+<!ENTITY showData.label "ë³´ê³ í ìë£ ë³´ê¸°">
+<!ENTITY data.label "ë³´ê³ í ìë£">
+<!ENTITY data.accesskey "p">
+<!ENTITY sendPage.heading "ë³´ê³ ì ì ì¡">
+<!ENTITY sendPage.waitMessage "ë³´ê³ ì를 ì ì¶íë ëì ì ìë§ ê¸°ë¤ë ¤ì£¼ììì¤.">
+<!ENTITY sendPage.confirmation "ë³´ê³ ìê° ìë²ì ì ì¥ëìê³ , ë¤ì 주ìë¡ ë³´ê³ ì를 íì¸í ì ììµëë¤. íí° ì ì§ìê° ë³´ê³ ë¥¼ ì ìíë©´ ë³´ê³ ìì Status í목ìë unknown ëì ì ì²ë¦¬ ê²°ê³¼ê° íìë©ëë¤.">
+<!ENTITY sendPage.knownIssue "ë³´ê³ í 문ì ë ë¤ë¥¸ ì¬ì©ìë¤ì ìí´ ì´ë¯¸ ë§ì´ ë³´ê³ ëììµëë¤. ë ë§ì ì ë³´ :">
+<!ENTITY sendPage.errorMessage "ì¤ë¥ ì½ë "?1?"ì ìí´ ë³´ê³ ì ì¡ì ì¤í¨íìµëë¤. ì¸í°ë·ì´ ì ìëìëì§ íì¸í í ë¤ì ìëíììì¤. ë§ì½ 문ì ê° ê³ìí´ì ë°ìíë¤ë©´ [link]ì ëë¸ë¡ íë¬ì¤ í¬ë¼[/link]ì ëìì ìì²íììì¤.">
+<!ENTITY sendPage.retry.label "ë¤ì ì ì¡">
+<!ENTITY copyLink.label "ë³´ê³ ë§í¬ ë³µì¬">
+<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/ko/settings.dtd b/chrome/adblockplus.jar!/locale/ko/settings.dtd
similarity index 100%
rename from chrome/locale/ko/settings.dtd
rename to chrome/adblockplus.jar!/locale/ko/settings.dtd
diff --git a/chrome/adblockplus.jar!/locale/ko/sidebar.dtd b/chrome/adblockplus.jar!/locale/ko/sidebar.dtd
new file mode 100644
index 0000000..ccb8c66
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ko/sidebar.dtd
@@ -0,0 +1,35 @@
+<!ENTITY detached.title "ì°¨ë¨ ê°ë¥ ëª©ë¡ (ë¶ë¦¬ë¨)">
+<!ENTITY detach.label "ë¶ë¦¬">
+<!ENTITY reattach.label "íµí©">
+<!ENTITY search.label "ê²ì (S)">
+<!ENTITY search.accesskey "S">
+<!ENTITY type.label "íì">
+<!ENTITY address.label "주ì">
+<!ENTITY filter.label "íí°">
+<!ENTITY state.label "ìí">
+<!ENTITY size.label "í¬ê¸°">
+<!ENTITY docDomain.label "문ì ìì¹">
+<!ENTITY docDomain.thirdParty "(ì¸ë¶ ìì²)">
+<!ENTITY docDomain.firstParty "(ë´ë¶ ìì²)">
+<!ENTITY noitems.label "ì°¨ë¨ ê°ë¥í í목 ìì">
+<!ENTITY whitelisted.label "íì©ë íì´ì§">
+<!ENTITY tooltip.address.label "주ì :">
+<!ENTITY tooltip.type.label "íì :">
+<!ENTITY tooltip.type.blocked "(ì°¨ë¨ë¨)">
+<!ENTITY tooltip.type.whitelisted "(íì©ë¨)">
+<!ENTITY tooltip.size.label "í¬ê¸° :">
+<!ENTITY tooltip.docDomain.label "문ì ìì¹ :">
+<!ENTITY tooltip.filter.label "íí° :">
+<!ENTITY tooltip.filter.disabled "(ì¬ì© ì¤ì§)">
+<!ENTITY tooltip.filterSource.label "íí° ê·¸ë£¹ :">
+<!ENTITY context.block.label "ì°¨ë¨ íí° ì¶ê°">
+<!ENTITY context.editfilter.label "íí° í¸ì§">
+<!ENTITY context.whitelist.label "íì© íí° ì¶ê°">
+<!ENTITY context.disablefilter.label "íí° ì¬ì© ì¤ì§ : ?1?">
+<!ENTITY context.enablefilter.label "íí° ë¤ì ì¬ì© : ?1?">
+<!ENTITY context.disablefilteronsite.label "ì§ì ë ëë©ì¸ìë§ ì ì© ì¤ì§ : ?1?">
+<!ENTITY context.open.label "ì íì¼ë¡ ì´ê¸°">
+<!ENTITY context.flash.label "í목 ìì¹ íì¸">
+<!ENTITY context.copy.label "주ì ë³µì¬">
+<!ENTITY context.copyFilter.label "íí° ë³µì¬">
+<!ENTITY context.selectAll.label "모ë ì í">
diff --git a/chrome/locale/ko/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ko/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ko/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ko/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/lv/about.dtd b/chrome/adblockplus.jar!/locale/lv/about.dtd
new file mode 100644
index 0000000..37d1b4d
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/about.dtd
@@ -0,0 +1,10 @@
+<!ENTITY dialog.title "Par Adblock Plus">
+<!ENTITY version.title "Versija">
+<!ENTITY description "Adblock Plus ļauj Jums izlemt, ko JÅ«s vÄlaties redzÄt internetÄ.
+ Jums vairs nevajag lejupielÄdÄt reklÄmas un banerus; ja jÅ«s tos
+ nevÄlaties - noÅemiet tos ar Adblock Plus!">
+<!ENTITY homepage.label "Adblock Plus mÄjas lapa:">
+<!ENTITY author.label "Autors:">
+<!ENTITY contributors.label "IeguldÄ«tÄji:">
+<!ENTITY subscriptionAuthors.label "Filtru abonementu autori:">
+<!ENTITY translators.label "TulkotÄji:">
diff --git a/chrome/adblockplus.jar!/locale/lv/composer.dtd b/chrome/adblockplus.jar!/locale/lv/composer.dtd
new file mode 100644
index 0000000..91a5640
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/composer.dtd
@@ -0,0 +1,47 @@
+<!ENTITY dialog.title "Pievienot Adblock Plus filtra noteikumu">
+<!ENTITY accept.label "Pievienot filtru">
+<!ENTITY advanced.label "Uzlabotais skats">
+<!ENTITY basic.label "Pamata skats">
+<!ENTITY disabled.warning "Adblock Plus Å¡obrÄ«d ir atspÄjots. JÅ«s joprojÄm varat pievienot filtrus, bet tie netiks pielietoti, ja vien JÅ«s [link]neiespÄjosiet Adblock Plus[/link].">
+<!ENTITY groupDisabled.warning "Filtru grupa "?1?", kurai tiks pievienots Å¡is filtrs paÅ¡laik ir atspÄjota.JÅ«s joprojÄm varat pievienot filtrus, bet tie netiks pielietoti, ja vien JÅ«s [link]neiespÄjosiet filtru grupu[/link].">
+<!ENTITY filter.label "Jauns filtrs:">
+<!ENTITY filter.accesskey "f">
+<!ENTITY preferences.label "RÄdÄ«t esoÅ¡os filtrus...">
+<!ENTITY preferences.accesskey "e">
+<!ENTITY type.filter.label "BloÄ·ÄjoÅ¡ais filtrs">
+<!ENTITY type.filter.accesskey "B">
+<!ENTITY type.whitelist.label "IzÅÄmuma noteikums">
+<!ENTITY type.whitelist.accesskey "z">
+<!ENTITY pattern.label "MeklÄt shÄmu">
+<!ENTITY pattern.explanation "ShÄma var bÅ«t jebkurÄ adreses daļÄ; zvaigznÄ«tes (*) funkcionÄ kÄ aizstÄjÄjzÄ«mes. Filtrs tiks pielietots tikai adresÄm, kas atbilst shÄmai.">
+<!ENTITY regexp.warning "JÅ«su ievadÄ«tÄ shÄma tiks interpretÄta kÄ regulÄrÄ izteiksme, kuru Adblock Plus nevar veiksmÄ«gi apstrÄdÄt un tÄ var palÄninÄt JÅ«su pÄrlÅ«koÅ¡anas pieredzi. Ja JÅ«s nevÄlÄjÄties izmantot regulÄro izteiksme, pievienojiet zvaigznÄ«ti (*) shÄmas galÄ.">
+<!ENTITY shortpattern.warning "JÅ«su ievadÄ«tÄ shÄma ir pÄrÄk Ä«sa, lai tiktu optimizÄta un tÄ var palÄninÄt JÅ«su pÄrlÅ«koÅ¡anas pieredzi. Tiek rekomendÄts izvÄlÄties garÄku rindu Å¡im filtram, lai Adblock Plus varÄtu to efektÄ«vÄk apstrÄdÄt.">
+<!ENTITY match.warning "JÅ«su ievadÄ«tÄ shÄma vairs neatbilst bloÄ·Äjamai/baltÄ saraksta adresei un tai uz to nebÅ«s efekta.">
+<!ENTITY custom.pattern.label "PielÄgots:">
+<!ENTITY custom.pattern.accesskey "P">
+<!ENTITY anchors.label "AkceptÄt tikai shÄmu:">
+<!ENTITY anchor.start.label "adreses sÄkumÄ">
+<!ENTITY anchor.start.accesskey "s">
+<!ENTITY anchor.start.flexible.label "domÄna vÄrda sÄkumÄ">
+<!ENTITY anchor.start.flexible.accesskey "s">
+<!ENTITY anchor.end.label "adreses beigÄs">
+<!ENTITY anchor.end.accesskey "d">
+<!ENTITY options.label "Opcijas">
+<!ENTITY domainRestriction.label "Ierobežot domÄnÄ:">
+<!ENTITY domainRestriction.accesskey "I">
+<!ENTITY domainRestriction.help "Izmantojiet Å¡o iespÄju, lai norÄdÄ«tu vienu vai vairÄkus domÄnus atdalÄ«tus ar joslu lÄ«niju (|). Filtrs tiks pielietots tikai norÄdÄ«tajiem domÄniem. Tilde (~) pirms domÄna norÄda, ka filtrs netiks pielietots uz Å¡o domÄnu.">
+<!ENTITY firstParty.label "tikai pirmÄs-puses">
+<!ENTITY firstParty.accesskey "u">
+<!ENTITY thirdParty.label "tikai treÅ¡Äs-puses">
+<!ENTITY thirdParty.accesskey "t">
+<!ENTITY matchCase.label "Reģistr-jutīgs">
+<!ENTITY matchCase.accesskey "R">
+<!ENTITY types.label "Pielietot tipiem:">
+<!ENTITY selectAllTypes.label "IezÄ«mÄt visu">
+<!ENTITY unselectAllTypes.label "NeiezÄ«mÄt neko">
+<!ENTITY collapse.label "Sakļaut bloÄ·Ätos:">
+<!ENTITY collapse.accesskey "l">
+<!ENTITY collapse.default.yes.label "Izmantot noklusÄjumu (jÄ)">
+<!ENTITY collapse.default.no.label "Izmantot noklusÄjumu (nÄ)">
+<!ENTITY collapse.yes.label "JÄ">
+<!ENTITY collapse.no.label "NÄ">
diff --git a/chrome/adblockplus.jar!/locale/lv/global.properties b/chrome/adblockplus.jar!/locale/lv/global.properties
new file mode 100644
index 0000000..b6844fc
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=Noklikšķiniet, lai parÄdÄ«tu konteksta izvÄlni, vidÄjais klikšķis, lai aktivizÄtu/deaktivizÄtu.
+action1_tooltip=Noklikšķiniet, lai atvÄrtu aizvÄrtu bloÄ·ÄjamÄs vienÄ«bas, vidÄjais klikšķis, lai aktivizÄtu/deaktivizÄtu.
+action2_tooltip=Noklikšķiniet, lai atvÄrtu iestatÄ«jumus, vidÄjais klikšķis, lai aktivizÄtu/deaktivizÄtu.
+action3_tooltip=Noklikšķiniet, lai aktivizÄtu/deaktivizÄtu Adblock Plus.
+disabled_tooltip=Adblock Plus ir deaktivizÄts.
+active_tooltip=Adblock Plus ir aktivizÄts, ?1? filtru abonementi un ?2? pielÄgotie filtri tiek izmantoti.
+whitelisted_tooltip=PaÅ¡reizÄjÄ lapÄ Adblock Plus ir deaktivizÄts.
+blocked_count_tooltip=?1? no ?2?
+blocked_count_addendum=(arÄ«, baltajÄ sarakstÄ: ?1?, slÄpti: ?2?)
+no_blocking_suggestions=PaÅ¡reizÄjÄ lapÄ nav bloÄ·Äjamu vienÄ«bu
+whitelisted_page=PaÅ¡reizÄjÄ lapÄ Adblock Plus ir ticis deaktivizÄts.
+whitelist_description=Mani izÅÄmumu noteikumi
+filterlist_description=Mani reklÄmu bloÄ·ÄÅ¡anas noteikumi
+invalid_description=Mani nederīgie noteikumi
+elemhide_description=Mani elementu slÄpÅ¡anas noteikumi
+subscription_description=Filtru abonements
+subscription_wrong_version=Lai pareizi darbotos, dažiem filtriem Å¡ajÄ abonementÄ nepiecieÅ¡ams Adblock Plus ?1?.
+subscription_source=Avots:
+subscription_status=Statuss:
+subscription_status_autodownload=AutomÄtiski atjauninÄts
+subscription_status_manualdownload=ManuÄli atjauninÄts
+subscription_status_externaldownload=AtjauninÄts ÄrÄji (cits papildinÄjums)
+subscription_status_lastdownload=PÄdÄjÄ lejupielÄde:
+subscription_status_lastdownload_inprogress=LejupielÄdÄ...
+subscription_status_lastdownload_unknown=N/A
+remove_subscription_warning=Vai JÅ«s tieÅ¡Äm vÄlaties noÅemt Å¡o abonementu?
+import_filters_wrong_version=BrÄ«dinÄjums: lai pareizi darbotos, dažiem filtriem Å¡ajÄ sarakstÄ nepiecieÅ¡ams Adblock Plus ?1?. Jums vajadzÄtu atjauninÄt uz jaunÄku Adblock Plus versiju pirms šī saraksta importÄÅ¡anas.
+import_filters_warning=Vai JÅ«s vÄlaties aizvietot JÅ«su paÅ¡reizÄjos filtrus vai pievienot jaunos filtrus saraksta galÄ?
+import_filters_title=ImportÄt filtrus
+export_filters_title=EksportÄt filtrus
+invalid_filters_file=Nav derīgs Adblock Plus filtru fails.
+filters_write_error=Rakstot filtrus failÄ radÄ kļūda. PÄrliecinieties, ka fails nav aizsargÄts pret rakstīšanu vai atvÄrts citÄ programmÄ.
+clearall_warning=Vai JÅ«s tieÅ¡Äm vÄlaties noÅemt visus filtrus no saraksta?
+resethitcounts_warning=Vai JÅ«s tieÅ¡Äm vÄlaties atiestatÄ«t trÄpÄ«jumu skaitu atpakaļ uz nulli? PiezÄ«me: šī operÄcija nevar tik atsaukta.
+resethitcounts_selected_warning=Vai JÅ«s tieÅ¡Äm vÄlaties atiestatÄ«t trÄpÄ«jumu skaitu izvÄlÄtajiem filtriem atpakaļ uz nulli? PiezÄ«me: šī operÄcija nevar tik atsaukta.
+filter_regexp_tooltip=Å is filtrs ir vai nu regulÄrÄ izteiksme vai arÄ« pÄrÄk Ä«ss, lai tiktu optimizÄts. PÄrÄk daudz Å¡Ädu filtru var palÄninÄt JÅ«su parlÅ«koÅ¡anu.
+filter_elemhide_duplicate_id=Tikai viens paslÄpjamÄ elementa ID drÄ«kst tikt norÄdÄ«ts.
+filter_elemhide_nocriteria=Elementa paslÄpÅ¡anai nav norÄdÄ«ts neviens kritÄrijs
+subscription_notAdded_warning=JÅ«s nepievienojÄt filtru abonementu. Bez filtru abonementa Jums vajadzÄs pievienot manuÄli pievienot Adblock Plus filtrus.
+subscription_notAdded_warning_addendum=Vai vÄlaties turpinÄt?
+subscription_invalid_location=Filtru saraksta atraÅ¡anÄs vieta nav ne derÄ«gs URL ne arÄ« derÄ«gs faila nosaukums.
+synchronize_invalid_url=NeizdevÄs, nav derÄ«ga adrese
+synchronize_connection_error=NeizdevÄs, lejupielÄde neizdevÄs
+synchronize_invalid_data=NeizdevÄs, nav derÄ«gs filtru saraksts
+synchronize_checksum_mismatch=NeizdevÄs, kontrolsummas neatbilstÄ«ba
+synchronize_ok=IzdevÄs
+overwrite=PÄrrakstÄ«t
+append=Pievienot
+new_filter_group_title=Jauns filtrs
+type_label_other=cits
+type_label_script=skripts
+type_label_image=attÄls
+type_label_stylesheet=stila lapa
+type_label_object=objekts
+type_label_subdocument=rÄmis
+type_label_document=dokuments
+type_label_elemhide=paslÄpts
+type_label_xbl=XBL sasaiste
+type_label_ping=saites ping
+type_label_xmlhttprequest=XML pieprasījums
+type_label_object_subrequest=objekta apakš-pieprasījums
+type_label_dtd=DTD
+type_label_media=audio/video
+type_label_font=fonts
+fennec_status_enabled=Adblock Plus ir iespÄjots.
+fennec_status_disabled=Adblock Plus ir atspÄjots.
+fennec_status_enabled_site=Adblock Plus ir iespÄjots uz ?1?.
+fennec_status_disabled_site=Adblock Plus ir atspÄjots uz ?1?.
+sync_engine_title=Adblock Plus dati
diff --git a/chrome/adblockplus.jar!/locale/lv/overlay.dtd b/chrome/adblockplus.jar!/locale/lv/overlay.dtd
new file mode 100644
index 0000000..0cd24fd
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "Statuss:">
+<!ENTITY blocked.tooltip "BloÄ·ÄtÄs vienÄ«bas Å¡ajÄ lapÄ:">
+<!ENTITY filters.tooltip "VisaktÄ«vÄkie filtri:">
+<!ENTITY menuitem.label "Adblock Plus Iestatījumi">
+<!ENTITY menuitem.accesskey "b">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: BloÄ·ÄjamÄs vienÄ«bas">
+<!ENTITY context.image.label "Adblock Plus: BloÄ·Ät attÄlu">
+<!ENTITY context.object.label "Adblock Plus: BloÄ·Ät objektu">
+<!ENTITY context.frame.label "Adblock Plus: BloÄ·Ät rÄmi">
+<!ENTITY context.media.label "Adblock Plus: BloÄ·Ät audio/video">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: IespÄjot Å¡ajÄ lapÄ">
+<!ENTITY sidebar.title "BloÄ·ÄjamÄs vienÄ«bas Å¡ajÄ lapÄ">
+<!ENTITY sendReport.label "Iesniegt ziÅojumu par Å¡o lapu">
+<!ENTITY sendReport.accesskey "z">
+<!ENTITY settings.label "Iestatījumi">
+<!ENTITY settings.accesskey "t">
+<!ENTITY opensidebar.label "AtvÄrt bloÄ·ÄjamÄs vienÄ«bas">
+<!ENTITY opensidebar.accesskey "b">
+<!ENTITY closesidebar.label "AizvÄrt bloÄ·ÄjamÄs vienÄ«bas">
+<!ENTITY closesidebar.accesskey "b">
+<!ENTITY whitelist.site.label "AtspÄjot uz ?1?">
+<!ENTITY whitelist.page.label "AtspÄjot tikai Å¡ajÄ lapÄ">
+<!ENTITY disable.label "AtspÄjot visur">
+<!ENTITY recommend.label "RekomendÄt mÅ«s Facebook">
+<!ENTITY objecttab.title "BloÄ·Ät">
+<!ENTITY objecttab.tooltip "Klikšķini Å¡eit, lai bloÄ·Ätu Å¡o objektu ar Adblock Plus">
diff --git a/chrome/adblockplus.jar!/locale/lv/sendReport.dtd b/chrome/adblockplus.jar!/locale/lv/sendReport.dtd
new file mode 100644
index 0000000..5e95544
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/sendReport.dtd
@@ -0,0 +1,76 @@
+<!ENTITY wizard.title "ProblÄmu ziÅotÄjs">
+<!ENTITY privacyPolicy.label "PrivÄtuma politika">
+<!ENTITY dataCollector.heading "Laipni lÅ«dzu problÄmu ziÅotÄjÄ">
+<!ENTITY dataCollector.description "Uzgaidiet pÄris mirkļus, kamÄr Adblock Plus apkopo nepiecieÅ¡amos datus.">
+<!ENTITY typeSelector.heading "IzvÄlieties problÄmas tipu">
+<!ENTITY typeSelector.description "Å is log JÅ«s vedÄ«s cauri nepiecieÅ¡amajiem soļiem, lai nosÅ«tÄ«tu Adblock Plus problÄmu ziÅojumu. Vispirms, lÅ«dzu izvÄlieties tipu problÄmai, ko JÅ«s pieredzat Å¡ajÄ lapÄ:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus bloÄ·Ä pÄrÄk daudz">
+<!ENTITY typeSelector.falsePositive.accesskey "d">
+<!ENTITY typeSelector.falsePositive.description "IzvÄlaties Å¡o opciju, ja lai trÅ«kst svarÄ«ga saturam tÄ tiek nepareizi attÄlota vai nefunkcionÄ pareizi. JÅ«s varat noteikt vai to izraisa Adblock Plus, to
+Ä«slaicÄ«gi atslÄdzot.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus nebloÄ·Ä reklÄmu">
+<!ENTITY typeSelector.falseNegative.accesskey "r">
+<!ENTITY typeSelector.falseNegative.description "IzvÄlaties Å¡o opciju ja reklÄma tiek attÄlota neskatoties uz to ka Adblock Plus ir ieslÄgts.">
+<!ENTITY typeSelector.other.label "Cita problÄma">
+<!ENTITY typeSelector.other.accesskey "c">
+<!ENTITY typeSelector.other.description "IzvÄlaties Å¡o opciju ja JÅ«s nojauÅ¡at problÄmu ar paÅ¡u Adblock Plus nevis tÄ filtriem.">
+<!ENTITY showRecentReports.label "ParÄdÄ«t nesen nosÅ«tÄ«tos ziÅojumus">
+<!ENTITY recentReports.label "JÅ«su nesen nosÅ«tÄ«tie ziÅojumi">
+<!ENTITY recentReports.clear.label "NoÅemt visus ziÅojumus">
+<!ENTITY recentReports.clear.accesskey "N">
+<!ENTITY issues.description "Adblock Plus ir atradis problÄmu JÅ«su konfigurÄcijÄ, kas varÄtu bÅ«t atbildÄ«ga par Å¡o problÄmu vai arÄ« apgrÅ«tinÄs ziÅojuma izmeklÄÅ¡anu.">
+<!ENTITY issues.whitelist.description "Adblock Plus paÅ¡reiz ir atslÄgt lapÄ par kuru JÅ«s ziÅojat. Lai palÄ«dzÄtu problÄmas izmeklÄÅ¡anÄ, pirms ziÅojuma sÅ«tīšanas lÅ«dzu ieslÄdziet to un atsvaidziniet lapu.">
+<!ENTITY issues.whitelist.remove.label "IespÄjot Adblock Plus Å¡ajÄ lapÄ">
+<!ENTITY issues.disabled.description "Adblock Plus ir atspÄjots, paÅ¡reizÄjÄ stÄvoklÄ« tas nebloÄ·Äs neko.">
+<!ENTITY issues.disabled.enable.label "IespÄjot Adblock Plus">
+<!ENTITY issues.nofilters.description "PaÅ¡reizÄjÄ lapÄ Adblock Plus neko nebloÄ·Ä. ProblÄma, ko JÅ«s pieredzat visticamÄk ir nesaistÄ«ta ar Adblock Plus.">
+<!ENTITY issues.nosubscriptions.description "IzskatÄs, ka JÅ«s neabonÄjat nevienu no gatavajiem sarakstiem, kuri automÄtiski noÅem nevajadzÄ«go saturu no mÄjas lapÄm.">
+<!ENTITY issues.nosubscriptions.add.label "Pievienot filtru abonementu">
+<!ENTITY issues.subscriptionCount.description "IzskatÄs, ka JÅ«s abonÄjat pÄrÄk daudz abonementu. Å Äda konfigurÄcija netiek rekomendÄta, jo tas palielina problÄmu iespÄjamÄ«bu. MÄs nespÄjam pieÅemt ziÅojumu, jo nav skaidrs kuram filtru abonementam ir jÄrÄ«kojas. LÅ«dzu noÅemiet visu izÅemot tieÅ¡Äm nepiecieÅ¡amos abonementus un pÄrbaudiet vai problÄma joprojÄm pastÄv.">
+<!ENTITY issues.openPreferences.label "AtvÄrt filtru iestatÄ«jumus">
+<!ENTITY issues.ownfilters.description "Daži no Å¡ajÄ lapÄ pielietotajiem filtriem ir lietotÄja izveidoti. LÅ«dzu atslÄdziet filtrus, kas varÄja izraisÄ«t Å¡o problÄmu:">
+<!ENTITY issues.ownfilters.disable.label "AtspÄjot filtru">
+<!ENTITY issues.disabledgroups.description "SekojoÅ¡ie filtru abonementi / filtru grupas ir atslÄgti, tomÄr tiem ir ietekme uz Å¡o lapu:">
+<!ENTITY issues.disabledgroups.enable.label "Ievadīt filtru abonementu / filtru grupu">
+<!ENTITY issues.disabledfilters.description "SekojoÅ¡ie filtri ir atslÄgt, tomÄr tiem var bÅ«t ietekme uz Å¡o lapu:">
+<!ENTITY issues.disabledfilters.enable.label "IespÄjot filtru">
+<!ENTITY issues.override.label "KonfigurÄcija ir pareiza, varat turpinÄt ziÅojumu">
+<!ENTITY issues.override.accesskey "K">
+<!ENTITY issues.change.description "JÅ«su konfigurÄcija ir izmanÄ«ta. LÅ«dzu pÄrlÄdÄjiet lapu, lai pÄrbaudÄ«tu izmaiÅas un nosÅ«tÄ«tu ziÅojumu, ja izmaiÅas nav novÄrsuÅ¡as problÄmu.">
+<!ENTITY typeWarning.description "JÅ«s norÄdÄ«jÄt, ka vÄlaties ziÅot par vispÄrÄju Adblock Plus problÄmu nevis problÄmu ar filtriem. Par Å¡ÄdÄm problÄmÄm vislabÄk ir paziÅot [link]Adblock Plus forumÄ[/link]. Å o problÄmu ziÅotÄju vajadzÄtu izmantot tikai lai papildinÄtu esoÅ¡u diskusiju, jo neviens neredzÄs JÅ«su ziÅojumu, ja JÅ«s nenodroÅ¡inÄs viÅus ar saiti uz to. AutomÄtiski Ä£enerÄtÄ saite tiks nodroÅ¡inÄta pÄc ziÅojuma nosÅ«tīšanas.">
+<!ENTITY typeWarning.override.label "Es saprotu un vienalga vÄlos nosÅ«tÄ«t ziÅojumu">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "PÄrlÄdÄt lapu">
+<!ENTITY reloadButton.accesskey "l">
+<!ENTITY screenshot.heading "Pievienojiet ekrÄn-Å¡ÄviÅu">
+<!ENTITY screenshot.description "TÄ pati lapa var izskatÄ«ties atšķirÄ«gi dažÄdiem cilvÄkiem. Ja JÅ«s pievienosiet ekrÄn-Å¡ÄviÅu, tas mums palÄ«dzÄs izprast problÄmu. JÅ«s varat noÅemt apgabalus, kas satur jÅ«tÄ«gu informÄciju kÄ arÄ« iezÄ«mÄt vietas, kur ir redzama problÄma. Lai to izdarÄ«tu, noklikšķiniet uz atbilstoÅ¡Äs pogas un izvÄlieties apgabalu ar peli.">
+<!ENTITY screenshot.attach.label "Pievienot ziÅojumam lapas attÄlu">
+<!ENTITY screenshot.attach.accesskey "P">
+<!ENTITY screenshot.mark.label "IezÄ«mÄt problÄmu">
+<!ENTITY screenshot.mark.accesskey "z">
+<!ENTITY screenshot.remove.label "NoÅemt jÅ«tÄ«gu informÄciju">
+<!ENTITY screenshot.remove.accesskey "N">
+<!ENTITY screenshot.undo.label "Atsaukt">
+<!ENTITY screenshot.undo.accesskey "u">
+<!ENTITY commentPage.heading "Pievienojiet komentÄru">
+<!ENTITY commentPage.description "Teksta laukums ļauj Jums ierakstÄ«t komentÄru, lai palÄ«dzÄtu mums saprast problÄmu. Å is solis nav obligÄts, bet ir rekomendÄts, ja problÄma nav acÄ«mredzama. JÅ«s arÄ« varat pÄrskatÄ«t ziÅojuma datus, pirms nosÅ«tīšanas.">
+<!ENTITY comment.label "KomentÄrs (nav obligÄti):">
+<!ENTITY comment.accesskey "K">
+<!ENTITY comment.lengthWarning "JÅ«su komentÄra garums pÄrsniedz 1000 simbolus. Tikai pirmie 1000 simboli tiks nosÅ«tÄ«ti.">
+<!ENTITY email.label "E-pasts turpmÄkai izziÅai (nav obligÄti):">
+<!ENTITY email.accesskey "p">
+<!ENTITY attachExtensions.label "Pievienot ziÅojumam sarakstu ar aktÄ«viem papildinÄjumiem, gadÄ«jumÄ, ja kÄds papildinÄjums izraisa problÄmu">
+<!ENTITY attachExtensions.accesskey "d">
+<!ENTITY sendButton.label "SÅ«tÄ«t ziÅojumu">
+<!ENTITY sendButton.accesskey "S">
+<!ENTITY showData.label "RÄdÄ«t ziÅojuma datus">
+<!ENTITY data.label "ZiÅojuma dati:">
+<!ENTITY data.accesskey "Z">
+<!ENTITY sendPage.heading "SÅ«tÄ«t ziÅojumu">
+<!ENTITY sendPage.waitMessage "LÅ«dzu uzgaidiet kamÄr Adblock Plus sÅ«ta JÅ«su ziÅojumu.">
+<!ENTITY sendPage.confirmation "JÅ«su ziÅojums ir saglabÄts. JÅ«s tam varat piekļūt sekojoÅ¡ajÄ adresÄ:">
+<!ENTITY sendPage.knownIssue "JÅ«su nosÅ«tÄ«tais problÄma iespÄjams jau ir zinÄma. VairÄk informÄcija:">
+<!ENTITY sendPage.errorMessage "MÄÄ£inÄjums sÅ«tÄ«t ziÅojumu neizdevÄs. Kļūdas kods "?1?". LÅ«dzu pÄrliecinieties, ka Jums ir savienojums ar internetu un mÄÄ£iniet vÄlreiz. Ja problÄma atkÄrtojas, lÅ«dzu prasiet palÄ«dzÄ«bu [link]Adblock Plus forumÄ[/link].">
+<!ENTITY sendPage.retry.label "SÅ«tÄ«t vÄlreiz">
+<!ENTITY copyLink.label "KopÄt ziÅojuma saiti">
+<!ENTITY copyLink.accesskey "K">
diff --git a/chrome/adblockplus.jar!/locale/lv/settings.dtd b/chrome/adblockplus.jar!/locale/lv/settings.dtd
new file mode 100644
index 0000000..7811359
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Adblock Plus Iestatījumi">
+<!ENTITY filters.label "Filtri">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "Pievienot filtru">
+<!ENTITY add.accesskey "P">
+<!ENTITY addsubscription.label "Pievienot filtru abonementu">
+<!ENTITY addsubscription.accesskey "a">
+<!ENTITY synchsubscriptions.label "AtjauninÄt visus abonementus">
+<!ENTITY synchsubscriptions.accesskey "v">
+<!ENTITY import.label "ImportÄt filtrus">
+<!ENTITY import.accesskey "m">
+<!ENTITY export.label "EksportÄt pielÄgotos filtrus">
+<!ENTITY export.accesskey "k">
+<!ENTITY clearall.label "NoÅemt visus pielÄgotos filtrus">
+<!ENTITY clearall.accesskey "l">
+<!ENTITY resethitcounts.label "AtiestatÄ«t trÄpÄ«jumu statistiku">
+<!ENTITY resethitcounts.accesskey "t">
+<!ENTITY edit.label "RediÄ£Ät">
+<!ENTITY edit.accesskey "e">
+<!ENTITY cut.label "Izgriezt">
+<!ENTITY cut.accesskey "t">
+<!ENTITY copy.label "KopÄt">
+<!ENTITY copy.accesskey "K">
+<!ENTITY paste.label "IelÄ«mÄt">
+<!ENTITY paste.accesskey "I">
+<!ENTITY remove.label "DzÄst">
+<!ENTITY remove.accesskey "D">
+<!ENTITY menu.find.label "MeklÄt">
+<!ENTITY menu.find.accesskey "M">
+<!ENTITY menu.findagain.label "MeklÄt atkal">
+<!ENTITY menu.findagain.accesskey "l">
+<!ENTITY view.label "Skats">
+<!ENTITY view.accesskey "S">
+<!ENTITY sort.label "Å Ä·irot pÄc">
+<!ENTITY sort.accesskey "o">
+<!ENTITY sort.none.label "Nešķirots">
+<!ENTITY sort.none.accesskey "N">
+<!ENTITY sort.ascending.label "A > Z šķirošanas secība">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Z > A šķirošanas secība">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Opcijas">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "IespÄjot Adblock Plus">
+<!ENTITY enable.accesskey "I">
+<!ENTITY showintoolbar.label "RÄdÄ«t rÄ«kjoslÄ">
+<!ENTITY showintoolbar.accesskey "r">
+<!ENTITY showinstatusbar.label "RÄdÄ«t statusa joslÄ">
+<!ENTITY showinstatusbar.accesskey "s">
+<!ENTITY objecttabs.label "RÄdÄ«t cilnes uz Flash un Java">
+<!ENTITY objecttabs.accesskey "c">
+<!ENTITY collapse.label "Sakļaut bloÄ·Ätos elementus">
+<!ENTITY collapse.accesskey "b">
+<!ENTITY sync.label "SinhronizÄt Adblock Plus iestatÄ«jumus">
+<!ENTITY sync.accesskey "n">
+<!ENTITY help.label "Palīdzība">
+<!ENTITY help.accesskey "l">
+<!ENTITY gettingStarted.label "SÄkÅ¡ana">
+<!ENTITY gettingStarted.accesskey "S">
+<!ENTITY faq.label "Bieži uzdotie jautÄjumi">
+<!ENTITY faq.accesskey "B">
+<!ENTITY filterdoc.label "Adblock Plus filtru veidošana">
+<!ENTITY filterdoc.accesskey "f">
+<!ENTITY about.label "Par Adblock Plus">
+<!ENTITY about.accesskey "A">
+<!ENTITY description "SekojoÅ¡ie filtri nosaka, kuras adreses ir jÄbloÄ·Ä un kuras jÄatļauj:">
+<!ENTITY filter.column "Filtra noteikums">
+<!ENTITY filter.accesskey "F">
+<!ENTITY slow.column "RÄdÄ«t filtrus">
+<!ENTITY slow.accesskey "d">
+<!ENTITY enabled.column "IespÄjots">
+<!ENTITY enabled.accesskey "j">
+<!ENTITY hitcount.column "TrÄpÄ«jumi">
+<!ENTITY hitcount.accesskey "T">
+<!ENTITY lasthit.column "PÄdÄjais trÄpÄ«jums">
+<!ENTITY lasthit.accesskey "P">
+<!ENTITY context.edit.label "RediÄ£Ät filtru">
+<!ENTITY context.resethitcount.label "AtiestatÄ«t trÄpÄ«jumu statistiku filtram">
+<!ENTITY context.synchsubscription.label "AtjauninÄt abonementu tagad">
+<!ENTITY context.editsubscription.label "RediÄ£Ät abonementu">
+<!ENTITY context.moveup.label "PÄrvietot filtru uz augÅ¡u">
+<!ENTITY context.movedown.label "PÄrvietot filtru uz leju">
+<!ENTITY context.movegroupup.label "PÄrvietot grupu uz augÅ¡u">
+<!ENTITY context.movegroupdown.label "PÄrvietot grupu uz leju">
+<!ENTITY context.enable.label "IespÄjot">
+<!ENTITY context.disable.label "AtspÄjot">
+<!ENTITY apply.label "Pielietot">
+<!ENTITY apply.accesskey "i">
+<!ENTITY fennec.subscription.label "Filtru abonements">
diff --git a/chrome/adblockplus.jar!/locale/lv/sidebar.dtd b/chrome/adblockplus.jar!/locale/lv/sidebar.dtd
new file mode 100644
index 0000000..3ce9052
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/sidebar.dtd
@@ -0,0 +1,35 @@
+<!ENTITY detached.title "Adblock Plus: BloÄ·ÄjamÄs vienÄ«bas (atdalÄ«ts)">
+<!ENTITY detach.label "Atdalīt">
+<!ENTITY reattach.label "Pievienot atpakaļ">
+<!ENTITY search.label "MeklÄt:">
+<!ENTITY search.accesskey "M">
+<!ENTITY type.label "Tips">
+<!ENTITY address.label "Adrese">
+<!ENTITY filter.label "Filtrs">
+<!ENTITY state.label "StÄvoklis">
+<!ENTITY size.label "IzmÄrs">
+<!ENTITY docDomain.label "Dokumenta avots">
+<!ENTITY docDomain.thirdParty "(treÅ¡Ä puse)">
+<!ENTITY docDomain.firstParty "(pirmÄ puse)">
+<!ENTITY noitems.label "Nav bloÄ·Äjamu vienÄ«bu">
+<!ENTITY whitelisted.label "Lapa ir baltajÄ sarakstÄ">
+<!ENTITY tooltip.address.label "Adrese:">
+<!ENTITY tooltip.type.label "Tips:">
+<!ENTITY tooltip.type.blocked "(bloÄ·Äts)">
+<!ENTITY tooltip.type.whitelisted "(baltajÄ sarakstÄ)">
+<!ENTITY tooltip.size.label "IzmÄrs:">
+<!ENTITY tooltip.docDomain.label "Dokumenta avots:">
+<!ENTITY tooltip.filter.label "Aktīvais filtrs:">
+<!ENTITY tooltip.filter.disabled "(atspÄjots)">
+<!ENTITY tooltip.filterSource.label "Filtra avots:">
+<!ENTITY context.block.label "BloÄ·Ät Å¡o vienÄ«bu">
+<!ENTITY context.editfilter.label "RediÄ£Ät aktÄ«vo filtru">
+<!ENTITY context.whitelist.label "Pievienot izÅÄmuma noteikumu Å¡ai vienÄ«bai">
+<!ENTITY context.disablefilter.label "AtspÄjot filtru ?1?">
+<!ENTITY context.enablefilter.label "IespÄjot filtru ?1?">
+<!ENTITY context.disablefilteronsite.label "AtspÄjot Å¡o filtru ?1?">
+<!ENTITY context.open.label "AtvÄrt jaunÄ cilnÄ">
+<!ENTITY context.flash.label "Flash vienības malas">
+<!ENTITY context.copy.label "KopÄt vienÄ«bas adresi">
+<!ENTITY context.copyFilter.label "KopÄt filtru">
+<!ENTITY context.selectAll.label "IezÄ«mÄt visu">
diff --git a/chrome/adblockplus.jar!/locale/lv/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/lv/subscriptionSelection.dtd
new file mode 100644
index 0000000..f0d3eda
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/lv/subscriptionSelection.dtd
@@ -0,0 +1,27 @@
+<!ENTITY dialog.title "Pievienot Adblock Plus filtru abonementu">
+<!ENTITY dialog.title.edit "RediÄ£Ät filtru abonementu">
+<!ENTITY description.newInstall "Adblock Plus visefektÄ«vÄk darbosies, ja JÅ«s pievienosiet filtru abonementu.
+ Filtru abonementus bez maksas piedÄvÄ Adblock Plus lietotÄji. JÅ«su valodai
+ vispiemÄrotÄkais abonements jau ir izvÄlÄts.">
+<!ENTITY subscriptionSelector.label "LÅ«dzu izvÄlieties filtru abonementu no saraksta:">
+<!ENTITY viewList.label "Skatīt filtrus">
+<!ENTITY visitHomepage.label "ApmeklÄt mÄjas lapu">
+<!ENTITY addSubscription.label "Pievienot abonementu">
+<!ENTITY saveSubscription.label "SaglabÄt abonementu">
+<!ENTITY other.label "Pievienot citu abonementu">
+<!ENTITY other.accesskey "c">
+<!ENTITY list.download.failed "Adblock Plus neizdevÄs iegÅ«t sarakstu ar abonementiem.">
+<!ENTITY list.download.retry "MÄÄ£inÄt vÄlreiz">
+<!ENTITY list.download.website "ApskatÄ«t mÄjas lapu">
+<!ENTITY fromWeb.description "LÅ«dzu apstipriniet, ka vÄlaties pievienot Å¡o filtru abonementu. JÅ«s varat izmanÄ«t abonementa nosaukumu vai atraÅ¡anÄs vietu pirms pievienoÅ¡anas.">
+<!ENTITY edit.description "Ja nepiecieÅ¡ams jÅ«s varat izmanÄ«t abonementa nosaukumu vai atraÅ¡anÄs vietu.">
+<!ENTITY external.description "Å is ir ÄrÄjais filtru abonements, tas tiks atjauninÄts ar papildinÄjumu, kas radÄ«ja Å¡o abonementu.">
+<!ENTITY title.label "Abonementa nosaukums:">
+<!ENTITY title.accesskey "n">
+<!ENTITY location.label "Filtru saraksta atraÅ¡anÄs vieta:">
+<!ENTITY location.accesskey "l">
+<!ENTITY autodownload.label "AutomÄtiski atjauninÄt filtrus">
+<!ENTITY autodownload.accesskey "a">
+<!ENTITY supplementMessage "Å o filtru abonementu ir paredzÄts lietot kopÄ ar filtru abonementu "?1?", kuru JÅ«s vÄl nelietojat.">
+<!ENTITY addMain.label "Pievienot arī filtru abonementu "?1?"">
+<!ENTITY addMain.accesskey "f">
diff --git a/chrome/locale/mn/about.dtd b/chrome/adblockplus.jar!/locale/mn/about.dtd
similarity index 100%
rename from chrome/locale/mn/about.dtd
rename to chrome/adblockplus.jar!/locale/mn/about.dtd
diff --git a/chrome/locale/mn/composer.dtd b/chrome/adblockplus.jar!/locale/mn/composer.dtd
similarity index 100%
rename from chrome/locale/mn/composer.dtd
rename to chrome/adblockplus.jar!/locale/mn/composer.dtd
diff --git a/chrome/locale/mn/global.properties b/chrome/adblockplus.jar!/locale/mn/global.properties
similarity index 100%
rename from chrome/locale/mn/global.properties
rename to chrome/adblockplus.jar!/locale/mn/global.properties
diff --git a/chrome/adblockplus.jar!/locale/mn/overlay.dtd b/chrome/adblockplus.jar!/locale/mn/overlay.dtd
new file mode 100644
index 0000000..05adaab
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/mn/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "Төлөв:">
+<!ENTITY blocked.tooltip "Уг Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ñ
аÑигдÑан зүйлÑ:">
+<!ENTITY filters.tooltip "Хамгийн идÑвÑ
ÑÑй ÑүүлÑÒ¯Ò¯Ñүүд:">
+<!ENTITY menuitem.label "Adblock Plus">
+<!ENTITY menuitem.accesskey "B">
+<!ENTITY toolbarbutton.label "Adblock ÐÑмÑÑ
">
+<!ENTITY view.blockableItems.label "Adblock ÐÑмÑÑ
:ХаÑигдаÑ
ÑÐ¹Ñ Ð·Ò¯Ð¹Ð»Ñ">
+<!ENTITY context.image.label "Adblock ÐÑÑаг">
+<!ENTITY context.object.label "Adblock ÐбÑекÑ">
+<!ENTITY context.frame.label "Adblock Ð¥Ò¯ÑÑÑ">
+<!ENTITY context.media.label "Adblock: ÐÑÑ/видео">
+<!ENTITY context.removeWhitelist.label "Adblock: Уг Ñ
ÑÑдÑанд даÑ
ин нÑÑÑ
">
+<!ENTITY sidebar.title "ТÑÑ
айн Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ñ
аÑигдаж болоÑ
зүйлÑ">
+<!ENTITY sendReport.label "ÐÐ½Ñ Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ð°ÑÑÑдлÑг мÑдÑгдÑÑ
">
+<!ENTITY sendReport.accesskey "Ð">
+<!ENTITY settings.label "ТоÑ
иÑгоонÑÑд">
+<!ENTITY settings.accesskey "Т">
+<!ENTITY opensidebar.label "ХаÑигдаÑ
зүйлÑийг нÑÑÑ
">
+<!ENTITY opensidebar.accesskey "Ð¥">
+<!ENTITY closesidebar.label "ХаÑигдаÑ
зүйлÑийг Ñ
ааÑ
">
+<!ENTITY closesidebar.accesskey "Ð¥">
+<!ENTITY whitelist.site.label "ХааÑ
Ð½Ñ ?1?">
+<!ENTITY whitelist.page.label "ÐөвÑ
өн Ñг Ñ
ÑÑдÑанд Ñ
ааÑ
">
+<!ENTITY objecttab.title "ХаÑиÑ
">
+<!ENTITY objecttab.tooltip "Ðнд даÑвал Ñг обÑекÑийг Adblock Plus-Ð°Ð°Ñ Ñ
аÑиÑ
болно">
+<!ENTITY disable.label "Disable everywhere">
+<!ENTITY recommend.label "Recommend us on Facebook">
diff --git a/chrome/locale/en-US/sendReport.dtd b/chrome/adblockplus.jar!/locale/mn/sendReport.dtd
similarity index 100%
rename from chrome/locale/en-US/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/mn/sendReport.dtd
diff --git a/chrome/adblockplus.jar!/locale/mn/settings.dtd b/chrome/adblockplus.jar!/locale/mn/settings.dtd
new file mode 100644
index 0000000..35c3003
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/mn/settings.dtd
@@ -0,0 +1,91 @@
+<!ENTITY dialog.title "Adblock Plus ТоÑ
иÑгоонÑÑд">
+<!ENTITY filters.label "ШүүлÑÒ¯Ò¯Ñүүд">
+<!ENTITY filters.accesskey "Ш">
+<!ENTITY add.label "Ð¨Ò¯Ò¯Ð»Ñ Ð½ÑмÑÑ
">
+<!ENTITY add.accesskey "Ð">
+<!ENTITY addsubscription.label "ШүүлÑÒ¯Ò¯Ñ Ð¼ÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
+<!ENTITY addsubscription.accesskey "Ð">
+<!ENTITY synchsubscriptions.label "ÐÒ¯Ñ
мÑдÑÑлÑгÑийг ÑинÑÑлÑÑ
">
+<!ENTITY synchsubscriptions.accesskey "Ð">
+<!ENTITY import.label "ШүүлÑÒ¯Ò¯Ñ Ð¾ÑÑÑлаÑ
">
+<!ENTITY import.accesskey "Ð">
+<!ENTITY export.label "ШүүлÑÒ¯Ò¯Ñ Ð³Ð°ÑгаÑ
">
+<!ENTITY export.accesskey "Ð">
+<!ENTITY clearall.label "ÐÒ¯Ñ
ÑүүлÑÒ¯Ò¯Ñүүдийг Ñ
аÑаÑ
">
+<!ENTITY clearall.accesskey "С">
+<!ENTITY resethitcounts.label "ХандалÑÑн Ñөлвийг ÑÑ
лүүлÑÑ
">
+<!ENTITY resethitcounts.accesskey "Т">
+<!ENTITY edit.label "ÐаÑваÑ">
+<!ENTITY edit.accesskey "Ð">
+<!ENTITY cut.label "ХайÑлаÑ
">
+<!ENTITY cut.accesskey "Ч">
+<!ENTITY copy.label "Ð¥ÑÑлаÑ
">
+<!ENTITY copy.accesskey "Ð¥">
+<!ENTITY paste.label "ТавиÑ
">
+<!ENTITY paste.accesskey "Т">
+<!ENTITY remove.label "УÑÑгаÑ
">
+<!ENTITY remove.accesskey "У">
+<!ENTITY menu.find.label "ХайÑ
">
+<!ENTITY menu.find.accesskey "Ð">
+<!ENTITY menu.findagain.label "ÐаÑ
ин Ñ
айÑ
">
+<!ENTITY menu.findagain.accesskey "Ð">
+<!ENTITY view.label "ХаÑаÑ
">
+<!ENTITY view.accesskey "Ð¥">
+<!ENTITY sort.label "ÐÑÑмбÑлÑÑ
нÑ">
+<!ENTITY sort.accesskey "Ð">
+<!ENTITY sort.none.label "ÐÑÑÐ¼Ð±Ñ Ò¯Ð³Ò¯Ð¹">
+<!ENTITY sort.none.accesskey "Ò®">
+<!ENTITY sort.ascending.label "Ð > Я ÑÑÑмбÑлÑÑ
">
+<!ENTITY sort.ascending.accesskey "Ð">
+<!ENTITY sort.descending.label "Я > Ð ÑÑÑмбÑлÑÑ
">
+<!ENTITY sort.descending.accesskey "Я">
+<!ENTITY options.label "СонголÑÑÑд">
+<!ENTITY options.accesskey "Ð">
+<!ENTITY enable.label "Adblock Plus идÑвÑ
ÑÑй">
+<!ENTITY enable.accesskey "Ð">
+<!ENTITY showintoolbar.label "Ð¥ÑÑÑгÑлийн мөÑÑ Ñ
аÑÑÑлаÑ
">
+<!ENTITY showintoolbar.accesskey "Ð">
+<!ENTITY showinstatusbar.label "Төлвийн мөÑÑ Ñ
аÑÑÑлаÑ
">
+<!ENTITY showinstatusbar.accesskey "Т">
+<!ENTITY objecttabs.label "Flash болон Java-д tab Ñ
аÑÑÑлаÑ
">
+<!ENTITY objecttabs.accesskey "Ð¥">
+<!ENTITY collapse.label "ХаÑигдÑан ÑлеменÑийг Ñ
ÑмиÑ
">
+<!ENTITY collapse.accesskey "Ð">
+<!ENTITY help.label "ТÑÑламж">
+<!ENTITY help.accesskey "Т">
+<!ENTITY gettingStarted.label "ÐÑ
лÑл">
+<!ENTITY gettingStarted.accesskey "Ð">
+<!ENTITY faq.label "ТүгÑÑмÑл ÐÑÑÑлÑÑн ХаÑиÑлÑÑÑд">
+<!ENTITY faq.accesskey "Ð">
+<!ENTITY filterdoc.label "Adblock Plus ÑүүлÑÒ¯Ò¯Ñүүд биÑиÑ
">
+<!ENTITY filterdoc.accesskey "Ð">
+<!ENTITY about.label "Adblock Plus-ийн ÑÑÑ
ай">
+<!ENTITY about.accesskey "Т">
+<!ENTITY description "ХаÑиÑ
Ñг Ñ
Ò¯ÑÑÑн Ñ
аÑгаа нÑмÑÑ
дÑÑ, Ð´Ð¾Ð¾Ñ ÑнжиÑ
жагÑаалÑÐ°Ð°Ñ Ð°Ð²Ñ Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ñой.
+ Та * аÑиглан илүү еÑөнÑ
ий ÑүүлÑÒ¯Ò¯Ñ Ò¯Ò¯ÑгÑж болно. Ðлүү Ñ
ÑÑÑглÑгÑид
+ Ñнгийн илÑÑÑ
ийлÑл (regexpression) аÑиглаж Ñадна. Ð: /banner\d+\.gif$/.">
+<!ENTITY filter.column "ШүүÑ
дүÑÑм">
+<!ENTITY filter.accesskey "Ш">
+<!ENTITY slow.column "Удаан ÑүүлÑÒ¯Ò¯Ñүүд">
+<!ENTITY slow.accesskey "У">
+<!ENTITY enabled.column "ÐдÑвÑ
ÑÑй">
+<!ENTITY enabled.accesskey "Ð">
+<!ENTITY hitcount.column "ХандалÑ">
+<!ENTITY hitcount.accesskey "Ð¥">
+<!ENTITY lasthit.column "Сүүлийн Ñ
андалÑ">
+<!ENTITY lasthit.accesskey "С">
+<!ENTITY context.edit.label "ШүүлÑÒ¯Ò¯Ñ Ð·Ð°ÑаÑ
">
+<!ENTITY context.resethitcount.label "ШүүлÑÒ¯Ò¯Ñийн Ñ
андалÑÑн ÑÑаÑиÑÑикийг ÑÑ
лүүлÑÑ
">
+<!ENTITY context.synchsubscription.label "ÐÑдÑÑлÑгÑийг одоо ÑинÑÑлÑÑ
">
+<!ENTITY context.editsubscription.label "ÐÑдÑÑлÑÐ³Ñ Ð·Ð°ÑаÑ
">
+<!ENTITY context.moveup.label "ÐÑÑÑлүүлÑÑ
">
+<!ENTITY context.movedown.label "ÐооÑлÑÑлаÑ
">
+<!ENTITY context.movegroupup.label "Ðүлгийг дÑÑÑлүүлÑÑ
">
+<!ENTITY context.movegroupdown.label "Ðүлгийг дооÑлÑÑлаÑ
">
+<!ENTITY context.enable.label "ÐÑÑÑ
">
+<!ENTITY context.disable.label "ХааÑ
">
+<!ENTITY apply.label "Ð¥ÑÑÑглÑÑ
">
+<!ENTITY apply.accesskey "Ð">
+<!ENTITY fennec.subscription.label "ШүүÑ
мÑдÑÑлÑгÑ">
+<!ENTITY sync.accesskey "c">
+<!ENTITY sync.label "Sync Adblock Plus settings">
diff --git a/chrome/locale/mn/sidebar.dtd b/chrome/adblockplus.jar!/locale/mn/sidebar.dtd
similarity index 100%
rename from chrome/locale/mn/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/mn/sidebar.dtd
diff --git a/chrome/adblockplus.jar!/locale/mn/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/mn/subscriptionSelection.dtd
new file mode 100644
index 0000000..80a3b99
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/mn/subscriptionSelection.dtd
@@ -0,0 +1,30 @@
+<!ENTITY dialog.title "Adblock Plus-д ÑавÑай моÑил">
+<!ENTITY dialog.title.edit "ШүүлÑÒ¯Ò¯Ñийн мÑдÑÑлÑÐ³Ñ Ð·Ð°ÑаÑ
">
+<!ENTITY subscriptionSelector.label "ÐагÑаалÑÐ°Ð°Ñ ÑÒ¯Ò¯Ñ
мÑдÑÑлÑÐ³Ñ Ñонгоно ÑÑ:">
+<!ENTITY viewList.label "ШүүлÑÒ¯Ò¯Ñүүд Ñ
аÑаÑ
">
+<!ENTITY visitHomepage.label "ҮндÑÑн Ñ
ÑÑдÑанд зоÑлоÑ
">
+<!ENTITY addSubscription.label "ÐÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
+<!ENTITY saveSubscription.label "ÐÑдÑÑлÑÐ³Ñ Ñ
адгалаÑ
">
+<!ENTITY other.label "Ó¨Ó©Ñ Ð¼ÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
+<!ENTITY other.accesskey "Ó¨">
+<!ENTITY list.download.failed "Adblock Plus Ð½Ñ Ð¼ÑдÑÑлÑгÑийн жагÑаалÑÑг ÑаÑаж ÑадÑангүй.">
+<!ENTITY list.download.retry "ÐаÑ
иж оÑолдоÑ
">
+<!ENTITY list.download.website "ÐÑбÑайÑÑг Ñ
аÑаÑ
">
+<!ENTITY title.label "ÐÑдÑÑлÑгÑийн гаÑÑиг:">
+<!ENTITY title.accesskey "Ð">
+<!ENTITY location.label "ШүүлÑÒ¯Ò¯Ñийн жагÑаалÑÑн байÑÑил:">
+<!ENTITY location.accesskey "Ð">
+<!ENTITY autodownload.label "ÐвÑомаÑÐ°Ð°Ñ ÑинÑÑлÑÑ
">
+<!ENTITY autodownload.accesskey "Ð">
+<!ENTITY addMain.label "ШүүÑ
мÑдÑÑлÑÐ³Ñ "?1?" нÑмÑÑ
">
+<!ENTITY addMain.accesskey "Ш">
+<!ENTITY description.newInstall "
+ Adblock Plus will be most effective if you add a filter subscription.
+ Filter subscriptions are provided by other Adblock Plus users free of
+ charge. The most suitable subscription for your language is already
+ selected.
+">
+<!ENTITY external.description "This is an external filter subscription; it will be updated by the extension that created this subscription.">
+<!ENTITY fromWeb.description "Please confirm that you want to add this filter subscription. You can change the subscription title or location before adding it.">
+<!ENTITY supplementMessage "This filter subscription is meant to be used with the filter subscription "?1?" which you are not using yet.">
+<!ENTITY edit.description "You can change the subscription title or location as necessary.">
diff --git a/chrome/locale/ms-MY/about.dtd b/chrome/adblockplus.jar!/locale/ms-MY/about.dtd
similarity index 100%
rename from chrome/locale/ms-MY/about.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/about.dtd
diff --git a/chrome/locale/ms-MY/composer.dtd b/chrome/adblockplus.jar!/locale/ms-MY/composer.dtd
similarity index 100%
rename from chrome/locale/ms-MY/composer.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/composer.dtd
diff --git a/chrome/adblockplus.jar!/locale/ms-MY/global.properties b/chrome/adblockplus.jar!/locale/ms-MY/global.properties
new file mode 100644
index 0000000..75c2a6f
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ms-MY/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=Klik untuk mengeluarkan menu konteks, klik tengah untuk aktifkan/nyahaktifkan.
+action1_tooltip=Klik untuk membuka/menutup item yang boleh disekat, klik tengah untuk aktifkan/nyahaktifkan.
+action2_tooltip=Klik untuk buka tatarajah, klik tengah untuk aktifkan/nyahaktifkan.
+action3_tooltip=Klik untuk aktifkan/nyahaktifkan Adblock Plus.
+disabled_tooltip=Adblock Plus telah dinyahaktifkan.
+active_tooltip=Adblock Plus telah diaktifkan, ?1? langganan penapis dan ?2? penapis sendiri digunakan.
+whitelisted_tooltip=Adblock Plus dinyahaktifkan pada laman semasa.
+blocked_count_tooltip=?1? daripada ?2?
+blocked_count_addendum=(juga dikecualikan: ?1?, disembunyikan: ?2?
+no_blocking_suggestions=Tiada item yang boleh disekat pada laman semasa
+whitelisted_page=Adblock Plus telah dinyahaktifkan untuk laman semasa
+whitelist_description=Peraturan pengecualian saya
+filterlist_description=Peraturan penyekatan iklan saya
+invalid_description=Peraturan tidak sah saya
+elemhide_description=Peraturan menyembunyikan elemen saya
+subscription_description=Langganan penapis:
+subscription_wrong_version=Beberapa penapis dalam langganan ini memerlukan Adblock Plus ?1? untuk berfungsi.
+subscription_source=Sumber:
+subscription_status=Status:
+subscription_status_autodownload=Dikemaskini secara automatik
+subscription_status_manualdownload=Dikemaskini secara manual
+subscription_status_externaldownload=Dikemaskini secara luar (extension lain)
+subscription_status_lastdownload=Muat-turun terakhir:
+subscription_status_lastdownload_inprogress=Memuat-turun...
+subscription_status_lastdownload_unknown=N/A
+remove_subscription_warning=Adakah anda mahu membuang langganan ini?
+import_filters_wrong_version=Amaran: beberapa penapis dalam senarai ini memerlukan Adblock Plus ?1? untuk berfungsi dengan sempurna. Anda perlu menaiktaraf Adblock Plus kepada yang terbaru sebelum mengimport senarai ini.
+import_filters_warning=Adakah anda mahu menggantikan penapis sedia ada atau melampirkan penapis baru pada akhir senarai sedia ada?
+import_filters_title=Import penapis
+export_filters_title=Eksport penapis
+invalid_filters_file=Bukan fail penapis Adblock Plus yang sah.
+filters_write_error=Terdapat ralat dalam menulis penapis pada fail. Pastikan fail tidak dilindung-tulis atau dibuka dalam program lain.
+clearall_warning=Adakah anda mahu membuang semua penapis dari senarai?
+resethitcounts_warning=Adakah anda mahu reset semula pembilang hit semua penapis menjadi kosong? Operasi ini tidak boleh diundur!
+resethitcounts_selected_warning=Adakah anda mahu reset semula pembilang hit penapis yang dipilih menjadi kosong? Operasi ini tidak boleh diundur!
+filter_regexp_tooltip=Penapis ini hanya ungkapan biasa atau terlalu pendek untuk dioptimumkan. Terlalu banyak penapis mungkin akan melambatkan penjelajahan web.
+filter_elemhide_duplicate_id=Hanya satu ID elemen untuk disembunyikan boleh dinyatakan
+filter_elemhide_nocriteria=Tiada kriteria yang dinyatakan untuk mengenal pasti elemen untuk disembunyikan
+subscription_notAdded_warning=Anda belum lagi menambah langganan penapis. Tanpa langganan penapis anda perlu menambah penapis Adblock Plus secara manual.
+subscription_notAdded_warning_addendum=Adakah anda mahu mara?
+subscription_invalid_location=Lokasi senarai penapis sama ada URL atau nama fail adalah tidak sah.
+synchronize_invalid_url=Gagal, bukan alamat yang sah
+synchronize_connection_error=Gagal, kegagalan memuat-turun
+synchronize_invalid_data=Gagal, bukan senarai penapis yang sah
+synchronize_checksum_mismatch=Gagal, checksum tidak sepadan
+synchronize_ok=Berjaya
+overwrite=Tulis atas
+append=Lampirkan
+new_filter_group_title=Penapis baru
+type_label_other=lain
+type_label_script=skrip
+type_label_image=imej
+type_label_stylesheet=lembaran stail
+type_label_object=objek
+type_label_subdocument=bingkai
+type_label_document=dokumen
+type_label_elemhide=disembunyikan
+type_label_xbl=Ikatan XBL
+type_label_ping=pautan ping
+type_label_xmlhttprequest=permintaan XML
+type_label_object_subrequest=subpermintaan objek
+type_label_dtd=DTD
+type_label_media=audio/video
+type_label_font=font
+fennec_status_enabled=Adblock Plus telah diaktifkan
+fennec_status_disabled=Adblock Plus telah dinyahaktifkan
+fennec_status_enabled_site=Adblock Plus telah diaktifkan pada ?1?
+fennec_status_disabled_site=Adblock Plus telah dinyahaktifkan pada ?1?
+sync_engine_title=Data Adblock Plus
diff --git a/chrome/locale/ms-MY/overlay.dtd b/chrome/adblockplus.jar!/locale/ms-MY/overlay.dtd
similarity index 100%
rename from chrome/locale/ms-MY/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/overlay.dtd
diff --git a/chrome/locale/ms-MY/sendReport.dtd b/chrome/adblockplus.jar!/locale/ms-MY/sendReport.dtd
similarity index 100%
rename from chrome/locale/ms-MY/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/sendReport.dtd
diff --git a/chrome/locale/ms-MY/settings.dtd b/chrome/adblockplus.jar!/locale/ms-MY/settings.dtd
similarity index 100%
rename from chrome/locale/ms-MY/settings.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/settings.dtd
diff --git a/chrome/locale/ms-MY/sidebar.dtd b/chrome/adblockplus.jar!/locale/ms-MY/sidebar.dtd
similarity index 100%
rename from chrome/locale/ms-MY/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/sidebar.dtd
diff --git a/chrome/locale/ms-MY/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ms-MY/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ms-MY/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ms-MY/subscriptionSelection.dtd
diff --git a/chrome/locale/nl/about.dtd b/chrome/adblockplus.jar!/locale/nl/about.dtd
similarity index 100%
rename from chrome/locale/nl/about.dtd
rename to chrome/adblockplus.jar!/locale/nl/about.dtd
diff --git a/chrome/locale/nl/composer.dtd b/chrome/adblockplus.jar!/locale/nl/composer.dtd
similarity index 100%
rename from chrome/locale/nl/composer.dtd
rename to chrome/adblockplus.jar!/locale/nl/composer.dtd
diff --git a/chrome/locale/nl/global.properties b/chrome/adblockplus.jar!/locale/nl/global.properties
similarity index 100%
rename from chrome/locale/nl/global.properties
rename to chrome/adblockplus.jar!/locale/nl/global.properties
diff --git a/chrome/locale/nl/overlay.dtd b/chrome/adblockplus.jar!/locale/nl/overlay.dtd
similarity index 100%
rename from chrome/locale/nl/overlay.dtd
rename to chrome/adblockplus.jar!/locale/nl/overlay.dtd
diff --git a/chrome/locale/nl/sendReport.dtd b/chrome/adblockplus.jar!/locale/nl/sendReport.dtd
similarity index 100%
rename from chrome/locale/nl/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/nl/sendReport.dtd
diff --git a/chrome/locale/nl/settings.dtd b/chrome/adblockplus.jar!/locale/nl/settings.dtd
similarity index 100%
rename from chrome/locale/nl/settings.dtd
rename to chrome/adblockplus.jar!/locale/nl/settings.dtd
diff --git a/chrome/locale/nl/sidebar.dtd b/chrome/adblockplus.jar!/locale/nl/sidebar.dtd
similarity index 100%
rename from chrome/locale/nl/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/nl/sidebar.dtd
diff --git a/chrome/locale/nl/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/nl/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/nl/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/nl/subscriptionSelection.dtd
diff --git a/chrome/locale/pl/about.dtd b/chrome/adblockplus.jar!/locale/pl/about.dtd
similarity index 100%
rename from chrome/locale/pl/about.dtd
rename to chrome/adblockplus.jar!/locale/pl/about.dtd
diff --git a/chrome/locale/pl/composer.dtd b/chrome/adblockplus.jar!/locale/pl/composer.dtd
similarity index 100%
rename from chrome/locale/pl/composer.dtd
rename to chrome/adblockplus.jar!/locale/pl/composer.dtd
diff --git a/chrome/locale/pl/global.properties b/chrome/adblockplus.jar!/locale/pl/global.properties
similarity index 100%
rename from chrome/locale/pl/global.properties
rename to chrome/adblockplus.jar!/locale/pl/global.properties
diff --git a/chrome/locale/pl/overlay.dtd b/chrome/adblockplus.jar!/locale/pl/overlay.dtd
similarity index 100%
rename from chrome/locale/pl/overlay.dtd
rename to chrome/adblockplus.jar!/locale/pl/overlay.dtd
diff --git a/chrome/locale/pl/sendReport.dtd b/chrome/adblockplus.jar!/locale/pl/sendReport.dtd
similarity index 100%
rename from chrome/locale/pl/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/pl/sendReport.dtd
diff --git a/chrome/locale/pl/settings.dtd b/chrome/adblockplus.jar!/locale/pl/settings.dtd
similarity index 100%
rename from chrome/locale/pl/settings.dtd
rename to chrome/adblockplus.jar!/locale/pl/settings.dtd
diff --git a/chrome/locale/pl/sidebar.dtd b/chrome/adblockplus.jar!/locale/pl/sidebar.dtd
similarity index 100%
rename from chrome/locale/pl/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/pl/sidebar.dtd
diff --git a/chrome/locale/pl/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/pl/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/pl/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/pl/subscriptionSelection.dtd
diff --git a/chrome/locale/pt-BR/about.dtd b/chrome/adblockplus.jar!/locale/pt-BR/about.dtd
similarity index 100%
rename from chrome/locale/pt-BR/about.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/about.dtd
diff --git a/chrome/locale/pt-BR/composer.dtd b/chrome/adblockplus.jar!/locale/pt-BR/composer.dtd
similarity index 100%
rename from chrome/locale/pt-BR/composer.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/composer.dtd
diff --git a/chrome/locale/pt-BR/global.properties b/chrome/adblockplus.jar!/locale/pt-BR/global.properties
similarity index 100%
rename from chrome/locale/pt-BR/global.properties
rename to chrome/adblockplus.jar!/locale/pt-BR/global.properties
diff --git a/chrome/locale/pt-BR/overlay.dtd b/chrome/adblockplus.jar!/locale/pt-BR/overlay.dtd
similarity index 100%
rename from chrome/locale/pt-BR/overlay.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/overlay.dtd
diff --git a/chrome/locale/pt-BR/sendReport.dtd b/chrome/adblockplus.jar!/locale/pt-BR/sendReport.dtd
similarity index 100%
rename from chrome/locale/pt-BR/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/sendReport.dtd
diff --git a/chrome/locale/pt-BR/settings.dtd b/chrome/adblockplus.jar!/locale/pt-BR/settings.dtd
similarity index 100%
rename from chrome/locale/pt-BR/settings.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/settings.dtd
diff --git a/chrome/locale/pt-BR/sidebar.dtd b/chrome/adblockplus.jar!/locale/pt-BR/sidebar.dtd
similarity index 100%
rename from chrome/locale/pt-BR/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/sidebar.dtd
diff --git a/chrome/locale/pt-BR/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/pt-BR/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/pt-BR/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/pt-BR/subscriptionSelection.dtd
diff --git a/chrome/locale/pt-PT/about.dtd b/chrome/adblockplus.jar!/locale/pt-PT/about.dtd
similarity index 100%
rename from chrome/locale/pt-PT/about.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/about.dtd
diff --git a/chrome/locale/pt-PT/composer.dtd b/chrome/adblockplus.jar!/locale/pt-PT/composer.dtd
similarity index 100%
rename from chrome/locale/pt-PT/composer.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/composer.dtd
diff --git a/chrome/locale/pt-PT/global.properties b/chrome/adblockplus.jar!/locale/pt-PT/global.properties
similarity index 100%
rename from chrome/locale/pt-PT/global.properties
rename to chrome/adblockplus.jar!/locale/pt-PT/global.properties
diff --git a/chrome/locale/pt-PT/overlay.dtd b/chrome/adblockplus.jar!/locale/pt-PT/overlay.dtd
similarity index 100%
rename from chrome/locale/pt-PT/overlay.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/overlay.dtd
diff --git a/chrome/locale/pt-PT/sendReport.dtd b/chrome/adblockplus.jar!/locale/pt-PT/sendReport.dtd
similarity index 100%
rename from chrome/locale/pt-PT/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/sendReport.dtd
diff --git a/chrome/locale/pt-PT/settings.dtd b/chrome/adblockplus.jar!/locale/pt-PT/settings.dtd
similarity index 100%
rename from chrome/locale/pt-PT/settings.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/settings.dtd
diff --git a/chrome/locale/pt-PT/sidebar.dtd b/chrome/adblockplus.jar!/locale/pt-PT/sidebar.dtd
similarity index 100%
rename from chrome/locale/pt-PT/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/sidebar.dtd
diff --git a/chrome/locale/pt-PT/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/pt-PT/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/pt-PT/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/pt-PT/subscriptionSelection.dtd
diff --git a/chrome/locale/ro/about.dtd b/chrome/adblockplus.jar!/locale/ro/about.dtd
similarity index 100%
rename from chrome/locale/ro/about.dtd
rename to chrome/adblockplus.jar!/locale/ro/about.dtd
diff --git a/chrome/locale/ro/composer.dtd b/chrome/adblockplus.jar!/locale/ro/composer.dtd
similarity index 100%
rename from chrome/locale/ro/composer.dtd
rename to chrome/adblockplus.jar!/locale/ro/composer.dtd
diff --git a/chrome/locale/ro/global.properties b/chrome/adblockplus.jar!/locale/ro/global.properties
similarity index 100%
rename from chrome/locale/ro/global.properties
rename to chrome/adblockplus.jar!/locale/ro/global.properties
diff --git a/chrome/locale/ro/overlay.dtd b/chrome/adblockplus.jar!/locale/ro/overlay.dtd
similarity index 100%
rename from chrome/locale/ro/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ro/overlay.dtd
diff --git a/chrome/locale/ro/sendReport.dtd b/chrome/adblockplus.jar!/locale/ro/sendReport.dtd
similarity index 100%
rename from chrome/locale/ro/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/ro/sendReport.dtd
diff --git a/chrome/locale/ro/settings.dtd b/chrome/adblockplus.jar!/locale/ro/settings.dtd
similarity index 100%
rename from chrome/locale/ro/settings.dtd
rename to chrome/adblockplus.jar!/locale/ro/settings.dtd
diff --git a/chrome/locale/ro/sidebar.dtd b/chrome/adblockplus.jar!/locale/ro/sidebar.dtd
similarity index 100%
rename from chrome/locale/ro/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ro/sidebar.dtd
diff --git a/chrome/locale/ro/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ro/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/ro/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/ro/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/ru/about.dtd b/chrome/adblockplus.jar!/locale/ru/about.dtd
new file mode 100644
index 0000000..7bcea6c
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ru/about.dtd
@@ -0,0 +1,15 @@
+<!ENTITY dialog.title "Ð Adblock Plus">
+
+<!ENTITY version.title "ÐеÑÑиÑ">
+<!ENTITY description "
+ С Adblock Plus Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе Ñами ÑеÑаÑÑ, ÑÑо Ð²Ñ Ñ
оÑиÑе видеÑÑ Ð² инÑеÑнеÑе,
+ а ÑÑо - неÑ. Ðе нÑжно болÑÑе ÑÑаÑиÑÑ Ñвое вÑÐµÐ¼Ñ Ð½Ð° ÑкаÑивание ÑекламнÑÑ
+ баннеÑов, еÑли Ð²Ñ Ð½Ðµ Ñ
оÑиÑе иÑ
видеÑÑ - Adblock Plus вам поможеÑ!
+">
+
+<!ENTITY homepage.label "ÐомаÑнÑÑ ÑÑÑаниÑа пÑоекÑа:">
+<!ENTITY author.label "РазÑабоÑÑик:">
+<!ENTITY contributors.label "ÐÑÑгие ÑÑаÑÑники:">
+
+<!ENTITY subscriptionAuthors.label "ÐвÑоÑÑ ÑпиÑков ÑилÑÑÑов:">
+<!ENTITY translators.label "ÐеÑеводÑики:">
diff --git a/chrome/locale/ru/composer.dtd b/chrome/adblockplus.jar!/locale/ru/composer.dtd
similarity index 100%
rename from chrome/locale/ru/composer.dtd
rename to chrome/adblockplus.jar!/locale/ru/composer.dtd
diff --git a/chrome/locale/ru/global.properties b/chrome/adblockplus.jar!/locale/ru/global.properties
similarity index 100%
rename from chrome/locale/ru/global.properties
rename to chrome/adblockplus.jar!/locale/ru/global.properties
diff --git a/chrome/locale/ru/overlay.dtd b/chrome/adblockplus.jar!/locale/ru/overlay.dtd
similarity index 100%
rename from chrome/locale/ru/overlay.dtd
rename to chrome/adblockplus.jar!/locale/ru/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/ru/sendReport.dtd b/chrome/adblockplus.jar!/locale/ru/sendReport.dtd
new file mode 100644
index 0000000..2a43ef7
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ru/sendReport.dtd
@@ -0,0 +1,178 @@
+<!ENTITY wizard.title "СообÑиÑÑ Ð¾ пÑоблеме">
+<!ENTITY privacyPolicy.label "ÐÑавила конÑиденÑиалÑноÑÑи">
+
+<!ENTITY dataCollector.heading "ÐобÑо пожаловаÑÑ Ð² маÑÑÐµÑ Ð¾ÑпÑавки ÑообÑениÑ">
+<!ENTITY dataCollector.description "ÐожалÑйÑÑа, подождиÑе неÑколÑко ÑекÑнд, пока Adblock Plus ÑобиÑÐ°ÐµÑ Ð½ÑжнÑе даннÑе.">
+
+<!-- Please keep typeSelector.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY typeSelector.heading "ÐÑÐ±Ð¾Ñ Ñипа пÑоблемÑ">
+
+<!ENTITY typeSelector.description "
+ ÐаÑÑÐµÑ Ð¿Ð¾Ð¼Ð¾Ð¶ÐµÑ Ð²Ð°Ð¼ оÑпÑавиÑÑ ÑообÑение о пÑоблеме Ñ Adblock Plus.
+ ÐожалÑйÑÑа, ÑкажиÑе на ÑÑой ÑÑÑаниÑе Ñип пÑоблемÑ, Ñ ÐºÐ¾ÑоÑой Ð²Ñ ÑÑолкнÑлиÑÑ:
+">
+
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus блокиÑÑÐµÑ ÑлиÑком многое">
+<!ENTITY typeSelector.falsePositive.accesskey "м">
+<!ENTITY typeSelector.falsePositive.description "
+ ÐÑли на ÑÑÑаниÑе оÑÑÑÑÑÑвÑÑÑ Ð²Ð°Ð¶Ð½Ñе ÑаÑÑи ÑодеÑжимого, а Ñакже еÑли она
+ оÑобÑажаеÑÑÑ Ð¸Ð»Ð¸ ÑÑнкÑиониÑÑÐµÑ Ð½ÐµÐ¿ÑавилÑно, Ñо ÑледÑÐµÑ Ð²ÑбÑаÑÑ ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
+ ÐÑ Ð¼Ð¾Ð¶ÐµÑе пÑовеÑиÑÑ, ÑвлÑеÑÑÑ Ð»Ð¸ Adblock Plus иÑÑоÑником пÑоблемÑ, вÑеменно
+ оÑклÑÑив его.
+">
+
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus не блокиÑÑÐµÑ ÑекламÑ">
+<!ENTITY typeSelector.falseNegative.accesskey "Ñ">
+<!ENTITY typeSelector.falseNegative.description "
+ ÐÑли неÑмоÑÑÑ Ð½Ð° Ñо, ÑÑо Adblock Plus вклÑÑен, на ÑÑÑаниÑе оÑобÑажаеÑÑÑ Ñеклама,
+ Ñо ÑледÑÐµÑ Ð²ÑбÑаÑÑ ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
+">
+
+<!ENTITY typeSelector.other.label "ÐÑÑÐ³Ð°Ñ Ð¿Ñоблема">
+<!ENTITY typeSelector.other.accesskey "Ð">
+<!ENTITY typeSelector.other.description "
+ ÐÑли Ð²Ñ Ð¿Ð¾Ð´Ð¾Ð·ÑеваеÑе, ÑÑо пÑоблема в Ñамом ÑаÑÑиÑении Adblock Plus,
+ а не в его ÑилÑÑÑаÑ
, Ñо вÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
+">
+
+<!ENTITY showRecentReports.label "ÐоказаÑÑ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ оÑпÑавленнÑе ÑообÑениÑ">
+<!ENTITY recentReports.label "ÐаÑи недавно оÑпÑавленнÑе ÑообÑениÑ">
+<!ENTITY recentReports.clear.label "УдалиÑÑ Ð²Ñе ÑообÑениÑ">
+<!ENTITY recentReports.clear.accesskey "л">
+
+<!ENTITY issues.description "
+ Adblock Plus обнаÑÑжил пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð² ваÑиÑ
наÑÑÑойкаÑ
, коÑоÑÑе, возможно, вÑзвали
+ даннÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð¸Ð»Ð¸ ÑÑложнÑÑ ÑаÑÑмоÑÑение ваÑего ÑообÑениÑ.
+">
+
+<!ENTITY issues.whitelist.description "
+ Adblock Plus оÑклÑÑен на ÑÑÑаниÑе, о коÑоÑой Ð²Ñ ÑобиÑаеÑеÑÑ ÑообÑиÑÑ. ÐожалÑйÑÑа,
+ вклÑÑиÑе Adblock Plus и обновиÑе ÑÑÑаниÑÑ, пÑежде Ñем поÑÑлаÑÑ ÑообÑение.
+ ÐÑо Ð¿Ð¾Ð¼Ð¾Ð¶ÐµÑ ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ Ð²Ð°Ñего ÑообÑениÑ.
+">
+<!ENTITY issues.whitelist.remove.label "ÐклÑÑиÑÑ Adblock Plus на ÑÑой ÑÑÑаниÑе">
+
+<!ENTITY issues.disabled.description "
+ Adblock Plus оÑклÑÑен и ниÑего не блокиÑÑÐµÑ Ð² ÑÑом ÑоÑÑоÑнии.
+">
+<!ENTITY issues.disabled.enable.label "ÐклÑÑиÑÑ Adblock Plus">
+
+<!ENTITY issues.nofilters.description "
+ Adblock Plus ниÑего не блокиÑÑÐµÑ Ð½Ð° ÑÑой ÑÑÑаниÑе. СкоÑее вÑего, пÑоблема,
+ коÑоÑÑÑ Ð²Ñ Ð½Ð°Ð±Ð»ÑдаеÑе, не ÑвÑзана Ñ Adblock Plus.
+">
+
+<!ENTITY issues.nosubscriptions.description "
+ ÐÑ Ð½Ðµ подпиÑÐ°Ð½Ñ Ð½Ð¸ на один из гоÑовÑÑ
ÑпиÑков ÑилÑÑÑов, коÑоÑÑе авÑомаÑиÑеÑки
+ блокиÑÑÑÑ Ð½ÐµÐ¶ÐµÐ»Ð°ÑелÑнÑе ÑлеменÑÑ ÑÑÑаниÑ.
+">
+<!ENTITY issues.nosubscriptions.add.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
+
+<!ENTITY issues.subscriptionCount.description "
+ ÐоÑ
оже, ÑÑо Ð²Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ°Ð½Ñ Ð½Ð° ÑлиÑком болÑÑое колиÑеÑÑво ÑпиÑков ÑилÑÑÑов. ÐÑо
+ не ÑекомендÑеÑÑÑ, поÑколÑÐºÑ ÑилÑно возÑаÑÑÐ°ÐµÑ Ð²ÐµÑоÑÑноÑÑÑ Ð¿Ñоблем. Ðомимо
+ ÑÑого, Ð¼Ñ Ð½Ðµ можем пÑинÑÑÑ Ð²Ð°Ñе ÑообÑение, поÑколÑÐºÑ Ð½ÐµÑÑно, какой из ÑпиÑков
+ ÑилÑÑÑов нÑжно иÑпÑавлÑÑÑ. ÐожалÑйÑÑа, ÑдалиÑе вÑе ÑпиÑки ÑилÑÑÑов кÑоме
+ дейÑÑвиÑелÑно нÑжнÑÑ
. ÐоÑле ÑÑого пÑовеÑÑÑе, пÑоÑвлÑеÑÑÑ Ð»Ð¸ еÑе пÑоблема.
+">
+<!ENTITY issues.openPreferences.label "ÐÑкÑÑÑÑ Ð½Ð°ÑÑÑойки ÑилÑÑÑов">
+
+<!ENTITY issues.ownfilters.description "
+ ÐекоÑоÑÑе ÑилÑÑÑÑ, коÑоÑÑе пÑименÑÑÑÑÑ Ð½Ð° ÑÑой ÑÑÑаниÑе, Ð²Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»Ð¸ Ñами.
+ ÐожалÑйÑÑа, оÑклÑÑиÑе ÑилÑÑÑÑ, коÑоÑÑе могли вÑзваÑÑ ÑÑÑ Ð¿ÑоблемÑ:
+">
+<!ENTITY issues.ownfilters.disable.label "ÐÑклÑÑиÑÑ ÑилÑÑÑ">
+
+<!ENTITY issues.disabledgroups.description "
+ СледÑÑÑие подпиÑки / гÑÑÐ¿Ð¿Ñ ÑилÑÑÑов оÑклÑÑенÑ, но могли Ð±Ñ Ð¿Ð¾Ð²Ð»Ð¸ÑÑÑ Ð½Ð° ÑÑÑ ÑÑÑаниÑÑ:
+">
+<!ENTITY issues.disabledgroups.enable.label "ÐклÑÑиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ / гÑÑÐ¿Ð¿Ñ ÑилÑÑÑов">
+
+<!ENTITY issues.disabledfilters.description "
+ СледÑÑÑие ÑилÑÑÑÑ Ð¾ÑклÑÑенÑ, но могли Ð±Ñ Ð¿Ð¾Ð²Ð»Ð¸ÑÑÑ Ð½Ð° ÑÑÑ ÑÑÑаниÑÑ:
+">
+<!ENTITY issues.disabledfilters.enable.label "ÐклÑÑиÑÑ ÑилÑÑÑ">
+
+<!ENTITY issues.override.label "ÐаÑÑÑойки в поÑÑдке, пÑодолжиÑÑ Ð¾ÑпÑавление ÑообÑениÑ">
+<!ENTITY issues.override.accesskey "п">
+<!ENTITY issues.change.description "
+ ÐаÑи наÑÑÑойки изменилиÑÑ. ÐожалÑйÑÑа, обновиÑе ÑÑÑаниÑÑ Ð´Ð»Ñ Ð¿ÑовеÑки
+ внеÑеннÑÑ
изменений и оÑпÑавÑÑе ÑообÑение, еÑли пÑоблема не ÑазÑеÑилаÑÑ.
+">
+
+<!ENTITY typeWarning.description "
+ ÐÑ Ñказали, ÑÑо Ñ
оÑиÑе ÑообÑиÑÑ Ð¾ пÑоблеме в Adblock Plus, а не в его ÑилÑÑÑаÑ
.
+ ÐожалÑйÑÑа, ÑÑÑиÑе, ÑÑо о ÑакиÑ
пÑоблемаÑ
лÑÑÑе ÑообÑаÑÑ Ð½Ð°
+ [link]ÑоÑÑме Adblock Plus[/link]. ÐаÑÑÐµÑ Ð¾ÑпÑавки ÑообÑÐµÐ½Ð¸Ñ ÑледÑеÑ
+ иÑполÑзоваÑÑ Ð»Ð¸ÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии к обÑÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð° ÑоÑÑме, поÑколÑкÑ
+ никÑо не ÑÐ²Ð¸Ð´Ð¸Ñ Ð²Ð°Ñе ÑообÑение, еÑли не оÑÑавиÑÑ Ð½Ð° него ÑÑÑлкÑ. ÐÑ
+ полÑÑиÑе авÑомаÑиÑеÑки ÑозданнÑÑ ÑÑÑÐ»ÐºÑ Ð¿Ð¾Ñле оÑпÑавки ÑообÑениÑ.
+">
+
+<!ENTITY typeWarning.override.label "Я понÑл и, Ñем не менее, Ñ
оÑÑ Ð¾ÑпÑавиÑÑ ÑообÑение">
+<!ENTITY typeWarning.override.accesskey "п">
+
+<!ENTITY reloadButton.label "ÐбновиÑÑ ÑÑÑаниÑÑ">
+<!ENTITY reloadButton.accesskey "н">
+
+<!-- Please keep screenshot.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY screenshot.heading "Снимок ÑкÑана">
+
+<!ENTITY screenshot.description "
+ Ðдна и Ñа же ÑÑÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ Ð¿Ð¾-ÑÐ°Ð·Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÑазнÑÑ
лÑдей. Снимок ÑкÑана
+ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð½Ð°Ð¼ понÑÑÑ Ð¿ÑоблемÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑдалиÑÑ ÐºÐ¾Ð½ÑиденÑиалÑнÑе ÑаÑÑи Ñнимка
+ или помеÑиÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ñнимка, в коÑоÑой пÑоÑвлÑеÑÑÑ Ð¿Ñоблема. ÐÐ»Ñ ÑÑого
+ нажмиÑе на ÑооÑвеÑÑÑвÑÑÑÑÑ ÐºÐ½Ð¾Ð¿ÐºÑ Ð¸ вÑбеÑиÑе мÑÑкой ÑаÑÑÑ Ñнимка.
+">
+
+<!ENTITY screenshot.attach.label "ÐÑикÑепиÑÑ Ñнимок ÑкÑана к ÑообÑениÑ">
+<!ENTITY screenshot.attach.accesskey "к">
+<!ENTITY screenshot.mark.label "ÐомеÑиÑÑ Ð¿ÑоблемÑ">
+<!ENTITY screenshot.mark.accesskey "п">
+<!ENTITY screenshot.remove.label "УдалиÑÑ ÐºÐ¾Ð½ÑиденÑиалÑнÑе даннÑе">
+<!ENTITY screenshot.remove.accesskey "д">
+<!ENTITY screenshot.undo.label "ÐÑмениÑÑ">
+<!ENTITY screenshot.undo.accesskey "Ð">
+
+<!-- Please keep commentPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY commentPage.heading "ÐомменÑаÑий">
+
+<!ENTITY commentPage.description "
+ ÐÐ½Ð¸Ð·Ñ Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе добавиÑÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑий, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð½Ð°Ð¼ понÑÑÑ Ð¿ÑоблемÑ.
+ ÐÑо не обÑзаÑелÑно, но ÑекомендÑеÑÑÑ Ð´Ð»Ñ Ð½ÐµÐ¾ÑевиднÑÑ
пÑоблем.
+ Также Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пÑовеÑиÑÑ Ð´Ð°Ð½Ð½Ñе ÑообÑениÑ, пÑежде Ñем оно бÑдеÑ
+ оÑпÑавлено.
+">
+
+<!ENTITY comment.label "ÐомменÑаÑий (необÑзаÑелÑно):">
+<!ENTITY comment.accesskey "Ð">
+<!ENTITY comment.lengthWarning "Ðлина комменÑаÑÐ¸Ñ Ð¿ÑевÑÑÐ°ÐµÑ 1000 Ñимволов. ТолÑко пеÑвÑе 1000 Ñимволов бÑдÑÑ Ð¾ÑпÑавленÑ.">
+<!ENTITY email.label "ÐдÑÐµÑ ÑлекÑÑонной поÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ
вопÑоÑов (необÑзаÑелÑно):">
+<!ENTITY email.accesskey "д">
+
+<!ENTITY attachExtensions.label "ÐÑикÑепиÑÑ ÑпиÑок вклÑÑеннÑÑ
ÑаÑÑиÑений к ÑообÑÐµÐ½Ð¸Ñ Ð½Ð° ÑлÑÑай, еÑли пÑоблема вÑзвана конÑликÑом ÑаÑÑиÑений">
+<!ENTITY attachExtensions.accesskey "Ñ">
+
+<!ENTITY sendButton.label "ÐÑпÑавиÑÑ ÑообÑение">
+<!ENTITY sendButton.accesskey "п">
+
+<!ENTITY showData.label "ÐоказаÑÑ Ð´Ð°Ð½Ð½Ñе ÑообÑениÑ">
+<!ENTITY data.label "ÐаннÑе ÑообÑениÑ:">
+<!ENTITY data.accesskey "н">
+
+<!-- Please keep sendPage.heading short - it is shown in the progress bar, not much space there -->
+<!ENTITY sendPage.heading "ÐÑпÑавка ÑообÑениÑ">
+<!ENTITY sendPage.waitMessage "ÐожалÑйÑÑа, подождиÑе, пока Adblock Plus оÑпÑавлÑÐµÑ Ð²Ð°Ñе ÑообÑение.">
+<!ENTITY sendPage.confirmation "СообÑение оÑпÑавлено и ÑоÑ
Ñанено. ÐÑ Ð¼Ð¾Ð¶ÐµÑе пÑоÑмоÑÑеÑÑ ÐµÐ³Ð¾ по ÑледÑÑÑей ÑÑÑлке:">
+<!ENTITY sendPage.knownIssue "Ðозможно, ÑÑо пÑоблема, о коÑоÑой Ð²Ñ ÑообÑили, Ñже извеÑÑна. ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ:">
+
+<!-- Note: the placeholder ?1? will be replaced by the error code -->
+<!ENTITY sendPage.errorMessage "
+ ÐÑибка оÑпÑавки ÑообÑениÑ: «?1?». ÐожалÑйÑÑа,
+ ÑдоÑÑовеÑÑÑеÑÑ, ÑÑо ваÑе Ñоединение Ñ ÑеÑÑÑ ÐнÑеÑÐ½ÐµÑ ÑабоÑаеÑ, и попÑобÑйÑе еÑе Ñаз.
+ ÐÑли пÑоблема оÑÑаеÑÑÑ, обÑаÑиÑеÑÑ Ð² [link]ÑоÑÑм Adblock Plus[/link].
+">
+<!ENTITY sendPage.retry.label "ÐÑпÑавиÑÑ ÐµÑе Ñаз">
+
+<!ENTITY copyLink.label "СкопиÑоваÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° ÑообÑение">
+<!ENTITY copyLink.accesskey "к">
diff --git a/chrome/locale/ru/settings.dtd b/chrome/adblockplus.jar!/locale/ru/settings.dtd
similarity index 100%
rename from chrome/locale/ru/settings.dtd
rename to chrome/adblockplus.jar!/locale/ru/settings.dtd
diff --git a/chrome/locale/ru/sidebar.dtd b/chrome/adblockplus.jar!/locale/ru/sidebar.dtd
similarity index 100%
rename from chrome/locale/ru/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/ru/sidebar.dtd
diff --git a/chrome/adblockplus.jar!/locale/ru/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/ru/subscriptionSelection.dtd
new file mode 100644
index 0000000..990bf60
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/ru/subscriptionSelection.dtd
@@ -0,0 +1,38 @@
+<!ENTITY dialog.title "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð´Ð»Ñ Adblock Plus">
+<!ENTITY dialog.title.edit "РедакÑиÑоваÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
+
+<!ENTITY description.newInstall "
+ Adblock Plus бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ ÑÑÑекÑивно, еÑли Ð²Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñе подпиÑÐºÑ Ð½Ð°
+ ÑпиÑок ÑилÑÑÑов. ÐÑи ÑпиÑки ÑилÑÑÑов пÑедоÑÑавлÑÑÑÑÑ Ð±ÐµÑплаÑно дÑÑгими
+ полÑзоваÑелÑми Adblock Plus. Ð¡Ð°Ð¼Ð°Ñ Ð¿Ð¾Ð´Ñ
одÑÑÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñка Ð´Ð»Ñ Ð²Ð°Ñего ÑзÑка Ñже
+ вÑбÑана.
+">
+
+<!ENTITY subscriptionSelector.label "ÐожалÑйÑÑа, вÑбеÑиÑе подпиÑÐºÑ Ð¸Ð· ÑпиÑка:">
+
+<!ENTITY viewList.label "ÐÑоÑмоÑÑеÑÑ ÑилÑÑÑÑ">
+<!ENTITY visitHomepage.label "ÐоÑеÑиÑÑ Ð´Ð¾Ð¼Ð°ÑнÑÑ ÑÑÑаниÑÑ ÑпиÑка">
+
+<!ENTITY addSubscription.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
+<!ENTITY saveSubscription.label "СоÑ
ÑаниÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ">
+
+<!ENTITY list.download.failed "ÐÑи ÑкаÑивании ÑпиÑка подпиÑок пÑоизоÑла оÑибка.">
+<!ENTITY list.download.retry "ÐопÑобоваÑÑ ÐµÑе Ñаз">
+<!ENTITY list.download.website "ÐÑкÑÑÑÑ ÑÑÑаниÑÑ Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñками">
+<!ENTITY other.label "ÐобавиÑÑ Ð´ÑÑгÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
+<!ENTITY other.accesskey "б">
+
+<!ENTITY fromWeb.description "ÐожалÑйÑÑа, подÑвеÑдиÑе, ÑÑо Ð²Ñ Ð´ÐµÐ¹ÑÑвиÑелÑно Ñ
оÑиÑе добавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð½Ð° ÑÑÐ¾Ñ ÑпиÑок ÑилÑÑÑов. ÐÑ Ð¼Ð¾Ð¶ÐµÑе измениÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ и адÑÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки пеÑед добавлением.">
+<!ENTITY edit.description "ÐÑ Ð¼Ð¾Ð¶ÐµÑе измениÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ и адÑÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки по надобноÑÑи.">
+<!ENTITY external.description "ÐÑо внеÑнÑÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñка, ÑÑи ÑилÑÑÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÑÑÑÑÑ ÑаÑÑиÑением, коÑоÑое добавило ÑÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ.">
+
+<!ENTITY location.label "ÐдÑÐµÑ ÑпиÑка ÑилÑÑÑов:">
+<!ENTITY location.accesskey "д">
+<!ENTITY title.label "Ðазвание подпиÑки:">
+<!ENTITY title.accesskey "з">
+<!ENTITY autodownload.label "ÐбновлÑÑÑ Ð°Ð²ÑомаÑиÑеÑки">
+<!ENTITY autodownload.accesskey "Ñ">
+
+<!ENTITY supplementMessage "ÐÑÐ¾Ñ ÑпиÑок ÑилÑÑÑов должен иÑполÑзоваÑÑÑÑ Ð² комбинаÑии Ñо ÑпиÑком ÑилÑÑÑов «?1?», коÑоÑÑй Ð²Ñ Ð½Ðµ иÑполÑзÑеÑе.">
+<!ENTITY addMain.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð½Ð° ÑпиÑок ÑилÑÑÑов «?1?»">
+<!ENTITY addMain.accesskey "в">
diff --git a/chrome/locale/sk/about.dtd b/chrome/adblockplus.jar!/locale/sk/about.dtd
similarity index 100%
rename from chrome/locale/sk/about.dtd
rename to chrome/adblockplus.jar!/locale/sk/about.dtd
diff --git a/chrome/locale/sk/composer.dtd b/chrome/adblockplus.jar!/locale/sk/composer.dtd
similarity index 100%
rename from chrome/locale/sk/composer.dtd
rename to chrome/adblockplus.jar!/locale/sk/composer.dtd
diff --git a/chrome/locale/sk/global.properties b/chrome/adblockplus.jar!/locale/sk/global.properties
similarity index 100%
rename from chrome/locale/sk/global.properties
rename to chrome/adblockplus.jar!/locale/sk/global.properties
diff --git a/chrome/locale/sk/overlay.dtd b/chrome/adblockplus.jar!/locale/sk/overlay.dtd
similarity index 100%
rename from chrome/locale/sk/overlay.dtd
rename to chrome/adblockplus.jar!/locale/sk/overlay.dtd
diff --git a/chrome/locale/sk/sendReport.dtd b/chrome/adblockplus.jar!/locale/sk/sendReport.dtd
similarity index 100%
rename from chrome/locale/sk/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/sk/sendReport.dtd
diff --git a/chrome/locale/sk/settings.dtd b/chrome/adblockplus.jar!/locale/sk/settings.dtd
similarity index 100%
rename from chrome/locale/sk/settings.dtd
rename to chrome/adblockplus.jar!/locale/sk/settings.dtd
diff --git a/chrome/locale/sk/sidebar.dtd b/chrome/adblockplus.jar!/locale/sk/sidebar.dtd
similarity index 100%
rename from chrome/locale/sk/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/sk/sidebar.dtd
diff --git a/chrome/locale/sk/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/sk/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/sk/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/sk/subscriptionSelection.dtd
diff --git a/chrome/locale/sl/about.dtd b/chrome/adblockplus.jar!/locale/sl/about.dtd
similarity index 100%
rename from chrome/locale/sl/about.dtd
rename to chrome/adblockplus.jar!/locale/sl/about.dtd
diff --git a/chrome/locale/sl/composer.dtd b/chrome/adblockplus.jar!/locale/sl/composer.dtd
similarity index 100%
rename from chrome/locale/sl/composer.dtd
rename to chrome/adblockplus.jar!/locale/sl/composer.dtd
diff --git a/chrome/locale/sl/global.properties b/chrome/adblockplus.jar!/locale/sl/global.properties
similarity index 100%
rename from chrome/locale/sl/global.properties
rename to chrome/adblockplus.jar!/locale/sl/global.properties
diff --git a/chrome/locale/sl/overlay.dtd b/chrome/adblockplus.jar!/locale/sl/overlay.dtd
similarity index 100%
rename from chrome/locale/sl/overlay.dtd
rename to chrome/adblockplus.jar!/locale/sl/overlay.dtd
diff --git a/chrome/locale/sl/sendReport.dtd b/chrome/adblockplus.jar!/locale/sl/sendReport.dtd
similarity index 100%
rename from chrome/locale/sl/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/sl/sendReport.dtd
diff --git a/chrome/locale/sl/settings.dtd b/chrome/adblockplus.jar!/locale/sl/settings.dtd
similarity index 100%
rename from chrome/locale/sl/settings.dtd
rename to chrome/adblockplus.jar!/locale/sl/settings.dtd
diff --git a/chrome/locale/sl/sidebar.dtd b/chrome/adblockplus.jar!/locale/sl/sidebar.dtd
similarity index 100%
rename from chrome/locale/sl/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/sl/sidebar.dtd
diff --git a/chrome/locale/sl/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/sl/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/sl/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/sl/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/sq/about.dtd b/chrome/adblockplus.jar!/locale/sq/about.dtd
new file mode 100644
index 0000000..b962ba7
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/about.dtd
@@ -0,0 +1,8 @@
+<!ENTITY dialog.title "Rreth Adblock Plus">
+<!ENTITY version.title "Versioni">
+<!ENTITY description "Adblock ju lejon të vendosni çfarë doni të shihni në faqen që hapni. Nuk ka nevojë të ju hapen të gjitha reklamat më, nëse nuk i doni!">
+<!ENTITY homepage.label "Adblock Plus internet faqja">
+<!ENTITY author.label "Autori">
+<!ENTITY contributors.label "Kontribuuesit">
+<!ENTITY subscriptionAuthors.label "Filtrim i autoreve sipas abonimit:">
+<!ENTITY translators.label "Perkthyesit:">
diff --git a/chrome/adblockplus.jar!/locale/sq/composer.dtd b/chrome/adblockplus.jar!/locale/sq/composer.dtd
new file mode 100644
index 0000000..b897243
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/composer.dtd
@@ -0,0 +1,47 @@
+<!ENTITY dialog.title "Shtim rregulli filtrimi ne Adblock Plus">
+<!ENTITY accept.label "Shto filtrin">
+<!ENTITY advanced.label "Pamja e avancuar">
+<!ENTITY basic.label "Pamja e zakonshme">
+<!ENTITY disabled.warning "Aktualisht Adblock Plus eshte i bllokuar. Ju mund te shtoni filtra por ata nuk do te aplikohen deri sa ju te [link]aktivizoni Adblock Plus[/link].">
+<!ENTITY groupDisabled.warning "Grupi i filtrave "?1?" ku do te shtohet ky filter eshte aktualisht i bllokuar. Ju mund ta shtoni filtrin por nuk do te aplikohet deri sa ju te [link]aktivizoni kete grup filtrash[/link].">
+<!ENTITY filter.label "Filtrues i ri:">
+<!ENTITY filter.accesskey "f">
+<!ENTITY preferences.label "Trego filtruesit ekzistues...">
+<!ENTITY preferences.accesskey "S">
+<!ENTITY type.filter.label "Blloko filtruesin">
+<!ENTITY type.filter.accesskey "B">
+<!ENTITY type.whitelist.label "Mos përfill">
+<!ENTITY type.whitelist.accesskey "x">
+<!ENTITY pattern.label "Shiko per model">
+<!ENTITY pattern.explanation "Modeli mund te jete cfaredo pjese e adreses; yjet (*) veprojne si pergjithesues. Filtri do ti aplikohet vetem adresave te cilat perputhen me modelin e dhene.">
+<!ENTITY regexp.warning "Modeli qe ju dhate do te interpretohet si nje shprehje e rregullt e cila nuk mund te perpunohet sakte nga Adblock Plus dhe mund te ngadalesoje lundrimin tuaj. Nese ju nuk deshironi te perdorni nje shprehje te rregullt, shtoni nje yll (*) ne fund te modelit.">
+<!ENTITY shortpattern.warning "Modeli qe ju dhate eshte shume i shkurter per te qene optimal dhe mund te ngadalesoje lundrimin tuaj. Rekomandohet qe ju te zgjidhni nje fjale me te gjate per kete filter, ne menyre qe te lejoni Adblock Plus te perpunoje filtrin ne menyre me efikase.">
+<!ENTITY match.warning "Modeli qe ju dhate nuk perputhet me adresen e cila do te bllokohet/lejohet dhe nuk do te kete asnje efekt.">
+<!ENTITY custom.pattern.label "Përshtatja:">
+<!ENTITY custom.pattern.accesskey "C">
+<!ENTITY anchors.label "Prano modelin vetem:">
+<!ENTITY anchor.start.label "ne fillimin e adreses">
+<!ENTITY anchor.start.accesskey "g">
+<!ENTITY anchor.start.flexible.label "ne fillimin e emrit te domain">
+<!ENTITY anchor.start.flexible.accesskey "g">
+<!ENTITY anchor.end.label "në fund të adresës">
+<!ENTITY anchor.end.accesskey "n">
+<!ENTITY options.label "Mundësitë">
+<!ENTITY domainRestriction.label "Vetem ne domain:">
+<!ENTITY domainRestriction.accesskey "d">
+<!ENTITY domainRestriction.help "Ky funksion perdoret per te percaktuar nje ose me shume domain te ndare nga nje vije (|). Filtri do ti aplikohet vetem domain(eve) te perzgjedhur. Nje tilde (~) perpara emrit te domain tregon qe filtri nuk do te aplikohet ne kete domain.">
+<!ENTITY firstParty.label "Vetëm pjesa e parë">
+<!ENTITY firstParty.accesskey "r">
+<!ENTITY thirdParty.label "Vetëm pjesa e tretë">
+<!ENTITY thirdParty.accesskey "T">
+<!ENTITY matchCase.label "Sipas germave:">
+<!ENTITY matchCase.accesskey "M">
+<!ENTITY types.label "Apliko në llojet:">
+<!ENTITY selectAllTypes.label "Selekto të gjitha">
+<!ENTITY unselectAllTypes.label "Mos selekto asnjë">
+<!ENTITY collapse.label "Mbyll te bllokuarat:">
+<!ENTITY collapse.accesskey "I">
+<!ENTITY collapse.default.yes.label "Përdor të parazgjedhurën (po):">
+<!ENTITY collapse.default.no.label "Përdor të parazgjedhurën (jo):">
+<!ENTITY collapse.yes.label "Po">
+<!ENTITY collapse.no.label "Jo">
diff --git a/chrome/adblockplus.jar!/locale/sq/global.properties b/chrome/adblockplus.jar!/locale/sq/global.properties
new file mode 100644
index 0000000..9aacf46
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=Klikoni ketu per te hapur menune kontekstuale, klikoni me butonin e mesit te mausit per ta aktivizuar/ç'aktivizuar.
+action1_tooltip=Klikoni per te hapur/mbyllur objektet e bllokueshme, klikoni me butonin e mesit te mausit per ta aktivizuar/ç'aktivizuar.
+action2_tooltip=Klikoni per te hapur parametrat, klikoni me butonin e mesit te mausit per ta aktivizuar/ç'aktivizuar.
+action3_tooltip=Aktivizim/çaktivizo Adblock Plus.
+disabled_tooltip=Adblock Plus është ç'aktiv.
+active_tooltip=Adblock Plus eshte aktivm, jane ne perdorim ?1? abonime filtrash dhe ?2? filtra personale.
+whitelisted_tooltip=Adblock Plus është aktiv por i pasivizuar në këtë faqe.
+blocked_count_tooltip=?1?jasht nga ?2?
+blocked_count_addendum=(gjithashtu te lejuar: ?1?, fshehur: ?2?)
+no_blocking_suggestions=S'ka elemente bllokuese në këtë faqe
+whitelisted_page=Adblock Plus eshte ç'aktivizuar per faqen aktuale
+whitelist_description=Rregullat personale të përjashtimit
+filterlist_description=Rregullat personale të bllokimit
+invalid_description=Rregullat personale jo valide
+elemhide_description=Rregullat personale të fshehjes së elementeve
+subscription_description=Filtro abonimet:
+subscription_wrong_version=Disa filtra ne kete abonim kane nevoje per Adblock Plus ?1? qe te punojne siç duhet.
+subscription_source=Burimi:
+subscription_status=Gjendja:
+subscription_status_autodownload=Freskimi automatik
+subscription_status_manualdownload=Freskimi manual
+subscription_status_externaldownload=Freskuar nga jashtë (shtesë tjetër)
+subscription_status_lastdownload=Shkarkimi i fundit:
+subscription_status_lastdownload_inprogress=Duke u shkarkuar...
+subscription_status_lastdownload_unknown=N/D
+remove_subscription_warning=Jeni i sigurt qe deshironi te hiqni kete abonim?
+import_filters_wrong_version=Kujdes: disa nga filtrat ne kete liste kane nevoje per Adblock Plus ?1? qe te punojne siç duhet. Ndoshta ju duhet te merrni versionin me te fundit te Adblock Plus perpara se te importoni kete liste.
+import_filters_warning=Deshironi te mbivendosni filtrat tuaj aktuale apo te shtoni filtrat e rinj ne fund te listes?
+import_filters_title=Importo filtrues
+export_filters_title=Eksporto filtrues
+invalid_filters_file=Ky nuk eshte skedar i vlefshem Adblock Plus.
+filters_write_error=Pati nje gabim gjate shkrimit te filtrave ne skedar. Ju lutem sigurohuni qe skedari nuk eshte i mbrojtur per shkrimin dhe qe te mos jete i hapur ne ndonje aplikacion tjeter.
+clearall_warning=Jeni i sigurt qe deshironi te hiqni te gjithe filtrat nga lista?
+resethitcounts_warning=Jeni i sigurt qe deshironi te zeroni numerimin e vizitave per te gjithe filtrat? Shenim: ky veprim nuk mund te zhbehet.
+resethitcounts_selected_warning=Jeni i sigurt qe deshironi te zeroni numerimin e vizitave per filtrat e perzgjedhur? Shenim: ky veprim nuk mund te zhbehet.
+filter_regexp_tooltip=Ky filter eshte ose nje shprehje e rregullt ose shume e shkurter per tu bere optimal. Shume nga keto lloj filtrash mund te ngadalesojne lundrimin tuaj ne internet.
+filter_elemhide_duplicate_id=Vetem nje ID elementi qe do te fshihet mund te percaktohet
+filter_elemhide_nocriteria=Nuk eshte percaktuar asnje kriter per te njohur elementin i cili do te fshihet
+subscription_notAdded_warning=Ju nuk keni shtuar abonim ne filtra. Pa asnje abonim ne filtra juve do ju duhet te shtoni filtra Adblock Plus manualisht.
+subscription_notAdded_warning_addendum=Deshironi te vazhdoni?
+subscription_invalid_location=Vendndodhja e listes se filtra nuk eshte as nje URL e sakte e as nje emer skedari i sakte.
+synchronize_invalid_url=Gabim, nuk eshte adrese e vlefshme
+synchronize_connection_error=Gabim, shkarkim i pamundur
+synchronize_invalid_data=Gabim, liste filtrash e pavlefshme
+synchronize_checksum_mismatch=Gabim, mosperputhje e kontrollit (checksum)
+synchronize_ok=Sukses
+overwrite=Rishkruaj
+append=Shto
+new_filter_group_title=Filtrues i ri
+type_label_other=tjera
+type_label_script=skripta
+type_label_image=figura
+type_label_stylesheet=stilet
+type_label_object=objekti
+type_label_subdocument=ndarja
+type_label_document=dokumenti
+type_label_elemhide=fshehur
+type_label_xbl=XBL e detyrueshme
+type_label_ping=ping lidhje
+type_label_xmlhttprequest=kerkimi për XML
+type_label_object_subrequest=nen-kerkese objekti
+type_label_dtd=DTD
+type_label_media=tingull/video
+type_label_font=shkronjat
+fennec_status_enabled=Adblock Plus eshte aktiv.
+fennec_status_disabled=Adblock Plus eshte jo aktiv.
+fennec_status_enabled_site=Adblock Plus eshte aktiv ne ?1?.
+fennec_status_disabled_site=Adblock Plus eshte jo aktiv ne ?1?.
+sync_engine_title=Te dhenat e Adblock Plus
diff --git a/chrome/adblockplus.jar!/locale/sq/overlay.dtd b/chrome/adblockplus.jar!/locale/sq/overlay.dtd
new file mode 100644
index 0000000..f1c5785
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "Gjendja:">
+<!ENTITY blocked.tooltip "Artikuj te bllokuar ne kete faqe:">
+<!ENTITY filters.tooltip "Filtruesit më aktivë:">
+<!ENTITY menuitem.label "Parapëlqimet e Adblock Plus">
+<!ENTITY menuitem.accesskey "B">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: Gjërat e bllokuara">
+<!ENTITY context.image.label "Adblock Plus: Figurat e bllokuara">
+<!ENTITY context.object.label "Adblock Plus: Objektet e bllokuara">
+<!ENTITY context.frame.label "Adblock Plus: Pjesët e bllokuara">
+<!ENTITY context.media.label "Adblock Plus: Bllokim audio/video">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: Rilejo në këtë faqe">
+<!ENTITY sidebar.title "Artikuj qe mund te bllokohen ne kete faqe">
+<!ENTITY sendReport.label "Raportoni probleme ne kete faqe">
+<!ENTITY sendReport.accesskey "R">
+<!ENTITY settings.label "Parapëlqimet">
+<!ENTITY settings.accesskey "P">
+<!ENTITY opensidebar.label "Hap elementet bllokuese">
+<!ENTITY opensidebar.accesskey "B">
+<!ENTITY closesidebar.label "Mbyll elementet bllokuese">
+<!ENTITY closesidebar.accesskey "B">
+<!ENTITY whitelist.site.label "Ãaktivizo në ?1?">
+<!ENTITY whitelist.page.label "Ãaktivizo vetëm në këtë faqe">
+<!ENTITY disable.label "Blloko gjithandej">
+<!ENTITY recommend.label "Na rekomandoni ne Facebook">
+<!ENTITY objecttab.title "Blloko">
+<!ENTITY objecttab.tooltip "Klikoni ketu per te bllokuar kete objekt me Adblock Plus">
diff --git a/chrome/adblockplus.jar!/locale/sq/sendReport.dtd b/chrome/adblockplus.jar!/locale/sq/sendReport.dtd
new file mode 100644
index 0000000..e4a61a4
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/sendReport.dtd
@@ -0,0 +1,75 @@
+<!ENTITY wizard.title "Raportuesi i problemeve">
+<!ENTITY privacyPolicy.label "Rregulli i te dhenave vetjake">
+<!ENTITY dataCollector.heading "Mire se vini ne raportuesin e problemeve">
+<!ENTITY dataCollector.description "Ju lutem prisni disa momente deri sa Adblock Plus te mbledhe te gjitha te dhenat e nevojshme.">
+<!ENTITY typeSelector.heading "Lloji i problemit">
+<!ENTITY typeSelector.description "Kjo dritare do ju udhezoje neper gjithe hapat e nevojshem per dergimin e raportit te problemeve me Adblock Plus. Si fillim, ju lutem zgjidhni tipin e problemit qe ju vereni me kete faqe:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus po bllokon shume">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "Zgjidhni kete mundesi nese faqes i mungon permbajtja e rendesishme, shfaqet gabim ose nuk funksionon ne rregull. Ju mund te percaktoni nese problemi eshte Adblock Plus duke e fikur ate perkohesisht.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus nuk po bllokon nje reklame">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "Zgjidhni kete mundesi nese nje reklame shfaqet edhe pse Adblock Plus eshte aktiv.">
+<!ENTITY typeSelector.other.label "Problem tjeter">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY typeSelector.other.description "Zgjidhni kete mundesi nese ju dyshoni se eshte nje problem me vete Adblock Plus ne vend te filtrave te tij.">
+<!ENTITY showRecentReports.label "Afisho raportimet e derguara se fundmi">
+<!ENTITY recentReports.label "Raportimet tuaja me te fundit">
+<!ENTITY recentReports.clear.label "Hiq gjithe raportimet">
+<!ENTITY recentReports.clear.accesskey "R">
+<!ENTITY issues.description "Adblock Plus ka dalluar probleme me konfigurimin tuaj i cili mund te jete pergjegjes per kete problem ose do te veshtiresoje hetimin e raportit.">
+<!ENTITY issues.whitelist.description "Adblock Plus eshte aktualisht jo-aktiv ne faqen ne te cilen ju po raportoni. Ju lutem ri-aktivizojeni ate dhe ringarkoni faqen perpara se te dergoni raportin i cili do te ndihmoje ne hetimin e metejshem te ketij problemi.">
+<!ENTITY issues.whitelist.remove.label "Ri-aktivizo Adblock Plus ne kete faqe">
+<!ENTITY issues.disabled.description "Adblock Plus eshte jo-aktiv, ai nuk do te bllokoje asnje gje ne gjendjen aktuale.">
+<!ENTITY issues.disabled.enable.label "Aktivizo Adblock Plus">
+<!ENTITY issues.nofilters.description "Adblock Plus nuk eshte duke bllokuar asgje ne faqen aktuale. Ky problem qe ju po vereni ka shume mundesi qe nuk ka fare lidhje me Adblock Plus.">
+<!ENTITY issues.nosubscriptions.description "Duket sikur ju nuk keni asnje abonim ne filtrat e gatshem te cilet heqin automatikisht permbajtjen e padeshiruar nga faqet web.">
+<!ENTITY issues.nosubscriptions.add.label "Shto abonim ne filtra">
+<!ENTITY issues.subscriptionCount.description "Duket sikur ju jeni abonuar ne shume filtra. Ky konfigurim nuk rekomandohet sepse to te shtoje rastet e problemeve te njejta. Gjithashtu ne nuk mund te pranojme raportimin tuaj te problemeve sepse eshet i paqarte se me ke abonim filtri autori duhet te veproje. Ju lutem hiqni te gjithe abonimet ne filtra perveç atyre te nevojshem dhe provoni nese problemi do te jete perseri.">
+<!ENTITY issues.openPreferences.label "Hap parametrat e filtrave">
+<!ENTITY issues.ownfilters.description "Disa nga filtrat e aplikuar ne kete faqe jane te percaktuar nga perdoruesi. Ju lutem bllokoni filtrat te cilet mund te kene shkaktuar kete problem:">
+<!ENTITY issues.ownfilters.disable.label "Blloko filtrin">
+<!ENTITY issues.disabledgroups.description "Abonimet e meposhtme ne filtra/grupe filtrash jane te bllokuar, gjithashtu ata mund te kene efikasitet ne kete faqe:">
+<!ENTITY issues.disabledgroups.enable.label "Aktivizo abonim filtri/grup filtrash">
+<!ENTITY issues.disabledfilters.description "Filtrat e meposhtem jane te bllokuar, gjithashtu ata mund te kene efikasitet ne kete faqe:">
+<!ENTITY issues.disabledfilters.enable.label "Aktivizo filtrin">
+<!ENTITY issues.override.label "Konfigurimi eshte i sakte, vazhdoni me raportimin">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY issues.change.description "Konfigurimi juaj ka ndryshuar. Ju lutem ri-ngarkoni faqen per te provuar ndryshimet dhe per te derguar nje raportim nese problemi nuk eshte zgjidhur nga ndryshimet ne konfigurim.">
+<!ENTITY typeWarning.description "Ju keni treguar se deshironi te raportoni nje problem te pergjithshem me Adblock Plus ne vend te nje problemi me filtrat. Ju lutem kini parasysh se keto probleme raportohen me mire ne [link]forumin Adblock Plus[/link]. Ju duhet te perdorni raportimin e problemeve vetem si shtese te nje diskutimi ekzistues, sepse askush nuk do ta vere re raportimin tuaj, vetem nese ju jepni nje adrese te problemit. Adrese e krijuar automatikisht do ju jepet pasi ju te keni derguar raportin.">
+<!ENTITY typeWarning.override.label "Une kuptoj dhe deshiroj te dergoj raportin gjithsesi">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "Ringarko faqen">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "Bashkangjit foto">
+<!ENTITY screenshot.description "E njejta faqe mund te duket ndryshe per njerez te ndryshem. Mund te na ndihmoje ne kuptimin e problemit nese ju bashkangjisni nje foto raportimit tuaj. Ju mund te hiqni ose mbuloni fusha te cilat permbajne informacion te rendesishem dhe personal dhe gjithashtu mund te shenoni zonat ku eshte i dukshem problemi. Per te bere kete klikoni butonin e duhur dhe zgjidhni nje zone te fotos me mausin tuaj.">
+<!ENTITY screenshot.attach.label "Bashkangjit nje faqe me imazh ketij raportimi">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY screenshot.mark.label "Shenoni problemin">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "Hiqni te dhenat personale">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY screenshot.undo.label "Zhbeje">
+<!ENTITY screenshot.undo.accesskey "U">
+<!ENTITY commentPage.heading "Koment">
+<!ENTITY commentPage.description "Fusha e meposhtme ju lejon qe te jepni nje koment qe te na ndihmoje ne ta kuptojme me mire problemin. Ky hap eshte fakultativ por i rekomanduar nese problemi nuk eshte lehtesisht i dallueshem. Ju mund te rishikoni gjithashtu te dhenat e raportimit perpara se te dergohet.">
+<!ENTITY comment.label "Koment (fakultative):">
+<!ENTITY comment.accesskey "C">
+<!ENTITY comment.lengthWarning "Gjatesia e komentit tuaj i kapercent 1000 karaktere. Vetem 1000 karakteret e para do te dergohen se bashku me raportin.">
+<!ENTITY email.label "Adresa e-mail per kontakte te metejshe (fakultative):">
+<!ENTITY email.accesskey "m">
+<!ENTITY attachExtensions.label "Bashkangjisni nje liste te prapashtesave aktive ne raportim, ne rast se shkaku i problemit eshte nje konflikt ndermjet moduleve.">
+<!ENTITY attachExtensions.accesskey "x">
+<!ENTITY sendButton.label "Dergo raportin">
+<!ENTITY sendButton.accesskey "n">
+<!ENTITY showData.label "Afisho permbajtjen e raportit">
+<!ENTITY data.label "Permbajtja e raportit:">
+<!ENTITY data.accesskey "p">
+<!ENTITY sendPage.heading "Dergo raportin">
+<!ENTITY sendPage.waitMessage "Ju lutem prisni sa Adblock Plus te dergoje raportin tuaj.">
+<!ENTITY sendPage.confirmation "Raporti juaj eshte ruajtur. Ju mund ta shikoni ate ne kete adrese:">
+<!ENTITY sendPage.knownIssue "Problemi qe ju keni raportuar ka shume mundesi te jete i njohur. Per me shume informacion:">
+<!ENTITY sendPage.errorMessage "Tentativa per te derguar raportin ngeci me kodin e gabimit "?1?". Ju lutem sigurohuni qe jeni te lidhur ne internet dhe provoni perseri. Nese ky problem perseritet kerkoni ndihme ne [link]forumin e Adblock Plus[/link].">
+<!ENTITY sendPage.retry.label "Dergo perseri">
+<!ENTITY copyLink.label "KOpjo adresen e raportit">
+<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/adblockplus.jar!/locale/sq/settings.dtd b/chrome/adblockplus.jar!/locale/sq/settings.dtd
new file mode 100644
index 0000000..e4fadc7
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Parapëlqimet e Adblock Plus">
+<!ENTITY filters.label "Filtruesit">
+<!ENTITY filters.accesskey "L">
+<!ENTITY add.label "Vendos filtrues">
+<!ENTITY add.accesskey "A">
+<!ENTITY addsubscription.label "Shto abonim ne filter">
+<!ENTITY addsubscription.accesskey "S">
+<!ENTITY synchsubscriptions.label "Rifresko te gjitha abonimet">
+<!ENTITY synchsubscriptions.accesskey "D">
+<!ENTITY import.label "Importo filtrues">
+<!ENTITY import.accesskey "M">
+<!ENTITY export.label "Eksporto filtruesit ekzistues">
+<!ENTITY export.accesskey "X">
+<!ENTITY clearall.label "Largo të gjithë filtruesit ekxistues">
+<!ENTITY clearall.accesskey "L">
+<!ENTITY resethitcounts.label "Rishkruaj statistikat">
+<!ENTITY resethitcounts.accesskey "R">
+<!ENTITY edit.label "Redakto">
+<!ENTITY edit.accesskey "E">
+<!ENTITY cut.label "Kopjo-largo">
+<!ENTITY cut.accesskey "T">
+<!ENTITY copy.label "Kopjo">
+<!ENTITY copy.accesskey "K">
+<!ENTITY paste.label "Hedh">
+<!ENTITY paste.accesskey "P">
+<!ENTITY remove.label "Fshije">
+<!ENTITY remove.accesskey "F">
+<!ENTITY menu.find.label "Kërko">
+<!ENTITY menu.find.accesskey "O">
+<!ENTITY menu.findagain.label "Kërko përsëri">
+<!ENTITY menu.findagain.accesskey "G">
+<!ENTITY view.label "Shih">
+<!ENTITY view.accesskey "V">
+<!ENTITY sort.label "Radhit sipas">
+<!ENTITY sort.accesskey "R">
+<!ENTITY sort.none.label "Pa radhitur">
+<!ENTITY sort.none.accesskey "P">
+<!ENTITY sort.ascending.label "A > Z radhitje">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Z > A radhitje">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Mundësitë">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "Aktivizo Adblock Plus">
+<!ENTITY enable.accesskey "N">
+<!ENTITY showintoolbar.label "Afisho ne shiritin e mjeteve">
+<!ENTITY showintoolbar.accesskey "B">
+<!ENTITY showinstatusbar.label "Afisho ne shiritin e gjendjes">
+<!ENTITY showinstatusbar.accesskey "S">
+<!ENTITY objecttabs.label "Afisho skedat ne Flash dhe Java">
+<!ENTITY objecttabs.accesskey "T">
+<!ENTITY collapse.label "Mblidhi elementet e bllokuar">
+<!ENTITY collapse.accesskey "L">
+<!ENTITY sync.label "Sinkronizo parametrat e Adblock Plus">
+<!ENTITY sync.accesskey "c">
+<!ENTITY help.label "Ndihmë">
+<!ENTITY help.accesskey "H">
+<!ENTITY gettingStarted.label "Fillo">
+<!ENTITY gettingStarted.accesskey "s">
+<!ENTITY faq.label "Pyetje e zakonshme">
+<!ENTITY faq.accesskey "F">
+<!ENTITY filterdoc.label "Duke shkruar filtruesit e Adblock Plus">
+<!ENTITY filterdoc.accesskey "R">
+<!ENTITY about.label "Rreth Adblock Plus">
+<!ENTITY about.accesskey "B">
+<!ENTITY description "Filtrat e meposhtem percaktojne cilat adresa duhet te bllokohen dhe cilat duhet te lejohen:">
+<!ENTITY filter.column "Rregulla e filtrimit">
+<!ENTITY filter.accesskey "F">
+<!ENTITY slow.column "Filtruesit e ngadalshëm">
+<!ENTITY slow.accesskey "w">
+<!ENTITY enabled.column "Aktivizo">
+<!ENTITY enabled.accesskey "n">
+<!ENTITY hitcount.column "Shtypje">
+<!ENTITY hitcount.accesskey "H">
+<!ENTITY lasthit.column "Shtypja e fundit">
+<!ENTITY lasthit.accesskey "L">
+<!ENTITY context.edit.label "Redakto filtruesin">
+<!ENTITY context.resethitcount.label "Zero statistikat e vizitave per filtrin">
+<!ENTITY context.synchsubscription.label "Rifresko abonimin tani">
+<!ENTITY context.editsubscription.label "Modifiko abonimin">
+<!ENTITY context.moveup.label "Zhvendos filtruesin sipër">
+<!ENTITY context.movedown.label "Zhvendos filtruesin poshtë">
+<!ENTITY context.movegroupup.label "Zhvendos grupin sipër">
+<!ENTITY context.movegroupdown.label "Zhvendos grupin poshtë">
+<!ENTITY context.enable.label "Aktivizo">
+<!ENTITY context.disable.label "Ã'aktivizoj">
+<!ENTITY apply.label "Ruaji">
+<!ENTITY apply.accesskey "p">
+<!ENTITY fennec.subscription.label "Abonim ne filter">
diff --git a/chrome/adblockplus.jar!/locale/sq/sidebar.dtd b/chrome/adblockplus.jar!/locale/sq/sidebar.dtd
new file mode 100644
index 0000000..f1ef281
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/sidebar.dtd
@@ -0,0 +1,35 @@
+<!ENTITY detached.title "Adblock Plus: Artikuj qe mund te bllokohen (shekputur)">
+<!ENTITY detach.label "Shkeput">
+<!ENTITY reattach.label "Ri-bashkoni">
+<!ENTITY search.label "Kërko">
+<!ENTITY search.accesskey "K">
+<!ENTITY type.label "Lloji">
+<!ENTITY address.label "Adresa">
+<!ENTITY filter.label "Filtruesi">
+<!ENTITY state.label "Gjendja">
+<!ENTITY size.label "Madhësia">
+<!ENTITY docDomain.label "Burimi i dokumentit">
+<!ENTITY docDomain.thirdParty "(pale e trete)">
+<!ENTITY docDomain.firstParty "(pala kryesore)">
+<!ENTITY noitems.label "S'ka elemente bllokuese">
+<!ENTITY whitelisted.label "Faqja e listes se lejimit">
+<!ENTITY tooltip.address.label "Adresa:">
+<!ENTITY tooltip.type.label "Lloji:">
+<!ENTITY tooltip.type.blocked "(bllokuar)">
+<!ENTITY tooltip.type.whitelisted "(lejuar)">
+<!ENTITY tooltip.size.label "Madhësia:">
+<!ENTITY tooltip.docDomain.label "Burimi i dokumentit:">
+<!ENTITY tooltip.filter.label "Filtruesi efektiv:">
+<!ENTITY tooltip.filter.disabled "(bllokuar)">
+<!ENTITY tooltip.filterSource.label "Burimi i filtruesit:">
+<!ENTITY context.block.label "Blloko këtë send">
+<!ENTITY context.editfilter.label "Vendos filtruesin në veprim">
+<!ENTITY context.whitelist.label "Shto rregull perjashtimi per artikullin">
+<!ENTITY context.disablefilter.label "Ãaktivizo filtruesin ?1?">
+<!ENTITY context.enablefilter.label "Ri mundëso filtruesin ?1?">
+<!ENTITY context.disablefilteronsite.label "Pamundëso filtruesin në ?1?">
+<!ENTITY context.open.label "Hape një një lidhje të re">
+<!ENTITY context.flash.label "Pulso bordurat e artikullit">
+<!ENTITY context.copy.label "Kopjo adresën e elementit">
+<!ENTITY context.copyFilter.label "Kopjo filtruesin">
+<!ENTITY context.selectAll.label "Selekto të gjitha">
diff --git a/chrome/adblockplus.jar!/locale/sq/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/sq/subscriptionSelection.dtd
new file mode 100644
index 0000000..a72e04a
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/sq/subscriptionSelection.dtd
@@ -0,0 +1,25 @@
+<!ENTITY dialog.title "Shto abonim filtri ne Adblock Plus">
+<!ENTITY dialog.title.edit "Modifiko abonim filtri">
+<!ENTITY description.newInstall "Adblock Plus do te jete me efikas nese ju shtoni abonime ne filtra. Abonimet ne filtra jane dhene falas nga perdorues te tjere te Adblock Plus. Abonimi me i pershtatshem per gjuhen tuaj eshte zgjedhur.">
+<!ENTITY subscriptionSelector.label "Ju lutem zgjidhni nje abonim ne filter nga lista:">
+<!ENTITY viewList.label "Shiko filtrat">
+<!ENTITY visitHomepage.label "Vizito faqen web">
+<!ENTITY addSubscription.label "Shto abonim">
+<!ENTITY saveSubscription.label "Ruaj abonimin">
+<!ENTITY other.label "Shto nje abonim tjeter">
+<!ENTITY other.accesskey "J">
+<!ENTITY list.download.failed "Adblock Plus nuk arriti te gjeje listen e abonimeve.">
+<!ENTITY list.download.retry "Provoni perseri">
+<!ENTITY list.download.website "Shikoni faqen web">
+<!ENTITY fromWeb.description "Ju lutem konfirmoni qe ju deshironi te shtoni kete abonim ne filter. Ju mund te ndryshoni titullin ose vendndodhjen e abonimit perpara se ta shtoni ate.">
+<!ENTITY edit.description "Ju mund te ndryshoni titullin e abonimit ose vendndodhjen sipas deshires.">
+<!ENTITY external.description "Ky eshte nje abonim ne nje filter te jashtem; do te marre te dhenat me te fundit nga moduli i cili e krijoi kete abonim.">
+<!ENTITY title.label "Titulli i abonimit:">
+<!ENTITY title.accesskey "T">
+<!ENTITY location.label "Vendi i listës së filtruesit">
+<!ENTITY location.accesskey "L">
+<!ENTITY autodownload.label "Fresko Automatikisht">
+<!ENTITY autodownload.accesskey "F">
+<!ENTITY supplementMessage "Abonimi ne filter eshte menduar qe te perdoret me abonimin "?1?" te cilin ju nuk jeni duke e perdorur aktualisht.">
+<!ENTITY addMain.label "Shtoje edhe abonimin "?1?" gjithashtu">
+<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/sr/about.dtd b/chrome/adblockplus.jar!/locale/sr/about.dtd
similarity index 100%
rename from chrome/locale/sr/about.dtd
rename to chrome/adblockplus.jar!/locale/sr/about.dtd
diff --git a/chrome/locale/sr/composer.dtd b/chrome/adblockplus.jar!/locale/sr/composer.dtd
similarity index 100%
rename from chrome/locale/sr/composer.dtd
rename to chrome/adblockplus.jar!/locale/sr/composer.dtd
diff --git a/chrome/locale/sr/global.properties b/chrome/adblockplus.jar!/locale/sr/global.properties
similarity index 100%
rename from chrome/locale/sr/global.properties
rename to chrome/adblockplus.jar!/locale/sr/global.properties
diff --git a/chrome/locale/sr/overlay.dtd b/chrome/adblockplus.jar!/locale/sr/overlay.dtd
similarity index 100%
rename from chrome/locale/sr/overlay.dtd
rename to chrome/adblockplus.jar!/locale/sr/overlay.dtd
diff --git a/chrome/locale/sr/sendReport.dtd b/chrome/adblockplus.jar!/locale/sr/sendReport.dtd
similarity index 100%
rename from chrome/locale/sr/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/sr/sendReport.dtd
diff --git a/chrome/locale/sr/settings.dtd b/chrome/adblockplus.jar!/locale/sr/settings.dtd
similarity index 100%
rename from chrome/locale/sr/settings.dtd
rename to chrome/adblockplus.jar!/locale/sr/settings.dtd
diff --git a/chrome/locale/sr/sidebar.dtd b/chrome/adblockplus.jar!/locale/sr/sidebar.dtd
similarity index 100%
rename from chrome/locale/sr/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/sr/sidebar.dtd
diff --git a/chrome/locale/sr/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/sr/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/sr/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/sr/subscriptionSelection.dtd
diff --git a/chrome/locale/sv-SE/about.dtd b/chrome/adblockplus.jar!/locale/sv-SE/about.dtd
similarity index 100%
rename from chrome/locale/sv-SE/about.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/about.dtd
diff --git a/chrome/locale/sv-SE/composer.dtd b/chrome/adblockplus.jar!/locale/sv-SE/composer.dtd
similarity index 100%
rename from chrome/locale/sv-SE/composer.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/composer.dtd
diff --git a/chrome/locale/sv-SE/global.properties b/chrome/adblockplus.jar!/locale/sv-SE/global.properties
similarity index 100%
rename from chrome/locale/sv-SE/global.properties
rename to chrome/adblockplus.jar!/locale/sv-SE/global.properties
diff --git a/chrome/locale/sv-SE/overlay.dtd b/chrome/adblockplus.jar!/locale/sv-SE/overlay.dtd
similarity index 100%
rename from chrome/locale/sv-SE/overlay.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/overlay.dtd
diff --git a/chrome/locale/sv-SE/sendReport.dtd b/chrome/adblockplus.jar!/locale/sv-SE/sendReport.dtd
similarity index 100%
rename from chrome/locale/sv-SE/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/sendReport.dtd
diff --git a/chrome/locale/sv-SE/settings.dtd b/chrome/adblockplus.jar!/locale/sv-SE/settings.dtd
similarity index 100%
rename from chrome/locale/sv-SE/settings.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/settings.dtd
diff --git a/chrome/locale/sv-SE/sidebar.dtd b/chrome/adblockplus.jar!/locale/sv-SE/sidebar.dtd
similarity index 100%
rename from chrome/locale/sv-SE/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/sidebar.dtd
diff --git a/chrome/locale/sv-SE/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/sv-SE/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/sv-SE/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/sv-SE/subscriptionSelection.dtd
diff --git a/chrome/locale/th/about.dtd b/chrome/adblockplus.jar!/locale/th/about.dtd
similarity index 100%
rename from chrome/locale/th/about.dtd
rename to chrome/adblockplus.jar!/locale/th/about.dtd
diff --git a/chrome/locale/th/composer.dtd b/chrome/adblockplus.jar!/locale/th/composer.dtd
similarity index 100%
rename from chrome/locale/th/composer.dtd
rename to chrome/adblockplus.jar!/locale/th/composer.dtd
diff --git a/chrome/locale/th/global.properties b/chrome/adblockplus.jar!/locale/th/global.properties
similarity index 100%
rename from chrome/locale/th/global.properties
rename to chrome/adblockplus.jar!/locale/th/global.properties
diff --git a/chrome/locale/th/overlay.dtd b/chrome/adblockplus.jar!/locale/th/overlay.dtd
similarity index 100%
rename from chrome/locale/th/overlay.dtd
rename to chrome/adblockplus.jar!/locale/th/overlay.dtd
diff --git a/chrome/locale/th/sendReport.dtd b/chrome/adblockplus.jar!/locale/th/sendReport.dtd
similarity index 100%
rename from chrome/locale/th/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/th/sendReport.dtd
diff --git a/chrome/locale/th/settings.dtd b/chrome/adblockplus.jar!/locale/th/settings.dtd
similarity index 100%
rename from chrome/locale/th/settings.dtd
rename to chrome/adblockplus.jar!/locale/th/settings.dtd
diff --git a/chrome/locale/th/sidebar.dtd b/chrome/adblockplus.jar!/locale/th/sidebar.dtd
similarity index 100%
rename from chrome/locale/th/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/th/sidebar.dtd
diff --git a/chrome/locale/th/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/th/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/th/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/th/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/locale/tr/about.dtd b/chrome/adblockplus.jar!/locale/tr/about.dtd
new file mode 100644
index 0000000..a47057b
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/about.dtd
@@ -0,0 +1,8 @@
+<!ENTITY dialog.title "Adblock Plus Hakkında">
+<!ENTITY version.title "Sürüm">
+<!ENTITY description "Adblock Plus size internette neyi görmek istediÄinize karar verme Åansı sunar. Artık istenmeyen reklamları ve tanıtımları izlemek zorunda deÄilsiniz, onları Adblock Plus'la kaldırabilirsiniz!">
+<!ENTITY homepage.label "Adblock Plus ana sayfası:">
+<!ENTITY author.label "Yazar:">
+<!ENTITY contributors.label "Katkıda bulunanlar:">
+<!ENTITY subscriptionAuthors.label "Süzgeç aboneliÄi yazarları:">
+<!ENTITY translators.label "Ãevirmenler:">
diff --git a/chrome/adblockplus.jar!/locale/tr/composer.dtd b/chrome/adblockplus.jar!/locale/tr/composer.dtd
new file mode 100644
index 0000000..85e1874
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/composer.dtd
@@ -0,0 +1,47 @@
+<!ENTITY dialog.title "Adblock Plus süzgeç kuralı ekle">
+<!ENTITY accept.label "Süzgeç ekle">
+<!ENTITY advanced.label "GeliÅmiÅ görünüm">
+<!ENTITY basic.label "Temel görünüm">
+<!ENTITY disabled.warning "Adblock Plus Åu an devre dıÅı. Yine de süzgeç ekleyebilirsiniz, ancak bunlar [link]Adblock Plus etkinleÅtirilene kadar[/link]uygulanmayacaktır.">
+<!ENTITY groupDisabled.warning "Süzgecin eklenmesi gereken "?1?" süzgeç grubu Åu an devre dıÅı. Süzgeci Åu an ekleyebilirsiniz ancak [link]süzgeç grubunu devreye soktuÄunuzda[/link]kullanılabilecektir.">
+<!ENTITY filter.label "Yeni süzgeç:">
+<!ENTITY filter.accesskey "y">
+<!ENTITY preferences.label "Mevcut süzgeçleri göster...">
+<!ENTITY preferences.accesskey "S">
+<!ENTITY type.filter.label "Engelleyen süzgeç">
+<!ENTITY type.filter.accesskey "l">
+<!ENTITY type.whitelist.label "Hariç tutma kuralı">
+<!ENTITY type.whitelist.accesskey "h">
+<!ENTITY pattern.label "Aranacak örnek">
+<!ENTITY pattern.explanation "Bu örnek adresin herhangi bir bölümü olabilir ve (*) iÅareti joker görevi yapar. Süzgeç sadece örneÄe uyan adreslere uygulanacaktır.">
+<!ENTITY regexp.warning "GirdiÄiniz örnek düzenli ifade olarak yorumlanacaktır. Ãok fazla düzenli ifade, taramayı yavaÅlatabilir. Gerçekten düzenli ifade kullanmak istediÄinizden emin deÄilseniz lütfen örneÄin sonuna (*) iÅareti koyun.">
+<!ENTITY shortpattern.warning "GirdiÄiniz örnek iyileÅtirme için çok kısa ve bu tür örnekler tarayıcı deneyiminizi yavaÅlatabilir. Adblock Plus'ın daha etkin çalıÅabilmesi için bu süzgece yönelik daha uzun bir satır seçmeniz tavsiye edilir.">
+<!ENTITY match.warning "GirdiÄiniz örnek artık engellenecek olan veya kara listeden çıkarılacak adresle uyuÅmuyor ve üzerinde hiçbir etkisi olmayacaktır.">
+<!ENTITY custom.pattern.label "Ãzel:">
+<!ENTITY custom.pattern.accesskey "z">
+<!ENTITY anchors.label "ÃrneÄi sadece burada kabul et:">
+<!ENTITY anchor.start.label "adresin baÅında">
+<!ENTITY anchor.start.accesskey "b">
+<!ENTITY anchor.start.flexible.label "alan adının baÅında">
+<!ENTITY anchor.start.flexible.accesskey "b">
+<!ENTITY anchor.end.label "adresin sonunda">
+<!ENTITY anchor.end.accesskey "o">
+<!ENTITY options.label "Seçenekler">
+<!ENTITY domainRestriction.label "Alan adına kısıtlama:">
+<!ENTITY domainRestriction.accesskey "d">
+<!ENTITY domainRestriction.help "Aralarına "|" simgesi koyarak bir ya da daha fazla alan adı belirtin. Böylece süzgeç sadece bu sitelerde uygulanacaktır. Alan adından önce "~" simgesi kullanılması, süzgecin o alan adında kullanılmaması gerektiÄi anlamına gelir.">
+<!ENTITY firstParty.label "Sadece birinci kiÅilerden">
+<!ENTITY firstParty.accesskey "i">
+<!ENTITY thirdParty.label "Sadece üçüncü kiÅilerden">
+<!ENTITY thirdParty.accesskey "c">
+<!ENTITY matchCase.label "Birebir eÅleÅme">
+<!ENTITY matchCase.accesskey "e">
+<!ENTITY types.label "Bu türlere uygula:">
+<!ENTITY selectAllTypes.label "Tümünü seç">
+<!ENTITY unselectAllTypes.label "Hiçbirini seçme">
+<!ENTITY collapse.label "Engellenenleri kapat:">
+<!ENTITY collapse.accesskey "p">
+<!ENTITY collapse.default.yes.label "Ãntanımlı kullan (evet)">
+<!ENTITY collapse.default.no.label "Ãntanımlı kullan (hayır)">
+<!ENTITY collapse.yes.label "Evet">
+<!ENTITY collapse.no.label "Hayır">
diff --git a/chrome/adblockplus.jar!/locale/tr/global.properties b/chrome/adblockplus.jar!/locale/tr/global.properties
new file mode 100644
index 0000000..7b33c9c
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/global.properties
@@ -0,0 +1,70 @@
+default_dialog_title=Adblock Plus
+action0_tooltip=İçerik menüsünü açmak için tıklayın; etkinleÅtirmek ya da devre dıÅı bırakmak için orta düÄmeye tıklayın.
+action1_tooltip=Engellenebilir öÄeleri açmak ya da kapatmak için tıklayın; etkinleÅtirmek ya da devre dıÅı bırakmak için orta düÄmeye tıklayın.
+action2_tooltip=Tercihler penceresini açmak için tıklayın; etkinleÅtirmek ya da devre dıÅı bırakmak için orta düÄmeye tıklayın.
+action3_tooltip=Adblock Plus'ı etkinleÅtirmek ya da devre dıÅı bırakmak için orta düÄmeye tıklayın.
+disabled_tooltip=Adblock Plus devre dıÅıdır.
+active_tooltip=Adblock Plus devrede ve ?1? süzgeç aboneliÄi ile ?2? özel süzgeç kullanıyor.
+whitelisted_tooltip=Adblock Plus etkin, ancak bu sayfada devre dıÅıdır.
+blocked_count_tooltip=?1? toplam ?2?
+blocked_count_addendum=(ayrıca ?1? tane ak listede, ?2? tane gizli)
+no_blocking_suggestions=Bakılan sayfada engellenebilecek bir öÄe bulunmuyor
+whitelisted_page=Adblock Plus bakılan sayfa için devre dıÅı bırakıldı
+whitelist_description=Ayrıcalıklar
+filterlist_description=Reklam süzgeçleri
+invalid_description=Geçersiz süzgeçler
+elemhide_description=ÃÄe engelleme kuralları
+subscription_description=Süzgeç abonelikleri:
+subscription_wrong_version=Bazı süzgeçlerin düzgün çalıÅabilmesi için Adblock Plus ?1? gerekiyor.
+subscription_source=Kaynak:
+subscription_status=Durum:
+subscription_status_autodownload=Otomatik olarak güncellendi
+subscription_status_manualdownload=Elle güncellendi
+subscription_status_externaldownload=DıÅarıdan güncellendi (baÅka bir eklenti tarafından)
+subscription_status_lastdownload=En son indiriÅ:
+subscription_status_lastdownload_inprogress=İndiriliyor...
+subscription_status_lastdownload_unknown=Yok
+remove_subscription_warning=Gerçekten abonelikten çıkmak istiyor musunuz?
+import_filters_wrong_version=Uyarı: Bazı süzgeçlerin düzgün çalıÅabilmesi için Adblock Plus ?1? gerekiyor. Bu listeyi içe aktarmadan önce büyük olasılıkla en güncel Adblock Plus sürümüne yükseltmeniz gerekiyor.
+import_filters_warning=Geçerli süzgeçlerinizi deÄiÅtirmek mi, yoksa yeni gelecekleri Åu anki süzgeçlerin sonuna mı eklemek istersiniz?
+import_filters_title=Süzgeçleri içe aktar
+export_filters_title=Süzgeçleri dıÅa aktar
+invalid_filters_file=Bu geçerli bir Adblock Plus süzgeç dosyası deÄildir.
+filters_write_error=Süzgeçler dosyaya yazılırken hatayla karÅılaÅıldı. Dosyanın yazmaya karÅı korunup korunmadıÄından ve baÅka bir program tarafından kullanılıp kullanılmadıÄından emin olun.
+clearall_warning=Gerçekten listedeki bütün süzgeçleri kaldırmak istiyor musunuz?
+resethitcounts_warning=Bütün süzgeçlerin isabet istatistiklerini gerçekten sıfırlamak istiyor musunuz? Not: Bu iÅlem geri alınamaz.
+resethitcounts_selected_warning=Seçilen süzgeçlerin isabet istatistiklerini gerçekten sıfırlamak istiyor musunuz? Not: Bu iÅlem geri alınamaz.
+filter_regexp_tooltip=Süzgeç ya düzenli ifade ya da en iyileÅtirmek için çok kısadır. Bu süzgeçlerden çok fazlası, taramanızı yavaÅlatabilir.
+filter_elemhide_duplicate_id=Gizlenecek sadece bir bileÅen kimliÄi belirtilebilir
+filter_elemhide_nocriteria=Gizlenecek bileÅeni anlamak için hiçbir ölçüt belirtilmedi
+subscription_notAdded_warning=Hiçbir süzgece abone olmadınız. Süzgeç aboneliÄiniz yokken Adblock Plus'ta kendinize süzgeç tanımlamanız gerekecektir.
+subscription_notAdded_warning_addendum=Devam etmek istiyor musunuz?
+subscription_invalid_location=Dosya listesi konumu düzgün bir URL ya da düzgün bir ada sahip deÄil!
+synchronize_invalid_url=Olmadı, bu geçerli bir adres deÄil!
+synchronize_connection_error=Olmadı, indirmede sorun var.
+synchronize_invalid_data=Olmadı, bu düzgün bir süzgeç listesi deÄil!
+synchronize_checksum_mismatch=BaÅarısız, checksum eÅleÅmedi
+synchronize_ok=EÅleme baÅarılı oldu.
+overwrite=Ãstüne Yaz
+append=Ekle
+new_filter_group_title=Yeni süzgeç
+type_label_other=diÄer
+type_label_script=betik
+type_label_image=resim
+type_label_stylesheet=biçem yapraÄı
+type_label_object=nesne
+type_label_subdocument=çerçeve
+type_label_document=belge
+type_label_elemhide=gizli
+type_label_xbl=XBL baÄlantısı
+type_label_ping=baÄlantı yoklaması
+type_label_xmlhttprequest=XML isteÄi
+type_label_object_subrequest=nesne alt isteÄi
+type_label_dtd=DTD
+type_label_media=ses/görüntü
+type_label_font=yazıtipi
+fennec_status_enabled=Adblock Plus devrede.
+fennec_status_disabled=Adblock Plus devre dıÅı.
+fennec_status_enabled_site=Adblock Plus ?1? sitesinde devrede.
+fennec_status_disabled_site=Adblock Plus ?1? sitesinde devre dıÅı.
+sync_engine_title=Adblock Plus verisi
diff --git a/chrome/locale/tr/overlay.dtd b/chrome/adblockplus.jar!/locale/tr/overlay.dtd
similarity index 100%
rename from chrome/locale/tr/overlay.dtd
rename to chrome/adblockplus.jar!/locale/tr/overlay.dtd
diff --git a/chrome/adblockplus.jar!/locale/tr/sendReport.dtd b/chrome/adblockplus.jar!/locale/tr/sendReport.dtd
new file mode 100644
index 0000000..f5564d0
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/sendReport.dtd
@@ -0,0 +1,75 @@
+<!ENTITY wizard.title "Sorun bildirici">
+<!ENTITY privacyPolicy.label "Gizlilik politikası">
+<!ENTITY dataCollector.heading "Sorun bildiriciye hoÅ geldiniz">
+<!ENTITY dataCollector.description "Adblock Plus eklentisinin gerekli bilgileri toplaması için lütfen biraz bekleyin.">
+<!ENTITY typeSelector.heading "Sorun türünü seçin">
+<!ENTITY typeSelector.description "Bu pencere Adblock Plus sorun bildirimi göndermek için gerekli adımların atılmasında size rehberlik edecek. Ãnce bu sayfada ne tür sorun yaÅadıÄınızı seçin:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus çok fazla engelleme yapıyor">
+<!ENTITY typeSelector.falsePositive.accesskey "f">
+<!ENTITY typeSelector.falsePositive.description "Sayfanın önemli içeriÄi hiç görünmüyorsa, yanlıŠgörünüyorsa veya sayfa düzgün iÅlemiyorsa bu seçeneÄi seçin. Sorun kaynaÄının Adblock Plus olup olmadıÄını eklentiyi geçici olarak devre dıÅı bırakıp belirleyebilirsiniz.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus reklamlardan birini engellemiyor">
+<!ENTITY typeSelector.falseNegative.accesskey "m">
+<!ENTITY typeSelector.falseNegative.description "Adblock Plus devrede olmasına raÄmen reklamın biri görünüyorsa bu seçeneÄi seçin.">
+<!ENTITY typeSelector.other.label "BaÅka bir sorun">
+<!ENTITY typeSelector.other.accesskey "b">
+<!ENTITY typeSelector.other.description "Sorunun süzgeçlerinden çok Adblock Plus'ın kendisinden kaynaklandıÄından Åüpheleniyorsanız bu seçeneÄi seçin.">
+<!ENTITY showRecentReports.label "Yakında gönderilen bildirimleri göster">
+<!ENTITY recentReports.label "Yakında gönderdiÄiniz bildirimler">
+<!ENTITY recentReports.clear.label "Tüm bildirimleri sil">
+<!ENTITY recentReports.clear.accesskey "r">
+<!ENTITY issues.description "Adblock Plus yapılandırmanızda bu sorunun nedeni olabilecek veya bildirimi incelemeyi güçleÅtirecek sorunlar keÅfetti.">
+<!ENTITY issues.whitelist.description "Adblock Plus bildirimde bulunduÄunuz sayfada devre dıÅı. Bu sorunun incelenmesine yardım etmek için bildirim göndermeden önce eklentiyi devreye sokun ve sayfayı yeniden yükleyin.">
+<!ENTITY issues.whitelist.remove.label "Adblock Plus'u bu sayfada devreye sok">
+<!ENTITY issues.disabled.description "Adblock Plus devre dıÅı ve Åu anki durumunda hiçbir Åeyi engellemeyecek.">
+<!ENTITY issues.disabled.enable.label "Adblock Plus'ı etkinleÅtir">
+<!ENTITY issues.nofilters.description "Adblock Plus bu sayfada hiçbir Åeyi engellemiyor. GözlemlediÄiniz sorun büyük olasılıkla Adblock Plus ile ilgisizdir.">
+<!ENTITY issues.nosubscriptions.description "Sitelerdeki istenmeyen içeriÄi yok eden önceden hazırlanmıŠsüzgeç listelerinden herhangi birine abone olmuÅ deÄilsiniz.">
+<!ENTITY issues.nosubscriptions.add.label "Süzgeç aboneliÄi ekle">
+<!ENTITY issues.subscriptionCount.description "Ãok fazla süzgeç listesine abone olduÄunuz görülüyor. Bunu yapmanız tavsiye edilmez çünkü bu, sorun çıkma olasılıÄını daha da arttırır. Ayrıca hangi süzgeç aboneliÄi yazarının hatayı düzeltmesi gerektiÄi belirsiz olduÄundan hata bildiriminizi kabul edemeyiz. Sadece gerçekten gerekli olan süzgeç abonelikleri dıÅında kalanlardan çıkın ve sorunun hâlâ yaÅanıp yaÅanmadıÄına bakın.">
+<!ENTITY issues.openPreferences.label "Süzgeç tercihlerini aç">
+<!ENTITY issues.ownfilters.description "Bu sayfada uygulanan süzgeçlerin bazıları kullanıcı tarafından tanımlanmıÅ. Lütfen soruna neden olmuÅ olabilecek süzgeçleri devre dıÅı bırakın:">
+<!ENTITY issues.ownfilters.disable.label "Süzgeci devre dıÅı bırak">
+<!ENTITY issues.disabledgroups.description "Bu sayfada etkisi olabilecek aÅaÄıdaki abonelikler ve süzgeç grupları devre dıÅı bırakıldı:">
+<!ENTITY issues.disabledgroups.enable.label "Süzgeç aboneliÄini veya grubunu devreye sok">
+<!ENTITY issues.disabledfilters.description "Bu sayfada etkisi olabilecek aÅaÄıdaki süzgeçler devre dıÅı bırakıldı:">
+<!ENTITY issues.disabledfilters.enable.label "Süzgeci devreye sok">
+<!ENTITY issues.override.label "Yapılandırma doÄru, bildirime devam et">
+<!ENTITY issues.override.accesskey "d">
+<!ENTITY issues.change.description "Yapılandırmanız deÄiÅti. Lütfen deÄiÅiklikleri sınamak için sayfayı yeniden yükleyin ve yapılan deÄiÅiklikler sorunu gidermediyse hatayı bildirin.">
+<!ENTITY typeWarning.description "Süzgeçlerle ilgili bir sorun deÄil de Adblock Plus ile ilgili genel bir sorun bildiriminde bulunmak istediÄinizi belirttiniz. Lütfen böyle sorunların en iyi bildirim yerinin [link]Adblock Plus forumu[/link] olduÄu aklınızda olsun. Siz baÄlantı vermediÄiniz sürece kimse bildiriminizi görmeyeceÄi için sorun bildiriciyi sadece mevcut bir tartıÅmaya katkı saÄlamak için kullanmalısınız.">
+<!ENTITY typeWarning.override.label "Anlıyorum ve ne olursa olsun bildirimi göndermek istiyorum">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "Sayfayı tazele">
+<!ENTITY reloadButton.accesskey "t">
+<!ENTITY screenshot.heading "Ekran görüntüsü ekle">
+<!ENTITY screenshot.description "Aynı sayfa farklı kiÅilerce farklı biçimde görülebilir. Bildirime ekran görüntüsü eklemeniz sorunu anlamamıza yardımcı olabilir. Hassas bilgilerin olduÄu bölümleri silebilirsiniz ve sorunun görünür olduÄu yerleri iÅaretleyebilirsiniz. Bunu yapmak için ilgili düÄmeye basın ve resimde bir bölümü farenizle seçin.">
+<!ENTITY screenshot.attach.label "Bildirime sayfa resmi ekle">
+<!ENTITY screenshot.attach.accesskey "f">
+<!ENTITY screenshot.mark.label "Sorunu iÅaretle">
+<!ENTITY screenshot.mark.accesskey "a">
+<!ENTITY screenshot.remove.label "Hassas veriyi sil">
+<!ENTITY screenshot.remove.accesskey "v">
+<!ENTITY screenshot.undo.label "Geri al">
+<!ENTITY screenshot.undo.accesskey "g">
+<!ENTITY commentPage.heading "Yorum ekle">
+<!ENTITY commentPage.description "AÅaÄıdaki metin alanı sorunu anlamamız için yorum yazmanıza olanak tanır. Bu adım isteÄe baÄlıdır ancak sorun açık deÄilse tavsiye edilir. Ayrıca bildirimi göndermeden önce gözden geçirebilirsiniz.">
+<!ENTITY comment.label "Yorum (isteÄe baÄlı):">
+<!ENTITY comment.accesskey "o">
+<!ENTITY comment.lengthWarning "Yorumunuzun uzunluÄu 1000 karakteri aÅıyor. Sadece ilk 1000 karakter gönderilecek.">
+<!ENTITY email.label "Daha fazla bilgi almamız için e-posta adresi (isteÄe baÄlı):">
+<!ENTITY email.accesskey "d">
+<!ENTITY attachExtensions.label "Sorun kaynaÄının eklenti uyumsuzluÄu olup olmadıÄının belirlenmesi için etkin eklentilerin listesini bildirime ekle">
+<!ENTITY attachExtensions.accesskey "u">
+<!ENTITY sendButton.label "Bildirimi gönder">
+<!ENTITY sendButton.accesskey "b">
+<!ENTITY showData.label "Bildirim verisini göster">
+<!ENTITY data.label "Bildirim verisi:">
+<!ENTITY data.accesskey "v">
+<!ENTITY sendPage.heading "Bildirimi gönder">
+<!ENTITY sendPage.waitMessage "Lüftfen Adblock Plus bildirimi gönderirken bekleyin.">
+<!ENTITY sendPage.confirmation "Bildiriminiz kaydedildi ve ona aÅaÄıdaki adresten ulaÅabilirsiniz:">
+<!ENTITY sendPage.knownIssue "BildirdiÄiniz sorun büyük olasılıkla biliniyor. Daha fazla bilgi:">
+<!ENTITY sendPage.errorMessage "Hata bildirimi gönderme giriÅiminiz "?1?" hata koduyla baÅarısız oldu. Lütfen internete baÄlı olduÄunuzdan emin olun ve yeniden deneyin. Sorun devam ederse lütfen [link]Adblock Plus forumunda[/link] yardım isteyin.">
+<!ENTITY sendPage.retry.label "Yeniden gönder">
+<!ENTITY copyLink.label "Bildirimi baÄlantısını kopyala">
+<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/adblockplus.jar!/locale/tr/settings.dtd b/chrome/adblockplus.jar!/locale/tr/settings.dtd
new file mode 100644
index 0000000..b83dc27
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Adblock Plus Tercihleri">
+<!ENTITY filters.label "Süzgeçler">
+<!ENTITY filters.accesskey "G">
+<!ENTITY add.label "Süzgeç ekle">
+<!ENTITY add.accesskey "K">
+<!ENTITY addsubscription.label "Süzgeç aboneliÄi ekle">
+<!ENTITY addsubscription.accesskey "E">
+<!ENTITY synchsubscriptions.label "Tüm abonelikleri güncelle">
+<!ENTITY synchsubscriptions.accesskey "C">
+<!ENTITY import.label "Süzgeçleri içe aktar">
+<!ENTITY import.accesskey "Z">
+<!ENTITY export.label "Süzgeçleri dıÅa aktar">
+<!ENTITY export.accesskey "D">
+<!ENTITY clearall.label "Tüm süzgeçleri kaldır">
+<!ENTITY clearall.accesskey "L">
+<!ENTITY resethitcounts.label "İstatistikleri sıfırla">
+<!ENTITY resethitcounts.accesskey "R">
+<!ENTITY edit.label "Düzen">
+<!ENTITY edit.accesskey "z">
+<!ENTITY cut.label "Kes">
+<!ENTITY cut.accesskey "e">
+<!ENTITY copy.label "Kopyala">
+<!ENTITY copy.accesskey "K">
+<!ENTITY paste.label "YapıÅtır">
+<!ENTITY paste.accesskey "Y">
+<!ENTITY remove.label "Sil">
+<!ENTITY remove.accesskey "S">
+<!ENTITY menu.find.label "Bul">
+<!ENTITY menu.find.accesskey "B">
+<!ENTITY menu.findagain.label "Sonrakini bul">
+<!ENTITY menu.findagain.accesskey "A">
+<!ENTITY view.label "Görünüm">
+<!ENTITY view.accesskey "r">
+<!ENTITY sort.label "Sırala">
+<!ENTITY sort.accesskey "S">
+<!ENTITY sort.none.label "SıralanmamıÅ">
+<!ENTITY sort.none.accesskey "m">
+<!ENTITY sort.ascending.label "A'da Z'ye sıralama">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "Z'den A'ya sıralama">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "Seçenekler">
+<!ENTITY options.accesskey "S">
+<!ENTITY enable.label "Adblock Plus'ı etkinleÅtir">
+<!ENTITY enable.accesskey "A">
+<!ENTITY showintoolbar.label "Araç çubuÄunda göster">
+<!ENTITY showintoolbar.accesskey "R">
+<!ENTITY showinstatusbar.label "Durum çubuÄunda göster">
+<!ENTITY showinstatusbar.accesskey "D">
+<!ENTITY objecttabs.label "Flash ve Java'yı kulakçıklarla belirt">
+<!ENTITY objecttabs.accesskey "J">
+<!ENTITY collapse.label "ÃÄeleri kapat">
+<!ENTITY collapse.accesskey "T">
+<!ENTITY sync.label "Adblock Plus ayarlarını eÅitle">
+<!ENTITY sync.accesskey "e">
+<!ENTITY help.label "Yardım">
+<!ENTITY help.accesskey "A">
+<!ENTITY gettingStarted.label "İlk adım">
+<!ENTITY gettingStarted.accesskey "k">
+<!ENTITY faq.label "Sıkça sorulan sorular">
+<!ENTITY faq.accesskey "S">
+<!ENTITY filterdoc.label "Adblock Plus süzgeç yazımı">
+<!ENTITY filterdoc.accesskey "z">
+<!ENTITY about.label "Adblock Plus hakkında">
+<!ENTITY about.accesskey "O">
+<!ENTITY description "Engellemek istediÄiniz adresleri yazın. Ãneriler için açılır menüye bakın. Daha genel süzgeçler tanımlamak için * iÅaretini kullanabilirsiniz. İleri düzeyde bilgiye sahip kullanıcılar düzenli ifadelere de (ör. /reklamd+.gif$/) baÅvurabilirler.">
+<!ENTITY filter.column "Süzgeç kuralı">
+<!ENTITY filter.accesskey "k">
+<!ENTITY slow.column "Süzgeçleri göster">
+<!ENTITY slow.accesskey "g">
+<!ENTITY enabled.column "Etkinlik">
+<!ENTITY enabled.accesskey "n">
+<!ENTITY hitcount.column "İsabet">
+<!ENTITY hitcount.accesskey "e">
+<!ENTITY lasthit.column "Son isabet">
+<!ENTITY lasthit.accesskey "i">
+<!ENTITY context.edit.label "Süzgeci düzenle">
+<!ENTITY context.resethitcount.label "İsabet istatistiÄi sıfırlanacak süzgeç:">
+<!ENTITY context.synchsubscription.label "AboneliÄi eÅle">
+<!ENTITY context.editsubscription.label "AboneliÄi düzenle">
+<!ENTITY context.moveup.label "Yukarıya taÅı">
+<!ENTITY context.movedown.label "AÅaÄıya taÅı">
+<!ENTITY context.movegroupup.label "ÃbeÄi yukarıya taÅı">
+<!ENTITY context.movegroupdown.label "ÃbeÄi aÅaÄıya taÅı">
+<!ENTITY context.enable.label "Devreye sok">
+<!ENTITY context.disable.label "Devreden çıkar">
+<!ENTITY apply.label "Uygula">
+<!ENTITY apply.accesskey "u">
+<!ENTITY fennec.subscription.label "Süzgeç aboneliÄi">
diff --git a/chrome/locale/tr/sidebar.dtd b/chrome/adblockplus.jar!/locale/tr/sidebar.dtd
similarity index 100%
rename from chrome/locale/tr/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/tr/sidebar.dtd
diff --git a/chrome/adblockplus.jar!/locale/tr/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/tr/subscriptionSelection.dtd
new file mode 100644
index 0000000..593b197
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/tr/subscriptionSelection.dtd
@@ -0,0 +1,25 @@
+<!ENTITY dialog.title "Adblock Plus süzgeç aboneliÄi ekle">
+<!ENTITY dialog.title.edit "Süzgeç aboneliklerini düzenle">
+<!ENTITY description.newInstall "Adblock Plus herhangi bir süzgeç aboneliÄiyle birlikte en etkin Åekilde kullanılır. Bu abonelikler diÄer Adblock Plus kullanıcıları tarafından ücretsiz sunulmaktadır. Dilinize en uygun abonelik, halihazırda seçilmiÅ durumdadır.">
+<!ENTITY subscriptionSelector.label "Lütfen listeden bir süzgeç aboneliÄi seçin:">
+<!ENTITY viewList.label "Süzgeçlere bak">
+<!ENTITY visitHomepage.label "Ana sayfaya git">
+<!ENTITY addSubscription.label "Abone ol">
+<!ENTITY saveSubscription.label "AboneliÄi kaydet">
+<!ENTITY other.label "BaÅka abonelik ekle">
+<!ENTITY other.accesskey "B">
+<!ENTITY list.download.failed "Adblock Plus abonelik listesini alamadı">
+<!ENTITY list.download.retry "Yeniden dene">
+<!ENTITY list.download.website "Siteye git">
+<!ENTITY fromWeb.description "Lütfen bu süzgeç aboneliÄini eklemek istediÄinizi teyit edin. Eklemeden önce abonelik adını ve konumunu deÄiÅtirebilirsiniz.">
+<!ENTITY edit.description "Abonelik adını ve konumunu gerekirse deÄiÅtirebilirsiniz.">
+<!ENTITY external.description "Bu harici bir süzgeç aboneliÄi ve aboneliÄi baÅlatan eklenti tarafından güncellenecek.">
+<!ENTITY title.label "AboneliÄin adı:">
+<!ENTITY title.accesskey "A">
+<!ENTITY location.label "Süzgeç listesi konumu:">
+<!ENTITY location.accesskey "L">
+<!ENTITY autodownload.label "Otomatik olarak güncelle">
+<!ENTITY autodownload.accesskey "O">
+<!ENTITY supplementMessage "Bu süzgeç aboneliÄi henüz kullanmadıÄınız "?1?" süzgeç aboneliÄiyle kullanılmak üzere hazırlanmıÅ.">
+<!ENTITY addMain.label ""?1?" süzgeç aboneliÄini de ekle">
+<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/uk/about.dtd b/chrome/adblockplus.jar!/locale/uk/about.dtd
similarity index 100%
rename from chrome/locale/uk/about.dtd
rename to chrome/adblockplus.jar!/locale/uk/about.dtd
diff --git a/chrome/locale/uk/composer.dtd b/chrome/adblockplus.jar!/locale/uk/composer.dtd
similarity index 100%
rename from chrome/locale/uk/composer.dtd
rename to chrome/adblockplus.jar!/locale/uk/composer.dtd
diff --git a/chrome/locale/uk/global.properties b/chrome/adblockplus.jar!/locale/uk/global.properties
similarity index 100%
rename from chrome/locale/uk/global.properties
rename to chrome/adblockplus.jar!/locale/uk/global.properties
diff --git a/chrome/adblockplus.jar!/locale/uk/overlay.dtd b/chrome/adblockplus.jar!/locale/uk/overlay.dtd
new file mode 100644
index 0000000..dd3da0f
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/uk/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "СÑаÑÑÑ:">
+<!ENTITY blocked.tooltip "ÐÐ°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи на ÑÑй ÑÑоÑÑнÑÑ:">
+<!ENTITY filters.tooltip "ÐайбÑлÑÑ ÑаÑÑо заÑÑоÑÐ¾Ð²Ð°Ð½Ñ ÑÑлÑÑÑи:">
+<!ENTITY menuitem.label "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Adblock Plus">
+<!ENTITY menuitem.accesskey "A">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: елеменÑи ÑÑоÑÑнки">
+<!ENTITY context.image.label "Adblock Plus: заблокÑваÑи зобÑаженнÑ">
+<!ENTITY context.object.label "Adblock Plus: заблокÑваÑи обâÑкÑ">
+<!ENTITY context.frame.label "Adblock Plus: заблокÑваÑи ÑÑейм">
+<!ENTITY context.media.label "Adblock Plus: ÐлокÑваÑи аÑдÑо/вÑдео">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: Ðнов ÑвÑмкнÑÑи Ð´Ð»Ñ ÑÑÑÑ ÑÑоÑÑнки">
+<!ENTITY sidebar.title "ÐлеменÑи вÑдкÑиÑÐ¾Ñ ÑÑоÑÑнки">
+<!ENTITY sendReport.label "ÐовÑдомиÑи пÑо пÑоблеми на ÑÑоÑÑнÑÑ">
+<!ENTITY sendReport.accesskey "Ñ">
+<!ENTITY settings.label "ÐалаÑÑÑваннÑ">
+<!ENTITY settings.accesskey "Ñ">
+<!ENTITY opensidebar.label "ÐÑдкÑиÑи ÑпиÑок елеменÑÑв">
+<!ENTITY opensidebar.accesskey "п">
+<!ENTITY closesidebar.label "ÐакÑиÑи ÑпиÑок елеменÑÑв">
+<!ENTITY closesidebar.accesskey "п">
+<!ENTITY whitelist.site.label "ÐимкнÑÑи: на ?1?">
+<!ENTITY whitelist.page.label "ÐимкнÑÑи: ÑÑлÑки на ÑÑй ÑÑоÑÑнÑÑ">
+<!ENTITY objecttab.title "ÐаблокÑваÑи">
+<!ENTITY objecttab.tooltip "ÐаÑиÑнÑÑÑ ÑÑÑ, Ñоб заблокÑваÑи Ñей обâÑкÑ">
+<!ENTITY disable.label "Disable everywhere">
+<!ENTITY recommend.label "Recommend us on Facebook">
diff --git a/chrome/adblockplus.jar!/locale/uk/sendReport.dtd b/chrome/adblockplus.jar!/locale/uk/sendReport.dtd
new file mode 100644
index 0000000..9e087a3
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/uk/sendReport.dtd
@@ -0,0 +1,82 @@
+<!ENTITY wizard.title "ÐовÑдомиÑи пÑо пÑоблемÑ">
+<!ENTITY privacyPolicy.label "ÐолÑÑика пÑиваÑноÑÑÑ">
+<!ENTITY dataCollector.heading "ÐаÑкаво пÑоÑимо до звÑÑÑваÑа пÑо пÑоблеми">
+<!ENTITY dataCollector.description "ÐаждÑÑÑ, Adblock Plus збиÑÐ°Ñ Ð¿Ð¾ÑÑÑÐ±Ð½Ñ Ð´Ð°Ð½Ñ">
+<!ENTITY typeSelector.heading "ÐибеÑÑÑÑ Ñип пÑоблеми">
+<!ENTITY typeSelector.description "Це вÑкно пÑоведе Ð²Ð°Ñ Ð¿Ð¾ кÑокаÑ
надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ Ð¿Ñо пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð· Adblock Plus. СпеÑÑÑ, вибеÑÑÑÑ Ñип пÑоблеми з ÑÐºÐ¾Ñ Ð²Ð¸ зÑÑкнÑлиÑÑ Ð½Ð° ÑÑй ÑÑоÑÑнÑÑ:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus блокÑÑ Ð·Ð°Ð±Ð°Ð³Ð°Ñо">
+<!ENTITY typeSelector.falsePositive.accesskey "б">
+<!ENTITY typeSelector.falsePositive.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо на ÑÑоÑÑнÑÑ Ð²ÑдÑÑÑÐ½Ñ ÑаÑÑина вмÑÑÑÑ, або ÑкÑо вона показÑÑÑÑÑÑ Ñи ÑÑнкÑÑонÑÑ Ð½ÐµÐ¿ÑавилÑно. Ðи можеÑе пеÑевÑÑиÑи, Ñи бÑв Adblock Plus пÑиÑÐ¸Ð½Ð¾Ñ ÑимÑаÑово його вимкнÑвÑи.">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus не блокÑÑ ÑекламÑ">
+<!ENTITY typeSelector.falseNegative.accesskey "Ñ">
+<!ENTITY typeSelector.falseNegative.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо Ñеклама показÑÑÑÑ Ð¿Ð¾Ð¿Ñи Ñе Ñо Adblock Plus ÑвÑмкнено.">
+<!ENTITY typeSelector.other.label "ÐнÑа пÑоблема">
+<!ENTITY typeSelector.other.accesskey "Ñ">
+<!ENTITY typeSelector.other.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо ви пÑдозÑÑÑÑе пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñаме з Adblock Plus нÑж з його ÑÑлÑÑÑами.">
+<!ENTITY showRecentReports.label "ÐоказаÑи недавно заÑÐ»Ð°Ð½Ñ Ð·Ð²ÑÑи">
+<!ENTITY recentReports.label "ÐаÑÑ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ заÑÐ»Ð°Ð½Ñ Ð·Ð²ÑÑи">
+<!ENTITY recentReports.clear.label "ÐилÑÑиÑи вÑÑ Ð·Ð²ÑÑи">
+<!ENTITY recentReports.clear.accesskey "Ð">
+<!ENTITY issues.description "Adblock Plus знайÑов пÑоблеми Ñ Ð²Ð°ÑиÑ
налаÑÑÑваннÑÑ
коÑÑÑ, можливо, ÑпÑиÑинили ÑÑ Ð¿ÑоблемÑ, або ÑÑладнÑÑÑ ÑозглÑд звÑÑÑ.">
+<!ENTITY issues.whitelist.description "Adblock Plus наÑÐ°Ð·Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¹ на ÑÑй ÑÑоÑÑнÑÑ Ð¿Ñо ÑÐºÑ Ð²Ð¸ звÑÑÑÑÑе. УвÑмкнÑÑÑ Ð¹Ð¾Ð³Ð¾ Ñа пеÑегÑÑзÑÑÑ ÑÑоÑÑÐ½ÐºÑ Ð¿ÐµÑед надÑиланнÑм звÑÑÑ. Це допоможе в його ÑозглÑдÑ.">
+<!ENTITY issues.whitelist.remove.label "ÐеÑеÑвÑмкнÑÑи Adblock Plus на ÑÑй ÑÑоÑÑнÑÑ">
+<!ENTITY issues.disabled.description "Adblock Plus вимкнено, вÑн не блокÑваÑиме нÑÑого Ñ Ð¿Ð¾ÑоÑÐ½Ð¾Ð¼Ñ ÑÑанÑ.">
+<!ENTITY issues.disabled.enable.label "УвÑмкнÑÑи Adblock Plus">
+<!ENTITY issues.nofilters.description "Adblock Plus не блокÑÑ Ð½ÑÑого на поÑоÑнÑй ÑÑоÑÑнÑÑ. Ðаайже напевне, пÑоблема, ÑÐºÑ Ð²Ð¸ баÑиÑе, не повâÑзана з Adblock Plus.">
+<!ENTITY issues.nosubscriptions.description "Ðи не пÑдпиÑÐ°Ð½Ñ Ð½Ð° жоден з гоÑовиÑ
ÑпиÑкÑв ÑÑлÑÑÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐ¾ÑÑÑ Ð°Ð²ÑомаÑиÑно вилÑÑаÑÑÑ Ð½ÐµÐ±Ð°Ð¶Ð°Ð½Ð¸Ð¹ вмÑÑÑ Ð· ÑайÑÑв.">
+<!ENTITY issues.nosubscriptions.add.label "ÐодаÑи пÑдпиÑÐºÑ Ð½Ð° ÑÑлÑÑÑи">
+<!ENTITY issues.ownfilters.description "ÐеÑÐºÑ Ð· заÑÑоÑованиÑ
ÑÑлÑÑÑÑв бÑли Ð·Ð°Ð´Ð°Ð½Ñ ÐºÐ¾ÑиÑÑÑваÑем. ÐимкнÑÑÑ ÑÑлÑÑÑи Ñо могли ÑпÑиÑиниÑи пÑоблемÑ.">
+<!ENTITY issues.ownfilters.disable.label "ÐимкнÑÑи ÑÑлÑÑÑ">
+<!ENTITY issues.disabledgroups.description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑки/гÑÑпи вимкненÑ, але могли вплинÑÑи на ÑÑ ÑÑоÑÑнкÑ:">
+<!ENTITY issues.disabledgroups.enable.label "УвÑмкнÑÑи ÑÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑкÑ/гÑÑпÑ">
+<!ENTITY issues.disabledfilters.description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑи вимкненÑ, але могли вплинÑÑи на ÑÑ ÑÑоÑÑнкÑ:">
+<!ENTITY issues.disabledfilters.enable.label "УвÑмкнÑÑи ÑÑлÑÑÑ">
+<!ENTITY issues.override.label "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑавилÑнÑ, пÑодовжиÑи звÑÑ">
+<!ENTITY issues.override.accesskey "п">
+<!ENTITY issues.change.description "ÐаÑÑ Ð½Ð°Ð»Ð°ÑÑÑÐ²Ð°Ð½Ð½Ñ Ð±Ñло змÑнено. ÐеÑегÑÑзÑÑÑ ÑÑоÑÑÐ½ÐºÑ Ð´Ð»Ñ Ð¿ÐµÑевÑÑки внеÑениÑ
змÑн Ñа заÑлÑÑÑ Ð·Ð²ÑÑ ÑкÑо пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð½Ðµ виÑÑÑено.">
+<!ENTITY typeWarning.description "Ðи вказали Ñо Ñ
оÑеÑе повÑдомиÑи пÑо загалÑÐ½Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð² Adblock Plus, а не в ÑÑлÑÑÑаÑ
. ÐаÑважÑе, Ñо пÑо ÑÐ°ÐºÑ Ð¿Ñоблеми найкÑаÑе повÑдомлÑÑи до [link]ÑоÑÑÐ¼Ñ Adblock Plus[/link]. ÐайÑÑÑа звÑÑÑв ÑлÑд викоÑиÑÑовÑваÑи лиÑе в додаÑок до ÑÑнÑÑÑÐ¾Ñ Ð´Ð¸ÑкÑÑÑÑ, оÑкÑлÑки нÑÑ
Ñо не побаÑиÑÑ Ð²Ð°Ñого звÑÑÑ, ÑкÑо не поÑÑавиÑи на нÑого поÑиланнÑ. Ðи оÑÑимаÑÑе авÑомаÑиÑно ÑÑвоÑене поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿ÑÑÐ»Ñ Ð½Ð°Ð´ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ.">
+<!ENTITY typeWarning.override.label "Я ÑозÑмÑÑ, Ñа вÑе ж Ñ
оÑÑ Ð¿Ð¾ÑлаÑи звÑÑ">
+<!ENTITY typeWarning.override.accesskey "Ñ">
+<!ENTITY reloadButton.label "ÐеÑегÑÑзиÑи ÑÑоÑÑнкÑ">
+<!ENTITY reloadButton.accesskey "Ð">
+<!ENTITY screenshot.heading "ÐодаÑи ÑкÑÑнÑоÑ">
+<!ENTITY screenshot.description "Та Ñама ÑÑоÑÑнка може виглÑдаÑи по ÑÑÐ·Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÑÑзниÑ
лÑдей. ÐнÑмок екÑана (ÑкÑÑнÑоÑ) може допомогÑи нам зÑозÑмÑÑи пÑоблемÑ. Ðи можеÑе вилÑÑиÑи конÑÑденÑÑÐ¹Ð½Ñ ÑаÑÑини, а Ñакож познаÑиÑи облаÑÑÑ Ð´Ðµ пÑиÑÑÑÐ½Ñ Ð¿Ñоблема. Щоб Ñе зÑобиÑи, клаÑнÑÑÑ Ð¿Ð¾ вÑдповÑднÑй клавÑÑÑ Ñа вибеÑÑÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð¼Ð¸ÑкоÑ.">
+<!ENTITY screenshot.attach.label "ÐодаÑи зобÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑÑоÑÑнки до звÑÑÑ">
+<!ENTITY screenshot.attach.accesskey "Ð">
+<!ENTITY screenshot.mark.label "ÐознаÑиÑи пÑоблемÑ">
+<!ENTITY screenshot.mark.accesskey "з">
+<!ENTITY screenshot.remove.label "ÐилÑÑиÑи конÑÑденÑÑÐ¹Ð½Ñ Ð´Ð°Ð½Ñ">
+<!ENTITY screenshot.remove.accesskey "Ð">
+<!ENTITY screenshot.undo.label "ÐовеÑнÑÑи">
+<!ENTITY screenshot.undo.accesskey "Ð">
+<!ENTITY commentPage.heading "ÐвеÑÑи коменÑаÑ">
+<!ENTITY commentPage.description "ÐижÑе ви можеÑе ввеÑÑи коменÑÐ°Ñ Ñоб допомогÑи нам зÑозÑмÑÑи пÑоблемÑ. Цей кÑок необовâÑзковий, пÑоÑе Ñекомендований коли пÑоблема не ÑамооÑевидна. Ðи можеÑе Ñакож пеÑеглÑнÑÑи ÑвÑй коменÑÐ°Ñ Ð¿ÐµÑед надÑиланнÑм.">
+<!ENTITY comment.label "ÐоменÑÐ°Ñ (необовâÑзково):">
+<!ENTITY comment.accesskey "Ð">
+<!ENTITY comment.lengthWarning "Ðовжина коменÑаÑÑ Ð¿ÐµÑевиÑÑÑ 1000 ÑимволÑв. ÐÑдÑÑÑ Ð¿Ð¾ÑÐ»Ð°Ð½Ñ Ð»Ð¸Ñе пеÑÑÑ 1000 ÑимволÑв.">
+<!ENTITY email.label "Ðл.поÑÑа Ð´Ð»Ñ Ð´Ð°Ð»ÑÑого звâÑÐ·ÐºÑ (необовâÑзково):">
+<!ENTITY email.accesskey "Ð">
+<!ENTITY attachExtensions.label "ÐолÑÑиÑи до звÑÑÑ ÑпиÑок акÑивниÑ
ÑозÑиÑÐµÐ½Ñ â на випадок ÑкÑо пÑиÑÐ¸Ð½Ð¾Ñ Ð¿Ñоблеми Ñ ÐºÐ¾Ð½ÑлÑÐºÑ ÑозÑиÑенÑ">
+<!ENTITY attachExtensions.accesskey "Ñ">
+<!ENTITY sendButton.label "ÐадÑÑлаÑи звÑÑ">
+<!ENTITY sendButton.accesskey "Ð">
+<!ENTITY showData.label "ÐоказаÑи Ð´Ð°Ð½Ñ Ð·Ð²ÑÑÑ">
+<!ENTITY data.label "ÐÐ°Ð½Ñ Ð·Ð²ÑÑÑ:">
+<!ENTITY data.accesskey "д">
+<!ENTITY sendPage.heading "ÐадÑÑлаÑи звÑÑ">
+<!ENTITY sendPage.waitMessage "ÐаждÑÑÑ Ð´Ð¾ÐºÐ¸ Adblock Plus надÑÐ¸Ð»Ð°Ñ Ð²Ð°Ñ Ð·Ð²ÑÑ.">
+<!ENTITY sendPage.confirmation "ÐвÑÑ Ð±Ñло запиÑано. Ðи можеÑе пеÑеглÑнÑÑи його за поÑиланнÑм:">
+<!ENTITY sendPage.knownIssue "ÐÑоблема пÑо ÑÐºÑ Ð²Ð¸ повÑдомили вже вÑдома. ÐеÑалÑнÑÑе:">
+<!ENTITY sendPage.errorMessage "Ðомилка вÑдпÑавки звÑÑÑ: «?1?». УпевнÑÑÑÑÑ Ñо ви пÑдâÑÐ´Ð½Ð°Ð½Ñ Ð´Ð¾ ÑнÑеÑнеÑÑ Ñа ÑпÑобÑйÑе Ñе Ñаз. ЯкÑо пÑоблема не зникаÑ, бÑÐ´Ñ Ð»Ð°Ñка поÑÑкайÑе допомоги на [link]ÑоÑÑÐ¼Ñ Adblock Plus[/link].">
+<!ENTITY sendPage.retry.label "ÐадÑÑлаÑи Ñе Ñаз">
+<!ENTITY copyLink.label "СкопÑÑваÑи поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ">
+<!ENTITY copyLink.accesskey "к">
+<!ENTITY issues.openPreferences.label "Open filter preferences">
+<!ENTITY issues.subscriptionCount.description "
+ It seems that you are subscribed to too many filter subscriptions. This
+ setup is not recommended because it will make the likeliness
+ of issues much higher. We also cannot accept your issue report because it
+ is unclear which filter subscription author needs to take action. Please
+ remove all but the really necessary filter subscriptions and test whether
+ the issue still occurs then.
+">
diff --git a/chrome/adblockplus.jar!/locale/uk/settings.dtd b/chrome/adblockplus.jar!/locale/uk/settings.dtd
new file mode 100644
index 0000000..493e20e
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/uk/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Adblock Plus - ÐалаÑÑÑваннÑ">
+<!ENTITY filters.label "ФÑлÑÑÑи">
+<!ENTITY filters.accesskey "Ñ">
+<!ENTITY add.label "ÐодаÑи ÑÑлÑÑÑ">
+<!ENTITY add.accesskey "д">
+<!ENTITY addsubscription.label "ÐодаÑи пÑдпиÑкÑ">
+<!ENTITY addsubscription.accesskey "о">
+<!ENTITY synchsubscriptions.label "ÐикаÑаÑи вÑÑ Ð¿ÑдпиÑки">
+<!ENTITY synchsubscriptions.accesskey "п">
+<!ENTITY import.label "ÐмпоÑÑ ÑÑлÑÑÑÑв">
+<!ENTITY import.accesskey "м">
+<!ENTITY export.label "ÐкÑпоÑÑ ÑÑлÑÑÑÑв">
+<!ENTITY export.accesskey "к">
+<!ENTITY clearall.label "СÑеÑÑи вÑÑ ÑÑлÑÑÑи">
+<!ENTITY clearall.accesskey "и">
+<!ENTITY resethitcounts.label "ÐбнÑлиÑи ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ñ">
+<!ENTITY resethitcounts.accesskey "Ñ">
+<!ENTITY edit.label "ÐÑавка">
+<!ENTITY edit.accesskey "Ñ">
+<!ENTITY cut.label "ÐиÑÑзаÑи">
+<!ENTITY cut.accesskey "Ñ">
+<!ENTITY copy.label "ÐопÑÑваÑи">
+<!ENTITY copy.accesskey "о">
+<!ENTITY paste.label "ÐÑÑавиÑи">
+<!ENTITY paste.accesskey "а">
+<!ENTITY remove.label "ÐилÑÑиÑи">
+<!ENTITY remove.accesskey "и">
+<!ENTITY menu.find.label "ÐнайÑи ÑÑлÑÑÑ">
+<!ENTITY menu.find.accesskey "н">
+<!ENTITY menu.findagain.label "ÐнайÑи наÑÑÑпний">
+<!ENTITY menu.findagain.accesskey "Ñ">
+<!ENTITY view.label "ÐиглÑд">
+<!ENTITY view.accesskey "Ð">
+<!ENTITY sort.label "СоÑÑÑваÑи за">
+<!ENTITY sort.accesskey "С">
+<!ENTITY sort.none.label "ÐеÑоÑÑовано">
+<!ENTITY sort.none.accesskey "Ð">
+<!ENTITY sort.ascending.label "ÐÑд Рдо Я">
+<!ENTITY sort.ascending.accesskey "Ð">
+<!ENTITY sort.descending.label "ÐÑд Я до Ð">
+<!ENTITY sort.descending.accesskey "Я">
+<!ENTITY options.label "ÐалаÑÑÑваннÑ">
+<!ENTITY options.accesskey "а">
+<!ENTITY enable.label "УвÑмкнÑÑи Adblock Plus">
+<!ENTITY enable.accesskey "У">
+<!ENTITY showintoolbar.label "ÐоказÑваÑи в Ð¿Ð°Ð½ÐµÐ»Ñ ÑнÑÑÑÑменÑÑв">
+<!ENTITY showintoolbar.accesskey "к">
+<!ENTITY showinstatusbar.label "ÐоказÑваÑи в ÑÑÐ´ÐºÑ ÑÑанÑ">
+<!ENTITY showinstatusbar.accesskey "Ñ">
+<!ENTITY objecttabs.label "ÐоказÑваÑи ÑÑлик на Flash Ñ Java">
+<!ENTITY objecttabs.accesskey "Ñ">
+<!ENTITY collapse.label "ÐгоÑÑаÑи Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи">
+<!ENTITY collapse.accesskey "о">
+<!ENTITY help.label "ÐовÑдка">
+<!ENTITY help.accesskey "о">
+<!ENTITY gettingStarted.label "ÐоÑаÑкÑвÑÑм">
+<!ENTITY gettingStarted.accesskey "Ð">
+<!ENTITY faq.label "ÐиÑаннÑ, Ñо ÑаÑÑо ÑÑавлÑÑÑÑÑ (англÑйÑÑкоÑ)">
+<!ENTITY faq.accesskey "и">
+<!ENTITY filterdoc.label "Ð¡ÐºÐ»Ð°Ð´Ð°Ð½Ð½Ñ ÑÑлÑÑÑÑв Ð´Ð»Ñ Adblock Plus (англÑйÑÑкоÑ)">
+<!ENTITY filterdoc.accesskey "а">
+<!ENTITY about.label "ÐÑо Adblock Plus">
+<!ENTITY about.accesskey "о">
+<!ENTITY description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑи визнаÑаÑÑÑ ÑÐºÑ Ð°Ð´ÑеÑи блокÑÑÑÑÑÑ Ñа ÑÐºÑ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑÑÑÑÑ:">
+<!ENTITY filter.column "ÐÑавило ÑÑлÑÑÑÑваннÑ">
+<!ENTITY filter.accesskey "Ñ">
+<!ENTITY slow.column "ÐовÑлÑÐ½Ñ ÑÑлÑÑÑи">
+<!ENTITY slow.accesskey "Ñ">
+<!ENTITY enabled.column "УвÑмкнено">
+<!ENTITY enabled.accesskey "в">
+<!ENTITY hitcount.column "ÐопаданÑ">
+<!ENTITY hitcount.accesskey "п">
+<!ENTITY lasthit.column "ÐÑÑÐ°Ð½Ð½Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ð½Ñ">
+<!ENTITY lasthit.accesskey "Ð">
+<!ENTITY context.edit.label "РедагÑваÑи ÑÑлÑÑÑ">
+<!ENTITY context.resethitcount.label "ÐбнÑлиÑи ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ñ Ð´Ð»Ñ ÑÑлÑÑÑÑ">
+<!ENTITY context.synchsubscription.label "ÐикаÑаÑи ÑÑлÑÑÑи наново">
+<!ENTITY context.editsubscription.label "РедагÑваÑи пÑдпиÑкÑ">
+<!ENTITY context.moveup.label "ÐÑÑÑиÑи вгоÑÑ">
+<!ENTITY context.movedown.label "ÐÑÑÑиÑи вниз">
+<!ENTITY context.movegroupup.label "ÐÑÑÑиÑи гÑÑÐ¿Ñ Ð²Ð³Ð¾ÑÑ">
+<!ENTITY context.movegroupdown.label "ÐÑÑÑиÑи гÑÑÐ¿Ñ Ð²Ð½Ð¸Ð·">
+<!ENTITY context.enable.label "УвÑмкнÑÑи">
+<!ENTITY context.disable.label "ÐимкнÑÑи">
+<!ENTITY apply.label "ÐаÑÑоÑÑваÑи">
+<!ENTITY apply.accesskey "Ñ">
+<!ENTITY fennec.subscription.label "ФÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑки">
+<!ENTITY sync.accesskey "c">
+<!ENTITY sync.label "Sync Adblock Plus settings">
diff --git a/chrome/locale/uk/sidebar.dtd b/chrome/adblockplus.jar!/locale/uk/sidebar.dtd
similarity index 100%
rename from chrome/locale/uk/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/uk/sidebar.dtd
diff --git a/chrome/locale/uk/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/uk/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/uk/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/uk/subscriptionSelection.dtd
diff --git a/chrome/locale/vi/about.dtd b/chrome/adblockplus.jar!/locale/vi/about.dtd
similarity index 100%
rename from chrome/locale/vi/about.dtd
rename to chrome/adblockplus.jar!/locale/vi/about.dtd
diff --git a/chrome/locale/vi/composer.dtd b/chrome/adblockplus.jar!/locale/vi/composer.dtd
similarity index 100%
rename from chrome/locale/vi/composer.dtd
rename to chrome/adblockplus.jar!/locale/vi/composer.dtd
diff --git a/chrome/locale/vi/global.properties b/chrome/adblockplus.jar!/locale/vi/global.properties
similarity index 100%
rename from chrome/locale/vi/global.properties
rename to chrome/adblockplus.jar!/locale/vi/global.properties
diff --git a/chrome/locale/vi/overlay.dtd b/chrome/adblockplus.jar!/locale/vi/overlay.dtd
similarity index 100%
rename from chrome/locale/vi/overlay.dtd
rename to chrome/adblockplus.jar!/locale/vi/overlay.dtd
diff --git a/chrome/locale/vi/sendReport.dtd b/chrome/adblockplus.jar!/locale/vi/sendReport.dtd
similarity index 100%
rename from chrome/locale/vi/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/vi/sendReport.dtd
diff --git a/chrome/locale/vi/settings.dtd b/chrome/adblockplus.jar!/locale/vi/settings.dtd
similarity index 100%
rename from chrome/locale/vi/settings.dtd
rename to chrome/adblockplus.jar!/locale/vi/settings.dtd
diff --git a/chrome/locale/vi/sidebar.dtd b/chrome/adblockplus.jar!/locale/vi/sidebar.dtd
similarity index 100%
rename from chrome/locale/vi/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/vi/sidebar.dtd
diff --git a/chrome/locale/vi/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/vi/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/vi/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/vi/subscriptionSelection.dtd
diff --git a/chrome/locale/zh-CN/about.dtd b/chrome/adblockplus.jar!/locale/zh-CN/about.dtd
similarity index 100%
rename from chrome/locale/zh-CN/about.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/about.dtd
diff --git a/chrome/locale/zh-CN/composer.dtd b/chrome/adblockplus.jar!/locale/zh-CN/composer.dtd
similarity index 100%
rename from chrome/locale/zh-CN/composer.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/composer.dtd
diff --git a/chrome/locale/zh-CN/global.properties b/chrome/adblockplus.jar!/locale/zh-CN/global.properties
similarity index 100%
rename from chrome/locale/zh-CN/global.properties
rename to chrome/adblockplus.jar!/locale/zh-CN/global.properties
diff --git a/chrome/locale/zh-CN/overlay.dtd b/chrome/adblockplus.jar!/locale/zh-CN/overlay.dtd
similarity index 100%
rename from chrome/locale/zh-CN/overlay.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/overlay.dtd
diff --git a/chrome/locale/zh-CN/sendReport.dtd b/chrome/adblockplus.jar!/locale/zh-CN/sendReport.dtd
similarity index 100%
rename from chrome/locale/zh-CN/sendReport.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/sendReport.dtd
diff --git a/chrome/locale/zh-CN/settings.dtd b/chrome/adblockplus.jar!/locale/zh-CN/settings.dtd
similarity index 100%
rename from chrome/locale/zh-CN/settings.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/settings.dtd
diff --git a/chrome/locale/zh-CN/sidebar.dtd b/chrome/adblockplus.jar!/locale/zh-CN/sidebar.dtd
similarity index 100%
rename from chrome/locale/zh-CN/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/sidebar.dtd
diff --git a/chrome/locale/zh-CN/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/zh-CN/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/zh-CN/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/zh-CN/subscriptionSelection.dtd
diff --git a/chrome/locale/zh-TW/about.dtd b/chrome/adblockplus.jar!/locale/zh-TW/about.dtd
similarity index 100%
rename from chrome/locale/zh-TW/about.dtd
rename to chrome/adblockplus.jar!/locale/zh-TW/about.dtd
diff --git a/chrome/locale/zh-TW/composer.dtd b/chrome/adblockplus.jar!/locale/zh-TW/composer.dtd
similarity index 100%
rename from chrome/locale/zh-TW/composer.dtd
rename to chrome/adblockplus.jar!/locale/zh-TW/composer.dtd
diff --git a/chrome/locale/zh-TW/global.properties b/chrome/adblockplus.jar!/locale/zh-TW/global.properties
similarity index 100%
rename from chrome/locale/zh-TW/global.properties
rename to chrome/adblockplus.jar!/locale/zh-TW/global.properties
diff --git a/chrome/adblockplus.jar!/locale/zh-TW/overlay.dtd b/chrome/adblockplus.jar!/locale/zh-TW/overlay.dtd
new file mode 100644
index 0000000..0fe97d5
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/zh-TW/overlay.dtd
@@ -0,0 +1,27 @@
+<!ENTITY status.tooltip "çæ
:">
+<!ENTITY blocked.tooltip "æ¤é å·²å°éé
ç®:">
+<!ENTITY filters.tooltip "æå¸¸ç¨çæ¢ä»¶:">
+<!ENTITY menuitem.label "Adblock Plus å好è¨å®">
+<!ENTITY menuitem.accesskey "b">
+<!ENTITY toolbarbutton.label "Adblock Plus">
+<!ENTITY view.blockableItems.label "Adblock Plus: å¯é»æé
ç®">
+<!ENTITY context.image.label "Adblock Plus: 黿åç">
+<!ENTITY context.object.label "Adblock Plus: 黿ç©ä»¶">
+<!ENTITY context.frame.label "Adblock Plus: é»æé æ¡">
+<!ENTITY context.media.label "Adblock Plus: 黿影é³">
+<!ENTITY context.removeWhitelist.label "Adblock Plus: 卿¤é é¢éæ°åç¨">
+<!ENTITY sidebar.title "æ¬é å¯é»æé
ç®">
+<!ENTITY sendReport.label "åå ±æ¤é é¢é¯èª¤">
+<!ENTITY sendReport.accesskey "R">
+<!ENTITY settings.label "å好è¨å®">
+<!ENTITY settings.accesskey "f">
+<!ENTITY opensidebar.label "éåå¯é»æé
ç®">
+<!ENTITY opensidebar.accesskey "b">
+<!ENTITY closesidebar.label "ééå¯é»æé
ç®">
+<!ENTITY closesidebar.accesskey "b">
+<!ENTITY whitelist.site.label "卿¤ç¶²ååç¨: ?1?">
+<!ENTITY whitelist.page.label "åªå¨æ¤é é¢åç¨">
+<!ENTITY disable.label "å
¨é¨åç¨">
+<!ENTITY recommend.label "å¨ Facebook ä¸çµ¦æå建è°">
+<!ENTITY objecttab.title "å°é">
+<!ENTITY objecttab.tooltip "è«æéè£¡ç¨ Adblock Plus å°éæ¤ç©ä»¶">
diff --git a/chrome/adblockplus.jar!/locale/zh-TW/sendReport.dtd b/chrome/adblockplus.jar!/locale/zh-TW/sendReport.dtd
new file mode 100644
index 0000000..652fa5c
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/zh-TW/sendReport.dtd
@@ -0,0 +1,92 @@
+<!ENTITY wizard.title "é¯èª¤åå ±å¨">
+<!ENTITY privacyPolicy.label "é±ç§æ¿ç">
+<!ENTITY dataCollector.heading "æ¡è¿ä½¿ç¨é¯èª¤åå ±å¨">
+<!ENTITY dataCollector.description "è«ç¨åï¼Adblock Plus æ£å¨èéå¿
è¦çè³æã">
+<!ENTITY typeSelector.heading "鏿åé¡é¡å">
+<!ENTITY typeSelector.description "æ¬è¦çªæä¸æ¥æ¥æå°æ¨å³éä¸ä»½ Adblock Plus é¯èª¤å ±åã
+ é¦å
ï¼è«å
鏿æ¨éå°çé¯èª¤é¡å:">
+<!ENTITY typeSelector.falsePositive.label "Adblock Plus æäºå¤ªå¤æ±è¥¿">
+<!ENTITY typeSelector.falsePositive.accesskey "m">
+<!ENTITY typeSelector.falsePositive.description "鏿æ¤é¸é
表示網é 缺å°äºä¸»è¦å
§å®¹ã顯示é¯èª¤æåè½ç°å¸¸ã
+ æ¨å¯ä»¥æ«æåç¨ Adblock Plus å¾åè©¦ä¸æ¬¡ï¼è¥åç¨å¾å顿¶å¤±ï¼
+ åå¾å¯è½å°±æ¯ Adblock Plus çåé¡ã">
+<!ENTITY typeSelector.falseNegative.label "Adblock Plus æ²æææå»£å">
+<!ENTITY typeSelector.falseNegative.accesskey "v">
+<!ENTITY typeSelector.falseNegative.description "鏿æ¤é¸é
表示éç¶å·²åç¨ Adblock Plusï¼ä½å»£åä¾ç¶é¡¯ç¤ºå¨ç¶²é ä¸ã">
+<!ENTITY typeSelector.other.label "å
¶ä»é¯èª¤">
+<!ENTITY typeSelector.other.accesskey "t">
+<!ENTITY typeSelector.other.description "鏿æ¤é¸é
表示æå
¶ä»é¯èª¤ç¼çï¼è䏿¨æ·çæ¯ Adblock Plus æ¬èº«é æèééæ¿¾æ¢ä»¶å¼èµ·çé¯èª¤ã">
+<!ENTITY showRecentReports.label "顯示æè¿å³éçé¯èª¤å ±å">
+<!ENTITY recentReports.label "æ¨æè¿çé¯èª¤å ±å">
+<!ENTITY recentReports.clear.label "ç§»é¤ææé¯èª¤å ±å">
+<!ENTITY recentReports.clear.accesskey "R">
+<!ENTITY issues.description "Adblock Plus 嵿¸¬å°æäºè¨å®å¼å¯è½æé æè©²é¯èª¤ï¼ææ¯å½±é¿åæçµæã">
+<!ENTITY issues.whitelist.description "Adblock Plus ç®å卿¨åå ±çé é¢ä¸åç¨ãçºäºåå©åæé¯èª¤ï¼å¨å³éé¯èª¤å ±ååè«éæ°åç¨ä¸¦éæ°è¼å
¥è©²é é¢ã">
+<!ENTITY issues.whitelist.remove.label "éæ°åç¨ Adblock Plus æ¼æ¤é é¢">
+<!ENTITY issues.disabled.description "Adblock Plus å·²åç¨ï¼ç®åçæ
ä¸ä¸æé»æä»»ä½ç¶²é å
§å®¹ã">
+<!ENTITY issues.disabled.enable.label "åç¨ Adblock Plus">
+<!ENTITY issues.nofilters.description "Adblock Plus æ¼æ¤é 颿²æé»æä»»ä½å
§å®¹ãæ¨åå ±çé¯èª¤å¯è½å Adblock Plus ç¡éã">
+<!ENTITY issues.nosubscriptions.description "æ¨ä¼¼ä¹æ²æè¨é±ä»»ä½é濾æ¢ä»¶éï¼è¨é±é濾æ¢ä»¶éå¯èªåç§»é¤èç¶²é å
§å®¹ç¡éç廣åã">
+<!ENTITY issues.nosubscriptions.add.label "è¨é±é濾æ¢ä»¶é">
+<!ENTITY issues.subscriptionCount.description "æ¨ä¼¼ä¹è¨é±äºéå¤çéæ¿¾æ¢ä»¶éãæåä¸å»ºè°é麼åï¼å çºéå¯è½æå¢å ç¼çé¯èª¤çæ©çãåææåç¡æ³æ¥åæ¨çé¯èª¤åå ±ï¼å çºå¾é£å辨æ¯åªåæ¢ä»¶éåºäºåé¡ãè«ç§»é¤ä¸éè¦çéæ¿¾æ¢ä»¶éå¾åæ¸¬è©¦ä¸æ¬¡ï¼ççé¯èª¤æ¯å¦ä»æç¼çã">
+<!ENTITY issues.openPreferences.label "éåéæ¿¾æ¢ä»¶è¨å®è¦çª">
+<!ENTITY issues.ownfilters.description "該é é¢çæäºé濾æ¢ä»¶æ¯æ¨èªå·±æåè¨å®çã
+ è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
+<!ENTITY issues.ownfilters.disable.label "åç¨é濾æ¢ä»¶">
+<!ENTITY issues.disabledgroups.description "ä¸åéæ¿¾æ¢ä»¶é/éæ¿¾æ¢ä»¶çµå·²åç¨ï¼
+ è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
+<!ENTITY issues.disabledgroups.enable.label "åç¨é濾æ¢ä»¶é/éæ¿¾æ¢ä»¶çµ">
+<!ENTITY issues.disabledfilters.description "ä¸åéæ¿¾æ¢ä»¶å·²åç¨ï¼
+ è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
+<!ENTITY issues.disabledfilters.enable.label "åç¨é濾æ¢ä»¶">
+<!ENTITY issues.override.label "è¨å®å¼ç¡èª¤ï¼ç¹¼çºåå ±é¯èª¤">
+<!ENTITY issues.override.accesskey "c">
+<!ENTITY issues.change.description "æ¨çè¨å®å¼å·²è®æ´ãè«éæ°è¼å
¥é 颿¸¬è©¦é¯èª¤æ¯å¦ä»ç¶åå¨ï¼
+ è¥é¯èª¤ä¾èåå¨ï¼åå¿
é å³éé¯èª¤å ±åã">
+<!ENTITY typeWarning.description "æ¨è¡¨ç¤ºæ¨è¦åå ±çé¯èª¤æ¯ Adblock Plus æ¬èº«çé¯èª¤èééæ¿¾æ¢ä»¶å¼èµ·çé¯èª¤ã
+ è«æ³¨æï¼éé¡ç¨å¼é¯èª¤æå¥½è½å° [link]Adblock Plus è¨è«å[/link] ä¸åå ±ã
+ æ¬åå ±å¨å°éé¡é¯èª¤åªè½ç¨æ¼è¨è«åä¸å·²åå¨æç« çè£å
說æï¼
+ æ¨å¿
é å¨ Adblock Plus è¨è«åçæç« ä¸è²¼ä¸é次åå ±çé¯èª¤å ±åé£çµï¼å¦åç¡äººæç¼ç¾æ¤é¯èª¤å ±åã
+ é¯èª¤å ±åé£çµå¨å³éæåä¹å¾æèªåç¢çã">
+<!ENTITY typeWarning.override.label "æäºè§£ä¸¦è¦å³éé¯èª¤å ±å">
+<!ENTITY typeWarning.override.accesskey "s">
+<!ENTITY reloadButton.label "éæ°è¼å
¥é é¢">
+<!ENTITY reloadButton.accesskey "R">
+<!ENTITY screenshot.heading "éå è¢å¹æå">
+<!ENTITY screenshot.description "忍£çé 颿¯å人çå°çæ
æ³å¯è½é½ä¸åãéå è¢å¹æåå°å ±åä¸å¯ä»¥å¹«æåæ´è½äºè§£å顿å¨ã
+ æ¨å¯ä»¥å
ç§»é¤å
§å«ææ (ç§äºº) è³è¨çé¨ä»½ã並æ¨ç¤ºåºé¯èª¤ç¼ççæ®µè½ã
+ åªè¦æä¸å°æçæéä¸¦ç¨æ»é¼ 鏿æ¨è¦ç§»é¤/æ¨ç¤ºç段è½å³å¯ã">
+<!ENTITY screenshot.attach.label "éå é é¢åçå°å ±åä¸">
+<!ENTITY screenshot.attach.accesskey "t">
+<!ENTITY screenshot.mark.label "æ¨ç¤ºå顿å¨">
+<!ENTITY screenshot.mark.accesskey "M">
+<!ENTITY screenshot.remove.label "ç§»é¤ææ (ç§äºº) è³è¨">
+<!ENTITY screenshot.remove.accesskey "R">
+<!ENTITY screenshot.undo.label "復å">
+<!ENTITY screenshot.undo.accesskey "U">
+<!ENTITY commentPage.heading "輸å
¥å註">
+<!ENTITY commentPage.description "ä¸é¢çæåæ¹å¡å¯ä»¥è®æ¨è¼¸å
¥é¡å¤çå註ï¼ä»¥å¹«å©æåæ´è½äºè§£å顿å¨ã
+ é忥é©ä¸æ¯å¿
é çï¼ä½è¥åé¡ä¸å¤ªæé¡¯ææ¯è¼è¤éï¼å»ºè°æ¨éæ¯å¯«ä¸é¯èª¤ç詳細說æã
+ å¨åå ±ä¹åæ¨ä¹å¯ä»¥æª¢è¦å ±åè³æã">
+<!ENTITY comment.label "å註 (é¸ç¨):">
+<!ENTITY comment.accesskey "C">
+<!ENTITY comment.lengthWarning "æ¨è¼¸å
¥çå註è¶
é 1000 ååå
ï¼å註æ¬ä½åªè½å³é 1000 ååå
ã">
+<!ENTITY email.label "é²ä¸æ¥è¯ç¹«ç Email å°å (é¸ç¨):">
+<!ENTITY email.accesskey "m">
+<!ENTITY attachExtensions.label "éå ç®ååç¨çå¥ä»¶æ¸
å®å°å ±åä¸ï¼ä»¥ä¾¿æé¤æ¯å¥ä»¶è¡çªæé æçé¯èª¤">
+<!ENTITY attachExtensions.accesskey "x">
+<!ENTITY sendButton.label "å³éå ±å">
+<!ENTITY sendButton.accesskey "n">
+<!ENTITY showData.label "é¡¯ç¤ºå ±åè³æ">
+<!ENTITY data.label "å ±åè³æ:">
+<!ENTITY data.accesskey "p">
+<!ENTITY sendPage.heading "å³éå ±å">
+<!ENTITY sendPage.waitMessage "è«ç¨åï¼Adblock Plus æ£å¨å³éæ¨çå ±åã">
+<!ENTITY sendPage.confirmation "æ¨çå ±åå·²å²åï¼æ¨å¯ä»¥é»é¸ä¸åç¶²åæª¢è¦å ±å:">
+<!ENTITY sendPage.knownIssue "æ¨åå ±çé¯èª¤å·²éè¤ï¼æª¢è¦æ´å¤è³è¨:">
+<!ENTITY sendPage.errorMessage "å³éé¯èª¤å ±å失æï¼é¯èª¤ç¢¼ "?1?"ã
+ è«ç¢ºå®æ¨å·²é£ä¸ç¶²è·¯å¾åè©¦ä¸æ¬¡ãè¥ä¾è失æï¼
+ è«é£ä¸ [link]Adblock Plus è¨è«å[/link] å°æ±å¹«å©ã">
+<!ENTITY sendPage.retry.label "忬¡å³é">
+<!ENTITY copyLink.label "è¤è£½å ±åé£çµ">
+<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/adblockplus.jar!/locale/zh-TW/settings.dtd b/chrome/adblockplus.jar!/locale/zh-TW/settings.dtd
new file mode 100644
index 0000000..9cb851d
--- /dev/null
+++ b/chrome/adblockplus.jar!/locale/zh-TW/settings.dtd
@@ -0,0 +1,89 @@
+<!ENTITY dialog.title "Adblock Plus å好è¨å®">
+<!ENTITY filters.label "éæ¿¾æ¢ä»¶">
+<!ENTITY filters.accesskey "F">
+<!ENTITY add.label "æ°å¢é濾æ¢ä»¶">
+<!ENTITY add.accesskey "A">
+<!ENTITY addsubscription.label "è¨é±é濾æ¢ä»¶é">
+<!ENTITY addsubscription.accesskey "S">
+<!ENTITY synchsubscriptions.label "æ´æ°æææ¢ä»¶é">
+<!ENTITY synchsubscriptions.accesskey "D">
+<!ENTITY import.label "å¯å
¥é濾æ¢ä»¶">
+<!ENTITY import.accesskey "M">
+<!ENTITY export.label "å¯åºé濾æ¢ä»¶">
+<!ENTITY export.accesskey "X">
+<!ENTITY clearall.label "åªé¤ææèªè¨æ¢ä»¶">
+<!ENTITY clearall.accesskey "L">
+<!ENTITY resethitcounts.label "éè¨å½ä¸çµ±è¨è³æ">
+<!ENTITY resethitcounts.accesskey "R">
+<!ENTITY edit.label "編輯">
+<!ENTITY edit.accesskey "E">
+<!ENTITY cut.label "åªä¸">
+<!ENTITY cut.accesskey "T">
+<!ENTITY copy.label "è¤è£½">
+<!ENTITY copy.accesskey "C">
+<!ENTITY paste.label "è²¼ä¸">
+<!ENTITY paste.accesskey "P">
+<!ENTITY remove.label "åªé¤">
+<!ENTITY remove.accesskey "D">
+<!ENTITY menu.find.label "å°æ¾">
+<!ENTITY menu.find.accesskey "F">
+<!ENTITY menu.findagain.label "éæ°å°æ¾">
+<!ENTITY menu.findagain.accesskey "G">
+<!ENTITY view.label "檢è¦">
+<!ENTITY view.accesskey "V">
+<!ENTITY sort.label "æåº">
+<!ENTITY sort.accesskey "S">
+<!ENTITY sort.none.label "䏿åº">
+<!ENTITY sort.none.accesskey "U">
+<!ENTITY sort.ascending.label "éå¢æåº (A > Z)">
+<!ENTITY sort.ascending.accesskey "A">
+<!ENTITY sort.descending.label "éå¢æåº (Z > A)">
+<!ENTITY sort.descending.accesskey "Z">
+<!ENTITY options.label "é¸é
">
+<!ENTITY options.accesskey "O">
+<!ENTITY enable.label "åç¨ Adblock Plus">
+<!ENTITY enable.accesskey "N">
+<!ENTITY showintoolbar.label "å¨å·¥å
·å顯示">
+<!ENTITY showintoolbar.accesskey "B">
+<!ENTITY showinstatusbar.label "å¨çæ
å顯示">
+<!ENTITY showinstatusbar.accesskey "S">
+<!ENTITY objecttabs.label "å¨ Flash å Java ç©ä»¶ä¸é¡¯ç¤ºé 籤">
+<!ENTITY objecttabs.accesskey "T">
+<!ENTITY collapse.label "æç已黿å
ç´ ">
+<!ENTITY collapse.accesskey "L">
+<!ENTITY sync.label "忥 Adblock Plus è¨å®å¼">
+<!ENTITY sync.accesskey "c">
+<!ENTITY help.label "說æ">
+<!ENTITY help.accesskey "H">
+<!ENTITY gettingStarted.label "æ°æä¸è·¯ (è±æç¶²é )">
+<!ENTITY gettingStarted.accesskey "s">
+<!ENTITY faq.label "常è¦åé¡é (è±æç¶²é )">
+<!ENTITY faq.accesskey "F">
+<!ENTITY filterdoc.label "å¦ä½æ°å¯«é濾æ¢ä»¶ (è±æç¶²é )">
+<!ENTITY filterdoc.accesskey "R">
+<!ENTITY about.label "éæ¼ Adblock Plus">
+<!ENTITY about.accesskey "B">
+<!ENTITY description "ä¸é¢ååºçéæ¿¾æ¢ä»¶ææ±ºå®åªäºç¶²åæè¢«é»æãåªäºç¶²åæå
許顯示:">
+<!ENTITY filter.column "éæ¿¾è¦å">
+<!ENTITY filter.accesskey "F">
+<!ENTITY slow.column "ç·©æ
¢é濾æ¢ä»¶">
+<!ENTITY slow.accesskey "w">
+<!ENTITY enabled.column "å·²åç¨">
+<!ENTITY enabled.accesskey "n">
+<!ENTITY hitcount.column "å½ä¸æ¸">
+<!ENTITY hitcount.accesskey "H">
+<!ENTITY lasthit.column "æå¾ä½¿ç¨">
+<!ENTITY lasthit.accesskey "L">
+<!ENTITY context.edit.label "ç·¨è¼¯éæ¿¾æ¢ä»¶">
+<!ENTITY context.resethitcount.label "éè¨æ¤æ¢ä»¶çµ±è¨è³æ">
+<!ENTITY context.synchsubscription.label "ç«å³æ´æ°è¨é±æ¢ä»¶é">
+<!ENTITY context.editsubscription.label "編輯è¨é±æ¸
å®">
+<!ENTITY context.moveup.label "åä¸ç§»">
+<!ENTITY context.movedown.label "åä¸ç§»">
+<!ENTITY context.movegroupup.label "æ´çµåä¸ç§»">
+<!ENTITY context.movegroupdown.label "æ´çµåä¸ç§»">
+<!ENTITY context.enable.label "åç¨">
+<!ENTITY context.disable.label "åç¨">
+<!ENTITY apply.label "å¥ç¨">
+<!ENTITY apply.accesskey "P">
+<!ENTITY fennec.subscription.label "éæ¿¾æ¢ä»¶è¨é±">
diff --git a/chrome/locale/zh-TW/sidebar.dtd b/chrome/adblockplus.jar!/locale/zh-TW/sidebar.dtd
similarity index 100%
rename from chrome/locale/zh-TW/sidebar.dtd
rename to chrome/adblockplus.jar!/locale/zh-TW/sidebar.dtd
diff --git a/chrome/locale/zh-TW/subscriptionSelection.dtd b/chrome/adblockplus.jar!/locale/zh-TW/subscriptionSelection.dtd
similarity index 100%
rename from chrome/locale/zh-TW/subscriptionSelection.dtd
rename to chrome/adblockplus.jar!/locale/zh-TW/subscriptionSelection.dtd
diff --git a/chrome/adblockplus.jar!/skin/about.css b/chrome/adblockplus.jar!/skin/about.css
new file mode 100644
index 0000000..5db9c00
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/about.css
@@ -0,0 +1,58 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#mainBox
+{
+ visibility: hidden;
+}
+#mainBox[loaded]
+{
+ visibility: visible;
+}
+
+#title
+{
+ font-size: 48px;
+ font-weight: bold;
+}
+
+#mainGroup
+{
+ margin-top: 15px;
+ width: 450px;
+ height: 400px;
+ overflow: auto;
+}
+
+#homepageTitle, #authorsTitle, #contributorsTitle, #subscriptionAuthorsTitle, #translatorsTitle
+{
+ font-weight: bold;
+}
+
+#description, #homepage, #authorsBox, #contributorsBox, #subscriptionAuthorsBox
+{
+ margin-bottom: 10px;
+}
diff --git a/chrome/skin/abp-icon-big.png b/chrome/adblockplus.jar!/skin/abp-icon-big.png
similarity index 100%
rename from chrome/skin/abp-icon-big.png
rename to chrome/adblockplus.jar!/skin/abp-icon-big.png
diff --git a/chrome/skin/abp-status-16.png b/chrome/adblockplus.jar!/skin/abp-status-16.png
similarity index 100%
rename from chrome/skin/abp-status-16.png
rename to chrome/adblockplus.jar!/skin/abp-status-16.png
diff --git a/chrome/skin/abp-status.png b/chrome/adblockplus.jar!/skin/abp-status.png
similarity index 100%
rename from chrome/skin/abp-status.png
rename to chrome/adblockplus.jar!/skin/abp-status.png
diff --git a/chrome/skin/checkbox.png b/chrome/adblockplus.jar!/skin/checkbox.png
similarity index 100%
rename from chrome/skin/checkbox.png
rename to chrome/adblockplus.jar!/skin/checkbox.png
diff --git a/chrome/skin/close.png b/chrome/adblockplus.jar!/skin/close.png
similarity index 100%
rename from chrome/skin/close.png
rename to chrome/adblockplus.jar!/skin/close.png
diff --git a/chrome/adblockplus.jar!/skin/composer.css b/chrome/adblockplus.jar!/skin/composer.css
new file mode 100644
index 0000000..130cb9f
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/composer.css
@@ -0,0 +1,84 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+ at namespace html url("http://www.w3.org/1999/xhtml");
+
+/*
+ * Force left-to-right everywhere where we are displaying addresses
+ */
+.suggestion > .radio-label-box:-moz-locale-dir(rtl),
+html|*.textbox-input:-moz-locale-dir(rtl)
+{
+ direction: ltr;
+ text-align: end;
+}
+
+#patternGroup {
+ overflow: auto;
+}
+
+#anchorGroup {
+ padding-left: 20px;
+}
+
+#typeGroupLabel {
+ margin-top: 10px;
+}
+
+#typeGroup {
+ overflow: auto;
+ margin-bottom: 10px
+}
+
+:root:not([advancedMode="true"]) #options {
+ display: none;
+}
+
+#disabledWarning, #groupDisabledWarning, #regexpWarning, #shortpatternWarning, #matchWarning {
+ color: #E00000;
+}
+
+#disabledWarning > *, #groupDisabledWarning > * {
+ margin: 0px;
+ font-size: inherit;
+}
+
+.text-link {
+ font-size: 80%;
+ -moz-user-focus: ignore;
+}
+
+.help {
+ color: #0000E0;
+ border-bottom: 1px dotted #0000E0;
+ cursor: help;
+ margin: 0px;
+ padding: 0px;
+}
+
+tooltip {
+ /* Gecko 1.8.1 doesn't support multiline tooltips :-( */
+ max-width: none;
+}
diff --git a/chrome/skin/item-state.png b/chrome/adblockplus.jar!/skin/item-state.png
similarity index 100%
rename from chrome/skin/item-state.png
rename to chrome/adblockplus.jar!/skin/item-state.png
diff --git a/chrome/adblockplus.jar!/skin/overlay.css b/chrome/adblockplus.jar!/skin/overlay.css
new file mode 100644
index 0000000..eccdf16
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/overlay.css
@@ -0,0 +1,201 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#abp-status
+{
+ cursor: pointer;
+}
+
+toolbar[iconsize="small"] #abp-toolbarbutton,
+#PersonalToolbar #abp-toolbarbutton,
+#header-view-toolbar > #abp-toolbarbutton,
+#abp-status {
+ list-style-image: url("abp-status-16.png");
+ -moz-image-region: rect(0px, 16px, 16px, 0px);
+}
+toolbar[iconsize="small"] #abp-toolbarbutton[abpstate="disabled"],
+#PersonalToolbar #abp-toolbarbutton[abpstate="disabled"],
+#header-view-toolbar > #abp-toolbarbutton[abpstate="disabled"],
+#abp-status[abpstate="disabled"],
+toolbar[iconsize="small"] #abp-toolbarbutton[abpstate="whitelisted"],
+#PersonalToolbar #abp-toolbarbutton[abpstate="whitelisted"],
+#header-view-toolbar > #abp-toolbarbutton[abpstate="whitelisted"],
+#abp-status[abpstate="whitelisted"] {
+ -moz-image-region: rect(16px, 16px, 32px, 0px);
+}
+
+#abp-toolbar-popup {
+ list-style-image: none;
+ -moz-image-region: rect(0px, 0px, 0px, 0px);
+}
+
+toolbox[vertical="true"] toolbar #abp-toolbarbutton dropmarker {
+ display: none !important;
+}
+
+menuitem[default="true"] {
+ font-weight: bold;
+}
+
+#abp-toolbarbutton,
+#abp-site-info {
+ list-style-image: url("abp-status.png");
+ -moz-image-region: rect(0px, 24px, 24px, 0px);
+}
+#abp-toolbarbutton[abpstate="disabled"],
+#abp-toolbarbutton[abpstate="whitelisted"],
+#abp-site-info[abpstate="disabled"],
+#abp-site-info[abpstate="disabled_site"] {
+ -moz-image-region: rect(24px, 24px, 48px, 0px);
+}
+
+/* Hack: force the label to be displayed below icon for type="menu" */
+#abp-toolbarbutton[type="menu"]
+{
+ -moz-box-orient: horizontal;
+}
+toolbar[mode="full"] #abp-toolbarbutton[type="menu"]
+{
+ -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-vertical");
+}
+
+/* Thunderbird-specific toolbar icon styles */
+#header-view-toolbar > #abp-toolbarbutton
+{
+ -moz-appearance: dualbutton;
+ padding: 0px !important;
+}
+
+/* Hide toolbar icon text in Thunderbird to save space */
+#header-view-toolbar > #abp-toolbarbutton .toolbarbutton-text
+{
+ display: none;
+}
+
+/* SeaMonkey expects the icon to be rather large, add margin */
+#mail-toolbox #abp-toolbarbutton .toolbarbutton-icon
+{
+ margin-top: 5px;
+}
+
+#abp-status-image {
+ margin-left: 10px;
+ margin-right: 10px;
+}
+
+#abp-site-info .pageaction-image {
+ width: 32px;
+ height: 32px;
+ padding: 4px;
+}
+
+#abp-toolbarbutton > toolbarbutton {
+ /* Argh, Songbird defines image region directly on the anonymous toolbarbutton element */
+ -moz-image-region: inherit !important;
+}
+
+#abp-tooltip {
+ max-width: none;
+}
+
+#abp-tooltip label {
+ font-weight: bold;
+ margin-bottom: 0px;
+}
+
+#abp-tooltip description:not([hidden="true"])+label {
+ margin-top: 10px;
+}
+
+#abp-sidebar-title {
+ padding-left: 4px;
+}
+
+#abp-sidebar-toolbar {
+ display: -moz-box !important;
+ visibility: visible !important;
+}
+
+#abp-sidebar-close {
+ padding: 4px 2px;
+ border-style: none !important;
+ -moz-user-focus: normal;
+ list-style-image: url("close.png");
+ -moz-appearance: none;
+ -moz-image-region: rect(0px, 14px, 14px, 0px);
+}
+
+#abp-sidebar-close:hover {
+ -moz-image-region: rect(0px, 28px, 14px, 14px);
+}
+
+#abp-sidebar-close:hover:active {
+ -moz-image-region: rect(0px, 42px, 14px, 28px);
+}
+
+.abp-recommendbutton
+{
+ opacity: 0.7;
+ margin-top: 20px;
+}
+
+.abp-recommendbutton:hover
+{
+ opacity: 1;
+}
+
+.abp-recommendbutton-btn
+{
+ font-size: 80%;
+ margin-left: 40px;
+ margin-right: 40px;
+ list-style-image: url("data:image/gif;base64,R0lGODlhEAAQAKIAAGF5rEVinmB4q%2Bvu9G2EtP%2F%2F%2FztZmAAAACH5BAAAAAAALAAAAAAQABAAAAM4WLrcCibKGYGiWN4sxt6Y9xWZAZpkdp6R06bTIMpvucLUbeNKQPxAggIY6AWBw1%2BxAClJLI7oIgEAOw%3D%3D");
+}
+
+.abp-recommendbutton-close
+{
+ border-style: none !important;
+ -moz-user-focus: normal;
+ list-style-image: url("close.png");
+ -moz-appearance: none;
+ -moz-image-region: rect(0px, 14px, 14px, 0px);
+}
+
+.abp-recommendbutton-close:hover
+{
+ -moz-image-region: rect(0px, 28px, 14px, 14px);
+}
+
+#abp-survey-message > .title
+{
+ font-weight: bold;
+ font-size: 130%;
+}
+
+#abp-survey-message > .note
+{
+ font-size: 80%;
+}
diff --git a/chrome/adblockplus.jar!/skin/sendReport.css b/chrome/adblockplus.jar!/skin/sendReport.css
new file mode 100644
index 0000000..c07de7b
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/sendReport.css
@@ -0,0 +1,124 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+.wizard-header
+{
+ -moz-binding: url(chrome://adblockplus/content/ui/sendReport.xul#headerBinding) !important;
+ padding: 10px 5px !important;
+}
+
+.progressLabel
+{
+ margin: 5px 0px;
+ text-align: center;
+ font-size: 110%;
+ font-weight: normal;
+}
+
+.progressLabel.active
+{
+ font-weight: bold;
+}
+
+progressmeter
+{
+ margin-top: 100px;
+}
+
+.radioDescription
+{
+ -moz-margin-start: 32px;
+}
+
+radio, checkbox, .topLabel, #dataDeck
+{
+ margin-top: 15px;
+}
+
+#recentReports
+{
+ margin-top: 15px;
+}
+
+#recentReportsList
+{
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+
+#issuesBox
+{
+ overflow: auto;
+}
+
+#issuesChangeMessage
+{
+ color: red;
+}
+
+#screenshotButtons
+{
+ margin-top: 10px;
+}
+
+#screenshotBox
+{
+ overflow-y: scroll;
+}
+
+#commentLengthWarning
+{
+ color: red;
+}
+
+#commentLengthWarning[visible="false"]
+{
+ visibility: hidden;
+}
+
+/*
+ * Force left-to-right everywhere where we are displaying addresses
+ */
+#data:-moz-locale-dir(rtl)
+{
+ direction: ltr;
+}
+
+#sendReportError
+{
+ color: red;
+ font-size: 150%;
+}
+
+#sendReportErrorLinks, #typeWarningTextLink
+{
+ margin: 0px;
+}
+
+#sendReportErrorBox
+{
+ margin-bottom: 10px;
+}
diff --git a/chrome/adblockplus.jar!/skin/settings.css b/chrome/adblockplus.jar!/skin/settings.css
new file mode 100644
index 0000000..ddaf339
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/settings.css
@@ -0,0 +1,165 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+ at namespace html url("http://www.w3.org/1999/xhtml");
+
+dialog {
+ padding: 0px;
+}
+
+.dialog-button-box, #introduction, #listarea {
+ margin: 8px;
+}
+
+deck, deck * {
+ margin: 0px;
+}
+
+#listEditor menupopup description {
+ margin: 1px 3px;
+}
+
+#listEditorIcon {
+ list-style-image: url("close.png");
+ -moz-image-region: rect(0px, 14px, 14px, 0px);
+ margin-left: 2px;
+}
+#listEditorIcon:hover {
+ -moz-image-region: rect(0px, 28px, 14px, 14px);
+}
+#listEditorIcon:hover:active {
+ -moz-image-region: rect(0px, 42px, 14px, 28px);
+}
+
+#col-slow {
+ text-align: center;
+}
+
+#col-hitcount, #col-lasthit {
+ text-align: right;
+}
+
+#col-hitcount {
+ min-width: 60px;
+}
+#col-enabled {
+ min-width: 16px;
+}
+#col-slow {
+ min-width: 30px;
+}
+
+/*
+ * Force left-to-right everywhere where we are displaying addresses
+ */
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-invalid),
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-whitelist),
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-filterlist),
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-elemhide)
+{
+ direction: ltr;
+ text-align: end;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, description-true, selected-false) {
+ font-size: 80%;
+ color: #808080;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, filter-true, type-whitelist, selected-false) {
+ color: #008000;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, filter-true, type-elemhide, selected-false) {
+ color: #000080;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, filter-false, subscription-upgradeRequired-true, selected-false) {
+ color: #FF0000;
+}
+
+treechildren::-moz-tree-cell-text(col-slow) {
+ font-size: 0px;
+}
+
+treechildren::-moz-tree-row(filter-true, filter-disabled-true, selected-false),
+treechildren::-moz-tree-row(subscription-disabled-true, selected-false) {
+ background-color: #E0E0E0;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, filter-true, type-comment, selected-false) {
+ color: #808080;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, filter-true, type-invalid, selected-false) {
+ color: #C00000;
+}
+
+treechildren::-moz-tree-cell-text(col-filter, subscription-true) {
+ font-weight: bold;
+}
+
+treechildren::-moz-tree-image(col-enabled, filter-true, subscription-disabled-false, filter-disabled-true),
+treechildren::-moz-tree-image(col-enabled, subscription-true, subscription-disabled-true) {
+ list-style-image: url(checkbox.png);
+ -moz-image-region: rect(13px 13px 26px 0px);
+}
+
+treechildren::-moz-tree-image(col-enabled, filter-true, subscription-disabled-false, filter-disabled-false),
+treechildren::-moz-tree-image(col-enabled, subscription-true, subscription-disabled-false, subscription-dummy-false) {
+ list-style-image: url(checkbox.png);
+ -moz-image-region: rect(0px 13px 13px 0px);
+}
+
+treechildren::-moz-tree-image(col-slow, filter-true, filter-regexp-true) {
+ list-style-image: url(slow.png);
+}
+
+treechildren::-moz-tree-image(col-enabled) {
+ margin-left: 7px;
+}
+#col-enabled {
+ min-width: 24px;
+}
+
+.whitelisted:not([_moz-menuactive="true"]) {
+ color: #008000;
+}
+
+.filtered:not([_moz-menuactive="true"]) {
+ color: #C00000;
+}
+
+#findbar {
+ border: none !important;
+}
+
+#findbar .findbar-highlight {
+ display: none;
+}
+
+tooltip {
+ max-width: none;
+}
diff --git a/chrome/adblockplus.jar!/skin/sidebar.css b/chrome/adblockplus.jar!/skin/sidebar.css
new file mode 100644
index 0000000..07dbec5
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/sidebar.css
@@ -0,0 +1,117 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#suggestionsList {
+ margin: 0px;
+}
+
+#detachButton, #reattachButton:not([disabled="true"]) {
+ text-decoration: underline;
+ cursor: pointer;
+}
+
+#reattachButton[disabled="true"] {
+ color: GrayText;
+}
+
+#detachButton, #reattachButton {
+ font-size: 90%;
+}
+
+tooltip {
+ max-width: none;
+}
+
+#tooltipPreview {
+ margin:10px;
+ max-width: 300px;
+ max-height: 300px;
+}
+
+#tooltip label {
+ font-weight: bold;
+}
+
+#contextBlock,
+#contextWhitelist {
+ font-weight: bold;
+}
+
+#state {
+ min-width: 16px;
+}
+
+#size {
+ text-align: end;
+}
+
+/*
+ * Force left-to-right everywhere where we are displaying addresses
+ */
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter),
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-address),
+treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-size)
+{
+ direction: ltr;
+ text-align: end;
+}
+
+.disabledTextLabel
+{
+ font-style: italic;
+}
+
+treechildren::-moz-tree-cell-text(state-filtered, selected-false),
+treechildren::-moz-tree-cell-text(state-hidden, selected-false) {
+ color: #C00000;
+}
+treechildren::-moz-tree-cell-text(state-whitelisted, selected-false) {
+ color: #008000;
+}
+
+treechildren::-moz-tree-image(col-state, dummy-false)
+{
+ list-style-image: url(item-state.png);
+ -moz-image-region: rect(0px 10px 10px 0px);
+ margin-left: 3px;
+}
+treechildren::-moz-tree-image(col-state, filter-disabled-true, dummy-false) {
+ -moz-image-region: rect(10px 10px 20px 0px);
+}
+treechildren::-moz-tree-image(col-state, state-filtered, dummy-false),
+treechildren::-moz-tree-image(col-state, state-hidden, dummy-false) {
+ -moz-image-region: rect(20px 10px 30px 0px);
+}
+treechildren::-moz-tree-image(col-state, state-whitelisted, dummy-false) {
+ -moz-image-region: rect(30px 10px 40px 0px);
+}
+
+treechildren::-moz-tree-cell-text(col-filter, state-hidden, selected-false) {
+ color: #000080;
+}
+treechildren::-moz-tree-cell-text(col-filter, filter-disabled-true, selected-false) {
+ color: #C0C0C0;
+}
diff --git a/chrome/skin/slow.png b/chrome/adblockplus.jar!/skin/slow.png
similarity index 100%
rename from chrome/skin/slow.png
rename to chrome/adblockplus.jar!/skin/slow.png
diff --git a/chrome/adblockplus.jar!/skin/subscriptionSelection.css b/chrome/adblockplus.jar!/skin/subscriptionSelection.css
new file mode 100644
index 0000000..24de1e4
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/subscriptionSelection.css
@@ -0,0 +1,98 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+dialog
+{
+ min-width: 550px;
+}
+
+dialog[newInstall]
+{
+ background-image: url(abp-icon-big.png);
+ background-repeat: no-repeat;
+ background-position: 95% 5%;
+}
+
+dialog[newInstall] .dialog-content-box,
+dialog[newInstall] #content-scroll
+{
+ min-height: 150px;
+}
+
+#description-newInstall,
+#adblock-warning,
+#filtersetg-warning
+{
+ margin-bottom: 10px;
+}
+
+*[invisible="true"]
+{
+ visibility: hidden;
+}
+
+#adblock-warning,
+#filtersetg-warning,
+#supplementMessage
+{
+ color: #F00000;
+}
+
+.localeMatch
+{
+ font-weight: bold;
+}
+
+#all-subscriptions-loading
+{
+ margin: 50px;
+}
+
+#all-subscriptions
+{
+ min-height: 200px;
+}
+#all-subscriptions > richlistitem > .variant
+{
+ width: 200px;
+}
+#all-subscriptions > richlistitem:not(:first-child) > .subscriptionTitle,
+#all-subscriptions > richlistitem:not(:first-child) > .subscriptionTitle + .variant
+{
+ border-top: 1px dashed black;
+ margin-top: 0px;
+ padding-top: 4px;
+}
+
+#supplementMessage
+{
+ margin-top: 5px;
+}
+#supplementMessage > label
+{
+ margin-left: 0px;
+ margin-right: 0px;
+}
diff --git a/chrome/adblockplus.jar!/skin/subscriptionSelectionFennec.css b/chrome/adblockplus.jar!/skin/subscriptionSelectionFennec.css
new file mode 100644
index 0000000..e70d5ac
--- /dev/null
+++ b/chrome/adblockplus.jar!/skin/subscriptionSelectionFennec.css
@@ -0,0 +1,37 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+ at import url("chrome://browser/skin/platform.css");
+
+ at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+dialog
+{
+ min-width: 0px;
+}
+
+#all-subscriptions-container
+{
+ font-size: 60%;
+}
diff --git a/chrome/content/fennecContent.js b/chrome/content/fennecContent.js
deleted file mode 100644
index d37b01c..0000000
--- a/chrome/content/fennecContent.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Fabrice Desré.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Wladimir Palant
- *
- * ***** END LICENSE BLOCK ***** */
-
-if (!("@adblockplus.org/abp/policy;1" in Components.classes))
- Components.utils.import("chrome://adblockplus-modules/content/ContentPolicyRemote.jsm");
-if (!("@mozilla.org/network/protocol/about;1?what=abp-elemhidehit" in Components.classes))
- Components.utils.import("chrome://adblockplus-modules/content/ElemHideRemote.jsm");
-
-addEventListener("click", function(event)
-{
- // Ignore right-clicks
- if (event.button == 2)
- return;
-
- // Search the link associated with the click
- let link = event.target;
- while (link && !(link instanceof Ci.nsIDOMHTMLAnchorElement))
- link = link.parentNode;
-
- if (!link || !/^abp:\/*subscribe\/*\?(.*)/i.test(link.href)) /**/
- return;
-
- // This is our link - make sure the browser doesn't handle it
- event.preventDefault();
- event.stopPropagation();
-
- sendAsyncMessage("AdblockPlus:LinkClick", link.href);
-}, true);
diff --git a/chrome/content/objtabs.css b/chrome/content/objtabs.css
deleted file mode 100644
index 080a899..0000000
--- a/chrome/content/objtabs.css
+++ /dev/null
@@ -1,89 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.w3.org/1999/xhtml");
-
-.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%%, .%%CLASSHIDDEN%%
-{
- position: fixed !important;
- display: block !important;
-
- width: auto !important;
- height: auto !important;
- right: auto !important;
- bottom: auto !important;
- z-index: 65535 !important;
- float: left !important;
- border-color: black !important;
- border-style: solid !important;
- background: white !important;
- color: black !important;
- cursor: pointer !important;
- white-space: nowrap !important;
- font-family: Arial,Helvetica,Sans-Serif !important;
- font-size: 10px !important;
- font-style: normal !important;
- font-variant: normal !important;
- font-weight: normal !important;
- letter-spacing: normal !important;
- line-height: normal !important;
- text-align: center !important;
- text-decoration: none !important;
- text-indent: 0px !important;
- text-transform: none !important;
- direction: ltr !important;
- padding: 0px 5px !important;
- -moz-binding: none !important;
- -moz-user-focus: none !important;
- -moz-user-input: none !important;
- -moz-user-select: none !important;
-}
-
-.%%CLASSVISIBLETOP%%, .%%CLASSHIDDEN%%
-{
- border-width: 1px 1px 0px 1px !important;
- -moz-border-radius-topleft: 10px !important;
- -moz-border-radius-topright: 10px !important;
- -moz-border-radius-bottomleft: 0px !important;
- -moz-border-radius-bottomright: 0px !important;
-}
-
-.%%CLASSVISIBLEBOTTOM%%
-{
- border-width: 0px 1px 1px 1px !important;
- -moz-border-radius-topleft: 0px !important;
- -moz-border-radius-topright: 0px !important;
- -moz-border-radius-bottomleft: 10px !important;
- -moz-border-radius-bottomright: 10px !important;
-}
-
-.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%%
-{
- visibility: visible !important;
-}
-
-.%%CLASSHIDDEN%%
-{
- visibility: hidden !important;
-}
diff --git a/chrome/content/ui/about.js b/chrome/content/ui/about.js
deleted file mode 100644
index 70c62a5..0000000
--- a/chrome/content/ui/about.js
+++ /dev/null
@@ -1,180 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-try
-{
- Cu.import("resource://gre/modules/AddonManager.jsm");
-}
-catch (e) {}
-
-function init()
-{
- let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- if (typeof AddonManager != "undefined")
- {
- let addon = AddonManager.getAddonByID(Utils.addonID, function(addon)
- {
- loadInstallManifest(addon.getResourceURI("install.rdf"), addon.name, addon.homepageURL);
- });
- }
- else if ("@mozilla.org/extensions/manager;1" in Cc)
- {
- let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
- let rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
- let root = rdf.GetResource("urn:mozilla:item:" + Utils.addonID);
-
- function emResource(prop)
- {
- return rdf.GetResource("http://www.mozilla.org/2004/em-rdf#" + prop);
- }
-
- function getTarget(prop)
- {
- let target = extensionManager.datasource.GetTarget(root, emResource(prop), true);
- if (target)
- return target.QueryInterface(Ci.nsIRDFLiteral).Value;
- else
- return null;
- }
-
- let installLocation = extensionManager.getInstallLocation(Utils.addonID);
- let installManifestFile = installLocation.getItemFile(Utils.addonID, "install.rdf");
- loadInstallManifest(ioService.newFileURI(installManifestFile), getTarget("name"), getTarget("homepageURL"));
- }
- else
- {
- // No add-on manager, no extension manager - we must be running in K-Meleon.
- // Load Manifest.jsm as last solution.
- Cu.import(baseURL.spec + "Manifest.jsm");
- setExtensionData(manifest.name, manifest.version, manifest.homepage, [manifest.creator], manifest.contributors, manifest.translators);
- }
-}
-
-function loadInstallManifest(installManifestURI, name, homepage)
-{
- let rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
- let ds = rdf.GetDataSource(installManifestURI.spec);
- let root = rdf.GetResource("urn:mozilla:install-manifest");
-
- function emResource(prop)
- {
- return rdf.GetResource("http://www.mozilla.org/2004/em-rdf#" + prop);
- }
-
- function getTargets(prop)
- {
- let targets = ds.GetTargets(root, emResource(prop), true);
- let result = [];
- while (targets.hasMoreElements())
- result.push(targets.getNext().QueryInterface(Ci.nsIRDFLiteral).Value);
- return result;
- }
-
- function dataSourceLoaded()
- {
- setExtensionData(name, getTargets("version")[0],
- homepage, getTargets("creator"),
- getTargets("contributor"), getTargets("translator"));
- }
-
- if (ds instanceof Ci.nsIRDFRemoteDataSource && ds.loaded)
- dataSourceLoaded();
- else
- {
- let sink = ds.QueryInterface(Ci.nsIRDFXMLSink);
- sink.addXMLSinkObserver({
- onBeginLoad: function() {},
- onInterrupt: function() {},
- onResume: function() {},
- onEndLoad: function() {
- sink.removeXMLSinkObserver(this);
- dataSourceLoaded();
- },
- onError: function() {},
- });
- }
-}
-
-function cmpNoCase(a, b)
-{
- let aLC = a.toLowerCase();
- let bLC = b.toLowerCase();
- if (aLC < bLC)
- return -1;
- else if (aLC > bLC)
- return 1;
- else
- return 0;
-}
-
-function setExtensionData(name, version, homepage, authors, contributors, translators)
-{
- authors.sort(cmpNoCase);
- contributors.sort(cmpNoCase);
- translators.sort(cmpNoCase);
-
- E("title").value = name;
- E("version").value = version;
- E("homepage").value = homepage;
- E("authors").textContent = authors.join(", ");
- E("contributors").textContent = contributors.join(", ");
- E("translators").textContent = translators.join(", ");
-
- let request = new XMLHttpRequest();
- request.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml");
- request.onload = setSubscriptionAuthors;
- request.send(null);
-}
-
-function setSubscriptionAuthors()
-{
- let doc = this.responseXML;
- if (!doc || doc.documentElement.localName != "subscriptions")
- return;
-
- let authors = {__proto__: null};
- for (let node = doc.documentElement.firstChild; node; node = node.nextSibling)
- {
- if (node.localName != "subscription" || !node.hasAttribute("author"))
- continue;
-
- for each (let author in node.getAttribute("author").split(","))
- {
- author = author.replace(/^\s+/, "").replace(/\s+$/, "");
- if (author == "")
- continue;
-
- authors[author] = true;
- }
- }
-
- let list = [];
- for (let author in authors)
- list.push(author);
-
- list.sort(cmpNoCase)
- E("subscriptionAuthors").textContent = list.join(", ");
-
- E("mainBox").setAttribute("loaded", "true");
-}
diff --git a/chrome/content/ui/about.xul b/chrome/content/ui/about.xul
deleted file mode 100644
index 2b1e600..0000000
--- a/chrome/content/ui/about.xul
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/about.css" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/about.dtd">
-
-<dialog
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&dialog.title;"
- id="adblockAboutWindow"
- windowtype="abp:about"
- onload="init()"
- buttons="accept">
-
-<script type="application/x-javascript;version=1.7" src="utils.js"/>
-<script type="application/x-javascript;version=1.7" src="about.js"/>
-
-<vbox id="mainBox">
- <description id="title" value=" "/>
- <hbox align="baseline">
- <label control="version" value="&version.title;"/>
- <textbox id="version" flex="1" class="plain" readonly="true" tabindex="-1"/>
- </hbox>
-
- <groupbox id="mainGroup" flex="1">
- <description id="description">
- &description;
- </description>
-
- <description id="homepageTitle" value="&homepage.label;"/>
- <description id="homepage" class="text-link" onclick="Utils.loadInBrowser(this.getAttribute('value'))"/>
-
- <vbox id="authorsBox" align="top">
- <label id="authorsTitle" control="authors" value="&author.label;"/>
- <description id="authors"/>
- </vbox>
-
- <vbox id="contributorsBox" align="top">
- <label id="contributorsTitle" control="contributors" value="&contributors.label;"/>
- <description id="contributors"/>
- </vbox>
-
- <vbox id="subscriptionAuthorsBox" align="top">
- <label id="subscriptionAuthorsTitle" control="subscriptionAuthors" value="&subscriptionAuthors.label;"/>
- <description id="subscriptionAuthors"/>
- </vbox>
-
- <vbox id="translatorsBox">
- <label id="translatorsTitle" control="translators" value="&translators.label;"/>
- <description id="translators"/>
- </vbox>
- </groupbox>
-</vbox>
-
-</dialog>
diff --git a/chrome/content/ui/composer.js b/chrome/content/ui/composer.js
deleted file mode 100644
index 51efa8a..0000000
--- a/chrome/content/ui/composer.js
+++ /dev/null
@@ -1,430 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-let nodes = null;
-let item = null;
-let advancedMode = false;
-
-function init()
-{
- [nodes, item] = window.arguments;
-
- E("filterType").value = (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter ? "filterlist" : "whitelist");
- E("customPattern").value = item.location;
-
- let insertionPoint = E("customPatternBox");
- let addSuggestion = function(address)
- {
- // Always drop protocol and www. from the suggestion
- address = address.replace(/^[\w\-]+:\/+(?:www\.)?/, "");
-
- let suggestion = document.createElement("radio");
- suggestion.setAttribute("value", address);
- suggestion.setAttribute("label", address);
- suggestion.setAttribute("crop", "center");
- suggestion.setAttribute("class", "suggestion");
- insertionPoint.parentNode.insertBefore(suggestion, insertionPoint);
-
- return address;
- }
-
- let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- try
- {
- let suggestions = [""];
-
- let url = ioService.newURI(item.location, null, null)
- .QueryInterface(Ci.nsIURL);
- let suffix = (url.query ? "?*" : "");
- url.query = "";
- suggestions[1] = addSuggestion(url.spec + suffix);
-
- let parentURL = ioService.newURI(url.fileName == "" ? ".." : ".", null, url);
- if (!parentURL.equals(url))
- suggestions[2] = addSuggestion(parentURL.spec + "*");
- else
- suggestions[2] = suggestions[1];
-
- let rootURL = ioService.newURI("/", null, url);
- if (!rootURL.equals(parentURL) && !rootURL.equals(url))
- suggestions[3] = addSuggestion(rootURL.spec + "*");
- else
- suggestions[3] = suggestions[2];
-
- try
- {
- suggestions[4] = addSuggestion(url.host.replace(/^www\./, "") + "^");
-
- // Prefer example.com^ to example.com/*
- let undesired = suggestions[4].replace(/\^$/, "/*");
- for (let i = 0; i < suggestions.length - 1; i++)
- if (suggestions[i] == undesired)
- suggestions[i] = suggestions[4];
-
- for (let child = insertionPoint.parentNode.firstChild; child; child = child.nextSibling)
- {
- if (child.localName == "radio" && child.getAttribute("value") == undesired)
- {
- child.parentNode.removeChild(child);
- break;
- }
- }
- }
- catch (e)
- {
- suggestions[4] = suggestions[3];
- }
-
- try
- {
- let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
- let host = url.host;
- let baseDomain = effectiveTLD.getBaseDomainFromHost(host);
- if (baseDomain != host.replace(/^www\./, ""))
- suggestions[5] = addSuggestion(baseDomain + "^");
- else
- suggestions[5] = suggestions[4];
- }
- catch (e)
- {
- suggestions[5] = suggestions[4];
- }
-
- E("patternGroup").value = (Prefs.composer_default in suggestions ? suggestions[Prefs.composer_default] : suggestions[1]);
- }
- catch (e)
- {
- // IOService returned nsIURI - not much we can do with it
- addSuggestion(item.location);
- E("patternGroup").value = "";
- }
- if (Prefs.composer_default == 0)
- E("customPattern").focus();
- else
- E("patternGroup").focus();
-
- let types = [];
- for (let type in Policy.localizedDescr)
- {
- types.push(parseInt(type));
- }
- types.sort(function(a, b) {
- if (a < b)
- return -1;
- else if (a > b)
- return 1;
- else
- return 0;
- });
-
- let docDomain = item.docDomain;
- let thirdParty = item.thirdParty;
-
- if (docDomain)
- docDomain = docDomain.replace(/^www\./i, "").replace(/\.+$/, "");
- if (docDomain)
- E("domainRestriction").value = docDomain;
-
- E("thirdParty").hidden = !thirdParty;
- E("firstParty").hidden = thirdParty;
-
- let typeGroup = E("typeGroup");
- for each (let type in types)
- {
- if (type == Policy.type.ELEMHIDE)
- continue;
-
- let typeNode = document.createElement("checkbox");
- typeNode.setAttribute("value", Policy.typeDescr[type].toLowerCase().replace(/\_/g, "-"));
- typeNode.setAttribute("label", Policy.localizedDescr[type].toLowerCase());
- typeNode.setAttribute("checked", "true");
- if (item.type == type)
- typeNode.setAttribute("disabled", "true");
- typeNode.addEventListener("command", updateFilter, false);
- typeGroup.appendChild(typeNode);
- }
-
- let collapseDefault = E("collapseDefault");
- collapseDefault.label = collapseDefault.getAttribute(Prefs.fastcollapse ? "label_no" : "label_yes");
- E("collapse").value = "";
- E("collapse").setAttribute("label", collapseDefault.label);
-
- let warning = E("disabledWarning");
- generateLinkText(warning);
- warning.hidden = Prefs.enabled;
-
- updatePatternSelection();
-}
-
-function updateFilter()
-{
- let filter = "";
-
- let type = E("filterType").value
- if (type == "whitelist")
- filter += "@@";
-
- let pattern = E("patternGroup").value;
- if (pattern == "")
- pattern = E("customPattern").value;
-
- if (E("anchorStart").checked)
- filter += E("anchorStart").flexibleAnchor ? "||" : "|";
-
- filter += pattern;
-
- if (E("anchorEnd").checked)
- filter += "|";
-
- if (advancedMode)
- {
- let options = [];
-
- if (E("domainRestrictionEnabled").checked)
- {
- let domainRestriction = E("domainRestriction").value.replace(/[,\s]/g, "").replace(/\.+$/, "");
- if (domainRestriction)
- options.push("domain=" + domainRestriction);
- }
-
- if (E("firstParty").checked)
- options.push("~third-party");
- if (E("thirdParty").checked)
- options.push("third-party");
-
- if (E("matchCase").checked)
- options.push("match-case");
-
- let collapse = E("collapse");
- disableElement(collapse, type == "whitelist", "value", "");
- if (collapse.value != "")
- options.push(collapse.value);
-
- let enabledTypes = [];
- let disabledTypes = [];
- for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
- {
- let value = typeNode.getAttribute("value");
- if (value == "document")
- disableElement(typeNode, type != "whitelist", "checked", false);
-
- if (value != "document" || !typeNode.disabled)
- {
- if (typeNode.checked)
- enabledTypes.push(value);
- else
- disabledTypes.push("~" + value);
- }
- }
- if (disabledTypes.length < enabledTypes.length)
- options.push.apply(options, disabledTypes);
- else
- options.push.apply(options, enabledTypes);
-
- if (options.length)
- filter += "$" + options.join(",");
- }
-
- filter = Filter.normalize(filter);
- E("regexpWarning").hidden = !Filter.regexpRegExp.test(filter);
-
- let isSlow = false;
- let compiledFilter = Filter.fromText(filter);
- if (E("regexpWarning").hidden)
- {
- if (compiledFilter instanceof RegExpFilter && defaultMatcher.isSlowFilter(compiledFilter))
- isSlow = true;
- }
- E("shortpatternWarning").hidden = !isSlow;
-
- E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);
-
- E("filter").value = filter;
-
- if (E("disabledWarning").hidden)
- {
- let subscription = null;
- for each (let s in FilterStorage.subscriptions)
- if (s instanceof SpecialSubscription && s.isFilterAllowed(compiledFilter) && (!subscription || s.priority > subscription.priority))
- subscription = s;
-
- let warning = E("groupDisabledWarning");
- if (subscription && subscription.disabled)
- {
- warning.subscription = subscription;
- generateLinkText(warning, subscription.title);
- warning.hidden = false;
- }
- else
- warning.hidden = true;
- }
- else
- E("groupDisabledWarning").hidden = true;
-}
-
-function generateLinkText(element, replacement)
-{
- let template = element.getAttribute("textTemplate");
- if (typeof replacement != "undefined")
- template = template.replace(/\?1\?/g, replacement)
-
- let beforeLink, linkText, afterLink;
- if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
- [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
- else
- [beforeLink, linkText, afterLink] = ["", template, ""];
-
- while (element.firstChild && element.firstChild.nodeType != Node.ELEMENT_NODE)
- element.removeChild(element.firstChild);
- while (element.lastChild && element.lastChild.nodeType != Node.ELEMENT_NODE)
- element.removeChild(element.lastChild);
- if (!element.firstChild)
- return;
-
- element.firstChild.textContent = linkText;
- element.insertBefore(document.createTextNode(beforeLink), element.firstChild);
- element.appendChild(document.createTextNode(afterLink));
-}
-
-function updatePatternSelection()
-{
- let pattern = E("patternGroup").value;
- if (pattern == "")
- {
- pattern = E("customPattern").value;
- }
- else
- {
- E("anchorStart").checked = true;
- E("anchorEnd").checked = false;
- }
-
- function testFilter(/**String*/ filter) /**Boolean*/
- {
- return RegExpFilter.fromText(filter).matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);
- }
-
- let anchorStartCheckbox = E("anchorStart");
- if (!/^\*/.test(pattern) && testFilter("||" + pattern))
- {
- disableElement(anchorStartCheckbox, false, "checked", false);
- anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelFlexible"));
- anchorStartCheckbox.accessKey = anchorStartCheckbox.getAttribute("accesskeyFlexible");
- anchorStartCheckbox.flexibleAnchor = true;
- }
- else
- {
- disableElement(anchorStartCheckbox, /^\*/.test(pattern) || !testFilter("|" + pattern), "checked", false);
- anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelRegular"));
- anchorStartCheckbox.accessKey = anchorStartCheckbox.getAttribute("accesskeyRegular");
- anchorStartCheckbox.flexibleAnchor = false;
- }
- disableElement(E("anchorEnd"), /[\*\^]$/.test(pattern) || !testFilter(pattern + "|"), "checked", false);
-
- updateFilter();
- setAdvancedMode(document.documentElement.getAttribute("advancedMode") == "true");
-}
-
-function updateCustomPattern()
-{
- E("patternGroup").value = "";
- updatePatternSelection();
-}
-
-function addFilter() {
- let filter = Filter.fromText(document.getElementById("filter").value);
-
- if (filter.disabled)
- {
- filter.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter]);
- }
-
- FilterStorage.addFilter(filter);
- FilterStorage.saveToDisk();
-
- if (nodes)
- Policy.refilterNodes(nodes, item);
-
- return true;
-}
-
-function setAdvancedMode(mode) {
- advancedMode = mode;
-
- var dialog = document.documentElement;
- dialog.setAttribute("advancedMode", advancedMode);
-
- var button = dialog.getButton("disclosure");
- button.setAttribute("label", dialog.getAttribute(advancedMode ? "buttonlabeldisclosure_off" : "buttonlabeldisclosure_on"));
-
- updateFilter();
-}
-
-function disableElement(element, disable, valueProperty, disabledValue) {
- if (element.disabled == disable)
- return;
-
- element.disabled = disable;
- if (disable)
- {
- element._abpStoredValue = element[valueProperty];
- element[valueProperty] = disabledValue;
- }
- else
- {
- if ("_abpStoredValue" in element)
- element[valueProperty] = element._abpStoredValue;
- delete element._abpStoredValue;
- }
-}
-
-function openPreferences() {
- Utils.openSettingsDialog(item.location, E("filter").value);
-}
-
-function doEnable() {
- Prefs.enabled = true;
- E("disabledWarning").hidden = true;
-}
-
-function enableSubscription(subscription)
-{
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- FilterStorage.saveToDisk();
- E("groupDisabledWarning").hidden = true;
-}
-
-/**
- * Selects or unselects all type checkboxes except those
- * that are disabled.
- */
-function selectAllTypes(/**Boolean*/ select)
-{
- for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
- if (typeNode.getAttribute("disabled") != "true")
- typeNode.checked = select;
- updateFilter();
-}
diff --git a/chrome/content/ui/composer.xul b/chrome/content/ui/composer.xul
deleted file mode 100644
index a8fd1cd..0000000
--- a/chrome/content/ui/composer.xul
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<!DOCTYPE overlay SYSTEM "chrome://adblockplus/locale/composer.dtd">
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/composer.css" type="text/css"?>
-
-<dialog id="abp-composer"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&dialog.title;"
- onload="init()"
- ondialogaccept="return addFilter()"
- ondialogdisclosure="setAdvancedMode(!advancedMode)"
- buttons="accept,cancel,disclosure"
- width="800px"
- height="400px"
- persist="screenX screenY width height sizemode advancedMode"
- advancedMode="false"
- buttonlabelaccept="&accept.label;"
- buttonlabeldisclosure="&advanced.label;"
- buttonlabeldisclosure_on="&advanced.label;"
- buttonlabeldisclosure_off="&basic.label;"
- windowtype="abp:composer">
-
- <script type="application/x-javascript;version=1.7" src="utils.js"/>
- <script type="application/x-javascript;version=1.7" src="composer.js"/>
-
- <popupset>
- <tooltip id="domainRestrictionHelp" label="&domainRestriction.help;"/>
- </popupset>
-
- <description id="disabledWarning" hidden="true" textTemplate="&disabled.warning;">
- <label class="text-link" onclick="doEnable()"/>
- </description>
-
- <description id="groupDisabledWarning" textTemplate="&groupDisabled.warning;" hidden="true">
- <label class="text-link" onclick="enableSubscription(this.parentNode.subscription)"/>
- </description>
-
- <hbox id="filterBox" align="center">
- <label control="filter" value="&filter.label;" accesskey="&filter.accesskey;"/>
- <textbox id="filter" flex="1" tabindex="-1" readonly="true"/>
- <button id="preferences" label="&preferences.label;" accesskey="&preferences.accesskey;" oncommand="openPreferences()"/>
- </hbox>
-
- <radiogroup orient="horizontal" id="filterType" oncommand="updateFilter()">
- <radio label="&type.filter.label;" accesskey="&type.filter.accesskey;" value="filterlist" flex="1"/>
- <radio label="&type.whitelist.label;" accesskey="&type.whitelist.accesskey;" value="whitelist" flex="1"/>
- </radiogroup>
-
- <hbox flex="1">
- <groupbox id="pattern" flex="1">
- <caption label="&pattern.label;"/>
- <radiogroup id="patternGroup" flex="1" oncommand="updatePatternSelection()" style="overflow: auto;">
- <description id="patternExplanation">&pattern.explanation;</description>
- <description id="regexpWarning" hidden="true">®exp.warning;</description>
- <description id="shortpatternWarning" hidden="true">&shortpattern.warning;</description>
- <description id="matchWarning" hidden="true">&match.warning;</description>
- <hbox id="customPatternBox">
- <radio id="customPatternRadio" label="&custom.pattern.label;" accesskey="&custom.pattern.accesskey;" value="" control="customPattern"/>
- <textbox id="customPattern" flex="1" oninput="updateCustomPattern()"/>
- </hbox>
- </radiogroup>
- <hbox id="anchorGroup" pack="start" align="baseline">
- <label value="&anchors.label;"/>
- <description flex="1" style="margin: 0; padding: 0;">
- <checkbox id="anchorStart" labelRegular="&anchor.start.label;" accesskeyRegular="&anchor.start.accesskey;"
- labelFlexible="&anchor.start.flexible.label;" accesskeyFlexible="&anchor.start.flexible.accesskey;"
- oncommand="updateFilter()"/>
- <checkbox id="anchorEnd" label="&anchor.end.label;" accesskey="&anchor.end.accesskey;" oncommand="updateFilter()"/>
- </description>
- </hbox>
- </groupbox>
- <groupbox id="options">
- <caption label="&options.label;"/>
- <checkbox id="firstParty" label="&firstParty.label;" accesskey="&firstParty.accesskey;" oncommand="updateFilter()"/>
- <checkbox id="thirdParty" label="&thirdParty.label;" accesskey="&thirdParty.accesskey;" oncommand="updateFilter()"/>
- <checkbox id="matchCase" label="&matchCase.label;" accesskey="&matchCase.accesskey;" oncommand="updateFilter()"/>
- <hbox align="baseline">
- <checkbox id="domainRestrictionEnabled" label="&domainRestriction.label;" accesskey="&domainRestriction.accesskey;" oncommand="updateFilter()"/>
- <description class="help" value="?" tooltip="domainRestrictionHelp"/>
- </hbox>
- <textbox id="domainRestriction" oninput="updateFilter()"/>
-
- <label id="typeGroupLabel" value="&types.label;"/>
- <hbox>
- <label id="selectAllTypes" class="text-link" value="&selectAllTypes.label;" onclick="selectAllTypes(true)"/>
- <spacer flex="1"/>
- <label id="unselectAllTypes" class="text-link" value="&unselectAllTypes.label;" onclick="selectAllTypes(false)"/>
- </hbox>
- <vbox flex="1" id="typeGroup"/>
-
- <vbox>
- <label control="collapse" value="&collapse.label;" accesskey="&collapse.accesskey;"/>
- <menulist id="collapse" oncommand="updateFilter()">
- <menupopup>
- <menuitem id="collapseDefault" value="" label_yes="&collapse.default.yes.label;" label_no="&collapse.default.no.label;" selected="true"/>
- <menuitem label="&collapse.yes.label;" value="collapse"/>
- <menuitem label="&collapse.no.label;" value="~collapse"/>
- </menupopup>
- </menulist>
- </vbox>
- </groupbox>
- </hbox>
-</dialog>
diff --git a/chrome/content/ui/fennecOverlay.xul b/chrome/content/ui/fennecOverlay.xul
deleted file mode 100644
index ae6ed89..0000000
--- a/chrome/content/ui/fennecOverlay.xul
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Fabrice Desré.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- - Wladimir Palant
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="main-window">
- <box id="abp-hooks"
- getBrowser="return this.window.getBrowser();"
- addTab="Utils.runAsync(this.window.BrowserUI.newTab, this.window.BrowserUI, arguments[0]);"
- getContextMenu="return null"
- getToolbox="return null"
- getDefaultToolbar="return null"/>
- </window>
-
- <!-- Page actions container -->
- <hbox id="pageactions-container">
- <pageaction id="abp-site-info"/>
- </hbox>
-</overlay>
diff --git a/chrome/content/ui/fennecSettings.xul b/chrome/content/ui/fennecSettings.xul
deleted file mode 100644
index d5ccb73..0000000
--- a/chrome/content/ui/fennecSettings.xul
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Fabrice Desré.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- - Wladimir Palant
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<!DOCTYPE vbox SYSTEM "chrome://adblockplus/locale/settings.dtd">
-<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <setting pref="extensions.adblockplus.enabled" type="bool" title="&enable.label;"/>
- <setting type="control" title="&fennec.subscription.label;">
- <menulist id="adblockplus-subscription-list"/>
- </setting>
- <setting pref="extensions.adblockplus.fastcollapse" type="bool" title="&collapse.label;"
- inverted="true"/>
- <setting id="adblockplus-sync" type="bool" title="&sync.label;"/>
-</vbox>
diff --git a/chrome/content/ui/fennecSubscription.xul b/chrome/content/ui/fennecSubscription.xul
deleted file mode 100644
index 71ae218..0000000
--- a/chrome/content/ui/fennecSubscription.xul
+++ /dev/null
@@ -1,78 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- - Fabrice Desré
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<!DOCTYPE dialog [
-<!ENTITY % subst SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
-<!ENTITY % prompts SYSTEM "chrome://browser/locale/prompt.dtd">
-%subst;
-%prompts;
-]>
-
-<dialog
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="abpEditSubscription">
-
-<keyset>
- <key keycode="VK_RETURN" command="abp-subscription-cmd-ok"/>
- <key keycode="VK_ESCAPE" command="abp-subscription-cmd-cancel"/>
-</keyset>
-<commandset>
- <command id="abp-subscription-cmd-ok"/>
- <command id="abp-subscription-cmd-cancel" oncommand="document.getElementById('abpEditSubscription').close();"/>
-</commandset>
-
-<vbox class="prompt-header">
- <label value="&dialog.title;"/>
-
- <grid class="prompt-message">
- <columns>
- <column/>
- <column flex="1"/>
- </columns>
- <rows>
- <row align="center">
- <label value="&title.label;" control="abp-subscription-title"/>
- <description id="abp-subscription-title"/>
- </row>
- <row>
- <label value="&location.label;" control="abp-subscription-url"/>
- <scrollbox orient="vertical">
- <description id="abp-subscription-url"/>
- </scrollbox>
- </row>
- </rows>
- </grid>
-</vbox>
-
-<hbox class="prompt-buttons">
- <button id="abp-subscription-btn-ok" class="prompt-button" label="&ok.label;" command="abp-subscription-cmd-ok"/>
- <button class="prompt-button" label="&cancel.label;" command="abp-subscription-cmd-cancel"/>
-</hbox>
-
-</dialog>
diff --git a/chrome/content/ui/findbar.js b/chrome/content/ui/findbar.js
deleted file mode 100644
index 108817f..0000000
--- a/chrome/content/ui/findbar.js
+++ /dev/null
@@ -1,79 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * Fake browser implementation to make findbar widget happy - searches in
- * the filter list.
- */
-let fastFindBrowser =
-{
- fastFind: {
- searchString: null,
- foundLink: null,
- foundEditable: null,
- caseSensitive: false,
- get currentWindow() { return fastFindBrowser.contentWindow; },
-
- find: function(searchString, linksOnly)
- {
- this.searchString = searchString;
- return treeView.find(this.searchString, 0, false, this.caseSensitive);
- },
-
- findAgain: function(findBackwards, linksOnly)
- {
- return treeView.find(this.searchString, findBackwards ? -1 : 1, false, this.caseSensitive);
- },
-
- // Irrelevant for us
- init: function() {},
- setDocShell: function() {},
- setSelectionModeAndRepaint: function() {},
- collapseSelection: function() {}
- },
- currentURI: Utils.makeURI("http://example.com/"),
- contentWindow: {
- focus: function()
- {
- E("list").focus();
- },
- scrollByLines: function(num)
- {
- E("list").boxObject.scrollByLines(num);
- },
- scrollByPages: function(num)
- {
- E("list").boxObject.scrollByPages(num);
- },
- },
-
- addEventListener: function(event, handler, capture)
- {
- E("list").addEventListener(event, handler, capture);
- },
- removeEventListener: function(event, handler, capture)
- {
- E("list").addEventListener(event, handler, capture);
- },
-}
diff --git a/chrome/content/ui/firefoxOverlay.xul b/chrome/content/ui/firefoxOverlay.xul
deleted file mode 100644
index fd453c0..0000000
--- a/chrome/content/ui/firefoxOverlay.xul
+++ /dev/null
@@ -1,98 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="main-window">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks"
- getBrowser="return this.window.gBrowser;"
- addTab="
- if (arguments[1] && 'openNewTabWith' in this.window)
- this.window.openNewTabWith(arguments[0], this.window.content.document, null, arguments[1], false);
- else
- this.window.gBrowser.loadOneTab(arguments[0], null, null, null, false);"
- getContextMenu="return this.E('contentAreaContextMenu');"
- getToolbox="return this.E('navigator-toolbox')"
- getDefaultToolbar="return this.E('addon-bar') || this.E('nav-bar');"
- toolbarInsertBefore="return this.E('addonbar-closebutton');"
- unhideToolbar="return this.E('addon-bar')"/>
- </window>
-
- <!-- Songbird window -->
- <sb-support id="mainSupportSet">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks"
- getBrowser="return this.window.gBrowser;"
- addTab="this.window.gBrowser.loadOneTab(arguments[0], null, null, null, false);"
- getContextMenu="return this.E('contentAreaContextMenu');"
- getToolbox="return this.E('navigator-toolbox')"
- getDefaultToolbar="return this.E('nav-bar');"/>
- </sb-support>
-
- <!-- Status bar -->
- <statusbar id="status-bar">
- <statusbarpanel id="abp-status" mousethrough="never" insertbefore="resizerBottomRight"/>
- </statusbar>
-
- <!-- Toolbar -->
- <toolbarpalette id="BrowserToolbarPalette">
- <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertbefore="print-button"
- class="toolbarbutton-1"/>
- </toolbarpalette>
-
- <!-- Tools menu -->
- <menupopup id="menu_ToolsPopup">
- <menuitem id="abp-menuitem" insertafter="javascriptConsole"/>
- </menupopup>
-
- <!-- View menu -->
- <menupopup id="menu_viewPopup">
- <menuitem id="abp-blockableitems" insertafter="viewSidebarMenuMenu"/>
- </menupopup>
-
- <!-- Context menu -->
- <menupopup id="contentAreaContextMenu">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
-
- <!-- Fake sidebar -->
- <statuspanel id="statusbar-display" fixed="true"/> <!-- Make sure not to resize this element -->
- <vbox id="appcontent">
- <splitter id="abp-sidebar-splitter"/>
- <vbox id="abp-sidebar"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/flasher.js b/chrome/content/ui/flasher.js
deleted file mode 100644
index e8a51b7..0000000
--- a/chrome/content/ui/flasher.js
+++ /dev/null
@@ -1,122 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * Draws a blinking border for a list of matching nodes.
- */
-
-var flasher = {
- nodes: null,
- count: 0,
- timer: null,
-
- flash: function(nodes)
- {
- this.stop();
- if (nodes)
- nodes = nodes.filter(function(node) node.nodeType == Node.ELEMENT_NODE);
- if (!nodes || !nodes.length)
- return;
-
- if (Prefs.flash_scrolltoitem && nodes[0].ownerDocument)
- {
- // Ensure that at least one node is visible when flashing
- let wnd = nodes[0].ownerDocument.defaultView;
- try
- {
- let hooks = wnd.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow)
- .document.getElementById("abp-hooks");
- if (hooks.wrappedJSObject)
- hooks = hooks.wrappedJSObject;
-
- let viewer = hooks.getBrowser().markupDocumentViewer;
- viewer.scrollToNode(nodes[0]);
- }
- catch(e)
- {
- Cu.reportError(e);
- }
- }
-
- this.nodes = nodes;
- this.count = 0;
-
- this.doFlash();
- },
-
- doFlash: function() {
- if (this.count >= 12) {
- this.stop();
- return;
- }
-
- if (this.count % 2)
- this.switchOff();
- else
- this.switchOn();
-
- this.count++;
-
- this.timer = window.setTimeout(function() {flasher.doFlash()}, 300);
- },
-
- stop: function() {
- if (this.timer) {
- window.clearTimeout(this.timer);
- this.timer = null;
- }
-
- if (this.nodes) {
- this.switchOff();
- this.nodes = null;
- }
- },
-
- setOutline: function(outline, offset)
- {
- for (var i = 0; i < this.nodes.length; i++)
- {
- if ("style" in this.nodes[i])
- {
- this.nodes[i].style.outline = outline;
- this.nodes[i].style.outlineOffset = offset;
- }
- }
- },
-
- switchOn: function()
- {
- this.setOutline("#CC0000 dotted 2px", "-2px");
- },
-
- switchOff: function()
- {
- this.setOutline("", "");
- }
-};
diff --git a/chrome/content/ui/mailOverlay.xul b/chrome/content/ui/mailOverlay.xul
deleted file mode 100644
index 016fc4e..0000000
--- a/chrome/content/ui/mailOverlay.xul
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="messengerWindow">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks" getBrowser="return this.window.getMessageBrowser();"
- addTab="this.window.openNewTabWith(arguments[0], (arguments[1] ? this.window.content.document : null), (arguments[1] ? arguments[1].shiftKey : false));"
- getContextMenu="return this.E('messagePaneContext');"
- getToolbox="return this.E('mail-toolbox')"
- getDefaultToolbar="return this.E('msgToolbar');" toolbarInsertBefore="return this.E('button-junk');"/>
- </window>
-
- <!-- Status bar -->
- <statusbar id="status-bar">
- <statusbarpanel id="abp-status"/>
- </statusbar>
-
- <!-- Toolbar -->
- <toolbarpalette id="MailToolbarPalette">
- <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertafter="button-junk"
- class="toolbarbutton-1"/>
- </toolbarpalette>
-
- <!-- Tools menu -->
- <menupopup id="taskPopup">
- <menuitem id="abp-menuitem" insertafter="downloadmgr,javaScriptConsole"/>
- </menupopup>
-
- <!-- Context menu -->
- <menupopup id="messagePaneContext">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
-
- <!-- Fake sidebar -->
- <vbox id="messagepanebox">
- <splitter id="abp-sidebar-splitter"/>
- <vbox id="abp-sidebar"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/overlay.js b/chrome/content/ui/overlay.js
deleted file mode 100644
index e51b67c..0000000
--- a/chrome/content/ui/overlay.js
+++ /dev/null
@@ -1,51 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-{
- let Cc = Components.classes;
- let Ci = Components.interfaces;
- let Cr = Components.results;
- let Cu = Components.utils;
-
- // Use UIReady event to initialize in Fennec (bug 531071)
- let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
- let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- let utilsURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Utils.jsm", null, null));
- let eventName = Cu.import(utilsURL.spec, null).Utils.isFennec ? "UIReady" : "load";
-
- window.addEventListener(eventName, function()
- {
- window.removeEventListener(eventName, arguments.callee, false);
-
- if (!("@adblockplus.org/abp/private;1" in Cc))
- {
- // Force initialization (in Fennec we won't be initialized at this point)
- let bootstrapURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Bootstrap.jsm", null, null));
- Cu.import(bootstrapURL.spec, null).Bootstrap.startup();
- }
-
- let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
- Cu.import(baseURL.spec + "AppIntegration.jsm", null).AppIntegration.addWindow(window);
- }, false);
-}
diff --git a/chrome/content/ui/overlayGeneral.xul b/chrome/content/ui/overlayGeneral.xul
deleted file mode 100644
index d64d4fd..0000000
--- a/chrome/content/ui/overlayGeneral.xul
+++ /dev/null
@@ -1,130 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://adblockplus/skin/overlay.css" type="text/css"?>
-
-<!DOCTYPE overlay [
-<!ENTITY % overlayDTD SYSTEM "chrome://adblockplus/locale/overlay.dtd">
-%overlayDTD;
-<!ENTITY % settingsDTD SYSTEM "chrome://adblockplus/locale/settings.dtd">
-%settingsDTD;
-]>
-
-<overlay id="abp-overlay-general" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script type="application/x-javascript;version=1.7" src="overlay.js"/>
-
- <popupset id="abp-popupset">
- <!-- Icon's tooltip -->
- <tooltip id="abp-tooltip" orient="vertical">
- <description id="abp-tooltip-action" hidden="true"/>
- <label id="abp-tooltip-status-label" value="&status.tooltip;"/>
- <description id="abp-tooltip-status"/>
- <label id="abp-tooltip-blocked-label" value="&blocked.tooltip;" hidden="true"/>
- <description id="abp-tooltip-blocked" hidden="true"/>
- <label id="abp-tooltip-filters-label" value="&filters.tooltip;" hidden="true"/>
- <vbox id="abp-tooltip-filters" hidden="true"/>
- <description id="abp-tooltip-more-filters" value="â¦" hidden="true"/>
- </tooltip>
-
- <!-- Icon's context menu -->
- <menupopup id="abp-status-popup">
- <menuitem id="abp-status-sendReport" label="&sendReport.label;â¦" accesskey="&sendReport.accesskey;" key="abp-key-sendReport" command="abp-command-sendReport"/>
- <menuitem id="abp-status-opensidebar" label="&opensidebar.label;" accesskey="&opensidebar.accesskey;" key="abp-key-sidebar" command="abp-command-sidebar"/>
- <menuitem id="abp-status-closesidebar" label="&closesidebar.label;" accesskey="&closesidebar.accesskey;" key="abp-key-sidebar" command="abp-command-sidebar"/>
- <menuitem id="abp-status-settings" label="&settings.label;â¦" accesskey="&settings.accesskey;" key="abp-key-settings" command="abp-command-settings"/>
- <menuseparator id="abp-status-whitelist-sep"/>
- <menuitem id="abp-status-whitelistsite" labeltempl="&whitelist.site.label;" type="checkbox" command="abp-command-togglesitewhitelist"/>
- <menuitem id="abp-status-whitelistpage" label="&whitelist.page.label;" type="checkbox" command="abp-command-togglepagewhitelist"/>
- <menuitem id="abp-status-disabled" label="&disable.label;" type="checkbox" key="abp-key-enable" command="abp-command-enable"/>
- <menuseparator/>
- <menu id="abp-status-options" label="&options.label;" accesskey="&options.accesskey;">
- <menupopup id="abp-status-options-popup">
- <menuitem id="abp-status-frameobjects" label="&objecttabs.label;" accesskey="&objecttabs.accesskey;" type="checkbox" command="abp-command-toggleobjtabs"/>
- <menuitem id="abp-status-slowcollapse" label="&collapse.label;" accesskey="&collapse.accesskey;" type="checkbox" command="abp-command-togglecollapse"/>
- <menuitem id="abp-status-sync" label="&sync.label;" accesskey="&sync.accesskey;" type="checkbox" command="abp-command-togglesync"/>
- <menuseparator/>
- <menuitem id="abp-status-showintoolbar" label="&showintoolbar.label;" accesskey="&showintoolbar.accesskey;" type="checkbox" command="abp-command-toggleshowintoolbar"/>
- <menuitem id="abp-status-showinstatusbar" label="&showinstatusbar.label;" accesskey="&showinstatusbar.accesskey;" type="checkbox" command="abp-command-toggleshowinstatusbar"/>
- </menupopup>
- </menu>
-
- <hbox class="abp-recommendbutton" id="abp-status-recommendbutton" pack="center">
- <button class="abp-recommendbutton-btn" label="&recommend.label;" command="abp-command-recommend" flex="1"/>
- <toolbarbutton class="abp-recommendbutton-close" command="abp-command-recommend-hide"/>
- </hbox>
- </menupopup>
- </popupset>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset">
- <!-- Dummy oncommand attributes are work-arounds for bug 371900 -->
- <command id="abp-command-sendReport" oncommand="//"/>
- <command id="abp-command-settings" oncommand="//"/>
- <command id="abp-command-sidebar" oncommand="//"/>
- <command id="abp-command-togglesitewhitelist"/>
- <command id="abp-command-togglepagewhitelist"/>
- <command id="abp-command-toggleobjtabs"/>
- <command id="abp-command-togglecollapse"/>
- <command id="abp-command-togglesync"/>
- <command id="abp-command-toggleshowintoolbar"/>
- <command id="abp-command-toggleshowinstatusbar"/>
- <command id="abp-command-enable" oncommand="//"/>
- <command id="abp-command-recommend"/>
- <command id="abp-command-recommend-hide"/>
- </commandset>
-
- <statusbarpanel id="abp-status" class="statusbarpanel-iconic"
- context="abp-status-popup" tooltip="abp-tooltip"/>
-
- <toolbarbutton id="abp-toolbarbutton" label="&toolbarbutton.label;"
- tooltip="abp-tooltip" context="abp-status-popup"/>
-
- <box id="abp-hooks" objtabtext="&objecttab.title;â¦" objtabtooltip="&objecttab.tooltip;"/>
-
- <!-- Tools menu -->
- <menuitem id="abp-menuitem" label="&menuitem.label;â¦" accesskey="&menuitem.accesskey;" key="abp-key-settings" command="abp-command-settings"/>
-
- <!-- View menu -->
- <menuitem id="abp-blockableitems" label="&view.blockableItems.label;" type="checkbox" autocheck="false" key="abp-key-sidebar" command="abp-command-sidebar"/>
-
- <!-- Context menu -->
- <menuitem id="abp-image-menuitem" label="&context.image.label;â¦" hidden="true"/>
- <menuitem id="abp-object-menuitem" label="&context.object.label;â¦" hidden="true"/>
- <menuitem id="abp-media-menuitem" label="&context.media.label;â¦" hidden="true"/>
- <menuitem id="abp-frame-menuitem" label="&context.frame.label;â¦" hidden="true"/>
- <menuitem id="abp-removeWhitelist-menuitem" label="&context.removeWhitelist.label;" hidden="true"/>
-
- <!-- Fake sidebar -->
- <splitter id="abp-sidebar-splitter" hidden="true"/>
- <vbox id="abp-sidebar" height="200" width="200" hidden="true" persist="height width">
- <toolbox id="abp-sidebar-header">
- <toolbar id="abp-sidebar-toolbar" align="center" grippyhidden="true" fullscreentoolbar="true">
- <label id="abp-sidebar-title" control="abp-sidebar-browser" value="&sidebar.title;" flex="1" crop="end"/>
- <toolbarbutton id="abp-sidebar-close" command="abp-command-sidebar" tooltiptext="&closesidebar.label;"/>
- </toolbar>
- </toolbox>
- <iframe id="abp-sidebar-browser" flex="1"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/prismOverlay.xul b/chrome/content/ui/prismOverlay.xul
deleted file mode 100644
index d9de2a6..0000000
--- a/chrome/content/ui/prismOverlay.xul
+++ /dev/null
@@ -1,63 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2008
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="webrunner">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks" getBrowser="return this.E('browser_content');"
- getContextMenu="return this.E('popup_content');"/>
- </window>
-
- <!-- Status bar -->
- <statusbar id="statusbar">
- <statusbarpanel id="abp-status" mousethrough="never" insertbefore="button_commands"/>
- </statusbar>
-
- <!-- Tools menu -->
- <menupopup id="popup_tools">
- <menuitem id="abp-menuitem" insertbefore="menuitem_console"/>
- </menupopup>
-
- <!-- Context menu -->
- <menupopup id="popup_content">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
-
- <!-- Fake sidebar -->
- <vbox id="box_content">
- <splitter id="abp-sidebar-splitter"/>
- <vbox id="abp-sidebar"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/progressBar.xml b/chrome/content/ui/progressBar.xml
deleted file mode 100644
index 99aa152..0000000
--- a/chrome/content/ui/progressBar.xml
+++ /dev/null
@@ -1,174 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<bindings id="progressBarBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xbl="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
- <binding id="progressBar">
- <content orient="horizontal" pack="center">
- <xul:stack flex="1">
- <html:canvas anonid="canvas" width="1" height="1"/>
- <children/>
- </xul:stack>
- </content>
- <implementation>
- <field name="_gapWidth">5</field>
- <field name="_arrowheadWidth">5</field>
- <field name="_canvas">document.getAnonymousElementByAttribute(this, "anonid", "canvas")</field>
-
- <constructor>
- <![CDATA[
- // Run _init() after window loads, correct sizes might be unknown during construction
- let me = this;
- let callback = function()
- {
- window.removeEventListener("load", callback, false);
- window.setTimeout(function() me._init(), 0);
- }
- window.addEventListener("load", callback, false);
- ]]>
- </constructor>
-
- <method name="_init">
- <body>
- <![CDATA[
- let canvas = this._canvas;
- let width = canvas.width = canvas.offsetWidth;
- let height = canvas.height = canvas.offsetHeight;
-
- let context = canvas.getContext("2d");
- context.fillStyle = window.getComputedStyle(this, "").color;
- context.strokeStyle = window.getComputedStyle(this, "").color;
- context.lineWidth = 1;
-
- let panelCount = this.childNodes.length;
- let panelWidth = (width - this._gapWidth * (panelCount - 1) - 1) / panelCount;
- for (let i = 0; i < panelCount; i++)
- {
- context.save();
- context.translate(Math.round(i * (panelWidth + this._gapWidth)) + 0.5, 0.5);
- context.beginPath();
- if (i)
- context.moveTo(-this._arrowheadWidth, 0);
- else
- context.moveTo(0, 0);
- context.lineTo(panelWidth - this._arrowheadWidth, 0);
- context.lineTo(panelWidth, (height - 1) / 2);
- context.lineTo(panelWidth - this._arrowheadWidth, height - 1);
- if (i)
- {
- context.lineTo(-this._arrowheadWidth, height - 1);
- context.lineTo(0, (height - 1) / 2);
- context.lineTo(-this._arrowheadWidth, 0);
- }
- else
- {
- context.lineTo(0, height - 1);
- context.lineTo(0, 0);
- }
- context.stroke();
- context.restore();
-
- let childLeft = Math.round(i * (panelWidth + this._gapWidth) + 1);
- let childWidth = panelWidth - this._arrowheadWidth - 2;
- let child = this.childNodes[i];
- child.style.marginLeft = childLeft + "px";
- child.style.marginRight = (width - childLeft - childWidth) + "px";
- child.style.width = childWidth + "px";
- }
-
- // Resize after initialization should be ignored
- canvas.parentNode.removeAttribute("flex");
- ]]>
- </body>
- </method>
-
- <property name="activeItem">
- <getter>
- <![CDATA[
- for (let i = 0; i < this.childNodes.length; i++)
- {
- let child = this.childNodes[i];
- if (/\bactive\b/.test(child.className))
- return child;
- }
- return null;
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- let complete = true;
- for (let i = 0; i < this.childNodes.length; i++)
- {
- let child = this.childNodes[i];
- if (child == val)
- complete = false;
-
- if (!complete && child.value[0] == "â")
- child.value = child.value.replace(/^â\s*/, "");
- else if (complete && child.value[0] != "â")
- child.value = "â " + child.value;
-
- if (child != val && /\bactive\b/.test(child.className))
- child.className = child.className.replace(/\s*\bactive\b/, "");
- else if (child == val && !/\bactive\b/.test(child.className))
- child.className += " active";
- }
- return null;
- ]]>
- </setter>
- </property>
-
- <property name="activeItemComplete">
- <getter>
- <![CDATA[
- let activeItem = this.activeItem;
- if (!activeItem)
- return false;
- else
- return activeItem.value[0] == "â";
- ]]>
- </getter>
-
- <setter>
- <![CDATA[
- let activeItem = this.activeItem;
- if (!activeItem)
- return;
-
- if (!val && activeItem.value[0] == "â")
- activeItem.value = child.value.replace(/^â\s*/, "");
- else if (val && activeItem.value[0] != "â")
- activeItem.value = "â " + activeItem.value;
- ]]>
- </setter>
- </property>
- </implementation>
- </binding>
-</bindings>
diff --git a/chrome/content/ui/seamonkeyOverlay.xul b/chrome/content/ui/seamonkeyOverlay.xul
deleted file mode 100644
index 03b19d6..0000000
--- a/chrome/content/ui/seamonkeyOverlay.xul
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="main-window">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks"
- getBrowser="return this.window.gBrowser;"
- addTab="
- if (arguments[1] && 'openNewTabWith' in this.window)
- this.window.openNewTabWith(arguments[0], this.window.content.document, arguments[1].shiftKey);
- else if ('loadOneTab' in this.window.gBrowser) /* SeaMonkey 2.1 */
- this.window.gBrowser.loadOneTab(arguments[0], {inBackground: false});
- else /* SeaMonkey 2.0 */
- this.window.gBrowser.addTab(arguments[0], null, null, true);"
- getContextMenu="return this.E('contentAreaContextMenu');"
- getToolbox="return this.E('navigator-toolbox')"
- getDefaultToolbar="return this.E('PersonalToolbar');" toolbarInsertBefore="return this.E('bookmarks-button');"/>
- </window>
-
- <!-- Status bar -->
- <statusbar id="status-bar">
- <statusbarpanel id="abp-status" mousethrough="never" insertbefore="resizerBottomRight"/>
- </statusbar>
-
- <!-- Toolbar -->
- <toolbarpalette id="BrowserToolbarPalette">
- <toolbarbutton id="abp-toolbarbutton" type="menu-button" pack="end"
- class="toolbarbutton-1"/>
- </toolbarpalette>
-
- <!-- Tools menu -->
- <menupopup id="taskPopup">
- <menuitem id="abp-menuitem" insertafter="downloadmgr"/>
- </menupopup>
-
- <!-- View menu -->
- <menupopup id="view_toolbars_popup">
- <menuitem id="abp-blockableitems" insertafter="sidebar-menu"/>
- </menupopup>
-
- <!-- Context menu -->
- <menupopup id="contentAreaContextMenu">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
-
- <!-- Fake sidebar -->
- <vbox id="appcontent">
- <splitter id="abp-sidebar-splitter"/>
- <vbox id="abp-sidebar"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/sendReport.js b/chrome/content/ui/sendReport.js
deleted file mode 100644
index 33a5c3a..0000000
--- a/chrome/content/ui/sendReport.js
+++ /dev/null
@@ -1,1373 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-//
-// Report data template, more data will be added during data collection
-//
-
-let reportData =
- <report>
- <adblock-plus version={Utils.addonVersion} build={Utils.addonBuild} locale={Utils.appLocale}/>
- <application name={Utils.appInfo.name} vendor={Utils.appInfo.vendor} version={Utils.appInfo.version} userAgent={window.navigator.userAgent}/>
- <platform name="Gecko" version={Utils.appInfo.platformVersion} build={Utils.appInfo.platformBuildID}/>
- <options>
- <option id="enabled">{Prefs.enabled}</option>
- <option id="objecttabs">{Prefs.frameobjects}</option>
- <option id="collapse">{!Prefs.fastcollapse}</option>
- <option id="privateBrowsing">{Prefs.privateBrowsing}</option>
- </options>
- <window/>
- <requests/>
- <filters/>
- <subscriptions/>
- <errors/>
- </report>;
-
-//
-// Data collectors
-//
-
-let reportsListDataSource =
-{
- json: Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON),
- list: [],
-
- collectData: function(wnd, windowURI, callback)
- {
- let data = null;
- try
- {
- data = this.json.decode(Prefs.recentReports);
- }
- catch (e)
- {
- Cu.reportError(e);
- }
-
- if (data && "length" in data)
- {
- for (let i = 0; i < data.length; i++)
- {
- let entry = data[i];
- if (typeof entry.reportURL == "string" && entry.reportURL &&
- typeof entry.time == "number" && Date.now() - entry.time < 30*24*60*60*1000)
- {
- let newEntry = {site: null, reportURL: entry.reportURL, time: entry.time};
- if (typeof entry.site == "string" && entry.site)
- newEntry.site = entry.site;
- this.list.push(newEntry);
- }
- }
- }
-
- if (this.list.length > 10)
- this.list.splice(10);
-
- E("recentReports").hidden = !this.list.length;
- if (this.list.length)
- {
- let rows = E("recentReportsRows")
- for (let i = 0; i < this.list.length; i++)
- {
- let entry = this.list[i];
- let row = document.createElement("row");
-
- let link = document.createElement("description");
- link.setAttribute("class", "text-link");
- link.setAttribute("url", entry.reportURL);
- link.textContent = entry.reportURL.replace(/^.*\/(?=[^\/])/, "");
- row.appendChild(link);
-
- let site = document.createElement("description");
- if (entry.site)
- site.textContent = entry.site;
- row.appendChild(site);
-
- let time = document.createElement("description");
- time.textContent = Utils.formatTime(entry.time);
- row.appendChild(time);
-
- rows.appendChild(row);
- }
- }
-
- callback();
- },
-
- addReport: function(site, reportURL)
- {
- this.list.unshift({site: site, reportURL: reportURL, time: Date.now()});
- try
- {
- Prefs.recentReports = this.json.encode(this.list);
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- },
-
- clear: function()
- {
- this.list = [];
- Prefs.recentReports = this.json.encode(this.list);
- E("recentReports").hidden = true;
- },
-
- handleClick: function(event)
- {
- if (event.button != 0 || !event.target || !event.target.hasAttribute("url"))
- return;
-
- Utils.loadInBrowser(event.target.getAttribute("url"));
- }
-};
-
-let requestsDataSource =
-{
- requests: reportData.requests,
- origRequests: [],
- requestNotifier: null,
- callback: null,
- nodeByKey: {__proto__: null},
-
- collectData: function(wnd, windowURI, callback)
- {
- this.callback = callback;
- this.requestNotifier = new RequestNotifier(wnd, this.onRequestFound, this);
- },
-
- onRequestFound: function(frame, node, entry, scanComplete)
- {
- if (entry)
- {
- let key = entry.location + " " + entry.typeDescr + " " + entry.docDomain;
- let requestXML
- if (key in this.nodeByKey)
- {
- requestXML = this.nodeByKey[key];
- requestXML. at count = parseInt(requestXML. at count, 10) + 1;
- }
- else
- {
- requestXML = <request location={censorURL(entry.location)}
- type={entry.typeDescr}
- docDomain={entry.docDomain}
- thirdParty={entry.thirdParty}
- count="1"/>;
- this.nodeByKey[key] = requestXML;
- this.requests.appendChild(requestXML);
- }
-
- // Location is meaningless for element hiding hits
- if (entry.filter && entry.filter instanceof ElemHideFilter)
- delete requestXML. at location;
-
- if (entry.filter)
- requestXML. at filter = entry.filter.text;
-
- if (node instanceof Element)
- {
- requestXML. at node = node.localName;
- if (node.namespaceURI)
- requestXML. at node = node.namespaceURI + "#" + requestXML. at node;
-
- try
- {
- requestXML. at size = node.offsetWidth + "x" + node.offsetHeight;
- } catch(e) {}
- }
- this.origRequests.push(entry);
- }
-
- if (scanComplete)
- {
- this.requestNotifier.shutdown();
- this.requestNotifier = null;
- this.callback();
- }
- }
-};
-
-let filtersDataSource =
-{
- origFilters: [],
-
- collectData: function(wnd, windowURI, callback)
- {
- let wndStats = RequestNotifier.getWindowStatistics(wnd);
- if (wndStats)
- {
- let filters = reportData.filters;
- for (let f in wndStats.filters)
- {
- let filter = Filter.fromText(f)
- let hitCount = wndStats.filters[f];
- filters.appendChild(<filter text={filter.text} subscriptions={filter.subscriptions.filter(function(s) !s.disabled).map(function(s) s.url).join(" ")} hitCount={hitCount}/>);
- this.origFilters.push(filter);
- }
- }
- callback();
- }
-};
-
-let subscriptionsDataSource =
-{
- collectData: function(wnd, windowURI, callback)
- {
- let subscriptions = reportData.subscriptions;
- let now = Math.round(Date.now() / 1000);
- for (let i = 0; i < FilterStorage.subscriptions.length; i++)
- {
- let subscription = FilterStorage.subscriptions[i];
- if (subscription.disabled || !(subscription instanceof RegularSubscription))
- continue;
-
- let subscriptionXML = <subscription id={subscription.url} disabledFilters={subscription.filters.filter(function(filter) filter instanceof ActiveFilter && filter.disabled).length}/>;
- if (subscription.lastDownload)
- subscriptionXML. at lastDownloadAttempt = subscription.lastDownload - now;
- if (subscription instanceof DownloadableSubscription)
- {
- if (subscription.lastSuccess)
- subscriptionXML. at lastDownloadSuccess = subscription.lastSuccess - now;
- if (subscription.softExpiration)
- subscriptionXML. at softExpiration = subscription.softExpiration - now;
- if (subscription.expires)
- subscriptionXML. at hardExpiration = subscription.expires - now;
- subscriptionXML. at autoDownloadEnabled = subscription.autoDownload;
- subscriptionXML. at downloadStatus = subscription.downloadStatus;
- }
- subscriptions.appendChild(subscriptionXML);
- }
- callback();
- }
-};
-
-let screenshotDataSource =
-{
- imageOffset: 10,
-
- // Fields used for color reduction
- _mapping: [0x00, 0x55, 0xAA, 0xFF],
- _i: null,
- _max: null,
- _pixelData: null,
- _callback: null,
-
- // Fields used for user interaction
- _enabled: true,
- _canvas: null,
- _context: null,
- _selectionType: "mark",
- _currentData: null,
- _undoQueue: [],
-
- collectData: function(wnd, windowURI, callback)
- {
- this._callback = callback;
- this._canvas = E("screenshotCanvas");
- this._canvas.width = this._canvas.offsetWidth;
-
- // Do not resize canvas any more (no idea why Gecko requires both to be set)
- this._canvas.parentNode.style.MozBoxAlign = "center";
- this._canvas.parentNode.align = "center";
-
- this._context = this._canvas.getContext("2d");
- let wndWidth = wnd.document.documentElement.scrollWidth;
- let wndHeight = wnd.document.documentElement.scrollHeight;
-
- // Copy scaled screenshot of the webpage. We scale the webpage by width
- // but leave 10px on each side for easier selecting.
-
- // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe side.
- // Also, make sure height is at most five times the width to keep image size down.
- let copyWidth = Math.min(wndWidth, 30000);
- let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5);
- let copyX = Math.max(Math.min(wnd.scrollX - copyWidth / 2, wndWidth - copyWidth), 0);
- let copyY = Math.max(Math.min(wnd.scrollY - copyHeight / 2, wndHeight - copyHeight), 0);
-
- let scalingFactor = (this._canvas.width - this.imageOffset * 2) / copyWidth;
- this._canvas.height = copyHeight * scalingFactor + this.imageOffset * 2;
-
- this._context.save();
- this._context.translate(this.imageOffset, this.imageOffset);
- this._context.scale(scalingFactor, scalingFactor);
- this._context.drawWindow(wnd, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,255)");
- this._context.restore();
-
- // Init canvas settings
- this._context.fillStyle = "rgb(0, 0, 0)";
- this._context.strokeStyle = "rgba(255, 0, 0, 0.7)";
- this._context.lineWidth = 3;
- this._context.lineJoin = "round";
-
- // Reduce colors asynchronously
- this._pixelData = this._context.getImageData(this.imageOffset, this.imageOffset,
- this._canvas.width - this.imageOffset * 2,
- this._canvas.height - this.imageOffset * 2);
- this._max = this._pixelData.width * this._pixelData.height * 4;
- this._i = 0;
- Utils.threadManager.currentThread.dispatch(this, Ci.nsIEventTarget.DISPATCH_NORMAL);
- },
-
- run: function()
- {
- // Process only 5000 bytes at a time to prevent browser hangs
- let endIndex = Math.min(this._i + 5000, this._max);
- let i = this._i;
- for (; i < endIndex; i++)
- this._pixelData.data[i] = this._mapping[this._pixelData.data[i] >> 6];
-
- if (i >= this._max)
- {
- // Save data back and we are done
- this._context.putImageData(this._pixelData, this.imageOffset, this.imageOffset);
- this._callback();
- }
- else
- {
- this._i = i;
- Utils.threadManager.currentThread.dispatch(this, Ci.nsIEventTarget.DISPATCH_NORMAL);
- }
- },
-
- get enabled() this._enabled,
- set enabled(enabled)
- {
- if (this._enabled == enabled)
- return;
-
- this._enabled = enabled;
- this._canvas.style.opacity = this._enabled ? "" : "0.3"
- E("screenshotMarkButton").disabled = !this._enabled;
- E("screenshotRemoveButton").disabled = !this._enabled;
- E("screenshotUndoButton").disabled = !this._enabled || !this._undoQueue.length;
- },
-
- get selectionType() this._selectionType,
- set selectionType(type)
- {
- if (this._selectionType == type)
- return;
-
- // Abort selection already in progress
- this.abortSelection();
-
- this._selectionType = type;
- },
-
- exportData: function()
- {
- if (this.enabled)
- {
- reportData.screenshot = this._canvas.toDataURL();
- reportData.screenshot. at edited = (this._undoQueue.length ? 'true' : 'false');
- }
- else
- delete reportData.screenshot;
- },
-
- abortSelection: function()
- {
- if (this._currentData && this._currentData.data)
- {
- this._context.putImageData(this._currentData.data,
- Math.min(this._currentData.anchorX, this._currentData.currentX),
- Math.min(this._currentData.anchorY, this._currentData.currentY));
- }
- document.removeEventListener("keypress", this.handleKeyPress, true);
- this._currentData = null;
- },
-
- handleKeyPress: function(event)
- {
- if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE)
- {
- event.stopPropagation();
- event.preventDefault();
- screenshotDataSource.abortSelection();
- }
- },
-
- startSelection: function(event)
- {
- if (event.button == 2)
- this.abortSelection(); // Right mouse button aborts selection
-
- if (event.button != 0 || !this.enabled)
- return;
-
- // Abort selection already in progress
- this.abortSelection();
-
- let boxObject = document.getBoxObjectFor(this._canvas);
- let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY];
- this._currentData = {
- data: null,
- anchorX: x,
- anchorY: y,
- currentX: -1,
- currentY: -1
- };
- this.updateSelection(event);
-
- document.addEventListener("keypress", this.handleKeyPress, true);
- },
-
- updateSelection: function(event)
- {
- if (event.button != 0 || !this._currentData)
- return;
-
- let boxObject = document.getBoxObjectFor(this._canvas);
- let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY];
- if (this._currentData.currentX == x && this._currentData.currentY == y)
- return;
-
- if (this._currentData.data)
- {
- this._context.putImageData(this._currentData.data,
- Math.min(this._currentData.anchorX, this._currentData.currentX),
- Math.min(this._currentData.anchorY, this._currentData.currentY));
- }
-
- this._currentData.currentX = x;
- this._currentData.currentY = y;
-
- let left = Math.min(this._currentData.anchorX, this._currentData.currentX);
- let right = Math.max(this._currentData.anchorX, this._currentData.currentX);
- let top = Math.min(this._currentData.anchorY, this._currentData.currentY);
- let bottom = Math.max(this._currentData.anchorY, this._currentData.currentY);
-
- let minDiff = (this._selectionType == "mark" ? 3 : 1);
- if (right - left >= minDiff && bottom - top >= minDiff)
- this._currentData.data = this._context.getImageData(left, top, right - left, bottom - top);
- else
- this._currentData.data = null;
-
- if (this._selectionType == "mark")
- {
- // all coordinates need to be moved 1.5px inwards to get the desired result
- left += 1.5;
- right -= 1.5;
- top += 1.5;
- bottom -= 1.5;
- if (left < right && top < bottom)
- this._context.strokeRect(left, top, right - left, bottom - top);
- }
- else if (this._selectionType == "remove")
- this._context.fillRect(left, top, right - left, bottom - top);
- },
-
- stopSelection: function(event)
- {
- if (event.button != 0 || !this._currentData)
- return;
-
- if (this._currentData.data)
- {
- this._undoQueue.push(this._currentData);
- E("screenshotUndoButton").disabled = false;
- }
-
- this._currentData = null;
- document.removeEventListener("keypress", this.handleKeyPress, true);
- },
-
- undo: function()
- {
- let op = this._undoQueue.pop();
- if (!op)
- return;
-
- this._context.putImageData(op.data,
- Math.min(op.anchorX, op.currentX),
- Math.min(op.anchorY, op.currentY));
-
- if (!this._undoQueue.length)
- E("screenshotUndoButton").disabled = true;
- }
-};
-
-let framesDataSource =
-{
- site: null,
-
- collectData: function(wnd, windowURI, callback)
- {
- try
- {
- this.site = windowURI.host;
- if (this.site)
- document.title += " (" + this.site + ")";
- }
- catch (e)
- {
- // Expected exception - not all URL schemes have a host name
- }
-
- reportData.window. at url = censorURL(windowURI ? windowURI.spec : wnd.location.href);
- if (wnd.opener && wnd.opener.location.href)
- reportData.window. at opener = censorURL(wnd.opener.location.href);
- if (wnd.document.referrer)
- reportData.window. at referrer = censorURL(wnd.document.referrer);
- this.scanFrames(wnd, reportData.window);
-
- callback();
- },
-
- scanFrames: function(wnd, xmlList)
- {
- try
- {
- for (let i = 0; i < wnd.frames.length; i++)
- {
- let frame = wnd.frames[i];
- let frameXML = <frame url={censorURL(frame.location.href)}/>;
- this.scanFrames(frame, frameXML);
- xmlList.appendChild(frameXML);
- }
- }
- catch (e)
- {
- // Don't break if something goes wrong
- Cu.reportError(e);
- }
- }
-};
-
-let errorsDataSource =
-{
- collectData: function(wnd, windowURI, callback)
- {
- let messages = {};
- Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).getMessageArray(messages, {});
- messages = messages.value || [];
- messages = messages.filter(function(message)
- {
- return (message instanceof Ci.nsIScriptError &&
- !/^https?:/i.test(message.sourceName) &&
- (/adblock/i.test(message.errorMessage) || /adblock/i.test(message.sourceName)));
- });
- if (messages.length > 10) // Only the last 10 messages
- messages = messages.slice(messages.length - 10, messages.length);
-
- // Censor app and profile paths in error messages
- let censored = {__proto__: null};
- let pathList = [["ProfD", "%PROFILE%"], ["GreD", "%GRE%"], ["CurProcD", "%APP%"]];
- for (let i = 0; i < pathList.length; i++)
- {
- let [pathID, placeholder] = pathList[i];
- try
- {
- let file = Utils.dirService.get(pathID, Ci.nsIFile);
- censored[file.path.replace(/[\\\/]+$/, '')] = placeholder;
- let uri = Utils.ioService.newFileURI(file);
- censored[uri.spec.replace(/[\\\/]+$/, '')] = placeholder;
- } catch(e) {}
- }
-
- let errors = reportData.errors;
- for (let i = 0; i < messages.length; i++)
- {
- let message = messages[i];
-
- let text = message.errorMessage;
- for (let path in censored)
- text = text.replace(path, censored[path], "gi");
- if (text.length > 256)
- text = text.substr(0, 256) + "...";
-
- let file = message.sourceName;
- for (let path in censored)
- file = file.replace(path, censored[path], "gi");
- if (file.length > 256)
- file = file.substr(0, 256) + "...";
-
- let sourceLine = message.sourceLine;
- if (sourceLine.length > 256)
- sourceLine = sourceLine.substr(0, 256) + "...";
-
- let errorXML = <error type={message.flags & Ci.nsIScriptError.warningFlag ? "warning" : "error"}
- text={text} file={file} line={message.lineNumber} column={message.columnNumber} sourceLine={sourceLine}/>;
- errors.appendChild(errorXML);
- }
-
- callback();
- }
-};
-
-let extensionsDataSource =
-{
- data: <extensions/>,
-
- collectData: function(wnd, windowURI, callback)
- {
- let AddonManager = null;
- try
- {
- let namespace = {};
- Cu.import("resource://gre/modules/AddonManager.jsm", namespace);
- AddonManager = namespace.AddonManager;
- } catch (e) {}
-
- if (AddonManager)
- {
- // Gecko 2.0
- let me = this;
- AddonManager.getAddonsByTypes(["extension", "plugin"], function(items)
- {
- for (let i = 0; i < items.length; i++)
- {
- let item = items[i];
- if (!item.isActive)
- continue;
- me.data.appendChild(<extension id={item.id} name={item.name} type={item.type} version={item.version}/>);
- }
- callback();
- });
- }
- else if ("@mozilla.org/extensions/manager;1" in Cc)
- {
- // Gecko 1.9.x
- let extensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
- let ds = extensionManager.datasource;
- let rdfService = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
- let list = {};
- let items = extensionManager.getItemList(Ci.nsIUpdateItem.TYPE_EXTENSION | Ci.nsIUpdateItem.TYPE_PLUGIN, {});
- for (let i = 0; i < items.length; i++)
- {
- let item = items[i];
-
- // Check whether extension is disabled - yuk...
- let source = rdfService.GetResource("urn:mozilla:item:" + item.id);
- let link = rdfService.GetResource("http://www.mozilla.org/2004/em-rdf#isDisabled");
- let target = ds.GetTarget(source, link, true);
- if (target instanceof Ci.nsIRDFLiteral && target.Value == "true")
- continue;
-
- this.data.appendChild(<extension id={item.id} name={item.name} type={item.type == Ci.nsIUpdateItem.TYPE_EXTENSION ? "extension" : "plugin"} version={item.version}/>);
- }
- callback();
- }
- else
- {
- // No add-on manager, no extension manager - we must be running in K-Meleon.
- // Skip this step.
- callback();
- }
- },
-
- exportData: function(doExport)
- {
- if (doExport)
- reportData.extensions = this.data;
- else
- delete reportData.extensions;
- }
-};
-
-let issuesDataSource =
-{
- contentWnd: null,
- isEnabled: Prefs.enabled,
- whitelistFilter: null,
- disabledFilters: [],
- disabledSubscriptions: [],
- ownFilters: [],
- numSubscriptions: FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription && !subscription.disabled).length,
- numAppliedFilters: Infinity,
-
- collectData: function(wnd, windowURI, callback)
- {
- this.contentWnd = wnd;
- this.whitelistFilter = Policy.isWindowWhitelisted(wnd);
-
- if (!this.whitelistFilter && this.isEnabled)
- {
- // Find disabled filters in active subscriptions matching any of the requests
- let disabledMatcher = new CombinedMatcher();
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (subscription.disabled)
- continue;
-
- for each (let filter in subscription.filters)
- if (filter instanceof BlockingFilter && filter.disabled)
- disabledMatcher.add(filter);
- }
-
- let seenFilters = {__proto__: null};
- for each (let request in requestsDataSource.origRequests)
- {
- if (request.filter)
- continue;
-
- let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty);
- if (filter && !(filter.text in seenFilters))
- {
- this.disabledFilters.push(filter);
- seenFilters[filter.text] = true;
- }
- }
-
- // Find disabled subscriptions with filters matching any of the requests
- let seenSubscriptions = {__proto__: null};
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (!subscription.disabled)
- continue;
-
- disabledMatcher.clear();
- for each (let filter in subscription.filters)
- if (filter instanceof BlockingFilter)
- disabledMatcher.add(filter);
-
- for each (let request in requestsDataSource.origRequests)
- {
- if (request.filter)
- continue;
-
- let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty);
- if (filter && !(subscription.url in seenSubscriptions))
- {
- this.disabledSubscriptions.push(subscription);
- seenSubscriptions[subscription.text] = true;
- break;
- }
- }
- }
-
- this.numAppliedFilters = 0;
- for each (let filter in filtersDataSource.origFilters)
- {
- if (filter instanceof WhitelistFilter)
- continue;
-
- this.numAppliedFilters++;
- if (filter.subscriptions.some(function(subscription) subscription instanceof SpecialSubscription))
- this.ownFilters.push(filter);
- }
- }
-
- callback();
- },
-
- updateIssues: function(type)
- {
- if (type == "other")
- {
- E("typeSelectorPage").next = "typeWarning";
- return;
- }
-
- E("issuesWhitelistBox").hidden = !this.whitelistFilter;
- E("issuesDisabledBox").hidden = this.isEnabled;
- E("issuesNoFiltersBox").hidden = (type != "false positive" || this.numAppliedFilters > 0);
- E("issuesNoSubscriptionsBox").hidden = (type != "false negative" || this.numAppliedFilters > 0 || this.numSubscriptions > 0);
- E("issuesSubscriptionCountBox").hidden = (this.numSubscriptions < 5);
-
- let ownFiltersBox = E("issuesOwnFilters");
- if (this.ownFilters.length && !ownFiltersBox.firstChild)
- {
- let template = E("issuesOwnFiltersTemplate");
- for each (let filter in this.ownFilters)
- {
- let element = template.cloneNode(true);
- element.removeAttribute("id");
- element.removeAttribute("hidden");
- element.firstChild.setAttribute("value", filter.text);
- element.firstChild.setAttribute("tooltiptext", filter.text);
- element.abpFilter = filter;
- ownFiltersBox.appendChild(element);
- }
- }
- E("issuesOwnFiltersBox").hidden = (type != "false positive" || this.ownFilters.length == 0);
-
- let disabledSubscriptionsBox = E("issuesDisabledSubscriptions");
- if (this.disabledSubscriptions.length && !disabledSubscriptionsBox.firstChild)
- {
- let template = E("issuesDisabledSubscriptionsTemplate");
- for each (let subscription in this.disabledSubscriptions)
- {
- let element = template.cloneNode(true);
- element.removeAttribute("id");
- element.removeAttribute("hidden");
- element.firstChild.setAttribute("value", subscription.title);
- element.setAttribute("tooltiptext", subscription instanceof DownloadableSubscription ? subscription.url : subscription.title);
- element.abpSubscription = subscription;
- disabledSubscriptionsBox.appendChild(element);
- }
- }
- E("issuesDisabledSubscriptionsBox").hidden = (type != "false negative" || this.disabledSubscriptions.length == 0);
-
- let disabledFiltersBox = E("issuesDisabledFilters");
- if (this.disabledFilters.length && !disabledFiltersBox.firstChild)
- {
- let template = E("issuesDisabledFiltersTemplate");
- for each (let filter in this.disabledFilters)
- {
- let element = template.cloneNode(true);
- element.removeAttribute("id");
- element.removeAttribute("hidden");
- element.firstChild.setAttribute("value", filter.text);
- element.setAttribute("tooltiptext", filter.text);
- element.abpFilter = filter;
- disabledFiltersBox.appendChild(element);
- }
- }
- E("issuesDisabledFiltersBox").hidden = (type != "false negative" || this.disabledFilters.length == 0);
-
- // Don't allow sending report if the page is whitelisted - we need the data.
- // Also disallow reports without matching filters or without subscriptions,
- // subscription authors cannot do anything about those.
- E("issuesOverride").hidden = !E("issuesWhitelistBox").hidden ||
- !E("issuesDisabledBox").hidden ||
- !E("issuesNoFiltersBox").hidden ||
- !E("issuesNoSubscriptionsBox").hidden ||
- !E("issuesSubscriptionCountBox").hidden;
-
- if (E("issuesWhitelistBox").hidden && E("issuesDisabledBox").hidden &&
- E("issuesNoFiltersBox").hidden && E("issuesNoSubscriptionsBox").hidden &&
- E("issuesOwnFiltersBox").hidden && E("issuesDisabledFiltersBox").hidden &&
- E("issuesDisabledSubscriptionsBox").hidden && E("issuesSubscriptionCountBox").hidden)
- {
- E("typeSelectorPage").next = "screenshot";
- }
- else
- {
- E("typeSelectorPage").next = "issues";
- }
- },
-
- forceReload: function()
- {
- // User changed configuration, don't allow sending report now - page needs
- // to be reloaded
- E("issuesOverride").hidden = true;
- E("issuesChangeMessage").hidden = false;
- document.documentElement.canRewind = false;
- document.documentElement.canAdvance = true;
-
- let contentWnd = this.contentWnd;
- let nextButton = document.documentElement.getButton("next");
- nextButton.label = E("issuesPage").getAttribute("reloadButtonLabel");
- nextButton.accessKey = E("issuesPage").getAttribute("reloadButtonAccesskey");
- document.documentElement.addEventListener("wizardnext", function(event)
- {
- event.preventDefault();
- event.stopPropagation();
- window.close();
- contentWnd.location.reload();
- }, true);
- },
-
- removeWhitelist: function()
- {
- if (this.whitelistFilter && this.whitelistFilter.subscriptions.length && !this.whitelistFilter.disabled)
- {
- this.whitelistFilter.disabled = true;
- FilterStorage.triggerObservers("filters disable", [this.whitelistFilter]);
- }
- E("issuesWhitelistBox").hidden = true;
- this.forceReload();
- },
-
- enable: function()
- {
- Prefs.enabled = true;
- E("issuesDisabledBox").hidden = true;
- this.forceReload();
- },
-
- addSubscription: function()
- {
- let result = {};
- openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", null, result);
- if (!("url" in result))
- return;
-
- let subscriptionResults = [[result.url, result.title]];
- if ("mainSubscriptionURL" in result)
- subscriptionResults.push([result.mainSubscriptionURL, result.mainSubscriptionTitle]);
-
- for each (let [url, title] in subscriptionResults)
- {
- let subscription = Subscription.fromURL(url);
- if (!subscription)
- continue;
-
- FilterStorage.addSubscription(subscription);
-
- if (subscription.disabled)
- {
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- }
-
- subscription.title = title;
- if (subscription instanceof DownloadableSubscription)
- subscription.autoDownload = result.autoDownload;
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
-
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- }
- FilterStorage.saveToDisk();
-
- E("issuesNoSubscriptionsBox").hidden = true;
- this.forceReload();
- },
-
- disableFilter: function(node)
- {
- let filter = node.abpFilter;
- if (filter && filter.subscriptions.length && !filter.disabled)
- {
- filter.disabled = true;
- FilterStorage.triggerObservers("filters disable", [filter]);
- }
-
- node.parentNode.removeChild(node);
- if (!E("issuesOwnFilters").firstChild)
- E("issuesOwnFiltersBox").hidden = true;
- this.forceReload();
- },
-
- enableFilter: function(node)
- {
- let filter = node.abpFilter;
- if (filter && filter.subscriptions.length && filter.disabled)
- {
- filter.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter]);
- }
-
- node.parentNode.removeChild(node);
- if (!E("issuesDisabledFilters").firstChild)
- E("issuesDisabledFiltersBox").hidden = true;
- this.forceReload();
- },
-
-
- enableSubscription: function(node)
- {
- let subscription = node.abpSubscription;
- if (subscription && subscription.disabled)
- {
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- }
-
- node.parentNode.removeChild(node);
- if (!E("issuesDisabledSubscriptions").firstChild)
- E("issuesDisabledSubscriptionsBox").hidden = true;
- this.forceReload();
- }
-};
-
-let dataCollectors = [reportsListDataSource, requestsDataSource, filtersDataSource, subscriptionsDataSource,
- screenshotDataSource, framesDataSource, errorsDataSource, extensionsDataSource,
- issuesDataSource];
-
-//
-// Wizard logic
-//
-
-function initWizard()
-{
- // Make sure no issue type is selected by default
- E("typeGroup").selectedItem = null;
- document.documentElement.addEventListener("pageshow", updateNextButton, false);
-
- // Move privacy link
- let extraButton = document.documentElement.getButton("extra1");
- extraButton.parentNode.insertBefore(E("privacyLink"), extraButton);
-}
-
-function updateNextButton()
-{
- let nextButton = document.documentElement.getButton("next");
- if (!nextButton)
- return;
-
- if (document.documentElement.currentPage.id == "commentPage")
- {
- if (!nextButton.hasAttribute("_origLabel"))
- {
- nextButton.setAttribute("_origLabel", nextButton.getAttribute("label"));
- nextButton.setAttribute("label", document.documentElement.getAttribute("sendbuttonlabel"));
- nextButton.setAttribute("_origAccessKey", nextButton.getAttribute("accesskey"));
- nextButton.setAttribute("accesskey", document.documentElement.getAttribute("sendbuttonaccesskey"));
- }
- }
- else
- {
- if (nextButton.hasAttribute("_origLabel"))
- {
- nextButton.setAttribute("label", nextButton.getAttribute("_origLabel"));
- nextButton.removeAttribute("_origLabel");
- nextButton.setAttribute("accesskey", nextButton.getAttribute("_origAccessKey"));
- nextButton.removeAttribute("_origAccessKey");
- }
- }
-}
-
-function initDataCollectorPage()
-{
- document.documentElement.canAdvance = false;
-
- let contentWindow = window.arguments[0];
- let windowURI = (window.arguments[1] instanceof Ci.nsIURI ? window.arguments[1] : null);
- let totalSteps = dataCollectors.length;
- let initNextDataSource = function()
- {
- if (!dataCollectors.length)
- {
- // We are done, continue to next page
- document.documentElement.canAdvance = true;
- document.documentElement.advance();
- return;
- }
-
- let progress = (totalSteps - dataCollectors.length) / totalSteps * 100;
- if (progress > 0)
- {
- let progressMeter = E("dataCollectorProgress");
- progressMeter.mode = "determined";
- progressMeter.value = progress;
- }
-
- // Continue with the next data source, asynchronously to allow progress meter to update
- let dataSource = dataCollectors.shift();
- Utils.runAsync(function()
- {
- dataSource.collectData(contentWindow, windowURI, initNextDataSource);
- });
- };
-
- initNextDataSource();
-}
-
-function initTypeSelectorPage()
-{
- E("progressBar").activeItem = E("typeSelectorHeader");
- let header = document.getAnonymousElementByAttribute(document.documentElement, "class", "wizard-header");
- if (header)
- header.setAttribute("viewIndex", "1");
-
- document.documentElement.canRewind = false;
- typeSelectionUpdated();
-}
-
-function typeSelectionUpdated()
-{
- let selection = E("typeGroup").selectedItem;
- document.documentElement.canAdvance = (selection != null);
- if (selection)
- {
- if (reportData. at type != selection.value)
- {
- E("screenshotCheckbox").checked = (selection.value != "other");
- E("screenshotCheckbox").doCommand();
- E("extensionsCheckbox").checked = (selection.value == "other");
- E("extensionsCheckbox").doCommand();
- }
- reportData. at type = selection.value;
-
- issuesDataSource.updateIssues(selection.value);
- }
-}
-
-function initIssuesPage()
-{
- updateIssuesOverride();
-}
-
-function updateIssuesOverride()
-{
- document.documentElement.canAdvance = E("issuesOverride").checked;
-}
-
-function initTypeWarningPage()
-{
- updateTypeWarningOverride();
-
- let textElement = E("typeWarningText");
- if ("abpInitialized" in textElement)
- return;
-
- let template = textElement.textContent.replace(/[\r\n\s]+/g, " ");
-
- let beforeLink, linkText, afterLink;
- if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
- [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
- else
- [beforeLink, linkText, afterLink] = ["", template, ""];
-
- while (textElement.firstChild && textElement.firstChild.nodeType != Node.ELEMENT_NODE)
- textElement.removeChild(textElement.firstChild);
- while (textElement.lastChild && textElement.lastChild.nodeType != Node.ELEMENT_NODE)
- textElement.removeChild(textElement.lastChild);
-
- if (textElement.firstChild)
- textElement.firstChild.textContent = linkText;
- textElement.insertBefore(document.createTextNode(beforeLink), textElement.firstChild);
- textElement.appendChild(document.createTextNode(afterLink));
- textElement.abpInitialized = true;
-}
-
-function updateTypeWarningOverride()
-{
- document.documentElement.canAdvance = E("typeWarningOverride").checked;
-}
-
-function initScreenshotPage()
-{
- E("progressBar").activeItem = E("screenshotHeader");
-}
-
-function initCommentPage()
-{
- E("progressBar").activeItem = E("commentPageHeader");
-
- screenshotDataSource.exportData();
- updateDataField();
-}
-
-function showDataField()
-{
- E('dataDeck').selectedIndex = 1;
- updateDataField();
- E('data').focus();
-}
-
-let _dataFieldUpdateTimeout = null;
-
-function _updateDataField()
-{
- let dataField = E("data");
- let [selectionStart, selectionEnd] = [dataField.selectionStart, dataField.selectionEnd];
- dataField.value = reportData.toXMLString();
- dataField.setSelectionRange(selectionStart, selectionEnd);
-}
-
-function updateDataField()
-{
- // Don't do anything if data field is hidden
- if (E('dataDeck').selectedIndex != 1)
- return;
-
- if (_dataFieldUpdateTimeout)
- {
- window.clearTimeout(_dataFieldUpdateTimeout);
- _dataFieldUpdateTimeout = null;
- }
-
- _dataFieldUpdateTimeout = window.setTimeout(_updateDataField, 200);
-}
-
-function updateComment()
-{
- let value = E("comment").value;
- reportData.comment = value.substr(0, 1000);
- E("commentLengthWarning").setAttribute("visible", value.length > 1000);
- updateDataField();
-}
-
-function updateEmail()
-{
- reportData.email = E("email").value.replace(/\@/g, " at ").replace(/\./g, " dot ");
- updateDataField();
-}
-
-function updateExtensions(attach)
-{
- extensionsDataSource.exportData(attach);
- updateDataField();
-}
-
-function initSendPage()
-{
- E("progressBar").activeItem = E("sendPageHeader");
-
- E("result").hidden = true;
- E("sendReportErrorBox").hidden = true;
- E("sendReportMessage").hidden = false;
- E("sendReportProgress").hidden = false;
- E("sendReportProgress").mode = "undetermined";
-
- document.documentElement.canRewind = false;
- document.documentElement.getButton("finish").disabled = true;
-
- let guid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString().replace(/[\{\}]/g, "");
- let url = Prefs.report_submiturl.replace(/%GUID%/g, guid).replace(/%LANG%/g, Utils.appLocale);
- let request = new XMLHttpRequest();
- request.open("POST", url);
- request.setRequestHeader("Content-Type", "text/xml");
- request.setRequestHeader("X-Adblock-Plus", "1");
- request.addEventListener("load", reportSent, false);
- request.addEventListener("error", reportSent, false);
- if ("upload" in request && request.upload)
- request.upload.addEventListener("progress", updateReportProgress, false);
- request.send(reportData.toXMLString());
-}
-
-function updateReportProgress(event)
-{
- if (!event.lengthComputable)
- return;
-
- let progress = Math.round(event.loaded / event.total * 100);
- if (progress > 0)
- {
- let progressMeter = E("sendReportProgress");
- progressMeter.mode = "determined";
- progressMeter.value = progress;
- }
-}
-
-function reportSent(event)
-{
- let request = event.target;
- let success = false;
- let errorMessage = Utils.getString("synchronize_connection_error");
- try
- {
- let status = request.channel.status;
- if (Components.isSuccessCode(status))
- {
- success = (request.status == 200 || request.status == 0);
- errorMessage = request.status + " " + request.statusText;
- }
- else
- {
- errorMessage = "0x" + status.toString(16);
-
- // Try to find the name for the status code
- let exception = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCException);
- exception.initialize(null, status, null, null, null, null);
- if (exception.name)
- errorMessage = exception.name;
- }
- } catch (e) {}
-
- let result = "";
- try
- {
- result = request.responseText;
- } catch (e) {}
-
- result = result.replace(/%CONFIRMATION%/g, encodeHTML(E("result").getAttribute("confirmationMessage")));
- result = result.replace(/%KNOWNISSUE%/g, encodeHTML(E("result").getAttribute("knownIssueMessage")));
- result = result.replace(/(<html)\b/, '$1 dir="' + window.getComputedStyle(document.documentElement, "").direction + '"');
-
- if (!success)
- {
- let errorElement = E("sendReportError");
- let template = errorElement.getAttribute("textTemplate").replace(/[\r\n\s]+/g, " ");
-
- let beforeLink, linkText, afterLink;
- if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
- [beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
- else
- [beforeLink, linkText, afterLink] = ["", template, ""];
-
- beforeLink = beforeLink.replace(/\?1\?/g, errorMessage);
- afterLink = afterLink.replace(/\?1\?/g, errorMessage);
-
- while (errorElement.firstChild && errorElement.firstChild.nodeType != Node.ELEMENT_NODE)
- errorElement.removeChild(errorElement.firstChild);
- while (errorElement.lastChild && errorElement.lastChild.nodeType != Node.ELEMENT_NODE)
- errorElement.removeChild(errorElement.lastChild);
-
- if (errorElement.firstChild)
- errorElement.firstChild.textContent = linkText;
- errorElement.insertBefore(document.createTextNode(beforeLink), errorElement.firstChild);
- errorElement.appendChild(document.createTextNode(afterLink));
-
- E("sendReportErrorBox").hidden = false;
- }
-
- E("sendReportProgress").hidden = true;
-
- let frame = E("result");
- frame.hidden = false;
- frame.docShell.allowAuth = false;
- frame.docShell.allowJavascript = false;
- frame.docShell.allowMetaRedirects = false;
- frame.docShell.allowPlugins = false;
- frame.docShell.allowSubframes = false;
-
- frame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIComponent(result));
-
- E("sendReportMessage").hidden = true;
-
- if (success)
- {
- try
- {
- let link = request.responseXML.getElementById("link").getAttribute("href");
- let button = E("copyLink");
- button.setAttribute("url", link);
- button.removeAttribute("disabled");
-
- if (!Prefs.privateBrowsing)
- reportsListDataSource.addReport(framesDataSource.site, link);
- } catch (e) {}
- E("copyLinkBox").hidden = false;
-
- document.documentElement.getButton("finish").disabled = false;
- document.documentElement.getButton("cancel").disabled = true;
- E("progressBar").activeItemComplete = true;
- }
-}
-
-function processLinkClick(event)
-{
- event.preventDefault();
-
- let link = event.target;
- while (link && !(link instanceof HTMLAnchorElement))
- link = link.parentNode;
-
- if (link && (link.protocol == "http:" || link.protocol == "https:"))
- Utils.loadInBrowser(link.href);
-}
-
-function copyLink(url)
-{
- let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
- clipboardHelper.copyString(url);
-}
-
-function censorURL(url)
-{
- return url.replace(/([?;&\/#][^?;&\/#]+?=)[^?;&\/#]+/g, "$1*");
-}
-
-function encodeHTML(str)
-{
- return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
-}
diff --git a/chrome/content/ui/sendReport.xul b/chrome/content/ui/sendReport.xul
deleted file mode 100644
index 57cd5e0..0000000
--- a/chrome/content/ui/sendReport.xul
+++ /dev/null
@@ -1,239 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://global/skin/tree.css" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/sendReport.css" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/sendReport.dtd">
-
-<wizard
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&wizard.title;"
- id="abpSendReportWizard"
- onload="initWizard();"
- width="800"
- height="550"
- sendbuttonlabel="&sendButton.label;"
- sendbuttonaccesskey="&sendButton.accesskey;"
- windowtype="abp:sendReport">
-
-<script type="application/x-javascript;version=1.7" src="utils.js"/>
-<script type="application/x-javascript;version=1.7" src="sendReport.js"/>
-
-<keyset id="wizardKeys">
- <key id="undoKey" modifiers="accel" key="Z" oncommand="if (document.documentElement.currentPage.id == 'screenshotPage') screenshotDataSource.undo();"/>
-</keyset>
-
-<box hidden="true">
- <xbl:bindings id="headerBindings" xmlns:xbl="http://www.mozilla.org/xbl">
- <xbl:binding id="headerBinding">
- <xbl:content orient="vertical">
- <deck xbl:inherits="selectedIndex=viewIndex">
- <description class="wizard-header-label" xbl:inherits="value=label"/>
- <progressbar id="progressBar" style="-moz-binding: url(progressBar.xml#progressBar);">
- <label id="typeSelectorHeader" class="progressLabel" value="&typeSelector.heading;" crop="end"/>
- <label id="screenshotHeader" class="progressLabel" value="&screenshot.heading;" crop="end"/>
- <label id="commentPageHeader" class="progressLabel" value="&commentPage.heading;" crop="end"/>
- <label id="sendPageHeader" class="progressLabel" value="&sendPage.heading;" crop="end"/>
- </progressbar>
- </deck>
- </xbl:content>
- </xbl:binding>
- </xbl:bindings>
-
- <label id="privacyLink" class="text-link" value="&privacyPolicy.label;" onclick="Utils.loadDocLink('reporter_privacy');"/>
-</box>
-
-<wizardpage id="dataCollectorPage" pageid="dataCollector" next="typeSelector" label="&dataCollector.heading;" onpageshow="initDataCollectorPage();">
- <description>&dataCollector.description;</description>
-
- <progressmeter id="dataCollectorProgress" mode="undetermined"/>
-</wizardpage>
-
-<wizardpage id="typeSelectorPage" pageid="typeSelector" next="screenshot" label="&typeSelector.heading;" onpageshow="initTypeSelectorPage();">
- <description>&typeSelector.description;</description>
-
- <radiogroup id="typeGroup" oncommand="typeSelectionUpdated();">
- <radio id="typeFalsePositive" value="false positive" label="&typeSelector.falsePositive.label;" accesskey="&typeSelector.falsePositive.accesskey;"/>
- <description class="radioDescription">&typeSelector.falsePositive.description;</description>
- <radio id="typeFalseNegative" value="false negative" label="&typeSelector.falseNegative.label;" accesskey="&typeSelector.falseNegative.accesskey;"/>
- <description class="radioDescription">&typeSelector.falseNegative.description;</description>
- <radio id="typeOther" value="other" label="&typeSelector.other.label;" accesskey="&typeSelector.other.accesskey;"/>
- <description class="radioDescription">&typeSelector.other.description;</description>
- </radiogroup>
-
- <deck id="recentReports" currentIndex="0" flex="1">
- <vbox pack="end">
- <label class="text-link" value="&showRecentReports.label;" onclick="E('recentReports').selectedIndex = 1;"/>
- </vbox>
- <groupbox flex="1">
- <caption label="&recentReports.label;"/>
- <grid flex="1" id="recentReportsList">
- <columns>
- <column flex="2"/>
- <column flex="1"/>
- <column/>
- </columns>
- <rows id="recentReportsRows" onclick="reportsListDataSource.handleClick(event);"/>
- </grid>
-
- <hbox pack="start">
- <button label="&recentReports.clear.label;" accesskey="&recentReports.clear.accesskey;" oncommand="reportsListDataSource.clear();"/>
- </hbox>
- </groupbox>
- </deck>
-</wizardpage>
-
-<wizardpage id="issuesPage" pageid="issues" next="screenshot" onpageshow="initIssuesPage();" reloadButtonLabel="&reloadButton.label;" reloadButtonAccesskey="&reloadButton.accesskey;">
- <description>&issues.description;</description>
-
- <vbox id="issuesBox" flex="1">
- <groupbox id="issuesWhitelistBox" hidden="true">
- <description>&issues.whitelist.description;</description>
- <hbox pack="end">
- <button label="&issues.whitelist.remove.label;" oncommand="issuesDataSource.removeWhitelist();"/>
- </hbox>
- </groupbox>
- <groupbox id="issuesDisabledBox" hidden="true">
- <description>&issues.disabled.description;</description>
- <hbox pack="end">
- <button label="&issues.disabled.enable.label;" oncommand="issuesDataSource.enable();"/>
- </hbox>
- </groupbox>
- <groupbox id="issuesNoFiltersBox" hidden="true">
- <description>&issues.nofilters.description;</description>
- </groupbox>
- <groupbox id="issuesNoSubscriptionsBox" hidden="true">
- <description>&issues.nosubscriptions.description;</description>
- <hbox pack="end">
- <button label="&issues.nosubscriptions.add.label;" oncommand="issuesDataSource.addSubscription();"/>
- </hbox>
- </groupbox>
- <groupbox id="issuesSubscriptionCountBox" hidden="true">
- <description>&issues.subscriptionCount.description;</description>
- <hbox pack="end">
- <button label="&issues.openPreferences.label;" oncommand="Utils.openSettingsDialog();window.close();"/>
- </hbox>
- </groupbox>
- <groupbox id="issuesOwnFiltersBox" hidden="true">
- <description>&issues.ownfilters.description;</description>
- <hbox id="issuesOwnFiltersTemplate" align="center" hidden="true">
- <description flex="1" crop="end"/>
- <button label="&issues.ownfilters.disable.label;" oncommand="issuesDataSource.disableFilter(this.parentNode);"/>
- </hbox>
- <vbox id="issuesOwnFilters"/>
- </groupbox>
- <groupbox id="issuesDisabledSubscriptionsBox" hidden="true">
- <description>&issues.disabledgroups.description;</description>
- <hbox id="issuesDisabledSubscriptionsTemplate" align="center" hidden="true">
- <description flex="1" crop="end"/>
- <button label="&issues.disabledgroups.enable.label;" oncommand="issuesDataSource.enableSubscription(this.parentNode);"/>
- </hbox>
- <vbox id="issuesDisabledSubscriptions"/>
- </groupbox>
- <groupbox id="issuesDisabledFiltersBox" hidden="true">
- <description>&issues.disabledfilters.description;</description>
- <hbox id="issuesDisabledFiltersTemplate" align="center" hidden="true">
- <description flex="1" crop="end"/>
- <button label="&issues.disabledfilters.enable.label;" oncommand="issuesDataSource.enableFilter(this.parentNode);"/>
- </hbox>
- <vbox id="issuesDisabledFilters"/>
- </groupbox>
- </vbox>
-
- <checkbox id="issuesOverride" label="&issues.override.label;" accesskey="&issues.override.accesskey;" oncommand="updateIssuesOverride();"/>
- <description id="issuesChangeMessage" hidden="true">&issues.change.description;</description>
-</wizardpage>
-
-<wizardpage id="typeWarningPage" pageid="typeWarning" next="screenshot" onpageshow="initTypeWarningPage();">
- <description id="typeWarningText">
- &typeWarning.description;
- <label id="typeWarningTextLink" class="text-link" onclick="Utils.loadDocLink('reporter_other_link');"/>
- </description>
-
- <checkbox id="typeWarningOverride" label="&typeWarning.override.label;" accesskey="&typeWarning.override.accesskey;" oncommand="updateTypeWarningOverride();"/>
-</wizardpage>
-
-<wizardpage id="screenshotPage" pageid="screenshot" next="comment" label="&screenshot.heading;" onpageshow="initScreenshotPage();">
- <description>&screenshot.description;</description>
-
- <checkbox id="screenshotCheckbox" checked="true" label="&screenshot.attach.label;" accesskey="&screenshot.attach.accesskey;" oncommand="screenshotDataSource.enabled = this.checked;"/>
- <hbox id="screenshotButtons" pack="end">
- <button id="screenshotMarkButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'mark';" checked="true" label="&screenshot.mark.label;" accesskey="&screenshot.mark.accesskey;"/>
- <button id="screenshotRemoveButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'remove';" label="&screenshot.remove.label;" accesskey="&screenshot.remove.accesskey;"/>
- <button id="screenshotUndoButton" oncommand="screenshotDataSource.undo();" disabled="true" label="&screenshot.undo.label;" accesskey="&screenshot.undo.accesskey;"/>
- </hbox>
- <vbox id="screenshotBox" flex="1">
- <canvas xmlns="http://www.w3.org/1999/xhtml" id="screenshotCanvas" onmousedown="screenshotDataSource.startSelection(event);" onmouseup="screenshotDataSource.stopSelection(event);" onmouseout="screenshotDataSource.stopSelection(event);" onmousemove="screenshotDataSource.updateSelection(event);"/>
- </vbox>
-</wizardpage>
-
-<wizardpage id="commentPage" pageid="comment" next="send" label="&commentPage.heading;" onpageshow="initCommentPage();">
- <description>&commentPage.description;</description>
-
- <label class="topLabel" control="comment" value="&comment.label;" accesskey="&comment.accesskey;"/>
- <textbox id="comment" multiline="true" flex="1" oninput="updateComment();"/>
- <hbox align="baseline">
- <label control="email" value="&email.label;" accesskey="&email.accesskey;"/>
- <textbox id="email" flex="1" maxlength="200" oninput="updateEmail();"/>
- </hbox>
- <description id="commentLengthWarning" visible="false">&comment.lengthWarning;</description>
-
- <checkbox id="extensionsCheckbox" label="&attachExtensions.label;" accesskey="&attachExtensions.accesskey;" oncommand="updateExtensions(this.checked);"/>
-
- <deck id="dataDeck" selectedIndex="0" flex="2">
- <vbox pack="start">
- <label class="text-link" value="&showData.label;" onclick="showDataField();"/>
- </vbox>
- <vbox>
- <label control="data" value="&data.label;" accesskey="&data.accesskey;"/>
- <textbox id="data" readonly="true" multiline="true" wrap="off" flex="1"/>
- </vbox>
- </deck>
-</wizardpage>
-
-<wizardpage id="sendPage" pageid="send" label="&sendPage.heading;" onpageshow="initSendPage();">
- <description id="sendReportMessage">&sendPage.waitMessage;</description>
-
- <vbox id="sendReportErrorBox" align="end" hidden="true">
- <description id="sendReportError" textTemplate="&sendPage.errorMessage;">
- <label id="sendReportErrorLinks" class="text-link" onclick="Utils.loadDocLink('reporter_connect_issue');"/>
- </description>
- <button id="sendRetryButton" label="&sendPage.retry.label;" oncommand="initSendPage();"/>
- </vbox>
-
- <progressmeter id="sendReportProgress" mode="undetermined"/>
-
- <iframe id="result" type="content" flex="1" hidden="true" onclick="processLinkClick(event);"
- confirmationMessage="&sendPage.confirmation;" knownIssueMessage="&sendPage.knownIssue;"/>
-
- <hbox id="copyLinkBox" pack="end" hidden="true">
- <button id="copyLink" disabled="true" label="©Link.label;" accesskey="©Link.accesskey;" oncommand="copyLink(this.getAttribute('url'));"/>
- </hbox>
-</wizardpage>
-
-</wizard>
diff --git a/chrome/content/ui/settings.js b/chrome/content/ui/settings.js
deleted file mode 100644
index 5c8dd84..0000000
--- a/chrome/content/ui/settings.js
+++ /dev/null
@@ -1,3049 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-const altMask = 2;
-const ctrlMask = 4;
-const metaMask = 8;
-
-let accelMask = ctrlMask;
-try {
- let accelKey = Utils.prefService.getIntPref("ui.key.accelKey");
- if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_META)
- accelMask = metaMask;
- else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_ALT)
- accelMask = altMask;
-} catch(e) {}
-
-/**
- * Initialization function, called when the window is loaded.
- */
-function init()
-{
- // Insert Apply button between OK and Cancel
- let okBtn = document.documentElement.getButton("accept");
- let cancelBtn = document.documentElement.getButton("cancel");
- let applyBtn = E("applyButton");
- let insertBefore = cancelBtn;
- for (let sibling = cancelBtn; sibling; sibling = sibling.nextSibling)
- if (sibling == okBtn)
- insertBefore = okBtn;
- insertBefore.parentNode.insertBefore(applyBtn, insertBefore);
- applyBtn.setAttribute("disabled", "true");
- applyBtn.hidden = false;
-
- // Convert menubar into toolbar on Mac OS X
- let isMac = ("@mozilla.org/xre/app-info;1" in Cc && Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS == "Darwin");
- if (isMac)
- {
- function copyAttributes(from, to)
- {
- for (let i = 0; i < from.attributes.length; i++)
- to.setAttribute(from.attributes[i].name, from.attributes[i].value);
- }
-
- let menubar = E("menu");
- let toolbar = document.createElement("toolbar");
- copyAttributes(menubar, toolbar);
-
- for (let menu = menubar.firstChild; menu; menu = menu.nextSibling)
- {
- let button = document.createElement("toolbarbutton");
- copyAttributes(menu, button);
- button.setAttribute("type", "menu");
- while (menu.firstChild)
- button.appendChild(menu.firstChild);
- toolbar.appendChild(button);
- }
-
- menubar.parentNode.replaceChild(toolbar, menubar);
- }
-
- // Copy View menu contents into list header context menu
- let viewMenu = E("view-popup").cloneNode(true);
- let viewContext = E("treecols-context");
- function replaceId(menuItem)
- {
- if (menuItem.id)
- menuItem.id = "context-" + menuItem.id;
- for (let child = menuItem.firstChild; child; child = child.nextSibling)
- replaceId(child);
- }
- while (viewMenu.firstChild)
- {
- replaceId(viewMenu.firstChild);
- viewContext.appendChild(viewMenu.firstChild);
- }
-
- // Install listener
- FilterStorage.addObserver(onFilterStorageChange);
-
- // Capture keypress events - need to get them before the tree does
- E("listStack").addEventListener("keypress", onListKeyPress, true);
-
- // Use our fake browser with the findbar - and prevent default action on Enter key
- E("findbar").browser = fastFindBrowser;
- E("findbar").addEventListener("keypress", function(event)
- {
- // Work-around for bug 490047
- if (event.keyCode == KeyEvent.DOM_VK_RETURN)
- event.preventDefault();
- }, false);
- // Hack to prevent "highlight all" from getting enabled
- E("findbar").toggleHighlight = function() {};
-
- // Initialize tree view
- E("list").view = treeView;
- treeView.setEditor(E("listEditor"), E("listEditorParent"));
-
- // Set the focus to the input field by default
- E("list").focus();
-
- // Execute these actions delayed to work around bug 489881
- Utils.runAsync(function()
- {
- treeView.ensureSelection(0);
-
- let e = document.createEvent("Events");
- e.initEvent("post-load", false, false);
- window.dispatchEvent(e);
- });
-}
-
-/**
- * This should be called from "post-load" event handler to set the address that is
- * supposed to be edited. This will initialize the editor and start the editor delayed
- * (a subsequent call to selectFilter() will prevent the editor from opening).
- * @param {String} location URL of the address to be taken as template of a new filter
- */
-function setLocation(location)
-{
- treeView.editorDummyInit = location;
-}
-
-/**
- * This should be called from "post-load" event handler to select a particular filter
- * in the list. If setLocation() was called before, this will also prevent the editor
- * from opening (though it keeps editor's initial value in case the user opens the editor
- * himself later).
- * @param {Filter} filter filter to be selected
- */
-function selectFilter(filter)
-{
- treeView.selectFilter(getFilterByText(filter.text));
- E("list").focus();
-}
-
-/**
- * Cleanup function to remove observers, called when the window is unloaded.
- */
-function cleanUp()
-{
- FilterStorage.removeObserver(onFilterStorageChange);
-}
-
-/**
- * Map of all subscription wrappers by their download location.
- * @type Object
- */
-let subscriptionWrappers = {__proto__: null};
-
-/**
- * Creates a subscription wrapper that can be modified
- * without affecting the original subscription. The properties
- * _sortedFilters and _description are initialized immediately.
- *
- * @param {Subscription} subscription subscription to be wrapped
- * @return {Subscription} subscription wrapper
- */
-function createSubscriptionWrapper(subscription)
-{
- if (subscription.url in subscriptionWrappers)
- return subscriptionWrappers[subscription.url];
-
- let wrapper =
- {
- __proto__: subscription,
- _isWrapper: true,
- _sortedFilters: subscription.filters,
- _description: getSubscriptionDescription(subscription)
- };
- subscriptionWrappers[subscription.url] = wrapper;
- return wrapper;
-}
-
-/**
- * Retrieves a subscription wrapper by the download location.
- *
- * @param {String} url download location of the subscription
- * @return Subscription subscription wrapper or null for invalid URL
- */
-function getSubscriptionByURL(url)
-{
- if (url in subscriptionWrappers)
- {
- let result = subscriptionWrappers[url];
- if (treeView.subscriptions.indexOf(result) < 0)
- treeView.resortSubscription(result);
- return result;
- }
- else
- {
- let result = Subscription.fromURL(url);
- if (!result || "_isWrapper" in result)
- return result;
-
- result = createSubscriptionWrapper(result);
- result.filters = result.filters.slice();
- for (let i = 0; i < result.filters.length; i++)
- result.filters[i] = getFilterByText(result.filters[i].text);
-
- treeView.resortSubscription(result);
- return result;
- }
-}
-
-/**
- * Map of all filter wrappers by their text representation.
- * @type Object
- */
-let filterWrappers = {__proto__: null};
-
-/**
- * Creates a filter wrapper that can be modified without affecting
- * the original filter.
- *
- * @param {Filter} filter filter to be wrapped
- * @return {Filter} filter wrapper
- */
-function createFilterWrapper(filter)
-{
- if (filter.text in filterWrappers)
- return filterWrappers[filter.text];
-
- let wrapper =
- {
- __proto__: filter,
- _isWrapper: true
- };
- filterWrappers[filter.text] = wrapper;
- return wrapper;
-}
-
-/**
- * Retrieves a filter by its text (might be a filter wrapper).
- *
- * @param {String} text text representation of the filter
- * @return Filter
- */
-function getFilterByText(text)
-{
- if (text in filterWrappers)
- return filterWrappers[text];
- else
- return Filter.fromText(text);
-}
-
-/**
- * Generates the additional rows that should be shown as description
- * of the subscription in the list.
- *
- * @param {Subscription} subscription
- * @return {Array of String}
- */
-function getSubscriptionDescription(subscription)
-{
- let result = [];
-
- if (!(subscription instanceof RegularSubscription))
- return result;
-
- if (subscription instanceof DownloadableSubscription && subscription.upgradeRequired)
- result.push(Utils.getString("subscription_wrong_version").replace(/\?1\?/, subscription.requiredVersion));
-
- if (subscription instanceof DownloadableSubscription)
- result.push(Utils.getString("subscription_source") + " " + subscription.url);
-
- let status = "";
- if (subscription instanceof ExternalSubscription)
- status += Utils.getString("subscription_status_externaldownload");
- else
- status += (subscription.autoDownload ? Utils.getString("subscription_status_autodownload") : Utils.getString("subscription_status_manualdownload"));
-
- status += "; " + Utils.getString("subscription_status_lastdownload") + " ";
- if (Synchronizer.isExecuting(subscription.url))
- status += Utils.getString("subscription_status_lastdownload_inprogress");
- else
- {
- status += (subscription.lastDownload > 0 ? Utils.formatTime(subscription.lastDownload * 1000) : Utils.getString("subscription_status_lastdownload_unknown"));
- if (subscription instanceof DownloadableSubscription && subscription.downloadStatus)
- {
- try {
- status += " (" + Utils.getString(subscription.downloadStatus) + ")";
- } catch (e) {}
- }
- }
-
- result.push(Utils.getString("subscription_status") + " " + status);
- return result;
-}
-
-/**
- * Removes all filters from the list (after a warning).
- */
-function clearList()
-{
- if (Utils.confirm(window, Utils.getString("clearall_warning")))
- treeView.removeUserFilters();
-}
-
-/**
- * Shows a warning and resets hit statistics on the filters if the user confirms.
- * @param {Boolean} resetAll If true, statistics of all filters will be reset. If false, only selected filters will be reset.
- */
-function resetHitCounts(resetAll)
-{
- if (resetAll && Utils.confirm(window, Utils.getString("resethitcounts_warning")))
- FilterStorage.resetHitCounts(null);
- else if (!resetAll && Utils.confirm(window, Utils.getString("resethitcounts_selected_warning")))
- {
- let filters = treeView.getSelectedFilters(false);
- FilterStorage.resetHitCounts(filters.map(function(filter)
- {
- return ("_isWrapper" in filter ? filter.__proto__ : filter);
- }));
- }
-}
-
-/**
- * Gets the default download dir, as used by the browser itself.
- * @return {nsIFile}
- * @see saveDefaultDir()
- */
-function getDefaultDir()
-{
- // Copied from Firefox: getTargetFile() in contentAreaUtils.js
- try
- {
- return Utils.prefService.getComplexValue("browser.download.lastDir", Ci.nsILocalFile);
- }
- catch (e)
- {
- // No default download location. Default to desktop.
- let fileLocator = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
-
- return fileLocator.get("Desk", Ci.nsILocalFile);
- }
-}
-
-/**
- * Saves new default download dir after the user chose a different directory to
- * save his files to.
- * @param {nsIFile} dir
- * @see getDefaultDir()
- */
-function saveDefaultDir(dir)
-{
- // Copied from Firefox: getTargetFile() in contentAreaUtils.js
- try
- {
- Utils.prefService.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, dir);
- } catch(e) {};
-}
-
-/**
- * Adds a set of filters to the list.
- * @param {Array of String} filters
- * @return {Filter} last filter added (or null)
- */
-function addFilters(filters)
-{
- let commentQueue = [];
- let lastAdded = null;
- for each (let text in filters)
- {
- // Don't add checksum comments
- if (/!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(text))
- continue;
-
- text = Filter.normalize(text);
- if (!text)
- continue;
-
- let filter = getFilterByText(text);
- if (filter instanceof CommentFilter)
- commentQueue.push(filter);
- else
- {
- lastAdded = filter;
- let subscription = treeView.addFilter(filter, null, null, true);
- if (subscription && commentQueue.length)
- {
- // Insert comments before the filter that follows them
- for each (let comment in commentQueue)
- treeView.addFilter(comment, subscription, filter, true);
- commentQueue.splice(0, commentQueue.length);
- }
- }
- }
-
- for each (let comment in commentQueue)
- {
- lastAdded = comment;
- treeView.addFilter(comment, null, null, true);
- }
-
- return lastAdded;
-}
-
-/**
- * Lets the user choose a file and reads user-defined filters from this file.
- */
-function importList()
-{
- let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
- picker.init(window, Utils.getString("import_filters_title"), picker.modeOpen);
- picker.appendFilters(picker.filterText);
- picker.appendFilters(picker.filterAll);
-
- let dir = getDefaultDir();
- if (dir)
- picker.displayDirectory = dir;
-
- if (picker.show() != picker.returnCancel)
- {
- saveDefaultDir(picker.file.parent.QueryInterface(Ci.nsILocalFile));
- let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- fileStream.init(picker.file, 0x01, 0444, 0);
-
- let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
- stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- stream = stream.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- let lines = [];
- let line = {value: null};
- while (stream.readLine(line))
- lines.push(Filter.normalize(line.value));
- if (line.value)
- lines.push(Filter.normalize(line.value));
- stream.close();
-
- if (/\[Adblock(?:\s*Plus\s*([\d\.]+)?)?\]/i.test(lines[0]))
- {
- let minVersion = RegExp.$1;
- let warning = "";
- if (minVersion && Utils.versionComparator.compare(minVersion, Utils.addonVersion) > 0)
- warning = Utils.getString("import_filters_wrong_version").replace(/\?1\?/, minVersion) + "\n\n";
-
- let promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
- let flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
- promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1 +
- promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
- let result = promptService.confirmEx(window, Utils.getString("import_filters_title"),
- warning + Utils.getString("import_filters_warning"), flags, Utils.getString("overwrite"),
- null, Utils.getString("append"), null, {});
- if (result == 1)
- return;
-
- if (result == 0)
- treeView.removeUserFilters();
-
- lines.shift();
- addFilters(lines);
- treeView.ensureSelection(0);
- }
- else
- Utils.alert(window, Utils.getString("invalid_filters_file"));
- }
-}
-
-/**
- * Lets the user choose a file and writes user-defined filters into this file.
- */
-function exportList()
-{
- if (!treeView.hasUserFilters())
- return;
-
- let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
- picker.init(window, Utils.getString("export_filters_title"), picker.modeSave);
- picker.defaultExtension = ".txt";
- picker.appendFilters(picker.filterText);
- picker.appendFilters(picker.filterAll);
-
- let dir = getDefaultDir();
- if (dir)
- picker.displayDirectory = dir;
-
- if (picker.show() != picker.returnCancel)
- {
- saveDefaultDir(picker.file.parent.QueryInterface(Ci.nsILocalFile));
- let lineBreak = Utils.getLineBreak();
-
- let list = ["[Adblock]"];
- let minVersion = "0";
- for each (let subscription in treeView.subscriptions)
- {
- if (subscription instanceof SpecialSubscription)
- {
- for each (let filter in subscription.filters)
- {
- // Skip checksums
- if (filter instanceof CommentFilter && /!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(filter.text))
- continue;
-
- list.push(filter.text);
-
- // Find version requirements of this filter
- let filterVersion;
- if (filter instanceof RegExpFilter)
- {
- if (filter.contentType & RegExpFilter.typeMap.DONOTTRACK)
- filterVersion = "1.3.5";
- else if (filter.contentType & RegExpFilter.typeMap.ELEMHIDE)
- filterVersion = "1.2";
- else if (/^(?:@@)?\|\|/.test(filter.text) || (!Filter.regexpRegExp.test(filter.text) && /\^/.test(filter.text)))
- filterVersion = "1.1";
- else if (filter.includeDomains != null || filter.excludeDomains != null)
- filterVersion = "1.0.1";
- else if (filter.thirdParty != null)
- filterVersion = "1.0";
- else if (filter.collapse != null)
- filterVersion = "0.7.5";
- else if (Filter.optionsRegExp.test(filter.text))
- filterVersion = "0.7.1";
- else if (/^(?:@@)?\|/.test(filter.text) || /\|$/.test(filter.text))
- filterVersion = "0.6.1.2";
- else
- filterVersion = "0";
- }
- else if (filter instanceof ElemHideFilter)
- {
- if (filter.excludeDomains != null)
- filterVersion = "1.1";
- else if (/^#([\w\-]+|\*)(?:\(([\w\-]+)\))?$/.test(filter.text))
- filterVersion = "0.6.1";
- else
- filterVersion = "0.7";
- }
- else
- filterVersion = "0";
-
- // Adjust version requirements of the complete filter set
- if (filterVersion != "0" && Utils.versionComparator.compare(minVersion, filterVersion) < 0)
- minVersion = filterVersion;
- }
- }
- }
-
- if (minVersion != "0")
- {
- if (Utils.versionComparator.compare(minVersion, "0.7.1") >= 0)
- list[0] = "[Adblock Plus " + minVersion + "]";
- else
- list[0] = "(Adblock Plus " + minVersion + " or higher required) " + list[0];
- }
-
- list.push("");
-
- // Insert checksum
- let checksum = Utils.generateChecksum(list);
- if (checksum)
- list.splice(1, 0, "! Checksum: " + checksum);
-
- try
- {
- let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
- fileStream.init(picker.file, 0x02 | 0x08 | 0x20, 0644, 0);
-
- let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
- stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
- stream.writeString(list.join(lineBreak));
-
- stream.close();
- }
- catch (e)
- {
- dump("Adblock Plus: error writing to file: " + e + "\n");
- Utils.alert(window, Utils.getString("filters_write_error"));
- }
- }
-}
-
-/**
- * Handles keypress event on the filter list
- */
-function onListKeyPress(/**Event*/ e)
-{
- // Ignore any keys directed to the editor
- if (treeView.isEditing)
- return;
-
- let modifiers = 0;
- if (e.altKey)
- modifiers |= altMask;
- if (e.ctrlKey)
- modifiers |= ctrlMask;
- if (e.metaKey)
- modifiers |= metaMask;
-
- if ((e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER) && modifiers)
- document.documentElement.acceptDialog();
- else if (e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER || e.keyCode == e.DOM_VK_F2)
- {
- e.preventDefault();
- if (editFilter(null))
- e.stopPropagation();
- }
- else if (e.keyCode == e.DOM_VK_DELETE || e.keyCode == e.DOM_VK_BACK_SPACE)
- removeFilters(true);
- else if (e.keyCode == e.DOM_VK_INSERT)
- treeView.startEditor(true);
- else if (e.charCode == e.DOM_VK_SPACE && !E("col-enabled").hidden)
- toggleDisabled();
- else if ((e.keyCode == e.DOM_VK_UP || e.keyCode == e.DOM_VK_DOWN) && modifiers == accelMask)
- {
- if (e.shiftKey)
- treeView.moveSubscription(e.keyCode == e.DOM_VK_UP);
- else
- treeView.moveFilter(e.keyCode == e.DOM_VK_UP);
- e.stopPropagation();
- }
- else if (String.fromCharCode(e.charCode).toLowerCase() == "t" && modifiers == accelMask)
- synchSubscription(false);
-}
-
-/**
- * Handles click event on the filter list
- */
-function onListClick(/**Event*/ e)
-{
- if (e.button != 0)
- return;
-
- let row = {};
- let col = {};
- treeView.boxObject.getCellAt(e.clientX, e.clientY, row, col, {});
-
- if (!col.value || col.value.id != "col-enabled")
- return;
-
- let [subscription, filter] = treeView.getRowInfo(row.value);
- if (subscription && !filter)
- treeView.toggleDisabled([subscription]);
- else if (filter instanceof ActiveFilter)
- treeView.toggleDisabled([filter]);
-}
-
-/**
- * Handles dblclick event on the filter list
- */
-function onListDblClick(/**Event*/ e)
-{
- if (e.button != 0)
- return;
-
- let col = {};
- treeView.boxObject.getCellAt(e.clientX, e.clientY, {}, col, {});
-
- if (col.value && col.value.id == "col-enabled")
- return;
-
- editFilter(null);
-}
-
-/**
- * Handles dragstart event on the filter list
- */
-function onListDragStart(/**Event*/ e)
-{
- treeView.startDrag(treeView.boxObject.getRowAt(e.clientX, e.clientY), e);
-}
-
-/**
- * Handles dragend event on the filter list
- */
-function onListDragEnd(/**Event*/ e)
-{
- treeView.finishDrag();
-}
-
-/**
- * Observer for filter storage changes, calls onFilterChange or onSubscriptionChange
- * @see FilterStorage.addObserver()
- */
-function onFilterStorageChange(/**String*/ action, /**Array*/ items, additionalData)
-{
- if (/^filters (.*)/.test(action))
- onFilterChange(RegExp.$1, items, additionalData);
- else if (/^subscriptions (.*)/.test(action))
- onSubscriptionChange(RegExp.$1, items, additionalData);
-}
-
-/**
- * Filter change observer
- */
-function onFilterChange(/**String*/ action, /**Array of Filter*/ filters, additionalData)
-{
- switch (action)
- {
- case "add":
- // addFilter() won't invalidate if the filter is already there because
- // the subscription didn't create its subscription.filters copy yet,
- // an update batch makes sure that everything is invalidated.
- treeView.boxObject.beginUpdateBatch();
- for each (let filter in filters)
- {
- let insertBefore = (additionalData ? getFilterByText(additionalData.text) : null);
- treeView.addFilter(getFilterByText(filter.text), null, insertBefore, true);
- }
- treeView.boxObject.endUpdateBatch();
- return;
- case "remove":
- // removeFilter() won't invalidate if the filter is already removed because
- // the subscription didn't create its subscription.filters copy yet,
- // an update batch makes sure that everything is invalidated.
- treeView.boxObject.beginUpdateBatch();
- for each (let filter in filters)
- treeView.removeFilter(null, getFilterByText(filter.text));
- treeView.boxObject.endUpdateBatch();
- return;
- case "enable":
- case "disable":
- // Remove existing changes to "disabled" property
- for each (let filter in filters)
- {
- filter = getFilterByText(filter.text);
- if ("_isWrapper" in filter && filter.hasOwnProperty("disabled"))
- delete filter.disabled;
- }
- break;
- case "hit":
- if (E("col-hitcount").hidden && E("col-lasthit").hidden)
- {
- // The data isn't visible, no need to invalidate
- return;
- }
- break;
- default:
- return;
- }
-
- if (filters.length == 1)
- treeView.invalidateFilter(getFilterByText(filters[0].text));
- else
- treeView.boxObject.invalidate();
-}
-
-/**
- * Subscription change observer
- */
-function onSubscriptionChange(/**String*/ action, /**Array of Subscription*/ subscriptions)
-{
- for each (let subscription in subscriptions)
- {
- subscription = getSubscriptionByURL(subscription.url);
- switch (action)
- {
- case "add":
- treeView.addSubscription(subscription, true);
- break;
- case "remove":
- treeView.removeSubscription(subscription);
- break;
- case "enable":
- case "disable":
- // Remove existing changes to "disabled" property
- delete subscription.disabled;
- treeView.invalidateSubscription(subscription);
- break;
- case "update":
- if ("oldSubscription" in subscription)
- {
- treeView.removeSubscription(getSubscriptionByURL(subscription.oldSubscription.url));
- delete subscriptionWrappers[subscription.oldSubscription.url];
- if (treeView.subscriptions.indexOf(subscription) < 0)
- {
- treeView.addSubscription(subscription, true);
- break;
- }
- }
- let oldCount = treeView.getSubscriptionRowCount(subscription);
-
- delete subscription.filters;
- subscription.filters = subscription.filters.map(function(filter)
- {
- return getFilterByText(filter.text);
- });
-
- treeView.resortSubscription(subscription);
- treeView.invalidateSubscription(subscription, oldCount);
- break;
- case "updateinfo":
- if ("oldSubscription" in subscription)
- {
- treeView.removeSubscription(getSubscriptionByURL(subscription.oldSubscription.url));
- delete subscriptionWrappers[subscription.oldSubscription.url];
- if (treeView.subscriptions.indexOf(subscription) < 0)
- {
- treeView.addSubscription(subscription, true);
- break;
- }
- }
- treeView.invalidateSubscriptionInfo(subscription);
- break;
- }
- }
-
- // Date.toLocaleFormat() doesn't handle Unicode properly if called directly from XPCOM (bug 441370)
- setTimeout(function()
- {
- for each (let subscription in subscriptions)
- {
- subscription = getSubscriptionByURL(subscription.url);
- treeView.invalidateSubscriptionInfo(subscription);
- }
- }, 0);
-}
-
-/**
- * Starts editor for filter or subscription.
- * @param {String} type "filter", "subscription" or null (any)
- */
-function editFilter(type) /**Boolean*/
-{
- let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
- if (!filter && !type)
- {
- // Don't do anything for group titles unless we were explicitly told what to do
- return false;
- }
-
- if (type != "filter" && subscription instanceof RegularSubscription)
- editSubscription(subscription);
- else
- treeView.startEditor(false);
-
- return true;
-}
-
-/**
- * Starts editor for a given subscription (pass null to add a new subscription).
- */
-function editSubscription(/**Subscription*/ subscription)
-{
- let hasSubscription = function(url) treeView.subscriptions.indexOf(getSubscriptionByURL(url)) >= 0;
- let result = {};
- openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", subscription, result, hasSubscription);
-
- if (!("url" in result))
- return;
-
- let subscriptionResults = [[result.url, result.title]];
- if ("mainSubscriptionURL" in result)
- subscriptionResults.push([result.mainSubscriptionURL, result.mainSubscriptionTitle]);
-
- let changed = false;
- for each (let [url, title] in subscriptionResults)
- {
- let newSubscription = getSubscriptionByURL(url);
- if (!newSubscription)
- continue;
-
- changed = true;
- if (subscription && subscription != newSubscription)
- treeView.removeSubscription(subscription);
-
- treeView.addSubscription(newSubscription);
-
- newSubscription.title = title;
- newSubscription.disabled = result.disabled;
- newSubscription.autoDownload = result.autoDownload;
-
- treeView.invalidateSubscriptionInfo(newSubscription);
-
- if (newSubscription instanceof DownloadableSubscription && !newSubscription.lastDownload)
- Synchronizer.execute(newSubscription.__proto__, false);
- }
-
- if (changed)
- onChange();
-}
-
-/**
- * Removes the selected entries from the list and sets selection to the
- * next item.
- * @param {Boolean} allowSubscriptions if true, a subscription will be
- * removed if no removable filters are selected
- */
-function removeFilters(allowSubscriptions)
-{
- // Retrieve selected items
- let selected = treeView.getSelectedInfo(false);
-
- let found = false;
- for each (let [subscription, filter] in selected)
- {
- if (subscription instanceof SpecialSubscription && filter instanceof Filter)
- {
- treeView.removeFilter(subscription, filter);
- found = true;
- }
- }
-
- if (found)
- return;
-
- if (allowSubscriptions)
- {
- // No removable filters found, maybe we can remove a subscription?
- let selectedSubscription = null;
- for each (let [subscription, filter] in selected)
- {
- if (!selectedSubscription)
- selectedSubscription = subscription;
- else if (selectedSubscription != subscription)
- return;
- }
-
- if (selectedSubscription && selectedSubscription instanceof RegularSubscription && Utils.confirm(window, Utils.getString("remove_subscription_warning")))
- treeView.removeSubscription(selectedSubscription);
- }
-}
-
-/**
- * Enables or disables selected filters or the selected subscription
- */
-function toggleDisabled()
-{
- // Look for selected filters first
- let selected = treeView.getSelectedFilters(true).filter(function(filter)
- {
- return filter instanceof ActiveFilter;
- });
-
- if (selected.length)
- treeView.toggleDisabled(selected);
- else
- {
- // No filters selected, maybe a subscription?
- let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
- if (subscription && !filter)
- treeView.toggleDisabled([subscription]);
- }
-}
-
-/**
- * Copies selected filters to clipboard.
- */
-function copyToClipboard()
-{
- let selected = treeView.getSelectedFilters(false);
- if (!selected.length)
- return;
-
- let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
- let lineBreak = Utils.getLineBreak();
- clipboardHelper.copyString(selected.map(function(filter)
- {
- return filter.text;
- }).join(lineBreak) + lineBreak);
-}
-
-/**
- * Pastes text as list of filters from clipboard
- */
-function pasteFromClipboard() {
- let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
- let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
- transferable.addDataFlavor("text/unicode");
-
- try {
- clipboard.getData(transferable, clipboard.kGlobalClipboard);
- }
- catch (e) {
- return;
- }
-
- let data = {};
- transferable.getTransferData("text/unicode", data, {});
-
- try {
- data = data.value.QueryInterface(Ci.nsISupportsString).data;
- }
- catch (e) {
- return;
- }
-
- let lastAdded = addFilters(data.split(/[\r\n]+/));
- if (lastAdded)
- treeView.selectFilter(lastAdded);
-}
-
-/**
- * Starts synchronization of the currently selected subscription
- */
-function synchSubscription()
-{
- let [subscription, filter] = treeView.getRowInfo(treeView.selection.currentIndex);
- if (subscription instanceof DownloadableSubscription)
- Synchronizer.execute(subscription.__proto__, true, true);
-}
-
-/**
- * Starts synchronization for all subscriptions
- */
-function synchAllSubscriptions()
-{
- for each (let subscription in treeView.subscriptions)
- if (subscription instanceof DownloadableSubscription)
- Synchronizer.execute(subscription.__proto__, true, true);
-}
-
-/**
- * Updates the contents of the Filters menu, making sure the right
- * items are checked/enabled.
- */
-function fillFiltersPopup()
-{
- let empty = !treeView.hasUserFilters();
- E("export-command").setAttribute("disabled", empty);
- E("clearall").setAttribute("disabled", empty);
-}
-
-/**
- * Updates the contents of the View menu, making sure the right
- * items are checked/enabled.
- */
-function fillViewPopup(/**String*/prefix)
-{
- E(prefix + "view-filter").setAttribute("checked", !E("col-filter").hidden);
- E(prefix + "view-slow").setAttribute("checked", !E("col-slow").hidden);
- E(prefix + "view-enabled").setAttribute("checked", !E("col-enabled").hidden);
- E(prefix + "view-hitcount").setAttribute("checked", !E("col-hitcount").hidden);
- E(prefix + "view-lasthit").setAttribute("checked", !E("col-lasthit").hidden);
-
- let sortColumn = treeView.sortColumn;
- let sortColumnID = (sortColumn ? sortColumn.id : null);
- let sortDir = (sortColumn ? sortColumn.getAttribute("sortDirection") : "natural");
- E(prefix + "sort-none").setAttribute("checked", sortColumn == null);
- E(prefix + "sort-filter").setAttribute("checked", sortColumnID == "col-filter");
- E(prefix + "sort-enabled").setAttribute("checked", sortColumnID == "col-enabled");
- E(prefix + "sort-hitcount").setAttribute("checked", sortColumnID == "col-hitcount");
- E(prefix + "sort-lasthit").setAttribute("checked", sortColumnID == "col-lasthit");
- E(prefix + "sort-asc").setAttribute("checked", sortDir == "ascending");
- E(prefix + "sort-desc").setAttribute("checked", sortDir == "descending");
-}
-
-/**
- * Toggles visibility of a column.
- * @param {String} col ID of the column to made visible/invisible
- */
-function toggleColumn(col)
-{
- col = E(col);
- col.setAttribute("hidden", col.hidden ? "false" : "true");
-}
-
-/**
- * Switches list sorting to the specified column. Sort order is kept.
- * @param {String} col ID of the column to sort by or null for unsorted
- */
-function sortBy(col)
-{
- if (col)
- treeView.resort(E(col), treeView.sortColumn ? treeView.sortColumn.getAttribute("sortDirection") : "ascending");
- else
- treeView.resort(null, "natural");
-}
-
-/**
- * Changes sort order of the list. Sorts by filter column if the list is unsorted.
- * @param {String} order either "ascending" or "descending"
- */
-function setSortOrder(order)
-{
- let col = treeView.sortColumn || E("col-filter");
- treeView.resort(col, order);
-}
-
-/**
- * Updates the contents of the Options menu, making sure the right
- * items are checked/enabled.
- */
-function fillOptionsPopup()
-{
- E("abp-enabled").setAttribute("checked", Prefs.enabled);
- E("frameobjects").setAttribute("checked", Prefs.frameobjects);
- E("slowcollapse").setAttribute("checked", !Prefs.fastcollapse);
- E("showintoolbar").setAttribute("checked", Prefs.showintoolbar);
- E("showinstatusbar").setAttribute("checked", Prefs.showinstatusbar);
-
- let syncEngine = Sync.getEngine();
- E("sync").hidden = !syncEngine;
- E("sync").setAttribute("checked", syncEngine && syncEngine.enabled);
-}
-
-/**
- * Updates the state of copy/paste commands whenever selection changes.
- */
-function updateCommands()
-{
- // Retrieve selected items
- let selected = treeView.getSelectedInfo(true);
-
- // Check whether all selected items belong to the same subscription
- let selectedSubscription = null;
- for each (let [subscription, filter] in selected)
- {
- if (!selectedSubscription)
- selectedSubscription = subscription;
- else if (subscription != selectedSubscription)
- {
- // More than one subscription selected, ignoring it
- selectedSubscription = null;
- break;
- }
- }
-
- // Check whether any filters have been selected and whether any of them can be removed
- let hasFilters = selected.some(function([subscription, filter]) filter instanceof Filter);
- let hasRemovable = selected.some(function([subscription, filter]) subscription instanceof SpecialSubscription && filter instanceof Filter);
-
- // Check whether clipboard contains text
- let clipboard = Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
- let hasFlavour = clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard);
-
- E("copy-command").setAttribute("disabled", !hasFilters);
- E("cut-command").setAttribute("disabled", !hasRemovable);
- E("paste-command").setAttribute("disabled", !hasFlavour);
- E("remove-command").setAttribute("disabled", !(hasRemovable || selectedSubscription instanceof RegularSubscription));
-}
-
-/**
- * Updates the contents of the context menu, making sure the right
- * items are checked/enabled.
- */
-function fillContext()
-{
- // Retrieve selected items
- let selected = treeView.getSelectedInfo(true);
-
- let currentSubscription = null;
- let currentFilter = null;
- if (selected.length)
- [currentSubscription, currentFilter] = selected[0];
-
- // Check whether all selected items belong to the same subscription
- let selectedSubscription = null;
- for each (let [subscription, filter] in selected)
- {
- if (!selectedSubscription)
- selectedSubscription = subscription;
- else if (subscription != selectedSubscription)
- {
- // More than one subscription selected, ignoring it
- selectedSubscription = null;
- break;
- }
- }
-
- // Check whether any filters have been selected and which filters can be enabled/disabled
- let hasFilters = selected.some(function([subscription, filter]) filter instanceof Filter);
- let activeFilters = selected.filter(function([subscription, filter]) filter instanceof ActiveFilter);
-
- if (selectedSubscription instanceof RegularSubscription)
- {
- E("context-editsubscription").hidden = false;
- E("context-edit").hidden = true;
- }
- else
- {
- E("context-editsubscription").hidden = true;
- E("context-edit").hidden = false;
- E("context-edit").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter));
- }
-
- E("context-synchsubscription").setAttribute("disabled", !(selectedSubscription instanceof DownloadableSubscription));
- E("context-resethitcount").setAttribute("disabled", !hasFilters);
-
- E("context-moveup").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter && !treeView.isSorted() && currentSubscription._sortedFilters.indexOf(currentFilter) > 0));
- E("context-movedown").setAttribute("disabled", !(currentSubscription instanceof SpecialSubscription && currentFilter instanceof Filter && !treeView.isSorted() && currentSubscription._sortedFilters.indexOf(currentFilter) < currentSubscription._sortedFilters.length - 1));
-
- E("context-movegroupup").setAttribute("disabled", !selectedSubscription || treeView.isFirstSubscription(selectedSubscription));
- E("context-movegroupdown").setAttribute("disabled", !selectedSubscription || treeView.isLastSubscription(selectedSubscription));
-
- if (activeFilters.length || (selectedSubscription && !currentFilter))
- {
- let current = activeFilters.length ? activeFilters[0][1] : selectedSubscription;
- E("context-enable").hidden = !current.disabled;
- E("context-disable").hidden = current.disabled;
- E("context-disable").setAttribute("disabled", "false");
- }
- else
- {
- E("context-enable").hidden = true;
- E("context-disable").hidden = false;
- E("context-disable").setAttribute("disabled", "true");
- }
-
- return true;
-}
-
-/**
- * Toggles the value of a boolean preference.
- * @param {String} pref preference name (Prefs object property)
- */
-function togglePref(pref)
-{
- Prefs[pref] = !Prefs[pref];
-}
-
-/**
- * Toggles the pref for the Adblock Plus sync engine.
- */
-function toggleSync()
-{
- let syncEngine = Sync.getEngine();
- syncEngine.enabled = !syncEngine.enabled;
-}
-
-/**
- * Applies filter list changes.
- */
-function applyChanges()
-{
- treeView.applyChanges();
- E("applyButton").setAttribute("disabled", "true");
-}
-
-/**
- * Checks whether a tooltip should be shown and sets tooltip text appropriately
- */
-function showTreeTooltip(/**Event*/ event) /**Boolean*/
-{
- let col = {};
- let row = {};
- let childElement = {};
- treeView.boxObject.getCellAt(event.clientX, event.clientY, row, col, childElement);
-
- let [subscription, filter] = treeView.getRowInfo(row.value);
- if (row.value && col.value && col.value.id == "col-slow" && treeView.getCellText(row.value, col.value))
- {
- E("tree-tooltip").setAttribute("label", Utils.getString("filter_regexp_tooltip"));
- return true;
- }
-
- if (filter instanceof InvalidFilter && filter.reason)
- {
- E("tree-tooltip").setAttribute("label", filter.reason);
- return true;
- }
-
- if (row.value && col.value && treeView.boxObject.isCellCropped(row.value, col.value))
- {
- let text = treeView.getCellText(row.value, col.value);
- if (text)
- {
- E("tree-tooltip").setAttribute("label", text);
- return true;
- }
- }
-
- return false;
-}
-
-/**
- * Opens About Adblock Plus dialog
- */
-function openAbout()
-{
- openDialog("about.xul", "_blank", "chrome,centerscreen,modal");
-}
-
-/**
- * Should be called after each change to the filter list that needs applying later
- */
-function onChange() {
- E("applyButton").removeAttribute("disabled");
-}
-
-/**
- * Sort function for the filter list, compares two filters by their text
- * representation.
- */
-function compareText(/**Filter*/ filter1, /**Filter*/ filter2)
-{
- if (filter1.text < filter2.text)
- return -1;
- else if (filter1.text > filter2.text)
- return 1;
- else
- return 0;
-}
-
-/**
- * Sort function for the filter list, compares two filters by "slow"
- * marker.
- */
-function compareSlow(/**Filter*/ filter1, /**Filter*/ filter2)
-{
- let isSlow1 = filter1 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter1);
- let isSlow2 = filter2 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter2);
- return isSlow1 - isSlow2;
-}
-
-/**
- * Sort function for the filter list, compares two filters by "enabled"
- * state.
- */
-function compareEnabled(/**Filter*/ filter1, /**Filter*/ filter2)
-{
- let hasEnabled1 = (filter1 instanceof ActiveFilter ? 1 : 0);
- let hasEnabled2 = (filter2 instanceof ActiveFilter ? 1 : 0);
- if (hasEnabled1 != hasEnabled2)
- return hasEnabled1 - hasEnabled2;
- else if (hasEnabled1 && filter1.disabled != filter2.disabled)
- return (filter1.disabled ? -1 : 1);
- else
- return 0;
-}
-
-/**
- * Sort function for the filter list, compares two filters by their hit count.
- */
-function compareHitCount(/**Filter*/ filter1, /**Filter*/ filter2)
-{
- let hasHitCount1 = (filter1 instanceof ActiveFilter ? 1 : 0);
- let hasHitCount2 = (filter2 instanceof ActiveFilter ? 1 : 0);
- if (hasHitCount1 != hasHitCount2)
- return hasHitCount1 - hasHitCount2;
- else if (hasHitCount1)
- return filter1.hitCount - filter2.hitCount;
- else
- return 0;
-}
-
-/**
- * Sort function for the filter list, compares two filters by their last hit.
- */
-function compareLastHit(/**Filter*/ filter1, /**Filter*/ filter2)
-{
- let hasLastHit1 = (filter1 instanceof ActiveFilter ? 1 : 0);
- let hasLastHit2 = (filter2 instanceof ActiveFilter ? 1 : 0);
- if (hasLastHit1 != hasLastHit2)
- return hasLastHit1 - hasLastHit2;
- else if (hasLastHit1)
- return filter1.lastHit - filter2.lastHit;
- else
- return 0;
-}
-
-/**
- * Creates a sort function from a primary and a secondary comparison function.
- * @param {Function} cmpFunc comparison function to be called first
- * @param {Function} fallbackFunc (optional) comparison function to be called if primary function returns 0
- * @param {Boolean} desc if true, the result of the primary function (not the secondary function) will be reversed - sorting in descending order
- * @result {Function} comparison function to be used
- */
-function createSortFunction(cmpFunc, fallbackFunc, desc)
-{
- let factor = (desc ? -1 : 1);
-
- return function(filter1, filter2)
- {
- // Comment replacements without prototype always go last
- let isLast1 = (filter1.__proto__ == null);
- let isLast2 = (filter2.__proto__ == null);
- if (isLast1)
- return (isLast2 ? 0 : 1)
- else if (isLast2)
- return -1;
-
- let ret = cmpFunc(filter1, filter2);
- if (ret == 0 && fallbackFunc)
- return fallbackFunc(filter1, filter2);
- else
- return factor * ret;
- }
-}
-
-const nsITreeView = Ci.nsITreeView;
-
-/**
- * nsITreeView implementation used for the filters list.
- * @class
- */
-let treeView = {
- //
- // nsISupports implementation
- //
-
- QueryInterface: function(uuid) {
- if (!uuid.equals(Ci.nsISupports) &&
- !uuid.equals(Ci.nsITreeView))
- {
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
-
- return this;
- },
-
- //
- // nsITreeView implementation
- //
-
- setTree: function(boxObject)
- {
- if (!boxObject)
- return;
-
- this.boxObject = boxObject;
-
- let stringAtoms = ["col-filter", "col-enabled", "col-hitcount", "col-lasthit", "type-comment", "type-filterlist", "type-whitelist", "type-elemhide", "type-invalid"];
- let boolAtoms = ["selected", "dummy", "subscription", "description", "filter", "filter-regexp", "subscription-special", "subscription-external", "subscription-autoDownload", "subscription-disabled", "subscription-upgradeRequired", "subscription-dummy", "filter-disabled"];
- let atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService);
-
- this.atoms = {};
- for each (let atom in stringAtoms)
- this.atoms[atom] = atomService.getAtom(atom);
- for each (let atom in boolAtoms)
- {
- this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true");
- this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false");
- }
-
- // Copy the subscription list, we don't want to apply our changes immediately
- this.subscriptions = FilterStorage.subscriptions.map(createSubscriptionWrapper);
-
- this.closed = {__proto__: null};
- let closed = this.boxObject.treeBody.parentNode.getAttribute("closedSubscriptions");
- if (closed)
- for each (let id in closed.split(" "))
- if (id in FilterStorage.knownSubscriptions)
- this.closed[id] = true;
-
- // Check current sort direction
- let cols = document.getElementsByTagName("treecol");
- let sortColumn = null;
- let sortDir = null;
- for (let i = 0; i < cols.length; i++)
- {
- let col = cols[i];
- let dir = col.getAttribute("sortDirection");
- if (dir && dir != "natural")
- {
- sortColumn = col;
- sortDir = dir;
- }
- }
-
- if (sortColumn)
- this.resort(sortColumn, sortDir);
-
- // Make sure we stop the editor when scrolling or resizing window
- let me = this;
- this.boxObject.treeBody.addEventListener("DOMMouseScroll", function()
- {
- me.stopEditor(true);
- }, false);
- window.addEventListener("resize", function()
- {
- me.stopEditor(true);
- }, false);
- },
-
- get rowCount()
- {
- let count = 0;
- for each (let subscription in this.subscriptions)
- {
- // Special subscriptions are only shown if they aren't empty
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- continue;
-
- count++;
- if (!(subscription.url in this.closed))
- count += subscription._description.length + subscription._sortedFilters.length;
- }
-
- return count;
- },
-
- getCellText: function(row, col)
- {
- col = col.id;
-
- // Only three columns have text
- if (col != "col-filter" && col != "col-slow" && col != "col-hitcount" && col != "col-lasthit")
- return null;
-
- // Don't show text in the edited row
- if (col == "col-filter" && this.editedRow == row)
- return null;
-
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription)
- return null;
-
- if (filter instanceof Filter)
- {
- if (col == "col-filter")
- return filter.text;
- else if (col == "col-slow")
- return (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter) ? "!" : null);
- else if (filter instanceof ActiveFilter)
- {
- if (col == "col-hitcount")
- return filter.hitCount;
- else
- return (filter.lastHit ? Utils.formatTime(filter.lastHit) : null);
- }
- else
- return null;
- }
- else if (col != "col-filter")
- return null;
- else if (!filter)
- return (subscription instanceof RegularSubscription ? this.titlePrefix : "") + subscription.title;
- else
- return filter;
- },
-
- getColumnProperties: function(col, properties)
- {
- col = col.id;
-
- if (col in this.atoms)
- properties.AppendElement(this.atoms[col]);
- },
-
- getRowProperties: function(row, properties)
- {
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription)
- return;
-
- properties.AppendElement(this.atoms["selected-" + this.selection.isSelected(row)]);
- properties.AppendElement(this.atoms["subscription-" + !filter]);
- properties.AppendElement(this.atoms["filter-" + (filter instanceof Filter)]);
- properties.AppendElement(this.atoms["filter-regexp-" + (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter))]);
- properties.AppendElement(this.atoms["description-" + (typeof filter == "string")]);
- properties.AppendElement(this.atoms["subscription-special-" + (subscription instanceof SpecialSubscription)]);
- properties.AppendElement(this.atoms["subscription-external-" + (subscription instanceof ExternalSubscription)]);
- properties.AppendElement(this.atoms["subscription-autoDownload-" + (subscription instanceof DownloadableSubscription && subscription.autoDownload)]);
- properties.AppendElement(this.atoms["subscription-disabled-" + subscription.disabled]);
- properties.AppendElement(this.atoms["subscription-upgradeRequired-" + (subscription instanceof DownloadableSubscription && subscription.upgradeRequired)]);
- properties.AppendElement(this.atoms["subscription-dummy-" + (subscription instanceof Subscription && subscription.url == "~dummy~")]);
- if (filter instanceof Filter)
- {
- if (filter instanceof ActiveFilter)
- properties.AppendElement(this.atoms["filter-disabled-" + filter.disabled]);
-
- if (filter instanceof CommentFilter)
- properties.AppendElement(this.atoms["type-comment"]);
- else if (filter instanceof BlockingFilter)
- properties.AppendElement(this.atoms["type-filterlist"]);
- else if (filter instanceof WhitelistFilter)
- properties.AppendElement(this.atoms["type-whitelist"]);
- else if (filter instanceof ElemHideFilter)
- properties.AppendElement(this.atoms["type-elemhide"]);
- else if (filter instanceof InvalidFilter)
- properties.AppendElement(this.atoms["type-invalid"]);
- }
- },
-
- getCellProperties: function(row, col, properties)
- {
- this.getColumnProperties(col, properties);
- this.getRowProperties(row, properties);
- },
-
- isContainer: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- return subscription && !filter;
- },
-
- isContainerOpen: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- return subscription && !filter && !(subscription.url in this.closed);
- },
-
- isContainerEmpty: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- return subscription && !filter && subscription._description.length + subscription._sortedFilters.length == 0;
- },
-
- getLevel: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- return (filter ? 1 : 0);
- },
-
- getParentIndex: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- return (subscription && filter ? this.getSubscriptionRow(subscription) : -1);
- },
-
- hasNextSibling: function(row, afterRow)
- {
- let [subscription, filter] = this.getRowInfo(row);
- if (!filter)
- return false;
-
- let startIndex = this.getSubscriptionRow(subscription);
- if (startIndex < 0)
- return false;
-
- return (startIndex + subscription._description.length + subscription._sortedFilters.length > afterRow);
- },
-
- toggleOpenState: function(row)
- {
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription || filter)
- return;
-
- let count = subscription._description.length + subscription._sortedFilters.length;
- if (subscription.url in this.closed)
- {
- delete this.closed[subscription.url];
- this.boxObject.rowCountChanged(row + 1, count);
- }
- else
- {
- this.closed[subscription.url] = true;
- this.boxObject.rowCountChanged(row + 1, -count);
- }
- this.boxObject.invalidateRow(row);
-
- // Update closedSubscriptions attribute so that the state persists
- let closed = [];
- for (let url in this.closed)
- closed.push(url);
- this.boxObject.treeBody.parentNode.setAttribute("closedSubscriptions", closed.join(" "));
- },
-
- cycleHeader: function(col)
- {
- col = col.element;
-
- let cycle =
- {
- natural: 'ascending',
- ascending: 'descending',
- descending: 'natural'
- };
-
- let curDirection = "natural";
- if (this.sortColumn == col)
- curDirection = col.getAttribute("sortDirection");
- else if (this.sortColumn)
- this.sortColumn.removeAttribute("sortDirection");
-
- this.resort(col, cycle[curDirection]);
- },
-
- isSorted: function()
- {
- return (this.sortProc != null);
- },
-
- canDrop: function(row, orientation)
- {
- if (!this.dragSubscription || orientation == nsITreeView.DROP_ON)
- return false;
-
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription)
- return false;
-
- if (this.dragFilter)
- {
- // Dragging a filter
- return filter && subscription instanceof SpecialSubscription && subscription.isFilterAllowed(this.dragFilter);
- }
- else
- {
- // Dragging a subscription
- return true;
- }
- },
-
- drop: function(row, orientation)
- {
- if (!this.dragSubscription || orientation == nsITreeView.DROP_ON)
- return;
-
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription)
- return;
-
- if (this.dragFilter)
- {
- // Dragging a filter
- if (!(filter && subscription instanceof SpecialSubscription && subscription.isFilterAllowed(this.dragFilter)))
- return;
-
- let oldSubscription = this.dragSubscription;
- let oldSortedIndex = oldSubscription._sortedFilters.indexOf(this.dragFilter);
- let newSortedIndex = subscription._sortedFilters.indexOf(filter);
- if (oldSortedIndex < 0 || newSortedIndex < 0)
- return;
- if (orientation == nsITreeView.DROP_AFTER)
- newSortedIndex++;
-
- let oldIndex = (oldSubscription.filters == oldSubscription._sortedFilters ? oldSortedIndex : oldSubscription.filters.indexOf(this.dragFilter));
- let newIndex = (subscription.filters == subscription._sortedFilters || newSortedIndex >= subscription._sortedFilters.length ? newSortedIndex : subscription.filters.indexOf(subscription._sortedFilters[newSortedIndex]));
- if (oldIndex < 0 || newIndex < 0)
- return;
- if (oldSubscription == subscription && (newIndex == oldIndex || newIndex == oldIndex + 1))
- return;
-
- {
- if (!oldSubscription.hasOwnProperty("filters"))
- oldSubscription.filters = oldSubscription.filters.slice();
-
- let rowCountBefore = treeView.getSubscriptionRowCount(oldSubscription);
- let row = treeView.getSubscriptionRow(oldSubscription) + rowCountBefore - oldSubscription._sortedFilters.length + oldSortedIndex;
- oldSubscription.filters.splice(oldIndex, 1);
- this.resortSubscription(oldSubscription);
- let rowCountAfter = treeView.getSubscriptionRowCount(oldSubscription);
- this.boxObject.rowCountChanged(row + 1 + rowCountAfter - rowCountBefore, rowCountAfter - rowCountBefore);
- }
-
- if (oldSubscription == subscription && newSortedIndex > oldSortedIndex)
- newSortedIndex--;
- if (oldSubscription == subscription && newIndex > oldIndex)
- newIndex--;
-
- {
- if (!subscription.hasOwnProperty("filters"))
- subscription.filters = subscription.filters.slice();
-
- let rowCountBefore = treeView.getSubscriptionRowCount(subscription);
- subscription.filters.splice(newIndex, 0, this.dragFilter);
- this.resortSubscription(subscription);
- let rowCountAfter = treeView.getSubscriptionRowCount(subscription);
- let row = treeView.getSubscriptionRow(subscription) + rowCountAfter - subscription._sortedFilters.length + newSortedIndex;
- this.boxObject.rowCountChanged(row + 1 + rowCountBefore - rowCountAfter, rowCountAfter - rowCountBefore);
-
- treeView.selectRow(row);
- }
- }
- else
- {
- // Dragging a subscription
- if (subscription == this.dragSubscription)
- return;
-
- let rowCount = this.getSubscriptionRowCount(this.dragSubscription);
-
- let oldIndex = this.subscriptions.indexOf(this.dragSubscription);
- let newIndex = this.subscriptions.indexOf(subscription);
- if (oldIndex < 0 || newIndex < 0)
- return;
-
- if (filter && oldIndex > newIndex)
- orientation = nsITreeView.DROP_BEFORE;
- else if (filter)
- orientation = nsITreeView.DROP_AFTER;
-
- let oldRow = this.getSubscriptionRow(this.dragSubscription);
- this.subscriptions.splice(oldIndex, 1);
- this.boxObject.rowCountChanged(oldRow, -rowCount);
-
- if (orientation == nsITreeView.DROP_AFTER)
- newIndex++;
- if (oldIndex < newIndex)
- newIndex--;
-
- this.subscriptions.splice(newIndex, 0, this.dragSubscription);
- let newRow = this.getSubscriptionRow(this.dragSubscription);
- this.boxObject.rowCountChanged(newRow, rowCount);
-
- treeView.selectRow(newRow);
- }
-
- onChange();
- },
-
- getCellValue: function() {return null},
- getProgressMode: function() {return null},
- getImageSrc: function() {return null},
- isSeparator: function() {return false},
- isEditable: function() {return false},
- cycleCell: function() {},
- performAction: function() {},
- performActionOnRow: function() {},
- performActionOnCell: function() {},
- selection: null,
- selectionChanged: function() {},
-
- //
- // Custom properties and methods
- //
-
- /**
- * List of subscriptions displayed
- * @type Array of Subscription
- */
- subscriptions: null,
-
- /**
- * Box object of the tree
- * @type nsITreeBoxObject
- */
- boxObject: null,
-
- /**
- * Map containing URLs of subscriptions that are displayed collapsed
- * @type Object
- */
- closed: null,
-
- /**
- * String to be displayed before the title of regular subscriptions
- * @type String
- * @const
- */
- titlePrefix: Utils.getString("subscription_description") + " ",
-
- /**
- * Map of atoms being used as col/row/cell properties, String => nsIAtom
- * @type Object
- */
- atoms: null,
-
- /**
- * Column by which the list is sorted or null for natural order
- * @type Element
- */
- sortColumn: null,
-
- /**
- * Comparison function used to sort the list or null for natural order
- * @type Function
- */
- sortProc: null,
-
- /**
- * Returns the first row of a subscription in the list or -1 if the
- * subscription isn't in the list or isn't visible.
- */
- getSubscriptionRow: function(/**Subscription*/ search) /**Integer*/
- {
- let index = 0;
- for each (let subscription in this.subscriptions)
- {
- let rowCount = this.getSubscriptionRowCount(subscription);
- if (rowCount > 0 && search == subscription)
- return index;
-
- index += rowCount;
- }
- return -1;
- },
-
- /**
- * Returns the number of rows used to display the subscription in the list.
- */
- getSubscriptionRowCount: function(/**Subscription*/ subscription) /**Integer*/
- {
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- return 0;
-
- if (subscription.url in this.closed)
- return 1;
-
- return 1 + subscription._description.length + subscription._sortedFilters.length;
- },
-
- /**
- * Returns the filter displayed in the given row and the corresponding filter subscription.
- * @param {Integer} row row index
- * @return {Array} array with two elements indicating the contents of the row:
- * [null, null] - empty row
- * [Subscription, null] - subscription title row
- * [Subscription, String] - subscription description row (row text is second array element)
- * [Subscription, Filter] - filter from the given subscription
- */
- getRowInfo: function(row)
- {
- for each (let subscription in this.subscriptions)
- {
- // Special subscriptions are only shown if they aren't empty
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- continue;
-
- // Check whether the subscription row has been requested
- row--;
- if (row < 0)
- return [subscription, null];
-
- if (!(subscription.url in this.closed))
- {
- // Check whether the subscription description row has been requested
- if (row < subscription._description.length)
- return [subscription, subscription._description[row]];
-
- row -= subscription._description.length;
-
- // Check whether one of the filters has been requested
- if (row < subscription._sortedFilters.length)
- return [subscription, subscription._sortedFilters[row]];
-
- row -= subscription._sortedFilters.length;
- }
- }
-
- return [null, null];
- },
-
- /**
- * Returns the filters currently selected.
- * @param {Boolean} prependCurrent if true, current element will be returned first
- * @return {Array of Filter}
- */
- getSelectedFilters: function(prependCurrent)
- {
- return this.getSelectedInfo(prependCurrent).map(function(info)
- {
- return info[1];
- }).filter(function(filter)
- {
- return filter instanceof Filter;
- });
- },
-
- /**
- * Returns the filters/subscription currently selected.
- * @param {Boolean} prependCurrent if true, current element will be returned first
- * @return {Array} each array entry has the same format as treeView.getRowInfo() result
- * @see treeView.getRowInfo()
- */
- getSelectedInfo: function(prependCurrent)
- {
- let result = [];
- for (let i = 0; i < this.selection.getRangeCount(); i++)
- {
- let min = {};
- let max = {};
- this.selection.getRangeAt(i, min, max);
- for (let j = min.value; j <= max.value; j++)
- {
- let info = this.getRowInfo(j);
- if (info[0])
- {
- if (prependCurrent && j == treeView.selection.currentIndex)
- result.unshift(info);
- else
- result.push(info);
- }
- }
- }
- return result;
- },
-
- /**
- * Checks whether the filter already has a wrapper. If
- * not, replaces all instances of the filter but the
- * wrapper.
- * @param {Filter} filter filter to be tested
- * @return {Filter} wrapped filter
- */
- ensureFilterWrapper: function(filter)
- {
- if ("_isWrapper" in filter)
- return filter;
-
- let wrapper = createFilterWrapper(filter);
- for each (let subscription in this.subscriptions)
- {
- // Replace filter by its wrapper in all subscriptions
- let index = -1;
- let found = false;
- do
- {
- index = subscription.filters.indexOf(filter, index + 1);
- if (index >= 0)
- {
- if (!subscription.hasOwnProperty("filters"))
- subscription.filters = subscription.filters.slice();
-
- subscription.filters[index] = wrapper;
- found = true;
- }
- } while (index >= 0);
-
- if (found)
- {
- if (treeView.sortProc)
- {
- // Sorted filter list needs updating as well
- index = -1;
- do
- {
- index = subscription._sortedFilters.indexOf(filter, index + 1);
- if (index >= 0)
- subscription._sortedFilters[index] = wrapper;
- } while (index >= 0);
- }
- else
- subscription._sortedFilters = subscription.filters;
- }
- }
- return wrapper;
- },
-
- /**
- * Map of comparison functions by column ID or column ID + "Desc" for
- * descending sort order.
- * @const
- */
- sortProcs:
- {
- filter: createSortFunction(compareText, null, false),
- filterDesc: createSortFunction(compareText, null, true),
- slow: createSortFunction(compareSlow, compareText, true),
- slowDesc: createSortFunction(compareSlow, compareText, false),
- enabled: createSortFunction(compareEnabled, compareText, false),
- enabledDesc: createSortFunction(compareEnabled, compareText, true),
- hitcount: createSortFunction(compareHitCount, compareText, false),
- hitcountDesc: createSortFunction(compareHitCount, compareText, true),
- lasthit: createSortFunction(compareLastHit, compareText, false),
- lasthitDesc: createSortFunction(compareLastHit, compareText, true)
- },
-
- /**
- * Changes sort direction of the list.
- * @param {Element} col column (<treecol>) the list should be sorted by
- * @param {String} direction either "natural" (unsorted), "ascending" or "descending"
- */
- resort: function(col, direction)
- {
- if (this.sortColumn)
- this.sortColumn.removeAttribute("sortDirection");
-
- if (direction == "natural")
- {
- this.sortColumn = null;
- this.sortProc = null;
- }
- else
- {
- this.sortColumn = col;
- this.sortProc = this.sortProcs[col.id.replace(/^col-/, "") + (direction == "descending" ? "Desc" : "")];
- this.sortColumn.setAttribute("sortDirection", direction);
- }
-
- for each (let subscription in this.subscriptions)
- this.resortSubscription(subscription);
-
- this.boxObject.invalidate();
- },
-
- /**
- * Updates subscription's _sortedFilters property (sorted index
- * of subscription's filters).
- */
- resortSubscription: function(/**Subscription*/ subscription)
- {
- if (this.sortProc)
- {
- // Hide comments in the list, they should be sorted like the filter following them
- let filters = subscription.filters.slice();
- let followingFilter = null;
- for (let i = filters.length - 1; i >= 0; i--)
- {
- if (filters[i] instanceof CommentFilter)
- filters[i] = { __proto__: followingFilter, _origFilter: filters[i] };
- else
- followingFilter = filters[i];
- }
-
- filters.sort(this.sortProc);
-
- // Restore comments
- for (let i = 0; i < filters.length; i++)
- if ("_origFilter" in filters[i])
- filters[i] = filters[i]._origFilter;
-
- subscription._sortedFilters = filters;
- }
- else
- subscription._sortedFilters = subscription.filters;
- },
-
- /**
- * Selects given tree row.
- */
- selectRow: function(/**Integer*/ row)
- {
- treeView.selection.select(row);
- treeView.boxObject.ensureRowIsVisible(row);
- },
-
- /**
- * Finds the given filter in the list and selects it.
- */
- selectFilter: function(/**Filter*/ filter)
- {
- let resultSubscription = null;
- let resultIndex;
- for each (let subscription in this.subscriptions)
- {
- let index = subscription._sortedFilters.indexOf(filter);
- if (index >= 0)
- {
- [resultSubscription, resultIndex] = [subscription, index];
-
- // If the subscription is disabled continue searching - maybe
- // we have the same filter in an enabled subscription as well
- if (!subscription.disabled)
- break;
- }
- }
-
- if (resultSubscription)
- {
- let parentRow = this.getSubscriptionRow(resultSubscription);
- if (resultSubscription.url in this.closed)
- this.toggleOpenState(parentRow);
- this.selectRow(parentRow + 1 + resultSubscription._description.length + resultIndex);
- }
- },
-
- /**
- * This method will select the first row of a subscription.
- */
- selectSubscription: function(/**Subscription*/ subscription)
- {
- let row = this.getSubscriptionRow(subscription);
- if (row < 0)
- return;
-
- this.selection.select(row);
- this.boxObject.ensureRowIsVisible(row);
- },
-
- /**
- * This method will make sure that the list has some selection (assuming
- * that it has at least one entry).
- * @param {Integer} row row to be selected if the list has no selection
- */
- ensureSelection: function(row)
- {
- if (this.selection.count == 0)
- {
- let rowCount = this.rowCount;
- if (row < 0)
- row = 0;
- if (row >= rowCount)
- row = rowCount - 1;
- if (row >= 0)
- {
- this.selection.select(row);
- this.boxObject.ensureRowIsVisible(row);
- }
- }
- else if (this.selection.currentIndex < 0)
- {
- let min = {};
- this.selection.getRangeAt(0, min, {});
- this.selection.currentIndex = min.value;
- }
- },
-
- /**
- * Checks whether there are any user-defined filters in the list.
- */
- hasUserFilters: function() /**Boolean*/
- {
- for each (let subscription in this.subscriptions)
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length)
- return true;
-
- return false;
- },
-
- /**
- * Checks whether the given subscription is the first one displayed.
- */
- isFirstSubscription: function(/**Subscription*/ search) /**Boolean*/
- {
- for each (let subscription in this.subscriptions)
- {
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- continue;
-
- return (subscription == search);
- }
- return false;
- },
-
- /**
- * Checks whether the given subscription is the last one displayed.
- */
- isLastSubscription: function(/**Subscription*/ search) /**Boolean*/
- {
- for (let i = this.subscriptions.length - 1; i >= 0; i--)
- {
- let subscription = this.subscriptions[i];
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- continue;
-
- return (subscription == search);
- }
- return false;
- },
-
- /**
- * Adds a filter to a subscription. If no subscription is given, will
- * find one that accepts filters of this type.
- * @result {Subscription} the subscription this filter was added to
- */
- addFilter: function(/**Filter*/ filter, /**Subscription*/ subscription, /**Filter*/ insertBefore, /**Boolean*/ noSelect)
- {
- if (!filter)
- return null;
-
- if (!subscription)
- {
- for each (let s in this.subscriptions)
- {
- if (s instanceof SpecialSubscription && s.isFilterAllowed(filter))
- {
- if (s._sortedFilters.indexOf(filter) >= 0 || s.filters.indexOf(filter) >= 0)
- {
- subscription = s;
- break;
- }
-
- if (!subscription || s.priority > subscription.priority)
- subscription = s;
- }
- }
- }
- if (!subscription)
- return null;
-
- let insertPositionSorted = subscription._sortedFilters.indexOf(filter);
- if (insertPositionSorted >= 0)
- {
- // We have that filter already, only need to select it
- if (!noSelect)
- {
- let parentRow = this.getSubscriptionRow(subscription);
- if (subscription.url in this.closed)
- this.toggleOpenState(parentRow);
-
- this.selectRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
- }
- return subscription;
- }
-
- let insertPosition = -1;
- if (insertBefore)
- insertPosition = subscription.filters.indexOf(insertBefore);
- if (insertPosition < 0)
- {
- insertPosition = subscription.filters.length;
-
- // Insert before the comments at the end
- while (insertPosition > 0 && subscription.filters[insertPosition - 1] instanceof CommentFilter && !(filter instanceof CommentFilter))
- insertPosition--;
- if (insertPosition == 0)
- insertPosition = subscription.filters.length;
- }
-
- // If we don't have our own filters property the filter might be there already
- if (subscription.filters.indexOf(filter) < 0)
- {
- // Create a copy of the original subscription filters before modifying
- if (!subscription.hasOwnProperty("filters"))
- subscription.filters = subscription.filters.slice();
-
- subscription.filters.splice(insertPosition, 0, filter);
- }
- this.resortSubscription(subscription);
- insertPositionSorted = subscription._sortedFilters.indexOf(filter);
-
- let parentRow = this.getSubscriptionRow(subscription);
-
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 1)
- {
- this.boxObject.rowCountChanged(parentRow, this.getSubscriptionRowCount(subscription));
- }
- else if (!(subscription.url in this.closed))
- {
- this.boxObject.rowCountChanged(parentRow + 1 + subscription._description.length + insertPositionSorted, 1);
- this.boxObject.invalidateRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
- }
-
- if (!noSelect)
- {
- if (subscription.url in this.closed)
- this.toggleOpenState(parentRow);
- this.selectRow(parentRow + 1 + subscription._description.length + insertPositionSorted);
- }
-
- onChange();
- return subscription;
- },
-
- /**
- * Adds a subscription to the list (if it isn't there already)
- * and makes sure it is selected.
- */
- addSubscription: function(/**Subscription*/ subscription, /**Boolean*/ noSelect)
- {
- if (this.subscriptions.indexOf(subscription) < 0)
- {
- this.subscriptions.push(subscription);
- this.boxObject.rowCountChanged(this.getSubscriptionRow(subscription), this.getSubscriptionRowCount(subscription));
- }
-
- if (!noSelect)
- {
- let [currentSelected, dummy] = this.getRowInfo(this.selection.currentIndex);
- if (currentSelected != subscription)
- this.selectSubscription(subscription);
- }
- },
-
- /**
- * Removes a filter from the list.
- * @param {SpecialSubscription} subscription the subscription the filter belongs to (if null, filter will be removed from all special subscriptions)
- * @param {Filter} filter filter to be removed
- */
- removeFilter: function(subscription, filter)
- {
- if (!subscription)
- {
- for each (let subscription in this.subscriptions)
- {
- if (!(subscription instanceof SpecialSubscription))
- continue;
-
- this.removeFilter(subscription, filter);
- }
- return;
- }
-
- let parentRow = this.getSubscriptionRow(subscription);
- let rowCount = this.getSubscriptionRowCount(subscription);
- let newSelection = parentRow;
-
- // The filter might be removed already if we don't have our own filters property yet
- let index = subscription.filters.indexOf(filter);
- if (index >= 0)
- {
- if (!subscription.hasOwnProperty("filters"))
- subscription.filters = subscription.filters.slice();
-
- subscription.filters.splice(index, 1);
- }
-
- if (subscription.filters != subscription._sortedFilters)
- index = subscription._sortedFilters.indexOf(filter);
- if (index < 0)
- return;
-
- if (treeView.sortProc)
- subscription._sortedFilters.splice(index, 1);
- else
- subscription._sortedFilters = subscription.filters;
-
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length == 0)
- {
- // Empty special subscriptions aren't shown, remove everything
- this.boxObject.rowCountChanged(parentRow, -rowCount);
- newSelection -= rowCount;
- }
- else if (!(subscription.url in this.closed))
- {
- newSelection = parentRow + 1 + subscription._description.length + index;
- this.boxObject.rowCountChanged(newSelection, -1);
- }
-
- this.ensureSelection(newSelection);
- onChange();
- },
-
- /**
- * Removes a filter subscription from the list.
- * @param {RegularSubscription} subscription filter subscription to be removed
- */
- removeSubscription: function(subscription)
- {
- let index = this.subscriptions.indexOf(subscription);
- if (index < 0)
- return;
-
- let firstRow = this.getSubscriptionRow(subscription);
- let rowCount = this.getSubscriptionRowCount(subscription);
-
- this.subscriptions.splice(index, 1);
- this.boxObject.rowCountChanged(firstRow, -rowCount);
-
- this.ensureSelection(firstRow);
- onChange();
- },
-
- /**
- * Moves a filter in the list up or down.
- * @param {Boolean} up if true, the filter is moved up
- */
- moveFilter: function(up)
- {
- let oldRow = this.selection.currentIndex;
- let [subscription, filter] = this.getRowInfo(oldRow);
- if (this.isSorted() || !(filter instanceof Filter) || !(subscription instanceof SpecialSubscription))
- return;
-
- let oldIndex = subscription.filters.indexOf(filter);
- if (oldIndex < 0)
- return;
-
- let newIndex = (up ? oldIndex - 1 : oldIndex + 1);
- if (newIndex < 0 || newIndex >= subscription.filters.length)
- return;
-
- // Create a copy of the original subscription filters before modifying
- if (!subscription.hasOwnProperty("filters"))
- {
- subscription.filters = subscription.filters.slice();
- subscription._sortedFilters = subscription.filters;
- }
-
- [subscription.filters[oldIndex], subscription.filters[newIndex]] = [subscription.filters[newIndex], subscription.filters[oldIndex]];
-
- let newRow = oldRow - oldIndex + newIndex;
- this.boxObject.invalidateRange(Math.min(oldRow, newRow), Math.max(oldRow, newRow));
- this.selectRow(newRow);
-
- onChange();
- },
-
- /**
- * Moves a filter in the list up or down.
- * @param {Boolean} up if true, the filter is moved up
- */
- moveSubscription: function(up)
- {
- let [subscription, filter] = this.getRowInfo(this.selection.currentIndex);
-
- let oldIndex = this.subscriptions.indexOf(subscription);
- if (oldIndex < 0)
- return;
-
- let oldRow = this.getSubscriptionRow(subscription);
- let offset = this.selection.currentIndex - oldRow;
- let newIndex = oldIndex;
- do
- {
- newIndex = (up ? newIndex - 1 : newIndex + 1);
- if (newIndex < 0 || newIndex >= this.subscriptions.length)
- return;
- } while (this.subscriptions[newIndex] instanceof SpecialSubscription && this.subscriptions[newIndex]._sortedFilters.length == 0);
-
- [this.subscriptions[oldIndex], this.subscriptions[newIndex]] = [this.subscriptions[newIndex], this.subscriptions[oldIndex]];
-
- let newRow = this.getSubscriptionRow(subscription);
- let rowCount = this.getSubscriptionRowCount(subscription);
- this.boxObject.invalidateRange(Math.min(oldRow, newRow), Math.max(oldRow, newRow) + rowCount - 1);
- this.selectRow(newRow + offset);
-
- onChange();
- },
-
- dragSubscription: null,
- dragFilter: null,
- startDrag: function(row, e)
- {
- let [subscription, filter] = this.getRowInfo(row);
- if (!subscription)
- return;
- if (filter instanceof Filter && !(subscription instanceof SpecialSubscription))
- return;
- if (filter instanceof Filter && !(filter instanceof CommentFilter) && this.isSorted())
- return;
-
- if (!(filter instanceof Filter))
- filter = null;
-
- let array = Cc["@mozilla.org/supports-array;1"].createInstance(Ci.nsISupportsArray);
- let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
- let data = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
- if (filter instanceof Filter)
- e.dataTransfer.setData("text/plain", filter.text);
- else
- e.dataTransfer.setData("text/plain", subscription.title);
-
- this.dragSubscription = subscription;
- this.dragFilter = filter;
-
- e.stopPropagation();
- },
-
- finishDrag: function()
- {
- this.dragSubscription = null;
- this.dragFilter = null;
- },
-
- /**
- * Toggles disabled state of the selected filters/subscriptions.
- * @param {Array of Filter or Subscription} items
- */
- toggleDisabled: function(items)
- {
- let newValue;
- for each (let item in items)
- {
- if (!(item instanceof ActiveFilter || item instanceof Subscription))
- return;
-
- if (item instanceof ActiveFilter)
- item = this.ensureFilterWrapper(item);
-
- if (typeof newValue == "undefined")
- newValue = !item.disabled;
-
- item.disabled = newValue;
- }
-
- if (typeof newValue != "undefined")
- {
- this.boxObject.invalidate();
- onChange();
- }
- },
-
- /**
- * Invalidates all instances of a filter in the list, making sure changes
- * are displayed.
- */
- invalidateFilter: function(/**Filter*/ search)
- {
- let min = this.boxObject.getFirstVisibleRow();
- let max = this.boxObject.getLastVisibleRow();
- for (let i = min; i <= max; i++)
- {
- let [subscription, filter] = this.getRowInfo(i);
- if (filter == filter)
- this.boxObject.invalidateRow(i);
- }
- },
-
- /**
- * Invalidates a subscription in the list, making sure changes are displayed.
- * @param {Subscription} subscription
- * @param {Integer} oldRowCount (optional) number of roww in the subscription before the change
- */
- invalidateSubscription: function(subscription, oldRowCount)
- {
- let row = this.getSubscriptionRow(subscription);
- if (row < 0)
- return;
-
- let rowCount = this.getSubscriptionRowCount(subscription);
- if (typeof oldRowCount != "undefined" && rowCount != oldRowCount)
- this.boxObject.rowCountChanged(row + Math.min(rowCount, oldRowCount), rowCount - oldRowCount);
-
- if (typeof oldRowCount != "undefined" && oldRowCount < rowCount)
- rowCount = oldRowCount;
- this.boxObject.invalidateRange(row, row + rowCount - 1);
- },
-
- /**
- * Makes sure the description rows of the subscription are updated.
- */
- invalidateSubscriptionInfo: function(/**Subscription*/subscription)
- {
- let row = this.getSubscriptionRow(subscription);
-
- let oldCount = subscription._description.length;
- subscription._description = getSubscriptionDescription(subscription);
- let newCount = subscription._description.length;
- if (oldCount != newCount)
- this.boxObject.rowCountChanged(row + Math.min(oldCount, newCount), newCount - oldCount);
-
- this.boxObject.invalidateRange(row, row + newCount);
- },
-
- /**
- * Removes all user-defined filters from the list.
- */
- removeUserFilters: function()
- {
- for each (let subscription in this.subscriptions)
- {
- if (subscription instanceof SpecialSubscription && subscription._sortedFilters.length > 0)
- {
- let row = this.getSubscriptionRow(subscription);
- let count = this.getSubscriptionRowCount(subscription);
-
- subscription.filters = [];
- subscription._sortedFilters = subscription.filters;
- this.boxObject.rowCountChanged(row, -count);
-
- onChange();
- }
- }
- this.ensureSelection(0);
- },
-
- /**
- * Saves all changes back to filter storage.
- */
- applyChanges: function()
- {
- try
- {
- FilterListener.batchMode = true;
-
- let oldSubscriptions = {__proto__: null};
- for each (let subscription in FilterStorage.subscriptions)
- oldSubscriptions[subscription.url] = true;
-
- let newSubscriptions = {__proto__: null};
- let subscriptions = [];
- for each (let subscription in this.subscriptions)
- {
- let changed = false;
- let disableChanged = (subscription.disabled != subscription.__proto__.disabled);
- for (let key in subscription)
- {
- if (subscription.hasOwnProperty(key) && key[0] != "_" && key != "filters")
- {
- subscription.__proto__[key] = subscription[key];
- delete subscription[key];
- changed = true;
- }
- }
-
- let hasFilters = {__proto__: null};
- let hadWrappers = false;
- for (let i = 0; i < subscription.filters.length; i++)
- {
- let filter = subscription.filters[i];
- if ("_isWrapper" in filter)
- {
- if (filter.disabled != filter.__proto__.disabled)
- {
- filter.__proto__.disabled = filter.disabled;
- FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter.__proto__]);
- }
- subscription.filters[i] = filter.__proto__;
- hadWrappers = true;
- }
- hasFilters[filter.text] = true;
- }
-
- let filtersChanged = (subscription.filters.length != subscription.__proto__.filters.length);
- if (!filtersChanged)
- {
- for each (let filter in subscription.__proto__.filters)
- {
- if (!(filter.text in hasFilters))
- {
- filtersChanged = true;
- break;
- }
- }
- }
-
- if (!(subscription.url in oldSubscriptions))
- FilterStorage.addSubscription(subscription.__proto__);
- else if (filtersChanged)
- FilterStorage.updateSubscriptionFilters(subscription.__proto__, subscription.filters);
- else if (changed)
- {
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription.__proto__]);
- if (disableChanged)
- FilterStorage.triggerObservers(subscription.disabled ? "subscriptions disable" : "subscriptions enable", [subscription.__proto__]);
- }
-
- // Even if the filters didn't change, their ordering might have
- // changed. Replace filters on the original subscription without
- // triggering observers.
- subscription.__proto__.filters = subscription.filters;
- delete subscription.filters;
-
- if (hadWrappers)
- {
- // Reinitialize _sortedFilters to remove wrappers from it
- this.resortSubscription(subscription);
- }
-
- newSubscriptions[subscription.url] = true;
- subscriptions.push(subscription.__proto__);
- }
-
- filterWrappers = {__proto__: null};
-
- for each (let subscription in FilterStorage.subscriptions.slice())
- if (!(subscription.url in newSubscriptions))
- FilterStorage.removeSubscription(subscription);
-
- // Make sure that filter storage has the subscriptions in correct order,
- // replace subscriptions list without triggering observers.
- FilterStorage.subscriptions = subscriptions;
-
- FilterStorage.saveToDisk();
- }
- finally
- {
- FilterListener.batchMode = false;
- }
- },
-
- /**
- * Searches a text string in the subscription titles, subscription
- * descriptions and filters. Selects the matches.
- * @param {String} text text being searched
- * @param {Integer} direction 1 for searching forwards from current position,
- * -1 for searching backwards,
- * 0 for searching forwards but including current position as well
- * @param {Boolean} highlightAll if true, all matches will be selected and not only the current one
- * @param {Boolean} caseSensitive if true, string comparisons should be case-sensitive
- * @return {Integer} one of the nsITypeAheadFind constants
- */
- find: function(text, direction, highlightAll, caseSensitive)
- {
- function normalizeString(string)
- {
- return caseSensitive ? string : string.toLowerCase();
- }
- text = normalizeString(text);
-
- // Matches: current row, first match, previous match, next match, last match
- let match = [null, null, null, null, null];
- let [currentSubscription, currentFilter] = this.getRowInfo(this.selection.currentIndex);
- let isCurrent = false;
- let foundCurrent = !currentSubscription;
- let rowCache = {__proto__: null};
- if (highlightAll)
- this.selection.clearSelection();
-
- let selectMatch = function(subscription, offset)
- {
- if (highlightAll)
- {
- if (!(subscription.url in rowCache))
- rowCache[subscription.url] = treeView.getSubscriptionRow(subscription);
-
- let row = rowCache[subscription.url];
- if (offset && subscription.url in treeView.closed)
- treeView.toggleOpenState(row);
- treeView.selection.rangedSelect(row + offset, row + offset, true);
- }
-
- let index = (isCurrent ? 0 : (foundCurrent ? 4 : 2));
- match[index] = [subscription, offset];
- if (index > 0 && !match[index - 1])
- match[index - 1] = match[index];
- };
-
- for each (let subscription in this.subscriptions)
- {
- // Skip invisible subscriptions
- let rowCount = this.getSubscriptionRowCount(subscription);
- if (rowCount == 0)
- continue;
-
- let offset = 0;
- isCurrent = (subscription == currentSubscription && !currentFilter);
- if (normalizeString(subscription.title).indexOf(text) >= 0)
- selectMatch(subscription, offset);
- if (isCurrent)
- foundCurrent = true;
- offset++;
-
- for each (let description in subscription._description)
- {
- isCurrent = (subscription == currentSubscription && currentFilter === description);
- if (normalizeString(description).indexOf(text) >= 0)
- selectMatch(subscription, offset);
- if (isCurrent)
- foundCurrent = true;
- offset++;
- }
-
- for each (let filter in subscription._sortedFilters)
- {
- isCurrent = (subscription == currentSubscription && filter == currentFilter);
- if (normalizeString(filter.text).indexOf(text) >= 0)
- selectMatch(subscription, offset);
- if (isCurrent)
- foundCurrent = true;
- offset++;
- }
- }
-
- let found = null;
- let status = "";
- if (direction == 0)
- found = match[0] || match[3] || match[1];
- else if (direction > 0)
- found = match[3] || match[1] || match[0];
- else
- found = match[2] || match[4] || match[0];
-
- if (!found)
- return Ci.nsITypeAheadFind.FIND_NOTFOUND;
-
- let [subscription, offset] = found;
- let row = this.getSubscriptionRow(subscription);
- if (offset && subscription.url in this.closed)
- this.toggleOpenState(row);
- if (highlightAll)
- this.selection.currentIndex = row + offset;
- else
- this.selection.select(row + offset);
- this.boxObject.ensureRowIsVisible(row + offset);
-
- if (direction < 0 && found != match[2])
- return Ci.nsITypeAheadFind.FIND_WRAPPED;
- if ((direction > 0 && found != match[3]) || (direction == 0 && found == match[1]))
- return Ci.nsITypeAheadFind.FIND_WRAPPED;
-
- return Ci.nsITypeAheadFind.FIND_FOUND;
- },
-
- //
- // Inline filter editor
- //
-
- editor: null,
- editorParent: null,
- editedRow: -1,
- editorKeyPressHandler: null,
- editorBlurHandler: null,
- editorCancelHandler: null,
- editorDummy: null,
- editorDummyInit: "",
-
- /**
- * true if the editor is currently open
- * @type Boolean
- */
- get isEditing()
- {
- return (this.editedRow >= 0);
- },
-
- /**
- * Initializes inline editor.
- * @param {Element} editor text field to be used as inline editor
- * @param {Element} editorParent editor's parent node to be made visible when the editor should be shown
- */
- setEditor: function(editor, editorParent)
- {
- this.editor = editor;
- this.editorParent = editorParent;
-
- let me = this;
- this.editorKeyPressHandler = function(e)
- {
- if (e.keyCode == e.DOM_VK_RETURN || e.keyCode == e.DOM_VK_ENTER)
- {
- me.stopEditor(true);
- if (e.ctrlKey || e.altKey || e.metaKey)
- document.documentElement.acceptDialog();
- else
- {
- e.preventDefault();
- e.stopPropagation();
- }
- }
- else if (e.keyCode == e.DOM_VK_CANCEL || e.keyCode == e.DOM_VK_ESCAPE)
- {
- me.stopEditor(false);
- e.preventDefault();
- e.stopPropagation();
- }
- };
- this.editorBlurHandler = function(e)
- {
- setTimeout(function()
- {
- let focused = document.commandDispatcher.focusedElement;
- if (!focused || focused != me.editor.field)
- me.stopEditor(true, true);
- }, 0);
- };
-
- // Prevent cyclic references through closures
- editor = null;
- editorParent = null;
- },
-
- /**
- * Opens inline editor.
- * @param {Boolean} insert if false, the editor will insert a new filter, otherwise edit currently selected filter
- */
- startEditor: function(insert)
- {
- this.stopEditor(false);
-
- let row = this.selection.currentIndex;
- let [subscription, filter] = this.getRowInfo(row);
- if (!(subscription instanceof SpecialSubscription) || !(filter instanceof Filter))
- {
- let dummySubscription = new Subscription("~dummy~");
- dummySubscription.title = Utils.getString("new_filter_group_title");
- dummySubscription.filters.push(" ");
- dummySubscription = createSubscriptionWrapper(dummySubscription);
-
- this.subscriptions.unshift(dummySubscription);
- this.boxObject.rowCountChanged(0, this.getSubscriptionRowCount(dummySubscription));
-
- row = 1;
- this.selectRow(row);
- this.editorDummy = dummySubscription;
- }
- else if (insert)
- {
- if (subscription._sortedFilters == subscription.filters)
- subscription._sortedFilters = subscription.filters.slice();
-
- let index = subscription._sortedFilters.indexOf(filter);
- subscription._sortedFilters.splice(index, 0, " ");
- this.boxObject.rowCountChanged(row, 1);
-
- this.selectRow(row);
- this.editorDummy = [subscription, index];
- }
-
- let col = this.boxObject.columns.getPrimaryColumn();
- let textX = {};
- let textY = {};
- let textWidth = {};
- let textHeight = {};
- this.boxObject.ensureRowIsVisible(row);
- this.boxObject.getCoordsForCellItem(row, col, "text", textX, textY, textWidth, textHeight);
-
- let cellX = {};
- let cellWidth = {};
- this.boxObject.getCoordsForCellItem(row, col, "cell", cellX, {}, cellWidth, {});
- cellWidth.value -= textX.value - cellX.value;
-
- // Need to translate coordinates so that they are relative to <stack>, not <treechildren>
- let treeBody = this.boxObject.treeBody;
- let editorStack = this.editorParent.parentNode;
- textX.value += treeBody.boxObject.x - editorStack.boxObject.x;
- textY.value += treeBody.boxObject.y - editorStack.boxObject.y;
-
- this.selection.clearSelection();
-
- let style = window.getComputedStyle(this.editor, "");
- let topadj = parseInt(style.borderTopWidth) + parseInt(style.paddingTop);
-
- this.editedRow = row;
- this.editorParent.hidden = false;
- this.editorParent.width = cellWidth.value;
- this.editorParent.height = textHeight.value + topadj + parseInt(style.borderBottomWidth) + parseInt(style.paddingBottom);
- this.editorParent.left = textX.value;
- this.editorParent.top = textY.value - topadj;
-
- let text = (this.editorDummy ? this.editorDummyInit : filter.text);
-
- this.editor.focus();
- this.editor.field = document.commandDispatcher.focusedElement;
- this.editor.field.value = text;
- this.editor.field.setSelectionRange(this.editor.value.length, this.editor.value.length);
-
- // Need to attach handlers to the embedded html:input instead of menulist - won't catch blur otherwise
- this.editor.field.addEventListener("keypress", this.editorKeyPressHandler, false);
- this.editor.field.addEventListener("blur", this.editorBlurHandler, false);
-
- this.boxObject.invalidateRow(row);
- },
-
- /**
- * Closes inline editor.
- * @param {Boolean} save if true, the editor result should be saved (user accepted changes)
- * @param {Boolean} blur if true, editor was closed on blur and the list shouldn't be focused
- */
- stopEditor: function(save, blur)
- {
- if (this.editedRow < 0)
- return;
-
- this.editor.field.removeEventListener("keypress", this.editorKeyPressHandler, false);
- this.editor.field.removeEventListener("blur", this.editorBlurHandler, false);
-
- let insert = (this.editorDummy != null);
- if (this.editorDummy instanceof Subscription)
- {
- let rowCount = this.getSubscriptionRowCount(this.editorDummy);
- this.subscriptions.shift();
- this.boxObject.rowCountChanged(0, -rowCount);
- this.selectRow(0);
- this.editedRow = -1;
- }
- else if (this.editorDummy)
- {
- let [subscription, index] = this.editorDummy;
- subscription._sortedFilters.splice(index, 1);
- this.boxObject.rowCountChanged(this.editedRow, -1);
- this.selectRow(this.editedRow);
- }
- else
- this.selectRow(this.editedRow);
-
- if (typeof blur == "undefined" || !blur)
- this.boxObject.treeBody.parentNode.focus();
-
- let [subscription, filter] = this.getRowInfo(this.editedRow);
- let text = Filter.normalize(this.editor.value);
- if (save && text && (insert || !(filter instanceof Filter) || text != filter.text))
- {
- let newFilter = getFilterByText(text);
- if (filter && subscription.isFilterAllowed(newFilter))
- this.addFilter(newFilter, subscription, filter);
- else
- this.addFilter(newFilter);
-
- if (!insert)
- this.removeFilter(subscription, filter);
-
- onChange();
- }
-
- this.editor.field.value = "";
- this.editorParent.hidden = true;
-
- this.editedRow = -1;
- this.editorDummy = null;
- this.editorDummyInit = (save ? "" : text);
- }
-};
diff --git a/chrome/content/ui/settings.xul b/chrome/content/ui/settings.xul
deleted file mode 100644
index 260862c..0000000
--- a/chrome/content/ui/settings.xul
+++ /dev/null
@@ -1,220 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://global/skin/tree.css" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/settings.css" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/settings.dtd">
-
-<dialog
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="&dialog.title;"
- id="abpPreferencesWindow"
- onload="init()"
- onunload="cleanUp()"
- ondialogaccept="applyChanges(); return true;"
- ondialogextra2="treeView.startEditor(true)"
- buttons="accept,cancel,extra2"
- buttonlabelextra2="&add.label;â¦"
- buttonaccesskeyextra2="&add.accesskey;"
- width="600"
- height="450"
- persist="screenX screenY width height sizemode"
- windowtype="abp:settings">
-
-<script type="application/x-javascript;version=1.7" src="utils.js"/>
-<script type="application/x-javascript;version=1.7" src="settings.js"/>
-<script type="application/x-javascript;version=1.7" src="findbar.js"/>
-
-<keyset id="adblockKeys">
- <key id="synchsubscription-key" key="t" modifiers="accel"/>
- <key id="synchsubscriptions-key" key="t" modifiers="accel,shift" command="synchsubscriptions-command"/>
- <key id="import-key" key="i" modifiers="accel" command="import-command"/>
- <key id="export-key" key="e" modifiers="accel" command="export-command"/>
- <key id="selectall-key" key="a" modifiers="accel" command="selectall-command"/>
- <key id="copy-key" key="c" modifiers="accel" command="copy-command"/>
- <key id="cut-key" key="x" modifiers="accel" command="cut-command"/>
- <key id="paste-key" key="v" modifiers="accel" command="paste-command"/>
- <key id="find-key" key="f" modifiers="accel" command="find-command"/>
- <key id="find-again-key" key="g" modifiers="accel" command="find-again-command"/>
- <key id="find-previous-key" key="g" modifiers="accel,shift" command="find-previous-command"/>
- <key id="find-again-key2" keycode="VK_F3" command="find-again-command"/>
- <key id="find-previous-key2" keycode="VK_F3" modifiers="shift" command="find-previous-command"/>
- <key id="edit-key" keycode="VK_ENTER"/>
- <key id="remove-key" keycode="VK_DELETE"/>
- <key id="addfilter-key" keycode="VK_INSERT"/>
- <key id="moveup-key" keycode="VK_UP" modifiers="accel"/>
- <key id="movedown-key" keycode="VK_DOWN" modifiers="accel"/>
- <key id="movegroupup-key" keycode="VK_UP" modifiers="accel,shift"/>
- <key id="movegroupdown-key" keycode="VK_DOWN" modifiers="accel,shift"/>
-</keyset>
-
-<commandset id="abpCommands">
- <command id="addsubscription-command" oncommand="editSubscription(null)"/>
- <command id="synchsubscriptions-command" oncommand="synchAllSubscriptions()"/>
- <command id="import-command" oncommand="importList()"/>
- <command id="export-command" oncommand="exportList()"/>
- <command id="selectall-command" oncommand="treeView.selection.selectAll()"/>
- <command id="copy-command" oncommand="copyToClipboard()"/>
- <command id="cut-command" oncommand="copyToClipboard(); removeFilters(false)"/>
- <command id="paste-command" oncommand="pasteFromClipboard()"/>
- <command id="remove-command" oncommand="removeFilters(true)"/>
- <command id="find-command" oncommand="E('findbar').startFind(E('findbar').FIND_NORMAL)"/>
- <command id="find-again-command" oncommand="E('findbar').onFindAgainCommand(false)"/>
- <command id="find-previous-command" oncommand="E('findbar').onFindAgainCommand(true)"/>
-</commandset>
-
-<popupset id="abpPopups">
- <menupopup id="listitem-context" onpopupshowing="return fillContext()">
- <menuitem id="context-synchsubscription" label="&context.synchsubscription.label;" oncommand="synchSubscription()" key="synchsubscription-key" />
- <menuitem id="context-editsubscription" label="&context.editsubscription.label;â¦" oncommand="editFilter('subscription')" key="edit-key"/>
- <menuitem id="context-edit" label="&context.edit.label;" oncommand="editFilter('filter')" key="edit-key"/>
- <menuitem id="context-resethitcount" label="&context.resethitcount.label;â¦" oncommand="resetHitCounts(false)"/>
- <menuitem id="context-moveup" label="&context.moveup.label;" oncommand="treeView.moveFilter(true)" key="moveup-key"/>
- <menuitem id="context-movedown" label="&context.movedown.label;" oncommand="treeView.moveFilter(false)" key="movedown-key"/>
- <menuseparator/>
- <menuitem id="context-cut" label="&cut.label;" accesskey="&cut.accesskey;" command="cut-command" key="cut-key"/>
- <menuitem id="context-copy" label="©.label;" accesskey="©.accesskey;" command="copy-command" key="copy-key"/>
- <menuitem id="context-paste" label="&paste.label;" accesskey="&paste.accesskey;" command="paste-command" key="paste-key"/>
- <menuitem id="context-remove" label="&remove.label;" accesskey="&remove.accesskey;" command="remove-command" key="remove-key"/>
- <menuitem id="context-enable" label="&context.enable.label;" oncommand="toggleDisabled()"/>
- <menuitem id="context-disable" label="&context.disable.label;" oncommand="toggleDisabled()"/>
- <menuseparator/>
- <menuitem id="context-movegroupup" label="&context.movegroupup.label;" oncommand="treeView.moveSubscription(true)" key="movegroupup-key"/>
- <menuitem id="context-movegroupdown" label="&context.movegroupdown.label;" oncommand="treeView.moveSubscription(false)" key="movegroupdown-key"/>
- </menupopup>
- <menupopup id="treecols-context" onpopupshowing="fillViewPopup('context-')"/>
- <tooltip id="tree-tooltip" onpopupshowing="return showTreeTooltip(event);"/>
-</popupset>
-
-<toolbox id="menuToolbox">
- <menubar id="menu" onpopupshowing="treeView.stopEditor(true, true);">
- <menu id="filters-menu" label="&filters.label;" accesskey="&filters.accesskey;">
- <menupopup id="filters-popup" onpopupshowing="fillFiltersPopup()">
- <menuitem id="addfilter" label="&add.label;â¦" accesskey="&add.accesskey;" key="addfilter-key" oncommand="treeView.startEditor(true)"/>
- <menuseparator/>
- <menuitem id="addsubscription" label="&addsubscription.label;â¦" accesskey="&addsubscription.accesskey;" command="addsubscription-command"/>
- <menuitem id="synchsubscriptions" label="&synchsubscriptions.label;" accesskey="&synchsubscriptions.accesskey;" key="synchsubscriptions-key" command="synchsubscriptions-command"/>
- <menuseparator/>
- <menuitem id="import" label="&import.label;â¦" accesskey="&import.accesskey;" key="import-key" command="import-command"/>
- <menuitem id="export" label="&export.label;â¦" accesskey="&export.accesskey;" key="export-key" command="export-command"/>
- <menuitem id="clearall" label="&clearall.label;â¦" accesskey="&clearall.accesskey;" oncommand="clearList()"/>
- <menuseparator/>
- <menuitem id="resethitcounts" label="&resethitcounts.label;â¦" accesskey="&resethitcounts.accesskey;" oncommand="resetHitCounts(true)"/>
- </menupopup>
- </menu>
- <menu id="edit-menu" label="&edit.label;" accesskey="&edit.accesskey;">
- <menupopup id="edit-popup">
- <menuitem id="cut" label="&cut.label;" accesskey="&cut.accesskey;" command="cut-command" key="cut-key"/>
- <menuitem id="copy" label="©.label;" accesskey="©.accesskey;" command="copy-command" key="copy-key"/>
- <menuitem id="paste" label="&paste.label;" accesskey="&paste.accesskey;" command="paste-command" key="paste-key"/>
- <menuitem id="remove" label="&remove.label;" accesskey="&remove.accesskey;" command="remove-command" key="remove-key"/>
- <menuseparator/>
- <menuitem id="find" label="&menu.find.label;â¦" accesskey="&menu.find.accesskey;" command="find-command" key="find-key"/>
- <menuitem id="find-again" label="&menu.findagain.label;" accesskey="&menu.findagain.accesskey;" command="find-again-command" key="find-again-key"/>
- </menupopup>
- </menu>
- <menu id="view-menu" label="&view.label;" accesskey="&view.accesskey;">
- <menupopup id="view-popup" onpopupshowing="fillViewPopup('')">
- <menuitem id="view-filter" label="&filter.column;" accesskey="&filter.accesskey;" type="checkbox" disabled="true"/>
- <menuitem id="view-slow" label="&slow.column;" accesskey="&slow.accesskey;" type="checkbox" oncommand="toggleColumn('col-slow')"/>
- <menuitem id="view-enabled" label="&enabled.column;" accesskey="&enabled.accesskey;" type="checkbox" oncommand="toggleColumn('col-enabled')"/>
- <menuitem id="view-hitcount" label="&hitcount.column;" accesskey="&hitcount.accesskey;" type="checkbox" oncommand="toggleColumn('col-hitcount')"/>
- <menuitem id="view-lasthit" label="&lasthit.column;" accesskey="&lasthit.accesskey;" type="checkbox" oncommand="toggleColumn('col-lasthit')"/>
- <menuseparator/>
- <menu id="sort-menu" label="&sort.label;" accesskey="&sort.accesskey;">
- <menupopup id="sort-popup">
- <menuitem id="sort-none" label="&sort.none.label;" accesskey="&sort.none.accesskey;" type="radio" name="sortColumn" oncommand="sortBy(null)"/>
- <menuitem id="sort-filter" label="&filter.column;" accesskey="&filter.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-filter')"/>
- <menuitem id="sort-slow" label="&slow.column;" accesskey="&slow.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-slow')"/>
- <menuitem id="sort-enabled" label="&enabled.column;" accesskey="&enabled.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-enabled')"/>
- <menuitem id="sort-hitcount" label="&hitcount.column;" accesskey="&hitcount.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-hitcount')"/>
- <menuitem id="sort-lasthit" label="&lasthit.column;" accesskey="&lasthit.accesskey;" type="radio" name="sortColumn" oncommand="sortBy('col-lasthit')"/>
- <menuseparator/>
- <menuitem id="sort-asc" label="&sort.ascending.label;" accesskey="&sort.ascending.accesskey;" type="radio" name="sortOrder" oncommand="setSortOrder('ascending')"/>
- <menuitem id="sort-desc" label="&sort.descending.label;" accesskey="&sort.descending.accesskey;" type="radio" name="sortOrder" oncommand="setSortOrder('descending')"/>
- </menupopup>
- </menu>
- </menupopup>
- </menu>
- <menu id="options-menu" label="&options.label;" accesskey="&options.accesskey;">
- <menupopup id="options-popup" onpopupshowing="fillOptionsPopup()">
- <menuitem id="abp-enabled" label="&enable.label;" accesskey="&enable.accesskey;" type="checkbox" oncommand="togglePref('enabled')"/>
- <menuseparator/>
- <menuitem id="frameobjects" label="&objecttabs.label;" accesskey="&objecttabs.accesskey;" type="checkbox" oncommand="togglePref('frameobjects')"/>
- <menuitem id="slowcollapse" label="&collapse.label;" accesskey="&collapse.accesskey;" type="checkbox" oncommand="togglePref('fastcollapse')"/>
- <menuitem id="sync" label="&sync.label;" accesskey="&sync.accesskey;" type="checkbox" oncommand="toggleSync();"/>
- <menuseparator/>
- <menuitem id="showintoolbar" label="&showintoolbar.label;" accesskey="&showintoolbar.accesskey;" type="checkbox" oncommand="togglePref('showintoolbar')"/>
- <menuitem id="showinstatusbar" label="&showinstatusbar.label;" accesskey="&showinstatusbar.accesskey;" type="checkbox" oncommand="togglePref('showinstatusbar')"/>
- </menupopup>
- </menu>
- <menu id="help-menu" label="&help.label;" accesskey="&help.accesskey;">
- <menupopup id="help-popup">
- <menuitem id="gettingStartedLink" label="&gettingStarted.label;" accesskey="&gettingStarted.accesskey;" oncommand="Utils.loadDocLink('gettingStarted');"/>
- <menuitem id="faqLink" label="&faq.label;" accesskey="&faq.accesskey;" oncommand="Utils.loadDocLink('faq');"/>
- <menuitem id="filtersLink" label="&filterdoc.label;" accesskey="&filterdoc.accesskey;" oncommand="Utils.loadDocLink('filterdoc');"/>
- <menuseparator/>
- <menuitem id="aboutAbp" label="&about.label;â¦" accesskey="&about.accesskey;" oncommand="openAbout()"/>
- </menupopup>
- </menu>
- </menubar>
-</toolbox>
-
-<description id="introduction">
- &description;
-</description>
-
-<button id="applyButton" class="dialog-button" hidden="true" label="&apply.label;" accesskey="&apply.accesskey;" oncommand="applyChanges()"/>
-
-<vbox id="listarea" flex="1">
- <stack id="listStack" flex="1">
- <tree id="list" onselect="updateCommands()" context="listitem-context" persist="closedSubscriptions" flex="1" seltype="multiple" hidecolumnpicker="true" enableColumnDrag="true">
- <treecols context="treecols-context">
- <treecol id="col-filter" label="&filter.column;" primary="true" flex="10" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="col-slow" label="!" flex="0" width="16" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="col-enabled" label="&enabled.column;" flex="0" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="col-hitcount" label="&hitcount.column;" flex="0" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="col-lasthit" label="&lasthit.column;" hidden="true" flex="4" persist="width ordinal sortDirection hidden"/>
- </treecols>
-
- <treechildren id="treechildren" tooltip="tree-tooltip" onclick="onListClick(event)" ondblclick="onListDblClick(event)" ondragstart="onListDragStart(event);" ondragend="onListDragEnd(event);"/>
- </tree>
- <hbox id="listEditorParent" align="center" hidden="true">
- <textbox id="listEditor" class="tree-input" flex="1"/>
- <image id="listEditorIcon" onclick="if (event.button == 0) treeView.stopEditor(false);" />
- </hbox>
- </stack>
-
- <findbar id="findbar"/>
-</vbox>
-
-</dialog>
diff --git a/chrome/content/ui/sidebar.js b/chrome/content/ui/sidebar.js
deleted file mode 100644
index 9f2200c..0000000
--- a/chrome/content/ui/sidebar.js
+++ /dev/null
@@ -1,1166 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-
-// Main browser window
-var mainWin = parent;
-
-// The window handler currently in use
-var requestNotifier = null;
-
-var cacheSession = null;
-var noFlash = false;
-
-// Matcher for disabled filters
-var disabledMatcher = new CombinedMatcher();
-
-// Cached string values
-var docDomainThirdParty = null;
-var docDomainFirstParty = null;
-
-var abpHooks = null;
-
-let lastSelectionProp = "abpSelected" + RequestNotifier.getDataSeed();
-
-function init() {
- docDomainThirdParty = document.documentElement.getAttribute("docDomainThirdParty");
- docDomainFirstParty = document.documentElement.getAttribute("docDomainFirstParty");
-
- var list = E("list");
- list.view = treeView;
-
- // Restore previous state
- var params = Utils.getParams();
- if (params && params.filter)
- {
- E("searchField").value = params.filter;
- treeView.setFilter(params.filter);
- }
- if (params && params.focus && E(params.focus))
- E(params.focus).focus();
- else
- E("searchField").focus();
-
- var selected = null;
- if (/sidebarDetached\.xul$/.test(parent.location.href)) {
- mainWin = parent.opener;
- mainWin.addEventListener("unload", mainUnload, false);
- E("detachButton").hidden = true;
- E("reattachButton").hidden = false;
- if (!mainWin.document.getElementById("abp-sidebar"))
- E("reattachButton").setAttribute("disabled", "true");
- if (mainWin.document.getElementById("abp-key-sidebar")) {
- var sidebarKey = mainWin.document.getElementById("abp-key-sidebar").cloneNode(true);
- parent.document.getElementById("detached-keyset").appendChild(parent.document.importNode(sidebarKey, true));
- }
-
- // Set default size/position unless already persisted
- let defaults = {screenX: 0, screenY: 0, width: 600, height: 300};
- if (params && params.position)
- defaults = params.position;
-
- let wnd = parent.document.documentElement;
- for (let attr in defaults)
- if (!wnd.hasAttribute(attr))
- wnd.setAttribute(attr, defaults[attr]);
- }
-
- abpHooks = mainWin.document.getElementById("abp-hooks");
- window.__defineGetter__("content", function() {return abpHooks.getBrowser().contentWindow;});
-
- // Initialize matcher for disabled filters
- reloadDisabledFilters();
- FilterStorage.addObserver(reloadDisabledFilters);
- Prefs.addListener(onPrefChange);
-
- // Activate flasher
- list.addEventListener("select", onSelectionChange, false);
-
- // Initialize data
- handleLocationChange();
-
- // Install a progress listener to catch location changes
- abpHooks.getBrowser().addProgressListener(progressListener);
-}
-
-// To be called for a detached window when the main window has been closed
-function mainUnload() {
- parent.close();
-}
-
-// To be called on unload
-function cleanUp() {
- flasher.stop();
- requestNotifier.shutdown();
- FilterStorage.removeObserver(reloadDisabledFilters);
- Prefs.removeListener(onPrefChange);
-
- abpHooks.getBrowser().removeProgressListener(progressListener);
- mainWin.removeEventListener("unload", mainUnload, false);
-}
-
-/**
- * Tracks preference changes, calls reloadDisabledFilters whenever Adblock Plus
- * is enabled/disabled.
- */
-function onPrefChange(name)
-{
- if (name == "enabled")
- reloadDisabledFilters();
-}
-
-/**
- * Updates matcher for disabled filters (global disabledMatcher variable),
- * called on each filter change.
- */
-function reloadDisabledFilters()
-{
- disabledMatcher.clear();
-
- if (Prefs.enabled)
- {
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (subscription.disabled)
- continue;
-
- for each (let filter in subscription.filters)
- if (filter instanceof RegExpFilter && filter.disabled)
- disabledMatcher.add(filter);
- }
- }
-
- treeView.updateFilters();
-}
-
-// Called whenever list selection changes - triggers flasher
-function onSelectionChange() {
- var item = treeView.getSelectedItem();
- if (item)
- E("copy-command").removeAttribute("disabled");
- else
- E("copy-command").setAttribute("disabled", "true");
-
- if (item && window.content)
- {
- let key = item.location + " " + item.type + " " + item.docDomain;
- window.content.document.setUserData(lastSelectionProp, key, null);
- treeView.itemToSelect = null;
- }
-
- if (!noFlash)
- flasher.flash(item ? item.nodes : null);
-}
-
-function handleLocationChange()
-{
- if (requestNotifier)
- requestNotifier.shutdown();
-
- treeView.clearData();
- treeView.itemToSelect = window.content.document.getUserData(lastSelectionProp);
- requestNotifier = new RequestNotifier(window.content, function(wnd, node, item, scanComplete)
- {
- if (item)
- treeView.addItem(node, item, scanComplete);
- });
-}
-
-// Fills a box with text splitting it up into multiple lines if necessary
-function setMultilineContent(box, text, noRemove)
-{
- if (!noRemove)
- while (box.firstChild)
- box.removeChild(box.firstChild);
-
- for (var i = 0; i < text.length; i += 80)
- {
- var description = document.createElement("description");
- description.setAttribute("value", text.substr(i, 80));
- box.appendChild(description);
- }
-}
-
-// Fill in tooltip data before showing it
-function fillInTooltip(e) {
- var item;
- if (treeView.data && !treeView.data.length)
- item = treeView.getDummyTooltip();
- else
- item = treeView.getItemAt(e.clientX, e.clientY);
-
- if (!item)
- return false;
-
- let filter = ("filter" in item && item.filter ? item.filter : null);
- let size = ("tooltip" in item ? null : getItemSize(item));
- let subscriptions = (filter ? filter.subscriptions.filter(function(subscription) { return !subscription.disabled; }) : []);
-
- E("tooltipDummy").hidden = !("tooltip" in item);
- E("tooltipAddressRow").hidden = ("tooltip" in item);
- E("tooltipTypeRow").hidden = ("tooltip" in item);
- E("tooltipSizeRow").hidden = !size;
- E("tooltipDocDomainRow").hidden = ("tooltip" in item || !item.docDomain);
- E("tooltipFilterRow").hidden = !filter;
- E("tooltipFilterSourceRow").hidden = !subscriptions.length;
-
- if ("tooltip" in item)
- E("tooltipDummy").setAttribute("value", item.tooltip);
- else
- {
- E("tooltipAddress").parentNode.hidden = (item.typeDescr == "ELEMHIDE");
- setMultilineContent(E("tooltipAddress"), item.location);
-
- var type = item.localizedDescr;
- if (filter && filter instanceof WhitelistFilter)
- type += " " + E("tooltipType").getAttribute("whitelisted");
- else if (filter && item.typeDescr != "ELEMHIDE")
- type += " " + E("tooltipType").getAttribute("filtered");
- E("tooltipType").setAttribute("value", type);
-
- if (size)
- E("tooltipSize").setAttribute("value", size.join(" x "));
-
- E("tooltipDocDomain").setAttribute("value", item.docDomain + " " + (item.thirdParty ? docDomainThirdParty : docDomainFirstParty));
- }
-
- if (filter)
- {
- let filterField = E("tooltipFilter");
- setMultilineContent(filterField, filter.text);
- if (filter.disabled)
- {
- let disabledText = document.createElement("description");
- disabledText.className = "disabledTextLabel";
- disabledText.textContent = filterField.getAttribute("disabledText");
- filterField.appendChild(disabledText);
- }
-
- if (subscriptions.length)
- {
- let sourceElement = E("tooltipFilterSource");
- while (sourceElement.firstChild)
- sourceElement.removeChild(sourceElement.firstChild);
- for (let i = 0; i < subscriptions.length; i++)
- setMultilineContent(sourceElement, subscriptions[i].title, true);
- }
- }
-
- var showPreview = Prefs.previewimages && !("tooltip" in item);
- showPreview = showPreview && item.typeDescr == "IMAGE";
- showPreview = showPreview && (!item.filter || item.filter instanceof WhitelistFilter);
- if (showPreview) {
- // Check whether image is in cache (stolen from ImgLikeOpera)
- if (!cacheSession) {
- var cacheService = Cc["@mozilla.org/network/cache-service;1"].getService(Ci.nsICacheService);
- cacheSession = cacheService.createSession("HTTP", Ci.nsICache.STORE_ANYWHERE, true);
- }
-
- try {
- var descriptor = cacheSession.openCacheEntry(item.location, Ci.nsICache.ACCESS_READ, false);
- descriptor.close();
- }
- catch (e) {
- showPreview = false;
- }
- }
-
- if (showPreview) {
- E("tooltipPreviewBox").hidden = false;
- E("tooltipPreview").setAttribute("src", "");
- E("tooltipPreview").setAttribute("src", item.location);
- }
- else
- E("tooltipPreviewBox").hidden = true;
-
- return true;
-}
-
-const visual = {
- OTHER: true,
- IMAGE: true,
- SUBDOCUMENT: true
-}
-
-/**
- * Updates context menu before it is shown.
- */
-function fillInContext(/**Event*/ e)
-{
- let item, allItems;
- if (treeView.data && !treeView.data.length)
- {
- item = treeView.getDummyTooltip();
- allItems = [item];
- }
- else
- {
- item = treeView.getItemAt(e.clientX, e.clientY);
- allItems = treeView.getAllSelectedItems();
- }
-
- if (!item || ("tooltip" in item && !("filter" in item)))
- return false;
-
- E("contextDisableFilter").hidden = true;
- E("contextEnableFilter").hidden = true;
- E("contextDisableOnSite").hidden = true;
- if ("filter" in item && item.filter)
- {
- let filter = item.filter;
- let menuItem = E(filter.disabled ? "contextEnableFilter" : "contextDisableFilter");
- menuItem.filter = filter;
- menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, filter.text));
- menuItem.hidden = false;
-
- if (filter instanceof ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription)))
- {
- let domain = null;
- try {
- domain = content.location.host;
- domain = Utils.effectiveTLD.getBaseDomainFromHost(domain);
- } catch (e) {}
-
- if (domain && !filter.isActiveOnlyOnDomain(domain))
- {
- menuItem = E("contextDisableOnSite");
- menuItem.item = item;
- menuItem.filter = filter;
- menuItem.domain = domain;
- menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, domain));
- menuItem.hidden = false;
- }
- }
- }
-
- E("contextWhitelist").hidden = ("tooltip" in item || !item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter || item.typeDescr == "ELEMHIDE");
- E("contextBlock").hidden = !E("contextWhitelist").hidden;
- E("contextBlock").setAttribute("disabled", "filter" in item && item.filter && !item.filter.disabled);
- E("contextEditFilter").setAttribute("disabled", !("filter" in item && item.filter));
- E("contextOpen").setAttribute("disabled", "tooltip" in item || item.typeDescr == "ELEMHIDE");
- E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.typeDescr in visual) || (item.filter && !item.filter.disabled && !(item.filter instanceof WhitelistFilter)));
- E("contextCopyFilter").setAttribute("disabled", !allItems.some(function(item) {return "filter" in item && item.filter}));
-
- return true;
-}
-
-/**
- * Processed mouse clicks on the item list.
- * @param {Event} event
- */
-function handleClick(event)
-{
- let item = treeView.getItemAt(event.clientX, event.clientY);
- if (event.button == 0 && treeView.getColumnAt(event.clientX, event.clientY) == "state")
- {
- if (item.filter)
- enableFilter(item.filter, item.filter.disabled);
- event.preventDefault();
- }
- else if (event.button == 1)
- {
- openInTab(item, event);
- event.preventDefault();
- }
-}
-
-/**
- * Processes double-clicks on the item list.
- * @param {Event} event
- */
-function handleDblClick(event)
-{
- if (event.button != 0 || treeView.getColumnAt(event.clientX, event.clientY) == "state")
- return;
-
- doBlock();
-}
-
-/**
- * Opens the item in a new tab.
- */
-function openInTab(item, /**Event*/ event)
-{
- let items = (item ? [item] : treeView.getAllSelectedItems());
- for each (let item in items)
- {
- if (item && item.typeDescr != "ELEMHIDE")
- Utils.loadInBrowser(item.location, mainWin, event);
- }
-}
-
-function doBlock() {
- var item = treeView.getSelectedItem();
- if (!item || item.typeDescr == "ELEMHIDE")
- return;
-
- var filter = null;
- if (item.filter && !item.filter.disabled)
- filter = item.filter;
-
- if (filter && filter instanceof WhitelistFilter)
- return;
-
- openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", item.nodes, item.orig);
-}
-
-function editFilter() {
- var item = treeView.getSelectedItem();
- if (treeView.data && !treeView.data.length)
- item = treeView.getDummyTooltip();
-
- if (!("filter" in item) || !item.filter)
- return;
-
- if (!("location") in item)
- item.location = undefined
-
- Utils.openSettingsDialog(item.location, item.filter);
-}
-
-function enableFilter(filter, enable) {
- filter.disabled = !enable;
- FilterStorage.triggerObservers(enable ? "filters enable" : "filters disable", [filter]);
- FilterStorage.saveToDisk();
-
- treeView.boxObject.invalidate();
-}
-
-/**
- * Edits the filter to disable it on a particular domain.
- */
-function disableOnSite(item, /**Filter*/ filter, /**String*/ domain)
-{
- // Generate text for new filter that excludes current domain
- domain = domain.toUpperCase();
- let text = filter.text;
- if (filter instanceof RegExpFilter)
- {
- if (Filter.optionsRegExp.test(text))
- {
- let found = false;
- let options = RegExp.$1.toUpperCase().split(",");
- for (let i = 0; i < options.length; i++)
- {
- if (/^DOMAIN=(.*)/.test(options[i]))
- {
- let domains = RegExp.$1.split("|").filter(function(d) d != domain && d != "~" + domain && (d.length <= domain.length || d.lastIndexOf("." + domain) != d.length - domain.length - 1));
- domains.push("~" + domain);
- options[i] = "DOMAIN=" + domains.join("|");
- found = true;
- break;
- }
- }
- if (!found)
- options.push("DOMAIN=~" + domain);
-
- text = text.replace(Filter.optionsRegExp, "$" + options.join(",").toLowerCase());
- }
- else
- text += "$domain=~" + domain.toLowerCase();
- }
- else if (filter instanceof ElemHideFilter)
- {
- if (/^([^#]+)(#.*)/.test(text))
- {
- let selector = RegExp.$2;
- let domains = RegExp.$1.toUpperCase().split(",").filter(function(d) d != domain && (d.length <= domain.length || d != "~" + domain && d.lastIndexOf("." + domain) != d.length - domain.length - 1));
- domains.push("~" + domain);
- text = domains.join(",").toLowerCase() + selector;
- }
- else
- text = "~" + domain.toLowerCase() + text;
- }
-
- if (text == filter.text)
- return; // Just in case, shouldn't happen
-
- // Insert new filter before the old one and remove the old one then
- let newFilter = Filter.fromText(text);
- if (newFilter.disabled && newFilter.subscriptions.length)
- {
- newFilter.disabled = false;
- FilterStorage.triggerObservers("filters enable", [newFilter]);
- }
- else if (!newFilter.subscriptions.length)
- {
- newFilter.disabled = false;
- FilterStorage.addFilter(newFilter, filter);
- }
- FilterStorage.removeFilter(filter);
- FilterStorage.saveToDisk();
-
- // Update display
- item.filter = null;
- treeView.boxObject.invalidate();
-}
-
-function copyToClipboard() {
- var items = treeView.getAllSelectedItems();
- if (!items.length)
- return;
-
- var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
- clipboardHelper.copyString(items.map(function(item) {return item.location}).join(Utils.getLineBreak()));
-}
-
-function copyFilter() {
- var items = treeView.getAllSelectedItems().filter(function(item) {return item.filter});
- if (treeView.data && !treeView.data.length)
- items = [treeView.getDummyTooltip()];
-
- if (!items.length)
- return;
-
- var clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
- clipboardHelper.copyString(items.map(function(item) {return item.filter.text}).join(Utils.getLineBreak()));
-}
-
-function selectAll() {
- treeView.selectAll();
-}
-
-// Saves sidebar's state before detaching/reattaching
-function saveState() {
- var focused = document.commandDispatcher.focusedElement;
- while (focused && (!focused.id || !("focus" in focused)))
- focused = focused.parentNode;
-
- // Calculate default position for the detached window
- var boxObject = document.documentElement.boxObject;
- var position = {screenX: boxObject.screenX, screenY: boxObject.screenY, width: boxObject.width, height: boxObject.height};
-
- var params = {
- filter: treeView.filter,
- focus: (focused ? focused.id : null),
- position: position
- };
- Utils.setParams(params);
-}
-
-// closes the sidebar
-function doClose()
-{
- mainWin.document.getElementById("abp-command-sidebar").doCommand();
-}
-
-// detaches/reattaches the sidebar
-function detach(doDetach)
-{
- saveState();
-
- // Store variables locally, global variables will go away when we are closed
- let myPrefs = Prefs;
- let myMainWin = mainWin;
-
- // Close sidebar and open detached window
- myMainWin.document.getElementById("abp-command-sidebar").doCommand();
- myPrefs.detachsidebar = doDetach;
- myMainWin.document.getElementById("abp-command-sidebar").doCommand();
-}
-
-// Returns items size in the document if available
-function getItemSize(item)
-{
- if (item.filter && !item.filter.disabled && item.filter instanceof BlockingFilter)
- return null;
-
- for each (let node in item.nodes)
- {
- if (node instanceof HTMLImageElement && (node.naturalWidth || node.naturalHeight))
- return [node.naturalWidth, node.naturalHeight];
- else if (node instanceof HTMLElement && (node.offsetWidth || node.offsetHeight))
- return [node.offsetWidth, node.offsetHeight];
- }
- return null;
-}
-
-// Sort functions for the item list
-function sortByAddress(item1, item2) {
- if (item1.location < item2.location)
- return -1;
- else if (item1.location > item2.location)
- return 1;
- else
- return 0;
-}
-
-function sortByAddressDesc(item1, item2) {
- return -sortByAddress(item1, item2);
-}
-
-function compareType(item1, item2) {
- if (item1.localizedDescr < item2.localizedDescr)
- return -1;
- else if (item1.localizedDescr > item2.localizedDescr)
- return 1;
- else
- return 0;
-}
-
-function compareFilter(item1, item2) {
- var hasFilter1 = (item1.filter ? 1 : 0);
- var hasFilter2 = (item2.filter ? 1 : 0);
- if (hasFilter1 != hasFilter2)
- return hasFilter1 - hasFilter2;
- else if (hasFilter1 && item1.filter.text < item2.filter.text)
- return -1;
- else if (hasFilter1 && item1.filter.text > item2.filter.text)
- return 1;
- else
- return 0;
-}
-
-function compareState(item1, item2) {
- var state1 = (!item1.filter ? 0 : (item1.filter.disabled ? 1 : (item1.filter instanceof WhitelistFilter ? 2 : 3)));
- var state2 = (!item2.filter ? 0 : (item2.filter.disabled ? 1 : (item2.filter instanceof WhitelistFilter ? 2 : 3)));
- return state1 - state2;
-}
-
-function compareSize(item1, item2) {
- var size1 = getItemSize(item1);
- size1 = size1 ? size1[0] * size1[1] : 0;
-
- var size2 = getItemSize(item2);
- size2 = size2 ? size2[0] * size2[1] : 0;
- return size1 - size2;
-}
-
-function compareDocDomain(item1, item2)
-{
- if (item1.docDomain < item2.docDomain)
- return -1;
- else if (item1.docDomain > item2.docDomain)
- return 1;
- else if (item1.thirdParty && !item2.thirdParty)
- return -1;
- else if (!item1.thirdParty && item2.thirdParty)
- return 1;
- else
- return 0;
-}
-
-function createSortWithFallback(cmpFunc, fallbackFunc, desc) {
- var factor = (desc ? -1 : 1);
-
- return function(item1, item2) {
- var ret = cmpFunc(item1, item2);
- if (ret == 0)
- return fallbackFunc(item1, item2);
- else
- return factor * ret;
- }
-}
-
-var progressListener =
-{
- onLocationChange: function() handleLocationChange(),
- onProgressChange: function() {},
- onSecurityChange: function() {},
- onStateChange: function() {},
- onStatusChange: function() {},
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference])
-};
-
-// Item list's tree view object
-var treeView = {
- //
- // nsISupports implementation
- //
-
- QueryInterface: function(uuid) {
- if (!uuid.equals(Ci.nsISupports) &&
- !uuid.equals(Ci.nsITreeView))
- {
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
-
- return this;
- },
-
- //
- // nsITreeView implementation
- //
-
- selection: null,
-
- setTree: function(boxObject) {
- if (!boxObject)
- return;
-
- this.boxObject = boxObject;
- this.itemsDummy = boxObject.treeBody.getAttribute("noitemslabel");
- this.whitelistDummy = boxObject.treeBody.getAttribute("whitelistedlabel");
-
- var stringAtoms = ["col-address", "col-type", "col-filter", "col-state", "col-size", "col-docDomain", "state-regular", "state-filtered", "state-whitelisted", "state-hidden"];
- var boolAtoms = ["selected", "dummy", "filter-disabled"];
- var atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService);
-
- this.atoms = {};
- for each (let atom in stringAtoms)
- this.atoms[atom] = atomService.getAtom(atom);
- for each (let atom in boolAtoms)
- {
- this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true");
- this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false");
- }
-
- this.itemsDummyTooltip = Utils.getString("no_blocking_suggestions");
- this.whitelistDummyTooltip = Utils.getString("whitelisted_page");
-
- // Check current sort direction
- var cols = document.getElementsByTagName("treecol");
- var sortDir = null;
- for (let i = 0; i < cols.length; i++) {
- var col = cols[i];
- var dir = col.getAttribute("sortDirection");
- if (dir && dir != "natural") {
- this.sortColumn = col;
- sortDir = dir;
- }
- }
- if (!this.sortColumn)
- {
- let defaultSort = E("list").getAttribute("defaultSort");
- if (/^(\w+)\s+(ascending|descending)$/.test(defaultSort))
- {
- this.sortColumn = E(RegExp.$1);
- if (this.sortColumn)
- {
- sortDir = RegExp.$2;
- this.sortColumn.setAttribute("sortDirection", sortDir);
- }
- }
- }
-
- if (sortDir)
- {
- this.sortProc = this.sortProcs[this.sortColumn.id + (sortDir == "descending" ? "Desc" : "")];
- E("list").setAttribute("defaultSort", " ");
- }
-
- // Make sure to update the dummy row every two seconds
- setInterval(function(view) {
- if (!view.data || !view.data.length)
- view.boxObject.invalidateRow(0);
- }, 2000, this);
-
- // Prevent a reference through closures
- boxObject = null;
- },
-
- get rowCount() {
- return (this.data && this.data.length ? this.data.length : 1);
- },
-
- getCellText: function(row, col) {
- col = col.id;
-
- if (col != "type" && col != "address" && col != "filter" && col != "size" && col != "docDomain")
- return "";
-
- if (this.data && this.data.length) {
- if (row >= this.data.length)
- return "";
-
- if (col == "type")
- return this.data[row].localizedDescr;
- else if (col == "filter")
- return (this.data[row].filter ? this.data[row].filter.text : "");
- else if (col == "size")
- {
- let size = getItemSize(this.data[row]);
- return (size ? size.join(" x ") : "");
- }
- else if (col == "docDomain")
- return this.data[row].docDomain + " " + (this.data[row].thirdParty ? docDomainThirdParty : docDomainFirstParty);
- else
- return this.data[row].location;
- }
- else {
- // Empty list, show dummy
- if (row > 0 || (col != "address" && col != "filter"))
- return "";
-
- if (col == "filter") {
- var filter = Policy.isWindowWhitelisted(window.content);
- return filter ? filter.text : "";
- }
-
- return (Policy.isWindowWhitelisted(window.content) ? this.whitelistDummy : this.itemsDummy);
- }
- },
-
- getColumnProperties: function(col, properties) {
- col = col.id;
-
- if ("col-" + col in this.atoms)
- properties.AppendElement(this.atoms["col-" + col]);
- },
-
- getRowProperties: function(row, properties) {
- if (row >= this.rowCount)
- return;
-
- properties.AppendElement(this.atoms["selected-" + this.selection.isSelected(row)]);
-
- var state;
- if (this.data && this.data.length) {
- properties.AppendElement(this.atoms["dummy-false"]);
-
- let filter = this.data[row].filter;
- if (filter)
- properties.AppendElement(this.atoms["filter-disabled-" + filter.disabled]);
-
- state = "state-regular";
- if (filter && !filter.disabled)
- {
- if (filter instanceof WhitelistFilter)
- state = "state-whitelisted";
- else if (filter instanceof BlockingFilter)
- state = "state-filtered";
- else if (filter instanceof ElemHideFilter)
- state = "state-hidden";
- }
- }
- else {
- properties.AppendElement(this.atoms["dummy-true"]);
-
- state = "state-filtered";
- if (this.data && Policy.isWindowWhitelisted(window.content))
- state = "state-whitelisted";
- }
- properties.AppendElement(this.atoms[state]);
- },
-
- getCellProperties: function(row, col, properties)
- {
- this.getColumnProperties(col, properties);
- this.getRowProperties(row, properties);
- },
-
- cycleHeader: function(col) {
- col = col.id;
-
- col = E(col);
- if (!col)
- return;
-
- var cycle = {
- natural: 'ascending',
- ascending: 'descending',
- descending: 'natural'
- };
-
- var curDirection = "natural";
- if (this.sortColumn == col)
- curDirection = col.getAttribute("sortDirection");
- else if (this.sortColumn)
- this.sortColumn.removeAttribute("sortDirection");
-
- curDirection = cycle[curDirection];
-
- if (curDirection == "natural")
- this.sortProc = null;
- else
- this.sortProc = this.sortProcs[col.id + (curDirection == "descending" ? "Desc" : "")];
-
- if (this.data)
- this.refilter();
-
- col.setAttribute("sortDirection", curDirection);
- this.sortColumn = col;
-
- this.boxObject.invalidate();
- },
-
- isSorted: function() {
- return this.sortProc;
- },
-
- isContainer: function() {return false},
- isContainerOpen: function() {return false},
- isContainerEmpty: function() {return false},
- getLevel: function() {return 0},
- getParentIndex: function() {return -1},
- hasNextSibling: function() {return false},
- toggleOpenState: function() {},
- canDrop: function() {return false},
- drop: function() {},
- getCellValue: function() {return null},
- getProgressMode: function() {return null},
- getImageSrc: function() {return null},
- isSeparator: function() {return false},
- isEditable: function() {return false},
- cycleCell: function() {},
- performAction: function() {},
- performActionOnRow: function() {},
- performActionOnCell: function() {},
- selectionChanged: function() {},
-
- //
- // Custom properties and methods
- //
-
- boxObject: null,
- atoms: null,
- filter: "",
- data: null,
- allData: [],
- dataMap: {__proto__: null},
- sortColumn: null,
- sortProc: null,
- resortTimeout: null,
- itemsDummy: null,
- whitelistDummy: null,
- itemsDummyTooltip: null,
- whitelistDummyTooltip: null,
- itemToSelect: null,
-
- sortProcs: {
- address: sortByAddress,
- addressDesc: sortByAddressDesc,
- type: createSortWithFallback(compareType, sortByAddress, false),
- typeDesc: createSortWithFallback(compareType, sortByAddress, true),
- filter: createSortWithFallback(compareFilter, sortByAddress, false),
- filterDesc: createSortWithFallback(compareFilter, sortByAddress, true),
- state: createSortWithFallback(compareState, sortByAddress, false),
- stateDesc: createSortWithFallback(compareState, sortByAddress, true),
- size: createSortWithFallback(compareSize, sortByAddress, false),
- sizeDesc: createSortWithFallback(compareSize, sortByAddress, true),
- docDomain: createSortWithFallback(compareDocDomain, sortByAddress, false),
- docDomainDesc: createSortWithFallback(compareDocDomain, sortByAddress, true)
- },
-
- clearData: function(data) {
- var oldRows = this.rowCount;
-
- this.allData = [];
- this.dataMap = {__proto__: null};
- this.refilter();
-
- this.boxObject.rowCountChanged(0, -oldRows);
- this.boxObject.rowCountChanged(0, this.rowCount);
- },
-
- addItem: function(/**Node*/ node, /**RequestEntry*/ item, /**Boolean*/ scanComplete)
- {
- // Merge duplicate entries
- let key = item.location + " " + item.type + " " + item.docDomain;
- if (key in this.dataMap)
- {
- // We know this item already - take over the filter if any and be done with it
- let existing = this.dataMap[key];
- if (item.filter)
- existing.filter = item.filter;
-
- existing.nodes.push(node);
- this.invalidateItem(existing);
- return;
- }
-
- // Add new item to the list
- // Store original item in orig property - reading out prototype is messed up in Gecko 1.9.2
- item = {__proto__: item, orig: item, nodes: [node]};
- this.allData.push(item);
- this.dataMap[key] = item;
-
- // Show disabled filters if no other filter applies
- if (!item.filter)
- item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
-
- if (!this.matchesFilter(item))
- return;
-
- let index = -1;
- if (this.sortProc && this.sortColumn && this.sortColumn.id == "size")
- {
- // Sorting by size requires accessing content document, and that's
- // dangerous from a content policy (and we are likely called directly
- // from a content policy call). Size data will be inaccurate anyway,
- // delay sorting until later.
- if (this.resortTimeout)
- clearTimeout(this.resortTimeout);
- this.resortTimeout = setTimeout(function(me)
- {
- if (me.sortProc)
- me.data.sort(me.sortProc);
- me.boxObject.invalidate();
- }, 500, this);
- }
- else if (this.sortProc)
- for (var i = 0; index < 0 && i < this.data.length; i++)
- if (this.sortProc(item, this.data[i]) < 0)
- index = i;
-
- if (index >= 0)
- this.data.splice(index, 0, item);
- else {
- this.data.push(item);
- index = this.data.length - 1;
- }
-
- if (this.data.length == 1)
- this.boxObject.invalidateRow(0);
- else
- this.boxObject.rowCountChanged(index, 1);
-
- if (this.itemToSelect == key)
- {
- this.selection.select(index);
- this.boxObject.ensureRowIsVisible(index);
- this.itemToSelect = null;
- }
- else if (!scanComplete && this.selection.currentIndex >= 0) // Keep selected row visible while scanning
- this.boxObject.ensureRowIsVisible(this.selection.currentIndex);
- },
-
- updateFilters: function()
- {
- for each (let item in this.allData)
- {
- if (item.filter instanceof RegExpFilter && item.filter.disabled)
- delete item.filter;
- if (!item.filter)
- item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty);
- }
- this.refilter();
- },
-
- /**
- * Updates the list after a filter or sorting change.
- */
- refilter: function()
- {
- if (this.resortTimeout)
- clearTimeout(this.resortTimeout);
-
- this.data = this.allData.filter(this.matchesFilter, this);
-
- if (this.sortProc)
- this.data.sort(this.sortProc);
- },
-
- /**
- * Tests whether an item matches current list filter.
- * @return {Boolean} true if the item should be shown
- */
- matchesFilter: function(item)
- {
- if (!this.filter)
- return true;
-
- return (item.location.toLowerCase().indexOf(this.filter) >= 0 ||
- (item.filter && item.filter.text.toLowerCase().indexOf(this.filter) >= 0) ||
- item.localizedDescr.toLowerCase().indexOf(this.filter) >= 0 ||
- (item.docDomain && item.docDomain.toLowerCase().indexOf(this.filter) >= 0) ||
- (item.docDomain && item.thirdParty && docDomainThirdParty.toLowerCase().indexOf(this.filter) >= 0) ||
- (item.docDomain && !item.thirdParty && docDomainFirstParty.toLowerCase().indexOf(this.filter) >= 0));
- },
-
- setFilter: function(filter) {
- var oldRows = this.rowCount;
-
- this.filter = filter.toLowerCase();
- this.refilter();
-
- var newRows = this.rowCount;
- if (oldRows != newRows)
- this.boxObject.rowCountChanged(oldRows < newRows ? oldRows : newRows, this.rowCount - oldRows);
- this.boxObject.invalidate();
- },
-
- selectAll: function() {
- this.selection.selectAll();
- },
-
- getSelectedItem: function() {
- if (!this.data || this.selection.currentIndex < 0 || this.selection.currentIndex >= this.data.length)
- return null;
-
- return this.data[this.selection.currentIndex];
- },
-
- getAllSelectedItems: function() {
- let result = [];
- if (!this.data)
- return result;
-
- let numRanges = this.selection.getRangeCount();
- for (let i = 0; i < numRanges; i++)
- {
- let min = {};
- let max = {};
- let range = this.selection.getRangeAt(i, min, max);
- for (let j = min.value; j <= max.value; j++)
- {
- if (j >= 0 && j < this.data.length)
- result.push(this.data[j]);
- }
- }
- return result;
- },
-
- getItemAt: function(x, y)
- {
- if (!this.data)
- return null;
-
- var row = this.boxObject.getRowAt(x, y);
- if (row < 0 || row >= this.data.length)
- return null;
-
- return this.data[row];
- },
-
- getColumnAt: function(x, y)
- {
- if (!this.data)
- return null;
-
- let col = {};
- this.boxObject.getCellAt(x, y, {}, col, {});
- if (col.value)
- return col.value.id;
- },
-
- getDummyTooltip: function() {
- if (!this.data || this.data.length)
- return null;
-
- var filter = Policy.isWindowWhitelisted(window.content);
- if (filter)
- return {tooltip: this.whitelistDummyTooltip, filter: filter};
- else
- return {tooltip: this.itemsDummyTooltip};
- },
-
- invalidateItem: function(item)
- {
- let row = this.data.indexOf(item);
- if (row >= 0)
- this.boxObject.invalidateRow(row);
- }
-}
diff --git a/chrome/content/ui/sidebar.xul b/chrome/content/ui/sidebar.xul
deleted file mode 100644
index 2df559f..0000000
--- a/chrome/content/ui/sidebar.xul
+++ /dev/null
@@ -1,145 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/sidebar.css" type="text/css"?>
-
-<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd">
-
-<page
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="abp-sidebar"
- onload="init()"
- onunload="cleanUp()"
- docDomainThirdParty="&docDomain.thirdParty;"
- docDomainFirstParty="&docDomain.firstParty;">
-
- <script type="application/x-javascript;version=1.7" src="utils.js"/>
- <script type="application/x-javascript;version=1.7" src="sidebar.js"/>
- <script type="application/x-javascript;version=1.7" src="flasher.js"/>
-
- <keyset id="sidebarKeys">
- <key id="block-key" keycode="VK_ENTER"/>
- <key id="copy-key" modifiers="accel" key="C" command="copy-command"/>
- <key id="selectAll-key" modifiers="accel" key="A" command="selectAll-command"/>
- </keyset>
-
- <commandset id="sidebarCommands">
- <command id="copy-command" oncommand="copyToClipboard()" disabled="true"/>
- <command id="selectAll-command" oncommand="selectAll()"/>
- </commandset>
-
- <popupset id="sidebarPopups">
- <tooltip id="tooltip" orient="vertical" onpopupshowing="return fillInTooltip(event);">
- <description id="tooltipDummy"/>
- <hbox id="tooltipPreviewBox" pack="start">
- <image id="tooltipPreview" validate="never"/>
- </hbox>
- <grid>
- <columns>
- <column/>
- <column flex="1"/>
- </columns>
- <rows>
- <row id="tooltipAddressRow" align="top">
- <label value="&tooltip.address.label;"/>
- <vbox id="tooltipAddress"/>
- </row>
- <row id="tooltipTypeRow">
- <label value="&tooltip.type.label;"/>
- <description id="tooltipType" filtered="&tooltip.type.blocked;" whitelisted="&tooltip.type.whitelisted;"/>
- </row>
- <row id="tooltipSizeRow">
- <label value="&tooltip.size.label;"/>
- <description id="tooltipSize"/>
- </row>
- <row id="tooltipDocDomainRow">
- <label value="&tooltip.docDomain.label;"/>
- <description id="tooltipDocDomain"/>
- </row>
- <row id="tooltipFilterRow" align="top">
- <label value="&tooltip.filter.label;"/>
- <vbox id="tooltipFilter" disabledText="&tooltip.filter.disabled;"/>
- </row>
- <row id="tooltipFilterSourceRow" align="top">
- <label value="&tooltip.filterSource.label;"/>
- <vbox id="tooltipFilterSource"/>
- </row>
- </rows>
- </grid>
- </tooltip>
-
- <menupopup id="context" onpopupshowing="return fillInContext(event)">
- <menuitem id="contextBlock" label="&context.block.label;â¦" oncommand="doBlock()" key="block-key"/>
- <menuitem id="contextWhitelist" label="&context.whitelist.label;â¦" oncommand="doBlock()" key="block-key"/>
- <menuitem id="contextEditFilter" label="&context.editfilter.label;â¦" oncommand="editFilter()"/>
- <menuitem id="contextDisableFilter" labeltempl="&context.disablefilter.label;" oncommand="enableFilter(this.filter, false)"/>
- <menuitem id="contextEnableFilter" labeltempl="&context.enablefilter.label;" oncommand="enableFilter(this.filter, true)"/>
- <menuitem id="contextDisableOnSite" labeltempl="&context.disablefilteronsite.label;" oncommand="disableOnSite(this.item, this.filter, this.domain)"/>
- <menuseparator id="contextOpenSep"/>
- <menuitem id="contextOpen" label="&context.open.label;" oncommand="openInTab(null, event)"/>
- <menuitem id="contextFlash" label="&context.flash.label;" oncommand="onSelectionChange()"/>
- <menuitem id="contextCopy" label="&context.copy.label;" command="copy-command" key="copy-key"/>
- <menuitem id="contextCopyFilter" label="&context.copyFilter.label;" oncommand="copyFilter()"/>
- <menuseparator id="contextSelectSep"/>
- <menuitem id="contextSelectAll" label="&context.selectAll.label;" command="selectAll-command" key="selectAll-key"/>
- </menupopup>
- </popupset>
-
- <hbox>
- <hbox align="center" flex="1">
- <label value="&search.label;" accesskey="&search.accesskey;" control="searchField"/>
- <textbox id="searchField" flex="1" type="search" oncommand="treeView.setFilter(this.value)"/>
- </hbox>
- <description id="detachButton" value="&detach.label;" onclick="detach(true)"/>
- <description id="reattachButton" value="&reattach.label;" onclick="if (this.getAttribute('disabled') != 'true') detach(false)" hidden="true"/>
- </hbox>
-
- <tree id="list" context="context" flex="1" seltype="multiple" enableColumnDrag="true"
- defaultSort="state descending" persist="defaultSort"
- onkeypress="if (event.keyCode == event.DOM_VK_RETURN || event.keyCode == event.DOM_VK_ENTER) doBlock()">
- <treecols>
- <treecol id="address" label="&address.label;" flex="2" crop="center" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="filter" label="&filter.label;" flex="1" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="type" label="&type.label;" width="80" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="state" label="&state.label;" width="16" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="size" label="&size.label;" width="60" hidden="true" persist="width ordinal sortDirection hidden"/>
- <splitter class="tree-splitter"/>
- <treecol id="docDomain" label="&docDomain.label;" width="100" hidden="true" persist="width ordinal sortDirection hidden"/>
- </treecols>
-
- <treechildren id="treechildren"
- tooltip="tooltip"
- onclick="handleClick(event)"
- ondblclick="handleDblClick(event)"
- noitemslabel="&noitems.label;"
- whitelistedlabel="&whitelisted.label;"/>
- </tree>
-</page>
diff --git a/chrome/content/ui/sidebarDetached.xul b/chrome/content/ui/sidebarDetached.xul
deleted file mode 100644
index 4f0eece..0000000
--- a/chrome/content/ui/sidebarDetached.xul
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-
-<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd">
-
-<window
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- id="abpDetachedSidebar"
- title="&detached.title;"
- persist="screenX screenY width height sizemode"
- onclose="document.getElementById('abp-command-sidebar').doCommand(); return false;">
-
- <script type="application/x-javascript">
- // Some people actually switch off browser.frames.enabled and are surprised
- // that things stop working...
- window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocShell)
- .allowSubframes = true;
- </script>
-
- <keyset id="detached-keyset">
- <key keycode="VK_ESCAPE" command="abp-command-sidebar"/>
- <key modifiers="accel" key="w" command="abp-command-sidebar"/>
- </keyset>
-
- <commandset id="detached-commandset">
- <command id="abp-command-sidebar" oncommand="document.getElementById('sidebarFrame').contentWindow.doClose()"/>
- </commandset>
-
- <iframe src="sidebar.xul" id="sidebarFrame" flex="1"/>
-</window>
diff --git a/chrome/content/ui/subscriptionSelection.js b/chrome/content/ui/subscriptionSelection.js
deleted file mode 100644
index 269d6d1..0000000
--- a/chrome/content/ui/subscriptionSelection.js
+++ /dev/null
@@ -1,671 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-let newInstall = true;
-let savedDialogFlex = null;
-let editMode = true;
-let autoAdd = false;
-let source = null;
-let result = null;
-let initialized = false;
-
-/**
- * Suppresses window resizing while the window is loading or if the window is loaded in a browser tab.
- * @type Boolean
- */
-let suppressResize = true;
-
-let closing = false;
-let subscriptionListLoading = false;
-let otherButton = null;
-
-function init()
-{
- if (window.arguments && window.arguments.length)
- {
- newInstall = false;
- [source, result] = window.arguments;
- if (window.arguments.length > 2 && window.arguments[2])
- window.hasSubscription = window.arguments[2];
- }
-
- if (newInstall && Utils.isFennec)
- {
- // HACK: In Fennec 4.0 menulist elements won't work "by themselves". We
- // have to go to the top level and trigger MenuListHelperUI manually.
- let topWnd = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- if (topWnd.wrappedJSObject)
- topWnd = topWnd.wrappedJSObject;
-
- let menulist = E("subscriptions");
- if ("MenuListHelperUI" in topWnd && menulist.parentNode.localName != "stack")
- {
- // Add a layer on top of the menulist to handle clicks, menulist clicks
- // are otherwise ignored and cannot be intercepted
- let stack = document.createElement("stack");
- menulist.parentNode.replaceChild(stack, menulist);
- stack.appendChild(menulist);
-
- let clickLayer = document.createElement("hbox");
- stack.appendChild(clickLayer);
-
- clickLayer.addEventListener("click", function(event)
- {
- if (event.button == 0 && !menulist.disabled && menulist.itemCount)
- {
- menulist.focus();
- topWnd.MenuListHelperUI.show(menulist);
- }
- }, true);
-
- // menulist needs to be initialized after being moved, re-run init() later
- Utils.runAsync(init);
- return;
- }
-
- // The template is being displayed as a list item, remove it
- let subscriptionsTemplate = E("subscriptionsTemplate");
- if (subscriptionsTemplate && subscriptionsTemplate.parentNode)
- subscriptionsTemplate.parentNode.removeChild(subscriptionsTemplate);
-
- // window.close() closes the entire window (bug 642604), make sure to close
- // only a single tab instead.
- if ("BrowserUI" in topWnd)
- {
- window.close = function()
- {
- topWnd.BrowserUI.closeTab();
- };
- }
- }
-
- if (!result)
- {
- result = {};
- autoAdd = true;
- }
- if (!source)
- {
- editMode = false;
- source = {title: "", url: "", disabled: false, external: false, autoDownload: true, mainSubscriptionTitle: null, mainSubscriptionURL: null};
- }
- else
- {
- if (typeof source.mainSubscriptionURL == "undefined")
- source.mainSubscriptionURL = source.mainSubscriptionTitle = null;
- }
-
- if (newInstall && !Utils.isFennec)
- {
- // HACK: We will remove dialog content box flex if a subscription is
- // selected, need to find the content box and save it flex value.
- let docContent = document.getAnonymousNodes(document.documentElement);
- docContent = (docContent && docContent.length ? docContent[0] : null);
- if (docContent && docContent.hasAttribute("class") &&
- /\bdialog-content-box\b/.test(docContent.getAttribute("class")) &&
- docContent.hasAttribute("flex"))
- {
- savedDialogFlex = [docContent, docContent.getAttribute("flex")]
- }
- }
-
- E("description-newInstall").hidden = !newInstall;
- if (newInstall)
- document.documentElement.setAttribute("newInstall", "true");
-
- E("subscriptionsBox").hidden = E("all-subscriptions-container").hidden
- = E("subscriptionInfo").hidden = editMode;
-
- E("fromWebText").hidden = !editMode || source instanceof Subscription;
- E("editText").hidden = !(source instanceof Subscription) || source instanceof ExternalSubscription;
- E("externalText").hidden = !(source instanceof ExternalSubscription);
- E("differentSubscription").hidden = !editMode;
-
- otherButton = document.documentElement.getButton("extra2");
- if (!editMode)
- {
- // Transform the button into a text link
- let link = document.createElement("label");
- link.setAttribute("id", "otherButton");
- link.setAttribute("class", "text-link");
- link.setAttribute("value", otherButton.label);
- link.setAttribute("accesskey", otherButton.accessKey);
- link.setAttribute("control", "otherButton");
- link.setAttribute("flex", "1");
- link.setAttribute("crop", "end");
-
- let handler = new Function("event", document.documentElement.getAttribute("ondialogextra2"));
- link.addEventListener("command", handler, false);
- link.addEventListener("click", handler, false);
- link.addEventListener("keypress", function(event)
- {
- if (event.keyCode == event.DOM_VK_ENTER || event.keyCode == event.DOM_VK_RETURN)
- {
- this.doCommand();
- event.preventDefault();
- }
- }, false);
-
- otherButton.parentNode.setAttribute("align", "center");
- otherButton.parentNode.replaceChild(link, otherButton);
- otherButton = link;
- }
- otherButton.hidden = editMode;
-
- setCustomSubscription(source.title, source.url,
- source.mainSubscriptionTitle, source.mainSubscriptionURL);
-
- if (source instanceof Subscription)
- {
- document.title = document.documentElement.getAttribute("edittitle");
- document.documentElement.getButton("accept").setAttribute("label", document.documentElement.getAttribute("buttonlabelacceptedit"))
- }
-
- if (source instanceof ExternalSubscription)
- {
- E("location").setAttribute("disabled", "true");
- E("autoDownload").setAttribute("disabled", "true");
- E("autoDownload").checked = true;
- }
- else
- E("autoDownload").checked = source.autoDownload;
-
- initialized = true;
-
- if (!editMode)
- {
- let list = E("subscriptions");
- let items = list.menupopup.childNodes;
- let selectedItem = null;
- let selectedPrefix = null;
- let matchCount = 0;
- for (let i = 0; i < items.length; i++)
- {
- let item = items[i];
- let prefixes = item.getAttribute("_prefixes");
- if (!prefixes)
- continue;
-
- if (!selectedItem)
- selectedItem = item;
-
- let prefix = checkPrefixMatch(prefixes, Utils.appLocale);
- if (prefix)
- {
- item.setAttribute("class", "localeMatch");
- if (!selectedPrefix || selectedPrefix.length < prefix.length)
- {
- selectedItem = item;
- selectedPrefix = prefix;
- matchCount = 1;
- }
- else if (selectedPrefix && selectedPrefix.length == prefix.length)
- {
- matchCount++;
-
- // If multiple items have a matching prefix of the same length:
- // Select one of the items randomly, probability should be the same
- // for all items. So we replace the previous match here with
- // probability 1/N (N being the number of matches).
- if (Math.random() * matchCount < 1)
- {
- selectedItem = item;
- selectedPrefix = prefix;
- }
- }
- }
- }
- list.selectedItem = selectedItem;
- }
-
- // Only resize if we are a chrome window (not loaded into a browser tab)
- if (window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShellTreeItem).itemType == Ci.nsIDocShellTreeItem.typeChrome)
- suppressResize = false;
-}
-
-function checkPrefixMatch(prefixes, appLocale)
-{
- if (!prefixes)
- return null;
-
- for each (let prefix in prefixes.split(/,/))
- if (new RegExp("^" + prefix + "\\b").test(appLocale))
- return prefix;
-
- return null;
-}
-
-function collapseElements()
-{
- if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL)
- {
- let diff = 0;
- for (let i = 0; i < arguments.length; i++)
- diff -= arguments[i].boxObject.height;
- window.resizeBy(0, diff);
- window.moveBy(0, -diff/2);
- }
- for (let i = 0; i < arguments.length; i++)
- arguments[i].hidden = true;
-}
-
-function showElements()
-{
- for (let i = 0; i < arguments.length; i++)
- arguments[i].hidden = false;
-
- let scrollBox = E("content-scroll").boxObject;
- if (!suppressResize && window.windowState == Ci.nsIDOMChromeWindow.STATE_NORMAL && scrollBox instanceof Ci.nsIScrollBoxObject)
- {
- // Force reflow
- for (let i = 0; i < arguments.length; i++)
- arguments[i].boxObject.height;
-
- let scrollHeight = {};
- scrollBox.getScrolledSize({}, scrollHeight);
- if (scrollHeight.value > scrollBox.height)
- {
- let diff = scrollHeight.value - scrollBox.height;
- window.resizeBy(0, diff);
- window.moveBy(0, -diff/2);
- }
- }
-}
-
-function onSelectionChange()
-{
- if (!initialized)
- return;
-
- let selectedSubscription = E("subscriptions").value;
-
- // Show/hide extra UI widgets for custom subscriptions, resize window appropriately
- let container = E("all-subscriptions-container");
- let inputFields = E("differentSubscription");
- if (container.hidden && !selectedSubscription)
- showElements(container, inputFields);
- else if (!container.hidden && selectedSubscription)
- collapseElements(container, inputFields);
-
- // Make sure to hide "Add different subscription button" if we are already in that mode
- otherButton.hidden = !selectedSubscription;
-
- if (!selectedSubscription)
- {
- loadSubscriptionList();
- E("title").focus();
- }
-
- if (savedDialogFlex)
- {
- let [docContent, flex] = savedDialogFlex;
- if (selectedSubscription)
- docContent.removeAttribute("flex");
- else
- docContent.setAttribute("flex", flex);
- }
-
- updateSubscriptionInfo();
-}
-
-function updateSubscriptionInfo()
-{
- let selectedSubscription = E("subscriptions").selectedItem;
- if (!selectedSubscription.value)
- selectedSubscription = E("all-subscriptions").selectedItem;
-
- E("subscriptionInfo").setAttribute("invisible", !selectedSubscription);
- if (selectedSubscription)
- {
- let url = selectedSubscription.getAttribute("_url");
- let homePage = selectedSubscription.getAttribute("_homepage")
-
- let viewLink = E("view-list");
- viewLink.setAttribute("_url", url);
- viewLink.setAttribute("tooltiptext", url);
-
- let homePageLink = E("visit-homepage");
- homePageLink.hidden = !homePage;
- if (homePage)
- {
- homePageLink.setAttribute("_url", homePage);
- homePageLink.setAttribute("tooltiptext", homePage);
- }
- }
-}
-
-function reloadSubscriptionList()
-{
- subscriptionListLoading = false;
- loadSubscriptionList();
-}
-
-function loadSubscriptionList()
-{
- if (subscriptionListLoading)
- return;
-
- E("all-subscriptions-container").selectedIndex = 0;
- E("all-subscriptions-loading").hidden = false;
-
- let request = new XMLHttpRequest();
- let errorHandler = function()
- {
- E("all-subscriptions-container").selectedIndex = 2;
- E("all-subscriptions-loading").hidden = true;
- };
- let successHandler = function()
- {
- if (!request.responseXML || request.responseXML.documentElement.localName != "subscriptions")
- {
- errorHandler();
- return;
- }
-
- try
- {
- processSubscriptionList(request.responseXML);
- }
- catch (e)
- {
- Cu.reportError(e);
- errorHandler();
- }
- };
-
- request.open("GET", Prefs.subscriptions_listurl);
- request.onerror = errorHandler;
- request.onload = successHandler;
- request.send(null);
-
- subscriptionListLoading = true;
-}
-
-function processSubscriptionList(doc)
-{
- let list = E("all-subscriptions");
- while (list.firstChild)
- list.removeChild(list.firstChild);
-
- addSubscriptions(list, doc.documentElement, 0, null, null);
- E("all-subscriptions-container").selectedIndex = 1;
- E("all-subscriptions-loading").hidden = true;
-}
-
-function addSubscriptions(list, parent, level, parentTitle, parentURL)
-{
- for (let i = 0; i < parent.childNodes.length; i++)
- {
- let node = parent.childNodes[i];
- if (node.nodeType != Node.ELEMENT_NODE || node.localName != "subscription")
- continue;
-
- if (node.getAttribute("type") != "ads" || node.getAttribute("deprecated") == "true")
- continue;
-
- let variants = node.getElementsByTagName("variants");
- if (!variants.length || !variants[0].childNodes.length)
- continue;
- variants = variants[0].childNodes;
-
- let isFirst = true;
- let mainTitle = null;
- let mainURL = null;
- for (let j = 0; j < variants.length; j++)
- {
- let variant = variants[j];
- if (variant.nodeType != Node.ELEMENT_NODE || variant.localName != "variant")
- continue;
-
- let item = document.createElement("richlistitem");
- item.setAttribute("_title", variant.getAttribute("title"));
- item.setAttribute("_url", variant.getAttribute("url"));
- if (parentTitle && parentURL && variant.getAttribute("complete") != "true")
- {
- item.setAttribute("_supplementForTitle", parentTitle);
- item.setAttribute("_supplementForURL", parentURL);
- }
- item.setAttribute("tooltiptext", variant.getAttribute("url"));
- item.setAttribute("_homepage", node.getAttribute("homepage"));
-
- let title = document.createElement("description");
- if (isFirst)
- {
- if (checkPrefixMatch(node.getAttribute("prefixes"), Utils.appLocale))
- title.setAttribute("class", "subscriptionTitle localeMatch");
- else
- title.setAttribute("class", "subscriptionTitle");
- title.textContent = node.getAttribute("title");
- mainTitle = variant.getAttribute("title");
- mainURL = variant.getAttribute("url");
- isFirst = false;
- }
- title.setAttribute("flex", "1");
- title.style.marginLeft = (20 * level) + "px";
- item.appendChild(title);
-
- let variantTitle = document.createElement("description");
- variantTitle.setAttribute("class", "variant");
- variantTitle.textContent = variant.getAttribute("title");
- variantTitle.setAttribute("crop", "end");
- item.appendChild(variantTitle);
-
- list.appendChild(item);
- }
-
- let supplements = node.getElementsByTagName("supplements");
- if (supplements.length)
- addSubscriptions(list, supplements[0], level + 1, mainTitle, mainURL);
- }
-}
-
-function onAllSelectionChange()
-{
- let selectedItem = E("all-subscriptions").selectedItem;
- if (!selectedItem)
- return;
-
- setCustomSubscription(selectedItem.getAttribute("_title"), selectedItem.getAttribute("_url"),
- selectedItem.getAttribute("_supplementForTitle"), selectedItem.getAttribute("_supplementForURL"));
-
- updateSubscriptionInfo();
-}
-
-function setCustomSubscription(title, url, mainSubscriptionTitle, mainSubscriptionURL)
-{
- E("title").value = title;
- E("location").value = url;
-
- let messageElement = E("supplementMessage");
- let addMainCheckbox = E("addMainSubscription");
- if (mainSubscriptionURL && !hasSubscription(mainSubscriptionURL))
- {
- if (messageElement.hidden)
- showElements(messageElement, addMainCheckbox);
-
- let beforeLink, afterLink;
- if (/(.*)\?1\?(.*)/.test(messageElement.getAttribute("_textTemplate")))
- [beforeLink, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
- else
- [beforeLink, afterLink] = [messageElement.getAttribute("_textTemplate"), ""];
-
- while (messageElement.firstChild)
- messageElement.removeChild(messageElement.firstChild);
- messageElement.appendChild(document.createTextNode(beforeLink));
- let link = document.createElement("label");
- link.className = "text-link";
- link.setAttribute("tooltiptext", mainSubscriptionURL);
- link.addEventListener("click", function() Utils.loadInBrowser(mainSubscriptionURL), false);
- link.textContent = mainSubscriptionTitle;
- messageElement.appendChild(link);
- messageElement.appendChild(document.createTextNode(afterLink));
-
- addMainCheckbox.value = mainSubscriptionURL;
- addMainCheckbox.setAttribute("_mainSubscriptionTitle", mainSubscriptionTitle)
- addMainCheckbox.label = addMainCheckbox.getAttribute("_labelTemplate").replace(/\?1\?/g, mainSubscriptionTitle);
- addMainCheckbox.accessKey = addMainCheckbox.accessKey;
- }
- else if (!messageElement.hidden)
- collapseElements(messageElement, addMainCheckbox);
-}
-
-function selectCustomSubscription()
-{
- let list = E("subscriptions")
- list.selectedItem = list.menupopup.lastChild;
-}
-
-function validateURL(url)
-{
- url = url.replace(/^\s+/, "").replace(/\s+$/, "");
-
- // Is this a file path?
- try {
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
- file.initWithPath(url);
- return Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newFileURI(file).spec;
- } catch (e) {}
-
- // Is this a valid URL?
- let uri = Utils.makeURI(url);
- if (uri)
- return uri.spec;
-
- return null;
-}
-
-function addSubscription()
-{
- let list = E("subscriptions");
- let url;
- let title;
- let autoDownload;
- if (list.value)
- {
- url = list.value;
- title = list.label;
- autoDownload = true;
- }
- else
- {
- url = E("location").value;
- if (!(source instanceof ExternalSubscription))
- url = validateURL(url);
- if (!url)
- {
- Utils.alert(window, Utils.getString("subscription_invalid_location"));
- E("location").focus();
- return false;
- }
-
- title = E("title").value.replace(/^\s+/, "").replace(/\s+$/, "");
- if (!title)
- title = url;
-
- autoDownload = E("autoDownload").checked;
- }
-
- result.url = url;
- result.title = title;
- result.autoDownload = autoDownload;
- result.disabled = source.disabled;
-
- let addMainCheckbox = E("addMainSubscription")
- if (!addMainCheckbox.hidden && addMainCheckbox.checked)
- {
- result.mainSubscriptionTitle = addMainCheckbox.getAttribute("_mainSubscriptionTitle");
- result.mainSubscriptionURL = addMainCheckbox.value;
- }
-
- if (autoAdd)
- {
- doAddSubscription(result.url, result.title, result.autoDownload, result.disabled);
- if ("mainSubscriptionURL" in result)
- doAddSubscription(result.mainSubscriptionURL, result.mainSubscriptionTitle, result.autoDownload, result.disabled);
- }
-
- closing = true;
- return true;
-}
-
-/**
- * Adds a new subscription to the list.
- */
-function doAddSubscription(/**String*/ url, /**String*/ title, /**Boolean*/ autoDownload, /**Boolean*/ disabled)
-{
- if (typeof autoDownload == "undefined")
- autoDownload = true;
- if (typeof disabled == "undefined")
- disabled = false;
-
- let subscription = Subscription.fromURL(url);
- if (!subscription)
- return;
-
- FilterStorage.addSubscription(subscription);
-
- if (disabled != subscription.disabled)
- {
- subscription.disabled = disabled;
- FilterStorage.triggerObservers(disabled ? "subscriptions disable" : "subscriptions enable", [subscription]);
- }
-
- subscription.title = title;
- if (subscription instanceof DownloadableSubscription)
- subscription.autoDownload = autoDownload;
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
-
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- FilterStorage.saveToDisk();
-}
-
-function hasSubscription(url)
-{
- return FilterStorage.subscriptions.some(function(subscription) subscription instanceof DownloadableSubscription && subscription.url == url);
-}
-
-function checkUnload()
-{
- if (newInstall && !closing)
- return Utils.getString("subscription_notAdded_warning");
-
- return undefined;
-}
-
-function onDialogCancel()
-{
- let message = checkUnload();
- if (!message)
- return true;
-
- message += " " + Utils.getString("subscription_notAdded_warning_addendum");
- closing = Utils.confirm(window, message);
- return closing;
-}
diff --git a/chrome/content/ui/subscriptionSelection.xul b/chrome/content/ui/subscriptionSelection.xul
deleted file mode 100644
index ca29701..0000000
--- a/chrome/content/ui/subscriptionSelection.xul
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://adblockplus/skin/subscriptionSelection.css" type="text/css"?>
-
-<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
-
-<dialog
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- buttons="accept,cancel,extra2"
- buttonlabelaccept="&addSubscription.label;"
- buttonlabelacceptedit="&saveSubscription.label;"
- buttonlabelextra2="&other.label;"
- buttonaccesskeyextra2="&other.accesskey;"
- title="&dialog.title;"
- edittitle="&dialog.title.edit;"
- id="abpSubscriptionSelection"
- windowtype="abp:subscriptionSelection"
- onload="init()"
- onbeforeunload="return checkUnload()"
- ondialogcancel="return onDialogCancel()"
- ondialogaccept="return addSubscription()"
- ondialogextra2="selectCustomSubscription()">
-
-<script type="application/x-javascript;version=1.7" src="utils.js"/>
-<script type="application/x-javascript;version=1.7" src="subscriptionSelection.js"/>
-
-<scrollbox id="content-scroll" orient="vertical" flex="1">
- <description id="description-newInstall">&description.newInstall;</description>
-
- <vbox id="subscriptionsBox">
- <label control="subscriptions">&subscriptionSelector.label;</label>
- <menulist id="subscriptions" label=" " onselect="onSelectionChange()">
- <menupopup datasources="subscriptions.xml" ref="*" querytype="xml">
- <template id="subscriptionsTemplate">
- <menuitem uri="?" label="?title" value="?url" _url="?url" _homepage="?homepage" _prefixes="?prefixes"/>
- </template>
- </menupopup>
- </menulist>
- </vbox>
-
- <deck id="all-subscriptions-container" selectedIndex="0" flex="1" hidden="true">
- <vbox pack="center">
- <progressmeter id="all-subscriptions-loading" mode="undetermined"/>
- </vbox>
- <richlistbox id="all-subscriptions" onselect="onAllSelectionChange()"/>
- <vbox pack="center" align="center">
- <description value="&list.download.failed;"/>
- <hbox>
- <button label="&list.download.retry;" oncommand="reloadSubscriptionList()"/>
- <button label="&list.download.website;" oncommand="Utils.loadDocLink('subscriptions')"/>
- </hbox>
- </vbox>
- </deck>
-
- <hbox id="subscriptionInfo" invisible="true">
- <label id="view-list" class="text-link" value="&viewList.label;" onclick="Utils.loadInBrowser(this.getAttribute('_url'))"/>
- <spacer flex="1"/>
- <label id="visit-homepage" class="text-link" value="&visitHomepage.label;" onclick="Utils.loadInBrowser(this.getAttribute('_url'))"/>
- </hbox>
-
- <description id="fromWebText" hidden="true">&fromWeb.description;</description>
- <description id="editText" hidden="true">&edit.description;</description>
- <description id="externalText" hidden="true">&external.description;</description>
-
- <groupbox id="differentSubscription" hidden="true">
- <label value="&title.label;" accesskey="&title.accesskey;" control="title"/>
- <textbox id="title"/>
-
- <label value="&location.label;" accesskey="&location.accesskey;" control="location"/>
- <textbox id="location"/>
-
- <checkbox id="autoDownload" label="&autodownload.label;" accesskey="&autodownload.accesskey;"/>
- </groupbox>
-
- <description id="supplementMessage" hidden="true" _textTemplate="&supplementMessage;">&supplementMessage;</description>
- <checkbox id="addMainSubscription" hidden="true" checked="true" _labelTemplate="&addMain.label;" label="&addMain.label;" accesskey="&addMain.accesskey;"/>
-</scrollbox>
-
-</dialog>
diff --git a/chrome/content/ui/subscriptions.xml b/chrome/content/ui/subscriptions.xml
deleted file mode 100644
index 90ac310..0000000
--- a/chrome/content/ui/subscriptions.xml
+++ /dev/null
@@ -1,61 +0,0 @@
-<?xml version="1.0"?>
-
-<!DOCTYPE subscriptions SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd">
-
-<subscriptions>
- <subscription title="EasyList (English)"
- url="https://easylist-downloads.adblockplus.org/easylist.txt"
- homepage="http://easylist.adblockplus.org/"
- prefixes="en"
- author="Michael, Ares2, Erunno, Khrin, MonztA"/>
- <subscription title="ABPindo+EasyList (Bahasa Indonesia)"
- url="https://easylist-downloads.adblockplus.org/abpindo+easylist.txt"
- homepage="http://indonesianfilter.blogspot.com/"
- prefixes="id"
- author="heradhis"/>
- <subscription title="Bulgarian list+EasyList (бÑлгаÑÑки)"
- url="https://easylist-downloads.adblockplus.org/bulgarian_list+easylist.txt"
- homepage="http://stanev.org/abp/"
- prefixes="bg"
- author="ÐлекÑандÑÑ Ð¡Ñанев"/>
- <subscription title="ChinaList+EasyList (䏿)"
- url="https://easylist-downloads.adblockplus.org/chinalist+easylist.txt"
- homepage="http://code.google.com/p/adblock-chinalist/"
- prefixes="zh"
- author="Gythialy"/>
- <subscription title="DutchAdblockList+EasyList (Nederlands)"
- url="https://easylist-downloads.adblockplus.org/dutchadblocklist+easylist.txt"
- homepage="http://sites.google.com/site/dutchadblockfilters/"
- prefixes="nl"
- author="Famlam"/>
- <subscription title="EasyList Germany+EasyList (Deutsch)"
- url="https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt"
- homepage="http://easylist.adblockplus.org/"
- prefixes="de"
- author="Ares2, Erunno, MonztA"/>
- <subscription title="Fanboy's List (English)"
- url="https://secure.fanboy.co.nz/fanboy-adblock.txt"
- homepage="http://www.fanboy.co.nz/adblock/"
- prefixes="en"
- author="fanboy, Nitrox"/>
- <subscription title="Liste FR+EasyList (français)"
- url="https://easylist-downloads.adblockplus.org/liste_fr+easylist.txt"
- homepage="http://adblock-listefr.com/"
- prefixes="fr"
- author="Lian"/>
- <subscription title="ROList+EasyList (românesc)"
- url="https://easylist-downloads.adblockplus.org/rolist+easylist.txt"
- homepage="http://www.zoso.ro/rolist"
- prefixes="ro"
- author="MenetZ, Zoso"/>
- <subscription title="RuAdList+EasyList (ÑÑÑÑкий, ÑкÑаÑнÑÑка)"
- url="https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt"
- homepage="http://code.google.com/p/ruadlist/"
- prefixes="ru,uk"
- author="Lain_13"/>
- <subscription title="&other.label;â¦"
- url=""
- homepage=""
- prefixes=""
- author=""/>
-</subscriptions>
\ No newline at end of file
diff --git a/chrome/content/ui/thunderbirdOverlay.xul b/chrome/content/ui/thunderbirdOverlay.xul
deleted file mode 100644
index f15f98a..0000000
--- a/chrome/content/ui/thunderbirdOverlay.xul
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0"?>
-
-<!-- ***** BEGIN LICENSE BLOCK *****
- - Version: MPL 1.1
- -
- - The contents of this file are subject to the Mozilla Public License Version
- - 1.1 (the "License"); you may not use this file except in compliance with
- - the License. You may obtain a copy of the License at
- - http://www.mozilla.org/MPL/
- -
- - Software distributed under the License is distributed on an "AS IS" basis,
- - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- - for the specific language governing rights and limitations under the
- - License.
- -
- - The Original Code is Adblock Plus.
- -
- - The Initial Developer of the Original Code is
- - Wladimir Palant.
- - Portions created by the Initial Developer are Copyright (C) 2006-2011
- - the Initial Developer. All Rights Reserved.
- -
- - Contributor(s):
- -
- - ***** END LICENSE BLOCK ***** -->
-
-<?xul-overlay href="chrome://adblockplus/content/ui/overlayGeneral.xul"?>
-
-<overlay id="abp-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <!-- Window extensions -->
- <window id="messengerWindow">
- <popupset id="abp-popupset"/>
- <keyset id="abp-keyset"/>
- <commandset id="abp-commandset"/>
- <box id="abp-hooks" getBrowser="return ('getBrowser' in this.window ? this.window.getBrowser() : this.window.messageContent);"
- addTab="this.E('tabmail').openTab('contentTab', {contentPage: arguments[0]});"
- getContextMenu="return this.E('mailContext') || this.E('messagePaneContext');"
- getToolbox="return this.E('mail-toolbox')"
- getDefaultToolbar="return this.E('mail-bar3');" toolbarInsertBefore="return this.E('button-tag');"/>
- </window>
-
- <!-- Status bar -->
- <statusbar id="status-bar">
- <statusbarpanel id="abp-status"/>
- </statusbar>
-
- <!-- Toolbar -->
- <toolbar id="header-view-toolbar">
- <toolbarbutton id="abp-toolbarbutton" type="menu-button" insertbefore="hdrReplyButton"
- class="toolbarbutton-1 msgHeaderView-button"/>
- </toolbar>
-
- <!-- Tools menu -->
- <menupopup id="taskPopup">
- <menuitem id="abp-menuitem" insertafter="downloadmgr,javaScriptConsole"/>
- </menupopup>
-
- <!-- Context menu -->
- <menupopup id="mailContext">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
- <menupopup id="messagePaneContext">
- <menuitem id="abp-image-menuitem"/>
- <menuitem id="abp-object-menuitem"/>
- <menuitem id="abp-media-menuitem"/>
- <menuitem id="abp-frame-menuitem"/>
- <menuitem id="abp-removeWhitelist-menuitem"/>
- </menupopup>
-
- <!-- Fake sidebar -->
- <vbox id="messagepanebox">
- <splitter id="abp-sidebar-splitter"/>
- <vbox id="abp-sidebar"/>
- </vbox>
-</overlay>
diff --git a/chrome/content/ui/utils.js b/chrome/content/ui/utils.js
deleted file mode 100644
index 263b061..0000000
--- a/chrome/content/ui/utils.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
-Cu.import(baseURL.spec + "ContentPolicy.jsm");
-Cu.import(baseURL.spec + "FilterClasses.jsm");
-Cu.import(baseURL.spec + "FilterListener.jsm");
-Cu.import(baseURL.spec + "FilterStorage.jsm");
-Cu.import(baseURL.spec + "Matcher.jsm");
-Cu.import(baseURL.spec + "Prefs.jsm");
-Cu.import(baseURL.spec + "RequestNotifier.jsm");
-Cu.import(baseURL.spec + "SubscriptionClasses.jsm");
-Cu.import(baseURL.spec + "Synchronizer.jsm");
-Cu.import(baseURL.spec + "Sync.jsm");
-Cu.import(baseURL.spec + "Utils.jsm");
-
-/**
- * Shortcut for document.getElementById(id)
- */
-function E(id)
-{
- return document.getElementById(id);
-}
diff --git a/chrome/locale/ar/global.properties b/chrome/locale/ar/global.properties
deleted file mode 100644
index 2a90f68..0000000
--- a/chrome/locale/ar/global.properties
+++ /dev/null
@@ -1,70 +0,0 @@
-default_dialog_title=Adblock Plus
-action0_tooltip=اضغط ÙØªØ¸Ùر اÙÙØ§Ø¦Ù
Ø© اÙÙ
راÙÙØ©Ø اضغط Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/Ø§ÙØªØ¹Ø·ÙÙ
-action1_tooltip=اضغط ÙÙØªØ/Ø¥ØºÙØ§Ù Ø§ÙØ¹Ùاصر اÙÙ
ØØ¬ÙØ¨Ø©Ø Ø§Ø¶ØºØ· Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/ Ø§ÙØªØ¹Ø·ÙÙ
-action2_tooltip=اضغط ÙÙØªØ Ø§ÙØ®ÙØ§Ø±Ø§ØªØ Ø§Ø¶ØºØ· Ø¨Ø§ÙØ²Ø± Ø§ÙØ£Ùسط ÙÙØªØ´ØºÙÙ/Ø§ÙØªØ¹Ø·ÙÙ
-action3_tooltip=اضغط ÙØªØ´ØºÙÙ/تعطÙ٠آدبÙÙÙ Ø¨ÙØ§Ø³
-disabled_tooltip=آدبÙÙÙ Ø¨ÙØ§Ø³ Ù
Ø¹Ø·Ù Ø§ÙØ¢Ù
-active_tooltip=إ٠آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù. ÙÙØ§Ù ?1? اشترا٠ÙÙØªØ± Ù ?2? ÙÙØ§ØªØ± Ù
خصصة ÙÙØ¯ Ø§ÙØ§Ø³ØªØ¹Ù
اÙ
-whitelisted_tooltip=آدبÙÙÙ Ø¨ÙØ§Ø³ ÙØ¹Ø§Ù Ø§ÙØ¢ÙØ Ù ÙÙÙÙ Ù
عط٠باÙÙØ³Ø¨Ø© ÙÙØ°Ù Ø§ÙØµÙØØ©
-blocked_count_tooltip=?1? خارج ع٠?2?
-blocked_count_addendum=اÙÙ
سÙ
ÙØ ب٠?1? ÙØ§ÙÙ
Ø®ÙÙ ?2?
-no_blocking_suggestions=ÙØ§ ÙÙØ¬Ø¯ Ø¹ÙØ§ØµØ± ÙÙØØ¬Ø¨ ÙÙ ÙØ°Ù Ø§ÙØµÙØØ©
-whitelisted_page=تÙ
تعطÙ٠آدبÙÙÙ Ø¨ÙØ§Ø³ ÙÙ Ø§ÙØµÙØØ© Ø§ÙØØ§ÙÙØ©
-whitelist_description=ÙÙØ§ÙÙÙ Ø§ÙØ§Ø³ØªØ«Ùاءات
-filterlist_description=ÙÙØ§ØªØ± Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª
-invalid_description=ÙÙØ§ØªØ± خاطئة
-elemhide_description=ÙÙØ§ÙÙÙ Ø¥Ø®ÙØ§Ø¡ Ø§ÙØ¹Ùصر
-subscription_description=اشترا٠ÙÙØªØ±
-subscription_wrong_version=بعض اÙÙÙØ§ØªØ± اÙÙ
ÙØ¬Ùدة ÙÙ ÙØ°Ø§ Ø§ÙØ§Ø´ØªØ±Ø§Ù ØªØªØ·ÙØ¨ آدبÙÙÙ Ø¨ÙØ³ ?1? ÙØªØ¹Ù
ÙÙ Ø¬ÙØ¯Ø§Ù
-subscription_source=اÙÙ
صدر
-subscription_status=Ø§ÙØØ§ÙØ©
-subscription_status_autodownload=ØªØØ¯ÙØ« Ø£ÙØªÙÙ
اتÙÙÙ
-subscription_status_manualdownload=ØªØØ¯ÙØ« ÙØ¯ÙÙ
-subscription_status_externaldownload=ØªØØ¯ÙØ« خارج٠(Ø¥Ø¶Ø§ÙØ© أخرÙ)
-subscription_status_lastdownload=آخر تØÙ
ÙÙ
-subscription_status_lastdownload_inprogress=Ø¬Ø§Ø±Ù Ø§ÙØªØÙ
ÙÙ
-subscription_status_lastdownload_unknown=ØºÙØ± Ù
تاØ
-remove_subscription_warning=ÙÙ Ø£ÙØª ØÙا٠راغب Ø¨Ø¥Ø²Ø§ÙØ© ÙØ°Ø§ Ø§ÙØ§Ø´ØªØ±Ø§ÙØ
-import_filters_wrong_version=ØªØØ°Ùر : بعض اÙÙÙØ§ØªØ± ÙÙ ÙØ°Ù اÙÙØ§Ø¦Ù
Ø© ØªØªØ·ÙØ¨ آدبÙÙÙ Ø¨ÙØ³ ?1? ÙØªØ¹Ù
ÙÙ Ø¬ÙØ¯Ø§Ù. ÙØ¬Ø¨ عÙÙÙ Ø§ÙØªØØ¯ÙØ« Ø¥Ù٠آخر إصدار Ù
٠آدبÙÙÙ Ø¨ÙØ§Ø³ ÙØ¨Ù Ø§Ø³ØªÙØ±Ø§Ø¯ ÙØ°Ù اÙÙØ§Ø¦Ù
Ø©.
-import_filters_warning=ÙÙ ØªØ±ÙØ¯ استبدا٠ÙÙØ§ØªØ±Ù Ø§ÙØØ§ÙÙØ© Ø£Ù
Ø¥Ø¶Ø§ÙØ© اÙÙÙØ§ØªØ± Ø§ÙØ¬Ø¯Ùدة ÙÙ ÙÙØ§ÙØ© اÙÙØ§Ø¦Ù
Ø©Ø
-import_filters_title=Ø§Ø³ØªÙØ±Ø§Ø¯ ÙÙØ§ØªØ±
-export_filters_title=ØªØµØ¯ÙØ± ÙÙØ§ØªØ±
-invalid_filters_file=ÙÙØ³ Ù
ÙÙ ØµØ§ÙØ ÙÙÙØªØ± ÙØ¢Ø¯Ø¨ÙÙÙ Ø¨ÙØ§Ø³
-filters_write_error=ÙØ§Ù ÙÙØ§Ù خطأ ÙÙ ÙØªØ§Ø¨Ø© اÙÙÙØ§ØªØ± Ø¥Ù٠اÙÙ
ÙÙ. ØªØ£ÙØ¯ Ù
٠أ٠اÙÙ
ÙÙ ØºÙØ± Ù
ØÙ
٠ضد اÙÙØªØ§Ø¨Ø© Ø£Ù ÙØªÙ
استعÙ
اÙÙ Ù
Ù Ø¨Ø±ÙØ§Ù
ج آخر
-clearall_warning=ÙÙ Ø£ÙØª راغب ÙØ¹Ùا٠ÙÙ Ø¥Ø²Ø§ÙØ© Ù٠اÙÙÙØ§ØªØ± Ù
٠اÙÙØ§Ø¦Ù
Ø©Ø
-resethitcounts_warning=Ø£ÙØª راغب ÙØ¹Ùا٠Ù٠إعادة ضبط عداد Ø§ÙØ¶ØºØ·Ø§Øª ÙÙ٠اÙÙÙØ§ØªØ± Ø¥ÙÙ Ø§ÙØµÙØ±Ø ÙØ°Ù Ø§ÙØ¹Ù
ÙÙØ© ÙØ§ ÙÙ
ÙÙ Ø§ÙØªØ±Ø§Ø¬Ø¹ عÙÙØ§!
-resethitcounts_selected_warning=ÙÙ Ø£ÙØª راغب ÙØ¹Ùا٠Ù٠إعادة ضبط عداد Ø§ÙØ¶ØºØ·Ø§Øª ÙÙÙÙØ§ØªØ± اÙÙ
ختارة Ø¥ÙÙ Ø§ÙØµÙØ±Ø ÙØ°Ù Ø§ÙØ¹Ù
ÙÙØ© ÙØ§ ÙÙ
ÙÙ Ø§ÙØªØ±Ø§Ø¬Ø¹ عÙÙØ§!
-filter_regexp_tooltip=ÙØ°Ø§ اÙÙÙØªØ± Ø¥Ù
ا "تعبر Ù
ÙØ·ÙÙ" Ø£Ù Ø£ÙØµØ± Ù
٠أ٠تتÙ
ØªØØ³ÙÙÙ. اÙÙØ«Ùر Ù
Ù ÙØ°Ù اÙÙÙØ§ØªØ± ÙØ¯ تؤد٠إÙ٠بطء ÙÙ Ø§ÙØªØµÙØ
-filter_elemhide_duplicate_id=ÙÙØ· ID ÙØ§ØØ¯ ÙÙØ¹Ùصر Ø§ÙØ°Ù Ø³ÙØªÙ
Ø¥Ø®ÙØ§Ø¤Ù ÙÙ
ÙÙ Ø£Ù ÙØØ¯Ø¯
-filter_elemhide_nocriteria=ÙÙ
ÙØªÙ
ØªØØ¯Ùد ØµÙØºØ© ÙÙØªØ¹Ø±Ù عÙÙ Ø§ÙØ¹Ùصر ÙØ¥Ø®ÙاؤÙ
-subscription_notAdded_warning=ÙÙ
تÙÙ
Ø¨Ø¥Ø¶Ø§ÙØ© أ٠اشترا٠ÙÙØªØ±. بدÙ٠اشترا٠ÙÙØªØ± ستضطر ÙØ¥Ø¶Ø§ÙØ© اÙÙÙØ§ØªØ± ÙØ¯ÙÙØ§Ù
-subscription_notAdded_warning_addendum=ÙÙ ØªØ±ÙØ¯ اÙÙ
تابعةØ
-subscription_invalid_location=Ù
ÙÙØ¹ ÙØ§Ø¦Ù
Ø© اÙÙÙØªØ± ÙÙØ³ صØÙØ ÙØ¹ÙÙØ§Ù ÙÙØ¨ Ù ÙØ§ ÙØ§Ø³Ù
Ù
ÙÙ
-synchronize_invalid_url=ÙØ´Ù Ø§ÙØ£Ù
Ø±Ø ÙÙØ³ عÙÙØ§Ù صØÙØ
-synchronize_connection_error=ÙØ´Ù Ø§ÙØ£Ù
ر بسبب ÙØ´Ù Ø§ÙØªØÙ
ÙÙ
-synchronize_invalid_data=ÙØ´Ù Ø§ÙØ£Ù
Ø±Ø ÙÙØ³Øª ÙØ§Ø¦Ù
Ø© ÙÙØ§ØªØ± صØÙØØ©
-synchronize_checksum_mismatch=ÙØ´ÙØ Ø¹Ø¯Ù
تطاب٠checksum
-synchronize_ok=ÙØ¬Ø§Ø
-overwrite=Ø§Ø³ØªØ¨Ø¯Ø§Ù Ø§ÙØØ§ÙÙ Ø¨Ø§ÙØ¬Ø¯Ùد
-append=Ø¥ÙØØ§Ù
-new_filter_group_title=ÙÙØªØ± Ø¬Ø¯ÙØ¯
-type_label_other=أخرÙ
-type_label_script=Ø³ÙØ±Ùبت
-type_label_image=ØµÙØ±Ø©
-type_label_stylesheet=جدÙÙ Ø§ÙØ£ÙÙ
اط
-type_label_object=Ø¹ÙØµØ±
-type_label_subdocument=إطار
-type_label_document=Ù
Ø³ØªÙØ¯
-type_label_elemhide=Ù
Ø®ÙÙ
-type_label_xbl=ربط XBL
-type_label_ping=Ping ÙÙØ±Ø§Ø¨Ø·
-type_label_xmlhttprequest=Ø·ÙØ¨ XML
-type_label_object_subrequest=Ø·ÙØ¨ ÙØ±Ø¹Ù ÙÙØ¹Ùصر
-type_label_dtd=DTD
-type_label_media=ØµÙØª\ÙÙØ¯ÙÙ
-type_label_font=Ø§ÙØ®Ø·
-fennec_status_enabled=آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù
-fennec_status_disabled=آدبÙÙÙ Ø¨ÙØ³ Ù
عطÙ
-fennec_status_enabled_site=آدبÙÙÙ Ø¨ÙØ³ Ù
ÙØ¹Ù عÙÙ ?1?
-fennec_status_disabled_site=آدبÙÙÙ Ø¨ÙØ³ Ù
عط٠عÙÙ ?1?
-sync_engine_title=Ø¨ÙØ§Ùات آدبÙÙÙ Ø¨ÙØ³
diff --git a/chrome/locale/ar/meta.properties b/chrome/locale/ar/meta.properties
deleted file mode 100644
index 07fdc66..0000000
--- a/chrome/locale/ar/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ù
Ø¤ÙØ¯ Ù
اردÙÙÙ
-name=Adblock Plus
-description=Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª Ø£ØµØ¨ØØª Ù
Ù Ø§ÙØ£Ù
س!
-description.short=ÙÙ Ø£ÙØª Ù
Ø²Ø¹ÙØ¬ Ù
Ù Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª Ù Ù
٠تتبع٠Ù
Ù ÙØ¨Ù اÙÙ
ÙØ§Ùع ÙÙ
Ù Ù٠تÙÙ Ø§ÙØ´Ø±Ø§Ø¦Ø· Ø§ÙØ¥Ø¹ÙاÙÙØ©Ø ÙÙ
بتØÙ
Ù٠آدبÙÙÙ Ø¨ÙØ³ ÙÙØªØªØÙÙ
Ø¨ØªØµÙØÙ ÙÙÙÙØ¨ ÙØªØºÙر Ø§ÙØ·Ø±ÙÙØ© Ø§ÙØªÙ ØªÙØ¸Ø± Ø¨ÙØ§ Ø¥ÙÙ Ø§ÙØ¥ÙØªØ±ÙØª.\n\nÙÙØ¯ÙÙ ÙØµÙر ØªÙØ¶ÙØÙ Ù
ØªÙØ§Ùر عÙÙ Ø§ÙØ¹ÙÙØ§Ù:http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=ÙØ³Ù
Ø Ù٠آدبÙÙÙ Ø¨ÙØ³ Ø¨Ø§ÙØªØÙÙ
Ø¨Ø§ÙØ¥ÙØªØ±ÙØª ÙØ¨Ø§ÙطرÙÙØ© Ø§ÙØªÙ ØªÙØ¸Ø± Ø¨ÙØ§ Ø¥Ù٠اÙÙÙØ¨ Ø¨Ø§ÙØ´ÙÙ Ø§ÙØ°Ù ØªØ±ÙØ¯Ù. Ø§Ù ÙØ°Ù Ø§ÙØ¥Ø¶Ø§ÙØ© Ù
دعÙÙ
Ø© Ù
Ù Ø£ÙØ«Ø± Ù
٠أربعÙ٠اشترا٠ÙÙØªØ± Ù٠عشرات اÙÙØºØ§Øª ÙØ§ÙØªÙ ÙØªÙ
Ø¶Ø¨Ø·ÙØ§ تÙÙØ§Ø¦Ùا ÙÙÙØ§Ø¦Ø¯ ØªØªØ±Ø§ÙØ بÙÙ Ø¥Ø²Ø§ÙØ© Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª Ø¥ÙÙ ØØ¬Ø¨ اÙÙ
ÙØ§Ùع Ø§ÙØ¶Ø§Ø±Ø©. ÙØ³Ù
Ø Ø¢Ø¯Ø¨ÙÙÙ Ø¨ÙØ³ Ø£ÙØ¶Ø§ بتعدÙ٠اÙÙÙØ§ØªØ± بÙ
ساعدة Ø§ÙØ¹Ø¯Ùد Ù
٠اÙÙ
Ø²Ø§ÙØ§ اÙÙØ§Ù
Ø© ÙØ®Ùار ÙØ¥Ø²Ø§ÙØ© Ø§ÙØµÙر ÙØªØ¨ÙÙØ¨Ø© ÙØØ¬Ø¨ Ø¹ÙØ§ØµØ± اÙÙÙØ§Ø´ ÙØ§ÙØ¬Ø§ÙØ§ ÙÙØ§Ø¦Ù
Ø© Ø¨Ø§ÙØ¹Ùاصر Ø§ÙØªÙ ÙÙ
ÙÙ ØØ¬Ø¨Ùا ÙØ¥Ø²Ø§ÙØ© Ø§ÙØ³ÙØ±ÙØ¨ØªØ§Øª ÙÙ
ÙÙØ§Øª Ø§ÙØ³ØªØ§ÙÙ.
diff --git a/chrome/locale/be/.incomplete b/chrome/locale/be/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/be/about.dtd b/chrome/locale/be/about.dtd
deleted file mode 100644
index 8ceea0b..0000000
--- a/chrome/locale/be/about.dtd
+++ /dev/null
@@ -1,7 +0,0 @@
-<!ENTITY dialog.title "ÐÑа Adblock Plus">
-<!ENTITY version.title "ÐÑÑÑÑÑ">
-<!ENTITY description "Adblock Plus дазвалÑе Ðам вÑÑаÑÑÑÑ, ÑÑо ÐÑ Ð±Ð¾Ð»ÑÑ Ð½Ðµ жадаеÑе баÑÑÑÑ Ñ Ð¡ÐµÑÑве.
-Ðам не паÑÑÑбна пампаваÑÑ ÑÑе банÑÑÑ Ð¹ ÑÑклÑмÑ, бо ÐºÐ°Ð»Ñ Ðам неÑÑа Ð·Ñ Ñе не падабаеÑÑа â ÑкажÑÑе аб гÑÑÑм Adblock Plus!">
-<!ENTITY homepage.label "ХаÑнÑÑ ÑÑаÑонка Adblock Plus:">
-<!ENTITY author.label "ÐÑÑаÑ:">
-<!ENTITY contributors.label "УкладÑÑкÑ:">
diff --git a/chrome/locale/be/settings.dtd b/chrome/locale/be/settings.dtd
deleted file mode 100644
index 567a54c..0000000
--- a/chrome/locale/be/settings.dtd
+++ /dev/null
@@ -1,65 +0,0 @@
-<!ENTITY dialog.title "ÐÐ°Ð»Ð°Ð´ÐºÑ Adblock Plus">
-<!ENTITY filters.label "ФÑлÑÑÑÑ">
-<!ENTITY filters.accesskey "Ф">
-<!ENTITY add.label "ÐадаÑÑ ÑÑлÑÑаÑ">
-<!ENTITY add.accesskey "Ð">
-<!ENTITY addsubscription.label "ÐадаÑÑ Ð¿Ð°Ð´Ð¿ÑÑÐºÑ Ð½Ð° ÑÑлÑÑаÑ">
-<!ENTITY addsubscription.accesskey "Ð">
-<!ENTITY synchsubscriptions.label "ÐднавÑÑÑ ÑÑе падпÑÑкÑ">
-<!ENTITY synchsubscriptions.accesskey "Ð">
-<!ENTITY import.label "ÐмпаÑÑаваÑÑ ÑÑлÑÑÑÑ">
-<!ENTITY import.accesskey "Ð">
-<!ENTITY export.label "ÐкÑпаÑÑаваÑÑ ÑÑлÑÑÑÑ">
-<!ENTITY export.accesskey "Ð">
-<!ENTITY clearall.label "ÐÑдалÑÑÑ ÑÑе ÑÑлÑÑÑÑ">
-<!ENTITY clearall.accesskey "У">
-<!ENTITY resethitcounts.label "СкÑнÑÑÑ ÑÑаÑÑÑÑÑкÑ">
-<!ENTITY resethitcounts.accesskey "Ð">
-<!ENTITY edit.label "Ð ÑдагаваÑÑ">
-<!ENTITY edit.accesskey "Ð ">
-<!ENTITY cut.label "ÐÑÑазаÑÑ">
-<!ENTITY cut.accesskey "Ы">
-<!ENTITY copy.label "ÐапÑÑваÑÑ">
-<!ENTITY copy.accesskey "Ð">
-<!ENTITY paste.label "УÑÑавÑÑÑ">
-<!ENTITY paste.accesskey "С">
-<!ENTITY remove.label "ÐÑдалÑÑÑ">
-<!ENTITY remove.accesskey "Ð">
-<!ENTITY menu.find.label "ÐоÑÑк">
-<!ENTITY menu.find.accesskey "Ш">
-<!ENTITY menu.findagain.label "ÐаÑÑаÑÑÑÑ Ð¿Ð¾ÑÑк">
-<!ENTITY menu.findagain.accesskey "Ð">
-<!ENTITY options.label "ÐаладкÑ">
-<!ENTITY options.accesskey "Ð">
-<!ENTITY enable.label "УклÑÑÑÑÑ Adblock Plus">
-<!ENTITY enable.accesskey "Ð">
-<!ENTITY showintoolbar.label "Show in toolbar">
-<!ENTITY showintoolbar.accesskey "B">
-<!ENTITY showinstatusbar.label "Show in status bar">
-<!ENTITY showinstatusbar.accesskey "S">
-<!ENTITY objecttabs.label "ÐаказваÑÑ Ð·Ð°ÐºÐ»Ð°Ð´ÐºÑ Ð½Ð° Flash Ñ Java">
-<!ENTITY objecttabs.accesskey "Ð">
-<!ENTITY collapse.label "СÑÑÑÑкаÑÑ Ð·Ð°Ð±Ð»ÑкаванÑÑ ÑлемÑнÑÑ">
-<!ENTITY collapse.accesskey "Ь">
-<!ENTITY help.label "Ðапамога">
-<!ENTITY help.accesskey "Ð">
-<!ENTITY faq.label "ÐÑÑанÑÐ½Ñ Ð¹ адказÑ">
-<!ENTITY faq.accesskey "Ð">
-<!ENTITY filterdoc.label "ÐапÑÑанÑне ÑÑлÑÑÑÐ°Ñ Ð´Ð»Ñ Adblock Plus">
-<!ENTITY filterdoc.accesskey "Ð">
-<!ENTITY about.label "ÐÑа Adblock Plus">
-<!ENTITY about.accesskey "Ð ">
-<!ENTITY description "ÐадайÑе адÑаÑÑ, ÑкÑÑ ÐÑ Ð¶Ð°Ð´Ð°ÐµÑе заблÑкаваÑÑ, ÑÑ Ð²ÑлÑÑÑе ÑÑ
з вÑпаднага ÑÑпÑÑÑ. ÐÑ Ð¼Ð¾Ð¶Ð°Ñе ÑжÑваÑÑ * Ð´Ð»Ñ Ñаго, каб ÑÑваÑаÑÑ Ð°Ð³ÑлÑнÑÑ Ð¿ÑавÑлÑ. ÐÑаÑÑнÑÑÑÑ ÐºÐ°ÑÑÑÑалÑнÑÐºÑ Ð¼Ð¾Ð³ÑÑÑ ÐºÐ°ÑÑÑÑаÑÑа ÑÑгÑлÑÑнÑÐ¼Ñ Ð²ÑÑÐ°Ð·Ð°Ð¼Ñ ÐºÑÑалÑÑ /banner\d+\.gif$/.">
-<!ENTITY enabled.column "УклÑÑанае">
-<!ENTITY hitcount.column "Ð¥ÑÑоÑ">
-<!ENTITY lasthit.column "ÐпоÑнÑ">
-<!ENTITY context.edit.label "Ð ÑдагаваÑÑ">
-<!ENTITY context.resethitcount.label "СкÑнÑÑÑ ÑÑаÑÑÑÑÑÐºÑ Ð´Ð»Ñ ÑÑлÑÑÑа">
-<!ENTITY context.synchsubscription.label "ÐднавÑÑÑ Ð¿Ð°Ð´Ð¿ÑÑкÑ">
-<!ENTITY context.editsubscription.label "Ð ÑдагаваÑÑ Ð¿Ð°Ð´Ð¿ÑÑкÑ">
-<!ENTITY context.moveup.label "ÐеÑаÑÑнÑÑÑ ÑвеÑÑ
">
-<!ENTITY context.movedown.label "ÐеÑаÑÑнÑÑÑ ÑнÑз">
-<!ENTITY context.movegroupup.label "ÐеÑаÑÑнÑÑÑ Ð³ÑÑÐ¿Ñ ÑвеÑÑ
">
-<!ENTITY context.movegroupdown.label "ÐеÑаÑÑнÑÑÑ Ð³ÑÑÐ¿Ñ ÑнÑз">
-<!ENTITY apply.label "ÐÑÑмÑнÑÑÑ">
-<!ENTITY apply.accesskey "Ð">
diff --git a/chrome/locale/be/subscriptionSelection.dtd b/chrome/locale/be/subscriptionSelection.dtd
deleted file mode 100644
index a529ed8..0000000
--- a/chrome/locale/be/subscriptionSelection.dtd
+++ /dev/null
@@ -1,7 +0,0 @@
-<!ENTITY dialog.title.edit "ÐÑаÑка падпÑÑÐºÑ Ð½Ð° ÑÑÑÑ">
-<!ENTITY title.label "Ðазва падпÑÑкÑ:">
-<!ENTITY title.accesskey "Ð">
-<!ENTITY location.label "ÐеÑÑазнаÑ
оджанне ÑпÑÑа ÑÑÑаÑ:">
-<!ENTITY location.accesskey "Ñ">
-<!ENTITY autodownload.label "ÐбнаÑлÑÑÑ ÑамаÑÑойна">
-<!ENTITY autodownload.accesskey "Ð">
diff --git a/chrome/locale/bg/meta.properties b/chrome/locale/bg/meta.properties
deleted file mode 100644
index 55d4ab1..0000000
--- a/chrome/locale/bg/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ðвайло ÐовÑев (s0urce)
-name=Adblock Plus
-description=РекламиÑе бÑÑ
а вÑеÑа!
-description.short=Ðедоволни ÑÑе Ð¾Ñ Ð¾Ð±Ñви? ÐÑиÑеÑнÑвани ÑÑе Ð¾Ñ Ð±Ð°Ð½ÐµÑи? ÐнÑÑалиÑайÑе Adblock ÐлÑÑ Ñега, за да Ñи вÑзвÑÑнеÑе конÑÑола и наÑина, по койÑо гледаÑе в ÐнÑеÑнеÑ.\n\nÐÑаÑÑк видео пÑеглед можеÑе да намеÑиÑе на http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock ÐлÑÑ Ð²Ð¸ позволÑва да Ñи вÑзвÑÑнеÑе конÑÑола вÑÑÑ
Ñ ÐнÑеÑÐ½ÐµÑ Ð¸ да видиÑе ÐнÑеÑÐ½ÐµÑ Ð¿Ð¾ наÑина, по койÑо иÑкаÑе. ÐобавкаÑа е подкÑепена Ð¾Ñ Ð½Ð°Ð´ ÑеÑиÑидеÑÐµÑ ÑилÑÑÑа за Ð°Ð±Ð¾Ð½Ð°Ð¼ÐµÐ½Ñ Ð½Ð° деÑеÑки езиÑи, коиÑо авÑомаÑиÑно го конÑигÑÑиÑÐ°Ñ Ð·Ð° Ñели, ваÑиÑаÑи Ð¾Ñ Ð¿ÑемаÑ
ване на онлайн Ñеклама до блокиÑане на вÑиÑки извеÑÑни зловÑедни пÑогÑами. Adblock ÐлÑÑ ÑÑÑо ви позволÑва да пеÑÑонализиÑаÑе ÑвоиÑе ÑилÑÑи Ñ Ð¿Ð¾Ð¼Ð¾ÑÑа на множеÑÑво полезни ÑÑнкÑии, вклÑÑиÑелно конÑекÑÑна вÑзможноÑÑ Ð·Ð° Ñнимки, Ñаздел за блокиÑане за Flash и Java обекÑи, какÑо и ÑпиÑÑк на блокиÑани пÑодÑкÑи за пÑемаÑ
ване на ÑкÑипÑове и ÑÑилове.
diff --git a/chrome/locale/bn-IN/.incomplete b/chrome/locale/bn-IN/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/bn-IN/subscriptionSelection.dtd b/chrome/locale/bn-IN/subscriptionSelection.dtd
deleted file mode 100644
index 5416b08..0000000
--- a/chrome/locale/bn-IN/subscriptionSelection.dtd
+++ /dev/null
@@ -1 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus -ঠসà§à¦¬à¦¾à¦à¦¤à¦®">
diff --git a/chrome/locale/br-FR/.incomplete b/chrome/locale/br-FR/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/br-FR/about.dtd b/chrome/locale/br-FR/about.dtd
deleted file mode 100644
index 05b4be6..0000000
--- a/chrome/locale/br-FR/about.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY dialog.title "Diwar benn Adblock Plus">
-<!ENTITY version.title "Stumm">
-<!ENTITY description "Gallout a rit boudañ n'eus forzh petra war genrouedad gant Adblock Plus . N'oc'h ket rediet da welout bruderezh ha gitonoù a bep seurt. Ma n'hoc'h ket ken c'hoant anezho, lugit Adblock Plus !">
-<!ENTITY homepage.label "Pajenn Kenrouedad :">
-<!ENTITY author.label "Aozer :">
-<!ENTITY contributors.label "Kenlabourerien :">
-<!ENTITY subscriptionAuthors.label "Aozerien koumanantoù ar siloù :">
-<!ENTITY translators.label "Troerien :">
diff --git a/chrome/locale/br-FR/composer.dtd b/chrome/locale/br-FR/composer.dtd
deleted file mode 100644
index c1af8fb..0000000
--- a/chrome/locale/br-FR/composer.dtd
+++ /dev/null
@@ -1,46 +0,0 @@
-<!ENTITY dialog.title "Ouzhpenn ur reolenn silabl Adblock Plus">
-<!ENTITY accept.label "Ouzhpenn ar sil">
-<!ENTITY advanced.label "Diskouez ouzhpenn">
-<!ENTITY basic.label "Diskouez a-reizh">
-<!ENTITY disabled.warning "Diweredekaet eo Adblock Plus a-vremañ. Gallout a rit kenderc'hel ouzhpenn siloù met ne labourint ket kement ne vo ket gweredekaet [link]Adblock Plus[/link].">
-<!ENTITY groupDisabled.warning "Ar strollad sil "?1?" e-lec'h e vefe bet lakaet ar sil a zo diweredekaet a-vremañ. Gallout a rit ouzhpenn anezhañ met ne labouro ket kement ne vo ket [link]gweredekaet ar strollad sil[/link].">
-<!ENTITY filter.label "Sil nevez :">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "Diskouez ar siloù a zo...">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "Sil stankañ">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Reolenn direizhadenn">
-<!ENTITY type.whitelist.accesskey "x">
-<!ENTITY pattern.label "Kinnig kinkladurioù">
-<!ENTITY pattern.explanation "Ar c'hinkladur a c'hall bezañ ul lodenn ar chomlec'h, ar simbol * o c'hoari ar roll joker. Ne labouro ket ar sil nemetken gant chomlec'hioù kenglotañ gant ar c'hinkladur.">
-<!ENTITY regexp.warning "Ar c'hinkladur hoc'h eus diskouezet a vo troet e-giz ur jedad a-reizh. Un niver vras jedadoù a-reizh a c'horreko hoc'h merdeiñ. Ma n'hoc'h eus ket c'hoant implij jedadoù a-reizh, Ouzhpennit un * ââ er in ar c'hinkladur.">
-<!ENTITY shortpattern.warning "Ret vihan eo ar c'hinkladur hoc'h eus diskouezet evit bezañ gwellaet, un niver vras gant stummoù kinkladur-se a c'horreko hoc'h merdeiñ. Gwelloc'h eo evideoc'h da zibab ur chadenn arouezenn hiroc'h evit ar sil-se.">
-<!ENTITY custom.pattern.label "Personnelaat :">
-<!ENTITY custom.pattern.accesskey "C">
-<!ENTITY anchors.label "A-duaat ar c'hinkladur nemetken :">
-<!ENTITY anchor.start.label "e penn ar chomlec'h">
-<!ENTITY anchor.start.accesskey "g">
-<!ENTITY anchor.start.flexible.label "e penn anv domani">
-<!ENTITY anchor.start.flexible.accesskey "g">
-<!ENTITY anchor.end.label "en dibenn chomlec'h">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "Dibaboù">
-<!ENTITY domainRestriction.label "Strizhañ en anv domani :">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "Resisaat unan pe meur domani distaget gant an arouezenn ¬´ | ¬ª, ne labouro ket ar sil nemet gant anv domani resiset. An arouezenn ¬´ ~ ¬ª a-raok un anv domani a dalvez ne vo ket ret bezañ da labour war an domani-se.">
-<!ENTITY firstParty.label "Dont diwar ar memes domani nemetken">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "Dont diwar domanioù all nemetken">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.label "Kizidig gant torret">
-<!ENTITY matchCase.accesskey "M">
-<!ENTITY types.label "Lakaat d'ar furmoù da heul :">
-<!ENTITY selectAllTypes.label "Diuzañ pep tra">
-<!ENTITY unselectAllTypes.label "Diuzañ netra">
-<!ENTITY collapse.label "Adimplij elfenn frankiz silet :">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY collapse.default.yes.label "Implij an emzalc'h da skouer (ya)">
-<!ENTITY collapse.default.no.label "Implij an emzalc'h da skouer (ket)">
-<!ENTITY collapse.yes.label "Ya">
-<!ENTITY collapse.no.label "Ket">
diff --git a/chrome/locale/br-FR/global.properties b/chrome/locale/br-FR/global.properties
deleted file mode 100644
index dad6aa4..0000000
--- a/chrome/locale/br-FR/global.properties
+++ /dev/null
@@ -1,69 +0,0 @@
-default_dialog_title=Adblock Plus
-action0_tooltip=Klik evit diskouez al lañser kendestenn, klik kreiz evit gweredekaat/diweredekaat.
-action1_tooltip=Klik evit digeriñ/serriñ elfennoù stankabl, klik kreiz evit gweredekaat/diweredekaat.
-action2_tooltip=Klik evit digeriñ dibaboù, klik kreiz evit gweredekaat/diweredekaat.
-action3_tooltip=Klik evit gweredekaat/diweredekaat Adblock Plus.
-disabled_tooltip=Diweredekaet eo Adblock Plus.
-active_tooltip=Gweredekaet eo Adblock Plus , ?1? koumanant siloù ha ?2? siloù personel implijet.
-whitelisted_tooltip=Diweredekaet eo Adblock Plus war ar bajenn a-vremañ.
-blocked_count_tooltip=?1? stanket war ?2?
-blocked_count_addendum=(er bajenn wenn: ?1?, kuzhet: ?2?)
-no_blocking_suggestions=Elfennoù ebet da stankañ war ar bajenn a-vremañ
-whitelisted_page=Diweredekaet eo bet Adblock Plus war ar bajenn a-vremañ
-whitelist_description=Ma reolennoù direizhadenn
-filterlist_description=Ma reolennoù a-enep bruderezh
-invalid_description=Ma reolennoù ne labour ket
-elemhide_description=Ma reolennoù elfenn kuzhet
-subscription_description=Koumanant sil:
-subscription_wrong_version=Siloù bennak ar c'houmanant a ret da labour gant Adblock Plus ?1? .
-subscription_source=Tarzh:
-subscription_status=Stad:
-subscription_status_autodownload=Hizivaat emgefre
-subscription_status_manualdownload=Hizivaat dre zorn
-subscription_status_externaldownload=Hizivaat er-maez (plugin all)
-subscription_status_lastdownload=pellgargañ diwezhañ
-subscription_status_lastdownload_inprogress=O pellgargañ...
-subscription_status_lastdownload_unknown=N/A
-remove_subscription_warning=Sur oc'h da skarzhañ kuit ar c'houmanant-se?
-import_filters_wrong_version=Diwall: Siloù bennak ar c'houmanant a ret da labour gant Adblock Plus ?1? . Ret e vefe deoc'h hizivaat war Adblock Plus diwezhañ a-raok enporzhiañ al listenn-se.
-import_filters_warning=C'hoant hoc'h eus erlec'hiañ hoc'h siloù a-vremañ pe ouzhpenn siloù nevez er fin al listenn?
-import_filters_title=Enporzhiañ siloù
-export_filters_title=Ezporzhiañ siloù
-invalid_filters_file=N'eo ket ur restr siloù mat evit Adblock Plus.
-filters_write_error=Fazi ez eus bet o skrivañ siloù er restr.Gwiriat n'eo ket gwarezet ar restr pe digoret gant ur meziant all.
-clearall_warning=Sur oc'h da skarzhañ kuit an holl siloù eus al listenn?
-resethitcounts_warning=Sur oc'h da adderaouiñ ar c'honter evit an holl siloù? Notenn:N'eus tu ebet da ziober.
-resethitcounts_selected_warning=Sur oc'h da adderaouiñ ar c'honter evit siloù diuzet? Notenn:N'eus tu ebet da ziober.
-filter_regexp_tooltip=Pe ur jedad a-reizh pe re vihan evit bezañ gwellaet eo ar sil-se. Re a siloù e-giz-se a gorreko hoc'h merdeer.
-filter_elemhide_duplicate_id=Unan ID eus an elfenn a vo kuzhet nemetken a c'hall bezañ spisaat
-filter_elemhide_nocriteria=Muzulioù ebet spisaet evit anavet evit an elfenn da guzhat
-subscription_notAdded_warning=N'eo ket ouzhpennet koumanant sil. Hep koumanant sil ret e vo deoc'h ouzhpenn siloù dre zorn.
-subscription_notAdded_warning_addendum=C'hoant hoc'h eus lakaat da labour?
-subscription_invalid_location=N'eo ket un URL mat al lec'hiadur restr sil pe n'eo ket un anv mat.
-synchronize_invalid_url=Fazi, n'eo ket ur chomlec'h
-synchronize_connection_error=Fazi, pellgargañ torret
-synchronize_invalid_data=Fazi, n'eo ket ul listenn siloù mat
-synchronize_checksum_mismatch=Fazi, n'eo ket ar memes checksum
-synchronize_ok=Trec'hadenn
-overwrite=Skrivañ warnezhañ
-append=Ouzhpenn
-new_filter_group_title=Sil nevez
-type_label_other=all
-type_label_script=skript
-type_label_image=skeudenn
-type_label_stylesheet=Stilpajenn
-type_label_object=elfenn
-type_label_subdocument=framm
-type_label_document=diell
-type_label_elemhide=kuzhet
-type_label_xbl=Eread XBL
-type_label_ping=ping al liamm
-type_label_xmlhttprequest=Reked XML
-type_label_object_subrequest=Isreked an elfenn
-type_label_dtd=DTD
-type_label_media=son/video
-type_label_font=font
-fennec_status_enabled=Gweredekaet eo Adblock Plus.
-fennec_status_disabled=Diweredekaet eo Adblock Plus.
-fennec_status_enabled_site=Gweredekaet eo Adblock Plus evit ?1?.
-fennec_status_disabled_site=Diweredekaet eo Adblock Plus evit ?1?.
diff --git a/chrome/locale/br-FR/meta.properties b/chrome/locale/br-FR/meta.properties
deleted file mode 100644
index 59579c9..0000000
--- a/chrome/locale/br-FR/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Servijer
-name=Adblock Plus
-description=Echu eo gant bruderezh!
-description.short=Hegaset gant bruderezh? Spontuset gant an heuliet? Diaeset gant gitonioù? Stalit Adblock Plus diouzhtu ha gounit ar c'hontrol kenrouedad, cheñchit hoc'h sell war genrouedad.\n\nDa vak eo ur video war http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adreiñ a ra deoc'h ar c'hontroll kenrouedad, hag ar sell hoc'h eus c'hoant. LAbour a ra an ouzhpenn meziant-se gant muioc'h a zaou-ugent koumanant e meur a yezhoù kefluniet emgefre evit kinnig deoc'h kalz a vruderezh domani. Gallout a rit personelat Adblock Plus gant siloù ha skoazell, gallout a rit stankañ skeudennoù gant dibaboù, an ivinell evit elfennoù Flash ha Java, hag ul listenn elfennoù skript ha CSS da stankañ.
diff --git a/chrome/locale/br-FR/overlay.dtd b/chrome/locale/br-FR/overlay.dtd
deleted file mode 100644
index a51e4f1..0000000
--- a/chrome/locale/br-FR/overlay.dtd
+++ /dev/null
@@ -1,23 +0,0 @@
-<!ENTITY status.tooltip "Stad :">
-<!ENTITY blocked.tooltip "Eflennoù stanket war ar bajenn :">
-<!ENTITY filters.tooltip "Siloù ar muiañ implijet :">
-<!ENTITY menuitem.label "Dibaboù Adblock Plus">
-<!ENTITY menuitem.accesskey "b">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus : elfennoù silabl">
-<!ENTITY context.image.label "Stankañ ar skeudenn gant Adblock">
-<!ENTITY context.object.label "Stankañ an elfenn gant Adblock">
-<!ENTITY context.frame.label "Stankañ ar framm gant Adblock">
-<!ENTITY context.media.label "Stankañ videoù/son gant Adblock">
-<!ENTITY context.removeWhitelist.label "Adblock Plus : Gweredekaat adnevez evit ar bajenn-se">
-<!ENTITY sidebar.title "Elfennoù silabl er bajenn a-vremañ">
-<!ENTITY settings.label "Dibaboù gwellañ">
-<!ENTITY settings.accesskey "f">
-<!ENTITY opensidebar.label "Digeriñ al listenn elfennoù silabl">
-<!ENTITY opensidebar.accesskey "b">
-<!ENTITY closesidebar.label "Serriñ al listenn elfennoù silabl">
-<!ENTITY closesidebar.accesskey "b">
-<!ENTITY whitelist.site.label "Diweredekaat evit ?1?">
-<!ENTITY whitelist.page.label "Diweredekaat evit ar bajenn-se nemetken">
-<!ENTITY objecttab.title "Stankañ">
-<!ENTITY objecttab.tooltip "Klikañ amañ hag Adblock Plus a stanko an elfenn-se">
diff --git a/chrome/locale/br-FR/settings.dtd b/chrome/locale/br-FR/settings.dtd
deleted file mode 100644
index decaec3..0000000
--- a/chrome/locale/br-FR/settings.dtd
+++ /dev/null
@@ -1,87 +0,0 @@
-<!ENTITY dialog.title "Dibaboù gwellañ Adblock Plus">
-<!ENTITY filters.label "Siloù">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Ouzhpenn ur sil">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.label "Koumanantiñ el listenn siloù">
-<!ENTITY addsubscription.accesskey "s">
-<!ENTITY synchsubscriptions.label "Hizivaat an holl koumanantoù">
-<!ENTITY synchsubscriptions.accesskey "d">
-<!ENTITY import.label "Enporzhiañ siloù">
-<!ENTITY import.accesskey "m">
-<!ENTITY export.label "Ezporzhiañ siloù personel">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.label "Skarzhañ an holl sil personel">
-<!ENTITY clearall.accesskey "l">
-<!ENTITY resethitcounts.label "Adlakaat ar c'honter da mann">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "Embann">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "Troc'hañ">
-<!ENTITY cut.accesskey "t">
-<!ENTITY copy.label "Kopiañ">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "Pegañ">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "Skarzhañ kuit">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "Klask">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "Adklask">
-<!ENTITY menu.findagain.accesskey "g">
-<!ENTITY view.label "Diskouez">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "Rummañ dre">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "Na rummet">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "Urzh A > Z">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Urzh Z > A">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Dibaboù">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "Gweredekaat Adblock Plus">
-<!ENTITY enable.accesskey "n">
-<!ENTITY showintoolbar.label "Diskouez er barrenn ostilh">
-<!ENTITY showintoolbar.accesskey "b">
-<!ENTITY showinstatusbar.label "Diskouez er barrenn stad">
-<!ENTITY showinstatusbar.accesskey "s">
-<!ENTITY objecttabs.label "Diskouez un tikedenn evit Flash ha Java">
-<!ENTITY objecttabs.accesskey "t">
-<!ENTITY collapse.label "Implij an dachenn frank gant an elfennoù stanket">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY help.label "Skoazell">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.label "Evit kregiñ">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.label "Foar ar Goulennoù">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.label "Krouiñ siloù Adblock Plus">
-<!ENTITY filterdoc.accesskey "r">
-<!ENTITY about.label "Diwar benn Adblock Plus">
-<!ENTITY about.accesskey "b">
-<!ENTITY description "Ar siloù da heul a ziskouez ar chomlec'hioù a vo ret stnaket hag ar re a vo ret aotret :">
-<!ENTITY filter.column "Reolenn silaj">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "Diskouez ar siloù">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "Gweredekaet">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "Konter">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "Implij diwezhañ">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "Cheñch ar sil">
-<!ENTITY context.resethitcount.label "Adlakaat ar c'honter mann">
-<!ENTITY context.synchsubscription.label "Hizivaat diouzhtu">
-<!ENTITY context.editsubscription.label "Embann ar c'houmanant">
-<!ENTITY context.moveup.label "Sevel">
-<!ENTITY context.movedown.label "Diskenn">
-<!ENTITY context.movegroupup.label "Sevel an diuz">
-<!ENTITY context.movegroupdown.label "Diskenn an diuz">
-<!ENTITY context.enable.label "Gweredekaat">
-<!ENTITY context.disable.label "Diweredekaat">
-<!ENTITY apply.label "Arloañ">
-<!ENTITY apply.accesskey "p">
-<!ENTITY fennec.subscription.label "Koumanant">
diff --git a/chrome/locale/br-FR/sidebar.dtd b/chrome/locale/br-FR/sidebar.dtd
deleted file mode 100644
index dbc28c6..0000000
--- a/chrome/locale/br-FR/sidebar.dtd
+++ /dev/null
@@ -1,32 +0,0 @@
-<!ENTITY detached.title "Adblock Plus : elfennoù silabl (distaget)">
-<!ENTITY detach.label "Distagañ">
-<!ENTITY reattach.label "Adstagañ">
-<!ENTITY search.label "Klask:">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "Furm">
-<!ENTITY address.label "Chomlec'h">
-<!ENTITY filter.label "Sil">
-<!ENTITY state.label "Stad">
-<!ENTITY size.label "Ment">
-<!ENTITY docDomain.label "Tarzh an diell">
-<!ENTITY noitems.label "Elfennoù ebet silabl">
-<!ENTITY whitelisted.label "Pajenn el listenn wenn">
-<!ENTITY tooltip.address.label "Chomlec'h:">
-<!ENTITY tooltip.type.label "Furm:">
-<!ENTITY tooltip.type.blocked "(stanket)">
-<!ENTITY tooltip.type.whitelisted "(aotret)">
-<!ENTITY tooltip.size.label "Ment:">
-<!ENTITY tooltip.docDomain.label "Tarzh an diell:">
-<!ENTITY tooltip.filter.label "Sil implijet:">
-<!ENTITY tooltip.filterSource.label "Tarzh ar sil:">
-<!ENTITY context.block.label "Stankañ an elfenn-se">
-<!ENTITY context.editfilter.label "Cheñch ar sil a labour">
-<!ENTITY context.whitelist.label "Ouzhpenn er listenn wenn">
-<!ENTITY context.disablefilter.label "Diweredekaat ar sil ?1?">
-<!ENTITY context.enablefilter.label "Adweredekaat ar sil ?1?">
-<!ENTITY context.disablefilteronsite.label "Diweredekaat ar sil-se evit ?1?">
-<!ENTITY context.open.label "Digeriñ en un ivinell nevez">
-<!ENTITY context.flash.label "Blinkañ riblennoù an elfenn">
-<!ENTITY context.copy.label "Kopiañ ar chomlec'h an elfen">
-<!ENTITY context.copyFilter.label "Kopiañ ar sil">
-<!ENTITY context.selectAll.label "Diuzañ pep tra">
diff --git a/chrome/locale/br-FR/subscriptionSelection.dtd b/chrome/locale/br-FR/subscriptionSelection.dtd
deleted file mode 100644
index 1aa71de..0000000
--- a/chrome/locale/br-FR/subscriptionSelection.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY dialog.title "Ouzhpenn ur c'houmanant en ul listenn siloù Adblock Plus">
-<!ENTITY dialog.title.edit "Cheñch ar c'houmanant">
-<!ENTITY description.newInstall "Ma c'houmanantit ouzh ul listenn siloù e vo efedusoc'h Adblock Plus. Roet eo ar c'houmanantoù gant implijourien all Adblock Plus. Ar c'houmanant ar muiañ reizh evit hor yezh a zo diuzet c'hoazh.">
-<!ENTITY subscriptionSelector.label "Diuzit ur c'houmanant el listenn da heul :">
-<!ENTITY viewList.label "Diskouez ar siloù">
-<!ENTITY visitHomepage.label "Mont el lec'hienn kenrouedad">
-<!ENTITY addSubscription.label "Ouzhpenn ar c'houmanant">
-<!ENTITY saveSubscription.label "Enrollañ ar c'houmanant">
-<!ENTITY other.label "Ouzhpenn ur c'houmanant all">
-<!ENTITY other.accesskey "f">
-<!ENTITY list.download.failed "N'hall ket Adblock Plus adtapout al listenn koumanantoù.">
-<!ENTITY list.download.retry "Adober endro">
-<!ENTITY list.download.website "Diskouez al lec'hienn kenrouedad">
-<!ENTITY fromWeb.description "C'hoant hoc'h eus ouzhpenn ar c'houmanant-se. Gallout a rit cheñch an titl hag al lec'hiadur koumanant a-raok ouzhpenn anezhañ.">
-<!ENTITY edit.description "Gallout a rit cheñch an titl hag al lec'hiadur e-giz hoc'h eus c'hoant.">
-<!ENTITY external.description "Ur c'houmanant er-maez eo ; hizivaet e vo anezhañ gant an astenn en deus krouet ar c'houmanant-se.">
-<!ENTITY title.label "Anv ar c'houmanant :">
-<!ENTITY title.accesskey "t">
-<!ENTITY location.label "Lec'hiadur al listenn :">
-<!ENTITY location.accesskey "l">
-<!ENTITY autodownload.label "Hizivaat emgefrek">
-<!ENTITY autodownload.accesskey "p">
-<!ENTITY supplementMessage "Ar c'houmanant-se a labour gant ar c'houmanant "?1?" n'eo ket implijet ganeoc'h c'hoazh.">
-<!ENTITY addMain.label "Ouzhpenn ivez ar c'houmanant "?1?"">
-<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/ca/meta.properties b/chrome/locale/ca/meta.properties
deleted file mode 100644
index 3b07045..0000000
--- a/chrome/locale/ca/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=el_libre, Toni Barrera
-name=Adblock Plus
-description=Els anuncis eren ahir
-description.short=Molest/a pels anuncis?Preocupat per seguiment?Instal·la Adblock Plus ara per recuperar el control d'Internet i canviar la manera com veus la web.\n\n Aquà teniu un breu resum en vÃdeo a http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus li permet recuperar el control d'Internet i veure la web de la manera que desitja. L'afegit compta amb el suport de més de 40 subscripcions de filtres en desenes d'idiomes, que automà ticament ho configurarà per a propòsits com l'eliminació de la publicitat en lÃnia per bloquejar tots els dominis de malware conegut. Adblock Plus també us permet personalitzar els filtres amb l'assistència d'una varietat de caracterÃstiques útils, incloent una opció de context per a les imatges, una fitxa per categories per als objectes de Flash i Java, i una llista d'elements amb bloqueig per eliminar els scripts i fulls d'estil.
diff --git a/chrome/locale/cs/meta.properties b/chrome/locale/cs/meta.properties
deleted file mode 100644
index 35f7ccb..0000000
--- a/chrome/locale/cs/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Jakub Tománek
-name=Adblock Plus
-description=A reklamy jsou minulostÃ!
-description.short=Jste otráveni reklamami? Nebavà vás být sledováni? ObtÄžujà vás bannery? Nainstalujte Adblock Plus, zÃskejte opÄt kontrolu nad internetem a zmÄÅte způsob, jakým web prohlÞÃte.
-description.long=Adblock Plus vám umožÅuje zÃskat kontrolu na internetem a prohlÞet stránky způsobem, jaký si zvolÃte vy, ne reklamy na stránkách. Tento doplnÄk je podporován vÃce než ÄtyÅiceti sadami cizÃch filtrů v desÃtkách jazyků, které automaticky nastavujà blokovánà reklam a známých domén se Å¡kodlivým software. Adblock Plus vám též umožÅuje nastavit vlastnà filtry obsahu za pomoci různých užiteÄných funkcà jako jsou mÃstnà nabÃdka pro obrázky, blokovacà ouÅ¡ka u Flash a Java objektů, a seznam blokovatelných položek umožÅujÃcà odstranÄnà skriptů a Å¡ablon stylů.
diff --git a/chrome/locale/cs/settings.dtd b/chrome/locale/cs/settings.dtd
deleted file mode 100644
index eb5ee01..0000000
--- a/chrome/locale/cs/settings.dtd
+++ /dev/null
@@ -1,89 +0,0 @@
-<!ENTITY dialog.title "PÅedvolby Adblock Plus">
-<!ENTITY filters.label "Filtry">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "PÅidat filtr">
-<!ENTITY add.accesskey "P">
-<!ENTITY addsubscription.label "PÅidat cizà filtry">
-<!ENTITY addsubscription.accesskey "c">
-<!ENTITY synchsubscriptions.label "Aktualizovat všechny cizà sady filtrů">
-<!ENTITY synchsubscriptions.accesskey "A">
-<!ENTITY import.label "Importovat filtry ze souboru">
-<!ENTITY import.accesskey "I">
-<!ENTITY export.label "Exportovat vlastnà filtry do souboru">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.label "Odstranit všechny vlastnà filtry">
-<!ENTITY clearall.accesskey "O">
-<!ENTITY resethitcounts.label "Vynulovat poÄÃtadla zásahů">
-<!ENTITY resethitcounts.accesskey "V">
-<!ENTITY edit.label "Ãpravy">
-<!ENTITY edit.accesskey "A">
-<!ENTITY cut.label "Vyjmout">
-<!ENTITY cut.accesskey "j">
-<!ENTITY copy.label "KopÃrovat">
-<!ENTITY copy.accesskey "K">
-<!ENTITY paste.label "Vložit">
-<!ENTITY paste.accesskey "l">
-<!ENTITY remove.label "Smazat">
-<!ENTITY remove.accesskey "z">
-<!ENTITY menu.find.label "NajÃt">
-<!ENTITY menu.find.accesskey "N">
-<!ENTITY menu.findagain.label "NajÃt dalÅ¡Ã">
-<!ENTITY menu.findagain.accesskey "d">
-<!ENTITY view.label "Zobrazit">
-<!ENTITY view.accesskey "Z">
-<!ENTITY sort.label "SeÅadit podle">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "NeÅadit">
-<!ENTITY sort.none.accesskey "N">
-<!ENTITY sort.ascending.label "VzestupnÄ (A-Z)">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "SestupnÄ (Z-A)">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Možnosti">
-<!ENTITY options.accesskey "M">
-<!ENTITY enable.label "Aktivovat Adblock Plus">
-<!ENTITY enable.accesskey "k">
-<!ENTITY showintoolbar.label "Zobrazit v nástrojové liÅ¡tÄ">
-<!ENTITY showintoolbar.accesskey "b">
-<!ENTITY showinstatusbar.label "Zobrazit ve stavovém Åádku">
-<!ENTITY showinstatusbar.accesskey "r">
-<!ENTITY objecttabs.label "Zobrazovat ouška u objektů Java a Flash">
-<!ENTITY objecttabs.accesskey "o">
-<!ENTITY collapse.label "Minimalizovat blokované objekty">
-<!ENTITY collapse.accesskey "i">
-<!ENTITY sync.label "Nastavenà synchronizace Adblocku Plus">
-<!ENTITY sync.accesskey "s">
-<!ENTITY help.label "NápovÄda">
-<!ENTITY help.accesskey "v">
-<!ENTITY gettingStarted.label "ZaÄÃnáme">
-<!ENTITY gettingStarted.accesskey "Z">
-<!ENTITY faq.label "Äasto kladené dotazy (FAQ)">
-<!ENTITY faq.accesskey "q">
-<!ENTITY filterdoc.label "Psanà Adblock Plus filtrů">
-<!ENTITY filterdoc.accesskey "f">
-<!ENTITY about.label "O doplÅku Adblock Plus">
-<!ENTITY about.accesskey "o">
-<!ENTITY description "NásledujÃcà filtry rozhodujÃ, které adresy budou blokovány a které budou povoleny:">
-<!ENTITY filter.column "Pravidlo filtru">
-<!ENTITY filter.accesskey "P">
-<!ENTITY slow.column "Pomalé filtry">
-<!ENTITY slow.accesskey "m">
-<!ENTITY enabled.column "AktivnÃ">
-<!ENTITY enabled.accesskey "k">
-<!ENTITY hitcount.column "Zásahy">
-<!ENTITY hitcount.accesskey "h">
-<!ENTITY lasthit.column "Poslednà zásah">
-<!ENTITY lasthit.accesskey "l">
-<!ENTITY context.edit.label "PÅidat filtr">
-<!ENTITY context.resethitcount.label "Vynulovat poÄÃtadlo zásahů tohoto filtru">
-<!ENTITY context.synchsubscription.label "Aktualizovat seznam cizÃch filtrů">
-<!ENTITY context.editsubscription.label "Upravit cizà filtry">
-<!ENTITY context.moveup.label "Posunout filtr nahoru">
-<!ENTITY context.movedown.label "Posunout filtr dolů">
-<!ENTITY context.movegroupup.label "Posunout skupinu nahoru">
-<!ENTITY context.movegroupdown.label "Posunout skupinu dolů">
-<!ENTITY context.enable.label "Povolit">
-<!ENTITY context.disable.label "Zakázat">
-<!ENTITY apply.label "PoužÃt">
-<!ENTITY apply.accesskey "U">
-<!ENTITY fennec.subscription.label "Cizà sada filtrů">
diff --git a/chrome/locale/cy/.incomplete b/chrome/locale/cy/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/cy/global.properties b/chrome/locale/cy/global.properties
deleted file mode 100644
index eb0828e..0000000
--- a/chrome/locale/cy/global.properties
+++ /dev/null
@@ -1,24 +0,0 @@
-action0_tooltip=Cliciwch i ddod a'r dewislen cysywllt, clic canol i'w alluogi/anablu.
-action1_tooltip=Cliciwch i agor/cau eitemau blocadwy, clic canol i'w alluogi/anablu.
-action2_tooltip=Cliciwch i agor dewisiadau, clic canol i'w alluogi/anablu.
-action3_tooltip=Cliciwch i alluogi/anablu Adblock Plws.
-disabled_tooltip=Mae Adblock Plws wedi cael ei anablu.
-whitelisted_tooltip=Mae Adblock Plws yn weithredol, ond mae hi wedi cael ei anablu ar y dudalen gyfredol.
-blocked_count_tooltip=?1? allan o ?2?
-no_blocking_suggestions=Dim eitemau blocadwy ar y tudalen gyfredol
-whitelisted_page=Mae Adblock Plws wedi cael ei anablu ar y dudalen gyfredol
-whitelist_description=Rheolau eithriadol
-filterlist_description=Ffilterau hysbysebion
-invalid_description=Ffilterau annilys
-elemhide_description=Rheolau cuddio elfen
-subscription_description=Tanysgrifiad ffilterau:
-subscription_wrong_version=Mae angen Adblock Plws ?1? arnoch i rhai o'r ffilteri i weithio'n iawn!
-subscription_source=Ffynhonell:
-subscription_status=Statws:
-subscription_status_autodownload=Wedi'i ddiweddaru'n awtomatig
-subscription_status_manualdownload=Wedi'i ddiweddaru'n seinglawr
-subscription_status_externaldownload=Wedi'i ddiweddaru'n allanol (estyniad arall)
-subscription_status_lastdownload=Lawrlwythiad dywethaf
-subscription_status_lastdownload_inprogress=Yn lawrlwytho...
-subscription_status_lastdownload_unknown=Ddim yn berthnasol
-remove_subscription_warning=Ydych chi wir eisiau dileu'r tanysgrifiad hon?
diff --git a/chrome/locale/cy/meta.properties b/chrome/locale/cy/meta.properties
deleted file mode 100644
index e3cf4f0..0000000
--- a/chrome/locale/cy/meta.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-name=Adblock Plus
-description=Y gorffennol yw hysbysebion!
diff --git a/chrome/locale/cy/subscriptionSelection.dtd b/chrome/locale/cy/subscriptionSelection.dtd
deleted file mode 100644
index 7703a9f..0000000
--- a/chrome/locale/cy/subscriptionSelection.dtd
+++ /dev/null
@@ -1,5 +0,0 @@
-<!ENTITY dialog.title.edit "Golygu tanysgrifiadau ffilter">
-<!ENTITY title.accesskey "T">
-<!ENTITY location.label "Lleoliad y rhestr ffilteri:">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.accesskey "P">
diff --git a/chrome/locale/da/meta.properties b/chrome/locale/da/meta.properties
deleted file mode 100644
index 504f9a8..0000000
--- a/chrome/locale/da/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=AlleyKat, Regmos
-name=Adblock Plus
-description=Reklamer er fortid!
-description.short=Træt af reklamer? Nervøs for sporing? Irriteret over bannere? Installer Adblock Plus for at genvinde kontrollen over internettet og den måde det vises på.\n\nKort videopræsentation: http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus lader dig genvinde kontrollen over internettet og se det som du selv ønsker. Tilføjelsen understøttes af over 40 filterabonnementer på mange sprog, som automatisk kan fjerne online reklamer og blokere kendte malware dommæner. Adblock Plus tilbyder også flere metoder for tilpasning af dine filtre, f.eks en højrekliksfunktion til billeder, et bloker faneblad for Flash og Java emner, og en liste over blokerbare emner til fjernelse af scripts og stilark.
diff --git a/chrome/locale/de/about.dtd b/chrome/locale/de/about.dtd
deleted file mode 100644
index cd28421..0000000
--- a/chrome/locale/de/about.dtd
+++ /dev/null
@@ -1,15 +0,0 @@
-<!ENTITY dialog.title "Ãber Adblock Plus">
-
-<!ENTITY version.title "Version">
-<!ENTITY description "
- Mit Adblock Plus können Sie entscheiden, was Sie im Internet sehen möchten
- und was nicht. Sie brauchen die ganze Werbung nicht mehr herunterzuladen,
- wenn Sie sie nicht sehen möchten - Adblock Plus regelt dies für Sie!
-">
-
-<!ENTITY homepage.label "Adblock Plus im Internet:">
-<!ENTITY author.label "Entwickler:">
-<!ENTITY contributors.label "Beteiligte:">
-
-<!ENTITY subscriptionAuthors.label "Autoren von Filterabonnements:">
-<!ENTITY translators.label "Ãbersetzer:">
diff --git a/chrome/locale/de/composer.dtd b/chrome/locale/de/composer.dtd
deleted file mode 100644
index c2f0b7a..0000000
--- a/chrome/locale/de/composer.dtd
+++ /dev/null
@@ -1,49 +0,0 @@
-<!ENTITY dialog.title "Neuen Filter hinzufügen">
-<!ENTITY accept.label "Filter hinzufügen">
-<!ENTITY advanced.label "Erweiterte Ansicht">
-<!ENTITY basic.label "Standardansicht">
-
-<!ENTITY disabled.warning "Adblock Plus ist deaktiviert. Sie können trotzdem den Filter hinzufügen, dieser wird jedoch erst angewandt, wenn Sie [link]Adblock Plus aktivieren[/link].">
-<!ENTITY groupDisabled.warning "Die Filtergruppe "?1?", in die dieser Filter eingefügt wird, ist derzeit deaktiviert. Sie können den Filter trotzdem hinzufügen, dieser wird jedoch erst angewandt, wenn Sie [link]diese Filtergruppe aktivieren[/link].">
-<!ENTITY filter.label "Neuer Filter:">
-<!ENTITY filter.accesskey "r">
-<!ENTITY preferences.label "Existierende Filter anzeigen...">
-<!ENTITY preferences.accesskey "z">
-<!ENTITY type.filter.label "Blockierregel">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Ausnahmeregel">
-<!ENTITY type.whitelist.accesskey "A">
-<!ENTITY pattern.label "Muster suchen">
-<!ENTITY pattern.explanation "Das Muster kann ein beliebiger Teil der Adresse sein, das Zeichen '*' kann dabei als Jokerzeichen verwendet werden. Der Filter wird nur auf Adressen angewandt, die auf das Muster passen.">
-<!ENTITY regexp.warning "Das Muster, das Sie eingegeben haben, wird als regulärer Ausdruck interpretiert. Zu viele reguläre Ausdrücke könnten Ihren Browser verlangsamen. Falls Sie nicht beabsichtigt haben, reguläre Ausdrücke zu verwenden, fügen Sie einfach das Symbol '*' am Ende des Musters an.">
-<!ENTITY shortpattern.warning "Das Muster, das Sie eingegeben haben, ist zu kurz zum Optimieren. Zu viele solche Muster könnten Ihren Browser verlangsamen. Es ist deshalb empfehlenswert, nach Möglichkeit einen längeren Muster für diesen Filter zu verwenden.">
-<!ENTITY match.warning "Das Muster, das Sie eingegeben haben, passt nicht mehr zu der Adresse, für die der Filter erstellt werden soll. Es wird keinen Einfluss mehr auf diese Adresse haben.">
-<!ENTITY custom.pattern.label "Benutzerdefiniert:">
-<!ENTITY custom.pattern.accesskey "n">
-<!ENTITY anchors.label "Muster nur akzeptieren:">
-<!ENTITY anchor.start.label "am Anfang der Adresse">
-<!ENTITY anchor.start.accesskey "f">
-<!ENTITY anchor.start.flexible.label "am Anfang des Domain-Namens">
-<!ENTITY anchor.start.flexible.accesskey "f">
-<!ENTITY anchor.end.label "am Ende der Adresse">
-<!ENTITY anchor.end.accesskey "d">
-<!ENTITY options.label "Optionen">
-<!ENTITY domainRestriction.label "Auf Domain beschränken:">
-<!ENTITY domainRestriction.accesskey "m">
-<!ENTITY domainRestriction.help "Geben Sie eine oder mehrere Domains an (Trennzeichen ist "|"), der Filter wird dann nur auf diesen Domains angewandt. Das Zeichen "~" vor einem Domainnamen bedeutet, dass der Filter auf dieser Domain nicht angewandt werden sollte.">
-<!ENTITY firstParty.label "Nur für Elemente der Ursprungsseite">
-<!ENTITY firstParty.accesskey "p">
-<!ENTITY thirdParty.label "Nur für Elemente von Drittseiten">
-<!ENTITY thirdParty.accesskey "t">
-<!ENTITY matchCase.label "GroÃ-/Kleinschreibung beachten">
-<!ENTITY matchCase.accesskey "K">
-<!ENTITY types.label "Auf Elementtypen anwenden:">
-<!ENTITY selectAllTypes.label "Alle auswählen">
-<!ENTITY unselectAllTypes.label "Keine auswählen">
-
-<!ENTITY collapse.label "Platz freigeben:">
-<!ENTITY collapse.accesskey "g">
-<!ENTITY collapse.default.yes.label "Standardeinstellung (ja)">
-<!ENTITY collapse.default.no.label "Standardeinstellung (nein)">
-<!ENTITY collapse.yes.label "Ja">
-<!ENTITY collapse.no.label "Nein">
diff --git a/chrome/locale/de/meta.properties b/chrome/locale/de/meta.properties
deleted file mode 100644
index dcf5b3b..0000000
--- a/chrome/locale/de/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Wladimir Palant
-name=Adblock Plus
-description=Werbung war gestern!
-description.short=Genervt von Werbung? Geplagt von Datensammlern? Jetzt Adblock Plus installieren, um die Kontrolle über das Internet wiederzuerlangen und es so zu erleben, wie es sein sollte.\n\nEine kurze Einleitung: http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Mit Adblock Plus haben Sie die Kontrolle wieder und bestimmen selber, was Sie sehen wollen. Die Erweiterung wird von über vierzig Filterabonnements für Dutzende Sprachen unterstützt, mit denen sie automatisch für verschiedene Einsatzzwecke konfiguriert wird, angefangen beim Blockieren von Werbung bis hin zum Blockieren bekannter bösartiger Webseiten. Mit Adblock Plus können Sie auch eigene Filter erstellen, unterstützt durch viele hilfreiche Features, z.B. ein Kontextmenü-Eintrag für Bilder, ein Tab zum Blockieren von Flash und Java, und die Liste blockierbarer Elemente zum Entfernen von Skripten.
diff --git a/chrome/locale/de/sendReport.dtd b/chrome/locale/de/sendReport.dtd
deleted file mode 100644
index b6afeac..0000000
--- a/chrome/locale/de/sendReport.dtd
+++ /dev/null
@@ -1,183 +0,0 @@
-<!ENTITY wizard.title "Fehler melden">
-<!ENTITY privacyPolicy.label "Datenschutzerklärung">
-
-<!ENTITY dataCollector.heading "Willkommen zum Fehlerberichts-Assistenten">
-<!ENTITY dataCollector.description "Bitte warten Sie einige Augenblicke, während Adblock Plus die benötigten Daten sammelt.">
-
-<!-- Please keep typeSelector.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY typeSelector.heading "Fehlerart wählen">
-
-<!ENTITY typeSelector.description "
- Dieser Assistent wird Sie durch die nötigen Schritte zum Melden eines Adblock Plus-Fehlers
- leiten. Zuerst wählen Sie bitte die Art des Fehlers, den Sie auf dieser Seite
- beobachten:
-">
-
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus blockiert zu viel">
-<!ENTITY typeSelector.falsePositive.accesskey "v">
-<!ENTITY typeSelector.falsePositive.description "
- Wählen Sie diese Option, falls auf der Seite wichtige Inhalte fehlen, die Seite
- falsch angezeigt wird oder nicht korrekt funktioniert. Sie können feststellen,
- ob Adblock Plus das Problem verursacht, indem Sie es vorübergehend deaktivieren.
-">
-
-<!ENTITY typeSelector.falseNegative.label "Eine Werbeeinblendung wird von Adblock Plus nicht blockiert">
-<!ENTITY typeSelector.falseNegative.accesskey "W">
-<!ENTITY typeSelector.falseNegative.description "
- Wählen Sie diese Option, falls Werbung auf der Seite angezeigt wird, obwohl
- Adblock Plus aktiviert ist.
-">
-
-<!ENTITY typeSelector.other.label "Anderer Fehler">
-<!ENTITY typeSelector.other.accesskey "d">
-<!ENTITY typeSelector.other.description "
- Wählen Sie diese Option, falls Sie ein Problem mit Adblock Plus selber und nicht
- mit dessen Filtern vermuten.
-">
-
-<!ENTITY showRecentReports.label "Zuletzt gesendeten Fehlerberichte anzeigen">
-<!ENTITY recentReports.label "Ihre zuletzt gesendeten Fehlerberichte">
-<!ENTITY recentReports.clear.label "Alle Berichte löschen">
-<!ENTITY recentReports.clear.accesskey "r">
-
-<!ENTITY issues.description "
- Adblock Plus hat Probleme in Ihren Einstellungen gefunden, die für das vorliegende
- Problem verantwortlich sein könnten oder eine Untersuchung des Problems behindern
- würden.
-">
-
-<!ENTITY issues.whitelist.description "
- Adblock Plus ist derzeit deaktiviert auf der Seite, für die Ihr Bericht gesendet werden
- soll. Bitte aktivieren Sie Adblock Plus wieder und laden Sie die Seite neu, bevor Sie
- den Fehler melden. Das wird die Untersuchung des Problems vereinfachen.
-">
-<!ENTITY issues.whitelist.remove.label "Adblock Plus auf dieser Seite wieder aktivieren">
-
-<!ENTITY issues.disabled.description "
- Adblock Plus ist deaktiviert, in diesem Zustand wird es nichts blockieren.
-">
-<!ENTITY issues.disabled.enable.label "Adblock Plus aktivieren">
-
-<!ENTITY issues.nofilters.description "
- Adblock Plus blockiert auf dieser Seite nichts. Das Problem, das Sie sehen, wurde
- wahrscheinlich nicht von Adblock Plus verursacht.
-">
-
-<!ENTITY issues.nosubscriptions.description "
- Es scheint, dass sie keine der fertigen Filterlisten abonniert haben. Ein solches
- kostenloses Abonnement ist jedoch erforderlich, um automatisch Werbung zu entfernen.
-">
-<!ENTITY issues.nosubscriptions.add.label "Filterabonnement hinzufügen">
-
-<!ENTITY issues.subscriptionCount.description "
- Es scheint, dass Sie zu viele Filterlisten abonniert haben. Das ist nicht
- empfohlen, weil die Wahrscheinlichkeit von Problemen dadurch sehr stark
- ansteigt. Wir können auÃerdem Ihren Fehlerbericht nicht annehmen, weil unklar
- ist, welche Filterliste für das Problem verantwortlich ist. Bitte entfernen
- Sie alle bis auf die wirklich notwendigen Filterabonnements und überprüfen
- Sie dann, ob das Problem immer noch auftritt.
-">
-<!ENTITY issues.openPreferences.label "Filtereinstellungen öffnen">
-
-<!ENTITY issues.ownfilters.description "
- Einige der Filter, die auf dieser Seite angewandt wurden, sind benutzerdefiniert.
- Bitte deaktivieren Sie Filter, die das Problem verursacht haben könnten:
-">
-<!ENTITY issues.ownfilters.disable.label "Filter deaktivieren">
-
-<!ENTITY issues.disabledgroups.description "
- Die folgenden Filterabonnements / Filtergruppen sind deaktiviert, hätten jedoch
- einen Einfluss auf diese Webseite:
-">
-<!ENTITY issues.disabledgroups.enable.label "Filterabonnement / Filtergruppe aktivieren">
-
-<!ENTITY issues.disabledfilters.description "
- Die folgenden Filter sind deaktiviert, hätten jedoch einen Einfluss auf diese Webseite:
-">
-<!ENTITY issues.disabledfilters.enable.label "Filter aktivieren">
-
-<!ENTITY issues.override.label "Die Einstellungen sind so korrekt, mit dem Fehlerbericht fortfahren">
-<!ENTITY issues.override.accesskey "k">
-<!ENTITY issues.change.description "
- Ihre Einstellungen wurden geändert. Bitte laden Sie die Seite neu, um die Ãnderungen
- jetzt zu testen. Bitte melden Sie den Fehler, falls das Problem durch die
- Ãnderungen nicht gelöst wurde.
-">
-
-<!ENTITY typeWarning.description "
- Sie haben angedeutet, dass Sie ein allgemeines Problem mit Adblock Plus melden wollen
- und kein Filterproblem. Bitte beachten Sie, dass solche Probleme am besten im
- [link]Adblock Plus Forum[/link] gemeldet werden sollten. Den Fehlerberichts-Assistenten
- sollte man nur als Ergänzung zu einer vorhandenen Diskussion verwenden. Sie müssen
- den Link zu Ihrem Fehlerbericht angeben, weil ihn sonst niemand sehen wird.
- Diesen automatisch generierten Link bekommen Sie nach dem Senden des Berichts.
-">
-
-<!ENTITY typeWarning.override.label "Ich verstehe und will trotzdem einen Fehlerbericht einsenden">
-<!ENTITY typeWarning.override.accesskey "v">
-
-<!ENTITY reloadButton.label "Seite neu laden">
-<!ENTITY reloadButton.accesskey "n">
-
-<!-- Please keep screenshot.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY screenshot.heading "Screenshot hinzufügen">
-
-<!ENTITY screenshot.description "
- Dieselbe Seite kann bei verschiedenen Leuten verschieden aussehen. Deswegen könnte es
- hilfreich sein, wenn Sie zu Ihrem Bericht ein Bild der Webseite hinzufügen. Sie können
- Teile der Seite entfernen, falls sie private Informationen enthalten. Ebenso können
- Sie Stellen markieren, wo das Problem deutlich wird. Klicken Sie dafür die entsprechende
- Taste und markieren Sie den Bereich auf dem Bild mit der Maus.
-">
-
-<!ENTITY screenshot.attach.label "Dieses Bild meinem Bericht hinzufügen">
-<!ENTITY screenshot.attach.accesskey "B">
-<!ENTITY screenshot.mark.label "Problem markieren">
-<!ENTITY screenshot.mark.accesskey "m">
-<!ENTITY screenshot.remove.label "Private Informationen löschen">
-<!ENTITY screenshot.remove.accesskey "P">
-<!ENTITY screenshot.undo.label "Rückgängig">
-<!ENTITY screenshot.undo.accesskey "R">
-
-<!-- Please keep commentPage.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY commentPage.heading "Kommentar eingeben">
-
-<!ENTITY commentPage.description "
- Unten können Sie einen Kommentar eingeben, um uns zu helfen, das Problem zu verstehen.
- Das ist zwar optional, ist jedoch empfohlen, falls das Problem nicht offensichtlich ist.
- Sie können auch die Daten Ihres Berichts überprüfen, bevor sie gesendet werden.
-">
-
-<!ENTITY comment.label "Kommentar (optional):">
-<!ENTITY comment.accesskey "K">
-<!ENTITY comment.lengthWarning "Ihr Kommentar ist länger als 1000 Zeichen. Nur die ersten 1000 Zeichen werden gesendet.">
-<!ENTITY email.label "Email-Adresse für zusätzliche Nachfragen (optional):">
-<!ENTITY email.accesskey "m">
-
-<!ENTITY attachExtensions.label "Liste aktiver Erweiterungen anhängen für den Fall, dass das Problem von einer anderen Erweiterung verursacht wird">
-<!ENTITY attachExtensions.accesskey "w">
-
-<!ENTITY sendButton.label "Bericht absenden">
-<!ENTITY sendButton.accesskey "s">
-
-<!ENTITY showData.label "Berichtdaten anzeigen">
-<!ENTITY data.label "Berichtdaten:">
-<!ENTITY data.accesskey "d">
-
-<!-- Please keep sendPage.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY sendPage.heading "Bericht absenden">
-<!ENTITY sendPage.waitMessage "Bitte warten Sie, während Adblock Plus Ihren Bericht sendet.">
-<!ENTITY sendPage.confirmation "Ihr Bericht wurde gespeichert. Sie können Ihn unter der folgenden Adresse aufrufen:">
-<!ENTITY sendPage.knownIssue "Das Problem, das Sie berichtet haben, ist möglicherweise bereits bekannt. Zusätzliche Information:">
-
-<!-- Note: the placeholder ?1? will be replaced by the error code -->
-<!ENTITY sendPage.errorMessage "
- Beim Senden des Berichts ist ein Fehler aufgetreten (Fehlercode "?1?").
- Bitte stellen Sie sicher, dass Sie mit dem Internet verbunden sind, und versuchen
- Sie, den Bericht noch einmal zu senden. Falls das Problem bestehen bleibt, wenden
- Sie sich an das [link]Adblock Plus Forum[/link].
-">
-<!ENTITY sendPage.retry.label "Noch einmal senden">
-
-<!ENTITY copyLink.label "Link zum Bericht kopieren">
-<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/locale/de/subscriptionSelection.dtd b/chrome/locale/de/subscriptionSelection.dtd
deleted file mode 100644
index a72c60a..0000000
--- a/chrome/locale/de/subscriptionSelection.dtd
+++ /dev/null
@@ -1,38 +0,0 @@
-<!ENTITY dialog.title "Filterabonnement für Adblock Plus hinzufügen">
-<!ENTITY dialog.title.edit "Filterabonnement bearbeiten">
-
-<!ENTITY description.newInstall "
- Adblock Plus funktioniert am besten, wenn ein Filterabonnement hinzugefügt wird.
- Filterabonnements werden von anderen Adblock Plus Nutzern kostenfrei zur
- Verfügung gestellt. Das Filterabonnement, das zu Ihrer Sprache am besten passt,
- ist bereits voreingestellt.
-">
-
-<!ENTITY subscriptionSelector.label "Bitte wählen Sie ein Filterabonnement aus der Liste aus:">
-
-<!ENTITY viewList.label "Filter ansehen">
-<!ENTITY visitHomepage.label "Webseite der Filterliste besuchen">
-
-<!ENTITY addSubscription.label "Filterabonnement hinzufügen">
-<!ENTITY saveSubscription.label "Ãnderungen speichern">
-
-<!ENTITY other.label "Anderes Abonnement hinzufügen">
-<!ENTITY other.accesskey "d">
-
-<!ENTITY list.download.failed "Adblock Plus konnte die Liste der Filterabonnements nicht herunterladen.">
-<!ENTITY list.download.retry "Nochmal versuchen">
-<!ENTITY list.download.website "Zur Webseite wechseln">
-<!ENTITY fromWeb.description "Bitte bestätigen Sie, dass Sie dieses Filterabonnement hinzufügen möchten. Die Bezeichnung und Adresse der Abonnements können vor dem Hinzufügen geändert werden.">
-<!ENTITY edit.description "Bitte ändern Sie die Bezeichnung und Adresse der Abonnements wie erforderlich.">
-<!ENTITY external.description "Das ist ein externes Filterabonnement, es wird von der Erweiterung aktualisiert, die es erstellt hat.">
-
-<!ENTITY title.label "Bezeichnung des Abonnements:">
-<!ENTITY title.accesskey "z">
-<!ENTITY location.label "Adresse der Filterliste:">
-<!ENTITY location.accesskey "r">
-<!ENTITY autodownload.label "Automatisch aktualisieren">
-<!ENTITY autodownload.accesskey "t">
-
-<!ENTITY supplementMessage "Dieses Filterabonnement sollte in Verbindung mit dem Filterabonnement "?1?" verwendet werden.">
-<!ENTITY addMain.label "Filterabonnement "?1?" auch hinzufügen">
-<!ENTITY addMain.accesskey "h">
diff --git a/chrome/locale/el/meta.properties b/chrome/locale/el/meta.properties
deleted file mode 100644
index d5aa065..0000000
--- a/chrome/locale/el/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=rookie
-name=Adblock Plus
-description=ÎÏήÏÏε ÏÎ¹Ï Î´Î¹Î±ÏημίÏÎµÎ¹Ï ÏÏο ÏθεÏ!
-description.short=ÎνοÏλημÎνοι αÏÏ ÏÎ¹Ï Î´Î¹Î±ÏημίÏειÏ; Î ÏοβλημαÏιÏμÎνοι αÏÏ Ïην καÏαγÏαÏή ÏÏν κινήÏεÏν ÏαÏ; Î£Î±Ï ÎµÎ¼ÏοδίζοÏ
ν Ïα banners; ÎγκαÏαÏÏήÏÏε Ïο Adblock Plus και αÏοκÏήÏÏε Ïον ÎλεγÏο ÏοÏ
διαδικÏÏοÏ
. ÎλλάξÏε Ïον ÏÏÏÏο ÏοÏ
βλÎÏεÏε ÏÎ¹Ï ÏελίδεÏ.
-description.long=Το Adblock Plus ÏÎ±Ï Î´Î¯Î½ÎµÎ¹ Ïην δÏ
ναÏÏÏηÏα να αÏοκÏήÏεÏε Ïον ÎλεγÏο ÏοÏ
διαδικÏÏοÏ
και να βλÎÏεÏε ÏÎ¹Ï ÏÎµÎ»Î¯Î´ÎµÏ ÏÏÏÏ ÎµÏÎµÎ¯Ï Î¸ÎλεÏε. ΠεÏÎκÏαÏη αÏ
Ïή, Ï
ÏοÏÏηÏίζεÏαι με ÏαÏαÏÎ¬Î½Ï Î±ÏÏ ÏαÏάνÏα ÏÏ
νδÏομÎÏ ÏίλÏÏÏν Ïε Î´ÎµÎºÎ¬Î´ÎµÏ Î³Î»ÏÏÏεÏ. ΧÏηÏιμοÏοιÏνÏÎ±Ï ÏÎ¹Ï ÏÏ
νδÏομÎÏ, Ïο Adblock Plus μÏοÏεί να ÏÏ
θμιÏÏεί ÏÏÏε να ÏÎ±Ï ÏÏοÏÏαÏεÏει αÏÏ ÏÎ¹Ï Î±Î½ÎµÏιθÏμηÏÎµÏ Î´Î¹Î±ÏημίÏÎµÎ¹Ï Î¼ÎÏÏι και να μÏλοκάÏει ÏÎ¹Ï ÎºÎ±ÎºÏβοÏ
Î»ÎµÏ ÏελίδεÏ. ÎÏίÏÎ·Ï Î¼ÏοÏείÏε να ÏÏοÏαÏμÏζεÏε Ïα ÏίλÏÏα με Ïην βοήθεια ÏÏήÏιμÏν λειÏοÏ
ÏγιÏν ÏοÏ
ÏεÏιλαμβάνοÏ
ν Ïην ÏÏαγή εικÏνÏν, ανÏικειμÎνÏν Flash και Java και μια λίÏÏα με Ïλα Ïα ανÏικείμενα ÏÎ·Ï ÏÎµÎ»Î¯Î´Î±Ï ÏÏÏε η ÏÏαγή ÏÏν scripts και ÏÏν stylesheets να γίνεÏαι ÏαιÏνίδι.
diff --git a/chrome/locale/en-GB/meta.properties b/chrome/locale/en-GB/meta.properties
deleted file mode 100644
index 2e1483b..0000000
--- a/chrome/locale/en-GB/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Mark Tyndall
-name=Adblock Plus
-description=Ads were yesterday!
-description.short=Annoyed by adverts? Troubled by tracking? Bothered by banners? Install Adblock Plus now to regain control of the internet and change the way that you view the web.\n\nA short video overview is available at http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus allows you to regain control of the internet and view the web the way you want to. The add-on is supported by over forty filter subscriptions in dozens of languages which automatically configure it for purposes ranging from removing online advertising to blocking all known malware domains. Adblock Plus also allows you to customise your filters with the assistance of a variety of useful features, including a context option for images, a block tab for Flash and Java objects, and a list of blockable items to remove scripts and stylesheets.
diff --git a/chrome/locale/en-US/about.dtd b/chrome/locale/en-US/about.dtd
deleted file mode 100644
index 4eba5a2..0000000
--- a/chrome/locale/en-US/about.dtd
+++ /dev/null
@@ -1,14 +0,0 @@
-<!ENTITY dialog.title "About Adblock Plus">
-
-<!ENTITY version.title "Version">
-<!ENTITY description "
- Adblock Plus allows you to decide what you want to see on the web.
- You don't need to download adverts and banners any more; if you
- don't want them - remove them with Adblock Plus!
-">
-
-<!ENTITY homepage.label "Adblock Plus homepage:">
-<!ENTITY author.label "Author:">
-<!ENTITY contributors.label "Contributors:">
-<!ENTITY subscriptionAuthors.label "Filter subscription authors:">
-<!ENTITY translators.label "Translators:">
diff --git a/chrome/locale/en-US/meta.properties b/chrome/locale/en-US/meta.properties
deleted file mode 100644
index 7f9a6ef..0000000
--- a/chrome/locale/en-US/meta.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-# Translator of this locale, separate by commas if multiple
-translator=Wladimir Palant
-# Extension title, usually it shouldn't be translated
-name=Adblock Plus
-# Extension description, to be displayed in the add-on manager
-description=Ads were yesterday!
-# Short description for addons.mozilla.org (250 characters limit!). Leave out the link to English-language video if it isn't useful for users speaking your language.
-description.short=Annoyed by adverts? Troubled by tracking? Bothered by banners? Install Adblock Plus now to regain control of the internet and change the way that you view the web.\n\nA short video overview is available at http://www.youtube.com/watch?v=oNvb2SjVjjI
-# Long description for addons.mozilla.org
-description.long=Adblock Plus allows you to regain control of the internet and view the web the way you want to. The add-on is supported by over forty filter subscriptions in dozens of languages which automatically configure it for purposes ranging from removing online advertising to blocking all known malware domains. Adblock Plus also allows you to customize your filters with the assistance of a variety of useful features, including a context option for images, a block tab for Flash and Java objects, and a list of blockable items to remove scripts and stylesheets.
diff --git a/chrome/locale/en-US/subscriptionSelection.dtd b/chrome/locale/en-US/subscriptionSelection.dtd
deleted file mode 100644
index b0109c7..0000000
--- a/chrome/locale/en-US/subscriptionSelection.dtd
+++ /dev/null
@@ -1,41 +0,0 @@
-<!ENTITY dialog.title "Add Adblock Plus filter subscription">
-<!ENTITY dialog.title.edit "Edit filter subscription">
-
-<!ENTITY description.newInstall "
- Adblock Plus will be most effective if you add a filter subscription.
- Filter subscriptions are provided by other Adblock Plus users free of
- charge. The most suitable subscription for your language is already
- selected.
-">
-
-<!ENTITY subscriptionSelector.label "Please choose a filter subscription from the list:">
-
-<!ENTITY viewList.label "View filters">
-<!ENTITY visitHomepage.label "Visit home page">
-
-<!ENTITY addSubscription.label "Add subscription">
-<!ENTITY saveSubscription.label "Save subscription">
-
-<!ENTITY other.label "Add a different subscription">
-<!ENTITY other.accesskey "f">
-
-<!ENTITY list.download.failed "Adblock Plus failed to retrieve the list of subscriptions.">
-<!ENTITY list.download.retry "Try again">
-<!ENTITY list.download.website "View website">
-
-<!ENTITY fromWeb.description "Please confirm that you want to add this filter subscription. You can change the subscription title or location before adding it.">
-<!ENTITY edit.description "You can change the subscription title or location as necessary.">
-<!ENTITY external.description "This is an external filter subscription; it will be updated by the extension that created this subscription.">
-
-<!ENTITY title.label "Subscription title:">
-<!ENTITY title.accesskey "t">
-<!ENTITY location.label "Filter list location:">
-<!ENTITY location.accesskey "l">
-<!ENTITY autodownload.label "Update filters automatically">
-<!ENTITY autodownload.accesskey "p">
-
-<!-- Note: the placeholder (?1?) will be replaced by the name of the filter subscription required -->
-<!ENTITY supplementMessage "This filter subscription is meant to be used with the filter subscription "?1?" which you are not using yet.">
-<!-- Note: the placeholder (?1?) will be replaced by the name of the filter subscription required -->
-<!ENTITY addMain.label "Add filter subscription "?1?" as well">
-<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/eo/meta.properties b/chrome/locale/eo/meta.properties
deleted file mode 100644
index 923d534..0000000
--- a/chrome/locale/eo/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Milupo
-name=Adblock Plus
-description=Anoncoj estis hieraÅ!
-description.short=Äu vi Äagrenas pri anoncoj, kolektantoj de datumoj kaj reklamrubandoj? Instalu Adblock Plus por regajni la kontrolon pri la interreto kaj ÅanÄu la manieron kiel rigardi la reton.\n\nMallonga video estas Äe http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus ebligas al vi regajni la kontrolon pri la interreto kaj rigardi la reton tiel, kiel vi volas tion. La aldonaĵo estas kompletigata per pli ol kvardek filtrilabonoj en dekduoj da lingvoj, kiuj aÅtomate konfiguras Äin por celoj, komencante kun forigo de reta reklamo Äis blokado de Äiuj retregionoj de fiprogramaro. Adblock Plus ankaÅ ebligas al vi adapti viajn filtrilojn helpe de multnombraj utilaj funkcioj, inter ili kunteksta opcio por bildoj, langeto por bloki objektojn de Flash kaj Äavo kaj listo de blokeblaj elementoj por forigi skriptojn kaj stilfoliojn.
diff --git a/chrome/locale/es-AR/meta.properties b/chrome/locale/es-AR/meta.properties
deleted file mode 100644
index 61a4a15..0000000
--- a/chrome/locale/es-AR/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=KNTRO
-name=Adblock Plus
-description=¡La publicidad es cosa del pasado!
-description.short=¿Te molestan las publicidades? ¿Te fastidian los báners? Instalá Adblock Plus ahora para recuperar el control de Internet y cambiar la forma en que ves la web.\n\nPodés ver un pantallazo, en video, en http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus te permite recuperar el control de Internet y cambiar la forma en que ves la web. La extensión incluye soporte para más de cuarenta suscripciones de filtros, en docenas de idiomas, cuyos propósitos van desde quitar publicidad en lÃnea hasta bloquear todos los dominios maliciosos conocidos. Adblock Plus también te permite configurar tus filtros con la asistencia de una variedad de funciones muy útiles, incluyendo una opción contextual para imágenes, una pestaña de bloqueos para objetos Flash y Java, y una lista de elementos susceptibles de ser bloqueados, para quitar asà scripts y hojas de estilo.
diff --git a/chrome/locale/es-ES/meta.properties b/chrome/locale/es-ES/meta.properties
deleted file mode 100644
index ad8642a..0000000
--- a/chrome/locale/es-ES/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Urko
-name=Adblock Plus
-description=La publicidad es cosa del ayer
-description.short=¿Le molestan los anuncios, los banners, que espÃen su navegación? Instale Adblock Plus para recuperar el control de Internet y cambie la forma en la que ve la web.\n\nPuede consultar la información en español en http://adblockplus.org/es/
-description.long=Adblock Plus le permite recuperar el control de Internet y ver la web como usted quiera. Esta extensión está apoyada por más de cuarenta suscripciones de filtros en docenas de idiomas que la configuran automáticamente para poder desde eliminar la publicidad online hasta bloquear todos los dominios de malware conocidos. Adblock Plus también le permite personalizar sus filtros con la ayuda de varias funciones útiles, como la opción del menú contextual para imágenes, la pestaña de bloqueo de objetos Flash y Java, y una lista de elementos bloqueables para eliminar scripts y hojas de estilo.
diff --git a/chrome/locale/es-MX/meta.properties b/chrome/locale/es-MX/meta.properties
deleted file mode 100644
index c45b4b2..0000000
--- a/chrome/locale/es-MX/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ninnetyer
-name=Adblock Plus
-description=Los Anuncios son cosa del Ayer!
-description.short=Irritado por los anuncios? Preocupado por los seguimientos? Molesto por tantos banners? Instala Adblock Plus ahora y recupera el control del internet y cambia el modo en el que ves la web.\n\nMas Info en: http://adblockplus.org/es
-description.long=Adblock Plus te permite recuperar el control de la internet y ver la web del modo en el que tu lo deseas. El complemento es apoyado por más de cuarenta subscripciones de filtros en docenas de idiomas que la configuran automáticamente para los propósitos que van desde la eliminación de publicidad en lÃnea a bloquear todos los dominios conocidos con malware en ellos. Adblock Plus también te permite personalizar tus filtros con la asistencia de una variedad de útiles caracterÃsticas, incluyendo una opción de contexto para las imágenes, una pestaña de bloqueo para ventanas y objetos de Flash y Java, y una lista de elementos bloqueables para asà eliminar los scripts y hojas de estilo no deseados.
diff --git a/chrome/locale/es-MX/overlay.dtd b/chrome/locale/es-MX/overlay.dtd
deleted file mode 100644
index 242007b..0000000
--- a/chrome/locale/es-MX/overlay.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY status.tooltip "Estado:">
-<!ENTITY blocked.tooltip "Elementos bloqueados en esta pagina:">
-<!ENTITY filters.tooltip "Filtros mas activos:">
-<!ENTITY menuitem.label "Preferencias de Adblock Plus">
-<!ENTITY menuitem.accesskey "e">
-<!ENTITY toolbarbutton.label "Adblock plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: Elementos bloqueables">
-<!ENTITY context.image.label "Adblock Plus: Bloquear imagen">
-<!ENTITY context.object.label "Adblock Plus: Bloquear objeto">
-<!ENTITY context.frame.label "Adblock Plus: Bloquear marco">
-<!ENTITY context.media.label "Adblock Plus: Bloquear sonido/video">
-<!ENTITY context.removeWhitelist.label "Adblock Plus: Re-habilitar en esta pagina">
-<!ENTITY sidebar.title "Elementos bloqueables en la pagina actual">
-<!ENTITY sendReport.label "Reportar problema en esta pagina">
-<!ENTITY sendReport.accesskey "a">
-<!ENTITY settings.label "Preferencias">
-<!ENTITY settings.accesskey "P">
-<!ENTITY opensidebar.label "Abrir elementos bloqueables">
-<!ENTITY opensidebar.accesskey "r">
-<!ENTITY closesidebar.label "Cerrar elementos bloqueables">
-<!ENTITY closesidebar.accesskey "r">
-<!ENTITY whitelist.site.label "Deshabilitar en ?1?">
-<!ENTITY whitelist.page.label "Deshabilitar solo en esta pagina">
-<!ENTITY objecttab.title "Bloquear">
-<!ENTITY objecttab.tooltip "Clicke aquà para bloquear este objecto con Adblock Plus">
diff --git a/chrome/locale/es-MX/sendReport.dtd b/chrome/locale/es-MX/sendReport.dtd
deleted file mode 100644
index 955c700..0000000
--- a/chrome/locale/es-MX/sendReport.dtd
+++ /dev/null
@@ -1,73 +0,0 @@
-<!ENTITY wizard.title "Reportero de problemas">
-<!ENTITY privacyPolicy.label "PolÃtica de Privacidad">
-<!ENTITY dataCollector.heading "Bienvenido al reportero de problemas">
-<!ENTITY dataCollector.description "Por favor espere un momento mientras Adblock Plus reúne los datos necesarios.">
-<!ENTITY typeSelector.heading "Elija tipo de error">
-<!ENTITY typeSelector.description "Esta ventana lo guiara con pasos, necesarios para el envio de un reporte de problemas de Adblock Plus. Primero, por favor seleccione el tipo de problema que esta experimentando en esta pagina:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus esta bloqueando demasiado">
-<!ENTITY typeSelector.falsePositive.accesskey "A">
-<!ENTITY typeSelector.falsePositive.description "Seleccione esta opción si la pagina carece de contenido importante, muestra incorrectamente o falla al funcionar como debe. Puede determinar si Adblock Plus es el causante del problema deshabilitandolo temporalmente.">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus no bloquea una publicidad">
-<!ENTITY typeSelector.falseNegative.accesskey "b">
-<!ENTITY typeSelector.falseNegative.description "Seleccione esta opción si una publicidad continua mostrandose a pesar que Adblock Plus se encuentra habilitado.">
-<!ENTITY typeSelector.other.label "Otro problema">
-<!ENTITY typeSelector.other.accesskey "O">
-<!ENTITY typeSelector.other.description "Seleccione esta opción si usted sospecha un problema con Adblock Plus especificamente en lugar de sus filtros.">
-<!ENTITY showRecentReports.label "Mostrar reportes enviados recientemente">
-<!ENTITY recentReports.label "Tus reportes recientemente enviados">
-<!ENTITY recentReports.clear.label "Quitar todos los reportes">
-<!ENTITY recentReports.clear.accesskey "Q">
-<!ENTITY issues.description "Adblock Plus ha detectado problemas con su configuración que puede ser la causa de este problema o que podria dificultar la investigación del problema.">
-<!ENTITY issues.whitelist.description "Adblock Plus se encuentra deshabilitado en la pagina que esta reportando. Por favor vuelva a habilitarlo y recargue la pagina antes de presentar el el informe para ayudar a la investigación de este tema.">
-<!ENTITY issues.whitelist.remove.label "Re-habilitar Adblock Plus en esta pagina">
-<!ENTITY issues.disabled.description "Adblock Plus esta deshabilitado, no bloqueara nada en su estado actual.">
-<!ENTITY issues.disabled.enable.label "Habilitar Adblock Plus">
-<!ENTITY issues.nofilters.description "Adblock Plus no esta bloqueando nada en la pagina actual. El problema que esta observando es probable que no se encuentre relacionado a Adblock Plus.">
-<!ENTITY issues.nosubscriptions.description "Usted no parece estar suscrito a ninguna lista de filtro pre-desarrollado que automáticamente remueve contenido no deseado de los sitios web.">
-<!ENTITY issues.nosubscriptions.add.label "Agregar filtro de suscripción">
-<!ENTITY issues.ownfilters.description "Alguno de los filtros aplicados en esta pagina se encuentran definidos por el usuarios. Por favor deshabilite los filtros que pueden causar el problema.">
-<!ENTITY issues.ownfilters.disable.label "Deshablitar filtro">
-<!ENTITY issues.disabledgroups.description "La siguiente subscripcion/Grupo de filtros se encuentra deshabilitada, aun asi pueden tener efectos en esta pagina:">
-<!ENTITY issues.disabledgroups.enable.label "Habilitar subscripcion/Grupo de filtros">
-<!ENTITY issues.disabledfilters.description "Los siguientes filtros estan deshabilitados, aun asi pueden tener efectos en esta pagina:">
-<!ENTITY issues.disabledfilters.enable.label "Habilitar filtro">
-<!ENTITY issues.override.label "La configuración es correcta, continue con el reporte">
-<!ENTITY issues.override.accesskey "L">
-<!ENTITY issues.change.description "Su configuración ha sido cambiada. Por favor recargue la pagina para probar los cambios y presentar un reporte si el problema no ha sido resuelto por las alteraciones.">
-<!ENTITY typeWarning.description "Ha indicado que desea reportar un problema general con Adblock Plus en lugar de un problema con los filtros. Por favor tenga en cuenta que estos problemas son mejor reportados en el [link]Foro de Adblock Plus[/link]. Solo deberia usar el reportero de problemas para complementar una discución existente, ya que nadie se percatara de su informe a menos que se les proporcione el enlace a la misma. El enlace generado automáticamente sera proporcionado despues de presentar el reporte respectivo.">
-<!ENTITY typeWarning.override.label "Entiendo y deseo presentar el reporte de todos modos">
-<!ENTITY typeWarning.override.accesskey "E">
-<!ENTITY reloadButton.label "Recargar pagina">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.heading "Adjuntar captura de pantalla">
-<!ENTITY screenshot.description "La misma pagina puede parecer diferente para cada persona. Puede ayudarnos a entender el problema si adjunta una captura de pantalla a su reporte. Puede quitar partes que contengan informacion sensitiva/privada asi mismo marcar areas donde el problema se note. Para hacerlo clicke el botón correspondiente y seleccione una parte de la imagen con su cursor/puntero.">
-<!ENTITY screenshot.attach.label "Adjuntar una imagen de la pagina al reporte">
-<!ENTITY screenshot.attach.accesskey "i">
-<!ENTITY screenshot.mark.label "Marcar el problema">
-<!ENTITY screenshot.mark.accesskey "M">
-<!ENTITY screenshot.remove.label "Quitar datos sensitivos/privados">
-<!ENTITY screenshot.remove.accesskey "u">
-<!ENTITY screenshot.undo.label "Deshacer">
-<!ENTITY screenshot.undo.accesskey "D">
-<!ENTITY commentPage.heading "Comentar">
-<!ENTITY commentPage.description "El campo de texto a continuación le permite escribir un comentario para ayudarnos a entender el problema. Este paso es opcional pero recomendado si el problema no es obvio. Puede tambien revisar el reporte de datos antes de que sea enviado.">
-<!ENTITY comment.label "Comentario (opcional):">
-<!ENTITY comment.accesskey "n">
-<!ENTITY comment.lengthWarning "El tamaño de su comentario excede los 1000 caracteres. Solo los primeros 1000 caracteres seran enviados.">
-<!ENTITY email.label "Correo Electrónico para futuras investigaciones (opcional):">
-<!ENTITY email.accesskey "r">
-<!ENTITY attachExtensions.label "Adjuntar una lista de extensiones activas a el repote en caso de que un conflicto de complementos sea la causa del problema">
-<!ENTITY attachExtensions.accesskey "d">
-<!ENTITY sendButton.label "Enviar reporte">
-<!ENTITY sendButton.accesskey "v">
-<!ENTITY showData.label "Mostrar datos del reporte">
-<!ENTITY data.label "Datos de Reporte">
-<!ENTITY data.accesskey "t">
-<!ENTITY sendPage.heading "Enviar reporte">
-<!ENTITY sendPage.waitMessage "Por favor espere mientras Adblock Plus envÃa su reporte.">
-<!ENTITY sendPage.confirmation "Su reporte ha sido salvado. Puede acceder al mismo en la siguiente direccion:">
-<!ENTITY sendPage.knownIssue "El problema que ha reportado probablemente ya sea conocido. Mas información:">
-<!ENTITY sendPage.errorMessage "Un intento de enviar el reporte ha fallado con el código de error "?1?". Por favor asegúrese de que se encuentra conectado a internet y vuelva a intentarlo. Si el problema persiste por favor solicite asistencia en el [link]Foro de Adblock Plus[/link].">
-<!ENTITY sendPage.retry.label "Enviar otra vez">
-<!ENTITY copyLink.label "Copiar dirección del reporte">
-<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/es-MX/settings.dtd b/chrome/locale/es-MX/settings.dtd
deleted file mode 100644
index fd41161..0000000
--- a/chrome/locale/es-MX/settings.dtd
+++ /dev/null
@@ -1,87 +0,0 @@
-<!ENTITY dialog.title "Preferencia de Adblock Plus">
-<!ENTITY filters.label "Filtros">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Agregar filtro">
-<!ENTITY add.accesskey "g">
-<!ENTITY addsubscription.label "Agregar suscripción de filtro">
-<!ENTITY addsubscription.accesskey "l">
-<!ENTITY synchsubscriptions.label "Actualizar todas las suscripciones">
-<!ENTITY synchsubscriptions.accesskey "z">
-<!ENTITY import.label "Importar filtros">
-<!ENTITY import.accesskey "I">
-<!ENTITY export.label "Exportar filtros personalizados">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.label "Quitar todos los filtros personalizados">
-<!ENTITY clearall.accesskey "Q">
-<!ENTITY resethitcounts.label "Restablecer contador de filtros">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "Editar">
-<!ENTITY edit.accesskey "d">
-<!ENTITY cut.label "Cortar">
-<!ENTITY cut.accesskey "t">
-<!ENTITY copy.label "Copiar">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "Pegar">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "Eliminar">
-<!ENTITY remove.accesskey "E">
-<!ENTITY menu.find.label "Buscar">
-<!ENTITY menu.find.accesskey "B">
-<!ENTITY menu.findagain.label "Buscar de nuevo">
-<!ENTITY menu.findagain.accesskey "u">
-<!ENTITY view.label "Ver">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "Ordenar por">
-<!ENTITY sort.accesskey "p">
-<!ENTITY sort.none.label "Sin clasificar">
-<!ENTITY sort.none.accesskey "S">
-<!ENTITY sort.ascending.label "Ordernar de la A > Z">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Ordernar de la Z > A">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Opciones">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "Habilitar Adblock Plus">
-<!ENTITY enable.accesskey "k">
-<!ENTITY showintoolbar.label "Mostrar barra de herramientas">
-<!ENTITY showintoolbar.accesskey "h">
-<!ENTITY showinstatusbar.label "Mostrar en la barra de estado">
-<!ENTITY showinstatusbar.accesskey "M">
-<!ENTITY objecttabs.label "Mostrar pestañas sobre Flash y Java">
-<!ENTITY objecttabs.accesskey "ñ">
-<!ENTITY collapse.label "Colapsar elementos bloqueados">
-<!ENTITY collapse.accesskey "b">
-<!ENTITY help.label "Ayuda">
-<!ENTITY help.accesskey "y">
-<!ENTITY gettingStarted.label "Primeros pasos">
-<!ENTITY gettingStarted.accesskey "P">
-<!ENTITY faq.label "Preguntas y Respuestas frecuentes">
-<!ENTITY faq.accesskey "f">
-<!ENTITY filterdoc.label "Escribiendo filtros de Adblock Plus">
-<!ENTITY filterdoc.accesskey "n">
-<!ENTITY about.label "Acerca de Adblock Plus">
-<!ENTITY about.accesskey "k">
-<!ENTITY description "El siguiente filtro determina que dirección debe ser bloqueada y cuales deben ser permitidas:">
-<!ENTITY filter.column "Regla de filtro">
-<!ENTITY filter.accesskey "f">
-<!ENTITY slow.column "Filtros lentos">
-<!ENTITY slow.accesskey "e">
-<!ENTITY enabled.column "Habilitado">
-<!ENTITY enabled.accesskey "o">
-<!ENTITY hitcount.column "Contador">
-<!ENTITY hitcount.accesskey "C">
-<!ENTITY lasthit.column "Ultima visita">
-<!ENTITY lasthit.accesskey "U">
-<!ENTITY context.edit.label "Editar filtro">
-<!ENTITY context.resethitcount.label "Restablecer contador de visitas del filtro">
-<!ENTITY context.synchsubscription.label "Actualizar suscripción ahora">
-<!ENTITY context.editsubscription.label "Editar suscripción">
-<!ENTITY context.moveup.label "Mover filtro arriba">
-<!ENTITY context.movedown.label "Mover filtro abajo">
-<!ENTITY context.movegroupup.label "Mover grupo arriba">
-<!ENTITY context.movegroupdown.label "Mover grupo abajo">
-<!ENTITY context.enable.label "Habilitar">
-<!ENTITY context.disable.label "Deshabilitar">
-<!ENTITY apply.label "Aplicar">
-<!ENTITY apply.accesskey "l">
-<!ENTITY fennec.subscription.label "Subscripción de filtros">
diff --git a/chrome/locale/et/meta.properties b/chrome/locale/et/meta.properties
deleted file mode 100644
index 70f18b6..0000000
--- a/chrome/locale/et/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Aivo Kuhlberg
-name=Adblock Plus
-description=Reklaamid on nüüd eilne päev!
-description.short=Sind häirivad reklaamid? Tunned muret jälgimise ees? Sind häirivad bännerid? Installi Adblock Plus, et saavutaksid kontrolli interneti üle ja et muuta seda, kuidas sa näed veebi.
-description.long=Adblock Plus võimaldab sul saavutada kontrolli interneti üle ja vaadata veebi just nii, nagu sa soovid. Sellele Firefoxi lisale on olemas üle 40 filtrite tellimuse kümnetes keeltes, mis häälestavad automaatselt selle tööd, eemaldades nii online reklaame kui ka blokeerides kõiki tuntuid pahavara domeene. Samuti võimaldab Adblock Plus sul luua enda jaoks sobivaid filtreid, kasutades mitmeid abivahendeid, nagu piltide kontekstimenüü valikud, Java ja Flash objektide blokeerimise sakk, ning blokeeritavate elementide loetelu, mille abil saab eemaldada skripte ja stiililehti.
diff --git a/chrome/locale/eu/.incomplete b/chrome/locale/eu/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/eu/about.dtd b/chrome/locale/eu/about.dtd
deleted file mode 100644
index cb3ab70..0000000
--- a/chrome/locale/eu/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Adblock Plusi buruz">
-<!ENTITY version.title "Bertsioa">
-<!ENTITY description "Adblock Plusek uzten dizu erabakitez zer ikusi nahi ez duzuna web-ean. Ez daukazu behera kargatu beharko iragarki gehiagorik, baldin eta ez nahi badituzu - esaiozu Adblock Plus-i!">
-<!ENTITY homepage.label "Adblock Plus-aren web orria:">
-<!ENTITY author.label "Egilea:">
-<!ENTITY contributors.label "Partaideak:">
diff --git a/chrome/locale/eu/global.properties b/chrome/locale/eu/global.properties
deleted file mode 100644
index d03e6ed..0000000
--- a/chrome/locale/eu/global.properties
+++ /dev/null
@@ -1,22 +0,0 @@
-no_blocking_suggestions=Ez daude elementu blokeagarririk uneko orrian
-whitelisted_page=Adblock Plus ezgaitu egin da uneko orrirako
-whitelist_description=Salbuespen arauak
-filterlist_description=Iragarki iragazakiak
-invalid_description=Baliogabeko iragazkiak
-elemhide_description=Elementuak ezkutatzeko arauak
-subscription_description=Iragazki harpidetza:
-subscription_source=Jatorria:
-subscription_status=Egoera:
-subscription_status_autodownload=Eguneratu automatikoki
-subscription_status_manualdownload=Eskuz eguneratua
-subscription_status_externaldownload=Kanpotik eguneratua (beste gehigarri batek)
-subscription_status_lastdownload=Azkeneko behera kargatzea:
-subscription_status_lastdownload_inprogress=Behera kargatzen...
-remove_subscription_warning=Ziur al zaude harpidetza hau ezabatu nahi duzula?
-import_filters_warning=Uneko iragazkiak ordeztu edo iragazki berriak zerrendaren bukaeran erantsi nahi dituzu?
-import_filters_title=Inportatu iragazkiak
-export_filters_title=Esportatu iragazkiak
-invalid_filters_file=Ez da Adblock Plus iragazki fitxategi baliogarria.
-filters_write_error=Errore bat egon da iragazkiak fitxategian idazterakoan. Ziurtatu fitxategia ez daukala idazketaren kontrako babesik edo beste programa batek hartuta ez daukala.
-clearall_warning=Ziur al zaude iragazki guztiak kendu nahi dituzula zerrendatik?
-type_label_object=objektua
diff --git a/chrome/locale/eu/meta.properties b/chrome/locale/eu/meta.properties
deleted file mode 100644
index 0f51942..0000000
--- a/chrome/locale/eu/meta.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-name=Adblock Plus
-description=Iragarkiak atzoko gauza dira!
diff --git a/chrome/locale/eu/overlay.dtd b/chrome/locale/eu/overlay.dtd
deleted file mode 100644
index 282d10a..0000000
--- a/chrome/locale/eu/overlay.dtd
+++ /dev/null
@@ -1,10 +0,0 @@
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY context.image.label "Adblock Irudia">
-<!ENTITY context.object.label "Adblock Objektu">
-<!ENTITY context.frame.label "Adblock Markoa">
-<!ENTITY sidebar.title "Elementu blokeagarriak uneko orrialdean">
-<!ENTITY settings.label "Lehentasunak">
-<!ENTITY opensidebar.label "Ireki elementu blokeagarriak">
-<!ENTITY closesidebar.label "Itxi elementu blokeagarriak">
-<!ENTITY whitelist.site.label "Ezgaitu ?1?">
-<!ENTITY whitelist.page.label "Ezgaitu orri honetan soilik">
diff --git a/chrome/locale/eu/settings.dtd b/chrome/locale/eu/settings.dtd
deleted file mode 100644
index 0777716..0000000
--- a/chrome/locale/eu/settings.dtd
+++ /dev/null
@@ -1,36 +0,0 @@
-<!ENTITY filters.label "Iragazkiak">
-<!ENTITY filters.accesskey "I">
-<!ENTITY add.label "Gehitu iragazkia">
-<!ENTITY import.label "Iragazkiak inportatu">
-<!ENTITY import.accesskey "n">
-<!ENTITY clearall.label "Kendu iragazki guztiak">
-<!ENTITY clearall.accesskey "K">
-<!ENTITY cut.label "Moztu">
-<!ENTITY cut.accesskey "M">
-<!ENTITY copy.label "Kopiatu">
-<!ENTITY copy.accesskey "K">
-<!ENTITY paste.label "Itsatsi">
-<!ENTITY paste.accesskey "I">
-<!ENTITY remove.label "Ezabatu">
-<!ENTITY remove.accesskey "E">
-<!ENTITY menu.find.label "Bilatu">
-<!ENTITY menu.find.accesskey "B">
-<!ENTITY menu.findagain.label "Berriro Bilatu">
-<!ENTITY options.label "Aukerak">
-<!ENTITY options.accesskey "A">
-<!ENTITY enable.label "Gaitu Adblock Plus">
-<!ENTITY showintoolbar.label "Erakutsi tresna-barran">
-<!ENTITY showintoolbar.accesskey "T">
-<!ENTITY showinstatusbar.label "Erakutsi egoera-barran">
-<!ENTITY objecttabs.label "Erakutsi fitxak Flash eta Javan">
-<!ENTITY collapse.label "Tolestu blokeatutako elementuak">
-<!ENTITY help.label "Laguntza">
-<!ENTITY help.accesskey "L">
-<!ENTITY enabled.column "Gaituta">
-<!ENTITY context.edit.label "Editatu iragazkia">
-<!ENTITY context.synchsubscription.label "Eguneratu harpidetza orain">
-<!ENTITY context.editsubscription.label "Editatu harpidetza">
-<!ENTITY context.moveup.label "Eraman gora">
-<!ENTITY context.movedown.label "Eraman behera">
-<!ENTITY context.movegroupup.label "Mugitu taldea gora">
-<!ENTITY context.movegroupdown.label "Mugitu taldea behera">
diff --git a/chrome/locale/eu/sidebar.dtd b/chrome/locale/eu/sidebar.dtd
deleted file mode 100644
index e7436fb..0000000
--- a/chrome/locale/eu/sidebar.dtd
+++ /dev/null
@@ -1,13 +0,0 @@
-<!ENTITY search.label "Bilatu:">
-<!ENTITY search.accesskey "B">
-<!ENTITY type.label "Mota">
-<!ENTITY address.label "Helbidea">
-<!ENTITY filter.label "Iragazki">
-<!ENTITY tooltip.address.label "Helbidea:">
-<!ENTITY tooltip.type.label "Mota:">
-<!ENTITY tooltip.type.blocked "(blokeatuta)">
-<!ENTITY context.block.label "Blokeatu elementu hau">
-<!ENTITY context.editfilter.label "Editatu martxan dabilen iragazkia">
-<!ENTITY context.open.label "Fitxa Berrian Ireki">
-<!ENTITY context.flash.label "Flash elementuaren ertzak">
-<!ENTITY context.copy.label "Elementuaren helbidea kopiatu">
diff --git a/chrome/locale/eu/subscriptionSelection.dtd b/chrome/locale/eu/subscriptionSelection.dtd
deleted file mode 100644
index 1d79fc3..0000000
--- a/chrome/locale/eu/subscriptionSelection.dtd
+++ /dev/null
@@ -1,3 +0,0 @@
-<!ENTITY dialog.title.edit "Editatu iragazki harpidetza">
-<!ENTITY title.label "Harpidetza titulua:">
-<!ENTITY autodownload.label "Eguneratu automatikoki">
diff --git a/chrome/locale/fa/meta.properties b/chrome/locale/fa/meta.properties
deleted file mode 100644
index 324e558..0000000
--- a/chrome/locale/fa/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Reza_NA, bahramm
-name=ÙÙ٠تبÙÛØº Ø´Ú©Ù
-description=تبÙÛØºØª Ù
تعÙÙ Ø¨Ù Ø¯ÛØ±Ùز Ø¨ÙØ¯!
-description.short=Ø¢ÛØ§ از دست تبÙÛØºØ§Øª Ø®Ø³ØªÙ Ø´Ø¯Ù Ø§ÛØ¯Ø با ÙØµØ¨ ÙÙ٠تبÙÛØº Ø´Ú©Ù ØªØ³ÙØ· گردش در Ø´Ø¨Ú©Ù Ø¬ÙØ§ÙÛ Ø±Ø§ ب٠دست Ø¨Ú¯ÛØ±Ûد ٠از ÙÙ
Ø§ÛØ´ Ø¬Ø¯ÛØ¯ Ø¢Ù ÙØ°Øª Ø¨Ø¨Ø±ÛØ¯\n\nÛÚ© ÙÛÙÙ
Ú©ÙØªØ§Ù از Ù¾ÛØ´ Ù
عرÙÛ Ø¯Ø± ÙØ´Ø§ÙÛ ÙÙÙ ÙØ§Ø¨Ù دست Ø±Ø³Û Ø§Ø³Øª: http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=ÙÙ٠تبÙÛØº شک٠اÙ
کا٠باز پس Ú¯ÛØ±Û ØªØ³ÙØ· بر Ø´Ø¨Ú©Ù Ø¬ÙØ§ÙÛ Ø±Ø§ ب٠شÙ
ا Ù
Û Ø¯ÙØ¯.اÛÙ Ø§ÙØ²ÙÙÙ ØªÙØ³Ø· Ø¨ÛØ´ از 40 اشتراک Ù¾Ø§ÙØ§Û٠در 10 ÙØ§ زبا٠Ù
ختÙÙ Ù¾Ø´ØªÛØ¨Ø§ÙÛ Ù
Û Ø´ÙØ¯ ک٠ب٠Ù
ÙØ¸Ùر Ù¾Ø§Ú©Ø³Ø§Ø²Û Ø´Ø¨Ú©Ù Ø§Ø² تبÙÛØºØ§Øª تÙÙÛØ¯ Ø´Ø¯Ù Ø§ÙØ¯. Ù ÙÙ
ÚÙÛ٠ب٠شÙ
ا اÙ
Ú©Ø§Ù Ø³ÙØ§Ø±Ø´Û Ø³Ø§Ø²Û Ù¾Ø§ÙØ§ÛÙ ÙØ§ را Ù
Û Ø¯ÙØ¯.
diff --git a/chrome/locale/fi/meta.properties b/chrome/locale/fi/meta.properties
deleted file mode 100644
index ce9b69b..0000000
--- a/chrome/locale/fi/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Joni Heinonen
-name=Adblock Plus
-description=Mainokset ovat menneisyyttä!
-description.short=Ãrsyttävätkö mainokset? Huolestutko jäljittämisestä? Asenna Adblock Plus saadaksesi Internetin ohjat takaisin ja muuttaaksesi tapaa, jolla näet verkon.\n\nLyhyt yleiskuvan antava video osoitteessa http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus antaa Internetin ohjat takaisin ja näet verkon sellaisena kuin haluat. Lisäosaa tukee yli neljäkymmentä kymmenillä kielillä olevaa tilattavaa suodatinlistaa, jotka automaattisesti asettavat asetukset eri tilanteisiin sopiviksi vaihdellen mainosten estämisestä haitallisia ohjelmia sisältävien sivustojen estämiseen. Adblock Plus sallii suodattimien muokkaamisen moninaisten hyödyllisten toimintojen avustuksella. Näihin lukeutuvat mm. kuvien estämisen valikkokohta, estokorvake Java -ja Flash-elementtien kanssa ja lista estettävistä komentosarjoista ja tyyliohjeista.
diff --git a/chrome/locale/fr/meta.properties b/chrome/locale/fr/meta.properties
deleted file mode 100644
index c0b1c18..0000000
--- a/chrome/locale/fr/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=jojaba, Dagobert_78, pirlouy
-name=Adblock Plus
-description=Les publicités, c'est du passé !
-description.short=Agacé par les publicités ? Préoccupé par le fait d'être pisté ? Installez Adblock Plus maintenant pour reprendre le contrôle de ce que vous voyez sur le Web.\n\nVidéo de démonstration : http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus vous permet de reprendre le contrôle d'Internet et de visualiser le Web de la manière que vous souhaitez. L'extension prend en charge plus de quarante abonnements à des listes de filtres en des dizaines de langues qui la configurent automatiquement afin, entre autres, de supprimer des publicités en ligne et de bloquer tous les domaines malveillants. Adblock Plus vous permet également de personnaliser vos filtres à l'aide d'une variété de fonctionnalités très utiles telles qu'une option contextuelle pour les images, un onglet permettant de bloquer les objets Flash et Java et une liste d'éléments filtrables pour supprimer des scripts et des feuilles de style.
diff --git a/chrome/locale/fy-NL/meta.properties b/chrome/locale/fy-NL/meta.properties
deleted file mode 100644
index 8df0354..0000000
--- a/chrome/locale/fy-NL/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Wim Benes
-name=Adblock Plus
-description=Fan no ôf gjin reklames mear!
-description.short=Argewaasje oer advertinsjes? Soargen oer achterfolgjen? Steurd troch banners? Ynstallearje Adblock Plus om kontrole te krijen oer it ynternet en hoe't jo ynternet besjogge.\n\nIn koarte fideo is te sjen op http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus jout jo de mooglikheid om de kontrole werom te krijen oer it ynternet en besjen sa as jo dat wolle. De tafoeging is stipe troch oer de fjirtich filterabonnemminten yn ferskate talen dy't it automatysk konfigurearje foar doeleinen fan it fuortsmiten fan online advertinsjes oant it blokkearkjen fan alle bekende malwaredomeinen. Adblock Plus out ek de mooglikheid om jo filters oan te passen mei de help fan in ferskaat oan brûkbere opsjes, ynklusyf in kontekst opsje foar ôfbyldings, in blokkearljepblêd foar Flash en Java objekten en in list mei blokkearbere items om scripts en stylesheets fuort te smiten.
diff --git a/chrome/locale/ga-IE/.incomplete b/chrome/locale/ga-IE/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/ga-IE/about.dtd b/chrome/locale/ga-IE/about.dtd
deleted file mode 100644
index feca2b7..0000000
--- a/chrome/locale/ga-IE/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Maidir le Adblock Plus">
-<!ENTITY version.title "Leagan">
-<!ENTITY description "Ligeann Adblock Plus duit cinn faoi cad nach teastaÃonn uait feiceáil ar an gréasán. Nà gá duit na fógraà agus meirgà a Ãosluchtú a thuilleadh, mura bhfuil siad de dhÃth uait - abair le Adblock Plus é!">
-<!ENTITY homepage.label "Clár cinn Adblock Plus:">
-<!ENTITY author.label "Ãdar:">
-<!ENTITY contributors.label "Rannpháirtithe:">
diff --git a/chrome/locale/ga-IE/global.properties b/chrome/locale/ga-IE/global.properties
deleted file mode 100644
index a26eeed..0000000
--- a/chrome/locale/ga-IE/global.properties
+++ /dev/null
@@ -1,10 +0,0 @@
-subscription_status_lastdownload_inprogress=Ag Ãosluchtú...
-subscription_status_lastdownload_unknown=N/A
-synchronize_ok=D'éirigh leis
-type_label_other=eile
-type_label_script=script
-type_label_image=Ãomhá
-type_label_object=nÃ
-type_label_subdocument=creatlach
-type_label_document=cáipéis
-type_label_elemhide=folaithe
diff --git a/chrome/locale/ga-IE/overlay.dtd b/chrome/locale/ga-IE/overlay.dtd
deleted file mode 100644
index 12c287b..0000000
--- a/chrome/locale/ga-IE/overlay.dtd
+++ /dev/null
@@ -1,11 +0,0 @@
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY context.image.label "Ãomhá Adblock">
-<!ENTITY context.frame.label "Creatlach Adblock">
-<!ENTITY settings.label "Sainroghanna">
-<!ENTITY settings.accesskey "F">
-<!ENTITY opensidebar.label "Oscail nithe ar féidir bac a chur orthu">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "Dún nithe ar féidir bac a chur orthu">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY objecttab.title "Cuir bac ar">
diff --git a/chrome/locale/ga-IE/settings.dtd b/chrome/locale/ga-IE/settings.dtd
deleted file mode 100644
index b7cb7aa..0000000
--- a/chrome/locale/ga-IE/settings.dtd
+++ /dev/null
@@ -1,49 +0,0 @@
-<!ENTITY dialog.title "Sainroghanna Adblock Plus">
-<!ENTITY filters.label "ScagairÃ">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.accesskey "S">
-<!ENTITY synchsubscriptions.accesskey "D">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.accesskey "X">
-<!ENTITY clearall.label "Bain gach scagaire">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "Déan eagar air">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "Gearr">
-<!ENTITY cut.accesskey "T">
-<!ENTITY copy.label "Macasamhlaigh">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "Greamaigh">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "Scrios">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "Aimsigh">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "Aimsigh ArÃs">
-<!ENTITY menu.findagain.accesskey "G">
-<!ENTITY options.label "Roghanna">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.accesskey "N">
-<!ENTITY showintoolbar.label "Taispeáin i sabh na n-uirlisÃ">
-<!ENTITY showintoolbar.accesskey "B">
-<!ENTITY showinstatusbar.label "Taispeáin sa treosabh">
-<!ENTITY showinstatusbar.accesskey "S">
-<!ENTITY objecttabs.label "Taispeáin cluaisÃnà ar Flash agus Java">
-<!ENTITY objecttabs.accesskey "T">
-<!ENTITY collapse.accesskey "L">
-<!ENTITY help.label "Cabhair">
-<!ENTITY help.accesskey "H">
-<!ENTITY faq.label "Ceisteanna Coitianta">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.accesskey "R">
-<!ENTITY about.label "Maidir le Adblock Plus">
-<!ENTITY about.accesskey "B">
-<!ENTITY enabled.column "Cumasaithe">
-<!ENTITY context.moveup.label "Bog suas">
-<!ENTITY context.movedown.label "Bog sÃos">
-<!ENTITY context.movegroupup.label "Bog an aicme suas">
-<!ENTITY context.movegroupdown.label "Bog an aicme sÃos">
-<!ENTITY apply.label "Cuir i bhfeidhm">
-<!ENTITY apply.accesskey "P">
diff --git a/chrome/locale/ga-IE/sidebar.dtd b/chrome/locale/ga-IE/sidebar.dtd
deleted file mode 100644
index ccfb29c..0000000
--- a/chrome/locale/ga-IE/sidebar.dtd
+++ /dev/null
@@ -1,22 +0,0 @@
-<!ENTITY detached.title "Adblock Plus: Nithe ar féidir bac a chur orthu (dÃscoirthe)">
-<!ENTITY detach.label "DÃscoir">
-<!ENTITY reattach.label "Athcheangail">
-<!ENTITY search.label "Cuardaigh:">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "Cineál">
-<!ENTITY address.label "Seoladh">
-<!ENTITY filter.label "Scagaire">
-<!ENTITY state.label "Stát">
-<!ENTITY noitems.label "NÃl nithe ar féidir bac a chur orthu ann">
-<!ENTITY whitelisted.label "Leathanach ar an réim slán">
-<!ENTITY tooltip.address.label "Seoladh:">
-<!ENTITY tooltip.type.label "Cineál:">
-<!ENTITY tooltip.type.blocked "(bactha)">
-<!ENTITY tooltip.type.whitelisted "(ar an réim slán)">
-<!ENTITY tooltip.filter.label "Scagaire i bhfeidhm:">
-<!ENTITY context.block.label "Cuir bac ar an nà seo">
-<!ENTITY context.editfilter.label "Scagaire eagarthóireachta i bhfeidhm">
-<!ENTITY context.whitelist.label "Cuir riail eisceachtúla leis an nà seo">
-<!ENTITY context.open.label "Oscail i gCluaisÃn Nua">
-<!ENTITY context.flash.label "Imill an nà Flash">
-<!ENTITY context.copy.label "Macasamhlaigh seoladh an nÃ">
diff --git a/chrome/locale/ga-IE/subscriptionSelection.dtd b/chrome/locale/ga-IE/subscriptionSelection.dtd
deleted file mode 100644
index adcd3dd..0000000
--- a/chrome/locale/ga-IE/subscriptionSelection.dtd
+++ /dev/null
@@ -1,9 +0,0 @@
-<!ENTITY dialog.title.edit "Déan eagarthóireacht ar sÃntiús an scagaire">
-<!ENTITY other.label "Cuir sÃntiús eile leis">
-<!ENTITY other.accesskey "T">
-<!ENTITY title.label "Teideal sÃntiús:">
-<!ENTITY title.accesskey "T">
-<!ENTITY location.label "Láthair réim an scagaire:">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.label "Uathnuashonraigh">
-<!ENTITY autodownload.accesskey "P">
diff --git a/chrome/locale/gl/meta.properties b/chrome/locale/gl/meta.properties
deleted file mode 100644
index 434d9e6..0000000
--- a/chrome/locale/gl/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Manuel Meixide
-name=Adblock Plus
-description=Os anuncios son cousa do pasado!
-description.short=Irritado polos anuncios e os banners? Preocupado polos rastreos? Instale Adblock Plus e recupere o control e cambie a súa visión da Internet.\n\nVexa un pequeno vÃdeo resumo en http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus permÃtelle recuperar o control de Internet e ver o web da maneira que desexa. O complemento apoiase en máis de corenta subscricións de filtros en decenas de idiomas, que automaticamente configúrano para propósitos que van desde a eliminación de publicidade en liña ao bloqueo de todos os dominios coñecidos de aplicacións maliciosas. Adblock Plus tamén permite personalizar os filtros, coa axuda dunha variedade de caracterÃsticas útiles, incluÃndo unha opción de contexto para as imaxes, unha pestana de bloqueo de obxectos Flash e Java, e unha lista de elementos a bloquear que eliminan guións executables (scripts) e follas de estilo.
diff --git a/chrome/locale/gl/sendReport.dtd b/chrome/locale/gl/sendReport.dtd
deleted file mode 100644
index 65e2441..0000000
--- a/chrome/locale/gl/sendReport.dtd
+++ /dev/null
@@ -1,13 +0,0 @@
-<!ENTITY wizard.title "Informador de problemas">
-<!ENTITY privacyPolicy.label "PolÃtica de privacidade">
-<!ENTITY dataCollector.heading "Benvinda ao Informador de problemas">
-<!ENTITY dataCollector.description "Agarde uns intres mentres Adblock Plus reúne os datos necesarios.">
-<!ENTITY typeSelector.heading "Seleccione o tipo de problema">
-<!ENTITY typeSelector.description "Esta xanela vai guiarlle a través dos pasos necesarios para a presentación dun informe de problema Adblock Plus. Primeiro, seleccione o tipo de problema que atopou nesta páxina:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus está bloqueado demais">
-<!ENTITY typeSelector.falsePositive.accesskey "m">
-<!ENTITY typeSelector.falsePositive.description "Seleccione esta opción se a páxina non ten contido importante, se amosa incorrectamente ou non funciona correctamente. Pode determinar se Adblock Plus é a causa do problema desactivándoo temporalmente.">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus non bloquea a publicidade">
-<!ENTITY typeSelector.falseNegative.accesskey "v">
-<!ENTITY typeSelector.falseNegative.description "Escolla esta opción se aparece un anuncio, a pesar de estar activado Adblock Plus.">
-<!ENTITY typeSelector.other.label "Outro problema">
diff --git a/chrome/locale/gl/sidebar.dtd b/chrome/locale/gl/sidebar.dtd
deleted file mode 100644
index a0d33a9..0000000
--- a/chrome/locale/gl/sidebar.dtd
+++ /dev/null
@@ -1,33 +0,0 @@
-<!ENTITY detached.title "Adblock Plus: Temas bloqueables (separados)">
-<!ENTITY detach.label "Separar">
-<!ENTITY reattach.label "Unir de novo">
-<!ENTITY search.label "Procurar:">
-<!ENTITY search.accesskey "P">
-<!ENTITY type.label "Tipo">
-<!ENTITY address.label "Enderezo">
-<!ENTITY filter.label "Filtro">
-<!ENTITY state.label "Estado">
-<!ENTITY size.label "Tamaño">
-<!ENTITY docDomain.label "Documento fonte">
-<!ENTITY noitems.label "Non hai temas bloqueables">
-<!ENTITY whitelisted.label "Páxina da Lista Branca">
-<!ENTITY tooltip.address.label "Enderezo:">
-<!ENTITY tooltip.type.label "Tipo">
-<!ENTITY tooltip.type.blocked "(bloqueado)">
-<!ENTITY tooltip.type.whitelisted "(engadido á lista branca)">
-<!ENTITY tooltip.size.label "Tamaño:">
-<!ENTITY tooltip.docDomain.label "Documento fonte:">
-<!ENTITY tooltip.filter.label "Filtro en vigor:">
-<!ENTITY tooltip.filter.disabled "(Desactivado)">
-<!ENTITY tooltip.filterSource.label "Fonte do filtro:">
-<!ENTITY context.block.label "Bloquear este tema">
-<!ENTITY context.editfilter.label "Editar o filtro en vigor">
-<!ENTITY context.whitelist.label "Engadir excepción para o tema">
-<!ENTITY context.disablefilter.label "Desactivar filtro ?1?">
-<!ENTITY context.enablefilter.label "Activar filtro ?1?">
-<!ENTITY context.disablefilteronsite.label "Desactivar este filtro en ?1?">
-<!ENTITY context.open.label "Abrir nun novo separador">
-<!ENTITY context.flash.label "Bordos do tema Flash">
-<!ENTITY context.copy.label "Copiar o enderezo do tema">
-<!ENTITY context.copyFilter.label "Copiar o filtro">
-<!ENTITY context.selectAll.label "Seleccionar todo">
diff --git a/chrome/locale/he/meta.properties b/chrome/locale/he/meta.properties
deleted file mode 100644
index d6a32c9..0000000
--- a/chrome/locale/he/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=catcat, SiiiE
-name=Adblock Plus
-description=×פרס×××ת ש××××ת ××¢×ר!
-description.short=×פרס×××ת ×צ××§×ת ××? ××××¨× ×××¢×§× ××ר××? ×××× ×¨×× ×פר××¢×× ××? ×תק×× × ×¢×ש×× ×ת Adblock Plus ××× ××§×× ×××¨× ×ת ×ש×××× ×××× ××¨× × ×××× ××©× ×ת ×ת ×××¨× ×©×× ××ª× ×¦××¤× ×רשת. \n\nסק×רת ××××× ×§×¦×¨× ××× ×××ת ×××× × ×Ö¾http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus ××פשרת ×× ××§×× ×××¨× ×ת ×ש×××× ×××× ××¨× × ××צפ×ת ×רשת ×××¨× ×רצ××× ××. ××ר××× ×ª×××ת ××××¢×× ××ר××¢×× ×רש××ת ××¡× × ×× ×תר×סר שפ×ת ש××××ר×ת ×××××××ת ×××ס×× ××× ×©× ×ס×××, ×פרס×××ת ××¢× ×תר×× ××××§××. Adblock Plus ×× ××פשר ×× ××ת××× ××¡× × ×× ×ש×× ××¢×רת ×××ר ××פ××× ×× ×©×××ש×××, ××××××× ×ª×¤×¨×× ×קשר ×ת××× ×ת, ×ש×× ×ת ××ס××ת פ××ש ××'×××× ×רש××ת פר×××× ××ס××× ××× ××ס×ר תסר×××× ×ס×× ×× ×ת.
diff --git a/chrome/locale/hr/composer.dtd b/chrome/locale/hr/composer.dtd
deleted file mode 100644
index 8d4233d..0000000
--- a/chrome/locale/hr/composer.dtd
+++ /dev/null
@@ -1,46 +0,0 @@
-<!ENTITY dialog.title "Dodaj Adblock Plus pravilo za filter">
-<!ENTITY accept.label "Dodaj filet">
-<!ENTITY advanced.label "Napredni pregled">
-<!ENTITY basic.label "osnovni pregled">
-<!ENTITY disabled.warning "Adblock Plus je trenutno onemoguÄen. Možete dodavati filtere ali se oni neÄe primjenjivati ako ne [link]omoguÄite Adblock Plus[/link].">
-<!ENTITY groupDisabled.warning "Grupa filtera "?1?" kojoj Äe ovaj filter biti dodan je trenutno onemoguÄena. Sveedno možete dodati filter ali on neÄe biti primjenjen ako ne [link]omoguÄite grupu filtera[/link].">
-<!ENTITY filter.label "Novi filter">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "Prikaži postojeÄe filtere">
-<!ENTITY preferences.accesskey "k">
-<!ENTITY type.filter.label "Blokirani filter">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Iznimka">
-<!ENTITY type.whitelist.accesskey "m">
-<!ENTITY pattern.label "Traži ponavljajuÄi uzorak">
-<!ENTITY pattern.explanation "uzorak može biti bilo koji dio adrese, asterisk (*) služi kao zamjena. Filter Äe biti primjenjen na adrese koje se poklapaju sa naznaÄenim uzorkom.">
-<!ENTITY regexp.warning "Uzorak koji ste unijeli biti Äe protumaÄen kao obiÄni izraz kojeg Adblock Plus ne može efikasno obraditi i može usporiti vaÅ¡e surfanje. Ako niste namjeravali koristiti obiÄni izra, dodajte asterisk (*) na kraju uzorka.">
-<!ENTITY shortpattern.warning "Uneseni uzorak je prekratak za optimizaciju i može usporiti vaÅ¡e surfanje. PreporuÄamo da odaberete duži niz za ovaj filter kako biste omoguÄili da Adblock Plus efikasnije obradi taj filter.">
-<!ENTITY custom.pattern.label "PrilagoÄeno:">
-<!ENTITY custom.pattern.accesskey "l">
-<!ENTITY anchors.label "Prihvati samo uzorak:">
-<!ENTITY anchor.start.label "na poÄetku adrese">
-<!ENTITY anchor.start.accesskey "p">
-<!ENTITY anchor.start.flexible.label "na poÄetku naziva domene">
-<!ENTITY anchor.start.flexible.accesskey "p">
-<!ENTITY anchor.end.label "na kraju adrese">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "Postavke">
-<!ENTITY domainRestriction.label "OgraniÄiti na domenu:">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "Koristite ovu opciju da odabir jedne ili viÅ¡e domena odvojenih okomitom linijom (|). Filter Äe biti primjenjen samo na odabrane domene. Tilda (~) prije naziva domene pokazuje da filter neÄe biti primjenjen na toj domeni.">
-<!ENTITY firstParty.label "Samo first-party">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "Samo third-party">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.label "ToÄan izraz">
-<!ENTITY matchCase.accesskey "z">
-<!ENTITY types.label "Primjeniti na tipove:">
-<!ENTITY selectAllTypes.label "Odabrati sve">
-<!ENTITY unselectAllTypes.label "Nijedan odabrati">
-<!ENTITY collapse.label "Sažeti blokirano:">
-<!ENTITY collapse.accesskey "S">
-<!ENTITY collapse.default.yes.label "Koristiti opÄenito (da)">
-<!ENTITY collapse.default.no.label "Koriatiti opÄenito (ne)">
-<!ENTITY collapse.yes.label "Da">
-<!ENTITY collapse.no.label "Ne">
diff --git a/chrome/locale/hr/global.properties b/chrome/locale/hr/global.properties
deleted file mode 100644
index d605919..0000000
--- a/chrome/locale/hr/global.properties
+++ /dev/null
@@ -1,69 +0,0 @@
-default_dialog_title=Adblock Plus
-action0_tooltip=Kliknite da bi se otvorio kontekstni izbornik, srednji klik za omoguÄavanje/onemoguÄavanje.
-action1_tooltip=Kliknite da bi se otvorile/zatvorile stavke koje se mogu blokirati, srednji klik za omoguÄavanje/onemoguÄavanje.
-action2_tooltip=Kliknite da bi se otvorila svojstva, srednji klik za omoguÄavanje/onemoguÄavanje.
-action3_tooltip=Kliknite da bi omoguÄili/onemoguÄili Adblock Plus.
-disabled_tooltip=Adblock Plus je onemoguÄen.
-active_tooltip=Adblock Plus je aktivan, ?1? pretplata na filtere i ?2? vlastitih filtera u uporabi.
-whitelisted_tooltip=Adblock Plus je aktivan, ali onemoguÄen za trenutnu stranicu.
-blocked_count_tooltip=?1? od ?2?
-blocked_count_addendum=dopušteni: ?1?, skriveni: ?2?)
-no_blocking_suggestions=Na trenutnoj stranici nema stavki koje se mogu blokirati
-whitelisted_page=Adblock Plus je onemoguÄen za trenutnu stranicu
-whitelist_description=Pravila izuzimanja
-filterlist_description=Filteri oglašavanja
-invalid_description=NevažeÄi filteri
-elemhide_description=Temeljna pravila skrivanja
-subscription_description=Pretplata na filter:
-subscription_wrong_version=Neki filteri u ovoj pretplati zahtijevaju Adblock Plus ?1? da bi ispravno radili!
-subscription_source=Izvor:
-subscription_status=Status:
-subscription_status_autodownload=Automatsko ažuriranje
-subscription_status_manualdownload=RuÄno ažuriranje
-subscription_status_externaldownload=Vanjsko ažuriranje (drugo proširenje)
-subscription_status_lastdownload=Zadnje preuzimanje:
-subscription_status_lastdownload_inprogress=Preuzimanje...
-subscription_status_lastdownload_unknown=N/A
-remove_subscription_warning=Želite li zbilja ukloniti ovu pretplatu?
-import_filters_wrong_version=Upozorenje: neki od filtera u ovom popisu zahtjevaju Adblock Plus ?1? da bi ispravno radili. Vjerojatno biste trebali nadograditi na zadnju inaÄicu Adblock Plus prije uvoza ovog popisa.
-import_filters_warning=Želite li zamijeniti Vaše trenutne filtere ili nove filtere želite dodati na kraj popisa?
-import_filters_title=Uvezi filtere
-export_filters_title=Izvezi filtere
-invalid_filters_file=NevažeÄa Adblock Plus datoteka filtera.
-filters_write_error=GreÅ¡ka prilikom zapisivanja filtera u datoteku. Provjerite da datoteka nije zaÅ¡tiÄena protiv pisanja ili u upotrebi od strane nekog drugog programa.
-clearall_warning=Želite li stvarno ukloniti sve filtere s popisa?
-resethitcounts_warning=Želite li doista ponovno postaviti brojanje pogodaka za sve filtere natrag na nulu? Ova operacija ne može biti opozvana!
-resethitcounts_selected_warning=Želite li doista ponovno postaviti brojanje pogodaka za odabrani filter natrag na nulu? Ova operacija ne može biti opozvana!
-filter_regexp_tooltip=Ovaj filter je ili regularan izraz ili je prekatak za optimizacju. Previše ovakvih filtera vam može usporiti surfanje.
-filter_elemhide_duplicate_id=Samo jedan ID elementa za skrivanje može biti odabran.
-filter_elemhide_nocriteria=Nijedan kriterij za prepoznavanje elementa koji Äe biti skriven
-subscription_notAdded_warning=Niste dodali pretplatu za filter. Bez pretplate za filter morate dodavati filtere za Adblock Plus ruÄno.
-subscription_notAdded_warning_addendum=Želite li nastaviti?
-subscription_invalid_location=Mjesto popisa filtera nije niti valjana web adresa niti naziv datoteke.
-synchronize_invalid_url=Neuspjeh, neispravna adresa
-synchronize_connection_error=Neuspjeh, neuspjelo preuzimanje
-synchronize_invalid_data=Neuspjeh, neispravan popis filtera
-synchronize_checksum_mismatch=NeuspjeÅ¡no, neusklaÄenost checksum-a.
-synchronize_ok=Uspjeh
-overwrite=Prepiši
-append=Dodaj na kraj
-new_filter_group_title=Novi filter
-type_label_other=drugi
-type_label_script=skripta
-type_label_image=slika
-type_label_stylesheet=stylesheet
-type_label_object=objekt
-type_label_subdocument=okvir
-type_label_document=dokument
-type_label_elemhide=skriveno
-type_label_xbl=XBL vezanje
-type_label_ping=ping linka
-type_label_xmlhttprequest=XML zahtjev
-type_label_object_subrequest=podzahtjev objekta
-type_label_dtd=DTD
-type_label_media=audio/video
-type_label_font=font
-fennec_status_enabled=Adblock Plus je omoguÄen.
-fennec_status_disabled=Adblock Plus je onemoguÄen.
-fennec_status_enabled_site=Adblock Plus je omoguÄen na ?1?.
-fennec_status_disabled_site=Adblock Plus je onemoguÄen na ?1?.
diff --git a/chrome/locale/hr/meta.properties b/chrome/locale/hr/meta.properties
deleted file mode 100644
index 2f177e3..0000000
--- a/chrome/locale/hr/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Hrvoje Majer, Leonid
-name=Adblock Plus
-description=Oglasi su prošlost!
-description.short=Oglasi vas živciraju? PraÄenje vas zabrinjava? Banneri vam dosaÄuju? instalirajte Adblock Plus sada i kontrolu nad internetom i promijenite naÄin na koji vidite web.\n\nKratak video pregled je dostupan na http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus vam omoguÄuje vraÄanje kontrole nad Internetom i pregledavanjem weba na naÄin koji vi želite. Dodatak je podržan sa preko 40 pretplata na filtere na desecima jezika koji ga automatski konfiguriraju za namjene od uklanjanja online oglasa do blokiraja svih poznatih Å¡tetnih stranica. Adblock Plus vam takoÄer omoguÄuje da sami stvorite vlastite filtere uz pomoÄ raznih korisnih moguÄnosti, ukljuÄujuÄi kontekstnu opciju za slike, karticu za blokiranje Flash i Java objekata i liste objekata koje možete blokirati kako biste uklonili skripte i stilove.
diff --git a/chrome/locale/hr/overlay.dtd b/chrome/locale/hr/overlay.dtd
deleted file mode 100644
index cb08fac..0000000
--- a/chrome/locale/hr/overlay.dtd
+++ /dev/null
@@ -1,23 +0,0 @@
-<!ENTITY status.tooltip "Status:">
-<!ENTITY blocked.tooltip "Blokirane stavke na ovoj stranici:">
-<!ENTITY filters.tooltip "Najaktivniji filteri:">
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY menuitem.accesskey "b">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: Stavke koje se mogu blokirati">
-<!ENTITY context.image.label "Blokiraj sliku s Adblock">
-<!ENTITY context.object.label "Blokiraj objekt s Adblock">
-<!ENTITY context.frame.label "Blokiraj okvir s Adblock">
-<!ENTITY context.media.label "Adblock Plus: Blokirati audio/video">
-<!ENTITY context.removeWhitelist.label "Adblock Plus: Ponovno omoguÄiti na ovoj stranici">
-<!ENTITY sidebar.title "Stavke koje se mogu blokirati na trenutnoj stranici">
-<!ENTITY settings.label "Postavke">
-<!ENTITY settings.accesskey "t">
-<!ENTITY opensidebar.label "Otvori stavke koje se mogu blokirati">
-<!ENTITY opensidebar.accesskey "b">
-<!ENTITY closesidebar.label "Zatvori stavke koje se mogu blokirati">
-<!ENTITY closesidebar.accesskey "b">
-<!ENTITY whitelist.site.label "OnemoguÄi na ?1?">
-<!ENTITY whitelist.page.label "OnemoguÄi samo na ovoj stranici">
-<!ENTITY objecttab.title "Blokiraj">
-<!ENTITY objecttab.tooltip "Kliknite ovdje da biste ovaj objekt blokirali s Adblock Plus">
diff --git a/chrome/locale/hr/settings.dtd b/chrome/locale/hr/settings.dtd
deleted file mode 100644
index e28ab6a..0000000
--- a/chrome/locale/hr/settings.dtd
+++ /dev/null
@@ -1,88 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus Postavke">
-<!ENTITY filters.label "Filteri">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Dodaj filter">
-<!ENTITY add.accesskey "j">
-<!ENTITY addsubscription.label "Dodaj pretplatu na filter">
-<!ENTITY addsubscription.accesskey "D">
-<!ENTITY synchsubscriptions.label "Ažuriraj sve pretplate">
-<!ENTITY synchsubscriptions.accesskey "ž">
-<!ENTITY import.label "Uvezi filtere">
-<!ENTITY import.accesskey "v">
-<!ENTITY export.label "Izvezi filtere">
-<!ENTITY export.accesskey "z">
-<!ENTITY clearall.label "Ukloni sve filtere">
-<!ENTITY clearall.accesskey "k">
-<!ENTITY resethitcounts.label "Vrati izvornu statistiku pogodaka">
-<!ENTITY resethitcounts.accesskey "r">
-<!ENTITY edit.label "Uredi">
-<!ENTITY edit.accesskey "r">
-<!ENTITY cut.label "Izreži">
-<!ENTITY cut.accesskey "z">
-<!ENTITY copy.label "Kopiraj">
-<!ENTITY copy.accesskey "o">
-<!ENTITY paste.label "Zalijepi">
-<!ENTITY paste.accesskey "l">
-<!ENTITY remove.label "Obriši">
-<!ENTITY remove.accesskey "b">
-<!ENTITY menu.find.label "Traži">
-<!ENTITY menu.find.accesskey "T">
-<!ENTITY menu.findagain.label "Ponovno traži">
-<!ENTITY menu.findagain.accesskey "n">
-<!ENTITY view.label "Pogledati">
-<!ENTITY view.accesskey "g">
-<!ENTITY sort.label "Posložiti po">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "Neposloženo">
-<!ENTITY sort.none.accesskey "N">
-<!ENTITY sort.ascending.label "A > Z red slaganja">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Z > A red slaganja">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Opcije">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "OmoguÄi Adblock Plus">
-<!ENTITY enable.accesskey "m">
-<!ENTITY showintoolbar.label "Prikaži u alatnoj traci">
-<!ENTITY showintoolbar.accesskey "a">
-<!ENTITY showinstatusbar.label "Prikaži u statusnoj traci">
-<!ENTITY showinstatusbar.accesskey "s">
-<!ENTITY objecttabs.label "Prikaži kartice s Flashom i Javom">
-<!ENTITY objecttabs.accesskey "k">
-<!ENTITY collapse.label "Sažmi blokirane elemente">
-<!ENTITY collapse.accesskey "e">
-<!ENTITY help.label "PomoÄ">
-<!ENTITY help.accesskey "Ä">
-<!ENTITY gettingStarted.label "Kako poÄeti">
-<!ENTITY gettingStarted.accesskey "p">
-<!ENTITY faq.label "Äesto postavljana pitanja">
-<!ENTITY faq.accesskey "t">
-<!ENTITY filterdoc.label "Pisanje Adblock Plus filtera">
-<!ENTITY filterdoc.accesskey "i">
-<!ENTITY about.label "O Adblock Plus">
-<!ENTITY about.accesskey "O">
-<!ENTITY description "Dodajte adrese koje želite blokirati, za prijedloge provjerite padajuÄi popis.
-Možete koristiti * kao joker da bi kreirali joÅ¡ opÄenitije filtere. Napredni korisnici mogu koristiti regularne izraze kao /banner\d+\.gif$/.">
-<!ENTITY filter.column "Pravilo filtera">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "Spori filteri">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "OmoguÄeno">
-<!ENTITY enabled.accesskey "m">
-<!ENTITY hitcount.column "Pogoci">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "Posljednji pogodak">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "Uredi filter">
-<!ENTITY context.resethitcount.label "Vrati izvornu statistiku pogodaka za filter">
-<!ENTITY context.synchsubscription.label "Ažuriraj pretplatu sada">
-<!ENTITY context.editsubscription.label "Uredi pretplatu">
-<!ENTITY context.moveup.label "Pomakni prema gore">
-<!ENTITY context.movedown.label "Pomakni prema dolje">
-<!ENTITY context.movegroupup.label "Pomakni grupu prema gore">
-<!ENTITY context.movegroupdown.label "Pomakni grupu prema dolje">
-<!ENTITY context.enable.label "OmoguÄiti">
-<!ENTITY context.disable.label "OnemoguÄiti">
-<!ENTITY apply.label "Primijeni">
-<!ENTITY apply.accesskey "P">
-<!ENTITY fennec.subscription.label "Pretplate na filtere">
diff --git a/chrome/locale/hr/sidebar.dtd b/chrome/locale/hr/sidebar.dtd
deleted file mode 100644
index 8e2ba02..0000000
--- a/chrome/locale/hr/sidebar.dtd
+++ /dev/null
@@ -1,32 +0,0 @@
-<!ENTITY detached.title "Adblock Plus: Stavke koje se mogu blokirati (odvojene)">
-<!ENTITY detach.label "Odvoji">
-<!ENTITY reattach.label "Ponovno spoji">
-<!ENTITY search.label "Traži:">
-<!ENTITY search.accesskey "T">
-<!ENTITY type.label "Tip">
-<!ENTITY address.label "Adresa">
-<!ENTITY filter.label "Filter">
-<!ENTITY state.label "Status">
-<!ENTITY size.label "VeliÄina">
-<!ENTITY docDomain.label "Izvor dokumenta">
-<!ENTITY noitems.label "Nema stavki koje se mogu blokirati">
-<!ENTITY whitelisted.label "Stranica koja je na dopuštenom popisu">
-<!ENTITY tooltip.address.label "Adresa:">
-<!ENTITY tooltip.type.label "Tip:">
-<!ENTITY tooltip.type.blocked "(blokiran)">
-<!ENTITY tooltip.type.whitelisted "(na dozvoljenom popisu)">
-<!ENTITY tooltip.size.label "VeliÄina:">
-<!ENTITY tooltip.docDomain.label "Izvor dokumenta:">
-<!ENTITY tooltip.filter.label "Filter u upotrebi:">
-<!ENTITY tooltip.filterSource.label "Izvor filtera:">
-<!ENTITY context.block.label "Blokiraj ovu stavku">
-<!ENTITY context.editfilter.label "Uredi filter u upotrebi">
-<!ENTITY context.whitelist.label "Dodaj pravilo izuzimanja za stavku">
-<!ENTITY context.disablefilter.label "OnemoguÄiti filter ?1?">
-<!ENTITY context.enablefilter.label "Ponovno omoguÄiti filter ?1?">
-<!ENTITY context.disablefilteronsite.label "OnemoguÄiti ovaj filter na ?1?">
-<!ENTITY context.open.label "Otvori u novoj kartici">
-<!ENTITY context.flash.label "Osvijetli granice stavke">
-<!ENTITY context.copy.label "Kopiraj adresu stavke">
-<!ENTITY context.copyFilter.label "Kopirati filter">
-<!ENTITY context.selectAll.label "Odabrati sve">
diff --git a/chrome/locale/hsb-DE/meta.properties b/chrome/locale/hsb-DE/meta.properties
deleted file mode 100644
index 21cb10d..0000000
--- a/chrome/locale/hsb-DE/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Milupo
-name=Adblock Plus
-description=Reklama bÄ wÄera!
-description.short=HnÄwaÄe so na reklamu, pÅesÄÄhanje a wabjenske chorhoje? InstalujÄe nÄtko Adblock Plus, zo byÅ¡Äe kontrolu wo interneÄe wróÄo dobyÅ a zmÄÅÄe waÅ¡nje, kak web widźiÄe.\n\nKrótke widejo steji na http://www.youtube.com/watch?v=oNvb2SjVjjI k dispoziciji
-description.long=Adblock Plus zmóžnja wam kontrolu wo interneÄe wróÄo dobyÄ a web tak widźeÄ, kaž to chceÄe. PÅidatk podpÄruje so pÅez wjace haÄ Å¡tyrceÄi filtrowych abonementow w dźesatkich rÄÄach, kotrež ju awtomatisce za wÅ¡elake zamÄry konfiguruja, zapoÄinajo z wotstronjenjom internetneje reklamy haÄ k blokowanju wÅ¡Äch znatych zÅowólnych domenow. Adblock Plus wam tež dowoluje waÅ¡e filtry z pomocu wulkeje liÄby wužitnych funkcijow pÅimÄriÄ, inkluziwnje kontekstowu opciju za wobrazy, blokowanski rajtark za objekty Flash a Java a lisÄinu blokujomnych elementow za wotstronjenje skriptow a stilowych pÅedÅohow.
diff --git a/chrome/locale/hu/meta.properties b/chrome/locale/hu/meta.properties
deleted file mode 100644
index a4c39b9..0000000
--- a/chrome/locale/hu/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Mikes Kaszmán István
-name=Adblock Plus
-description=A reklám a múlté!
-description.short=A weboldalon sok reklám és más, a weboldalt betöltését lassÃtó elem? TelepÃtse az Adblock Plus kiterjesztést és gyorsÃtsa a weboldalak betöltését.\n\nGyors áttekintést a http://www.youtube.com/watch?v=oNvb2SjVjjI weboldalon találhat
-description.long=Az Adblock Plus lehetÅvé teszi a weboldalakat az Ãn elképzelései szerint megtekinteni. Ez a kiegészÃtÅ számos nyelven több mint negyven szűrÅ segÃtségével automatikusan szűri az ismert weboldalak tartalmán levÅ reklámokat. Az Adblock Plus továbbá lehetÅvé teszi az Ãn számára a telepÃtett szűrÅk testreszabását számos beállÃtási lehetÅség felhasználásával: képek helyi menüjébÅl elérhetÅ opciók, Flash és Java objektumok blokkolása. Felhasználható a blokkolható elemek listája, amely szkriptek és stÃluslapok eltávolÃtásában nyújt kiváló segÃtséget.
diff --git a/chrome/locale/hy-AM/meta.properties b/chrome/locale/hy-AM/meta.properties
deleted file mode 100644
index 7609c17..0000000
--- a/chrome/locale/hy-AM/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ô·Õ¤Õ¸ÖÕ¡ÖÕ¤ Ô²Õ¡Õ¢Õ¡ÕµÕ¡Õ¶ (edo248)
-name=Adblock Plus
-description=Ô³Õ¸Õ¾Õ¡Õ¦Õ¤Õ¶Õ¥ÖÕ¨ Õ¥ÖÕ¥Õ¯ Õ§Õ«Õ¶!
-description.short=ÕÕ¸Õ£Õ¶Õ¥ÕÕ¬ Õ¥Ö Õ£Õ¸Õ¾Õ¡Õ¦Õ¤Õ¶Õ¥ÖÕ«Ö: Ô±Õ¶Õ°Õ¡Õ¶Õ£Õ½Õ¿Õ¡ÖÕ¶Õ¸ÕÖÕ´ Õ§, Õ¸Ö Õ±Õ¥Ö Õ¯Õ¬Õ«Õ¯Õ¥ÖÕ«Õ¶ Õ°Õ¥Õ¿ÖÕ¸ÖÕ´ Õ¥Õ¶: Ô¶Õ¦Õ¾ÖÕ¶Õ¸ÕÖÕ´ Õ¥Õ¶ Õ¢Õ¡Õ¶Õ¶Õ¥ÖÕ¶Õ¥ÖÕ¨: ÕÕ¥Õ²Õ¡Õ¤ÖÕ¥Ö Adblock Plus-Õ¨, Õ²Õ¥Õ¯Õ¡Õ¾Õ¡ÖÕ¥Ö Õ«Õ¶Õ¿Õ¥ÖÕ¶Õ¥Õ¿Õ« Ö
Õ£Õ¿Õ¡Õ£Õ¸ÖÕ®Õ¸ÖÕ´Õ¨ Ö ÖÕ¸ÕÕ¥Ö Õ¯Õ¡ÕµÖÕ¥ÖÕ« Õ¿Õ¥Õ½ÖÕ¨.\n\nÔ¿Õ¡ÖÕ³ Õ¾Õ«Õ¤Õ¥Õ¸Õ¶Õ¯Õ¡ÖÕ¡Õ£Õ«ÖÕ¨` http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus-Õ¨ Õ°Õ¶Õ¡ÖÕ¡Õ¾Õ¸ÖÕ¸ÖÕ©ÕµÕ¸ÖÕ¶ Õ§ Õ¿Õ¡Õ¬Õ«Õ½ Õ²Õ¥Õ¯Õ¡Õ¾Õ¡ÖÕ¥Õ¬ Õ±Õ¥Ö Õ«Õ¿Õ¥ÖÕ¶Õ¥Õ¿Õ«Ö Ö
Õ£Õ¿Õ¾Õ¥Õ¬Õ¨ Ö Õ¿Õ¥Õ½Õ¶Õ¥Õ¬ Õ¡ÕµÕ¶ ÖÕ¶Õ¡ÖÕ¨ Õ¸ÖÕ¨ Ô´ÕÕÕ Õ¸ÖÕ¦Õ¸ÖÕ´ Õ¥Ö. Ô±ÕµÕ½ add-on-Õ¨ Õ¡Õ»Õ¡Õ¯ÖÕ¾Õ¸ÖÕ´ Õ§ ÖÕ¡Õ¼Õ¡Õ½Õ¸ÖÕ¶Õ«Ö Õ¡Õ¾Õ¥Õ¬ ÖÕ«Õ¬Õ¿ÖÕ¥ÖÕ« Õ¢Õ¡ÕªÕ¡Õ¶Õ¡ÖÕ¤Õ¸Õ£ÖÕ¸ÖÕ©ÕµÕ¸ÖÕ¶Õ¶Õ¥ÖÕ¸Õ¾s Õ¢Õ¡Õ¦Õ´Õ¡Õ©Õ«Õ¾ Õ¬Õ¥Õ¦Õ¸ÖÕ¶Õ¥ÖÕ¸Õ¾, Õ¸ÖÕ¸Õ¶Ö Õ©Õ¸ÖÕµÕ¬ Õ¥Õ¶ Õ¿Õ¡Õ¬Õ«Õ½ Õ¡ÖÕ£Õ¥Õ¬Õ¥Õ¬ Õ£Õ¸Õ¾Õ¡Õ¦Õ¤Õ¶Õ¥ÖÕ« Õ¢Õ¥Õ¼Õ¶Õ¸ÖÕ´Õ¶ Õ¸Ö ÖÕ¸ÖÖÕ¡Õ¤ÖÕ¸ÖÕ´Õ¨, Õ«Õ¶Õ¹ÕºÕ¥Õ½ Õ¶Õ¡Ö ÕºÕ¡Õ·Õ¿ÕºÕ¡Õ¶Õ¸ÖÕ´ Õ¥Õ¶ Õ¢Õ¡Õ¦Õ´Õ¡Õ©Õ«Õ¾ Õ°Õ¡ÕµÕ¿Õ¶Õ« Õ¾Õ¶Õ¡Õ½Õ¡Õ¯Õ¡Ö Õ¯Õ¡ÕµÖÕ¥ÖÕ«Ö: Adblock Plus-Õ¨ Õ¶Õ¡Ö Õ©Õ¸ÖÕµÕ¬ Õ§ Õ¿Õ¡Õ¬Õ«Õ½ ÕÕ´Õ¢Õ¡Õ£ÖÕ¥Õ¬ ÖÕ«Õ¬Õ¿ÖÕ¥ÖÕ¨ Õ°Õ¡ÖÕ´Õ¡Ö Õ°Õ¶Õ¡ÖÕ¡Õ¾Õ¸ÖÕ¸ÖÕ©ÕµÕ¸ÖÕ¶Õ¶Õ¥ÖÕ¸Õ¾, Õ¡Õ¾Õ¿Õ¸Õ´Õ¡Õ¿ Õ¡Õ¼Õ¡Õ»Õ¡ÖÕ¯Õ¥Õ¬Õ¸Õ¾ Õ´Õ¥Õ¶ÕµÕ¸Ö ÖÕ«Õ¬Õ¿ÖÕ¥Õ¬Õ¸Ö Õ°Õ¡Õ´Õ¡Ö Õ¶Õ¯Õ¡Ö, Flash Õ¯Õ¡Õ´ Java, Õ¶Õ¡Ö Õ¿ÖÕ¡Õ´Õ¡Õ¤ÖÕ¥Õ¬Õ¸Õ¾ Õ¡Õ´Õ¶Õ¥ Õ§Õ»Õ« Õ¢Õ¸Õ¬Õ¸Ö ÖÕ«Õ¬Õ¿ÖÕ¾Õ¾Õ¸Õ² Õ¿Õ¡ÖÖÕ¥ÖÕ« ÖÕ¸ÖÖÕ¡Õ¯:
diff --git a/chrome/locale/id/.incomplete b/chrome/locale/id/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/id/about.dtd b/chrome/locale/id/about.dtd
deleted file mode 100644
index 64b3f6e..0000000
--- a/chrome/locale/id/about.dtd
+++ /dev/null
@@ -1,10 +0,0 @@
-<!ENTITY dialog.title "Tentang Adblock Plus">
-<!ENTITY version.title "Versi">
-<!ENTITY description "
- Adblock Plus membolehkan Anda untuk memilih apa yang tidak harus dilihat pada situs.
- Anda tidak perlu mendownload semua iklan dan banner, Jika Anda tidak menginginkannya
- - katakan Adblock Plus!
-">
-<!ENTITY homepage.label "Situs Adblock Plus:">
-<!ENTITY author.label "Pembuat:">
-<!ENTITY contributors.label "Para Kontributor:">
diff --git a/chrome/locale/id/composer.dtd b/chrome/locale/id/composer.dtd
deleted file mode 100644
index e9b0282..0000000
--- a/chrome/locale/id/composer.dtd
+++ /dev/null
@@ -1,43 +0,0 @@
-<!ENTITY dialog.title "Tambah aturan filter Adblock Plus">
-<!ENTITY accept.label "Tambah filter">
-<!ENTITY advanced.label "View lanjutan">
-<!ENTITY basic.label "View dasar">
-<!ENTITY disabled.warning "Adblock Plus sedang dimatikan. Anda tetap bisa menambahkan filter tapi tidak akan diaplikasikan kecuali Anda [link]Hidupkan Adblock Plus[/link].">
-<!ENTITY filter.label "Filter baru:">
-<!ENTITY filter.accesskey "F">
-<!ENTITY preferences.label "Tunjukkan filter yang ada...">
-<!ENTITY preferences.accesskey "k">
-<!ENTITY type.filter.label "Pemblokiran Filter">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Aturan pengecualian">
-<!ENTITY type.whitelist.accesskey "g">
-<!ENTITY pattern.label "Lihat pola">
-<!ENTITY pattern.explanation "Pola bisa diartikan untuk semua bagian dari alamat, simbol * sebagai wildcard. Filter hanya akan diaplikasikan ke alamat yang cocok dengan pola.">
-<!ENTITY regexp.warning "Pola yang Anda masukkan akan diartikan sebagai ekspresi biasa. Banyak ekspresi biasa bisa melambatkan browser Anda. Jika Anda tidak bermmaksud untuk memakai ekspresi biasa, tambahkan tanda * pada akhir pola.">
-<!ENTITY shortpattern.warning "Pola yang anda masukkan terlalu kecil untuk dioptimalkan, terlalu banyak pola bisa melambatkan browser Anda. Disarankan anda memilih string yang lebih panjang untuk filter ini.">
-<!ENTITY custom.pattern.label "Aturan Sendiri:">
-<!ENTITY custom.pattern.accesskey "t">
-<!ENTITY anchors.label "Pola yang disetujui saja:">
-<!ENTITY anchor.start.label "pada awal alamat">
-<!ENTITY anchor.start.accesskey "w">
-<!ENTITY anchor.end.label "pada akhir alamat">
-<!ENTITY anchor.end.accesskey "D">
-<!ENTITY options.label "Opsi">
-<!ENTITY domainRestriction.label "Terlarang ke domain:">
-<!ENTITY domainRestriction.accesskey "e">
-<!ENTITY domainRestriction.help "Spesifikasikan satu atau lebih domain yang dipisahkan oleh simbol "|", kemudian filter hanya akan dipakai padadomain tersebut. Simbol "~" sebelum nama domain berarti filter tidak seharusnya dipakai pada domain itu.">
-<!ENTITY firstParty.label "Pihak pertama saja">
-<!ENTITY firstParty.accesskey "R">
-<!ENTITY thirdParty.label "Pihak ketiga saja">
-<!ENTITY thirdParty.accesskey "j">
-<!ENTITY matchCase.label "Case tepat">
-<!ENTITY matchCase.accesskey "p">
-<!ENTITY types.label "Dipakai untuk tipe:">
-<!ENTITY selectAllTypes.label "Pilih semua">
-<!ENTITY unselectAllTypes.label "Jangan pilih apapun">
-<!ENTITY collapse.label "Gabungkan yang diblok:">
-<!ENTITY collapse.accesskey "L">
-<!ENTITY collapse.default.yes.label "Gunakan biasa (ya)">
-<!ENTITY collapse.default.no.label "Gunakan biasa (tidak)">
-<!ENTITY collapse.yes.label "Ya">
-<!ENTITY collapse.no.label "Tidak">
diff --git a/chrome/locale/id/global.properties b/chrome/locale/id/global.properties
deleted file mode 100644
index 0b69fd2..0000000
--- a/chrome/locale/id/global.properties
+++ /dev/null
@@ -1,59 +0,0 @@
-action0_tooltip=Klik untuk mengambil Menu Konteks, Klik Tengah untuk Hidupkan/Matikan.
-action1_tooltip=Klik untuk membuka/menutup item yang diblok, Klik Tengah untuk Hidupkan/Matikan.
-action2_tooltip=Klik untuk membuka preferensi, Klik Tengah untuk Hidupkan/Matikan.
-action3_tooltip=Klik untuk hidupkan/matikan Adblock Plus.
-disabled_tooltip=Adblock Plus telah dimatikan.
-whitelisted_tooltip=Adblock Plus telah aktif, tapi dimatikan pada beberapa halaman.
-blocked_count_tooltip=?1? diblok ?2?
-no_blocking_suggestions=Tidak ada item yang diblok pada halaman ini
-whitelisted_page=Adblock Plus telah dimatikan untuk halaman ini
-whitelist_description=Aturan Pengecualian
-filterlist_description=Aturan Iklan yang Diblok
-invalid_description=Aturan untuk Tak Valid
-elemhide_description=Aturan Penyembunyian Elemen
-subscription_description=Skrip filter:
-subscription_wrong_version=Beberapa filter pada skrip membutuhkan Adblock Plus ?1? untuk bekerja normal!
-subscription_source=Sumber:
-subscription_status=Status:
-subscription_status_autodownload=Diupdate secara otomatis
-subscription_status_manualdownload=Diupdate secara manual
-subscription_status_externaldownload=Diupdate secara eksternal (ekstensi lainnya)
-subscription_status_lastdownload=Download terakhir:
-subscription_status_lastdownload_inprogress=Mendownload...
-subscription_status_lastdownload_unknown=Tidak Ada
-remove_subscription_warning=Apakah Anda ingin membuang skrip ini?
-import_filters_wrong_version=Peringatan: beberapa filter di daftar ini membutuhkan Adblock Plus ?1? untuk bekerja normal. Anda mungkin seharusnya mengupgrade ke Adblock Plus terbaru sebelum mengimpor list ini.
-import_filters_warning=Anda ingin mengganti filter Anda atau menambahkan filter baru di akhir daftar?
-import_filters_title=Impor filter
-export_filters_title=Ekspor filter
-invalid_filters_file=Bukan file filter Adblock Plus yang valid.
-filters_write_error=Ada error dalam menulis filter ke file. Pastikan file tidak terproteksi atau dipakai oleh program lain.
-clearall_warning=Anda benar-benar ingin untuk membuang semua filter dari daftar?
-resethitcounts_warning=Anda benar-benar ingin untuk menyetel ulang semua filter ke nol? Operasi ini tidak bisa selesai!
-resethitcounts_selected_warning=Anda benar-benar ingin untuk menyetel ulang filter terpilih ke nol? Operasi ini tidak bisa selesai!
-filter_regexp_tooltip=Filter ini berekspresi biasa atau terlalu pendek untuk dioptimalkan. Terlalu banyak filter bisa melambatkan browser Anda.
-filter_elemhide_duplicate_id=Hanya satu identitas elemen yang ingin disembunyikan yang bisa dispesifikasi
-filter_elemhide_nocriteria=Kriteria tidak spesifik untuk mengenali elemen yang ingin disembunyikan
-subscription_invalid_location=Lokasi daftar filter bukan URL valid ataupun nama file valid.
-synchronize_invalid_url=Gagal, bukan alamat valid
-synchronize_connection_error=Download gagal
-synchronize_invalid_data=Gagal, bukan daftar filter yang valid
-synchronize_checksum_mismatch=Gagal, checksum tidak cocok
-synchronize_ok=Sukses
-overwrite=Meniban
-append=Menambahkan
-new_filter_group_title=Filter baru
-type_label_other=lainnya
-type_label_script=skrip
-type_label_image=gambar
-type_label_stylesheet=format stylesheet
-type_label_object=obyek
-type_label_subdocument=subdokumen
-type_label_document=dokumen
-type_label_elemhide=tersembunyi
-type_label_xbl=format XBL
-type_label_ping=alamat ping
-type_label_xmlhttprequest=permintaan XML
-type_label_object_subrequest=obyek subpermintaan
-type_label_dtd=DTD
-type_label_media=audio atau video
diff --git a/chrome/locale/id/meta.properties b/chrome/locale/id/meta.properties
deleted file mode 100644
index 35d104b..0000000
--- a/chrome/locale/id/meta.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-name=Adblock Plus
-description=Iklan telah berlalu!
diff --git a/chrome/locale/id/overlay.dtd b/chrome/locale/id/overlay.dtd
deleted file mode 100644
index 32b3b0d..0000000
--- a/chrome/locale/id/overlay.dtd
+++ /dev/null
@@ -1,21 +0,0 @@
-<!ENTITY status.tooltip "Status:">
-<!ENTITY blocked.tooltip "Item yang diblok pada halaman ini:">
-<!ENTITY filters.tooltip "Filter yang paling aktif:">
-<!ENTITY menuitem.label "Preferensi Adblock Plus">
-<!ENTITY menuitem.accesskey "r">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: Item yang Diblok">
-<!ENTITY context.image.label "Gambar Adblock">
-<!ENTITY context.object.label "Obyek Adblock">
-<!ENTITY context.frame.label "Bingkai Adblock">
-<!ENTITY sidebar.title "Item yang bisa diblok pada halaman ini">
-<!ENTITY settings.label "Preferensi">
-<!ENTITY settings.accesskey "F">
-<!ENTITY opensidebar.label "Buka item yang bisa diblok">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "Tutup item yang bisa diblok">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY whitelist.site.label "Matikan pada ?1?">
-<!ENTITY whitelist.page.label "Matikan pada halaman ini saja">
-<!ENTITY objecttab.title "Blok">
-<!ENTITY objecttab.tooltip "Klik ini untuk memblok obyek ini dengan Adblock Plus">
diff --git a/chrome/locale/id/settings.dtd b/chrome/locale/id/settings.dtd
deleted file mode 100644
index 8f94006..0000000
--- a/chrome/locale/id/settings.dtd
+++ /dev/null
@@ -1,84 +0,0 @@
-<!ENTITY dialog.title "Preferensi Adblock Plus">
-<!ENTITY filters.label "Filter">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Tambahkan filter">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.label "Tambahkan skrip filter">
-<!ENTITY addsubscription.accesskey "S">
-<!ENTITY synchsubscriptions.label "Update semua skrip">
-<!ENTITY synchsubscriptions.accesskey "D">
-<!ENTITY import.label "Impor filter">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.label "Ekspor filter buatan sendiri">
-<!ENTITY export.accesskey "E">
-<!ENTITY clearall.label "Buang semua filter buatan sendiri">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "Setel ulang statistik">
-<!ENTITY resethitcounts.accesskey "T">
-<!ENTITY edit.label "Ubah">
-<!ENTITY edit.accesskey "U">
-<!ENTITY cut.label "Potong">
-<!ENTITY cut.accesskey "T">
-<!ENTITY copy.label "Salin">
-<!ENTITY copy.accesskey "S">
-<!ENTITY paste.label "Tempel">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "Hapus">
-<!ENTITY remove.accesskey "h">
-<!ENTITY menu.find.label "Cari">
-<!ENTITY menu.find.accesskey "C">
-<!ENTITY menu.findagain.label "Cari Lagi">
-<!ENTITY menu.findagain.accesskey "G">
-<!ENTITY view.label "Lihat">
-<!ENTITY view.accesskey "L">
-<!ENTITY sort.label "Urutkan dari">
-<!ENTITY sort.accesskey "i">
-<!ENTITY sort.none.label "Acak">
-<!ENTITY sort.none.accesskey "K">
-<!ENTITY sort.ascending.label "Urut dari A > Z">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Urut dari Z > A">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Opsi">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "Hidupkan Adblock Plus">
-<!ENTITY enable.accesskey "N">
-<!ENTITY showintoolbar.label "Tunjukkan di toolbar">
-<!ENTITY showintoolbar.accesskey "B">
-<!ENTITY showinstatusbar.label "Tunjukkan di status bar">
-<!ENTITY showinstatusbar.accesskey "S">
-<!ENTITY objecttabs.label "Tunjukkan tab pada Flash dan Java">
-<!ENTITY objecttabs.accesskey "T">
-<!ENTITY collapse.label "Gabungkan elemen yang diblok">
-<!ENTITY collapse.accesskey "L">
-<!ENTITY help.label "Bantuan">
-<!ENTITY help.accesskey "b">
-<!ENTITY gettingStarted.label "Memulai">
-<!ENTITY gettingStarted.accesskey "a">
-<!ENTITY faq.label "Pertanyaan yang Sering Ditanya">
-<!ENTITY faq.accesskey "y">
-<!ENTITY filterdoc.label "Menulis filter Adblock Plus">
-<!ENTITY filterdoc.accesskey "R">
-<!ENTITY about.label "Tentang Adblock Plus">
-<!ENTITY about.accesskey "B">
-<!ENTITY description "Filter ini menunjukkan alamat mana yang harus diblok dan mana yang dibolehkan:">
-<!ENTITY filter.column "Aturan filter">
-<!ENTITY filter.accesskey "F">
-<!ENTITY enabled.column "Hidupkan">
-<!ENTITY enabled.accesskey "N">
-<!ENTITY hitcount.column "Sasaran">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "Sasaran terakhir">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "Ubah filter">
-<!ENTITY context.resethitcount.label "Setel ulang statistik sasaran untuk filter">
-<!ENTITY context.synchsubscription.label "Update skrip sekarang">
-<!ENTITY context.editsubscription.label "Edit skrip">
-<!ENTITY context.moveup.label "Pindahkan filter ke atas">
-<!ENTITY context.movedown.label "Pindahkan filter ke bawah">
-<!ENTITY context.movegroupup.label "Pindahkan grup ke atas">
-<!ENTITY context.movegroupdown.label "Pindahkan grup ke bawah">
-<!ENTITY context.enable.label "Hidupkan">
-<!ENTITY context.disable.label "Matikan">
-<!ENTITY apply.label "Pakai">
-<!ENTITY apply.accesskey "P">
diff --git a/chrome/locale/id/sidebar.dtd b/chrome/locale/id/sidebar.dtd
deleted file mode 100644
index 9ff4380..0000000
--- a/chrome/locale/id/sidebar.dtd
+++ /dev/null
@@ -1,30 +0,0 @@
-<!ENTITY detached.title "Adblock Plus: Item yang bisa diblok (dilepaskan)">
-<!ENTITY detach.label "Lepas">
-<!ENTITY reattach.label "Sertakan kembali">
-<!ENTITY search.label "Cari:">
-<!ENTITY search.accesskey "C">
-<!ENTITY type.label "Tipe">
-<!ENTITY address.label "Alamat">
-<!ENTITY filter.label "Filter">
-<!ENTITY state.label "Bagian">
-<!ENTITY size.label "Ukuran">
-<!ENTITY noitems.label "Tidak ada item yang bisa diblok">
-<!ENTITY whitelisted.label "Halaman yang dibebaskan">
-<!ENTITY tooltip.address.label "Alamat:">
-<!ENTITY tooltip.type.label "Tipe:">
-<!ENTITY tooltip.type.blocked "(diblok)">
-<!ENTITY tooltip.type.whitelisted "(dibebaskan)">
-<!ENTITY tooltip.size.label "Ukuran:">
-<!ENTITY tooltip.filter.label "Filter efek:">
-<!ENTITY tooltip.filterSource.label "Sumber filter:">
-<!ENTITY context.block.label "Blok item ini">
-<!ENTITY context.editfilter.label "Edit filter efek">
-<!ENTITY context.whitelist.label "Tambahkan Aturan pengecualian untuk item">
-<!ENTITY context.disablefilter.label "Matikan filter ?1?">
-<!ENTITY context.enablefilter.label "Hidupkan ulang filter ?1?">
-<!ENTITY context.disablefilteronsite.label "Matikan filter ini pada ?1?">
-<!ENTITY context.open.label "Buka di tab baru">
-<!ENTITY context.flash.label "Border item yang ber-flash">
-<!ENTITY context.copy.label "Salin alamat item">
-<!ENTITY context.copyFilter.label "Salin filter">
-<!ENTITY context.selectAll.label "Pilih semua">
diff --git a/chrome/locale/id/subscriptionSelection.dtd b/chrome/locale/id/subscriptionSelection.dtd
deleted file mode 100644
index a695904..0000000
--- a/chrome/locale/id/subscriptionSelection.dtd
+++ /dev/null
@@ -1,10 +0,0 @@
-<!ENTITY dialog.title "Tambahkan skrip filter Adblock Plus">
-<!ENTITY dialog.title.edit "Edit skrip filter">
-<!ENTITY other.label "Tambahkan skrip yang berbeda">
-<!ENTITY other.accesskey "y">
-<!ENTITY title.label "Judul Skrip:">
-<!ENTITY title.accesskey "J">
-<!ENTITY location.label "Lokasi daftar filter:">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.label "Update otomatis">
-<!ENTITY autodownload.accesskey "P">
diff --git a/chrome/locale/is/meta.properties b/chrome/locale/is/meta.properties
deleted file mode 100644
index e838965..0000000
--- a/chrome/locale/is/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Kristján Bjarni Guðmundsson
-name=Adblock Plus
-description=Auglýsingar eru hluti af fortÃðinni!
-description.short=Hatarðu auglýsingar? Er fylgst með þér? Ertu þreyttur á auglýsingum? Settu inn Adblock Plus til að ná aftur stjórn á netinu og breyttu þvà hvernig þú notar vefinn.\n\nStutt yfirlitsmyndband er hægt að sjá hér http://youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus gerir þér kleyft að ná aftur stjórn á netinu og gerir þér kleyft að vafra á vefnum eins og þú vilt. Viðbótin styður yfir fjörutÃu sÃu áskriftir á ýmsum tungumálum sem gera meðal annars kleyft að loka á auglýsingar yfir à það að stöðva öll þekkt vefsvæði sem innihalda óværu. Adblock Plus leyfir þér einnig að sérsnÃða sÃurnar með hinum ýmsum möguleikum, meðal annars sérstökum valmöguleikum fyrir myndir, Flash og Java hluti, og einnig lista yfir hluti eins og skriftur og stÃlsnið.
diff --git a/chrome/locale/it/meta.properties b/chrome/locale/it/meta.properties
deleted file mode 100644
index 6d1fd94..0000000
--- a/chrome/locale/it/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Luana Di Muzio
-name=Adblock Plus
-description=Permette di dire 'no' alla pubblicità presente nelle pagine web!
-description.short=Infastiditi da pubblicità , banner o da possibili tracciature? Installando Adblock Plus è possibile cambiare il modo in cui si naviga sul web!\n\nPer una rapida anteprima video in inglese visitare http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus permette di riprendere il controllo di internet e cambiare il modo in cui si naviga sul web! à possibile sia scegliere fra più di quaranta sottoscrizioni di filtri in svariate lingue che si configurano automaticamente per spaziare dall'eliminazione della pubblicità presente nelle pagine web al blocco di tutti i domini noti per essere pericolosi (in quanto contenenti potenzialmente dialer, virus, etc), sia personalizzare i filtri tramite svariate funzioni utili, tra cui voci di menu contestuale per bloccare immagini/oggetti/riquadri/video/audio, una linguetta per bloccare elementi Flash e Java ed infine una finestra -separabile- contenente gli elementi bloccabili per gestire script e fogli di stile
diff --git a/chrome/locale/it/sendReport.dtd b/chrome/locale/it/sendReport.dtd
deleted file mode 100644
index c5d5774..0000000
--- a/chrome/locale/it/sendReport.dtd
+++ /dev/null
@@ -1,143 +0,0 @@
-<!ENTITY wizard.title "Configurazione guidata per segnalare problemi in una pagina web">
-<!ENTITY privacyPolicy.label "Informativa sulla privacy">
-<!ENTITY dataCollector.heading "Benvenuti alla configurazione guidata per segnalare problemi in una pagina web">
-<!ENTITY dataCollector.description "Attendere mentre vengono raccolti i dati necessari per la segnalazione di Adblock Plus di problemi in una pagina web">
-<!ENTITY typeSelector.heading "Selezione del problema">
-<!ENTITY typeSelector.description "
- La configurazione guidata permette passo a passo di raccogliere ed inviare i dati necessari per effettuare la
- segnalazione di Adblock Plus di problemi in una pagina web. Come primo passo, selezionare il tipo di problema
- che si è verificato
-">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus sta bloccando troppi elementi">
-<!ENTITY typeSelector.falsePositive.accesskey "P">
-<!ENTITY typeSelector.falsePositive.description "
- Selezionare questa opzione se nella pagina web manca parte del contenuto importante, se la pagina web viene
- visualizzata non correttamente oppure se non funziona come dovrebbe. Ã possibile determinare se sia Adblock Plus
- la causa del problema disattivando temporaneamente l'estensione
-">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus non sta bloccando alcun elemento">
-<!ENTITY typeSelector.falseNegative.accesskey "n">
-<!ENTITY typeSelector.falseNegative.description "
- Selezionare questa opzione se nella pagina web vengono visualizzati banner e/o pubblicità nonostante
- Adblock Plus sia attiva
-">
-<!ENTITY typeSelector.other.label "Si è verificato un problema di altro tipo">
-<!ENTITY typeSelector.other.accesskey "S">
-<!ENTITY typeSelector.other.description "
- Selezionare questa opzione se nella pagina web si sta verificando un problema di altro tipo
- che si sospetta relativo all'estensione stessa piuttosto che ai suoi filtri
-">
-<!ENTITY showRecentReports.label "Mostra le segnalazioni recentemente inviate">
-<!ENTITY recentReports.label "Segnalazioni recentemente inviate">
-<!ENTITY recentReports.clear.label "Elimina tutte le segnalazioni">
-<!ENTITY recentReports.clear.accesskey "t">
-<!ENTITY issues.description "
- Sono stati rilevati dei problemi con le impostazioni di Adblock Plus che potrebbero essere responsabili
- del problema da segnalare oppure potrebbero rendere difficile rinvenirne le cause
-">
-<!ENTITY issues.whitelist.description "
- Adblock Plus è attualmente disattivata per la pagina web che si sta segnalando. Riattivare
- l'estensione e ricaricare la pagina prima di inviare la segnalazione del problema per
- rinvenirne le cause
-">
-<!ENTITY issues.whitelist.remove.label "Riattiva Adblock Plus nella pagina attuale">
-<!ENTITY issues.disabled.description "
- Adblock Plus è attualmente disattivata e quindi non bloccherà alcun elemento
-">
-<!ENTITY issues.disabled.enable.label "Attiva Adblock Plus">
-<!ENTITY issues.nofilters.description "
- Adblock Plus attualmente non sta bloccando alcun elemento. Il problema che si è
- verificato è più probabile che non sia relativo ad Adblock Plus
-">
-<!ENTITY issues.nosubscriptions.description "
- Non sembra essere attiva alcuna sottoscrizione di filtri che permette l'eliminazione
- automatica di banner e/o pubblicità presenti nei siti web
-">
-<!ENTITY issues.nosubscriptions.add.label "Aggiungi una sottoscrizione di filtriâ¦">
-<!ENTITY issues.subscriptionCount.description "
- Sembra che siano state aggiunte troppe sottoscrizioni di filtri. Ciò non è
- raccomandato poiché aumenta considerevolmente la possibilità che si verifichino
- dei problemi. Ã inoltre impossibile accettare tale segnalazione in quanto non
- è chiaro quale autore di sottoscrizioni di filtri debba controllare; eliminare
- tutte le sottoscrizioni superflue lasciando solo quella necessaria e verificare
- se il problema persiste ancora
-">
-<!ENTITY issues.openPreferences.label "Apri la finestra delle impostazioniâ¦">
-<!ENTITY issues.ownfilters.description "
- Alcuni dei filtri che vengono applicati nella pagina web attuale sono personalizzati;
- disattivare tali filtri che potrebbero essere la causa del seguente problema:
-">
-<!ENTITY issues.ownfilters.disable.label "Disattiva i filtri">
-<!ENTITY issues.disabledgroups.description "
- Gruppi/sottoscrizioni di filtri sono stati disattivati, ma potrebbero avere effetto
- nella seguente pagina web:
-">
-<!ENTITY issues.disabledgroups.enable.label "Attiva gruppi/sottoscrizioni di filtri">
-<!ENTITY issues.disabledfilters.description "
- I filtri sono stati disattivati, ma potrebbero avere effetto nella seguente pagina web:
-">
-<!ENTITY issues.disabledfilters.enable.label "Attiva i filtri">
-<!ENTITY issues.override.label "Le impostazioni di Adblock Plus sono corrette, proseguire con la raccolta dei dati per la segnalazione">
-<!ENTITY issues.override.accesskey "L">
-<!ENTITY issues.change.description "
- Le impostazioni di Adblock Plus sono state modificate. Ricaricare la pagina web per testare le
- modifiche e se il problema dovesse persistere inviare la segnalazione
-">
-<!ENTITY typeWarning.description "
- Ã stato indicato che si vuole segnalare un problema generico relativo all'estensione
- stessa piuttosto che ai suoi filtri. Poiché tali problemi sono riportati meglio sul
- [link]forum di Adblock Plus[/link], si suggerisce di utilizzare la segnalazione di
- problemi solo come integrazione di una discussione già esistente, visto che nessuno noterÃ
- una segnalazione priva di relativo link alla pagina web dove si verifica appunto il problema.
- Il link generato automaticamente verrà fornito dopo l'invio della segnalazione
-">
-<!ENTITY typeWarning.override.label "Comprendo e voglio inviare la segnalazione comunque">
-<!ENTITY typeWarning.override.accesskey "v">
-<!ENTITY reloadButton.label "Ricarica la pagina">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.heading "Immagine da allegare">
-<!ENTITY screenshot.description "
- Una stessa pagina web può apparire in modo differente a più persone. Potrebbe essere di aiuto per
- meglio comprendere il problema allegare un'immagine della pagina web alla segnalazione. Ã
- possibile eliminare le sezioni contenenti dati sensibili nonché contrassegnare le aree dove il
- problema è evidente facendo prima clic sui relativi pulsanti ed in seguito selezionando le parti
- interessate dell'immagine della pagina web con il mouse
-">
-<!ENTITY screenshot.attach.label "Allega un'immagine della pagina alla segnalazione">
-<!ENTITY screenshot.attach.accesskey "u">
-<!ENTITY screenshot.mark.label "Contrassegna l'area del problema">
-<!ENTITY screenshot.mark.accesskey "C">
-<!ENTITY screenshot.remove.label "Elimina i dati sensibili">
-<!ENTITY screenshot.remove.accesskey "E">
-<!ENTITY screenshot.undo.label "Annulla">
-<!ENTITY screenshot.undo.accesskey "A">
-<!ENTITY commentPage.heading "Invio di un commento">
-<!ENTITY commentPage.description "
- Ã possibile digitare nel relativo campo di testo qui sotto un commento per comprendere meglio
- il problema segnalato. Questo passo è opzionale ma raccomandato se il problema non è ovvio.
- Ã inoltre possibile visualizzare i dati della segnalazione prima di inviarla
-">
-<!ENTITY comment.label "Commento (opzionale):">
-<!ENTITY comment.accesskey "o">
-<!ENTITY comment.lengthWarning "La lunghezza massima del testo del commento è di 1000 caratteri; quelli eccedenti non verranno inviati">
-<!ENTITY email.label "E-mail per ulteriori richieste di informazioni (opzionale):">
-<!ENTITY email.accesskey "m">
-<!ENTITY attachExtensions.label "Allega la lista di estensioni e plugin attivi">
-<!ENTITY attachExtensions.accesskey "l">
-<!ENTITY sendButton.label "Invia la segnalazione">
-<!ENTITY sendButton.accesskey "z">
-<!ENTITY showData.label "Mostra i dati della segnalazione">
-<!ENTITY data.label "Dati della segnalazione:">
-<!ENTITY data.accesskey "D">
-<!ENTITY sendPage.heading "Invio della segnalazione">
-<!ENTITY sendPage.waitMessage "Attendere mentre la segnalazione di Adblock Plus viene inviata">
-<!ENTITY sendPage.confirmation "Segnalazione inviata correttamente, per visualizzarne i dati fare clic sul seguente link:">
-<!ENTITY sendPage.knownIssue "Problema segnalato precedentemente noto. Ulteriori informazioni:">
-<!ENTITY sendPage.errorMessage "
- Il tentativo di inviare la segnalazione non è riuscito a causa del seguente errore: "?1?".
- Accertarsi di essere collegati ad internet e riprovare. Se il problema persiste inviare una richiesta
- di assistenza nel [link]forum di Adblock Plus[/link]
-">
-<!ENTITY sendPage.retry.label "Riprova ad inviare">
-<!ENTITY copyLink.label "Copia il link della segnalazione">
-<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/locale/ja/meta.properties b/chrome/locale/ja/meta.properties
deleted file mode 100644
index a155533..0000000
--- a/chrome/locale/ja/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Schuzak, Premier, k2jp
-name=Adblock Plus
-description=åºåããã£ãã®ã¯éå»ã®è©±ã§ãï¼
-description.short=åºåã«ã¤ã©ã¤ã©ããããè¡å追跡ã«å°ã£ãããããã¼åºåã«æ©ã¾ããã¦ãã¾ãããï¼ Adblock Plus ãä»ããã¤ã³ã¹ãã¼ã«ãã¦ã¤ã³ã¿ã¼ãããå©ç¨ã®ä¸»å°æ¨©ãåãæ»ããWeb ãã¼ã¸åç
§æ¹æ³ãæ¹åãã¾ãããã\n\nçãç´¹ä»ãããªã¯ãã¡ã http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus ã使ããã¨ã§ã¤ã³ã¿ã¼ãããã®ä¸»å°æ¨©ãåãæ»ããèªåãæãéãã« Web ãè¦ããã¨ãã§ãã¾ãããã®ã¢ããªã³ã¯ãªã³ã©ã¤ã³åºååé¤ãããã«ã¦ã§ã¢é
å¸ãã¡ã¤ã³ã®ãããã¯ã¾ã§ãå¤è¨èªå¯¾å¿ãã 40 ãè¶ããèªåè¨å®ç¨è³¼èªãã£ã«ã¿ã«ãã£ã¦æ¯ãããã¦ãã¾ããããã« Adblock Plus ã§ã¯ç»åç¨ã³ã³ããã¹ããªãã·ã§ã³ãFlash ã Java ããããã¯ããã¿ããè¦ããªãã¹ã¯ãªãããã¹ã¿ã¤ã«ã·ã¼ãããããã¯ãããããã¯å¯è½é
ç®ãªã¹ãã®ãããªä¾¿å©ãªè£å©æ©è½ã使ããã¨ã§ãèªä½ãã£ã«ã¿ãã«ã¹ã¿ãã¤ãºãããã¨ãå¯è½ã§ãã
diff --git a/chrome/locale/ja/overlay.dtd b/chrome/locale/ja/overlay.dtd
deleted file mode 100644
index a7c41df..0000000
--- a/chrome/locale/ja/overlay.dtd
+++ /dev/null
@@ -1,27 +0,0 @@
-<!ENTITY status.tooltip "ã¹ãã¼ã¿ã¹:">
-<!ENTITY blocked.tooltip "ãããã¯æ¸ã¿é
ç®:">
-<!ENTITY filters.tooltip "æå¹ãªãã£ã«ã¿:">
-<!ENTITY menuitem.label "Adblock Plus è¨å®">
-<!ENTITY menuitem.accesskey "b">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus:ãããã¯å¯è½é
ç®">
-<!ENTITY context.image.label "Adblock Plus:ç»åããããã¯">
-<!ENTITY context.object.label "Adblock Plus:ãªãã¸ã§ã¯ãããããã¯">
-<!ENTITY context.frame.label "Adblock Plus:ãã¬ã¼ã ããããã¯">
-<!ENTITY context.media.label "Adblock Plus:ãããªï¼ãªã¼ãã£ãªããããã¯">
-<!ENTITY context.removeWhitelist.label "Adblock Plus:ãã®ãã¼ã¸ã§æå¹ã«æ»ã">
-<!ENTITY sidebar.title "ãã®ãã¼ã¸ã§ãããã¯å¯è½ãªé
ç®">
-<!ENTITY sendReport.label "ãã®ãã¼ã¸ã®åé¡ãå ±å">
-<!ENTITY sendReport.accesskey "R">
-<!ENTITY settings.label "è¨å®">
-<!ENTITY settings.accesskey "f">
-<!ENTITY opensidebar.label "ãããã¯å¯è½é
ç®ä¸è¦§ãéã">
-<!ENTITY opensidebar.accesskey "b">
-<!ENTITY closesidebar.label "ãããã¯å¯è½é
ç®ä¸è¦§ãéãã">
-<!ENTITY closesidebar.accesskey "b">
-<!ENTITY whitelist.site.label "?1? ã§ç¡å¹">
-<!ENTITY whitelist.page.label "ãã®ãã¼ã¸ã®ã¿ã§ç¡å¹">
-<!ENTITY disable.label "å
¨ãã¼ã¸ã§ç¡å¹">
-<!ENTITY recommend.label "Facebook ã§å§ãã">
-<!ENTITY objecttab.title "ãããã¯ãã">
-<!ENTITY objecttab.tooltip "ã¯ãªãã¯ã㦠Adblock Plus ã§ãªãã¸ã§ã¯ãããããã¯">
diff --git a/chrome/locale/ja/sendReport.dtd b/chrome/locale/ja/sendReport.dtd
deleted file mode 100644
index 3f8cdf4..0000000
--- a/chrome/locale/ja/sendReport.dtd
+++ /dev/null
@@ -1,75 +0,0 @@
-<!ENTITY wizard.title "åé¡ã¬ãã¼ã¿ã¼">
-<!ENTITY privacyPolicy.label "ãã©ã¤ãã·ã¼ ããªã·ã¼">
-<!ENTITY dataCollector.heading "åé¡ã¬ãã¼ã¿ã¼ã¸ãããã">
-<!ENTITY dataCollector.description "Adblock Plus ãå¿
è¦ãªãã¼ã¿ãéããã¾ã§ããã°ãããå¾
ã¡ãã ãã">
-<!ENTITY typeSelector.heading "åé¡ç¨®å¥ã鏿">
-<!ENTITY typeSelector.description "åé¡ã®å ±åã«å¿
è¦ãªã¹ããããæ¡å
ãã¾ããã¾ãæåã«ãééããåé¡ã®ç¨®å¥ã鏿ãã¦ãã ãã:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus ã®ãããã¯ãéå°">
-<!ENTITY typeSelector.falsePositive.accesskey "m">
-<!ENTITY typeSelector.falsePositive.description "ããã¹ãã³ã³ãã³ãããªãã表示ãä¸é©åããããã¯ãã£ã«ã¿ãæ£ããæ©è½ãã¦ããªãå ´åã¯ãã®ãªãã·ã§ã³ã鏿ãã¦ãã ããã䏿çã« Adblock Plus ãç¡å¹ã«ãã¦ã¿ããã¨ã§ãåå ã Adblock Plus ãã©ãã確ããããã¨ãã§ãã¾ãã">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus ãåºåããããã¯ãã¦ããªã">
-<!ENTITY typeSelector.falseNegative.accesskey "v">
-<!ENTITY typeSelector.falseNegative.description "Adblock Plus ãæå¹ã§ãåºåã表示ãããå ´åããã®ãªãã·ã§ã³ã鏿">
-<!ENTITY typeSelector.other.label "ãã®ä»ã®åé¡">
-<!ENTITY typeSelector.other.accesskey "t">
-<!ENTITY typeSelector.other.description "ãã£ã«ã¿ã§ã¯ãªã Adblock Plus èªä½ã®åé¡ãçãããå ´åã¯ãã®ãªãã·ã§ã³ã鏿">
-<!ENTITY showRecentReports.label "æè¿éä¿¡ããã¬ãã¼ãã表示">
-<!ENTITY recentReports.label "æè¿éä¿¡ããã¬ãã¼ã">
-<!ENTITY recentReports.clear.label "ãã¹ã¦ã®ã¬ãã¼ããåé¤">
-<!ENTITY recentReports.clear.accesskey "R">
-<!ENTITY issues.description "Adblock Plus ã¯ãã®åé¡ã«é¢ä¿ããããããã¯èª¿æ»ãå°é£ã«ããè¨å®ãçºè¦ãã¾ãã">
-<!ENTITY issues.whitelist.description "å ±åãããã¨ãã¦ãããã¼ã¸ã§ Adblock Plus ãç¡å¹ã«ãªã£ã¦ãã¾ãã調æ»ã®å¦¨ãã«ãªãã®ã§ Adblock Plus ãæå¹ã«æ»ããåèªã¿è¾¼ã¿ãã¦ããã¬ãã¼ããæåºãã¦ãã ããã">
-<!ENTITY issues.whitelist.remove.label "ãã®ãã¼ã¸ã§ Adblock Plus ãæå¹ã«æ»ã">
-<!ENTITY issues.disabled.description "Adblock Plus ãç¡å¹ãªã®ã§ãä½ããããã¯ããã¾ãã">
-<!ENTITY issues.disabled.enable.label "Adblock Plus ãæå¹ã«ãã">
-<!ENTITY issues.nofilters.description "Adblock Plus ã¯ç¾å¨ã®ãã¼ã¸ã§ä½ããããã¯ãã¦ããªãã®ã§ããæ°ä»ãã®åé¡ã¯æãã Adblock Plus ã¨é¢ä¿ããã¾ãã">
-<!ENTITY issues.nosubscriptions.description "ã¦ã§ããµã¤ãã®ä¸è¦ãªã³ã³ãã³ããèªååé¤ããè³¼èªãã£ã«ã¿ããã¾ã è³¼èªããã¦ããªãããã§ã">
-<!ENTITY issues.nosubscriptions.add.label "è³¼èªãã£ã«ã¿ã追å ">
-<!ENTITY issues.subscriptionCount.description "è³¼èªãã£ã«ã¿ãå¤éãã§ããã©ã®è³¼èªãã£ã«ã¿ä½è
ããã®åé¡ã«å¯¾å¦ãã¹ãã䏿ãªã®ã§ãã¬ãã¼ããåçã§ãã¾ãããæ¬å½ã«å¿
è¦ãªè³¼èªãã£ã«ã¿ä»¥å¤ãåé¤ããåé¡ãåç¾ããã確èªãã¦ãã ããã">
-<!ENTITY issues.openPreferences.label "è¨å®ç»é¢">
-<!ENTITY issues.ownfilters.description "ãã®ãã¼ã¸ã«é©ç¨ããã¦ãããã£ã«ã¿ã«èªä½ãã£ã«ã¿ãå«ã¾ãã¦ãã¾ããããããã£ã«ã¿ãåé¡ãèµ·ããã¦ããå¯è½æ§ãããã®ã§ç¡å¹ã«ãã¦ãã ãã:">
-<!ENTITY issues.ownfilters.disable.label "ãã£ã«ã¿ãç¡å¹ã«ãã">
-<!ENTITY issues.disabledgroups.description "次ã®è³¼èªãã£ã«ã¿ï¼ã°ã«ã¼ããã£ã«ã¿ã¯ç¡å¹ã«ãªã£ã¦ãã¾ããããã®ãã¼ã¸ã«å½±é¿ããã£ãããããã¾ãã:">
-<!ENTITY issues.disabledgroups.enable.label "è³¼èªãã£ã«ã¿ï¼ã°ã«ã¼ããã£ã«ã¿ãæå¹ã«ãã">
-<!ENTITY issues.disabledfilters.description "次ã®ãã£ã«ã¿ã¯ç¡å¹ã«ãªã£ã¦ãã¾ããããã®ãã¼ã¸ã«å½±é¿ããã£ãããããã¾ãã:">
-<!ENTITY issues.disabledfilters.enable.label "ãã£ã«ã¿ãæå¹ã«ãã">
-<!ENTITY issues.override.label "è¨å®ã¯æ£ããã®ã§ãã¬ãã¼ããç¶ç¶ãã¾ã">
-<!ENTITY issues.override.accesskey "c">
-<!ENTITY issues.change.description "è¨å®ã夿´ããã¾ããã夿´ã確èªããçºã«ãã¼ã¸ãåèªã¿è¾¼ã¿ããããåé¡ã解決ããªããã°ã¬ãã¼ããæåºãã¦ãã ãã">
-<!ENTITY typeWarning.description "ãã£ã«ã¿ã«ã¤ãã¦ã§ã¯ãªã Adblock Plus å
¨è¬ã®åé¡ãã¬ãã¼ããããã¨ãã¦ãã¾ããæ¬æ¥ãã®ãããªåé¡ã¯ [link]Adblock Plus ãã©ã¼ã©ã [/link] ã§ã¬ãã¼ããã¹ãã§ããã¾ããåé¡ã¬ãã¼ãã¸ã®ãªã³ã¯ãèªãæä¾ããªãéã誰ãããªãã®ã¬ãã¼ãã«æ°ä»ããªãã®ã§ãæ¢åã®è°è«ãè£å®ããããã ãã«ä½¿ç¨ãã¦ãã ãããã¬ãã¼ãã¸ã®ãªã³ã¯ã¯ã¬ãã¼ãéä¿¡å¾ã«èªåçæããã¾ãã">
-<!ENTITY typeWarning.override.label "çè§£ããä¸ã§ãã¬ãã¼ããæåºããã">
-<!ENTITY typeWarning.override.accesskey "s">
-<!ENTITY reloadButton.label "ãã¼ã¸ãåèªã¿è¾¼ã¿ãã">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.heading "ã¹ã¯ãªã¼ã³ã·ã§ãããæ·»ä»">
-<!ENTITY screenshot.description "åããã¼ã¸ã§ãå¥ã®äººã«ã¯ç°ãªã£ã¦è¡¨ç¤ºããããã¨ãããã®ã§ãã¹ã¯ãªã¼ã³ã·ã§ããã¯åé¡ã®ææ¡ã«å½¹ç«ã¤ã¡ã¾ãããã¿ã³ãã¯ãªãã¯ããã¹ã¯ãªã¼ã³ã·ã§ããä¸ã§ãã©ãã°ãããã¨ã«ãããåé¡ç®æã«å°ãã¤ãããå人æ
å ±ãé ããããããã¨ãã§ãã¾ãã">
-<!ENTITY screenshot.attach.label "ã¬ãã¼ãã«ãã¼ã¸ã®ã¹ã¯ãªã¼ã³ã·ã§ãããæ·»ä»">
-<!ENTITY screenshot.attach.accesskey "t">
-<!ENTITY screenshot.mark.label "åé¡ã«å°ãã¤ãã">
-<!ENTITY screenshot.mark.accesskey "M">
-<!ENTITY screenshot.remove.label "å人æ
å ±ãé ã">
-<!ENTITY screenshot.remove.accesskey "R">
-<!ENTITY screenshot.undo.label "å
ã«æ»ã">
-<!ENTITY screenshot.undo.accesskey "U">
-<!ENTITY commentPage.heading "ã³ã¡ã³ããå
¥å">
-<!ENTITY commentPage.description "ãã®ã¹ãããã¯ãªãã·ã§ã³ã§ãããåé¡ã®èª¬æãæ¸ãæ®ããã¨ãã§ãã¾ããèªæãªå ´å以å¤ã«ä½¿ç¨ã«ãã¦ãã ãããéä¿¡åã«ã¬ãã¼ãã®ãã¼ã¿ã忤è¨ãããã¨ãã§ãã¾ãã">
-<!ENTITY comment.label "ã³ã¡ã³ãï¼ãªãã·ã§ã³ï¼:">
-<!ENTITY comment.accesskey "C">
-<!ENTITY comment.lengthWarning "ã³ã¡ã³ãã 1000 æåãè¶
ãã¦ããã®ã§å
é ãã 1000 æåã ãéä¿¡ããã¾ã">
-<!ENTITY email.label "ãã詳細ãªè³ªåãå¿
è¦ãªå ´åã«ä½¿ãã¡ã¼ã«ã¢ãã¬ã¹ï¼ãªãã·ã§ã³ï¼:">
-<!ENTITY email.accesskey "m">
-<!ENTITY attachExtensions.label "åå ãã¢ããªã³ã®è¡çªã«ããå ´åã«åããæå¹ãªã¢ããªã³ã®ãªã¹ããã¬ãã¼ãã«æ·»ä»">
-<!ENTITY attachExtensions.accesskey "x">
-<!ENTITY sendButton.label "ã¬ãã¼ããéä¿¡">
-<!ENTITY sendButton.accesskey "n">
-<!ENTITY showData.label "ã¬ãã¼ããã¼ã¿ã表示">
-<!ENTITY data.label "ã¬ãã¼ããã¼ã¿:">
-<!ENTITY data.accesskey "p">
-<!ENTITY sendPage.heading "ã¬ãã¼ããéä¿¡">
-<!ENTITY sendPage.waitMessage "Adblock Plus ãã¬ãã¼ããæåºããéããã°ãããå¾
ã¡ãã ãã">
-<!ENTITY sendPage.confirmation "ããªãã®ã¬ãã¼ãã¯ä¿åããã¾ãããæ¬¡ã®ã¢ãã¬ã¹ã§ã¢ã¯ã»ã¹ã§ãã¾ã:">
-<!ENTITY sendPage.knownIssue "ããªãã®ã¬ãã¼ãã¯ããããæ¢ç¥ã®åé¡ã§ãã詳ããæ
å ±:">
-<!ENTITY sendPage.errorMessage "ã¬ãã¼ãéä¿¡ãã¨ã©ã¼ã³ã¼ã "?1?" ã§å¤±æãã¾ãããã¤ã³ã¿ã¼ãããã«æ¥ç¶ããã¦ããã確èªãå試è¡ãã¦ãã ãããåé¡ã解決ããªãå ´å㯠[link]Adblock Plus ãã©ã¼ã©ã [/link] ã§å©ããæ±ãã¦ãã ããã">
-<!ENTITY sendPage.retry.label "åéä¿¡">
-<!ENTITY copyLink.label "ã¬ãã¼ãã¸ã®ãªã³ã¯ãã³ãã¼">
-<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/ja/settings.dtd b/chrome/locale/ja/settings.dtd
deleted file mode 100644
index 3e53068..0000000
--- a/chrome/locale/ja/settings.dtd
+++ /dev/null
@@ -1,89 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus è¨å®">
-<!ENTITY filters.label "ãã£ã«ã¿">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "ãã£ã«ã¿ã追å ">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.label "è³¼èªãã£ã«ã¿ã追å ">
-<!ENTITY addsubscription.accesskey "s">
-<!ENTITY synchsubscriptions.label "å
¨è³¼èªãã£ã«ã¿ãæ´æ°">
-<!ENTITY synchsubscriptions.accesskey "d">
-<!ENTITY import.label "ãã£ã«ã¿ãã¤ã³ãã¼ã">
-<!ENTITY import.accesskey "m">
-<!ENTITY export.label "ãã£ã«ã¿ãã¨ã¯ã¹ãã¼ã">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.label "å
¨èªä½ãã£ã«ã¿ãåé¤">
-<!ENTITY clearall.accesskey "l">
-<!ENTITY resethitcounts.label "ãããæ°ããªã»ãã">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "ç·¨é">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "åãåã">
-<!ENTITY cut.accesskey "t">
-<!ENTITY copy.label "ã³ãã¼">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "è²¼ãä»ã">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "åé¤">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "æ¤ç´¢">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "åæ¤ç´¢">
-<!ENTITY menu.findagain.accesskey "g">
-<!ENTITY view.label "表示">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "ã½ã¼ã">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "ã½ã¼ããªã">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "A > Z é ã«ã½ã¼ã">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Z > A é ã«ã½ã¼ã">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "ãªãã·ã§ã³">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "Adblock Plus ãæå¹ã«ãã">
-<!ENTITY enable.accesskey "n">
-<!ENTITY showintoolbar.label "ãã¼ã«ãã¼è¡¨ç¤º">
-<!ENTITY showintoolbar.accesskey "b">
-<!ENTITY showinstatusbar.label "ã¹ãã¼ã¿ã¹ãã¼è¡¨ç¤º">
-<!ENTITY showinstatusbar.accesskey "s">
-<!ENTITY objecttabs.label "Flash 㨠Java ã§ã¿ãã表示">
-<!ENTITY objecttabs.accesskey "t">
-<!ENTITY collapse.label "ãããã¯å¾ã®ç©ºç½ã¹ãã¼ã¹ãæ¶ã">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY sync.label "åæè¨å®">
-<!ENTITY sync.accesskey "c">
-<!ENTITY help.label "ãã«ã">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.label "éå§">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.label "ãããã質åã¨åçï¼ï¼¦ï¼¡ï¼±ï¼">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.label "Adblock Plus ãã£ã«ã¿è¨è¿°ã¬ã¤ã">
-<!ENTITY filterdoc.accesskey "r">
-<!ENTITY about.label "Adblock Plus ã«ã¤ãã¦">
-<!ENTITY about.accesskey "b">
-<!ENTITY description "以ä¸ã®ãã£ã«ã¿ã§ãããã¯å¯¾è±¡ãå®ç¾©ãã¾ã:">
-<!ENTITY filter.column "ãã£ã«ã¿ã®ã«ã¼ã«">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "ä½éãã£ã«ã¿">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "æå¹">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "ãããæ°">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "æçµãããæ¥æ">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "ãã£ã«ã¿ç·¨é">
-<!ENTITY context.resethitcount.label "ãã®ãã£ã«ã¿ã®ãããæ°ããªã»ãã">
-<!ENTITY context.synchsubscription.label "ä»ããè³¼èªãã£ã«ã¿ãæ´æ°">
-<!ENTITY context.editsubscription.label "è³¼èªãã£ã«ã¿è¨å®">
-<!ENTITY context.moveup.label "ä¸ã¸">
-<!ENTITY context.movedown.label "ä¸ã¸">
-<!ENTITY context.movegroupup.label "ä¸ã®ã°ã«ã¼ãã¸">
-<!ENTITY context.movegroupdown.label "ä¸ã®ã°ã«ã¼ãã¸">
-<!ENTITY context.enable.label "æå¹">
-<!ENTITY context.disable.label "ç¡å¹">
-<!ENTITY apply.label "é©ç¨">
-<!ENTITY apply.accesskey "p">
-<!ENTITY fennec.subscription.label "è³¼èªãã£ã«ã¿">
diff --git a/chrome/locale/ka/.incomplete b/chrome/locale/ka/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/ka/about.dtd b/chrome/locale/ka/about.dtd
deleted file mode 100644
index d02130d..0000000
--- a/chrome/locale/ka/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus-áá¡ á¨áá¡áá®áá">
-<!ENTITY version.title "ááá á¡áá">
-<!ENTITY description "Adblock Plus á¨áá¡áá«áááááááá¡ ááá«áááá áááááá ááááá¬á§ááá¢áá áááááá áᣠáá á ááá áᣠáá á ááááááá¡, ááááá áá¡, á¤ááᨠááááá¥á¢áá¡ áá á¡á£á áááá¡ ááá®áá áááááá áᣠáá á. ááááá áááá áá á®áá á ááááááá£áá ááá¢áá ááá¢áááá áááááá¥áá©áá á§áááá á áááááá, ááááá á áá á¡á®áá, áᣠá áá¦ááªá áá áááá ááááá á£áá áááá á£áá®áá áᢠAdblock Plus-á¡ áá áááá áá áááááá áááá¬á£á á£áá áá¥áááá!">
-<!ENTITY homepage.label "Adblock Plus-áá¡ á¡ááá¢á">
-<!ENTITY author.label "ááá¢áá á">
-<!ENTITY contributors.label "áááá®ááá áááááá">
diff --git a/chrome/locale/ka/overlay.dtd b/chrome/locale/ka/overlay.dtd
deleted file mode 100644
index 61b30ba..0000000
--- a/chrome/locale/ka/overlay.dtd
+++ /dev/null
@@ -1,17 +0,0 @@
-<!ENTITY status.tooltip "á¡á¢áá¢á£á¡á:">
-<!ENTITY blocked.tooltip "áá web-áááá ááá áááááá ááá£áá ááááááá¢ááá:">
-<!ENTITY filters.tooltip "á§áááááá áá¥á¢áá£á á á¤ááá¢á ááá:">
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY context.image.label "ááááááá á¡á£á ááá">
-<!ENTITY context.object.label "ááááááá ááááá¥á¢á">
-<!ENTITY context.frame.label "ááááááá á¤á áááá">
-<!ENTITY sidebar.title "áá web-áááá ááá¡ áááááá ááááá ááááááá¢ááá">
-<!ENTITY settings.label "áááªáááá">
-<!ENTITY settings.accesskey "Ð">
-<!ENTITY opensidebar.label "ááá®á¡ááá áááááá ááááá ááááááá¢ááá">
-<!ENTITY opensidebar.accesskey "Ð">
-<!ENTITY closesidebar.label "ááá®á£á á áááááá ááááá ááááááá¢ááá">
-<!ENTITY closesidebar.accesskey "Ð">
-<!ENTITY whitelist.site.label "ááááá áá ââáá">
-<!ENTITY whitelist.page.label "ááááá áá áá®áááá áá web-áááá ááá">
diff --git a/chrome/locale/ka/subscriptionSelection.dtd b/chrome/locale/ka/subscriptionSelection.dtd
deleted file mode 100644
index ce3322b..0000000
--- a/chrome/locale/ka/subscriptionSelection.dtd
+++ /dev/null
@@ -1,2 +0,0 @@
-<!ENTITY other.label "á¡á®áá áááááá¡ááá¡ ááááá¢ááá">
-<!ENTITY other.accesskey "T">
diff --git a/chrome/locale/kk-KZ/meta.properties b/chrome/locale/kk-KZ/meta.properties
deleted file mode 100644
index 5465370..0000000
--- a/chrome/locale/kk-KZ/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=ÐаÑÑжан ÐÑÑÑаÑ
идинов
-name=Adblock Plus
-description=ÐаÑнамаÒа жол жоÒ!
-description.short=ÐаÑнамадан ÑаÑÑадÑÒ£Ñз ба? ÐаннеÑÐ»ÐµÑ Ð¼Ð°Ð·Ð°Ò£ÑÐ·Ð´Ñ Ð°Ð»Ð´Ñ Ð¼Ð°? ÐнÑеÑнеÑпен жұмÑÑÑÒ£ÑÐ·Ð´Ñ Ð¸ÐºÐµÐ¼Ð´Ñ ÒÑÐ»Ñ Ò¯ÑÑн Adblock Plus ÒазÑÑ Ð¾ÑнаÑÑÒ£Ñз.\n\nÒÑÑÒа видеоÑÑ Ð¾ÑÑнда баÑ: http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus ÑÑзге инÑеÑнеÑÑÑ Ð±Ð°ÑÒаÑÑÐ´Ñ ÒолÑÒ£ÑзÒа ÒайÑаÑÑп, вебÑÑ Ó©Ð·ÑÒ£Ñз ÒалаÒан ÑÒ¯Ñде көÑÑге мүмкÑндÑк беÑедÑ. Ðұл аддон ÓÑ ÑÒ¯ÑÐ»Ñ ÑÑлдеÑÐ´ÐµÐ³Ñ ÒÑÑÑÒÑан аÑÑам ÑүзгÑлеÑге жазÑлÑлаÑÐ´Ñ ÒолдайдÑ, Ð¾Ð»Ð°Ñ Ð±Ð¾Ð»Ñа, инÑеÑнеÑÑÐµÐ³Ñ Ð¼Ð°Ð·Ð°Ð»Ð°Ð¹ÑÑн жаÑнамадан баÑÑап, ÑабÑÑл жаÑайÑÑн домендеÑÐ´Ñ Ð±Ð»Ð¾ÐºÑаÑÒа дейÑн баÑадÑ. ÐÒан ÒоÑа, Adblock Plus ÑÑзге ÑүзгÑлеÑÐ´Ñ ÒолÑÒ£Ñзбен бапÑап, ÑаÒÑ Ð´Ð° ÑÑÑеÑÑÐµÑ Ò¯ÑÑн конÑекÑÑ Ð¼ÓзÑÑÑ, Flash пен Java обÑекÑÑÐ»ÐµÑ Ò¯ÑÑн блокÑÐ°Ñ Ð±Ð°ÑÑÑмаÑÑн, паÑаÒÑаÒÑ Ð±Ð»Ð¾ÐºÑаÑÒа болаÑÑн нÓÑÑÐµÐ»ÐµÑ ÑÑзÑмÑн көÑÑеÑÑ ÑиÑÒÑÑ Ð¼Ò¯Ð¼ÐºÑндÑкÑеÑÐ´Ñ Ò±ÑÑнадÑ.
diff --git a/chrome/locale/kn/.incomplete b/chrome/locale/kn/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/kn/about.dtd b/chrome/locale/kn/about.dtd
deleted file mode 100644
index 9f19492..0000000
--- a/chrome/locale/kn/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â ಬà²à³à²à³">
-<!ENTITY version.title "ವರà³âಶನà³">
-<!ENTITY description "à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â ನà³à²µà³ à²
à²à²¤à²°à³à²à²¾à²²à²¦à²²à³à²²à²¿ à²à²¨à²¨à³à²¨à³ ನà³à²¡à²²à²¿à²à³à²à²¿à²¸à³à²µà³à²¦à²¿à²²à³à²²à²µà³à²à²¬à³à²¦à²¨à³à²¨à³ ನಿರà³à²§à²°à²¿à²¸à²²à³ ಸಹà²à²°à²¿à²¸à³à²¤à³à²¤à²¦à³. à²à²¨à³à²¨à³ ಮà³à²à²¦à³ ನà³à²µà³ à²à²²à³à²²à²¾ à²à²¾à²¹à³à²°à²¾à²¤à³à²à²³à²¨à³à²¨à³ ಡà³à²¨à³âಲà³à²¡à³ ಮಾಡಬà³à²à²¾à²à²¿à²²à³à²², ನಿಮà²à³ à²
ವೠಬà³à²¡à²µà³à²à²¦à²¾à²¦à²°à³ à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³ââà²à³ ತಿಳಿಸಿ!">
-<!ENTITY homepage.label "à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â ಮà³à²à³à²¯à²¤à²¾à²£:">
-<!ENTITY author.label "à²à²°à³à²¤à³:">
-<!ENTITY contributors.label "ಸಹà²à²°à²¿à²¸à²¿à²¦à²µà²°à³:">
diff --git a/chrome/locale/kn/global.properties b/chrome/locale/kn/global.properties
deleted file mode 100644
index 86425ce..0000000
--- a/chrome/locale/kn/global.properties
+++ /dev/null
@@ -1,37 +0,0 @@
-action0_tooltip=ಮà³à²¨à³à²µà²¨à³à²¨à³ ಮà³à²à²¦à³ ತರಲೠà²à³à²²à²¿à²à³ ಮಾಡಿ, ಸà²à³à²°à²¿à²¯/ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à²²à³ ಮಧà³à²¯à²¦ à²à³à²à²¡à²¿à²¯à²¨à³à²¨à³ à²à³à²²à²¿à²à³ ಮಾಡಿ.
-action1_tooltip=ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ವಸà³à²¤à³à²à²³à²¨à³à²¨à³ ತà³à²°à³à²¯à²²à³/ಮà³à²à³à²à²²à³ à²à³à²²à²¿à²à³ ಮಾಡಿ, ಸà²à³à²°à²¿à²¯/ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à²²à³ ಮಧà³à²¯à²¦ à²à³à²à²¡à²¿à²¯à²¨à³à²¨à³ à²à³à²²à²¿à²à³ ಮಾಡಿ.
-action2_tooltip=à²à²¦à³à²¯à²¤à³à²à²³à²¨à³à²¨à³ ತà³à²°à³à²¯à²²à³ à²à³à²²à²¿à²à³ ಮಾಡಿ, ಸà²à³à²°à²¿à²¯/ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à²²à³ ಮಧà³à²¯à²¦ à²à³à²à²¡à²¿à²¯à²¨à³à²¨à³ à²à³à²²à²¿à²à³ ಮಾಡಿ.
-action3_tooltip=à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³ à²
ನà³à²¨à³ ಸà²à³à²°à²¿à²¯/ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à²²à³ à²à³à²²à²¿à²à³ ಮಾಡಿ.
-disabled_tooltip=à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³ ನಿಷà³à²à³à²°à²¿à²¯à²µà²¾à²à²¿à²¦à³.
-whitelisted_tooltip=à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³ ಸà²à³à²°à²¿à²¯à²µà²¾à²à²¿à²¦à³ à²à²¦à²°à³ ಸಧà³à²¯à²¦ ಪà³à²à²¦à²²à³à²²à²¿ ನಿಷà³à²à³à²°à²¿à²¯à²µà²¾à²à²¿à²¦à³.
-blocked_count_tooltip=?1? ರ ?2?
-no_blocking_suggestions=ಸಧà³à²¯à²¦ ಪà³à²à²¦à²²à³à²²à²¿ ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ಯಾವà³à²¦à³ ವಸà³à²¤à³à²à²³à²¿à²²à³à²².
-whitelisted_page=à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³ ಸಧà³à²¯à²¦ ಪà³à²à²¦à²²à³à²²à²¿ ನಿಷà³à²à³à²°à²¿à²¯à²µà²¾à²à²¿à²¦à³.
-whitelist_description=à²à²à³à²¸à³à²ªà³à²¶à²¨à³ ನಿಯಮà²à²³à³
-filterlist_description=à²à²¾à²¹à³à²°à²¾à²¤à³ ಫಿಲà³à²à²°à³âà²à²³à³
-invalid_description=ಸರಿಯಿಲà³à²²à²¦ ಫಿಲà³à²à²°à³âà²à²³à³
-elemhide_description=à²à²¾à²à²µà³à²à²¦à²¨à³à²¨à³ à²
ಡà²à²¿à²¸à³à²µ ನಿಯಮà²à²³à³
-subscription_description=ಫಿಲà³à²à²°à³ à²à²à²¦à²¾:
-subscription_source=ಮà³à²²:
-subscription_status=ಸà³à²à³à²à²¸à³:
-subscription_status_autodownload=ಸà³à²µà²¯à²à²à²¾à²²à²¿à²¤à²µà²¾à²à²¿ ನವà³à²à²°à²¿à²¸à²²à³à²ªà²à³à²à²¿à²¦à³
-subscription_status_manualdownload=ನಿಮà³à²®à²¿à²à²¦à²¾à²à²¿ ನವà³à²à²°à²¿à²¸à²²à³à²ªà²à³à²à²¿à²¦à³
-subscription_status_externaldownload=ಬಾಹà³à²¯à²°à³à²¤à²¿à²¯à²¿à²à²¦ ನವà³à²à²°à²¿à²¸à²²à³à²ªà²à³à²à²¿à²¦à³ (à²à²¨à³à²¨à³à²à²¦à³ à²à²à³à²¸à³âà²à³à²¨à³à²¶à²¨à³)
-subscription_status_lastdownload=ಹಿà²à²¦à²¿à²¨ ಡà³à²¨à³âಲà³à²¡à³:
-subscription_status_lastdownload_inprogress=ಡà³à²¨à³âಲà³à²¡à³ à²à²à³à²¤à³à²¤à²¿à²¦à³...
-subscription_status_lastdownload_unknown=ಸà²à²¬à²à²§à²ªà²¡à²¦
-remove_subscription_warning=ಠà²à²à²¦à²¾à²µà²¨à³à²¨à³ ನಿà²à²µà²¾à²à²¿à²¯à³ ತà³à²à³à²¯à²²à³ à²à²à³à²à²¿à²¸à³à²¤à³à²¤à³à²°à²¾?
-synchronize_ok=à²à³à²²à³à²µà³
-append=ಸà³à²°à²¿à²¸à³
-type_label_other=à²à²¤à²°
-type_label_script=ಸà³à²à³à²°à²¿à²ªà³à²à³
-type_label_stylesheet=ಸà³à²à³à²²à³ ಶà³à²à³
-type_label_object=ವಸà³à²¤à³
-type_label_subdocument=ಫà³à²°à³à²®à³
-type_label_document=ಬರಹ
-type_label_elemhide=à²
ಡà²à²¿à²¸à²²à²¾à²¦
-type_label_xbl=XBL binding
-type_label_ping=ಲಿà²à²à³ ಪಿà²à²à³
-type_label_xmlhttprequest=XML à²à³à²°à²¿à²à³
-type_label_object_subrequest=ವಸà³à²¤à³à²µà²¿à²¨ à²à²ªà²à³à²°à²¿à²à³
-type_label_dtd=DTD
diff --git a/chrome/locale/kn/meta.properties b/chrome/locale/kn/meta.properties
deleted file mode 100644
index b2eda04..0000000
--- a/chrome/locale/kn/meta.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-name=Adblock Plus
-description=à²à²¾à²¹à³à²°à²¾à²¤à³à²à²³à³ ನಿನà³à²¨à³à²¯à²¦à²¾à²¦à²µà³!
diff --git a/chrome/locale/kn/overlay.dtd b/chrome/locale/kn/overlay.dtd
deleted file mode 100644
index 96f3b00..0000000
--- a/chrome/locale/kn/overlay.dtd
+++ /dev/null
@@ -1,19 +0,0 @@
-<!ENTITY status.tooltip "ಸà³à²à³à²à²¸à³:">
-<!ENTITY blocked.tooltip "ಠಪà³à²à²¦à²²à³à²²à²¿ ತಡà³à²¹à²¿à²¡à²¿à²¦à²¿à²°à³à²µ ವಸà³à²¤à³à²à²³à³">
-<!ENTITY filters.tooltip "ಬಹಳ ಸà²à³à²°à²¿à²¯à²µà²¾à²à²¿à²°à³à²µ ಫಿಲà³à²à²°à³âà²à²³à³:">
-<!ENTITY menuitem.label "à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY context.image.label "à²à²¿à²¤à³à²°à²µà²¨à³à²¨à³ à²à²¡à³âಬà³à²²à²¾à²à³ ಮಾಡà³">
-<!ENTITY context.object.label "ವಸà³à²¤à³à²µà²¨à³à²¨à³ à²à²¡à³âಬà³à²²à²¾à²à³ ಮಾಡà³">
-<!ENTITY context.frame.label "ಫà³à²°à³à²®à³ à²
ನà³à²¨à³ à²à²¡à³âಬà³à²²à²¾à²à³ ಮಾಡà³">
-<!ENTITY sidebar.title "ಠಪà³à²à²¦à²²à³à²²à²¿à²¨ ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ವಸà³à²¤à³à²à²³à³">
-<!ENTITY settings.label "à²à²¦à³à²¯à²¤à³à²à²³à³">
-<!ENTITY settings.accesskey "F">
-<!ENTITY opensidebar.label "ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ವಸà³à²¤à³à²à²³à²¨à³à²¨à³ ತà³à²°à³">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ವಸà³à²¤à³à²à²³à²¨à³à²¨à³ ಮà³à²à³à²à³">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY whitelist.site.label "?1? à²
ಲà³à²²à²¿ ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à³">
-<!ENTITY whitelist.page.label "ಠಪà³à²à²¦à²²à³à²²à²¿ ಮಾತà³à²° ನಿಷà³à²à³à²°à²¿à²¯à²à³à²³à²¿à²¸à³">
-<!ENTITY objecttab.title "ತಡೠಹಿಡಿ">
-<!ENTITY objecttab.tooltip "ಠವಸà³à²¤à³à²µà²¨à³à²¨à³ à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â ಮà³à²²à² ತಡà³à²¹à²¿à²¡à²¿à²¯à²²à³ à²à²²à³à²²à³à²²à²¿ à²à³à²²à²¿à²à³ ಮಾಡಿ">
diff --git a/chrome/locale/kn/sidebar.dtd b/chrome/locale/kn/sidebar.dtd
deleted file mode 100644
index 924fb42..0000000
--- a/chrome/locale/kn/sidebar.dtd
+++ /dev/null
@@ -1,22 +0,0 @@
-<!ENTITY detached.title "à²à²¡à³âಬà³à²²à²¾à²à³ ಪà³à²²à²¸à³â: ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ವಸà³à²¤à³à²à²³à³ (ಹà³à²° ತà³à²à³à²¦à²¿à²¦à³)">
-<!ENTITY detach.label "ಹà³à²° ತà³à²à³">
-<!ENTITY reattach.label "ಮರೠಲà²à²¤à³à²¤à²¿à²¸à³">
-<!ENTITY search.label "ಹà³à²¡à³à²à³:">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "à²à³à²ªà³ ಮಾಡಿ">
-<!ENTITY address.label "ವಿಳಾಸ">
-<!ENTITY filter.label "ಫಿಲà³à²à²°à³">
-<!ENTITY state.label "ಸà³à²¥à²¿à²¤à²¿">
-<!ENTITY noitems.label "ತಡà³à²¹à²¿à²¡à²¿à²¯à²¬à²¹à³à²¦à²¾à²¦ ಯಾವà³à²¦à³ ವಸà³à²¤à³à²à²³à²¿à²²à³à²²">
-<!ENTITY whitelisted.label "ನà²à²¬à²¿à²à²¸à³à²¥ ಪà³à²">
-<!ENTITY tooltip.address.label "ವಿಳಾಸ:">
-<!ENTITY tooltip.type.label "à²à³à²ªà³ ಮಾಡಿ:">
-<!ENTITY tooltip.type.blocked "(ತಡà³à²¹à²¿à²¡à²¿à²¦à²¿à²¦à³)">
-<!ENTITY tooltip.type.whitelisted "(ನà²à²¬à²¿à²à²¸à³à²¥)">
-<!ENTITY tooltip.filter.label "à²à²¾à²²à³à²¤à²¿à²¯à²²à³à²²à²¿à²°à³à²µ ಫಿಲà³à²à²°à³">
-<!ENTITY context.block.label "ಠವಸà³à²¤à³à²µà²¨à³à²¨à³ ತಡà³à²¹à²¿à²¡à²¿">
-<!ENTITY context.editfilter.label "à²à²¾à²²à³à²¤à²¿à²¯à²²à³à²²à²¿à²°à³à²µ ಫಿಲà³à²à²°à³ à²
ನà³à²¨à³ ಸà²à²ªà²¾à²¦à²¿à²¸à³">
-<!ENTITY context.whitelist.label "ವಸà³à²¤à³à²µà²¿à²à³ à²à²à²¦à³ à²à²à³à²¸à³à²ªà³à²¶à²¨à³ ಸà³à²°à²¿à²¸à³">
-<!ENTITY context.open.label "ಹà³à²¸ ಹಾಳà³à²¯à²²à³à²²à²¿ ತà³à²°à³">
-<!ENTITY context.flash.label "ಫà³à²²à²¾à²¶à³ ವಸà³à²¤à³à²à²³ à²à²¡à²¿">
-<!ENTITY context.copy.label "ವಸà³à²¤à³à²µà²¿à²¨ ವಿಳಾಸವನà³à²¨à³ à²à²¾à²ªà²¿ ಮಾಡà³">
diff --git a/chrome/locale/kn/subscriptionSelection.dtd b/chrome/locale/kn/subscriptionSelection.dtd
deleted file mode 100644
index 65e382c..0000000
--- a/chrome/locale/kn/subscriptionSelection.dtd
+++ /dev/null
@@ -1,9 +0,0 @@
-<!ENTITY dialog.title.edit "ಫಿಲà³à²à²°à³ à²à²à²¦à²¾à²µà²¨à³à²¨à³ ಸà²à²ªà²¾à²¦à²¿à²¸à³">
-<!ENTITY other.label "à²à²¨à³à²¨à³à²à²¦à³ à²à²à²¦à²¾à²µà²¨à³à²¨à³ ಸà³à²°à²¿à²¸à²¿">
-<!ENTITY other.accesskey "T">
-<!ENTITY title.label "à²à²à²¦à²¾ ಶà³à²°à³à²·à²¿à²à³:">
-<!ENTITY title.accesskey "T">
-<!ENTITY location.label "ಫಿಲà³à²à²°à³ ಪà²à³à²à²¿à²¯ ಸà³à²¥à²¾à²¨:">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.label "ಸà³à²µà²¯à²à²à²¾à²²à²¿à²¤à²µà²¾à²à²¿ ನವà³à²¨à²à³à²³à²¿à²¸à³">
-<!ENTITY autodownload.accesskey "P">
diff --git a/chrome/locale/ko/about.dtd b/chrome/locale/ko/about.dtd
deleted file mode 100644
index c45f63a..0000000
--- a/chrome/locale/ko/about.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY dialog.title "ì ëë¸ë¡ íë¬ì¤ ì ë³´">
-<!ENTITY version.title "ë²ì ">
-<!ENTITY description "ì ëë¸ë¡ íë¬ì¤ë ì½í
ì¸ ì´ì©ì ë°©í´íê³ ì±ê°ì ê´ê³ 를 ì°¨ë¨íì¬ ëì± ë¹ ë¥´ê³ ì¾ì í ì¸í°ë·ì ë§ë¤ì´ì¤ëë¤. ì°¸ê³ ë¡ íì¡´íë ì ëë¸ë¡ íë¬ì¤ì ìì ì í기ë ì ëë¸ë¡ì ì í ë¤ë¥¸ íì¥ íë¡ê·¸ë¨ì
ëë¤.">
-<!ENTITY homepage.label "ííì´ì§">
-<!ENTITY author.label "ê°ë°ì">
-<!ENTITY contributors.label "ê³µíì">
-<!ENTITY subscriptionAuthors.label "구ë
íí° ì ì§ì">
-<!ENTITY translators.label "ë²ìê°">
diff --git a/chrome/locale/ko/composer.dtd b/chrome/locale/ko/composer.dtd
deleted file mode 100644
index ad8c482..0000000
--- a/chrome/locale/ko/composer.dtd
+++ /dev/null
@@ -1,47 +0,0 @@
-<!ENTITY dialog.title "íí° ì¶ê°">
-<!ENTITY accept.label "ì¶ê°">
-<!ENTITY advanced.label "ê³ ê¸ ë³´ê¸°">
-<!ENTITY basic.label "기본 보기">
-<!ENTITY disabled.warning "ì ëë¸ë¡ íë¬ì¤ê° ì¬ì© ì¤ì§ë¨ : íí° ì¶ê° ê°ë¥ + íí° ì ì© ì¤ì§ [link]â ì ëë¸ë¡ íë¬ì¤ ì¬ì©[/link]">
-<!ENTITY groupDisabled.warning ""?1?" íí° ê·¸ë£¹ì´ ì¬ì© ì¤ì§ë¨ : íí° ì¶ê° ê°ë¥ + íí° ê·¸ë£¹ ì ì© ì¤ì§ [link]â íí° ê·¸ë£¹ ì¬ì©[/link]">
-<!ENTITY filter.label "ì íí°">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "íí° ëª©ë¡">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "ì°¨ë¨ íí°">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "íì© íí°">
-<!ENTITY type.whitelist.accesskey "x">
-<!ENTITY pattern.label "í¨í´ 찾기">
-<!ENTITY pattern.explanation "í¨í´ì ì¼ì¹íë 주ì를 ê²ìíë í
ì¤í¸ 문ìì´ì´ë©°, ìì¼ë ì¹´ë 문ì(*)ë¡ ì ì© ë²ì를 ì¡°ì í ì ììµëë¤.">
-<!ENTITY regexp.warning "[ë린 íí°] í¨í´ ëì ìì¼ë ì¹´ë 문ì(*)ê° ìì¼ë©´ ì ê· ííìì¼ë¡ í´ìëë©°, ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ëë ¤ì§.">
-<!ENTITY shortpattern.warning "[ë린 íí°] í¨í´ì 길ì´ê° ë무 ì§§ì¼ë©´ íí°ê° ë¹í¨ì¨ì ì¼ë¡ ì²ë¦¬ëë©°, ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ëë ¤ì§.">
-<!ENTITY match.warning "ì
ë ¥í í¨í´ê³¼ ì¼ì¹íë 주ìê° ìì¼ë©°, ì°¨ë¨/íì©í 주ìì ìí¥ì 미ì¹ì§ ìì.">
-<!ENTITY custom.pattern.label "ì¬ì©ì ì§ì (C)">
-<!ENTITY custom.pattern.accesskey "C">
-<!ENTITY anchors.label "í¨í´ ì¼ì¹ ì¡°ê±´ :">
-<!ENTITY anchor.start.label "주ì ìì ë¶ë¶ì ì¼ì¹">
-<!ENTITY anchor.start.accesskey "g">
-<!ENTITY anchor.start.flexible.label "ëë©ì¸ ìì ë¶ë¶ì ì¼ì¹">
-<!ENTITY anchor.start.flexible.accesskey "g">
-<!ENTITY anchor.end.label "주ì ë ë¶ë¶ì ì¼ì¹">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "ìµì
">
-<!ENTITY domainRestriction.label "ì§ì ë ëë©ì¸ìë§ ì ì©(D) :">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "1. íì´í 기í¸(|)를 ì´ì©í´ ì¬ë¬ ëë©ì¸ì ì ì© (ìì : site1.com|site2.net). 2. 물결 기í¸(~)를 ì´ì©í´ íí°ë¥¼ ì ì©íì§ ìì ëë©ì¸ ì§ì (ìì : ~site.com)">
-<!ENTITY firstParty.label "ì 1ì ìì²ìë§ ì ì©">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "ì 3ì ìì²ìë§ ì ì©">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.label "ë/ì문ì 구ë¶">
-<!ENTITY matchCase.accesskey "M">
-<!ENTITY types.label "ì ì© íì">
-<!ENTITY selectAllTypes.label "모ë ì í">
-<!ENTITY unselectAllTypes.label "ì í í´ì ">
-<!ENTITY collapse.label "ì°¨ë¨ë ììì ìì ì¨ê¸°ê¸°">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY collapse.default.yes.label "ê¸°ë³¸ê° (ì)">
-<!ENTITY collapse.default.no.label "ê¸°ë³¸ê° (ìëì¤)">
-<!ENTITY collapse.yes.label "ì">
-<!ENTITY collapse.no.label "ìëì¤">
diff --git a/chrome/locale/ko/global.properties b/chrome/locale/ko/global.properties
deleted file mode 100644
index b530767..0000000
--- a/chrome/locale/ko/global.properties
+++ /dev/null
@@ -1,70 +0,0 @@
-default_dialog_title=ì ëë¸ë¡ íë¬ì¤
-action0_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
-action1_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
-action2_tooltip=ë§ì°ì¤ ê°ì´ë° ë²í¼ - ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
-action3_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì©/ì¤ì§
-disabled_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
-active_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© [구ë
íí° : ?1?ê°, ì¬ì©ì íí° : ?2?ê° ]
-whitelisted_tooltip=ì ëë¸ë¡ íë¬ì¤ ì¬ì© (íì©ë íì´ì§)
-blocked_count_tooltip=ì°¨ë¨ : ?1?ê°, ì ì²´ í목 : ?2?ê°
-blocked_count_addendum=(íì© : ?1?ê°, ìì ì¨ê¹ : ?2?ê°)
-no_blocking_suggestions=íì¬ íì´ì§ì ì°¨ë¨ ê°ë¥í íëª©ì´ ììµëë¤.
-whitelisted_page=íì©ë íì´ì§
-whitelist_description=íì© íí°
-filterlist_description=ì°¨ë¨ íí°
-invalid_description=ì¬ë°ë¥´ì§ ìì íí°
-elemhide_description=ìì ì¨ê¹ íí°
-subscription_description=구ë
íí° :
-subscription_wrong_version=구ë
íí° ì¤ ì¼ë¶ íí°ê° ì ìì ì¼ë¡ ìëí기 ìí´ì ìµìí ì ëë¸ë¡ íë¬ì¤ ?1? ë²ì ì ì¤ì¹í´ì¼ í©ëë¤.
-subscription_source=ìì¹ :
-subscription_status=ìí :
-subscription_status_autodownload=ìë ì
ë°ì´í¸
-subscription_status_manualdownload=ìë ì
ë°ì´í¸
-subscription_status_externaldownload=ì¸ë¶ ì
ë°ì´í¸ (ë¤ë¥¸ ë¶ê° 기ë¥)
-subscription_status_lastdownload=ë§ì§ë§ ë¤ì´ë¡ë :
-subscription_status_lastdownload_inprogress=ë¤ì´ë¡ë ì¤...
-subscription_status_lastdownload_unknown=ì ì ìì
-remove_subscription_warning=ì´ êµ¬ë
íí°ë¥¼ ì ê±°íìê² ìµëê¹?
-import_filters_wrong_version=ê²½ê³ : ì¼ë¶ íí°ê° ì ìì ì¼ë¡ ìëí기 ìí´ ìµìí ì ëë¸ë¡ íë¬ì¤ ?1? ë²ì ì ì¤ì¹í´ì¼ í©ëë¤. ì´ íí° ëª©ë¡ì ê°ì ¸ì¤ê¸° ì ì ì ëë¸ë¡ íë¬ì¤ë¥¼ ìµì ë²ì ì¼ë¡ ì
ê·¸ë ì´ëíììì¤.
-import_filters_warning=ê°ì ¸ì¨ íí°ë¥¼ íì¬ì ì¬ì©ì íí°ì ë®ì´ì°ê±°ë íí° ê·¸ë£¹ë³ë¡ ëª©ë¡ ëì ì¶ê°íìê² ìµëê¹?
-import_filters_title=íí° ê°ì ¸ì¤ê¸°
-export_filters_title=ì¬ì©ì íí° ë´ë³´ë´ê¸°
-invalid_filters_file=ì ëë¸ë¡ íë¬ì¤ì íí° íì¼ì´ ìëëë¤.
-filters_write_error=íí°ë¥¼ íì¼ë¡ ì ì¥íë ì¤ ì¤ë¥ê° ë°ìíìµëë¤. ì°ê¸° ê¸ì§ íì¼ì´ê±°ë ë¤ë¥¸ íë¡ê·¸ë¨ìì ì¬ì© ì¤ì¸ íì¼ì¸ì§ íì¸íììì¤.
-clearall_warning=íí° ëª©ë¡ìì 모ë ì¬ì©ì íí°ë¥¼ ì ê±°íìê² ìµëê¹?
-resethitcounts_warning=íí° ì ì© íì를 ì´ê¸°ííìê² ìµëê¹? ì´ ê¸°ë¥ì ëë릴 ì ììµëë¤!
-resethitcounts_selected_warning=ì íí íí°ì ì ì© íì를 ì´ê¸°ííìê² ìµëê¹? ì´ ê¸°ë¥ì ëë릴 ì ììµëë¤!
-filter_regexp_tooltip=ì´ íí°ë ì ê· ííìì´ê±°ë ìµì íí기ì 길ì´ê° ë무 ì§§ì¼ë¯ë¡ ì¹ íì´ì§ë¥¼ ë¶ë¬ì¤ë ìëê° ì íë©ëë¤.
-filter_elemhide_duplicate_id=ì¨ê¸°ë ¤ë ììì IDë í ê°ë§ ì§ì í ì ììµëë¤.
-filter_elemhide_nocriteria=ì¨ê¸°ë ¤ë ìì를 ì¸ìí기 ìí 기ì¤ì´ ì§ì ëì§ ìììµëë¤.
-subscription_notAdded_warning=구ë
íí°ë¥¼ ì¶ê°íì§ ìììµëë¤. 구ë
íí°ê° ìì¼ë©´ íí°ë¥¼ ì§ì ì¶ê°í´ì¼ í©ëë¤.
-subscription_notAdded_warning_addendum=ê³ì ì§ííìê² ìµëê¹?
-subscription_invalid_location=구ë
íí°ì ìì¹ì ì
ë ¥íë URL ëë íì¼ëª
ì´ ì¬ë°ë¥´ì§ ììµëë¤.
-synchronize_invalid_url=ì¤í¨í¨ : ì¬ë°ë¥´ì§ ìì 주ì
-synchronize_connection_error=ì¤í¨í¨ : ë¤ì´ë¡ë ì¤í¨
-synchronize_invalid_data=ì¤í¨í¨ : ì¬ë°ë¥´ì§ ìì íí°
-synchronize_checksum_mismatch=ì¤í¨í¨ : ì²´í¬ì¬ ë¶ì¼ì¹
-synchronize_ok=ë기í ì±ê³µ
-overwrite=ë®ì´ì°ê¸°
-append=ì¶ê°
-new_filter_group_title=ì íí°
-type_label_other=기í
-type_label_script=ì¤í¬ë¦½í¸
-type_label_image=ì´ë¯¸ì§
-type_label_stylesheet=ì¤íì¼ìí¸
-type_label_object=ê°ì²´
-type_label_subdocument=íë ì
-type_label_document=문ì
-type_label_elemhide=ì¨ê²¨ì§ ìì
-type_label_xbl=XBL ë°ì¸ë©
-type_label_ping=ë§í¬ í
-type_label_xmlhttprequest=XML ìì²
-type_label_object_subrequest=ê°ì²´ íì ìì²
-type_label_dtd=DTD
-type_label_media=ì¤ëì¤/ë¹ëì¤
-type_label_font=ê¸ê¼´
-fennec_status_enabled=ì ëë¸ë¡ íë¬ì¤ ì¬ì©
-fennec_status_disabled=ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
-fennec_status_enabled_site=?1?ìì ì ëë¸ë¡ íë¬ì¤ ì¬ì©
-fennec_status_disabled_site=?1?ìì ì ëë¸ë¡ íë¬ì¤ ì¬ì© ì¤ì§
-sync_engine_title=ì ëë¸ë¡ íë¬ì¤ ë°ì´í°
diff --git a/chrome/locale/ko/meta.properties b/chrome/locale/ko/meta.properties
deleted file mode 100644
index 343d5bc..0000000
--- a/chrome/locale/ko/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Maybee, sushizang
-name=Adblock Plus
-description=ì½í
ì¸ ì´ì©ì ë°©í´íê³ ì±ê°ì ê´ê³ , ì´ì ìë
!
-description.short=ì±ê°ì ë°°ëë ì§ì¦ëë ê´ê³ ê° ììµëê¹? ì¸í°ë· ìì ê°ì¸ ì ë³´ ëì¶ì ê±±ì íê³ ììµëê¹? ì´ì©ì íµì ë ¥ì ê°ê² íê³ , ì¹ ë¬¸ìì ë³´ë ë°©ìì ë³ê²½í기 ìí´ ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¤ì¹íììì¤.\n\nìê° ìì : http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¬ì©íë©´ ì´ì©ì íµì ë ¥ì ê°ê² ëê³ , ë³´ê³ ì¶ì ë°©ìì¼ë¡ ì¹ ë¬¸ì를 ë³¼ ì ììµëë¤. ì´ ë¶ê° íë¡ê·¸ë¨ì ì¸í°ë· ê´ê³ ì ê±°ììë¶í° ì ëª
í 모ë ì
ì± ëë©ì¸ ì°¨ë¨ê¹ì§ ë¤ìí 목ì ì ìí´ ìë ì¤ì ëë 구ë
íí°ë¥¼ ì§ìíë©°, íì¬ ììê° ì¸ì´ì ëí 40ê° ì´ìì 구ë
íí°ë¥¼ ì´ì©í ì ììµëë¤. ëí ì´ë¯¸ì§ ì°¨ë¨ì ìí 문맥 ë©ë´, íëìì ìë° ê°ì²´ì ì°¨ë¨ í, ì¤í¬ë¦½í¸ì ì¤íì¼ìí¸ê¹ì§ ì°¨ë¨í ì ìë ì°¨ë¨ ê°ë¥ ëª©ë¡ ë± ë¤ìíê³ ì ì©í 기ë¥ì ì§ìíì¬ ìíë ííì íí°ë¥¼ ìì±í ì ììµëë¤.
diff --git a/chrome/locale/ko/sendReport.dtd b/chrome/locale/ko/sendReport.dtd
deleted file mode 100644
index 1039743..0000000
--- a/chrome/locale/ko/sendReport.dtd
+++ /dev/null
@@ -1,75 +0,0 @@
-<!ENTITY wizard.title "문ì ë³´ê³ ë§ë²ì¬">
-<!ENTITY privacyPolicy.label "ê°ì¸ ì ë³´ ë³´í¸ ì ì±
">
-<!ENTITY dataCollector.heading "문ì ë³´ê³ ë§ë²ì¬ë¥¼ ì´ì©í´ì£¼ì
ì ê³ ë§ìµëë¤!">
-<!ENTITY dataCollector.description "íìí ìë£ë¥¼ ìì§íë ëì ì ìë§ ê¸°ë¤ë ¤ì£¼ììì¤.">
-<!ENTITY typeSelector.heading "문ì ì í ì í">
-<!ENTITY typeSelector.description "문ì ë³´ê³ ë§ë²ì¬ë ì ëë¸ë¡ íë¬ì¤ì 문ì 를 íí° ì ì§ììê² ë³´ê³ í기 ìí´ íìí ë¨ê³ë¥¼ ìë´í©ëë¤. 먼ì íì¬ íì´ì§ì 문ì ì íì ì ííììì¤.">
-<!ENTITY typeSelector.falsePositive.label "ì ëë¸ë¡ íë¬ì¤ê° ì½í
ì¸ ë¥¼ ê³¼ëíê² ì°¨ë¨í¨">
-<!ENTITY typeSelector.falsePositive.accesskey "m">
-<!ENTITY typeSelector.falsePositive.description "ì¤ìí ì½í
ì¸ ëë½, ì¹ íì´ì§ê° ì못 íìë¨, ì¤ìë ë± ì°¨ë¨ ì¤ë¥ê° ìì¼ë©´ ì´ ìµì
ì ì ííììì¤. ì ëë¸ë¡ íë¬ì¤ì ì¬ì©ì ììë¡ ì¤ì§íì¬ ì ëë¸ë¡ íë¬ì¤ê° 문ì ì ìì¸ì¸ì§ 먼ì íì¸íììì¤.">
-<!ENTITY typeSelector.falseNegative.label "ì ëë¸ë¡ íë¬ì¤ê° ê´ê³ 를 ì°¨ë¨ ì í¨">
-<!ENTITY typeSelector.falseNegative.accesskey "v">
-<!ENTITY typeSelector.falseNegative.description "ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¬ì©í¨ìë ë¶êµ¬íê³ ê´ê³ ê° ë³´ì´ë©´ ì´ ìµì
ì ì ííììì¤.">
-<!ENTITY typeSelector.other.label "ë¤ë¥¸ 문ì ">
-<!ENTITY typeSelector.other.accesskey "t">
-<!ENTITY typeSelector.other.description "íí° ë¬¸ì ê° ìë ì ëë¸ë¡ íë¬ì¤ ìì²´ì 문ì ë¡ ìì¬íë¤ë©´ ì´ ìµì
ì ì ííììì¤.">
-<!ENTITY showRecentReports.label "ìµê·¼ì ì ì¶í ë³´ê³ ì 보기">
-<!ENTITY recentReports.label "ìµê·¼ì ì ì¶í ë³´ê³ ì">
-<!ENTITY recentReports.clear.label "모ë ë³´ê³ ì ì ê±°">
-<!ENTITY recentReports.clear.accesskey "R">
-<!ENTITY issues.description "ì´ ë¬¸ì ì ìí¥ì ì¤ ì ìë ì¤ì ëë ìë£ ì¡°ì¬ë¥¼ ì´ë µê² íë ìì¸ì íì§íìµëë¤.">
-<!ENTITY issues.whitelist.description "íì¬ íì´ì§ì íì© íí°ë¥¼ ì ì©íì¬ ì½í
ì¸ ê° ì°¨ë¨ëì§ ìììµëë¤. íì¬ íì´ì§ì ì ì©ë íì© íí°ì ì¬ì©ì ì¤ì§í ìíìì ì¹ íì´ì§ë¥¼ ë¤ì ë¶ë¬ì¤ììì¤.">
-<!ENTITY issues.whitelist.remove.label "ì¬ì´í¸/íì´ì§ íì© íí°ë¥¼ ì¬ì© ì¤ì§">
-<!ENTITY issues.disabled.description "ì ëë¸ë¡ íë¬ì¤ë¥¼ ì¬ì©íì§ ìë ìíì´ë¯ë¡ ì무ê²ë ì°¨ë¨íì§ ììµëë¤.">
-<!ENTITY issues.disabled.enable.label "ì ëë¸ë¡ íë¬ì¤ ì¬ì©">
-<!ENTITY issues.nofilters.description "ì´ ë¬¸ì ë ì ëë¸ë¡ íë¬ì¤ê° ì무ê²ë ì°¨ë¨íì§ ìì ìíìì ë°ìí´ì ì ëë¸ë¡ íë¬ì¤ì ê´ë ¨ì´ ììµëë¤.">
-<!ENTITY issues.nosubscriptions.description "ì¹ ì¬ì´í¸ì ìíì§ ìë ê´ê³ 를 ìë ì°¨ë¨íë 구ë
íí°ë¥¼ ì¶ê°íì§ ìììµëë¤.">
-<!ENTITY issues.nosubscriptions.add.label "구ë
íí° ì¶ê°">
-<!ENTITY issues.subscriptionCount.description "ë무 ë§ì 구ë
íí°ë¥¼ 구ë
íê³ ììµëë¤. ì´ ì¤ì ì ë ë§ì 문ì 를 ë°ììí¬ ì ì기 ë문ì ê¶ì¥íì§ ììµëë¤. ëí íìí ì¡°ì¹ë¥¼ ì·¨í 구ë
íí° ì ì§ìê° ëª
ííì§ ì기 ë문ì ì´ ë¬¸ì ë³´ê³ ë¥¼ ë°ìë¤ì¼ ì ììµëë¤. ì¤ì ë¡ íìí 구ë
íí°ë¥¼ ì ì¸í 모ë 구ë
íí°ë¥¼ ì ê±°íê³ , ê·¸ë° íìë 문ì ê° ë°ìíëì§ë¥¼ í
ì¤í¸íììì¤.">
-<!ENTITY issues.openPreferences.label "íí° ì¤ì ì´ê¸°">
-<!ENTITY issues.ownfilters.description "íì¬ íì´ì§ì ì ì©ë íí°ì ì¼ë¶ë ì¬ì©ìê° ì§ì íìµëë¤. ì´ ë¬¸ì ì ìí¥ì ì¤ ì ìë ì¬ì©ì íí°ë ì¬ì©íì§ ë§ììì¤.">
-<!ENTITY issues.ownfilters.disable.label "íí° ì¬ì© ì¤ì§">
-<!ENTITY issues.disabledgroups.description "ë¤ì 구ë
íí°/íí° ê·¸ë£¹ì ì¬ì©íì§ ìì§ë§ ì´ íì´ì§ì ìí¥ì ì¤ ì ììµëë¤.">
-<!ENTITY issues.disabledgroups.enable.label "구ë
íí°/íí° ê·¸ë£¹ ì¬ì©">
-<!ENTITY issues.disabledfilters.description "ë¤ì íí°ë ì¬ì©íì§ ìì§ë§ íì¬ íì´ì§ì ìí¥ì ì¤ ì ììµëë¤.">
-<!ENTITY issues.disabledfilters.enable.label "íí° ì¬ì©">
-<!ENTITY issues.override.label "ì¤ì ìë ì´ìì´ ìì¼ë©°, ë³´ê³ ì ìì±ì ê³ì ì§íí¨">
-<!ENTITY issues.override.accesskey "c">
-<!ENTITY issues.change.description "ì¤ì ì´ ë³ê²½ëììµëë¤. ì¹ íì´ì§ë¥¼ ë¤ì ë¶ë¬ì¨ í 문ì ê° í´ê²°ëì§ ìëë¤ë©´ ë³´ê³ ì를 ì ì¶íììì¤.">
-<!ENTITY typeWarning.description "íí° ë¬¸ì ê° ìë ì ëë¸ë¡ íë¬ì¤ì ì¼ë°ì ì¸ ë¬¸ì ë [link]ì ëë¸ë¡ íë¬ì¤ í¬ë¼[/link]ì ë³´ê³ íë ê²ì´ ìµì ì±
ì
ëë¤. í¬ë¼ìì ì´ë¯¸ ë
¼ìë 문ì 를 ë³´ì¶©í기 ìí´ ë¬¸ì ë³´ê³ ë§ë²ì¬ë¥¼ ì´ì©í´ì¼ í©ëë¤. ë³´ê³ ì를 íì¸í ì ìë ë§í¬ë¥¼ ì ê³µíì§ ìì¼ë©´ ì무ë ë³´ê³ ë¥¼ íì¸í ì ì기 ë문ì
ëë¤. ë³´ê³ ì를 ì ì¶íë©´ ìëì¼ë¡ ìì±ë ë§í¬ê° ì ê³µë©ëë¤.">
-<!ENTITY typeWarning.override.label "ìì ë´ì©ì ì´í´íì¼ë©°, ë³´ê³ ì ìì±ì ê³ì ì§íí¨">
-<!ENTITY typeWarning.override.accesskey "s">
-<!ENTITY reloadButton.label "íì´ì§ ìë¡ê³ 침">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.heading "ì¤í¬ë¦° ì 첨ë¶">
-<!ENTITY screenshot.description "ê°ì íì´ì§ë ë¤ë¥¸ ì¬ëë¤ìê²ë ë¤ë¥´ê² ë³´ì¼ ì ììµëë¤. ê·¸ëì ë³´ê³ ìì ì¤í¬ë¦° ìì 첨ë¶íë©´ 문ì 를 ì´í´íëë° ëìì´ ë©ëë¤. 문ì ììì ë¶ê°í기 ìí´ íì´ì§ ì´ë¯¸ì§ì íì를 íê³ , 민ê°í ì ë³´ ììì ì¨ê¸¸ ì ììµëë¤. ìíë ë²í¼ì ëë¥´ê³ , ì´ë¯¸ì§ì ë§ì°ì¤ë¡ ììì íìíììì¤.">
-<!ENTITY screenshot.attach.label "ë³´ê³ ìì íì´ì§ ì´ë¯¸ì§ 첨ë¶">
-<!ENTITY screenshot.attach.accesskey "t">
-<!ENTITY screenshot.mark.label "문ì ìì íì">
-<!ENTITY screenshot.mark.accesskey "M">
-<!ENTITY screenshot.remove.label "민ê°í ìì ì¨ê¹">
-<!ENTITY screenshot.remove.accesskey "R">
-<!ENTITY screenshot.undo.label "ëë리기">
-<!ENTITY screenshot.undo.accesskey "U">
-<!ENTITY commentPage.heading "ë³´ê³ ë´ì© ì
ë ¥">
-<!ENTITY commentPage.description "모ë ì¸ì´ë¡ ì
ë ¥ ê°ë¥ + íì´ì§ ì ì²´ URL : íì ì¬ì©íê±°ë ì¤ëª
í기 ì¬ì´ ì¸ì´ë¡ ë³´ê³ í ë´ì©ì ì
ë ¥íììì¤. ê·¸ë° í 주ì íìì¤ì íì´ì§ ì ì²´ URLì ë³µì¬í´ ì
ë ¥í ë´ì© ìëì ë°ëì ë¶ì¬ë£ì¼ììì¤.">
-<!ENTITY comment.label "ë³´ê³ ë´ì© (íì í목) :">
-<!ENTITY comment.accesskey "C">
-<!ENTITY comment.lengthWarning "ì¤ëª
ì 길ì´ê° 1000ì를 ì´ê³¼íì¬ 1000ìê¹ì§ë§ ì ì¡ë©ëë¤.">
-<!ENTITY email.label "íí° ì ì§ìê° ì¶ê°ë¡ 문ìíê³ ì²ë¦¬ ìí를 ìë ¤ì£¼ê¸° ìí ì´ë©ì¼ 주ì (ê¶ì¥ í목) :">
-<!ENTITY email.accesskey "m">
-<!ENTITY attachExtensions.label "ì¬ì©íê³ ìë ë¶ê° ê¸°ë¥ ëª©ë¡ì ë³´ê³ ìì ì¶ê° (ë¤ë¥¸ ë¶ê° 기ë¥ê³¼ ì¶©ëì´ ìì¸ì¸ ê²½ì°)">
-<!ENTITY attachExtensions.accesskey "x">
-<!ENTITY sendButton.label "ë³´ê³ ì ì ì¡">
-<!ENTITY sendButton.accesskey "n">
-<!ENTITY showData.label "ë³´ê³ í ìë£ ë³´ê¸°">
-<!ENTITY data.label "ë³´ê³ í ìë£">
-<!ENTITY data.accesskey "p">
-<!ENTITY sendPage.heading "ë³´ê³ ì ì ì¡">
-<!ENTITY sendPage.waitMessage "ë³´ê³ ì를 ì ì¶íë ëì ì ìë§ ê¸°ë¤ë ¤ì£¼ììì¤.">
-<!ENTITY sendPage.confirmation "ë³´ê³ ìê° ìë²ì ì ì¥ëìê³ , ë¤ì 주ìë¡ ë³´ê³ ì를 íì¸í ì ììµëë¤. íí° ì ì§ìê° ë³´ê³ ë¥¼ ì ìíë©´ ë³´ê³ ìì Status í목ìë unknown ëì ì ì²ë¦¬ ê²°ê³¼ê° íìë©ëë¤.">
-<!ENTITY sendPage.knownIssue "ë³´ê³ í 문ì ë ë¤ë¥¸ ì¬ì©ìë¤ì ìí´ ì´ë¯¸ ë§ì´ ë³´ê³ ëììµëë¤. ë ë§ì ì ë³´ :">
-<!ENTITY sendPage.errorMessage "ì¤ë¥ ì½ë "?1?"ì ìí´ ë³´ê³ ì ì¡ì ì¤í¨íìµëë¤. ì¸í°ë·ì´ ì ìëìëì§ íì¸í í ë¤ì ìëíììì¤. ë§ì½ 문ì ê° ê³ìí´ì ë°ìíë¤ë©´ [link]ì ëë¸ë¡ íë¬ì¤ í¬ë¼[/link]ì ëìì ìì²íììì¤.">
-<!ENTITY sendPage.retry.label "ë¤ì ì ì¡">
-<!ENTITY copyLink.label "ë³´ê³ ë§í¬ ë³µì¬">
-<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/ko/sidebar.dtd b/chrome/locale/ko/sidebar.dtd
deleted file mode 100644
index a489d1c..0000000
--- a/chrome/locale/ko/sidebar.dtd
+++ /dev/null
@@ -1,35 +0,0 @@
-<!ENTITY detached.title "ì°¨ë¨ ê°ë¥ ëª©ë¡ (ë¶ë¦¬ë¨)">
-<!ENTITY detach.label "ë¶ë¦¬">
-<!ENTITY reattach.label "íµí©">
-<!ENTITY search.label "ê²ì (S)">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "íì">
-<!ENTITY address.label "주ì">
-<!ENTITY filter.label "íí°">
-<!ENTITY state.label "ìí">
-<!ENTITY size.label "í¬ê¸°">
-<!ENTITY docDomain.label "문ì ìì¹">
-<!ENTITY docDomain.thirdParty "(ì 3ì ìì²)">
-<!ENTITY docDomain.firstParty "(ì 1ì ìì²)">
-<!ENTITY noitems.label "ì°¨ë¨ ê°ë¥í í목 ìì">
-<!ENTITY whitelisted.label "íì©ë íì´ì§">
-<!ENTITY tooltip.address.label "주ì :">
-<!ENTITY tooltip.type.label "íì :">
-<!ENTITY tooltip.type.blocked "(ì°¨ë¨ë¨)">
-<!ENTITY tooltip.type.whitelisted "(íì©ë¨)">
-<!ENTITY tooltip.size.label "í¬ê¸° :">
-<!ENTITY tooltip.docDomain.label "문ì ìì¹ :">
-<!ENTITY tooltip.filter.label "íí° :">
-<!ENTITY tooltip.filter.disabled "(ì¬ì© ì¤ì§)">
-<!ENTITY tooltip.filterSource.label "íí° ê·¸ë£¹ :">
-<!ENTITY context.block.label "ì°¨ë¨ íí° ì¶ê°">
-<!ENTITY context.editfilter.label "íí° í¸ì§">
-<!ENTITY context.whitelist.label "íì© íí° ì¶ê°">
-<!ENTITY context.disablefilter.label "íí° ì¬ì© ì¤ì§ : ?1?">
-<!ENTITY context.enablefilter.label "íí° ë¤ì ì¬ì© : ?1?">
-<!ENTITY context.disablefilteronsite.label "ì§ì ë ëë©ì¸ìë§ ì ì© ì¤ì§ : ?1?">
-<!ENTITY context.open.label "ì íì¼ë¡ ì´ê¸°">
-<!ENTITY context.flash.label "í목 ìì¹ íì¸">
-<!ENTITY context.copy.label "주ì ë³µì¬">
-<!ENTITY context.copyFilter.label "íí° ë³µì¬">
-<!ENTITY context.selectAll.label "모ë ì í">
diff --git a/chrome/locale/lt/.incomplete b/chrome/locale/lt/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/lt/about.dtd b/chrome/locale/lt/about.dtd
deleted file mode 100644
index 5bec179..0000000
--- a/chrome/locale/lt/about.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY dialog.title "Apie âAdblock Plusâ">
-<!ENTITY version.title "Versija">
-<!ENTITY description "âAdblock Plusâ Jums patiems leidžia nusprÄsti, kÄ
norite matyti Internete. Jums nereikia siųsti visų reklamų, jei jų nenorite matyti - nurodykite âAdblock Plusâ!">
-<!ENTITY homepage.label "âAdblock Plusâ pradžios tinklalapis:">
-<!ENTITY author.label "Autorius:">
-<!ENTITY contributors.label "PrisidÄjo:">
-<!ENTITY subscriptionAuthors.label "Filtro prenumeratos autoriai:">
-<!ENTITY translators.label "VertÄjai:">
diff --git a/chrome/locale/lt/global.properties b/chrome/locale/lt/global.properties
deleted file mode 100644
index 8b5c232..0000000
--- a/chrome/locale/lt/global.properties
+++ /dev/null
@@ -1,63 +0,0 @@
-default_dialog_title=âAdblock Plusâ
-action0_tooltip=Spragtelkite, norÄdami iÅ¡kviesti kontekstinį meniu; spragtelkite viduriniuoju klaviÅ¡u norÄdami įjungti/iÅ¡jungti.
-action1_tooltip=Spragtelkite, norÄdami atverti/užverti blokuojamus elementus; spragtelkite viduriniuoju klaviÅ¡u norÄdami įjungti/iÅ¡jungti.
-action2_tooltip=Spragtelkite, norÄdami atverti nustatymus; spragtelkite viduriniuoju klaviÅ¡u norÄdami įjungti/iÅ¡jungti.
-action3_tooltip=Spragtelkite, norÄdami įjungti/iÅ¡jungti âAdblock Plusâ.
-disabled_tooltip=âAdblock Plusâ iÅ¡jungtas.
-active_tooltip=âAdblock Plusâ įjungtas, naudojama(os) ?1? filtro prenumerata(os) ir ?2? pasirinktinis(ai) filtras(ai).
-whitelisted_tooltip=âAdblock Plusâ aktyvus, bet iÅ¡jungtas dabartiniam tinklalapiui.
-blocked_count_tooltip=?1? iš ?2?
-blocked_count_addendum=(iÅ¡imÄių: ?1?, paslÄpta: ?2?)
-no_blocking_suggestions=Jokių blokuojamų elementų dabartiniame tinklalapyje
-whitelisted_page=âAdblock Plusâ yra iÅ¡jungtas dabartiniam tinklalapiui
-whitelist_description=IÅ¡imÄių taisyklÄs
-filterlist_description=Reklamų filtrai
-invalid_description=Netaisyklingi filtrai
-elemhide_description=Elementų paslÄpimo taisyklÄs
-subscription_description=Filtrų prenumerata:
-subscription_wrong_version=Kai kurių Å¡ios prenumeratos filtrų tinkamam darbui reikia âAdblock Plusâ ?1?!
-subscription_source=Å altinis:
-subscription_status=Būsena:
-subscription_status_autodownload=Automatiškai atnaujinta
-subscription_status_manualdownload=Atnaujinta rankiniu būdu
-subscription_status_externaldownload=Atnaujinta kitu priedu
-subscription_status_lastdownload=Paskutinis atsiuntimas:
-subscription_status_lastdownload_inprogress=AtsiunÄiama...
-subscription_status_lastdownload_unknown=N/D
-remove_subscription_warning=Ar tikrai norite atsisakyti šios prenumeratos?
-import_filters_wrong_version=Ä®spÄjimas: kai kurių Å¡io sÄ
raÅ¡o filtrų tinkamam darbui reikia âAdblock Plusâ ?1?. JÅ«s turÄtumÄte atnaujinti âAdblock Plusâ prieÅ¡ importuodami šį sÄ
raÅ¡Ä
.
-import_filters_warning=Ar norite pakeisti dabartinius filtrus, ar pridÄti naujus filtrus į sÄ
raÅ¡o apaÄiÄ
?
-import_filters_title=Importuoti filtrus
-export_filters_title=Eksportuoti filtrus
-invalid_filters_file=Netinkamas âAdblock Plusâ filtrų failas.
-filters_write_error=Ä®vyko klaida raÅ¡ant filtrus į failÄ
. Ä®sitikinkite, kad failas nÄra apsaugotas nuo raÅ¡ymo ar naudojamas kitos programos.
-clearall_warning=Ar tikrai norite paÅ¡alinti visus filtrus iÅ¡ sÄ
rašo?
-resethitcounts_warning=Ar tikrai norite atstatyti aplankymų skaitiklius visiems filtrams? Å is veiksmas negali bÅ«ti grÄ
žinamas!
-resethitcounts_selected_warning=Ar tikrai norite atstatyti aplankymų skaitiklius pasirinktiems filtrams? Å is veiksmas negali bÅ«ti grÄ
žinamas!
-subscription_notAdded_warning=JÅ«s nepridÄjote filtro prenumeratos. Jei nenaudosite filtro prenumeratos, Jums reikÄs patiems susikurti âAdblock Plusâ filtrus.
-subscription_notAdded_warning_addendum=Ar norite tÄsti?
-subscription_invalid_location=Filtrų sÄ
raÅ¡o adresas nÄra taisyklingas URL ar failo vardas.
-synchronize_invalid_url=Nepavyko, netinkamas adresas
-synchronize_connection_error=Nepavyko, atsiuntimo klaida
-synchronize_invalid_data=Nepavyko, netinkamas filtrų sÄ
rašas
-synchronize_ok=Pavyko
-overwrite=Pakeisti
-append=PridÄti
-new_filter_group_title=Naujas filtras
-type_label_other=kita
-type_label_script=skriptas
-type_label_image=paveikslÄlis
-type_label_stylesheet=stilius
-type_label_object=objektas
-type_label_subdocument=kadras
-type_label_document=dokumentas
-type_label_elemhide=paslÄpta
-type_label_xmlhttprequest=XML užklausa
-type_label_dtd=DTD
-type_label_media=audio/video
-type_label_font=šriftas
-fennec_status_enabled=âAdblock Plusâ yra įjungtas.
-fennec_status_disabled=âAdblock Plusâ yra iÅ¡jungtas.
-fennec_status_enabled_site=âAdblock Plusâ yra įjungtas tinklalapiui ?1?.
-fennec_status_disabled_site=âAdblock Plusâ yra iÅ¡jungtas tinklalapiui ?1?.
-sync_engine_title=âAdblock Plusâ duomenys
diff --git a/chrome/locale/lt/meta.properties b/chrome/locale/lt/meta.properties
deleted file mode 100644
index 959e98a..0000000
--- a/chrome/locale/lt/meta.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-translator=Jonas Slivka
-name=Adblock Plus
-description=Reklamos - tai jau praeitis!
diff --git a/chrome/locale/lt/overlay.dtd b/chrome/locale/lt/overlay.dtd
deleted file mode 100644
index ccc5a52..0000000
--- a/chrome/locale/lt/overlay.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY status.tooltip "Būsena:">
-<!ENTITY blocked.tooltip "Šiame tinklalapyje užblokuoti elementai:">
-<!ENTITY filters.tooltip "Aktyviausi filtrai:">
-<!ENTITY menuitem.label "âAdblock Plusâ">
-<!ENTITY menuitem.accesskey "A">
-<!ENTITY toolbarbutton.label "âAdblock Plusâ">
-<!ENTITY view.blockableItems.label "âAdblock Plusâ: blokuojami elementai">
-<!ENTITY context.image.label "Blokuoti paveikslÄlį">
-<!ENTITY context.object.label "Blokuoti objektÄ
">
-<!ENTITY context.frame.label "Blokuoti kadrÄ
">
-<!ENTITY context.media.label "âAdblock Plusâ: blokuoti audio/video">
-<!ENTITY context.removeWhitelist.label "âAdblock Plusâ: iÅ¡ naujo įjungti Å¡iame puslapyje">
-<!ENTITY sidebar.title "Blokuojami elementai dabartiniame tinklalapyje">
-<!ENTITY sendReport.label "PraneÅ¡ti apie problemÄ
šiame puslapyje">
-<!ENTITY sendReport.accesskey "R">
-<!ENTITY settings.label "Nustatymai">
-<!ENTITY settings.accesskey "N">
-<!ENTITY opensidebar.label "Atverti blokuojamus elementus">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "Užverti blokuojamus elementus">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY whitelist.site.label "Išjungti ?1?">
-<!ENTITY whitelist.page.label "Išjungti šiam tinklalapiui">
-<!ENTITY objecttab.title "Blokuoti">
-<!ENTITY objecttab.tooltip "Spragtelkite Äia norÄdami užblokuoti šį objektÄ
su âAdblock Plusâ">
diff --git a/chrome/locale/lt/settings.dtd b/chrome/locale/lt/settings.dtd
deleted file mode 100644
index 2a9e370..0000000
--- a/chrome/locale/lt/settings.dtd
+++ /dev/null
@@ -1,75 +0,0 @@
-<!ENTITY dialog.title "âAdblock Plusâ nustatymai">
-<!ENTITY filters.label "Filtrai">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "PridÄti filtrÄ
">
-<!ENTITY add.accesskey "D">
-<!ENTITY addsubscription.label "PridÄti filtro prenumeratÄ
">
-<!ENTITY addsubscription.accesskey "P">
-<!ENTITY synchsubscriptions.label "Atnaujinti visas prenumeratas">
-<!ENTITY synchsubscriptions.accesskey "u">
-<!ENTITY import.label "Importuoti filtrus">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.label "Eksportuoti filtrus">
-<!ENTITY export.accesskey "K">
-<!ENTITY clearall.label "Pašalinti visus filtrus">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "Atstatyti aplankymų statistikÄ
">
-<!ENTITY resethitcounts.accesskey "S">
-<!ENTITY edit.label "Taisa">
-<!ENTITY edit.accesskey "T">
-<!ENTITY cut.label "Iškirpti">
-<!ENTITY cut.accesskey "r">
-<!ENTITY copy.label "Kopijuoti">
-<!ENTITY copy.accesskey "K">
-<!ENTITY paste.label "Ä®dÄti">
-<!ENTITY paste.accesskey "d">
-<!ENTITY remove.label "Pašalinti">
-<!ENTITY remove.accesskey "Å¡">
-<!ENTITY menu.find.label "Rasti">
-<!ENTITY menu.find.accesskey "A">
-<!ENTITY menu.findagain.label "Rasti vÄl">
-<!ENTITY menu.findagain.accesskey "V">
-<!ENTITY view.label "Rodymas">
-<!ENTITY view.accesskey "R">
-<!ENTITY sort.label "Rikiuoti pagal">
-<!ENTITY sort.accesskey "k">
-<!ENTITY sort.none.label "Nerikiuojama">
-<!ENTITY sort.none.accesskey "N">
-<!ENTITY sort.ascending.label "Rikiavimo tvarka âA > Zâ">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Rikiavimo tvarka âZ > Aâ">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Pasirinktys">
-<!ENTITY options.accesskey "P">
-<!ENTITY enable.label "Ä®jungti âAdblock Plusâ">
-<!ENTITY enable.accesskey "J">
-<!ENTITY showintoolbar.label "Rodyti priemonių juostoje">
-<!ENTITY showintoolbar.accesskey "P">
-<!ENTITY showinstatusbar.label "Rodyti būsenos juostoje">
-<!ENTITY showinstatusbar.accesskey "B">
-<!ENTITY objecttabs.label "Rodyti korteles Flash ir Java elementams">
-<!ENTITY objecttabs.accesskey "F">
-<!ENTITY collapse.label "Suskleisti užblokuotus elementus">
-<!ENTITY collapse.accesskey "S">
-<!ENTITY help.label "Pagalba">
-<!ENTITY help.accesskey "G">
-<!ENTITY faq.label "Dažnai užduodami klausimai">
-<!ENTITY faq.accesskey "D">
-<!ENTITY filterdoc.label "Kaip raÅ¡yti âAdblock Plusâ filtrus">
-<!ENTITY filterdoc.accesskey "f">
-<!ENTITY about.label "Apie âAdblock Plusâ">
-<!ENTITY about.accesskey "A">
-<!ENTITY description "PridÄkite adresus, kuriuos norite blokuoti. NorÄdami gauti pasiÅ«lymus, peržiÅ«rÄkite iÅ¡skleidžiamÄ
jį sÄ
raÅ¡Ä
. Galite pridÄti â*â kaip pakaitos simbolį norÄdami sukurti bendresnius filtrus. PatyrÄ naudotojai gali naudoti reguliariuosius reiÅ¡kinius, tokius kaip â/banner\d+\.gif$/â.">
-<!ENTITY enabled.column "Įjungta">
-<!ENTITY hitcount.column "Aplankymai">
-<!ENTITY lasthit.column "Paskutinis blokavimas">
-<!ENTITY context.edit.label "Redaguoti filtrÄ
">
-<!ENTITY context.resethitcount.label "Atstatyti aplankymų statistikÄ
filtrui">
-<!ENTITY context.synchsubscription.label "Atnaujinti prenumeratÄ
">
-<!ENTITY context.editsubscription.label "Redaguoti prenumeratÄ
">
-<!ENTITY context.moveup.label "Perkelti aukÅ¡Äiau">
-<!ENTITY context.movedown.label "Perkelti žemiau">
-<!ENTITY context.movegroupup.label "Perkelti grupÄ aukÅ¡Äiau">
-<!ENTITY context.movegroupdown.label "Perkelti grupÄ Å¾emiau">
-<!ENTITY apply.label "Pritaikyti">
-<!ENTITY apply.accesskey "R">
diff --git a/chrome/locale/lt/sidebar.dtd b/chrome/locale/lt/sidebar.dtd
deleted file mode 100644
index 401a6d0..0000000
--- a/chrome/locale/lt/sidebar.dtd
+++ /dev/null
@@ -1,33 +0,0 @@
-<!ENTITY detached.title "âAdblock Plusâ blokuojami elementai (iÅ¡kelta)">
-<!ENTITY detach.label "Iškelti">
-<!ENTITY reattach.label "Iš naujo įkelti">
-<!ENTITY search.label "Ieškoti:">
-<!ENTITY search.accesskey "I">
-<!ENTITY type.label "Tipas">
-<!ENTITY address.label "Adresas">
-<!ENTITY filter.label "Filtras">
-<!ENTITY state.label "Būsena">
-<!ENTITY size.label "Dydis">
-<!ENTITY docDomain.label "Dokumento šaltinis">
-<!ENTITY noitems.label "NÄra blokuojamų elementų">
-<!ENTITY whitelisted.label "Tinklalapis, įtrauktas į išimtis">
-<!ENTITY tooltip.address.label "Adresas:">
-<!ENTITY tooltip.type.label "Tipas:">
-<!ENTITY tooltip.type.blocked "(užblokuota)">
-<!ENTITY tooltip.type.whitelisted "(įtraukta į išimtis)">
-<!ENTITY tooltip.size.label "Dydis:">
-<!ENTITY tooltip.docDomain.label "Dokumento šaltinis:">
-<!ENTITY tooltip.filter.label "Galiojantys filtrai:">
-<!ENTITY tooltip.filter.disabled "(išjungta)">
-<!ENTITY tooltip.filterSource.label "Filtro šaltinis:">
-<!ENTITY context.block.label "Blokuoti šį elementÄ
">
-<!ENTITY context.editfilter.label "Redaguoti aktyvų filtrÄ
">
-<!ENTITY context.whitelist.label "PridÄti iÅ¡imties taisyklÄ Å¡iam elementui">
-<!ENTITY context.disablefilter.label "IÅ¡jungti filtrÄ
?1?">
-<!ENTITY context.enablefilter.label "IÅ¡ naujo įjungti filtrÄ
?1?">
-<!ENTITY context.disablefilteronsite.label "IÅ¡jungti šį filtrÄ
tinklalapiui ?1?">
-<!ENTITY context.open.label "Atverti naujoje kortelÄje">
-<!ENTITY context.flash.label "ParyÅ¡kinti elemento rÄmelį">
-<!ENTITY context.copy.label "Kopijuoti elemento adresÄ
">
-<!ENTITY context.copyFilter.label "Kopijuoti filtrÄ
">
-<!ENTITY context.selectAll.label "ViskÄ
pažymÄti">
diff --git a/chrome/locale/lt/subscriptionSelection.dtd b/chrome/locale/lt/subscriptionSelection.dtd
deleted file mode 100644
index fdd06c1..0000000
--- a/chrome/locale/lt/subscriptionSelection.dtd
+++ /dev/null
@@ -1,17 +0,0 @@
-<!ENTITY dialog.title "PridÄti âAdblock Plusâ filtro prenumeratÄ
">
-<!ENTITY dialog.title.edit "Redaguoti filtrų prenumeratÄ
">
-<!ENTITY subscriptionSelector.label "Pasirinkite filtro prenumeratÄ
iÅ¡ Å¡io sÄ
rašo:">
-<!ENTITY viewList.label "Rodyti filtrus">
-<!ENTITY visitHomepage.label "Aplankyti tinklalapį">
-<!ENTITY addSubscription.label "PridÄti prenumeratÄ
">
-<!ENTITY saveSubscription.label "IÅ¡saugoti prenumeratÄ
">
-<!ENTITY other.label "PridÄti kitÄ
prenumeratÄ
">
-<!ENTITY other.accesskey "T">
-<!ENTITY list.download.retry "Bandyti dar">
-<!ENTITY list.download.website "Rodyti tinklalapį">
-<!ENTITY title.label "Prenumeratos pavadinimas:">
-<!ENTITY title.accesskey "P">
-<!ENTITY location.label "Filtrų sÄ
rašo vieta:">
-<!ENTITY location.accesskey "V">
-<!ENTITY autodownload.label "Automatiškai atnaujinti">
-<!ENTITY autodownload.accesskey "A">
diff --git a/chrome/locale/lv/.incomplete b/chrome/locale/lv/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/lv/about.dtd b/chrome/locale/lv/about.dtd
deleted file mode 100644
index d724127..0000000
--- a/chrome/locale/lv/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Par Adblock Plus">
-<!ENTITY version.title "Versija">
-<!ENTITY description " Adblock Plus ļauj jums izlemt, ko vÄlaties redzÄt InternetÄ.  Jums vairs nav nepiecieÅ¡ams lejupielÄdÄt reklÄmu un reklÄmkarogus, ja jÅ«s  nevÄlaties tos - aizvÄciet ar Adblock Plus!">
-<!ENTITY homepage.label "Adblock Plus mÄjaslapa:">
-<!ENTITY author.label "Autori:">
-<!ENTITY contributors.label "AtbalstÄ«tÄji:">
diff --git a/chrome/locale/lv/composer.dtd b/chrome/locale/lv/composer.dtd
deleted file mode 100644
index 6117bf0..0000000
--- a/chrome/locale/lv/composer.dtd
+++ /dev/null
@@ -1,46 +0,0 @@
-<!ENTITY dialog.title "Pievienot Adblock Plus filtra nosacījumu">
-<!ENTITY accept.label "Pievienot filtru">
-<!ENTITY advanced.label "PaplaÅ¡inÄts skatÄ«jums">
-<!ENTITY basic.label "Pamata skatījums">
-<!ENTITY disabled.warning "Adblock Plus Å¡obrÄ«d ir atspÄjots. JÅ«s joprojÄm varat pievienot filtrus, bet tie netiks piemÄroti tik ilgi, kamÄr jÅ«s [link] neiespÄjosiet Adblock Plus [/ link].">
-<!ENTITY groupDisabled.warning "Filtrs grupa "?1?" kurai Å¡is filtrs bÅ«s jÄpievieno paÅ¡laik ir atspÄjota. JÅ«s joprojÄm varat pievienot filtru, taÄu tas nav piemÄrojams, kamÄr jÅ«s [link] neiespÄjosiet filtra grupu [/link].">
-<!ENTITY filter.label "Jauns filtrs:">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "RÄdÄ«t esoÅ¡os filtrus...">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "BloÄ·ÄÅ¡anas filtrs">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "IzÅÄmuma nosacÄ«jums">
-<!ENTITY type.whitelist.accesskey "x">
-<!ENTITY pattern.label "MeklÄt paraugu">
-<!ENTITY pattern.explanation "Paraugs var bÅ«t jebkura daļa no adreses, zvaigznÄ«te (*) darbojas kÄ aizstÄjÄjzÄ«me. Filtrs var tikt piemÄrots tikai adresei, kas atbilst paredzÄtajam modelim.">
-<!ENTITY regexp.warning "Modelis jÅ«s ievadÄ«jÄt tiks interpretÄts kÄ regulÄra izteiksme, ko Adblock Plus nevar efektÄ«vi apstrÄdÄt un tas var palÄninÄt jÅ«su pÄrlÅ«koÅ¡anu. Ja jÅ«s neplÄnojat izmantot regulÄra izteiksmi, pievienojiet zvaigznÄ«ti (*) parauga beigÄs.">
-<!ENTITY shortpattern.warning "Paraugs, kuru jÅ«s ievadÄ«jÄt, ir pÄrÄk Ä«ss, lai bÅ«tu optimizÄts un tas var palÄninÄt jÅ«su pÄrlÅ«koÅ¡anu. Ieteicams izvÄlÄties garÄku virkni Å¡im filtram, lai Adblock Plus varÄtu apstrÄdÄt filtru efektÄ«vÄk.">
-<!ENTITY custom.pattern.label "PielÄgots:">
-<!ENTITY custom.pattern.accesskey "C">
-<!ENTITY anchors.label "ApstiprinÄt tiaki paraugus:">
-<!ENTITY anchor.start.label "adreses sÄkumÄ">
-<!ENTITY anchor.start.accesskey "g">
-<!ENTITY anchor.start.flexible.label "domÄna vÄrda sÄkumÄ">
-<!ENTITY anchor.start.flexible.accesskey "g">
-<!ENTITY anchor.end.label "adreses beigÄs">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "Opcijas">
-<!ENTITY domainRestriction.label "Ierobežot lÄ«dz domÄnam:">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "Izmantojiet Å¡o opciju, lai precizÄtu vienu vai vairÄkus domÄnus, atdalÄ«tus ar joslu lÄ«niju (|). Filtrs tiks attiecinÄts tikai uz izvÄlÄto domÄnu(-iem). Tilde (~) pirms domÄna vÄrda norÄda, ka filtrs netiek piemÄrots attiecÄ«bÄ uz Å¡o domÄnu.">
-<!ENTITY firstParty.label "Tikai pirmÄs puses">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "Tikai treÅ¡Äs puses">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.label "Saderīgs gadījums">
-<!ENTITY matchCase.accesskey "M">
-<!ENTITY types.label "Pielietot tipiem:">
-<!ENTITY selectAllTypes.label "IzvÄlÄties visu">
-<!ENTITY unselectAllTypes.label "IzvÄlÄties nevienu ">
-<!ENTITY collapse.label "Collapse blocked:">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY collapse.default.yes.label "Lietot noklusÄto vÄrtÄ«bu (jÄ)">
-<!ENTITY collapse.default.no.label "Lietot noklusÄto vÄrtÄ«bu (nÄ)">
-<!ENTITY collapse.yes.label "JÄ">
-<!ENTITY collapse.no.label "NÄ">
diff --git a/chrome/locale/lv/meta.properties b/chrome/locale/lv/meta.properties
deleted file mode 100644
index 598aec7..0000000
--- a/chrome/locale/lv/meta.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-translator=Klaids Borovs
-name=Adblock Plus
-description=Reklâmas ir vakardiena!
diff --git a/chrome/locale/lv/settings.dtd b/chrome/locale/lv/settings.dtd
deleted file mode 100644
index e7cd659..0000000
--- a/chrome/locale/lv/settings.dtd
+++ /dev/null
@@ -1,87 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus Iestatījumi">
-<!ENTITY filters.label "Filtri">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Pievienot Filtru">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.label "Pievienot filtra abonÄÅ¡anu">
-<!ENTITY addsubscription.accesskey "s">
-<!ENTITY synchsubscriptions.label "Atjaunot visus abonementus">
-<!ENTITY synchsubscriptions.accesskey "d">
-<!ENTITY import.label "ImportÄt filtrus">
-<!ENTITY import.accesskey "m">
-<!ENTITY export.label "EksportÄt atseviÅ¡kos filtrus">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.label "AizvÄkt visus atseviÅ¡kos filtrus">
-<!ENTITY clearall.accesskey "l">
-<!ENTITY resethitcounts.label "Atiestatīt klikšķu statistiku">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "RediÄ£Ät">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "Izgriezt">
-<!ENTITY cut.accesskey "t">
-<!ENTITY copy.label "KopÄt">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "IelÄ«mÄt">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "DzÄst">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "MeklÄt">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "MeklÄt atkÄroti">
-<!ENTITY menu.findagain.accesskey "g">
-<!ENTITY view.label "Skatīt">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "KÄrtot pÄc">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "NesakÄrtots">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "A > Z kÄrtoÅ¡anas secÄ«ba">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Z > A kÄrtoÅ¡anas secÄ«ba">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "IespÄjas">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "IespÄjot Adblock Plus">
-<!ENTITY enable.accesskey "n">
-<!ENTITY showintoolbar.label "RÄdÄ«t rÄ«kjoslÄ">
-<!ENTITY showintoolbar.accesskey "b">
-<!ENTITY showinstatusbar.label "RÄdÄ«t stÄvokļa joslÄ">
-<!ENTITY showinstatusbar.accesskey "s">
-<!ENTITY objecttabs.label "RÄdÄ«t cilnes Flash un Java">
-<!ENTITY objecttabs.accesskey "t">
-<!ENTITY collapse.label "SavÄrst bloÄ·Ätos elementus">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY help.label "Palīdzība">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.label "IesÄkumam">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.label "BiežÄk Uzdotie JautÄjumi">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.label "Rakstīt Adblock Plus filtrus">
-<!ENTITY filterdoc.accesskey "r">
-<!ENTITY about.label "Par Adblock Plus">
-<!ENTITY about.accesskey "b">
-<!ENTITY description "Å Ädi filtri nosaka, kurÄm adresÄm ir jÄbÅ«t bloÄ·ÄtÄm, un kÄdas ir atļautas:">
-<!ENTITY filter.column "Filtra noteikumi">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "LÄni filtri">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "IespÄjots">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "Klikšķi">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "PÄdÄjai klikšķis">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "RediÄ£Ät filtru">
-<!ENTITY context.resethitcount.label "Atiestatīt klikšķu statistiku filtram">
-<!ENTITY context.synchsubscription.label "Atjaunot abonÄÅ¡anu">
-<!ENTITY context.editsubscription.label "RediÄ£Ät abonementu">
-<!ENTITY context.moveup.label "PÄrvietot filtru augÅ¡up">
-<!ENTITY context.movedown.label "PÄrvietot filtru lejup">
-<!ENTITY context.movegroupup.label "PÄrvietot grupu augÅ¡up">
-<!ENTITY context.movegroupdown.label "PÄrvietot grupu lejup">
-<!ENTITY context.enable.label "IespÄjot">
-<!ENTITY context.disable.label "AtspÄjot">
-<!ENTITY apply.label "ApstiprinÄt">
-<!ENTITY apply.accesskey "p">
-<!ENTITY fennec.subscription.label "Filtra abonements">
diff --git a/chrome/locale/lv/subscriptionSelection.dtd b/chrome/locale/lv/subscriptionSelection.dtd
deleted file mode 100644
index 971ad5a..0000000
--- a/chrome/locale/lv/subscriptionSelection.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY dialog.title "Pievienot Adblock Plus filtra abonementu">
-<!ENTITY dialog.title.edit "RediÄ£Ät filtra abonementu">
-<!ENTITY description.newInstall " Adblock Plus bÅ«s visefektÄ«gÄkais, ja jÅ«s pievienosiet filtru abonementu.  Filtru abonementus bez maksas sniedz citi Adblock Plus lietotÄji. VispiemÄrotÄkais abonements JÅ«su valodÄ jau ir izvÄlÄts.">
-<!ENTITY subscriptionSelector.label "LÅ«dzu, izvÄlieties filtru abonementu no saraksta:">
-<!ENTITY viewList.label "Skatīt filtrus">
-<!ENTITY visitHomepage.label "ApmeklÄt mÄjaslapu">
-<!ENTITY addSubscription.label "Pievienot abonementu">
-<!ENTITY saveSubscription.label "SaglabÄt abonementu">
-<!ENTITY other.label "Pievienot citu abonementu">
-<!ENTITY other.accesskey "f">
-<!ENTITY list.download.failed "Adblock Plus neizdevÄs ielÄdÄt abonentu sarakstu.">
-<!ENTITY list.download.retry "MÄÄ£iniet vÄlreiz">
-<!ENTITY list.download.website "Skatīt tīmekļa vietni">
-<!ENTITY fromWeb.description "LÅ«dzu, apstipriniet, ka vÄlaties pievienot šī filtra abonementu. JÅ«s varat mainÄ«t abonementa nosaukumu vai atraÅ¡anÄs vietu pirms pievienoÅ¡anas.">
-<!ENTITY edit.description "NepiecieÅ¡amÄ«bas gadÄ«jumÄ JÅ«s varat mainÄ«t abonementa nosaukumu vai atraÅ¡anÄs vietu.">
-<!ENTITY external.description "Tas ir ÄrÄjÄ filtra abonements, tas tiks atjauninÄts ar paplaÅ¡inÄjumu, kas ir izveidojis Å¡o abonementu.">
-<!ENTITY title.label "Abonementa nosaukums:">
-<!ENTITY title.accesskey "t">
-<!ENTITY location.label "Filtru saraksta atraÅ¡anÄs vieta:">
-<!ENTITY location.accesskey "l">
-<!ENTITY autodownload.label "JauninÄt filtrus automÄtiski">
-<!ENTITY autodownload.accesskey "p">
-<!ENTITY supplementMessage "Å Ä« filtra abonements ir paredzÄts lietoÅ¡anai kopÄ ar filtra abonementu "?1?" kuru jÅ«s vÄl neizmantojat.">
-<!ENTITY addMain.label "Pievienot arī filtra abonementu "?1?"">
-<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/mn/meta.properties b/chrome/locale/mn/meta.properties
deleted file mode 100644
index d39d82f..0000000
--- a/chrome/locale/mn/meta.properties
+++ /dev/null
@@ -1,4 +0,0 @@
-translator=ÐаÑÑÑайÑ
ан ÐнÑ
Ñайван
-name=Adblock Plus
-description=СÑÑÑалÑилгаа бол Ó©ÑÐ¸Ð³Ð´Ó©Ñ Ð±Ð°Ð¹Ð»Ð°Ð°!
-description.short=СÑÑÑалÑилгаанÑÑÐ´Ð°Ð°Ñ Ð·Ð°Ð»Ñ
аж байна ÑÑ? ÐÑÑÐ°Ð³Ñ Ñ
ÑÑдÑÑÑÐ´Ð°Ð°Ñ ÑөвөгÑөөж байна ÑÑ? ЯдаÑгааÑай байна ÑÑ? ТÑгвÑл Adblock Plus ÑÑÑлгаÑиÑ
. Ð¢Ð°Ð½Ñ Ð²Ñб үзÑÑ
замÑг Ó©Ó©ÑÑилж, инÑеÑнÑÑийн ÑдиÑдлагÑг ÑÑгүүлж өгөÑ
болно.\n\nҮүний ÑÑÑ
ай богино кино http://www.youtube.com/watch?v=oNvb2SjVjjI -д байна.
diff --git a/chrome/locale/mn/overlay.dtd b/chrome/locale/mn/overlay.dtd
deleted file mode 100644
index 0e31771..0000000
--- a/chrome/locale/mn/overlay.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY status.tooltip "Төлөв:">
-<!ENTITY blocked.tooltip "Уг Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ñ
аÑигдÑан зүйлÑ:">
-<!ENTITY filters.tooltip "Хамгийн идÑвÑ
ÑÑй ÑүүлÑÒ¯Ò¯Ñүүд:">
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY toolbarbutton.label "Adblock ÐÑмÑÑ
">
-<!ENTITY view.blockableItems.label "Adblock ÐÑмÑÑ
:ХаÑигдаÑ
ÑÐ¹Ñ Ð·Ò¯Ð¹Ð»Ñ">
-<!ENTITY context.image.label "Adblock ÐÑÑаг">
-<!ENTITY context.object.label "Adblock ÐбÑекÑ">
-<!ENTITY context.frame.label "Adblock Ð¥Ò¯ÑÑÑ">
-<!ENTITY context.media.label "Adblock: ÐÑÑ/видео">
-<!ENTITY context.removeWhitelist.label "Adblock: Уг Ñ
ÑÑдÑанд даÑ
ин нÑÑÑ
">
-<!ENTITY sidebar.title "ТÑÑ
айн Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ñ
аÑигдаж болоÑ
зүйлÑ">
-<!ENTITY sendReport.label "ÐÐ½Ñ Ñ
ÑÑÐ´Ð°Ñ Ð´Ð°Ñ
Ñ Ð°ÑÑÑдлÑг мÑдÑгдÑÑ
">
-<!ENTITY sendReport.accesskey "Ð">
-<!ENTITY settings.label "ТоÑ
иÑгоонÑÑд">
-<!ENTITY settings.accesskey "Т">
-<!ENTITY opensidebar.label "ХаÑигдаÑ
зүйлÑийг нÑÑÑ
">
-<!ENTITY opensidebar.accesskey "Ð¥">
-<!ENTITY closesidebar.label "ХаÑигдаÑ
зүйлÑийг Ñ
ааÑ
">
-<!ENTITY closesidebar.accesskey "Ð¥">
-<!ENTITY whitelist.site.label "ХааÑ
Ð½Ñ ?1?">
-<!ENTITY whitelist.page.label "ÐөвÑ
өн Ñг Ñ
ÑÑдÑанд Ñ
ааÑ
">
-<!ENTITY objecttab.title "ХаÑиÑ
">
-<!ENTITY objecttab.tooltip "Ðнд даÑвал Ñг обÑекÑийг Adblock Plus-Ð°Ð°Ñ Ñ
аÑиÑ
болно">
diff --git a/chrome/locale/mn/settings.dtd b/chrome/locale/mn/settings.dtd
deleted file mode 100644
index e7aad14..0000000
--- a/chrome/locale/mn/settings.dtd
+++ /dev/null
@@ -1,89 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus ТоÑ
иÑгоонÑÑд">
-<!ENTITY filters.label "ШүүлÑÒ¯Ò¯Ñүүд">
-<!ENTITY filters.accesskey "Ш">
-<!ENTITY add.label "Ð¨Ò¯Ò¯Ð»Ñ Ð½ÑмÑÑ
">
-<!ENTITY add.accesskey "Ð">
-<!ENTITY addsubscription.label "ШүүлÑÒ¯Ò¯Ñ Ð¼ÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
-<!ENTITY addsubscription.accesskey "Ð">
-<!ENTITY synchsubscriptions.label "ÐÒ¯Ñ
мÑдÑÑлÑгÑийг ÑинÑÑлÑÑ
">
-<!ENTITY synchsubscriptions.accesskey "Ð">
-<!ENTITY import.label "ШүүлÑÒ¯Ò¯Ñ Ð¾ÑÑÑлаÑ
">
-<!ENTITY import.accesskey "Ð">
-<!ENTITY export.label "ШүүлÑÒ¯Ò¯Ñ Ð³Ð°ÑгаÑ
">
-<!ENTITY export.accesskey "Ð">
-<!ENTITY clearall.label "ÐÒ¯Ñ
ÑүүлÑÒ¯Ò¯Ñүүдийг Ñ
аÑаÑ
">
-<!ENTITY clearall.accesskey "С">
-<!ENTITY resethitcounts.label "ХандалÑÑн Ñөлвийг ÑÑ
лүүлÑÑ
">
-<!ENTITY resethitcounts.accesskey "Т">
-<!ENTITY edit.label "ÐаÑваÑ">
-<!ENTITY edit.accesskey "Ð">
-<!ENTITY cut.label "ХайÑлаÑ
">
-<!ENTITY cut.accesskey "Ч">
-<!ENTITY copy.label "Ð¥ÑÑлаÑ
">
-<!ENTITY copy.accesskey "Ð¥">
-<!ENTITY paste.label "ТавиÑ
">
-<!ENTITY paste.accesskey "Т">
-<!ENTITY remove.label "УÑÑгаÑ
">
-<!ENTITY remove.accesskey "У">
-<!ENTITY menu.find.label "ХайÑ
">
-<!ENTITY menu.find.accesskey "Ð">
-<!ENTITY menu.findagain.label "ÐаÑ
ин Ñ
айÑ
">
-<!ENTITY menu.findagain.accesskey "Ð">
-<!ENTITY view.label "ХаÑаÑ
">
-<!ENTITY view.accesskey "Ð¥">
-<!ENTITY sort.label "ÐÑÑмбÑлÑÑ
нÑ">
-<!ENTITY sort.accesskey "Ð">
-<!ENTITY sort.none.label "ÐÑÑÐ¼Ð±Ñ Ò¯Ð³Ò¯Ð¹">
-<!ENTITY sort.none.accesskey "Ò®">
-<!ENTITY sort.ascending.label "Ð > Я ÑÑÑмбÑлÑÑ
">
-<!ENTITY sort.ascending.accesskey "Ð">
-<!ENTITY sort.descending.label "Я > Ð ÑÑÑмбÑлÑÑ
">
-<!ENTITY sort.descending.accesskey "Я">
-<!ENTITY options.label "СонголÑÑÑд">
-<!ENTITY options.accesskey "Ð">
-<!ENTITY enable.label "Adblock Plus идÑвÑ
ÑÑй">
-<!ENTITY enable.accesskey "Ð">
-<!ENTITY showintoolbar.label "Ð¥ÑÑÑгÑлийн мөÑÑ Ñ
аÑÑÑлаÑ
">
-<!ENTITY showintoolbar.accesskey "Ð">
-<!ENTITY showinstatusbar.label "Төлвийн мөÑÑ Ñ
аÑÑÑлаÑ
">
-<!ENTITY showinstatusbar.accesskey "Т">
-<!ENTITY objecttabs.label "Flash болон Java-д tab Ñ
аÑÑÑлаÑ
">
-<!ENTITY objecttabs.accesskey "Ð¥">
-<!ENTITY collapse.label "ХаÑигдÑан ÑлеменÑийг Ñ
ÑмиÑ
">
-<!ENTITY collapse.accesskey "Ð">
-<!ENTITY help.label "ТÑÑламж">
-<!ENTITY help.accesskey "Т">
-<!ENTITY gettingStarted.label "ÐÑ
лÑл">
-<!ENTITY gettingStarted.accesskey "Ð">
-<!ENTITY faq.label "ТүгÑÑмÑл ÐÑÑÑлÑÑн ХаÑиÑлÑÑÑд">
-<!ENTITY faq.accesskey "Ð">
-<!ENTITY filterdoc.label "Adblock Plus ÑүүлÑÒ¯Ò¯Ñүүд биÑиÑ
">
-<!ENTITY filterdoc.accesskey "Ð">
-<!ENTITY about.label "Adblock Plus-ийн ÑÑÑ
ай">
-<!ENTITY about.accesskey "Т">
-<!ENTITY description "ХаÑиÑ
Ñг Ñ
Ò¯ÑÑÑн Ñ
аÑгаа нÑмÑÑ
дÑÑ, Ð´Ð¾Ð¾Ñ ÑнжиÑ
жагÑаалÑÐ°Ð°Ñ Ð°Ð²Ñ Ð±Ð¾Ð»Ð¾Ð¼Ð¶Ñой.
- Та * аÑиглан илүү еÑөнÑ
ий ÑүүлÑÒ¯Ò¯Ñ Ò¯Ò¯ÑгÑж болно. Ðлүү Ñ
ÑÑÑглÑгÑид
- Ñнгийн илÑÑÑ
ийлÑл (regexpression) аÑиглаж Ñадна. Ð: /banner\d+\.gif$/.">
-<!ENTITY filter.column "ШүүÑ
дүÑÑм">
-<!ENTITY filter.accesskey "Ш">
-<!ENTITY slow.column "Удаан ÑүүлÑÒ¯Ò¯Ñүүд">
-<!ENTITY slow.accesskey "У">
-<!ENTITY enabled.column "ÐдÑвÑ
ÑÑй">
-<!ENTITY enabled.accesskey "Ð">
-<!ENTITY hitcount.column "ХандалÑ">
-<!ENTITY hitcount.accesskey "Ð¥">
-<!ENTITY lasthit.column "Сүүлийн Ñ
андалÑ">
-<!ENTITY lasthit.accesskey "С">
-<!ENTITY context.edit.label "ШүүлÑÒ¯Ò¯Ñ Ð·Ð°ÑаÑ
">
-<!ENTITY context.resethitcount.label "ШүүлÑÒ¯Ò¯Ñийн Ñ
андалÑÑн ÑÑаÑиÑÑикийг ÑÑ
лүүлÑÑ
">
-<!ENTITY context.synchsubscription.label "ÐÑдÑÑлÑгÑийг одоо ÑинÑÑлÑÑ
">
-<!ENTITY context.editsubscription.label "ÐÑдÑÑлÑÐ³Ñ Ð·Ð°ÑаÑ
">
-<!ENTITY context.moveup.label "ÐÑÑÑлүүлÑÑ
">
-<!ENTITY context.movedown.label "ÐооÑлÑÑлаÑ
">
-<!ENTITY context.movegroupup.label "Ðүлгийг дÑÑÑлүүлÑÑ
">
-<!ENTITY context.movegroupdown.label "Ðүлгийг дооÑлÑÑлаÑ
">
-<!ENTITY context.enable.label "ÐÑÑÑ
">
-<!ENTITY context.disable.label "ХааÑ
">
-<!ENTITY apply.label "Ð¥ÑÑÑглÑÑ
">
-<!ENTITY apply.accesskey "Ð">
-<!ENTITY fennec.subscription.label "ШүүÑ
мÑдÑÑлÑгÑ">
diff --git a/chrome/locale/mn/subscriptionSelection.dtd b/chrome/locale/mn/subscriptionSelection.dtd
deleted file mode 100644
index f0bffe3..0000000
--- a/chrome/locale/mn/subscriptionSelection.dtd
+++ /dev/null
@@ -1,20 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus-д ÑавÑай моÑил">
-<!ENTITY dialog.title.edit "ШүүлÑÒ¯Ò¯Ñийн мÑдÑÑлÑÐ³Ñ Ð·Ð°ÑаÑ
">
-<!ENTITY subscriptionSelector.label "ÐагÑаалÑÐ°Ð°Ñ ÑÒ¯Ò¯Ñ
мÑдÑÑлÑÐ³Ñ Ñонгоно ÑÑ:">
-<!ENTITY viewList.label "ШүүлÑÒ¯Ò¯Ñүүд Ñ
аÑаÑ
">
-<!ENTITY visitHomepage.label "ҮндÑÑн Ñ
ÑÑдÑанд зоÑлоÑ
">
-<!ENTITY addSubscription.label "ÐÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
-<!ENTITY saveSubscription.label "ÐÑдÑÑлÑÐ³Ñ Ñ
адгалаÑ
">
-<!ENTITY other.label "Ó¨Ó©Ñ Ð¼ÑдÑÑлÑÐ³Ñ Ð½ÑмÑÑ
">
-<!ENTITY other.accesskey "Ó¨">
-<!ENTITY list.download.failed "Adblock Plus Ð½Ñ Ð¼ÑдÑÑлÑгÑийн жагÑаалÑÑг ÑаÑаж ÑадÑангүй.">
-<!ENTITY list.download.retry "ÐаÑ
иж оÑолдоÑ
">
-<!ENTITY list.download.website "ÐÑбÑайÑÑг Ñ
аÑаÑ
">
-<!ENTITY title.label "ÐÑдÑÑлÑгÑийн гаÑÑиг:">
-<!ENTITY title.accesskey "Ð">
-<!ENTITY location.label "ШүүлÑÒ¯Ò¯Ñийн жагÑаалÑÑн байÑÑил:">
-<!ENTITY location.accesskey "Ð">
-<!ENTITY autodownload.label "ÐвÑомаÑÐ°Ð°Ñ ÑинÑÑлÑÑ
">
-<!ENTITY autodownload.accesskey "Ð">
-<!ENTITY addMain.label "ШүүÑ
мÑдÑÑлÑÐ³Ñ "?1?" нÑмÑÑ
">
-<!ENTITY addMain.accesskey "Ш">
diff --git a/chrome/locale/ms-MY/global.properties b/chrome/locale/ms-MY/global.properties
deleted file mode 100644
index 8f825e2..0000000
--- a/chrome/locale/ms-MY/global.properties
+++ /dev/null
@@ -1,70 +0,0 @@
-default_dialog_title=Adblock Plus
-action0_tooltip=Klik untuk mengeluarkan menu konteks, klik tengah untuk aktifkan/nyahaktifkan.
-action1_tooltip=Klik untuk membuka/menutup item yang boleh disekat, klik tengah untuk aktifkan/nyahaktifkan.
-action2_tooltip=Klik untuk buka tatarajah, klik tengah untuk aktifkan/nyahaktifkan.
-action3_tooltip=Klik untuk aktifkan/nyahaktifkan Adblock Plus.
-disabled_tooltip=Adblock Plus telah dinyahaktifkan.
-active_tooltip=Adblock Plus telah dinyahaktifkan, ?1? langganan penapis dan ?2? penapis sendiri digunakan.
-whitelisted_tooltip=Adblock Plus dinyahaktifkan pada laman semasa.
-blocked_count_tooltip=?1? daripada ?2?
-blocked_count_addendum=(juga dikecualikan: ?1?, disembunyikan: ?2?
-no_blocking_suggestions=Tiada item yang boleh disekat pada laman semasa
-whitelisted_page=Adblock Plus telah dinyahaktifkan untuk laman semasa
-whitelist_description=Peraturan pengecualian saya
-filterlist_description=Peraturan penyekatan iklan saya
-invalid_description=Peraturan tidak sah saya
-elemhide_description=Peraturan menyembunyikan elemen saya
-subscription_description=Langganan penapis:
-subscription_wrong_version=Beberapa penapis dalam langganan ini memerlukan Adblock Plus ?1? untuk berfungsi.
-subscription_source=Sumber:
-subscription_status=Status:
-subscription_status_autodownload=Dikemaskini secara automatik
-subscription_status_manualdownload=Dikemaskini secara manual
-subscription_status_externaldownload=Dikemaskini secara luar (extension lain)
-subscription_status_lastdownload=Muat-turun terakhir:
-subscription_status_lastdownload_inprogress=Memuat-turun...
-subscription_status_lastdownload_unknown=N/A
-remove_subscription_warning=Adakah anda mahu membuang langganan ini?
-import_filters_wrong_version=Amaran: beberapa penapis dalam senarai ini memerlukan Adblock Plus ?1? untuk berfungsi dengan sempurna. Anda perlu menaiktaraf Adblock Plus kepada yang terbaru sebelum mengimport senarai ini.
-import_filters_warning=Adakah anda mahu menggantikan penapis sedia ada atau melampirkan penapis baru pada akhir senarai sedia ada?
-import_filters_title=Import penapis
-export_filters_title=Eksport penapis
-invalid_filters_file=Bukan fail penapis Adblock Plus yang sah.
-filters_write_error=Terdapat ralat dalam menulis penapis pada fail. Pastikan fail tidak dilindung-tulis atau dibuka dalam program lain.
-clearall_warning=Adakah anda mahu membuang semua penapis dari senarai?
-resethitcounts_warning=Adakah anda mahu reset semula pembilang hit semua penapis menjadi kosong? Operasi ini tidak boleh diundur!
-resethitcounts_selected_warning=Adakah anda mahu reset semula pembilang hit penapis yang dipilih menjadi kosong? Operasi ini tidak boleh diundur!
-filter_regexp_tooltip=Penapis ini hanya ungkapan biasa atau terlalu pendek untuk dioptimumkan. Terlalu banyak penapis mungkin akan melambatkan penjelajahan web.
-filter_elemhide_duplicate_id=Hanya satu ID elemen untuk disembunyikan boleh dinyatakan
-filter_elemhide_nocriteria=Tiada kriteria yang dinyatakan untuk mengenal pasti elemen untuk disembunyikan
-subscription_notAdded_warning=Anda belum lagi menambah langganan penapis. Tanpa langganan penapis anda perlu menambah penapis Adblock Plus secara manual.
-subscription_notAdded_warning_addendum=Adakah anda mahu mara?
-subscription_invalid_location=Lokasi senarai penapis sama ada URL atau nama fail adalah tidak sah.
-synchronize_invalid_url=Gagal, bukan alamat yang sah
-synchronize_connection_error=Gagal, kegagalan memuat-turun
-synchronize_invalid_data=Gagal, bukan senarai penapis yang sah
-synchronize_checksum_mismatch=Gagal, checksum tidak sepadan
-synchronize_ok=Berjaya
-overwrite=Tulis atas
-append=Lampirkan
-new_filter_group_title=Penapis baru
-type_label_other=lain
-type_label_script=skrip
-type_label_image=imej
-type_label_stylesheet=lembaran stail
-type_label_object=objek
-type_label_subdocument=bingkai
-type_label_document=dokumen
-type_label_elemhide=disembunyikan
-type_label_xbl=Ikatan XBL
-type_label_ping=pautan ping
-type_label_xmlhttprequest=permintaan XML
-type_label_object_subrequest=subpermintaan objek
-type_label_dtd=DTD
-type_label_media=audio/video
-type_label_font=font
-fennec_status_enabled=Adblock Plus telah diaktifkan
-fennec_status_disabled=Adblock Plus telah dinyahaktifkan
-fennec_status_enabled_site=Adblock Plus telah diaktifkan pada ?1?
-fennec_status_disabled_site=Adblock Plus telah dinyahaktifkan pada ?1?
-sync_engine_title=Data Adblock Plus
diff --git a/chrome/locale/ms-MY/meta.properties b/chrome/locale/ms-MY/meta.properties
deleted file mode 100644
index 8aa0b0e..0000000
--- a/chrome/locale/ms-MY/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=temperror
-name=Adblock Plus
-description=Iklan hanyalah zaman dulu!
-description.short=Menyampah dengan iklan? Risau mengenai tracking? Diganggu sepanduk? Pasanglah Adblock Plus untuk mendapatkan kembali kawalan ke atas internet and ubah cara anda melihat laman web.
-description.long=Adblock Plus membolehkan anda mendapatkan kembali kawalan ke atas internet dan cara anda melihat laman web. Add-on ini disokong oleh lebih empat puluh langganan dalam berbagai bahasa yang dapat menyediakannya untuk tujuan dari membuang iklan online hinggalah menyekat domain malware.
diff --git a/chrome/locale/nb-NO/.incomplete b/chrome/locale/nb-NO/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/nb-NO/about.dtd b/chrome/locale/nb-NO/about.dtd
deleted file mode 100644
index 3ce30b9..0000000
--- a/chrome/locale/nb-NO/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Om Adblock Plus">
-<!ENTITY version.title "Versjon">
-<!ENTITY description "Adblock Plus lar deg velge hva du ikke vil se på nettet. Nå trenger du ikke laste ned all reklamen lengre. Om du føler at du ikke vil det, så la Adblock Plus få vite det!">
-<!ENTITY homepage.label "Adblock Plus hjemmeside:">
-<!ENTITY author.label "Utgiver:">
-<!ENTITY contributors.label "Bidragsytere:">
diff --git a/chrome/locale/nb-NO/global.properties b/chrome/locale/nb-NO/global.properties
deleted file mode 100644
index c08d6f4..0000000
--- a/chrome/locale/nb-NO/global.properties
+++ /dev/null
@@ -1,52 +0,0 @@
-action0_tooltip=Trykk for å åpne menyen, trykk midtknapp for å Aktivere/Deaktivere.
-action1_tooltip=Trykk for å åpne/lukke elementer som kan blokkeres, trykk midtknapp for å Aktivere/Deaktivere.
-action2_tooltip=Trykk for å åpne innstillinger, trykk midtknapp for å Aktivere/Deaktivere.
-action3_tooltip=Trykk for å Aktivere/Deaktivere Adblock Plus.
-disabled_tooltip=Adblock Plus er deaktivert.
-whitelisted_tooltip=Adblock Plus er aktivert, men deaktivert på denne siden.
-blocked_count_tooltip=?1? av ?2?
-no_blocking_suggestions=Ingen elementer kan blokkeres på denne siden
-whitelisted_page=Adblock Plus har blitt deaktivert på denne siden
-whitelist_description=Unntaksregler
-filterlist_description=Reklamefiltre
-invalid_description=Ugyldige filtre
-elemhide_description=Regler for skjuling av elementer
-subscription_description=Filterabonnement:
-subscription_wrong_version=Noen filtre i dette abonnementet krever Adblock Plus for å virke!
-subscription_source=Kilde:
-subscription_status=Status:
-subscription_status_autodownload=Automatisk oppdatert
-subscription_status_manualdownload=Oppdatert manuelt
-subscription_status_externaldownload=Ekstern oppdatering (annet utvidelsesprogram)
-subscription_status_lastdownload=Siste nedlasting:
-subscription_status_lastdownload_inprogress=Laster ned...
-subscription_status_lastdownload_unknown=Ikke tilgjengelig
-remove_subscription_warning=Ãnsker du virkelig Ã¥ fjerne dette abonnementet?
-import_filters_wrong_version=Advarsel: Noen av filtrene i denne listen krever Adblock Plus for å virke. Du bør oppgradere til siste versjon av Adblock Plus før du importerer denne listen.
-import_filters_warning=Ãnsker du Ã¥ erstatte nÃ¥værende filtre eller legge nye filtre til i listen?
-import_filters_title=Importer filtre
-export_filters_title=Eksporter filtre
-invalid_filters_file=Denne filen inneholder ingen gyldige Adblock Plus filtre.
-filters_write_error=Det oppstod en feil ved skriving av filter til filen. Sjekk av filen ikke er skrivebeskyttet eller i bruk av et annet program.
-clearall_warning=Ãnsker du virkelig Ã¥ fjerne alle filtrene fra listen?
-resethitcounts_warning=Ãnsker du virkelig Ã¥ nullstille trefftelleren for alle filtre? Dette valget kan ikke bli omgjort!
-resethitcounts_selected_warning=Ãnsker du virkelig Ã¥ nullstille trefftelleren for valgte filtre? Dette valget kan ikke bli omgjort!
-subscription_invalid_location=Filterlisten du skrev inn har enten en ugyldig URL eller et ugyldig filnavn.
-synchronize_invalid_url=Mislykket, ikke en gyldig adresse
-synchronize_connection_error=Mislykket, feil i nedlasting
-synchronize_invalid_data=Mislykket, ikke en gyldig filterliste
-synchronize_ok=Vellykket
-overwrite=Skriv over
-append=Legg til
-type_label_other=annet
-type_label_script=skript
-type_label_image=bilde
-type_label_stylesheet=stilark
-type_label_object=objekt
-type_label_subdocument=ramme
-type_label_document=dokument
-type_label_elemhide=Skjult
-type_label_xbl=XBL tilknytning
-type_label_xmlhttprequest=XML anmodning
-type_label_object_subrequest=Objektanmodning
-type_label_dtd=DTD
diff --git a/chrome/locale/nb-NO/meta.properties b/chrome/locale/nb-NO/meta.properties
deleted file mode 100644
index 1ef4ec1..0000000
--- a/chrome/locale/nb-NO/meta.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-name=Adblock Plus
-description=Reklame er bare SÃ
i går!
diff --git a/chrome/locale/nb-NO/overlay.dtd b/chrome/locale/nb-NO/overlay.dtd
deleted file mode 100644
index e2a40bd..0000000
--- a/chrome/locale/nb-NO/overlay.dtd
+++ /dev/null
@@ -1,19 +0,0 @@
-<!ENTITY status.tooltip "Status:">
-<!ENTITY blocked.tooltip "Blokkerte elementer på denne siden:">
-<!ENTITY filters.tooltip "Mest aktive filtre:">
-<!ENTITY menuitem.label "Adblock Plus">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY context.image.label "Adblock Bilde">
-<!ENTITY context.object.label "Adblock Objekt">
-<!ENTITY context.frame.label "Adblock Ramme">
-<!ENTITY sidebar.title "Elementer som kan blokkeres på denne siden">
-<!ENTITY settings.label "Innstillinger">
-<!ENTITY settings.accesskey "t">
-<!ENTITY opensidebar.label "Ãpne elementer som kan blokkeres">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "Lukk elementer som kan blokkeres">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY whitelist.site.label "Deaktiver på ?1?">
-<!ENTITY whitelist.page.label "Deaktiver på denne siden">
-<!ENTITY objecttab.title "Blokkér">
-<!ENTITY objecttab.tooltip "Trykk her for å blokkere dette objektet med Adblock Plus">
diff --git a/chrome/locale/nb-NO/settings.dtd b/chrome/locale/nb-NO/settings.dtd
deleted file mode 100644
index 34eaf86..0000000
--- a/chrome/locale/nb-NO/settings.dtd
+++ /dev/null
@@ -1,65 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus Innstillinnger">
-<!ENTITY filters.label "Filtre">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Legg til filter">
-<!ENTITY add.accesskey "t">
-<!ENTITY addsubscription.label "Legg til filterabonnement">
-<!ENTITY addsubscription.accesskey "f">
-<!ENTITY synchsubscriptions.label "Oppdater alle abonnementer">
-<!ENTITY synchsubscriptions.accesskey "D">
-<!ENTITY import.label "Importer filtre">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.label "Eksporter filtre">
-<!ENTITY export.accesskey "k">
-<!ENTITY clearall.label "Fjern alle filtre">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "Tilbakestill statistikk for filtre">
-<!ENTITY resethitcounts.accesskey "b">
-<!ENTITY edit.label "Rediger">
-<!ENTITY edit.accesskey "R">
-<!ENTITY cut.label "Klipp ut">
-<!ENTITY cut.accesskey "u">
-<!ENTITY copy.label "Kopier">
-<!ENTITY copy.accesskey "K">
-<!ENTITY paste.label "Lim inn">
-<!ENTITY paste.accesskey "L">
-<!ENTITY remove.label "Slett">
-<!ENTITY remove.accesskey "t">
-<!ENTITY menu.find.label "Søk">
-<!ENTITY menu.find.accesskey "S">
-<!ENTITY menu.findagain.label "Søk igjen">
-<!ENTITY menu.findagain.accesskey "ø">
-<!ENTITY options.label "Valg">
-<!ENTITY options.accesskey "V">
-<!ENTITY enable.label "Aktiver Adblock Plus">
-<!ENTITY enable.accesskey "l">
-<!ENTITY showintoolbar.label "Vis i verkøylinje">
-<!ENTITY showintoolbar.accesskey "V">
-<!ENTITY showinstatusbar.label "Vis i statuslinje">
-<!ENTITY showinstatusbar.accesskey "t">
-<!ENTITY objecttabs.label "Vis fliker på Flash og Java">
-<!ENTITY objecttabs.accesskey "f">
-<!ENTITY collapse.label "Kollaps blokkerte elementer">
-<!ENTITY collapse.accesskey "p">
-<!ENTITY help.label "Hjelp">
-<!ENTITY help.accesskey "H">
-<!ENTITY faq.label "Hyppig stilte spørsmål">
-<!ENTITY faq.accesskey "H">
-<!ENTITY filterdoc.label "Opprett Adblock Plus filtre">
-<!ENTITY filterdoc.accesskey "R">
-<!ENTITY about.label "Om Adblock Plus">
-<!ENTITY about.accesskey "O">
-<!ENTITY description "Legg til adressene du vil blokkere. For forslag, se rullegardinlisten. Du kan bruke * som jokertegn for å lage mer dekkende filtre. Avanserte brukere kan bruke uttrykk som /banner\d+\.gif$/.">
-<!ENTITY enabled.column "Aktivert">
-<!ENTITY hitcount.column "Treff">
-<!ENTITY lasthit.column "Siste treff">
-<!ENTITY context.edit.label "Endre filter">
-<!ENTITY context.resethitcount.label "Nullstill all treffstatistikk for filtre">
-<!ENTITY context.synchsubscription.label "Oppdater abonnementer">
-<!ENTITY context.editsubscription.label "Endre abonnement">
-<!ENTITY context.moveup.label "Flytt opp">
-<!ENTITY context.movedown.label "Flytt ned">
-<!ENTITY context.movegroupup.label "Flytt gruppe opp">
-<!ENTITY context.movegroupdown.label "Flytt gruppe ned">
-<!ENTITY apply.label "Bruk">
-<!ENTITY apply.accesskey "B">
diff --git a/chrome/locale/nb-NO/sidebar.dtd b/chrome/locale/nb-NO/sidebar.dtd
deleted file mode 100644
index 6cd001a..0000000
--- a/chrome/locale/nb-NO/sidebar.dtd
+++ /dev/null
@@ -1,22 +0,0 @@
-<!ENTITY detached.title "Adblock Plus: Elementer som kan blokkeres (frittstående)">
-<!ENTITY detach.label "Kople fra">
-<!ENTITY reattach.label "Kople til">
-<!ENTITY search.label "Søk:">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "Type">
-<!ENTITY address.label "Adresse">
-<!ENTITY filter.label "Filter">
-<!ENTITY state.label "status">
-<!ENTITY noitems.label "Ingen elementer som kan blokkeres">
-<!ENTITY whitelisted.label "Hvitlistet side">
-<!ENTITY tooltip.address.label "Adresse:">
-<!ENTITY tooltip.type.label "Type:">
-<!ENTITY tooltip.type.blocked "(blokkert)">
-<!ENTITY tooltip.type.whitelisted "(hvitlistet)">
-<!ENTITY tooltip.filter.label "Filtre i bruk">
-<!ENTITY context.block.label "Blokker dette elementet">
-<!ENTITY context.editfilter.label "Endre filtre i bruk">
-<!ENTITY context.whitelist.label "Legg til unntak for elementer">
-<!ENTITY context.open.label "Ã
pne i ny flik">
-<!ENTITY context.flash.label "La kantene på elementer blinke">
-<!ENTITY context.copy.label "Kopier elementets adresse">
diff --git a/chrome/locale/nb-NO/subscriptionSelection.dtd b/chrome/locale/nb-NO/subscriptionSelection.dtd
deleted file mode 100644
index 8a9ef82..0000000
--- a/chrome/locale/nb-NO/subscriptionSelection.dtd
+++ /dev/null
@@ -1,9 +0,0 @@
-<!ENTITY dialog.title.edit "Endre abonnement på filter">
-<!ENTITY other.label "Legg til abonnement">
-<!ENTITY other.accesskey "T">
-<!ENTITY title.label "Navn på abonnement:">
-<!ENTITY title.accesskey "v">
-<!ENTITY location.label "Adresse til filterliste:">
-<!ENTITY location.accesskey "d">
-<!ENTITY autodownload.label "Automatisk oppdatering">
-<!ENTITY autodownload.accesskey "t">
diff --git a/chrome/locale/nl/meta.properties b/chrome/locale/nl/meta.properties
deleted file mode 100644
index 4c96d83..0000000
--- a/chrome/locale/nl/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=pitdicker, markh
-name=Adblock Plus
-description=Reclames behoren tot het verleden!
-description.short=Irritante reclames? Hinder van volgers? Altijd die banners? Installeer Adblock Plus nu om internet weer onder controle te krijgen en uw webervaring te veranderen.\n\nEen korte video is te zien op http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Met Adblock Plus kunt u internet weer onder controle krijgen en het web bekijken op de manier zoals u dat wilt. De add-on wordt ondersteund door meer dan veertig filterabonnementen in tientallen talen, die de extensie automatisch instellen voor doeleinden variërend van het verwijderen van online-advertenties to het blokkeren van alle bekende malwaredomeinen. Met Adblock Plus kunt u ook uw filters aanpassen met behulp van een reeks nuttige functies, inclusief een contextoptie voor afbeeldingen, een blokkeringstabblad voor Flash- en Java-objecten en een lijst met blokkeerbare items om scripts en stylesheets te verwijderen.
diff --git a/chrome/locale/nn-NO/.incomplete b/chrome/locale/nn-NO/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/nn-NO/about.dtd b/chrome/locale/nn-NO/about.dtd
deleted file mode 100644
index 0f3a216..0000000
--- a/chrome/locale/nn-NO/about.dtd
+++ /dev/null
@@ -1,9 +0,0 @@
-<!ENTITY dialog.title "Om Adblock Plus">
-<!ENTITY version.title "Versjon">
-<!ENTITY description "
- Adblock Plus lar deg avgjere kva du ikkje vil sjå på nettet.
- No treng du ikkje lenger Ã¥ laste ned all reklamen, om du ikkje vil ha den – sei det til Adblock Plus!
-">
-<!ENTITY homepage.label "Adblock Plus heimeside:">
-<!ENTITY author.label "Forfattar:">
-<!ENTITY contributors.label "Bidragsytarar:">
diff --git a/chrome/locale/nn-NO/composer.dtd b/chrome/locale/nn-NO/composer.dtd
deleted file mode 100644
index 4753ff1..0000000
--- a/chrome/locale/nn-NO/composer.dtd
+++ /dev/null
@@ -1,38 +0,0 @@
-<!ENTITY dialog.title "Legg til regel for Adblock Plus filter">
-<!ENTITY accept.label "Legg til filter">
-<!ENTITY advanced.label "Avansert vising">
-<!ENTITY basic.label "Grunnleggjande vising">
-<!ENTITY disabled.warning "Adblock Plus er kopla ut. Du kan like vel leggje til filtre, men desse vil ikkje bli tekne i bruk dersom du ikkje [link]koplar inn Adblock Plus[/link].">
-<!ENTITY filter.label "Nytt filter:">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "Syn filter...">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "Blokker filter">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Unntaksregel">
-<!ENTITY type.whitelist.accesskey "U">
-<!ENTITY pattern.label "Sjå etter mønster">
-<!ENTITY pattern.explanation "Mønsteret kan vera ein kvar del av adressa, bruk *-symbolet som jokerteikn. Filterert blir berre nytta på adressar som stemmer med mønsteret.">
-<!ENTITY regexp.warning "Mønsteret du la inn blir tolka som eit regulært uttrykk. Ã
ha mange regulære uttrykk kan gjera nettlesinga treig. Dersom du ikkje har tenkt til å nytte regulære uttrykk så sett eit *-symbol sist i mønsteret.">
-<!ENTITY custom.pattern.accesskey "C">
-<!ENTITY anchor.start.accesskey "g">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "Options">
-<!ENTITY domainRestriction.label "Restrict to domain:">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "Specify one or more domains separated by the symbol "|", the filter will only be applied on these domains then. The symbol "~" before a domain name means that the filter should not be applied on that domain.">
-<!ENTITY firstParty.label "First-party only">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "Third-party only">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.label "Match case">
-<!ENTITY matchCase.accesskey "M">
-<!ENTITY types.label "Apply to types:">
-<!ENTITY selectAllTypes.label "Select all">
-<!ENTITY unselectAllTypes.label "Select none">
-<!ENTITY collapse.label "Collapse blocked:">
-<!ENTITY collapse.accesskey "l">
-<!ENTITY collapse.default.yes.label "Use default (yes)">
-<!ENTITY collapse.default.no.label "Use default (no)">
-<!ENTITY collapse.yes.label "Yes">
-<!ENTITY collapse.no.label "No">
diff --git a/chrome/locale/pa-IN/.incomplete b/chrome/locale/pa-IN/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/pa-IN/about.dtd b/chrome/locale/pa-IN/about.dtd
deleted file mode 100644
index 34e9a74..0000000
--- a/chrome/locale/pa-IN/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus ਦ੠ਬਾਰà©">
-<!ENTITY version.title "Version">
-<!ENTITY description "Adblock Plus ਤà©à¨¹à¨¾à¨¨à©">
-<!ENTITY homepage.label "Adblock Plus ਹà©à¨® ਪà©à¨">
-<!ENTITY author.label "ਲà©à¨à¨">
-<!ENTITY subscriptionAuthors.label "ਫਿਲà¨à¨° ਸਬਸà©à¨à©à¨°à¨¿à¨ªà©à¨¶à¨¨ ਦ੠ਲà©à¨à¨">
diff --git a/chrome/locale/pa-IN/composer.dtd b/chrome/locale/pa-IN/composer.dtd
deleted file mode 100644
index 4deb785..0000000
--- a/chrome/locale/pa-IN/composer.dtd
+++ /dev/null
@@ -1,10 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus ਵਿਠਨਵਾਠਫਿਲà¨à¨° ਰà©à¨² ਪਾà¨">
-<!ENTITY accept.label "ਨਾਵਾਨ ਫਿਲà¨à¨°">
-<!ENTITY advanced.label "à¨
ਡਵਾà¨à¨¸à¨¡ ਵਿਯà©">
-<!ENTITY basic.label "ਬà©à¨¸à¨¿à¨ ਵਿਯà©">
-<!ENTITY disabled.warning "Adblock Plus à¨à¨¸ ਸਮà©à¨ à¨à¨¾à¨²à© ਨਹà©à¨ ਹ੠| ਤà©à¨¸à©à¨ ਹਾਲ੠ਵ੠ਨਵà©à¨ ਫਿਲà¨à¨° ਪਾ ਸà¨à¨¦à© ਹ੠ਪਰ à¨à¨¹ à¨à¨¦à©à¨ ਤਠਨਹà©à¨ à¨à¨²à¨¨à¨à© à¨à¨¦ ਤਦ ਤà©à¨¸à©à¨ ਫà©à¨° [link]Adblock Plus à¨à¨¾à¨²à© ਨਹà©à¨ à¨à¨°à¨¦à©[/link] |">
-<!ENTITY groupDisabled.warning ""?1?" ਫਿਲà¨à¨° à¨à¨°à©à¨ª à¨à¨¿à¨¸ ਵਿਠà¨à¨¹ ਫਿਲà¨à¨° ਪਾà¨à¨ à¨à¨¾à¨à¨à¨¾ à¨à¨¸ ਸਾਮਠਬੰਦ à¨à¨¾à¨²à© ਨਹà©à¨ ਹ੠| ਤà©à¨¸à©à¨ ਹਾਲ੠ਵ੠ਫਿਲà¨à¨° ਪਾ ਸà¨à¨¦à© ਹ੠ਹ੠ਪਰ à¨à¨¹ à¨à¨¸ ਸਮà©à¨ ਤਠà¨à¨à¨¾à¨²à© ਨਹà©à¨ ਹà©à¨µà©à¨à¨¾ à¨à¨¦ ਤਠਤà©à¨¸à©à¨ [link] ਫਿਲà¨à¨° à¨à¨°à©à¨ª à¨à¨¾à¨²à© ਨਹà©à¨ à¨à¨°à¨¦à© [/link] |">
-<!ENTITY filter.label "ਨਵਾਠਫਿਲà¨à¨°">
-<!ENTITY filter.accesskey "ਫ">
-<!ENTITY preferences.accesskey "ਸ">
-<!ENTITY type.filter.accesskey "ਬ">
diff --git a/chrome/locale/pl/meta.properties b/chrome/locale/pl/meta.properties
deleted file mode 100644
index e02937c..0000000
--- a/chrome/locale/pl/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Leszek(teo)Życzkowski
-name=Adblock Plus
-description=Powiedz NIE! reklamom
-description.short=Masz doÅÄ oglÄ
dania denerwujÄ
cych reklam i banerów, które dodatkowo wydÅużajÄ
wczytywanie stron? Zainstaluj Adblock Plus i uwolnij siÄ od nich!\n\nKrótkie wideo opisujÄ
ce instalacjÄ znajduje siÄ tutaj: http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=DziÄki rozszerzeniu Adblock Plus odzyskasz kontrolÄ nad Internetem i bÄdziesz móc przeglÄ
daÄ strony tak, jak chcesz. Dodatek jest wspierany przez ponad 40 możliwych do subskrybowania zestawów filtrów dostosowanych do różnych obszarów jÄzykowych. Filtry te automatycznie konfigurujÄ
Adblock Plus do różnych zadaÅ, poczÄ
wszy od usuwania reklam internetowych do blokowania wszystkich znanych domen ze zÅoÅliwym oprogramowaniem. Rozszerzenie umożliwia także rÄczne dostosowywanie filtrów, udostÄpniajÄ
c wiele przydatnych do tego celu funkcji takich, jak funkcje blokowania obrazków dostÄpne z poziomu menu kontekstowego, blokowania kart dla Flasha i obiektów Java oraz listÄ blokowalnych elementów sÅużÄ
cÄ
do usuwania skryptów i arkuszy stylów.
diff --git a/chrome/locale/pt-BR/meta.properties b/chrome/locale/pt-BR/meta.properties
deleted file mode 100644
index 2c07d01..0000000
--- a/chrome/locale/pt-BR/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Teboga, Mauro José da Silva
-name=Adblock Plus
-description=Propaganda indesejada é coisa do passado!
-description.short=Chateado com as propagandas? Incomodado com o rastreamento? Irritado com os banners? Instale agora o Adblock Plus para recuperar o controle da internet e mudar a maneira como você vê a web.
-description.long=O Adblock Plus permite que você recupere o controle da internet e veja a web do jeito que você quer. Esta extensão é suportada por mais de quarenta inscrições de filtros em diversos idiomas que a configuram automaticamente para fins que vão desde a remoção de publicidade online até o bloqueio de todos os domÃnios conhecidos de malware. O Adblock Plus também permite personalizar os filtros através de uma variedade de ferramentas úteis tais como: uma opção no menu de contexto das imagens, uma aba bloqueadora nos objetos de Flash e Java, uma lista de itens bloqueáveis para remover scripts e folhas de estilo.
diff --git a/chrome/locale/pt-PT/meta.properties b/chrome/locale/pt-PT/meta.properties
deleted file mode 100644
index cf82ce8..0000000
--- a/chrome/locale/pt-PT/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Raul Pimentel
-name=Adblock Plus
-description=Publicidade... já era!
-description.short=Aborrecido pelos anúncios? Incomodado pela monitorização? Incomodado por banners? Instale o Adblock Plus agora para recuperar o controle da internet e mudar a maneira como vê a web.\n\nResumo em http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=O Adblock Plus permite que recupere o controlo da internet e visualizar a web da maneira que quer. A extensão é suportada por mais de quarenta subscrições de filtro em dezenas de idiomas, que a configuram automaticamente para fins que vão desde a remoção de publicidade online até o bloqueio de todos os domÃnios conhecidos de malware. O Adblock Plus também permite que personalize os filtros com o auxÃlio de uma variedade de recursos úteis, incluindo uma opção de contexto para as imagens, um separador para Flash e objectos Java, e uma lista de itens bloqueáveis para remover scripts e folhas de estilo.
diff --git a/chrome/locale/ro/meta.properties b/chrome/locale/ro/meta.properties
deleted file mode 100644
index 6a1d26f..0000000
--- a/chrome/locale/ro/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=ultravioletu
-name=Adblock Plus
-description=EliminÄ publicitatea din paginile web.
-description.short=EÅti iritat de publicitate? Te enerveazÄ banerele? InstaleazÄ Adblock Plus pentru a recâÅtiga controlul asupra internetului.\n\n\PoÅ£i viziona în prealabil o prezentare scurtÄ http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus permite recâÅtigarea controlului asupra internetului Åi influenÅ£area felul în care paginile vizitate sunt vizualizate. Suplimentul este menÅ£inut Åi cu ajutorul a peste 40 de abonamente de filtre, care îl configureazÄ automat cu scopuri diverse, de la înlÄturarea banerelor publicitare pânÄ la blocarea domeniilor rÄu-intenÅ£ionate. Adblock Plus permite utilizatorului configurarea filtrelor proprii folosind diverse unelte de asistenÅ£Ä, ca de exemplu meniu contextual pentru imagini, tab pentru obiecte Flash Åi Java sau listÄ de elemente blocabile pentru scripturi Åi stiluri CSS.
diff --git a/chrome/locale/ru/about.dtd b/chrome/locale/ru/about.dtd
deleted file mode 100644
index 951cee6..0000000
--- a/chrome/locale/ru/about.dtd
+++ /dev/null
@@ -1,15 +0,0 @@
-<!ENTITY dialog.title "Ð Adblock Plus">
-
-<!ENTITY version.title "ÐеÑÑиÑ">
-<!ENTITY description "
- С Adblock Plus Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе Ñами ÑеÑаÑÑ, ÑÑо Ð²Ñ Ñ
оÑиÑе видеÑÑ Ð² инÑеÑнеÑе,
- а ÑÑо - неÑ. Ðе нÑжно болÑÑе ÑÑаÑиÑÑ Ñвое вÑÐµÐ¼Ñ Ð½Ð° ÑкаÑивание ÑекламнÑÑ
- баннеÑов, еÑли Ð²Ñ Ð½Ðµ Ñ
оÑиÑе иÑ
видеÑÑ - Adblock Plus вам поможеÑ!
-">
-
-<!ENTITY homepage.label "ÐомаÑнÑÑ ÑÑÑаниÑа пÑоекÑа:">
-<!ENTITY author.label "РазÑабоÑÑик:">
-<!ENTITY contributors.label "ÐÑÑгие ÑÑаÑÑники:">
-
-<!ENTITY subscriptionAuthors.label "ÐвÑоÑÑ ÑпиÑков ÑилÑÑÑов:">
-<!ENTITY translators.label "ÐеÑеводÑики:">
diff --git a/chrome/locale/ru/meta.properties b/chrome/locale/ru/meta.properties
deleted file mode 100644
index 53c14cb..0000000
--- a/chrome/locale/ru/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Wladimir Palant
-name=Adblock Plus
-description=Скажи "неÑ" Ñекламе!
-description.short=Ðадоела Ñеклама? ТоÑÐ¼Ð¾Ð·Ð¸Ñ Ð¸Ð½ÑеÑнеÑ? СлиÑком много баннеÑов? УÑÑанови Adblock Plus, ÑÑÐ¾Ð±Ñ Ð²ÐµÑнÑÑÑ Ñебе конÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ инÑеÑнеÑом и видеÑÑ Ð»Ð¸ÑÑ Ñо, ÑÑо Ñ
оÑеÑÑÑ.
-description.long=Adblock Plus даÑÑ Ð²Ð°Ð¼ веÑнÑÑÑ Ñебе конÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ инÑеÑнеÑом и видеÑÑ ÐµÐ³Ð¾ Ñаким, как Ñ
оÑеÑÑÑ Ð²Ð°Ð¼. ÐÐ»Ñ ÑаÑÑиÑÐµÐ½Ð¸Ñ ÑÑÑеÑÑвÑÐµÑ Ð±Ð¾Ð»ÐµÐµ ÑоÑока ÑпиÑков ÑилÑÑÑов Ð´Ð»Ñ Ð´ÐµÑÑÑков ÑзÑков, коÑоÑÑе авÑомаÑиÑеÑки наÑÑÑоÑÑ ÐµÐ³Ð¾ Ð´Ð»Ñ ÑазлиÑнÑÑ
Ñелей, Ð¾Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки ÑÐµÐºÐ»Ð°Ð¼Ñ Ð´Ð¾ блокиÑовки вÑеÑ
извеÑÑнÑÑ
опаÑнÑÑ
доменов. Adblock Plus Ñакже Ð¿Ð¾Ð·Ð²Ð¾Ð»Ð¸Ñ Ð²Ð°Ð¼ добавлÑÑÑ ÑобÑÑвеннÑе ÑилÑÑÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÑазлиÑнÑÑ
полезнÑÑ
инÑÑÑÑменÑов, вклÑÑÐ°Ñ ÐºÐ¾Ð½ÑекÑÑное Ð¼ÐµÐ½Ñ Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки каÑÑинок, ÑÑлÑк Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÐ¸Ñовки Flash-Ñоликов и Java-апплеÑов и ÑпиÑок ÑлеменÑов Ð´Ð»Ñ ÑÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ð½ÐµÐ²Ð¸Ð´Ð¸Ð¼ÑÑ
ÑлеменÑов (к пÑимеÑÑ, ÑкÑипÑов или ÑÑилей).
diff --git a/chrome/locale/ru/sendReport.dtd b/chrome/locale/ru/sendReport.dtd
deleted file mode 100644
index 8a33111..0000000
--- a/chrome/locale/ru/sendReport.dtd
+++ /dev/null
@@ -1,178 +0,0 @@
-<!ENTITY wizard.title "СообÑиÑÑ Ð¾ пÑоблеме">
-<!ENTITY privacyPolicy.label "ÐÑавила конÑиденÑиалÑноÑÑи">
-
-<!ENTITY dataCollector.heading "ÐобÑо пожаловаÑÑ Ð² маÑÑÐµÑ Ð¾ÑпÑавки ÑообÑениÑ">
-<!ENTITY dataCollector.description "ÐожалÑйÑÑа, подождиÑе неÑколÑко ÑекÑнд, пока Adblock Plus ÑобиÑÐ°ÐµÑ Ð½ÑжнÑе даннÑе.">
-
-<!-- Please keep typeSelector.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY typeSelector.heading "ÐÑÐ±Ð¾Ñ Ñипа пÑоблемÑ">
-
-<!ENTITY typeSelector.description "
- ÐаÑÑÐµÑ Ð¿Ð¾Ð¼Ð¾Ð¶ÐµÑ Ð²Ð°Ð¼ оÑпÑавиÑÑ ÑообÑение о пÑоблеме Ñ Adblock Plus.
- ÐожалÑйÑÑа, ÑкажиÑе на ÑÑой ÑÑÑаниÑе Ñип пÑоблемÑ, Ñ ÐºÐ¾ÑоÑой Ð²Ñ ÑÑолкнÑлиÑÑ:
-">
-
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus блокиÑÑÐµÑ ÑлиÑком многое">
-<!ENTITY typeSelector.falsePositive.accesskey "м">
-<!ENTITY typeSelector.falsePositive.description "
- ÐÑли на ÑÑÑаниÑе оÑÑÑÑÑÑвÑÑÑ Ð²Ð°Ð¶Ð½Ñе ÑаÑÑи ÑодеÑжимого, а Ñакже еÑли она
- оÑобÑажаеÑÑÑ Ð¸Ð»Ð¸ ÑÑнкÑиониÑÑÐµÑ Ð½ÐµÐ¿ÑавилÑно, Ñо ÑледÑÐµÑ Ð²ÑбÑаÑÑ ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
- ÐÑ Ð¼Ð¾Ð¶ÐµÑе пÑовеÑиÑÑ, ÑвлÑеÑÑÑ Ð»Ð¸ Adblock Plus иÑÑоÑником пÑоблемÑ, вÑеменно
- оÑклÑÑив его.
-">
-
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus не блокиÑÑÐµÑ ÑекламÑ">
-<!ENTITY typeSelector.falseNegative.accesskey "Ñ">
-<!ENTITY typeSelector.falseNegative.description "
- ÐÑли неÑмоÑÑÑ Ð½Ð° Ñо, ÑÑо Adblock Plus вклÑÑен, на ÑÑÑаниÑе оÑобÑажаеÑÑÑ Ñеклама,
- Ñо ÑледÑÐµÑ Ð²ÑбÑаÑÑ ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
-">
-
-<!ENTITY typeSelector.other.label "ÐÑÑÐ³Ð°Ñ Ð¿Ñоблема">
-<!ENTITY typeSelector.other.accesskey "Ð">
-<!ENTITY typeSelector.other.description "
- ÐÑли Ð²Ñ Ð¿Ð¾Ð´Ð¾Ð·ÑеваеÑе, ÑÑо пÑоблема в Ñамом ÑаÑÑиÑении Adblock Plus,
- а не в его ÑилÑÑÑаÑ
, Ñо вÑбеÑиÑе ÑÑÐ¾Ñ Ð²Ð°ÑианÑ.
-">
-
-<!ENTITY showRecentReports.label "ÐоказаÑÑ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ оÑпÑавленнÑе ÑообÑениÑ">
-<!ENTITY recentReports.label "ÐаÑи недавно оÑпÑавленнÑе ÑообÑениÑ">
-<!ENTITY recentReports.clear.label "УдалиÑÑ Ð²Ñе ÑообÑениÑ">
-<!ENTITY recentReports.clear.accesskey "л">
-
-<!ENTITY issues.description "
- Adblock Plus обнаÑÑжил пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð² ваÑиÑ
наÑÑÑойкаÑ
, коÑоÑÑе, возможно, вÑзвали
- даннÑÑ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð¸Ð»Ð¸ ÑÑложнÑÑ ÑаÑÑмоÑÑение ваÑего ÑообÑениÑ.
-">
-
-<!ENTITY issues.whitelist.description "
- Adblock Plus оÑклÑÑен на ÑÑÑаниÑе, о коÑоÑой Ð²Ñ ÑобиÑаеÑеÑÑ ÑообÑиÑÑ. ÐожалÑйÑÑа,
- вклÑÑиÑе Adblock Plus и обновиÑе ÑÑÑаниÑÑ, пÑежде Ñем поÑÑлаÑÑ ÑообÑение.
- ÐÑо Ð¿Ð¾Ð¼Ð¾Ð¶ÐµÑ ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ Ð²Ð°Ñего ÑообÑениÑ.
-">
-<!ENTITY issues.whitelist.remove.label "ÐклÑÑиÑÑ Adblock Plus на ÑÑой ÑÑÑаниÑе">
-
-<!ENTITY issues.disabled.description "
- Adblock Plus оÑклÑÑен и ниÑего не блокиÑÑÐµÑ Ð² ÑÑом ÑоÑÑоÑнии.
-">
-<!ENTITY issues.disabled.enable.label "ÐклÑÑиÑÑ Adblock Plus">
-
-<!ENTITY issues.nofilters.description "
- Adblock Plus ниÑего не блокиÑÑÐµÑ Ð½Ð° ÑÑой ÑÑÑаниÑе. СкоÑее вÑего, пÑоблема,
- коÑоÑÑÑ Ð²Ñ Ð½Ð°Ð±Ð»ÑдаеÑе, не ÑвÑзана Ñ Adblock Plus.
-">
-
-<!ENTITY issues.nosubscriptions.description "
- ÐÑ Ð½Ðµ подпиÑÐ°Ð½Ñ Ð½Ð¸ на один из гоÑовÑÑ
ÑпиÑков ÑилÑÑÑов, коÑоÑÑе авÑомаÑиÑеÑки
- блокиÑÑÑÑ Ð½ÐµÐ¶ÐµÐ»Ð°ÑелÑнÑе ÑлеменÑÑ ÑÑÑаниÑ.
-">
-<!ENTITY issues.nosubscriptions.add.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
-
-<!ENTITY issues.subscriptionCount.description "
- ÐоÑ
оже, ÑÑо Ð²Ñ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐ°Ð½Ñ Ð½Ð° ÑлиÑком болÑÑое колиÑеÑÑво ÑпиÑков ÑилÑÑÑов. ÐÑо
- не ÑекомендÑеÑÑÑ, поÑколÑÐºÑ ÑилÑно возÑаÑÑÐ°ÐµÑ Ð²ÐµÑоÑÑноÑÑÑ Ð¿Ñоблем. Ðомимо
- ÑÑого, Ð¼Ñ Ð½Ðµ можем пÑинÑÑÑ Ð²Ð°Ñе ÑообÑение, поÑколÑÐºÑ Ð½ÐµÑÑно, какой из ÑпиÑков
- ÑилÑÑÑов нÑжно иÑпÑавлÑÑÑ. ÐожалÑйÑÑа, ÑдалиÑе вÑе ÑпиÑки ÑилÑÑÑов кÑоме
- дейÑÑвиÑелÑно нÑжнÑÑ
. ÐоÑле ÑÑого пÑовеÑÑÑе, пÑоÑвлÑеÑÑÑ Ð»Ð¸ еÑе пÑоблема.
-">
-<!ENTITY issues.openPreferences.label "ÐÑкÑÑÑÑ Ð½Ð°ÑÑÑойки ÑилÑÑÑов">
-
-<!ENTITY issues.ownfilters.description "
- ÐекоÑоÑÑе ÑилÑÑÑÑ, коÑоÑÑе пÑименÑÑÑÑÑ Ð½Ð° ÑÑой ÑÑÑаниÑе, Ð²Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ð»Ð¸ Ñами.
- ÐожалÑйÑÑа, оÑклÑÑиÑе ÑилÑÑÑÑ, коÑоÑÑе могли вÑзваÑÑ ÑÑÑ Ð¿ÑоблемÑ:
-">
-<!ENTITY issues.ownfilters.disable.label "ÐÑклÑÑиÑÑ ÑилÑÑÑ">
-
-<!ENTITY issues.disabledgroups.description "
- СледÑÑÑие подпиÑки / гÑÑÐ¿Ð¿Ñ ÑилÑÑÑов оÑклÑÑенÑ, но могли Ð±Ñ Ð¿Ð¾Ð²Ð»Ð¸ÑÑÑ Ð½Ð° ÑÑÑ ÑÑÑаниÑÑ:
-">
-<!ENTITY issues.disabledgroups.enable.label "ÐклÑÑиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ / гÑÑÐ¿Ð¿Ñ ÑилÑÑÑов">
-
-<!ENTITY issues.disabledfilters.description "
- СледÑÑÑие ÑилÑÑÑÑ Ð¾ÑклÑÑенÑ, но могли Ð±Ñ Ð¿Ð¾Ð²Ð»Ð¸ÑÑÑ Ð½Ð° ÑÑÑ ÑÑÑаниÑÑ:
-">
-<!ENTITY issues.disabledfilters.enable.label "ÐклÑÑиÑÑ ÑилÑÑÑ">
-
-<!ENTITY issues.override.label "ÐаÑÑÑойки в поÑÑдке, пÑодолжиÑÑ Ð¾ÑпÑавление ÑообÑениÑ">
-<!ENTITY issues.override.accesskey "п">
-<!ENTITY issues.change.description "
- ÐаÑи наÑÑÑойки изменилиÑÑ. ÐожалÑйÑÑа, обновиÑе ÑÑÑаниÑÑ Ð´Ð»Ñ Ð¿ÑовеÑки
- внеÑеннÑÑ
изменений и оÑпÑавÑÑе ÑообÑение, еÑли пÑоблема не ÑазÑеÑилаÑÑ.
-">
-
-<!ENTITY typeWarning.description "
- ÐÑ Ñказали, ÑÑо Ñ
оÑиÑе ÑообÑиÑÑ Ð¾ пÑоблеме в Adblock Plus, а не в его ÑилÑÑÑаÑ
.
- ÐожалÑйÑÑа, ÑÑÑиÑе, ÑÑо о ÑакиÑ
пÑоблемаÑ
лÑÑÑе ÑообÑаÑÑ Ð½Ð°
- [link]ÑоÑÑме Adblock Plus[/link]. ÐаÑÑÐµÑ Ð¾ÑпÑавки ÑообÑÐµÐ½Ð¸Ñ ÑледÑеÑ
- иÑполÑзоваÑÑ Ð»Ð¸ÑÑ Ð´Ð»Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð¸Ð½ÑоÑмаÑии к обÑÑÐ¶Ð´ÐµÐ½Ð¸Ñ Ð½Ð° ÑоÑÑме, поÑколÑкÑ
- никÑо не ÑÐ²Ð¸Ð´Ð¸Ñ Ð²Ð°Ñе ÑообÑение, еÑли не оÑÑавиÑÑ Ð½Ð° него ÑÑÑлкÑ. ÐÑ
- полÑÑиÑе авÑомаÑиÑеÑки ÑозданнÑÑ ÑÑÑÐ»ÐºÑ Ð¿Ð¾Ñле оÑпÑавки ÑообÑениÑ.
-">
-
-<!ENTITY typeWarning.override.label "Я понÑл и, Ñем не менее, Ñ
оÑÑ Ð¾ÑпÑавиÑÑ ÑообÑение">
-<!ENTITY typeWarning.override.accesskey "п">
-
-<!ENTITY reloadButton.label "ÐбновиÑÑ ÑÑÑаниÑÑ">
-<!ENTITY reloadButton.accesskey "н">
-
-<!-- Please keep screenshot.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY screenshot.heading "Снимок ÑкÑана">
-
-<!ENTITY screenshot.description "
- Ðдна и Ñа же ÑÑÑаниÑа Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ Ð¿Ð¾-ÑÐ°Ð·Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÑазнÑÑ
лÑдей. Снимок ÑкÑана
- Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð½Ð°Ð¼ понÑÑÑ Ð¿ÑоблемÑ. ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑдалиÑÑ ÐºÐ¾Ð½ÑиденÑиалÑнÑе ÑаÑÑи Ñнимка
- или помеÑиÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ñнимка, в коÑоÑой пÑоÑвлÑеÑÑÑ Ð¿Ñоблема. ÐÐ»Ñ ÑÑого
- нажмиÑе на ÑооÑвеÑÑÑвÑÑÑÑÑ ÐºÐ½Ð¾Ð¿ÐºÑ Ð¸ вÑбеÑиÑе мÑÑкой ÑаÑÑÑ Ñнимка.
-">
-
-<!ENTITY screenshot.attach.label "ÐÑикÑепиÑÑ Ñнимок ÑкÑана к ÑообÑениÑ">
-<!ENTITY screenshot.attach.accesskey "к">
-<!ENTITY screenshot.mark.label "ÐомеÑиÑÑ Ð¿ÑоблемÑ">
-<!ENTITY screenshot.mark.accesskey "п">
-<!ENTITY screenshot.remove.label "УдалиÑÑ ÐºÐ¾Ð½ÑиденÑиалÑнÑе даннÑе">
-<!ENTITY screenshot.remove.accesskey "д">
-<!ENTITY screenshot.undo.label "ÐÑмениÑÑ">
-<!ENTITY screenshot.undo.accesskey "Ð">
-
-<!-- Please keep commentPage.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY commentPage.heading "ÐомменÑаÑий">
-
-<!ENTITY commentPage.description "
- ÐÐ½Ð¸Ð·Ñ Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе добавиÑÑ ÐºÐ¾Ð¼Ð¼ÐµÐ½ÑаÑий, ÑÑÐ¾Ð±Ñ Ð¿Ð¾Ð¼Ð¾ÑÑ Ð½Ð°Ð¼ понÑÑÑ Ð¿ÑоблемÑ.
- ÐÑо не обÑзаÑелÑно, но ÑекомендÑеÑÑÑ Ð´Ð»Ñ Ð½ÐµÐ¾ÑевиднÑÑ
пÑоблем.
- Также Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пÑовеÑиÑÑ Ð´Ð°Ð½Ð½Ñе ÑообÑениÑ, пÑежде Ñем оно бÑдеÑ
- оÑпÑавлено.
-">
-
-<!ENTITY comment.label "ÐомменÑаÑий (необÑзаÑелÑно):">
-<!ENTITY comment.accesskey "Ð">
-<!ENTITY comment.lengthWarning "Ðлина комменÑаÑÐ¸Ñ Ð¿ÑевÑÑÐ°ÐµÑ 1000 Ñимволов. ТолÑко пеÑвÑе 1000 Ñимволов бÑдÑÑ Ð¾ÑпÑавленÑ.">
-<!ENTITY email.label "ÐдÑÐµÑ ÑлекÑÑонной поÑÑÑ Ð´Ð»Ñ Ð´Ð¾Ð¿Ð¾Ð»Ð½Ð¸ÑелÑнÑÑ
вопÑоÑов (необÑзаÑелÑно):">
-<!ENTITY email.accesskey "д">
-
-<!ENTITY attachExtensions.label "ÐÑикÑепиÑÑ ÑпиÑок вклÑÑеннÑÑ
ÑаÑÑиÑений к ÑообÑÐµÐ½Ð¸Ñ Ð½Ð° ÑлÑÑай, еÑли пÑоблема вÑзвана конÑликÑом ÑаÑÑиÑений">
-<!ENTITY attachExtensions.accesskey "Ñ">
-
-<!ENTITY sendButton.label "ÐÑпÑавиÑÑ ÑообÑение">
-<!ENTITY sendButton.accesskey "п">
-
-<!ENTITY showData.label "ÐоказаÑÑ Ð´Ð°Ð½Ð½Ñе ÑообÑениÑ">
-<!ENTITY data.label "ÐаннÑе ÑообÑениÑ:">
-<!ENTITY data.accesskey "н">
-
-<!-- Please keep sendPage.heading short - it is shown in the progress bar, not much space there -->
-<!ENTITY sendPage.heading "ÐÑпÑавка ÑообÑениÑ">
-<!ENTITY sendPage.waitMessage "ÐожалÑйÑÑа, подождиÑе, пока Adblock Plus оÑпÑавлÑÐµÑ Ð²Ð°Ñе ÑообÑение.">
-<!ENTITY sendPage.confirmation "СообÑение оÑпÑавлено и ÑоÑ
Ñанено. ÐÑ Ð¼Ð¾Ð¶ÐµÑе пÑоÑмоÑÑеÑÑ ÐµÐ³Ð¾ по ÑледÑÑÑей ÑÑÑлке:">
-<!ENTITY sendPage.knownIssue "Ðозможно, ÑÑо пÑоблема, о коÑоÑой Ð²Ñ ÑообÑили, Ñже извеÑÑна. ÐополниÑелÑÐ½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ:">
-
-<!-- Note: the placeholder ?1? will be replaced by the error code -->
-<!ENTITY sendPage.errorMessage "
- ÐÑибка оÑпÑавки ÑообÑениÑ: «?1?». ÐожалÑйÑÑа,
- ÑдоÑÑовеÑÑÑеÑÑ, ÑÑо ваÑе Ñоединение Ñ ÑеÑÑÑ ÐнÑеÑÐ½ÐµÑ ÑабоÑаеÑ, и попÑобÑйÑе еÑе Ñаз.
- ÐÑли пÑоблема оÑÑаеÑÑÑ, обÑаÑиÑеÑÑ Ð² [link]ÑоÑÑм Adblock Plus[/link].
-">
-<!ENTITY sendPage.retry.label "ÐÑпÑавиÑÑ ÐµÑе Ñаз">
-
-<!ENTITY copyLink.label "СкопиÑоваÑÑ ÑÑÑÐ»ÐºÑ Ð½Ð° ÑообÑение">
-<!ENTITY copyLink.accesskey "к">
diff --git a/chrome/locale/ru/subscriptionSelection.dtd b/chrome/locale/ru/subscriptionSelection.dtd
deleted file mode 100644
index 9f675db..0000000
--- a/chrome/locale/ru/subscriptionSelection.dtd
+++ /dev/null
@@ -1,38 +0,0 @@
-<!ENTITY dialog.title "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð´Ð»Ñ Adblock Plus">
-<!ENTITY dialog.title.edit "РедакÑиÑоваÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
-
-<!ENTITY description.newInstall "
- Adblock Plus бÑÐ´ÐµÑ ÑабоÑаÑÑ Ð½Ð°Ð¸Ð±Ð¾Ð»ÐµÐµ ÑÑÑекÑивно, еÑли Ð²Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸Ñе подпиÑÐºÑ Ð½Ð°
- ÑпиÑок ÑилÑÑÑов. ÐÑи ÑпиÑки ÑилÑÑÑов пÑедоÑÑавлÑÑÑÑÑ Ð±ÐµÑплаÑно дÑÑгими
- полÑзоваÑелÑми Adblock Plus. Ð¡Ð°Ð¼Ð°Ñ Ð¿Ð¾Ð´Ñ
одÑÑÐ°Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñка Ð´Ð»Ñ Ð²Ð°Ñего ÑзÑка Ñже
- вÑбÑана.
-">
-
-<!ENTITY subscriptionSelector.label "ÐожалÑйÑÑа, вÑбеÑиÑе подпиÑÐºÑ Ð¸Ð· ÑпиÑка:">
-
-<!ENTITY viewList.label "ÐÑоÑмоÑÑеÑÑ ÑилÑÑÑÑ">
-<!ENTITY visitHomepage.label "ÐоÑеÑиÑÑ Ð´Ð¾Ð¼Ð°ÑнÑÑ ÑÑÑаниÑÑ ÑпиÑка">
-
-<!ENTITY addSubscription.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
-<!ENTITY saveSubscription.label "СоÑ
ÑаниÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ">
-
-<!ENTITY list.download.failed "ÐÑи ÑкаÑивании ÑпиÑка подпиÑок пÑоизоÑла оÑибка.">
-<!ENTITY list.download.retry "ÐопÑобоваÑÑ ÐµÑе Ñаз">
-<!ENTITY list.download.website "ÐÑкÑÑÑÑ ÑÑÑаниÑÑ Ñ Ð¿Ð¾Ð´Ð¿Ð¸Ñками">
-<!ENTITY other.label "ÐобавиÑÑ Ð´ÑÑгÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ">
-<!ENTITY other.accesskey "б">
-
-<!ENTITY fromWeb.description "ÐожалÑйÑÑа, подÑвеÑдиÑе, ÑÑо Ð²Ñ Ð´ÐµÐ¹ÑÑвиÑелÑно Ñ
оÑиÑе добавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð½Ð° ÑÑÐ¾Ñ ÑпиÑок ÑилÑÑÑов. ÐÑ Ð¼Ð¾Ð¶ÐµÑе измениÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ и адÑÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки пеÑед добавлением.">
-<!ENTITY edit.description "ÐÑ Ð¼Ð¾Ð¶ÐµÑе измениÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ и адÑÐµÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñки по надобноÑÑи.">
-<!ENTITY external.description "ÐÑо внеÑнÑÑ Ð¿Ð¾Ð´Ð¿Ð¸Ñка, ÑÑи ÑилÑÑÑÑ Ð¾Ð±Ð½Ð¾Ð²Ð»ÑÑÑÑÑ ÑаÑÑиÑением, коÑоÑое добавило ÑÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑкÑ.">
-
-<!ENTITY location.label "ÐдÑÐµÑ ÑпиÑка ÑилÑÑÑов:">
-<!ENTITY location.accesskey "д">
-<!ENTITY title.label "Ðазвание подпиÑки:">
-<!ENTITY title.accesskey "з">
-<!ENTITY autodownload.label "ÐбновлÑÑÑ Ð°Ð²ÑомаÑиÑеÑки">
-<!ENTITY autodownload.accesskey "Ñ">
-
-<!ENTITY supplementMessage "ÐÑÐ¾Ñ ÑпиÑок ÑилÑÑÑов должен иÑполÑзоваÑÑÑÑ Ð² комбинаÑии Ñо ÑпиÑком ÑилÑÑÑов «?1?», коÑоÑÑй Ð²Ñ Ð½Ðµ иÑполÑзÑеÑе.">
-<!ENTITY addMain.label "ÐобавиÑÑ Ð¿Ð¾Ð´Ð¿Ð¸ÑÐºÑ Ð½Ð° ÑпиÑок ÑилÑÑÑов «?1?»">
-<!ENTITY addMain.accesskey "в">
diff --git a/chrome/locale/si-LK/.incomplete b/chrome/locale/si-LK/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/si-LK/about.dtd b/chrome/locale/si-LK/about.dtd
deleted file mode 100644
index 942011d..0000000
--- a/chrome/locale/si-LK/about.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY dialog.title "à¶à¶©à·à¶¶à·à¶½à·à¶à· à¶´à·à¶½à·à· (Adblock Plus) à¶à·à¶±">
-<!ENTITY version.title "à·à·à·
à·à¶¸">
-<!ENTITY description "Adblock Plus allows you to decide what you want to see on the web. You don't need to download adverts and banners any more; if you don't want them - remove them with Adblock Plus!">
-<!ENTITY homepage.label "à¶à¶©à·à¶¶à·à¶½à·à¶à· à¶´à·à¶½à·à· (Adblock Plus) à·à·à¶¶à· à¶´à·à¶§à·à·">
-<!ENTITY author.label "à¶à¶»à·à¶à·">
-<!ENTITY contributors.label "දà·à¶ºà¶à¶ºà¶±à·">
-<!ENTITY subscriptionAuthors.label "Filter subscription authors:">
-<!ENTITY translators.label "à¶´à¶»à·à·à¶»à·à¶à¶à¶ºà¶±à·">
diff --git a/chrome/locale/si-LK/meta.properties b/chrome/locale/si-LK/meta.properties
deleted file mode 100644
index 2e3fb94..0000000
--- a/chrome/locale/si-LK/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=à¶à¶ à·.à¶à¶¸à·.à¶©à·.à¶à¶¸à·.à¶´à· à·à¶³à¶´à·à¶±à·à¶à·à¶©
-name=Adblock Plus
-description=à¶´à·à¶» දà·à¶± දà·à¶±à·à·à·à¶¸à·
-description.short=à¶à¶¶à¶§ à·à·à·
à¶³ දà·à¶±à·à·à·à¶¸à· à¶´à·âà¶»à·à·à¶±à¶ºà¶à·à¶¯ ?.à¶à·à· නම෠à¶
දම adblockpush දà·à¶à·à· à·à·à¶®à·à¶´à·à¶ à¶à¶»à¶à¶±à·à¶±. à·à·à¶©à· දà·à¶» à·à·à·à·à¶à¶» මà·à¶à¶±à·à¶±à· \n\n http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus allows you to regain control of the internet and view the web the way you want to. The add-on is supported by over forty filter subscriptions in dozens of languages which automatically configure it for purposes ranging from removing online advertising to blocking all known malware domains. Adblock Plus also allows you to customize your filters with the assistance of a variety of useful features, including a context option for images, a block tab for Flash and Java objects, and a list of blockable items to remove scripts and stylesheets.
diff --git a/chrome/locale/si-LK/overlay.dtd b/chrome/locale/si-LK/overlay.dtd
deleted file mode 100644
index 176374c..0000000
--- a/chrome/locale/si-LK/overlay.dtd
+++ /dev/null
@@ -1,4 +0,0 @@
-<!ENTITY menuitem.accesskey "b">
-<!ENTITY settings.accesskey "f">
-<!ENTITY opensidebar.accesskey "b">
-<!ENTITY closesidebar.accesskey "b">
diff --git a/chrome/locale/si-LK/sendReport.dtd b/chrome/locale/si-LK/sendReport.dtd
deleted file mode 100644
index f04c602..0000000
--- a/chrome/locale/si-LK/sendReport.dtd
+++ /dev/null
@@ -1,22 +0,0 @@
-<!ENTITY typeSelector.falsePositive.accesskey "m">
-<!ENTITY typeSelector.falseNegative.accesskey "v">
-<!ENTITY typeSelector.other.accesskey "t">
-<!ENTITY recentReports.clear.accesskey "R">
-<!ENTITY issues.override.accesskey "C">
-<!ENTITY typeWarning.override.accesskey "s">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.attach.accesskey "t">
-<!ENTITY screenshot.mark.accesskey "M">
-<!ENTITY screenshot.remove.accesskey "R">
-<!ENTITY screenshot.undo.accesskey "U">
-<!ENTITY comment.accesskey "C">
-<!ENTITY email.accesskey "m">
-<!ENTITY attachExtensions.accesskey "x">
-<!ENTITY sendButton.accesskey "m">
-<!ENTITY showData.label "යà·à¶± ලද දà¶à·à¶ à¶´à·à¶±à·à·à¶±à·à¶±">
-<!ENTITY data.label "දà¶à·à¶ à·à·à¶»à·à¶à· à¶à¶»à¶±à·à¶±">
-<!ENTITY data.accesskey "p">
-<!ENTITY sendPage.heading "දà¶à·à¶ යà·à¶±à·à¶±">
-<!ENTITY sendPage.retry.label "à¶±à·à·à¶ යà·à¶±à·à¶±">
-<!ENTITY copyLink.label "à¶±à·à·à¶ à¶´à·à¶§à¶´à¶à· à¶à¶»à¶±à·à¶±">
-<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/si-LK/settings.dtd b/chrome/locale/si-LK/settings.dtd
deleted file mode 100644
index d3d9318..0000000
--- a/chrome/locale/si-LK/settings.dtd
+++ /dev/null
@@ -1,45 +0,0 @@
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.accesskey "S">
-<!ENTITY synchsubscriptions.accesskey "d">
-<!ENTITY import.accesskey "m">
-<!ENTITY export.accesskey "x">
-<!ENTITY clearall.accesskey "l">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "à·à¶à·à·à¶à¶»à¶«à¶º à¶à¶»à¶±à·à¶±">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "à¶à¶´à· à·à¶»à·à¶±à·à·">
-<!ENTITY cut.accesskey "t">
-<!ENTITY copy.label "à¶´à·à¶§à¶´à¶à· à¶à¶»à¶±à·à¶±">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "à¶
à¶½à·à¶±à·à·">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.accesskey "g">
-<!ENTITY view.label "à¶´à·à¶±à·à¶¸">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "A > Z à¶
à¶±à·à¶´à·à·
à·à·à·à¶½">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "à·à·à¶à¶½à·à¶´">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.accesskey "n">
-<!ENTITY showintoolbar.accesskey "b">
-<!ENTITY showinstatusbar.accesskey "s">
-<!ENTITY objecttabs.accesskey "t">
-<!ENTITY help.label "Help">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.accesskey "r">
-<!ENTITY about.accesskey "b">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.accesskey "W">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY apply.label "යà·à¶¯à¶±à·à¶±">
-<!ENTITY apply.accesskey "p">
diff --git a/chrome/locale/si-LK/sidebar.dtd b/chrome/locale/si-LK/sidebar.dtd
deleted file mode 100644
index 904c566..0000000
--- a/chrome/locale/si-LK/sidebar.dtd
+++ /dev/null
@@ -1,18 +0,0 @@
-<!ENTITY detach.label "à¶à¶½à·à¶±à·à·">
-<!ENTITY reattach.label "à¶±à·à·à¶ à¶à¶à·à¶½à¶à· à¶à¶»à¶±à·à¶±">
-<!ENTITY search.label "à·à·à¶ºà¶±à·à¶±">
-<!ENTITY search.accesskey "s">
-<!ENTITY type.label "à·à¶»à·à¶à¶º">
-<!ENTITY address.label "à¶½à·à¶´à·à¶±à¶º">
-<!ENTITY filter.label "à¶´à·à¶»à¶±à¶º">
-<!ENTITY state.label "à¶à·à¶±à·à· à¶à¶à· à·à·à¶®à·à¶±à¶º">
-<!ENTITY size.label "à¶´à·âරමà·à¶«à¶º">
-<!ENTITY docDomain.label "à¶½à·à¶ මà·à¶½à·à¶à·âරය">
-<!ENTITY docDomain.thirdParty "(à¶à·à¶±à·à·à·à¶±à· à¶´à·à¶»à·à·à·à·à¶à¶»à·)">
-<!ENTITY docDomain.firstParty "(à¶´à·âරථම à¶´à·à¶»à·à·à·à·à¶à¶»à·)">
-<!ENTITY tooltip.address.label "à¶½à·à¶´à·à¶±à¶º:">
-<!ENTITY tooltip.type.label "à¶à¶à·à¶»à¶º:">
-<!ENTITY tooltip.type.blocked "(à¶
à·à·à·à¶» à¶à·à¶»à·à¶¸)">
-<!ENTITY tooltip.size.label "à¶´à·âරමà·à¶«à¶º:">
-<!ENTITY context.copyFilter.label "à¶´à·à¶»à¶±à¶º à¶´à·à¶§à¶´à¶à· à¶à¶»à¶±à·à¶±">
-<!ENTITY context.selectAll.label "à·à·à¶ºà¶½à·à¶½ à¶à·à¶»à¶±à·à·">
diff --git a/chrome/locale/si-LK/subscriptionSelection.dtd b/chrome/locale/si-LK/subscriptionSelection.dtd
deleted file mode 100644
index eba6ef6..0000000
--- a/chrome/locale/si-LK/subscriptionSelection.dtd
+++ /dev/null
@@ -1,14 +0,0 @@
-<!ENTITY viewList.label "à¶´à·à¶»à¶±à¶ºà¶±à· à¶´à·à¶±à·à·à¶±à·à¶±">
-<!ENTITY visitHomepage.label "à·à·à·à·à¶à¶» à¶´à·à¶§à·à·à¶§ යනà·à¶±">
-<!ENTITY addSubscription.label "දà·à¶ºà¶à¶à·à·à¶º ලබ෠දà·à¶±à·à¶±">
-<!ENTITY saveSubscription.label "දà·à¶ºà¶à¶à·à·à¶º à·à·à¶»à¶à·à¶±à·à¶±">
-<!ENTITY other.label "à·à·à¶±à¶à· දà·à¶ºà¶à¶à·à·à¶ºà¶à·">
-<!ENTITY other.accesskey "f">
-<!ENTITY list.download.retry "à¶±à·à·à¶ à¶à¶à·à·à· à¶à¶»à¶±à·à¶±">
-<!ENTITY list.download.website "à·à·à¶¶à· à¶´à·à¶§à·à· à¶´à·à¶±à·à·à¶±à·à¶±">
-<!ENTITY title.label "දà·à¶ºà¶à¶à·à·à¶ºà· නම">
-<!ENTITY title.accesskey "t">
-<!ENTITY location.accesskey "l">
-<!ENTITY autodownload.label "à¶´à·à¶»à¶±à¶ºà¶±à· à¶à¶¶à· යà·à·à¶à·à¶à·à¶½à·à¶± à¶à¶»à¶±à·à¶±">
-<!ENTITY autodownload.accesskey "p">
-<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/sk/meta.properties b/chrome/locale/sk/meta.properties
deleted file mode 100644
index 69b55b4..0000000
--- a/chrome/locale/sk/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ján Kendi (Jacen)
-name=Adblock Plus
-description=Reklamy sú minulosťou!
-description.short=Ste otrávenà reklamami? Máte problémy so sledovanÃm? ObÅ¥ažovanà banermi? NainÅ¡talujte si Adblock Plus teraz pre znovu zÃskanie kontroly na internete a zmeÅte pohľad na web.\n\n Krátke video je dostupné na http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus umožÅuje znovu zÃskanie kontroly na internete a pohľad na web aký chcete. RozÅ¡Ãrenie je podporované viac ako Å¡tyridsiatimi skupinami filtrov v niekoľkých jazykoch, ktoré sa automaticky konfigurujú v rozsahu od odstraÅovania online reklamy po blokovanie známych domén malware. Adblock Plus tiež umožÅuje upravovaÅ¥ vaÅ¡e filtre pomocou rôznych užitoÄných vlastnostÃ, vrátane kontextovej možnosti pre obrázky, blokovacie karty pre Flash a Java objekty a zoznam blokovateľných položiek na odstránenie skriptov a Å¡týlov.
diff --git a/chrome/locale/sl/meta.properties b/chrome/locale/sl/meta.properties
deleted file mode 100644
index 419c380..0000000
--- a/chrome/locale/sl/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Martin Srebotnjak
-name=Adblock Plus
-description=Oglasi so preteklost!
-description.short=Vas motijo reklame? Vam teži sledenje? Na živce vam gredo pasice? Namestite Adblock Plus takoj in prevzemite nadzor nad internetom in spremenite svoj pogled na splet.
-description.long=Adblock Plus omogoÄa ponoven prevzem nadzora nad internetom in ogledovanje spleta, kot to sami želite. Dodatek podpira veÄ kot Å¡tirideset naroÄnin na filtre v ducatu jezikov, ki ga samodejno prilagodija za namene od odstranjevanja spletnega oglaÅ¡evanja do blokiranja vseh znanih domen s Å¡kodljivimi vsebinami. Adblock Plus vam omogoÄa tudi prilagajanje filtrov s pomoÄjo Å¡tevilnih uporabnih funkcij, vkljuÄno s kontekstno možnostjo za slike, bloÄni zavihek za predmete Flash in Java, ter seznam blokiranih elementov za odstranjanje skript in oblikovnih predlog.
diff --git a/chrome/locale/sq/.incomplete b/chrome/locale/sq/.incomplete
deleted file mode 100644
index e69de29..0000000
diff --git a/chrome/locale/sq/about.dtd b/chrome/locale/sq/about.dtd
deleted file mode 100644
index 2dbef27..0000000
--- a/chrome/locale/sq/about.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY dialog.title "Rreth Adblock Plus">
-<!ENTITY version.title "Versioni">
-<!ENTITY description "Adblock ju lejon të vendosni çfarë doni të shihni në faqen që hapni. Nuk ka nevojë të ju hapen të gjitha reklamat më, nëse nuk i doni!">
-<!ENTITY homepage.label "Adblock Plus internet faqja">
-<!ENTITY author.label "Autori">
-<!ENTITY contributors.label "Kontribuuesit">
diff --git a/chrome/locale/sq/composer.dtd b/chrome/locale/sq/composer.dtd
deleted file mode 100644
index 0a29cfd..0000000
--- a/chrome/locale/sq/composer.dtd
+++ /dev/null
@@ -1,31 +0,0 @@
-<!ENTITY advanced.label "Pamja e avancuar">
-<!ENTITY basic.label "Pamja e zakonshme">
-<!ENTITY filter.label "Filtrues i ri:">
-<!ENTITY filter.accesskey "f">
-<!ENTITY preferences.label "Trego filtruesit ekzistues...">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "Blloko filtruesin">
-<!ENTITY type.filter.accesskey "B">
-<!ENTITY type.whitelist.label "Mos përfill">
-<!ENTITY type.whitelist.accesskey "x">
-<!ENTITY custom.pattern.label "Përshtatja:">
-<!ENTITY custom.pattern.accesskey "C">
-<!ENTITY anchor.start.accesskey "g">
-<!ENTITY anchor.start.flexible.accesskey "g">
-<!ENTITY anchor.end.label "në fund të adresës">
-<!ENTITY anchor.end.accesskey "n">
-<!ENTITY options.label "Mundësitë">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY firstParty.label "Vetëm pjesa e parë">
-<!ENTITY firstParty.accesskey "r">
-<!ENTITY thirdParty.label "Vetëm pjesa e tretë">
-<!ENTITY thirdParty.accesskey "T">
-<!ENTITY matchCase.accesskey "M">
-<!ENTITY types.label "Apliko në llojet:">
-<!ENTITY selectAllTypes.label "Selekto të gjitha">
-<!ENTITY unselectAllTypes.label "Mos selekto asnjë">
-<!ENTITY collapse.accesskey "I">
-<!ENTITY collapse.default.yes.label "Përdor të parazgjedhurën (po):">
-<!ENTITY collapse.default.no.label "Përdor të parazgjedhurën (jo):">
-<!ENTITY collapse.yes.label "Po">
-<!ENTITY collapse.no.label "Jo">
diff --git a/chrome/locale/sq/global.properties b/chrome/locale/sq/global.properties
deleted file mode 100644
index 3e6635d..0000000
--- a/chrome/locale/sq/global.properties
+++ /dev/null
@@ -1,34 +0,0 @@
-action3_tooltip=Aktivizim/çaktivizo Adblock Plus.
-disabled_tooltip=Adblock Plus është ç'aktiv.
-whitelisted_tooltip=Adblock Plus është aktiv por i pasivizuar në këtë faqe.
-blocked_count_tooltip=?1?jasht nga ?2?
-no_blocking_suggestions=S'ka elemente bllokuese në këtë faqe
-whitelist_description=Rregullat personale të përjashtimit
-filterlist_description=Rregullat personale të bllokimit
-invalid_description=Rregullat personale jo valide
-elemhide_description=Rregullat personale të fshehjes së elementeve
-subscription_source=Burimi:
-subscription_status=Gjendja:
-subscription_status_autodownload=Freskimi automatik
-subscription_status_manualdownload=Freskimi manual
-subscription_status_externaldownload=Freskuar nga jashtë (shtesë tjetër)
-subscription_status_lastdownload=Shkarkimi i fundit:
-subscription_status_lastdownload_inprogress=Duke u shkarkuar...
-subscription_status_lastdownload_unknown=N/D
-import_filters_title=Importo filtrues
-export_filters_title=Eksporto filtrues
-synchronize_ok=Sukses
-overwrite=Rishkruaj
-new_filter_group_title=Filtrues i ri
-type_label_other=tjera
-type_label_script=skripta
-type_label_image=figura
-type_label_stylesheet=stilet
-type_label_object=objekti
-type_label_subdocument=ndarja
-type_label_document=dokumenti
-type_label_elemhide=fshehur
-type_label_xmlhttprequest=kerkimi për XML
-type_label_dtd=DTD
-type_label_media=audio/video
-type_label_font=shkronjat
diff --git a/chrome/locale/sq/overlay.dtd b/chrome/locale/sq/overlay.dtd
deleted file mode 100644
index 1b1fc2c..0000000
--- a/chrome/locale/sq/overlay.dtd
+++ /dev/null
@@ -1,19 +0,0 @@
-<!ENTITY status.tooltip "Gjendja:">
-<!ENTITY filters.tooltip "Filtruesit më aktivë:">
-<!ENTITY menuitem.label "Parapëlqimet e Adblock Plus">
-<!ENTITY menuitem.accesskey "B">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: Gjërat e bllokuara">
-<!ENTITY context.image.label "Adblock Plus: Figurat e bllokuara">
-<!ENTITY context.object.label "Adblock Plus: Objektet e bllokuara">
-<!ENTITY context.frame.label "Adblock Plus: Pjesët e bllokuara">
-<!ENTITY context.removeWhitelist.label "Adblock Plus: Rilejo në këtë faqe">
-<!ENTITY settings.label "Parapëlqimet">
-<!ENTITY settings.accesskey "F">
-<!ENTITY opensidebar.label "Hap elementet bllokuese">
-<!ENTITY opensidebar.accesskey "B">
-<!ENTITY closesidebar.label "Mbyll elementet bllokuese">
-<!ENTITY closesidebar.accesskey "B">
-<!ENTITY whitelist.site.label "Ãaktivizo në ?1?">
-<!ENTITY whitelist.page.label "Ãaktivizo vetëm në këtë faqe">
-<!ENTITY objecttab.title "Blloko">
diff --git a/chrome/locale/sq/settings.dtd b/chrome/locale/sq/settings.dtd
deleted file mode 100644
index ffed489..0000000
--- a/chrome/locale/sq/settings.dtd
+++ /dev/null
@@ -1,76 +0,0 @@
-<!ENTITY dialog.title "Parapëlqimet e Adblock Plus">
-<!ENTITY filters.label "Filtruesit">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "Vendos filtrues">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.accesskey "S">
-<!ENTITY synchsubscriptions.accesskey "D">
-<!ENTITY import.label "Importo filtrues">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.label "Eksporto filtruesit ekzistues">
-<!ENTITY export.accesskey "X">
-<!ENTITY clearall.label "Largo të gjithë filtruesit ekxistues">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "Rishkruaj statistikat">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "Redakto">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "Kopjo-largo">
-<!ENTITY cut.accesskey "T">
-<!ENTITY copy.label "Kopjo">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "Hedh">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "Fshijë">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "Kërko">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "Kërko përsëri">
-<!ENTITY menu.findagain.accesskey "G">
-<!ENTITY view.label "Shih">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "Radhit sipas">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "Pa radhitur">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "A > Z radhitje">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Z > A radhitje">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Mundësitë">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "Aktivizo Adblock Plus">
-<!ENTITY enable.accesskey "N">
-<!ENTITY showintoolbar.accesskey "B">
-<!ENTITY showinstatusbar.accesskey "S">
-<!ENTITY objecttabs.accesskey "T">
-<!ENTITY collapse.accesskey "L">
-<!ENTITY help.label "Ndihmë">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.label "Fillo">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.label "Pyetje e zakonshme">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.label "Duke shkruar filtruesit e Adblock Plus">
-<!ENTITY filterdoc.accesskey "R">
-<!ENTITY about.label "Rreth Adblock Plus">
-<!ENTITY about.accesskey "B">
-<!ENTITY filter.column "Rregulla e filtrimit">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "Filtruesit e ngadalshëm">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "Aktivizo">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "Shtypje">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "Shtypja e fundit">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "Redakto filtruesin">
-<!ENTITY context.moveup.label "Zhvendos filtruesin sipër">
-<!ENTITY context.movedown.label "Zhvendos filtruesin poshtë">
-<!ENTITY context.movegroupup.label "Zhvendos grupin sipër">
-<!ENTITY context.movegroupdown.label "Zhvendos grupin poshtë">
-<!ENTITY context.enable.label "Aktivizo">
-<!ENTITY context.disable.label "Ã'aktivizoj">
-<!ENTITY apply.label "Ruaji">
-<!ENTITY apply.accesskey "p">
diff --git a/chrome/locale/sq/sidebar.dtd b/chrome/locale/sq/sidebar.dtd
deleted file mode 100644
index 798d73d..0000000
--- a/chrome/locale/sq/sidebar.dtd
+++ /dev/null
@@ -1,26 +0,0 @@
-<!ENTITY search.label "Kërko">
-<!ENTITY search.accesskey "S">
-<!ENTITY type.label "Lloji">
-<!ENTITY address.label "Adresa">
-<!ENTITY filter.label "Filtruesi">
-<!ENTITY state.label "Gjendja">
-<!ENTITY size.label "Madhësia">
-<!ENTITY docDomain.label "Burimi i dokumentit">
-<!ENTITY noitems.label "S'ka elemente bllokuese">
-<!ENTITY tooltip.address.label "Adresa:">
-<!ENTITY tooltip.type.label "Lloji:">
-<!ENTITY tooltip.type.blocked "(bllokuar)">
-<!ENTITY tooltip.type.whitelisted "(lejuar)">
-<!ENTITY tooltip.size.label "Madhësia:">
-<!ENTITY tooltip.docDomain.label "Burimi i dokumentit:">
-<!ENTITY tooltip.filter.label "Filtruesi efektiv:">
-<!ENTITY tooltip.filterSource.label "Burimi i filtruesit:">
-<!ENTITY context.block.label "Blloko këtë send">
-<!ENTITY context.editfilter.label "Vendos filtruesin në veprim">
-<!ENTITY context.disablefilter.label "Ãaktivizo filtruesin ?1?">
-<!ENTITY context.enablefilter.label "Ri mundëso filtruesin ?1?">
-<!ENTITY context.disablefilteronsite.label "Pamundëso filtruesin në ?1?">
-<!ENTITY context.open.label "Hape një një lidhje të re">
-<!ENTITY context.copy.label "Kopjo adresën e elementit">
-<!ENTITY context.copyFilter.label "Kopjo filtruesin">
-<!ENTITY context.selectAll.label "Selekto të gjitha">
diff --git a/chrome/locale/sq/subscriptionSelection.dtd b/chrome/locale/sq/subscriptionSelection.dtd
deleted file mode 100644
index 7ba53f7..0000000
--- a/chrome/locale/sq/subscriptionSelection.dtd
+++ /dev/null
@@ -1,6 +0,0 @@
-<!ENTITY other.accesskey "f">
-<!ENTITY title.accesskey "T">
-<!ENTITY location.label "Vendi i listës së filtruesit">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.label "Fresko Automatikisht">
-<!ENTITY autodownload.accesskey "P">
diff --git a/chrome/locale/sr/meta.properties b/chrome/locale/sr/meta.properties
deleted file mode 100644
index b3ed167..0000000
--- a/chrome/locale/sr/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=kapetance, ÐакСРÐÐÐÐ
-name=Adblock Plus
-description=Рекламе ÑÑ Ð¿ÑоÑлоÑÑ!
-description.short=ÐоÑадиле ÑÑ Ð²Ð°Ð¼ Ñекламе? ÐоÑÑа вам Ñе намеÑнÑÑиÑ
обÑекаÑа? СмаÑаÑÑ Ð²Ð°Ñ Ð±Ð°Ð½ÐµÑи? ÐнÑÑалиÑаÑÑе Adblock Plus да биÑÑе пÑеÑзели конÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ ÐнÑеÑнеÑом и ÑÑекли дÑÑгаÑиÑи поглед на Ñега.
-description.long=ÐдблоÑк ÐлÑÑ Ð²Ð°Ð¼ омогÑÑава да поново ÑÑекнеÑе конÑÑÐ¾Ð»Ñ Ð½Ð°Ð´ ÐнÑеÑнеÑом и изгледом ÑÑÑаниÑа. ÐодаÑак подÑжава пÑеко ÑеÑÑдеÑÐµÑ Ð¿ÑеÑплаÑа на ÑилÑеÑе на многим ÑезиÑима коÑи Ñе аÑÑомаÑÑки подеÑаваÑÑ ÐºÐ°ÐºÐ¾ би Ñклонили Ñве: од ÑклаÑана нежеÑениÑ
Ñеклама до блокиÑаÑа познаÑиÑ
злонамеÑниÑ
домена. Adblock Plus ÑакоÑе дозвоÑава пÑилагоÑаваÑе ÑилÑеÑа и Ð¿Ð¾Ð¼Ð¾Ñ Ð·Ð° ÑазновÑÑне могÑÑноÑÑи, као ÑÑо ÑÑ ÑадÑжаÑне опÑиÑе за Ñлике, ÑезиÑак за блокиÑаÑе Flash и Java обÑекаÑа и ÑпиÑак ÑÑавки коÑе Ñе могÑÑе блокиÑаÑи Ñади ÑклаÑаÑа ÑкÑипÑи и ÑÑилова.
diff --git a/chrome/locale/sv-SE/meta.properties b/chrome/locale/sv-SE/meta.properties
deleted file mode 100644
index fbd2611..0000000
--- a/chrome/locale/sv-SE/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Stefan Lewitas, Mikael Hiort af Ornäs
-name=Adblock Plus
-description=Säg farväl till all reklam!
-description.short=Retlig reklam? Snokande spårning? Besvärliga banderoller? Installera Adblock Plus nu för att återta kontrollen över Internet och visa webben som du vill se den.\n\nEn kort videoöversikt finns tillgänglig på http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus låter dig återta kontrollen över Internet och visa webben som du vill se den. Tillägget stöds av över fyrtio filterprenumerationer som spänner över dussintals språk. Filtren konfigurerar automatiskt Adblock Plus för avsett ändamål, som kan vara allt ifrån att avlägsna onlineannonser till att blockera alla kända skadliga domäner. Adblock Plus låter dig också anpassa dina filter med stöd av en mängd användbara funktioner, inklusive ett snabbmenyalternativ för bilder, en blockeringsflik för Flash- och Java-objekt, och en lista över blockeringsbara objekt för att kunna ta bort skript och formatmallar.
diff --git a/chrome/locale/th/meta.properties b/chrome/locale/th/meta.properties
deleted file mode 100644
index a773b80..0000000
--- a/chrome/locale/th/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ken,
-name=Adblock Plus
-description=ลาà¸à¹à¸à¸à¸à¸§à¸à¹à¸à¸©à¸à¸²!
-description.short=หาà¸à¸à¸¸à¸à¸£à¸³à¸à¸²à¸à¸à¸§à¸à¹à¸à¸©à¸à¸²à¸«à¸£à¸·à¸à¹à¸à¸à¹à¸à¸à¸£à¹ ลà¸à¸à¸à¸´à¸à¸à¸±à¹à¸ Adblock Plus à¹à¸à¸·à¹à¸à¸à¸§à¸à¸à¸¸à¸¡à¸à¸²à¸£à¹à¸à¹à¸à¸²à¸à¸à¸´à¸à¹à¸à¸à¸£à¹à¹à¸à¹à¸à¹à¸¥à¸°à¹à¸à¸¥à¸µà¹à¸¢à¸à¸à¸²à¸£à¸¡à¸à¸à¹à¸«à¹à¸à¹à¸§à¹à¸à¹à¸à¸à¹à¹à¸«à¸¡à¹\n\nà¸à¸¹à¸§à¸µà¸à¸´à¸à¸±à¸¨à¸à¹à¹à¸à¸°à¸à¸³à¸à¸±à¸§à¹à¸à¹à¸à¸µà¹ http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus à¸à¸³à¹à¸«à¹à¸à¸¸à¸à¸ªà¸²à¸¡à¸²à¸£à¸à¸à¸§à¸à¸à¸¸à¸¡à¸à¸±à¸à¹à¸à¹à¸à¸²à¸à¸à¸´à¸à¹à¸à¸à¸£à¹à¹à¸à¹à¸à¹à¸¥à¸°à¸¡à¸à¸à¹à¸«à¹à¸à¹à¸§à¹à¸à¹à¸à¸à¹à¸à¸²à¸¡à¸à¸µà¹à¸à¹à¸à¸à¸à¸²à¸£ สà¹à¸§à¸à¹à¸ªà¸£à¸´à¸¡à¸à¸µà¹à¹à¸à¹à¹à¸à¹à¸à¸²à¸à¸à¸±à¸§à¸à¸£à¸à¸à¸à¸§à¹à¸²à¸ªà¸µà¹à¸ªà¸´à¸à¸£à¸²à¸¢à¸à¸²à¸£à¹à¸à¸«à¸¥à¸²à¸¢à¸ าษา à¸à¸¶à¹à¸à¸à¹à¸§à¸¢à¸à¸±à¹à¸à¸à¹à¸²à¹à¸«à¹à¸à¸±à¹à¸à¹à¸à¹à¸¥à¸à¹à¸à¸©à¸à¸²à¸à¸à¸à¹à¸¥à¸à¹à¸à¸à¸à¸¶à¸à¸à¸¥à¹à¸à¸à¹à¸à¹à¸¡à¸à¸¡à¸±à¸¥à¹à¸§à¸£à¹à¸à¸µà¹à¸£à¸¹à¹à¸à¸±à¸ Adblock Plus สามารà¸à¹à¸«à¹à¸à¸¸à¸à¸à¸£à¸±à¸à¹à¸à¹à¸à¸à¸±à¸§à¸à¸£à¸à¸à¹à¸à¹à¹à¸à¸à¸à¹à¸§à¸¢à¹à¸à¸£à¸·à¹à¸à¸à¸¡à¸·à¸à¸à¸µà¹à¸¡à¸µà¸à¸£à¸°à¹à¸¢à¸à¸à¹ รวมà¸à¸¶à¸à¸à¸±à¸§à¹à¸¥à¸·à¸à¸à¸à¸£à¸´à¸à¸à¸ªà¸³à¸«à¸£à¸±à¸à¸£à¸¹à¸à¸ าภà¹à¸à¹à¸à¸à¸¥à¹à¸à¸à¸ªà¸³à¸«à¸£à¸±à¸ Flash à¹à¸¥à¸°à¸§à¸±à¸à¸à¸¸ Java à¹à¸¥à¸°à¸£à¸²à¸¢à¸à¸²à¸£à¸à¸à¸à¸§à¸±à¸à¸à¸¸à¸à¸µà¹à¸à¸¥à¹à¸à¸à¹à¸à¹à¹à¸à¸·à¹à¸à¸¥à¸à¸ªà¸à¸£à¸´à¸à¸à¹à¹à¸¥à¸°à¸ªà¹à¸à¸¥à¹à¸à¸µà¸
diff --git a/chrome/locale/tr/about.dtd b/chrome/locale/tr/about.dtd
deleted file mode 100644
index 53e7b68..0000000
--- a/chrome/locale/tr/about.dtd
+++ /dev/null
@@ -1,8 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus Hakkında">
-<!ENTITY version.title "Sürüm">
-<!ENTITY description "Adblock Plus size internette neyi görmek istediÄinize karar verme Åansı sunar. Artık reklamları ve tanıtımları izlemek zorunda deÄilsiniz. Görmek istemediklerinizi Adblock Plus'a bildirin yeter!">
-<!ENTITY homepage.label "Adblock Plus ana sayfası:">
-<!ENTITY author.label "Yazar:">
-<!ENTITY contributors.label "Katkıda bulunanlar:">
-<!ENTITY subscriptionAuthors.label "Süzgeç aboneliÄi yazarları:">
-<!ENTITY translators.label "Ãevirmenler:">
diff --git a/chrome/locale/tr/composer.dtd b/chrome/locale/tr/composer.dtd
deleted file mode 100644
index 7560afe..0000000
--- a/chrome/locale/tr/composer.dtd
+++ /dev/null
@@ -1,47 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus süzgeç kuralı ekle">
-<!ENTITY accept.label "Süzgeç ekle">
-<!ENTITY advanced.label "GeliÅmiÅ görünüm">
-<!ENTITY basic.label "Temel görünüm">
-<!ENTITY disabled.warning "Adblock Plus Åu an devre dıÅı. Yine de süzgeç ekleyebilirsiniz, ancak bunlar [link]Adblock Plus etkinleÅtirilene kadar[/link]uygulanmayacaktır.">
-<!ENTITY groupDisabled.warning "Süzgecin eklenmesi gereken "?1?" süzgeç grubu Åu an devre dıÅı. Süzgeci Åu an ekleyebilirsiniz ancak [link]süzgeç grubunu devreye soktuÄunuzda[/link]kullanılabilecektir.">
-<!ENTITY filter.label "Yeni süzgeç:">
-<!ENTITY filter.accesskey "y">
-<!ENTITY preferences.label "Mevcut süzgeçleri göster...">
-<!ENTITY preferences.accesskey "S">
-<!ENTITY type.filter.label "Engelleyen süzgeç">
-<!ENTITY type.filter.accesskey "l">
-<!ENTITY type.whitelist.label "Hariç tutma kuralı">
-<!ENTITY type.whitelist.accesskey "h">
-<!ENTITY pattern.label "Aranacak örnek">
-<!ENTITY pattern.explanation "Bu örnek adresin herhangi bir bölümü olabilir ve * iÅareti joker görevi yapar. Süzgeç sadece örneÄe uyan adreslere uygulanacak.">
-<!ENTITY regexp.warning "GirdiÄiniz örnek düzenli ifade olarak yorumlanacak. Ãok fazla düzenli ifade, taramayı yavaÅlatabilir. Gerçekten düzenli ifade kullanmak istediÄinizden emin deÄilseniz örneÄin sonuna * iÅareti koyun.">
-<!ENTITY shortpattern.warning "GirdiÄiniz örnek en iyileÅtirmek için çok kısa ve bu tür örnekler taramayı yavaÅlatabilir. Bu süzgeç için daha uzun bir satır seçmeniz tavsiye edilir.">
-<!ENTITY match.warning "GirdiÄiniz örnek artık engellenecek olan veya kara listeden çıkarılacak adresle uyuÅmuyor ve üzerinde hiçbir etkisi olmayacak.">
-<!ENTITY custom.pattern.label "Ãzel:">
-<!ENTITY custom.pattern.accesskey "z">
-<!ENTITY anchors.label "ÃrneÄi sadece burada kabul et:">
-<!ENTITY anchor.start.label "adresin baÅında">
-<!ENTITY anchor.start.accesskey "b">
-<!ENTITY anchor.start.flexible.label "alan adının baÅında">
-<!ENTITY anchor.start.flexible.accesskey "b">
-<!ENTITY anchor.end.label "adresin sonunda">
-<!ENTITY anchor.end.accesskey "o">
-<!ENTITY options.label "Seçenekler">
-<!ENTITY domainRestriction.label "Alan adına kısıtlama:">
-<!ENTITY domainRestriction.accesskey "d">
-<!ENTITY domainRestriction.help "Aralarına "|" simgesi koyarak bir ya da daha fazla alan adı belirtin. Böylece süzgeç sadece bu sitelerde uygulanacaktır. Alan adından önce "~" simgesi kullanılması, süzgecin o alan adında kullanılmaması gerektiÄi anlamına gelir.">
-<!ENTITY firstParty.label "Sadece birinci kiÅilerden">
-<!ENTITY firstParty.accesskey "i">
-<!ENTITY thirdParty.label "Sadece üçüncü kiÅilerden">
-<!ENTITY thirdParty.accesskey "c">
-<!ENTITY matchCase.label "Birebir eÅleÅme">
-<!ENTITY matchCase.accesskey "e">
-<!ENTITY types.label "Bu türlere uygula:">
-<!ENTITY selectAllTypes.label "Tümünü seç">
-<!ENTITY unselectAllTypes.label "Hiçbirini seçme">
-<!ENTITY collapse.label "Engellenenleri kapat:">
-<!ENTITY collapse.accesskey "p">
-<!ENTITY collapse.default.yes.label "Ãntanımlı kullan (evet)">
-<!ENTITY collapse.default.no.label "Ãntanımlı kullan (hayır)">
-<!ENTITY collapse.yes.label "Evet">
-<!ENTITY collapse.no.label "Hayır">
diff --git a/chrome/locale/tr/global.properties b/chrome/locale/tr/global.properties
deleted file mode 100644
index abd5230..0000000
--- a/chrome/locale/tr/global.properties
+++ /dev/null
@@ -1,70 +0,0 @@
-default_dialog_title=Adblock Plus
-action0_tooltip=İçerik menüsünü açmak için tıklayın; etkinleÅtirmek ya da etkisizleÅtirmek için orta düÄmeye tıklayın.
-action1_tooltip=Engellenebilir öÄeleri açmak ya da kapatmak için tıklayın; etkinleÅtirmek ya da etkisizleÅtirmek için orta düÄmeye tıklayın.
-action2_tooltip=Tercihler penceresini açmak için tıklayın; etkinleÅtirmek ya da etkisizleÅtirmek için orta düÄmeye tıklayın.
-action3_tooltip=Adblock Plus'ı etkinleÅtirmek ya da etkisizleÅtirmek için orta düÄmeye tıklayın.
-disabled_tooltip=Adblock Plus etkin deÄil.
-active_tooltip=Adblock Plus devrede ve ?1? süzgeç aboneliÄi ile ?2? özel süzgeç kullanıyor.
-whitelisted_tooltip=Adblock Plus etkin, ancak bu sayfada devre dıÅı.
-blocked_count_tooltip=?1? toplam ?2?
-blocked_count_addendum=(ayrıca ?1? tane ak listede, ?2? tane gizli)
-no_blocking_suggestions=Bakılan sayfada engellenebilecek bir öÄe bulunmuyor
-whitelisted_page=Adblock Plus bakılan sayfa için devre dıÅı bırakıldı
-whitelist_description=Ayrıcalıklar
-filterlist_description=Reklam süzgeçleri
-invalid_description=Geçersiz süzgeçler
-elemhide_description=ÃÄe engelleme kuralları
-subscription_description=Süzgeç abonelikleri:
-subscription_wrong_version=Bazı süzgeçlerin düzgün çalıÅabilmesi için Adblock Plus ?1? gerekiyor.
-subscription_source=Kaynak:
-subscription_status=Durum:
-subscription_status_autodownload=Otomatik olarak güncellendi
-subscription_status_manualdownload=Elle güncellendi
-subscription_status_externaldownload=DıÅarıdan güncellendi (baÅka bir eklenti tarafından)
-subscription_status_lastdownload=En son indiriÅ:
-subscription_status_lastdownload_inprogress=İndiriliyor...
-subscription_status_lastdownload_unknown=Yok
-remove_subscription_warning=Gerçekten abonelikten çıkmak istiyor musunuz?
-import_filters_wrong_version=Uyarı: Bazı süzgeçlerin düzgün çalıÅabilmesi için Adblock Plus ?1? gerekiyor. Bu listeyi içe aktarmadan önce büyük olasılıkla en güncel Adblock Plus sürümüne yükselmeniz gerekiyor.
-import_filters_warning=Geçerli süzgeçlerinizi deÄiÅtirmek mi yoksa yeni gelecekleri Åu anki süzgeçlerin sonuna eklemek mi istersiniz?
-import_filters_title=Süzgeçleri içe aktar
-export_filters_title=Süzgeçleri dıÅa aktar
-invalid_filters_file=Bu geçerli bir Adblock Plus süzgeç dosyası deÄil.
-filters_write_error=Süzgeçler dosyaya yazılırken hatayla karÅılaÅıldı. Dosyanın yazmaya karÅı korunup korunmadıÄından ve baÅka bir program tarafından kullanılıp kullanılmadıÄından emin olun.
-clearall_warning=Gerçekten listedeki bütün süzgeçleri kaldırmak istiyor musunuz?
-resethitcounts_warning=Bütün süzgeçlerin isabet istatistiklerini gerçekten sıfırlamak istiyor musunuz? Bu iÅlemden geri adım atılamaz!
-resethitcounts_selected_warning=Seçilen süzgeçlerin isabet istatistiklerini gerçekten sıfırlamak istiyor musunuz? Bu iÅlemden geri adım atılamaz!
-filter_regexp_tooltip=Süzgeç ya düzenli ifade ya da en iyileÅtirmek için çok kısa. Bu süzgeçlerden çok fazlası, taramanızı yavaÅlatabilir.
-filter_elemhide_duplicate_id=Gizlenecek sadece bir bileÅen kimliÄi belirtilebilir
-filter_elemhide_nocriteria=Gizlenecek bileÅeni anlamak için hiçbir ölçüt belirtilmedi
-subscription_notAdded_warning=Hiçbir süzgece abone olmadınız. Adblock Plus'ta kendiniz süzgeç tanımlamanız gerekecek.
-subscription_notAdded_warning_addendum=Devam etmek istiyor musunuz?
-subscription_invalid_location=Dosya listesi konumu ne düzgün bir URL ne de düzgün bir ada sahip.
-synchronize_invalid_url=Olmadı. Bu geçerli bir adres deÄil.
-synchronize_connection_error=Olmadı. İndirmede sorun var.
-synchronize_invalid_data=Olmadı. Bu düzgün bir süzgeç listesi deÄil.
-synchronize_checksum_mismatch=BaÅarısız, checksum eÅleÅmedi
-synchronize_ok=EÅleme baÅarılı oldu.
-overwrite=Ãstüne Yaz
-append=Ekle
-new_filter_group_title=Yeni süzgeç
-type_label_other=diÄer
-type_label_script=betik
-type_label_image=resim
-type_label_stylesheet=biçem yapraÄı
-type_label_object=nesne
-type_label_subdocument=çerçeve
-type_label_document=belge
-type_label_elemhide=gizli
-type_label_xbl=XBL baÄlantısı
-type_label_ping=baÄlantı yoklaması
-type_label_xmlhttprequest=XML isteÄi
-type_label_object_subrequest=nesne alt isteÄi
-type_label_dtd=DTD
-type_label_media=ses/görüntü
-type_label_font=yazıtipi
-fennec_status_enabled=Adblock Plus devrede.
-fennec_status_disabled=Adblock Plus devre dıÅı.
-fennec_status_enabled_site=Adblock Plus ?1? sitesinde devrede.
-fennec_status_disabled_site=Adblock Plus ?1? sitesinde devre dıÅı.
-sync_engine_title=Adblock Plus verisi
diff --git a/chrome/locale/tr/meta.properties b/chrome/locale/tr/meta.properties
deleted file mode 100644
index 6f809fd..0000000
--- a/chrome/locale/tr/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Ahmet Serkan Tıratacı
-name=Adblock Plus
-description=Reklamlar geçmiÅte kaldı!
-description.short=Reklamlar rahatsız mı ediyor? İzlenmek sorun mu yaratıyor? Koca koca tanıtımlardan bıktınız mı? Hemen Adblock Plus'ı kurun ve internetin kontrolünü yeniden ele geçirin, sayfaların nasıl görüneceÄine siz karar verin.
-description.long=Adblock Plus internetin kontrolünü yeniden ele geçirinmenize ve sayfaların nasıl görüneceÄine karar vermesinize olanak tanır. Reklamları yok etmekten zararlı yazılım daÄıtan siteleri engellemeye kadar birçok iÅi gören farklı dildeki 40'ı aÅkın süzgeç, Adblock Plus'ın arkasında. Adblock Plus ayrıca çeÅitli yararlı özellikler sayesinde süzgeçlerinizi düzenlemenize yardım eder. Bu özellikler arasında, sayfa üzerinden resim engelleme; Flash ve Java nesneleri için engelleme sekmesi; betik ve biçem sayfalarını (CSS) engellenecekler arasından çıkartmanızı saÄlayan 'engellenebilir öÄeler listesi' yer alır.
diff --git a/chrome/locale/tr/sendReport.dtd b/chrome/locale/tr/sendReport.dtd
deleted file mode 100644
index 73429b0..0000000
--- a/chrome/locale/tr/sendReport.dtd
+++ /dev/null
@@ -1,75 +0,0 @@
-<!ENTITY wizard.title "Sorun bildirici">
-<!ENTITY privacyPolicy.label "Gizlilik politikası">
-<!ENTITY dataCollector.heading "Sorun bildiriciye hoÅ geldiniz">
-<!ENTITY dataCollector.description "Adblock Plus eklentisinin gerekli bilgileri toplaması için lütfen biraz bekleyin.">
-<!ENTITY typeSelector.heading "Sorun türünü seçin">
-<!ENTITY typeSelector.description "Bu pencere Adblock Plus sorun bildirimi göndermek için gerekli adımların atılmasında size rehberlik edecek. Ãnce bu sayfada ne tür sorun yaÅadıÄınızı seçin:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus çok fazla engelleme yapıyor">
-<!ENTITY typeSelector.falsePositive.accesskey "f">
-<!ENTITY typeSelector.falsePositive.description "Sayfanın önemli içeriÄi hiç görünmüyorsa, yanlıŠgörünüyorsa veya sayfa düzgün iÅlemiyorsa bu seçeneÄi seçin. Sorun kaynaÄının Adblock Plus olup olmadıÄını eklentiyi geçici olarak devre dıÅı bırakıp belirleyebilirsiniz.">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus reklamın birini engellemiyor">
-<!ENTITY typeSelector.falseNegative.accesskey "m">
-<!ENTITY typeSelector.falseNegative.description "Adblock Plus devrede olmasına raÄmen reklamın biri görünüyorsa bu seçeneÄi seçin.">
-<!ENTITY typeSelector.other.label "BaÅka bir sorun">
-<!ENTITY typeSelector.other.accesskey "b">
-<!ENTITY typeSelector.other.description "Sorunun süzgeçlerinden çok Adblock Plus'ın kendisinden kaynaklandıÄından Åüpheleniyorsanız bu seçeneÄi seçin.">
-<!ENTITY showRecentReports.label "Yakında gönderilen bildirimleri göster">
-<!ENTITY recentReports.label "Yakında gönderdiÄiniz bildirimler">
-<!ENTITY recentReports.clear.label "Tüm bildirimleri sil">
-<!ENTITY recentReports.clear.accesskey "r">
-<!ENTITY issues.description "Adblock Plus yapılandırmanızda bu sorunun nedeni olabilecek veya bildirimi incelemeyi güçleÅtirecek sorunlar keÅfetti.">
-<!ENTITY issues.whitelist.description "Adblock Plus bildirimde bulunduÄunuz sayfada devre dıÅı. Bu sorunun incelenmesine yardım etmek için bildirim göndermeden önce eklentiyi devreye sokun ve sayfayı yeniden yükleyin.">
-<!ENTITY issues.whitelist.remove.label "Adblock Plus'u bu sayfada devreye sok">
-<!ENTITY issues.disabled.description "Adblock Plus devre dıÅı ve Åu anki durumunda hiçbir Åeyi engellemeyecek.">
-<!ENTITY issues.disabled.enable.label "Adblock Plus'ı etkinleÅtir">
-<!ENTITY issues.nofilters.description "Adblock Plus bu sayfada hiçbir Åeyi engellemiyor. GözlemlediÄiniz sorun büyük olasılıkla Adblock Plus ile ilgisiz.">
-<!ENTITY issues.nosubscriptions.description "Sitelerdeki istenmeyen içeriÄi yok eden önceden hazırlanmıŠsüzgeç listelerinden herhangi birine abone olmuÅ deÄilsiniz.">
-<!ENTITY issues.nosubscriptions.add.label "Süzgeç aboneliÄi ekle">
-<!ENTITY issues.subscriptionCount.description "Ãok fazla süzgeç listesine abone olduÄunuz görülüyor. Böyle yapmanız tavsiye edilmez çünkü bu, sorun çıkma olasılıÄını daha da arttırır. Ayrıca hangi süzgeç aboneliÄi yazarının hatayı düzeltmesi gerektiÄi belirsiz olduÄundan hata bildiriminizi kabul edemeyiz. Sadece gerçekten gerekli olan süzgeç abonelikleri dıÅında kalanlardan çıkın ve sorunun hâlâ yaÅanıp yaÅanmadıÄına bakın.">
-<!ENTITY issues.openPreferences.label "Süzgeç tercihlerini aç">
-<!ENTITY issues.ownfilters.description "Bu sayfada uygulanan süzgeçlerin bazıları kullanıcı tarafından tanımlanmıÅ. Lütfen soruna neden olmuÅ olabilecek süzgeçleri devre dıÅı bırakın:">
-<!ENTITY issues.ownfilters.disable.label "Süzgeci devre dıÅı bırak">
-<!ENTITY issues.disabledgroups.description "Bu sayfada etkisi olabilecek aÅaÄıdaki abonelikler ve süzgeç grupları devre dıÅı bırakıldı:">
-<!ENTITY issues.disabledgroups.enable.label "Süzgeç aboneliÄini veya grubunu devreye sok">
-<!ENTITY issues.disabledfilters.description "Bu sayfada etkisi olabilecek aÅaÄıdaki süzgeçler devre dıÅı bırakıldı:">
-<!ENTITY issues.disabledfilters.enable.label "Süzgeci devreye sok">
-<!ENTITY issues.override.label "Yapılandırma doÄru, bildirime devam et">
-<!ENTITY issues.override.accesskey "d">
-<!ENTITY issues.change.description "Yapılandırmanız deÄiÅti. Lütfen deÄiÅiklikleri sınamak için sayfayı yeniden yükleyin ve yapılan deÄiÅiklikler sorunu gidermediyse hatayı bildirin.">
-<!ENTITY typeWarning.description "Süzgeçlerle ilgili bir sorun deÄil de Adblock Plus ile ilgili genel bir sorun bildiriminde bulunmak istediÄinizi belirttiniz. Lütfen böyle sorunların en iyi bildirim yerinin [link]Adblock Plus forumu[/link] olduÄu aklınızda olsun. Siz baÄlantı vermediÄiniz sürece kimse bildiriminizi görmeyeceÄi için sorun bildiriciyi sadece mevcut bir tartıÅmaya katkı saÄlamak için kullanmalısınız.">
-<!ENTITY typeWarning.override.label "Anlıyorum ve ne olursa olsun bildirimi göndermek istiyorum">
-<!ENTITY typeWarning.override.accesskey "s">
-<!ENTITY reloadButton.label "Sayfayı tazele">
-<!ENTITY reloadButton.accesskey "t">
-<!ENTITY screenshot.heading "Ekran görüntüsü ekle">
-<!ENTITY screenshot.description "Aynı sayfa farklı kiÅilerce farklı biçimde görülebilir. Bildirime ekran görüntüsü eklemeniz sorunu anlamamıza yardımcı olabilir. Hassas bilgilerin olduÄu bölümleri silebilirsiniz ve sorunun görünür olduÄu yerleri iÅaretleyebilirsiniz. Bunu yapmak için ilgili düÄmeye basın ve resimde bir bölümü farenizle seçin.">
-<!ENTITY screenshot.attach.label "Bildirime sayfa resmi ekle">
-<!ENTITY screenshot.attach.accesskey "f">
-<!ENTITY screenshot.mark.label "Sorunu iÅaretle">
-<!ENTITY screenshot.mark.accesskey "a">
-<!ENTITY screenshot.remove.label "Hassas veriyi sil">
-<!ENTITY screenshot.remove.accesskey "v">
-<!ENTITY screenshot.undo.label "Geri al">
-<!ENTITY screenshot.undo.accesskey "g">
-<!ENTITY commentPage.heading "Yorum ekle">
-<!ENTITY commentPage.description "AÅaÄıdaki metin alanı sorunu anlamamız için yorum yazmanıza olanak tanır. Bu adım isteÄe baÄlıdır ancak sorun açık deÄilse tavsiye edilir. Ayrıca bildirimi göndermeden önce gözden geçirebilirsiniz.">
-<!ENTITY comment.label "Yorum (isteÄe baÄlı):">
-<!ENTITY comment.accesskey "o">
-<!ENTITY comment.lengthWarning "Yorumunuzun uzunluÄu 1000 karakteri aÅıyor. Sadece ilk 1000 karakter gönderilecek.">
-<!ENTITY email.label "Daha fazla bilgi almamız için e-posta adresi (isteÄe baÄlı):">
-<!ENTITY email.accesskey "d">
-<!ENTITY attachExtensions.label "Sorun kaynaÄının eklenti uyumsuzluÄu olup olmadıÄının belirlenmesi için etkin eklentilerin listesini bildirime ekle">
-<!ENTITY attachExtensions.accesskey "u">
-<!ENTITY sendButton.label "Bildirimi gönder">
-<!ENTITY sendButton.accesskey "b">
-<!ENTITY showData.label "Bildirim verisini göster">
-<!ENTITY data.label "Bildirim verisi:">
-<!ENTITY data.accesskey "v">
-<!ENTITY sendPage.heading "Bildirimi gönder">
-<!ENTITY sendPage.waitMessage "Lüftfen Adblock Plus bildirimi gönderirken bekleyin.">
-<!ENTITY sendPage.confirmation "Bildiriminiz kaydedildi ve ona aÅaÄıdaki adresten ulaÅabilirsiniz:">
-<!ENTITY sendPage.knownIssue "BildirdiÄiniz sorun büyük olasılıkla biliniyor. Daha fazla bilgi:">
-<!ENTITY sendPage.errorMessage "Hata bildirimi gönderme giriÅiminiz "?1?" hata koduyla baÅarısız oldu. Lütfen internete baÄlı olduÄunuzdan emin olun ve yeniden deneyin. Sorun devam ederse lütfen [link]Adblock Plus forumunda[/link] yardım isteyin.">
-<!ENTITY sendPage.retry.label "Yeniden gönder">
-<!ENTITY copyLink.label "Bildirimi baÄlantısını kopyala">
-<!ENTITY copyLink.accesskey "k">
diff --git a/chrome/locale/tr/settings.dtd b/chrome/locale/tr/settings.dtd
deleted file mode 100644
index 981f797..0000000
--- a/chrome/locale/tr/settings.dtd
+++ /dev/null
@@ -1,89 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus Tercihleri">
-<!ENTITY filters.label "Süzgeçler">
-<!ENTITY filters.accesskey "G">
-<!ENTITY add.label "Süzgeç ekle">
-<!ENTITY add.accesskey "K">
-<!ENTITY addsubscription.label "Süzgeç aboneliÄi ekle">
-<!ENTITY addsubscription.accesskey "E">
-<!ENTITY synchsubscriptions.label "Tüm abonelikleri güncelle">
-<!ENTITY synchsubscriptions.accesskey "C">
-<!ENTITY import.label "Süzgeçleri içe aktar">
-<!ENTITY import.accesskey "Z">
-<!ENTITY export.label "Süzgeçleri dıÅa aktar">
-<!ENTITY export.accesskey "D">
-<!ENTITY clearall.label "Tüm süzgeçleri kaldır">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "İstatistikleri sıfırla">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "Düzen">
-<!ENTITY edit.accesskey "z">
-<!ENTITY cut.label "Kes">
-<!ENTITY cut.accesskey "e">
-<!ENTITY copy.label "Kopyala">
-<!ENTITY copy.accesskey "K">
-<!ENTITY paste.label "YapıÅtır">
-<!ENTITY paste.accesskey "Y">
-<!ENTITY remove.label "Sil">
-<!ENTITY remove.accesskey "S">
-<!ENTITY menu.find.label "Bul">
-<!ENTITY menu.find.accesskey "B">
-<!ENTITY menu.findagain.label "Sonrakini bul">
-<!ENTITY menu.findagain.accesskey "A">
-<!ENTITY view.label "Görünüm">
-<!ENTITY view.accesskey "r">
-<!ENTITY sort.label "Sırala">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "SıralanmamıÅ">
-<!ENTITY sort.none.accesskey "m">
-<!ENTITY sort.ascending.label "A'da Z'ye sıralama">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "Z'den A'ya sıralama">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "Seçenekler">
-<!ENTITY options.accesskey "S">
-<!ENTITY enable.label "Adblock Plus'ı etkinleÅtir">
-<!ENTITY enable.accesskey "A">
-<!ENTITY showintoolbar.label "Araç çubuÄunda göster">
-<!ENTITY showintoolbar.accesskey "R">
-<!ENTITY showinstatusbar.label "Durum çubuÄunda göster">
-<!ENTITY showinstatusbar.accesskey "D">
-<!ENTITY objecttabs.label "Flash ve Java'yı kulakçıklarla belirt">
-<!ENTITY objecttabs.accesskey "J">
-<!ENTITY collapse.label "ÃÄeleri kapat">
-<!ENTITY collapse.accesskey "T">
-<!ENTITY sync.label "Adblock Plus ayarlarını eÅitle">
-<!ENTITY sync.accesskey "e">
-<!ENTITY help.label "Yardım">
-<!ENTITY help.accesskey "A">
-<!ENTITY gettingStarted.label "İlk adım">
-<!ENTITY gettingStarted.accesskey "k">
-<!ENTITY faq.label "Sıkça sorulan sorular">
-<!ENTITY faq.accesskey "S">
-<!ENTITY filterdoc.label "Adblock Plus süzgeç yazımı">
-<!ENTITY filterdoc.accesskey "z">
-<!ENTITY about.label "Adblock Plus hakkında">
-<!ENTITY about.accesskey "O">
-<!ENTITY description "Engellemek istediÄiniz adresleri yazın. Ãneriler için açılır menüye bakın. Daha genel süzgeçler tanımlamak için * iÅaretini kullanabilirsiniz. İleri düzeyde bilgiye sahip kullanıcılar düzenli ifadelere de (ör. /reklam\d+\.gif$/) baÅvurabilirler.">
-<!ENTITY filter.column "Süzgeç kuralı">
-<!ENTITY filter.accesskey "k">
-<!ENTITY slow.column "Süzgeçleri göster">
-<!ENTITY slow.accesskey "g">
-<!ENTITY enabled.column "Etkinlik">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "İsabet">
-<!ENTITY hitcount.accesskey "e">
-<!ENTITY lasthit.column "Son isabet">
-<!ENTITY lasthit.accesskey "i">
-<!ENTITY context.edit.label "Süzgeci düzenle">
-<!ENTITY context.resethitcount.label "İsabet istatistiÄi sıfırlanacak süzgeç:">
-<!ENTITY context.synchsubscription.label "AboneliÄi eÅle">
-<!ENTITY context.editsubscription.label "AboneliÄi düzenle">
-<!ENTITY context.moveup.label "Yukarıya taÅı">
-<!ENTITY context.movedown.label "AÅaÄıya taÅı">
-<!ENTITY context.movegroupup.label "ÃbeÄi yukarıya taÅı">
-<!ENTITY context.movegroupdown.label "ÃbeÄi aÅaÄıya taÅı">
-<!ENTITY context.enable.label "Devreye sok">
-<!ENTITY context.disable.label "Devreden çıkar">
-<!ENTITY apply.label "Uygula">
-<!ENTITY apply.accesskey "u">
-<!ENTITY fennec.subscription.label "Süzgeç aboneliÄi">
diff --git a/chrome/locale/tr/subscriptionSelection.dtd b/chrome/locale/tr/subscriptionSelection.dtd
deleted file mode 100644
index 11286e4..0000000
--- a/chrome/locale/tr/subscriptionSelection.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus süzgeç aboneliÄi ekle">
-<!ENTITY dialog.title.edit "Süzgeç aboneliklerini düzenle">
-<!ENTITY description.newInstall "Adblock Plus herhangi bir süzgeç aboneliÄiyle birlikte en etkin Åekilde kullanılır. Bu abonelikler diÄer Adblock Plus kullanıcıları tarafından ücretsiz sunulmaktadır. Dilinize en uygun abonelik seçilmiÅ durumda.">
-<!ENTITY subscriptionSelector.label "Lütfen listeden bir süzgeç aboneliÄi seçin:">
-<!ENTITY viewList.label "Süzgeçlere bak">
-<!ENTITY visitHomepage.label "Ana sayfaya git">
-<!ENTITY addSubscription.label "Abone ol">
-<!ENTITY saveSubscription.label "AboneliÄi kaydet">
-<!ENTITY other.label "BaÅka abonelik ekle">
-<!ENTITY other.accesskey "B">
-<!ENTITY list.download.failed "Adblock Plus abonelik listesini alamadı">
-<!ENTITY list.download.retry "Yeniden dene">
-<!ENTITY list.download.website "Siteye git">
-<!ENTITY fromWeb.description "Lütfen bu süzgeç aboneliÄini eklemek istediÄinizi teyit edin. Eklemeden önce abonelik adını ve konumunu deÄiÅtirebilirsiniz.">
-<!ENTITY edit.description "Abonelik adını ve konumunu gerekirse deÄiÅtirebilirsiniz.">
-<!ENTITY external.description "Bu harici bir süzgeç aboneliÄi ve aboneliÄi baÅlatan eklenti tarafından güncellenecek.">
-<!ENTITY title.label "AboneliÄin adı:">
-<!ENTITY title.accesskey "A">
-<!ENTITY location.label "Süzgeç listesi konumu:">
-<!ENTITY location.accesskey "L">
-<!ENTITY autodownload.label "Otomatik olarak güncelle">
-<!ENTITY autodownload.accesskey "O">
-<!ENTITY supplementMessage "Bu süzgeç aboneliÄi henüz kullanmadıÄınız "?1?" süzgeç aboneliÄiyle kullanılmak üzere hazırlanmıÅ.">
-<!ENTITY addMain.label ""?1?" süzgeç aboneliÄini de ekle">
-<!ENTITY addMain.accesskey "s">
diff --git a/chrome/locale/uk/meta.properties b/chrome/locale/uk/meta.properties
deleted file mode 100644
index e7b1173..0000000
--- a/chrome/locale/uk/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=ТимоÑÑй ÐабиÑ
-name=Adblock Plus
-description=Скажи «Ðл ÑекламÑ!
-description.short=ÐÑаÑÑÑÑÑ Ñеклами? ÐепокоÑÑÑ ÑÑеженнÑ? ÐабÑидли банеÑи? ÐÑÑановÑÑÑ Adblock Plus Ñоб повеÑнÑÑи ÑÐ¾Ð±Ñ Ð²Ð»Ð°Ð´Ñ Ð½Ð°Ð´ ÑнÑеÑнеÑом, Ñоб змÑниÑи Ñе, ÑÐºÐ¾Ñ Ð²Ð¸ баÑиÑе меÑежÑ.\n\nÐоÑоÑкий вÑдеооглÑд знаÑ
одиÑÑÑÑ Ð½Ð° http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=ÐÑÑановÑÑÑ Adblock Plus Ñоб повеÑнÑÑи ÑÐ¾Ð±Ñ Ð²Ð»Ð°Ð´Ñ Ð½Ð°Ð´ ÑнÑеÑнеÑом, Ñоб баÑиÑи меÑÐµÐ¶Ñ ÑакоÑ, Ñк вам Ñого Ñ
оÑеÑÑÑÑ. Ðо ÑÑого додаÑÐºÑ Ñ Ð±ÑлÑÑе ÑоÑока ÑÑлÑÑÑовиÑ
пÑдпиÑок деÑÑÑками мов. Це дозволÑÑ Ð°Ð²ÑомаÑиÑно налаÑÑÑваÑи його на бÑдÑ-ÑÐºÑ Ð¿Ð¾ÑÑеби, вÑд пÑибиÑÐ°Ð½Ð½Ñ Ð¾Ð½Ð»Ð°Ð¹Ð½Ð¾Ð²Ð¾Ñ Ñеклами до блокÑÐ²Ð°Ð½Ð½Ñ Ð²ÑÑÑ
вÑдомиÑ
зловмиÑниÑ
ÑайÑÑв. Adblock Plus Ñакож дозволÑÑ Ð½Ð°ÑÑÑоÑваÑи ваÑÑ ÑÑлÑÑÑи з Ð´Ð¾Ð¿Ð¾Ð¼Ð¾Ð³Ð¾Ñ Ð±ÐµÐ·Ð»ÑÑÑ ÐºÐ¾ÑиÑниÑ
можливоÑÑей. ТакиÑ
Ñк конÑекÑÑна команда Ð´Ð»Ñ Ð·Ð¾Ð±ÑаженÑ, ÑÑлиÑок блокÑÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ð¾Ð±âÑкÑÑв Flash Ñа Java Ñа повний пеÑелÑк елеменÑÑв ÑÑоÑÑнки Ð´Ð»Ñ Ð±Ð»Ð¾ÐºÑÐ²Ð°Ð½Ð½Ñ ÑкÑипÑÑв Ñа ÑÑилÑв.
diff --git a/chrome/locale/uk/overlay.dtd b/chrome/locale/uk/overlay.dtd
deleted file mode 100644
index aa8b24b..0000000
--- a/chrome/locale/uk/overlay.dtd
+++ /dev/null
@@ -1,25 +0,0 @@
-<!ENTITY status.tooltip "СÑаÑÑÑ:">
-<!ENTITY blocked.tooltip "ÐÐ°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи на ÑÑй ÑÑоÑÑнÑÑ:">
-<!ENTITY filters.tooltip "ÐайбÑлÑÑ ÑаÑÑо заÑÑоÑÐ¾Ð²Ð°Ð½Ñ ÑÑлÑÑÑи:">
-<!ENTITY menuitem.label "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Adblock Plus">
-<!ENTITY menuitem.accesskey "A">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: елеменÑи ÑÑоÑÑнки">
-<!ENTITY context.image.label "Adblock Plus: заблокÑваÑи зобÑаженнÑ">
-<!ENTITY context.object.label "Adblock Plus: заблокÑваÑи обâÑкÑ">
-<!ENTITY context.frame.label "Adblock Plus: заблокÑваÑи ÑÑейм">
-<!ENTITY context.media.label "Adblock Plus: ÐлокÑваÑи аÑдÑо/вÑдео">
-<!ENTITY context.removeWhitelist.label "Adblock Plus: Ðнов ÑвÑмкнÑÑи Ð´Ð»Ñ ÑÑÑÑ ÑÑоÑÑнки">
-<!ENTITY sidebar.title "ÐлеменÑи вÑдкÑиÑÐ¾Ñ ÑÑоÑÑнки">
-<!ENTITY sendReport.label "ÐовÑдомиÑи пÑо пÑоблеми на ÑÑоÑÑнÑÑ">
-<!ENTITY sendReport.accesskey "Ñ">
-<!ENTITY settings.label "ÐалаÑÑÑваннÑ">
-<!ENTITY settings.accesskey "Ñ">
-<!ENTITY opensidebar.label "ÐÑдкÑиÑи ÑпиÑок елеменÑÑв">
-<!ENTITY opensidebar.accesskey "п">
-<!ENTITY closesidebar.label "ÐакÑиÑи ÑпиÑок елеменÑÑв">
-<!ENTITY closesidebar.accesskey "п">
-<!ENTITY whitelist.site.label "ÐимкнÑÑи: на ?1?">
-<!ENTITY whitelist.page.label "ÐимкнÑÑи: ÑÑлÑки на ÑÑй ÑÑоÑÑнÑÑ">
-<!ENTITY objecttab.title "ÐаблокÑваÑи">
-<!ENTITY objecttab.tooltip "ÐаÑиÑнÑÑÑ ÑÑÑ, Ñоб заблокÑваÑи Ñей обâÑкÑ">
diff --git a/chrome/locale/uk/sendReport.dtd b/chrome/locale/uk/sendReport.dtd
deleted file mode 100644
index 9283acc..0000000
--- a/chrome/locale/uk/sendReport.dtd
+++ /dev/null
@@ -1,73 +0,0 @@
-<!ENTITY wizard.title "ÐовÑдомиÑи пÑо пÑоблемÑ">
-<!ENTITY privacyPolicy.label "ÐолÑÑика пÑиваÑноÑÑÑ">
-<!ENTITY dataCollector.heading "ÐаÑкаво пÑоÑимо до звÑÑÑваÑа пÑо пÑоблеми">
-<!ENTITY dataCollector.description "ÐаждÑÑÑ, Adblock Plus збиÑÐ°Ñ Ð¿Ð¾ÑÑÑÐ±Ð½Ñ Ð´Ð°Ð½Ñ">
-<!ENTITY typeSelector.heading "ÐибеÑÑÑÑ Ñип пÑоблеми">
-<!ENTITY typeSelector.description "Це вÑкно пÑоведе Ð²Ð°Ñ Ð¿Ð¾ кÑокаÑ
надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ Ð¿Ñо пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð· Adblock Plus. СпеÑÑÑ, вибеÑÑÑÑ Ñип пÑоблеми з ÑÐºÐ¾Ñ Ð²Ð¸ зÑÑкнÑлиÑÑ Ð½Ð° ÑÑй ÑÑоÑÑнÑÑ:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus блокÑÑ Ð·Ð°Ð±Ð°Ð³Ð°Ñо">
-<!ENTITY typeSelector.falsePositive.accesskey "б">
-<!ENTITY typeSelector.falsePositive.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо на ÑÑоÑÑнÑÑ Ð²ÑдÑÑÑÐ½Ñ ÑаÑÑина вмÑÑÑÑ, або ÑкÑо вона показÑÑÑÑÑÑ Ñи ÑÑнкÑÑонÑÑ Ð½ÐµÐ¿ÑавилÑно. Ðи можеÑе пеÑевÑÑиÑи, Ñи бÑв Adblock Plus пÑиÑÐ¸Ð½Ð¾Ñ ÑимÑаÑово його вимкнÑвÑи.">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus не блокÑÑ ÑекламÑ">
-<!ENTITY typeSelector.falseNegative.accesskey "Ñ">
-<!ENTITY typeSelector.falseNegative.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо Ñеклама показÑÑÑÑ Ð¿Ð¾Ð¿Ñи Ñе Ñо Adblock Plus ÑвÑмкнено.">
-<!ENTITY typeSelector.other.label "ÐнÑа пÑоблема">
-<!ENTITY typeSelector.other.accesskey "Ñ">
-<!ENTITY typeSelector.other.description "ÐибеÑÑÑÑ Ñей ваÑÑÐ°Ð½Ñ ÑкÑо ви пÑдозÑÑÑÑе пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ñаме з Adblock Plus нÑж з його ÑÑлÑÑÑами.">
-<!ENTITY showRecentReports.label "ÐоказаÑи недавно заÑÐ»Ð°Ð½Ñ Ð·Ð²ÑÑи">
-<!ENTITY recentReports.label "ÐаÑÑ Ð½ÐµÐ´Ð°Ð²Ð½Ð¾ заÑÐ»Ð°Ð½Ñ Ð·Ð²ÑÑи">
-<!ENTITY recentReports.clear.label "ÐилÑÑиÑи вÑÑ Ð·Ð²ÑÑи">
-<!ENTITY recentReports.clear.accesskey "Ð">
-<!ENTITY issues.description "Adblock Plus знайÑов пÑоблеми Ñ Ð²Ð°ÑиÑ
налаÑÑÑваннÑÑ
коÑÑÑ, можливо, ÑпÑиÑинили ÑÑ Ð¿ÑоблемÑ, або ÑÑладнÑÑÑ ÑозглÑд звÑÑÑ.">
-<!ENTITY issues.whitelist.description "Adblock Plus наÑÐ°Ð·Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¸Ð¹ на ÑÑй ÑÑоÑÑнÑÑ Ð¿Ñо ÑÐºÑ Ð²Ð¸ звÑÑÑÑÑе. УвÑмкнÑÑÑ Ð¹Ð¾Ð³Ð¾ Ñа пеÑегÑÑзÑÑÑ ÑÑоÑÑÐ½ÐºÑ Ð¿ÐµÑед надÑиланнÑм звÑÑÑ. Це допоможе в його ÑозглÑдÑ.">
-<!ENTITY issues.whitelist.remove.label "ÐеÑеÑвÑмкнÑÑи Adblock Plus на ÑÑй ÑÑоÑÑнÑÑ">
-<!ENTITY issues.disabled.description "Adblock Plus вимкнено, вÑн не блокÑваÑиме нÑÑого Ñ Ð¿Ð¾ÑоÑÐ½Ð¾Ð¼Ñ ÑÑанÑ.">
-<!ENTITY issues.disabled.enable.label "УвÑмкнÑÑи Adblock Plus">
-<!ENTITY issues.nofilters.description "Adblock Plus не блокÑÑ Ð½ÑÑого на поÑоÑнÑй ÑÑоÑÑнÑÑ. Ðаайже напевне, пÑоблема, ÑÐºÑ Ð²Ð¸ баÑиÑе, не повâÑзана з Adblock Plus.">
-<!ENTITY issues.nosubscriptions.description "Ðи не пÑдпиÑÐ°Ð½Ñ Ð½Ð° жоден з гоÑовиÑ
ÑпиÑкÑв ÑÑлÑÑÑÑÐ²Ð°Ð½Ð½Ñ ÐºÐ¾ÑÑÑ Ð°Ð²ÑомаÑиÑно вилÑÑаÑÑÑ Ð½ÐµÐ±Ð°Ð¶Ð°Ð½Ð¸Ð¹ вмÑÑÑ Ð· ÑайÑÑв.">
-<!ENTITY issues.nosubscriptions.add.label "ÐодаÑи пÑдпиÑÐºÑ Ð½Ð° ÑÑлÑÑÑи">
-<!ENTITY issues.ownfilters.description "ÐеÑÐºÑ Ð· заÑÑоÑованиÑ
ÑÑлÑÑÑÑв бÑли Ð·Ð°Ð´Ð°Ð½Ñ ÐºÐ¾ÑиÑÑÑваÑем. ÐимкнÑÑÑ ÑÑлÑÑÑи Ñо могли ÑпÑиÑиниÑи пÑоблемÑ.">
-<!ENTITY issues.ownfilters.disable.label "ÐимкнÑÑи ÑÑлÑÑÑ">
-<!ENTITY issues.disabledgroups.description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑки/гÑÑпи вимкненÑ, але могли вплинÑÑи на ÑÑ ÑÑоÑÑнкÑ:">
-<!ENTITY issues.disabledgroups.enable.label "УвÑмкнÑÑи ÑÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑкÑ/гÑÑпÑ">
-<!ENTITY issues.disabledfilters.description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑи вимкненÑ, але могли вплинÑÑи на ÑÑ ÑÑоÑÑнкÑ:">
-<!ENTITY issues.disabledfilters.enable.label "УвÑмкнÑÑи ÑÑлÑÑÑ">
-<!ENTITY issues.override.label "ÐалаÑÑÑÐ²Ð°Ð½Ð½Ñ Ð¿ÑавилÑнÑ, пÑодовжиÑи звÑÑ">
-<!ENTITY issues.override.accesskey "п">
-<!ENTITY issues.change.description "ÐаÑÑ Ð½Ð°Ð»Ð°ÑÑÑÐ²Ð°Ð½Ð½Ñ Ð±Ñло змÑнено. ÐеÑегÑÑзÑÑÑ ÑÑоÑÑÐ½ÐºÑ Ð´Ð»Ñ Ð¿ÐµÑевÑÑки внеÑениÑ
змÑн Ñа заÑлÑÑÑ Ð·Ð²ÑÑ ÑкÑо пÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð½Ðµ виÑÑÑено.">
-<!ENTITY typeWarning.description "Ðи вказали Ñо Ñ
оÑеÑе повÑдомиÑи пÑо загалÑÐ½Ñ Ð¿ÑÐ¾Ð±Ð»ÐµÐ¼Ñ Ð² Adblock Plus, а не в ÑÑлÑÑÑаÑ
. ÐаÑважÑе, Ñо пÑо ÑÐ°ÐºÑ Ð¿Ñоблеми найкÑаÑе повÑдомлÑÑи до [link]ÑоÑÑÐ¼Ñ Adblock Plus[/link]. ÐайÑÑÑа звÑÑÑв ÑлÑд викоÑиÑÑовÑваÑи лиÑе в додаÑок до ÑÑнÑÑÑÐ¾Ñ Ð´Ð¸ÑкÑÑÑÑ, оÑкÑлÑки нÑÑ
Ñо не побаÑиÑÑ Ð²Ð°Ñого звÑÑÑ, ÑкÑо не поÑÑавиÑи на нÑого поÑиланнÑ. Ðи оÑÑимаÑÑе авÑомаÑиÑно ÑÑвоÑене поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿ÑÑÐ»Ñ Ð½Ð°Ð´ÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ.">
-<!ENTITY typeWarning.override.label "Я ÑозÑмÑÑ, Ñа вÑе ж Ñ
оÑÑ Ð¿Ð¾ÑлаÑи звÑÑ">
-<!ENTITY typeWarning.override.accesskey "Ñ">
-<!ENTITY reloadButton.label "ÐеÑегÑÑзиÑи ÑÑоÑÑнкÑ">
-<!ENTITY reloadButton.accesskey "Ð">
-<!ENTITY screenshot.heading "ÐодаÑи ÑкÑÑнÑоÑ">
-<!ENTITY screenshot.description "Та Ñама ÑÑоÑÑнка може виглÑдаÑи по ÑÑÐ·Ð½Ð¾Ð¼Ñ Ð´Ð»Ñ ÑÑзниÑ
лÑдей. ÐнÑмок екÑана (ÑкÑÑнÑоÑ) може допомогÑи нам зÑозÑмÑÑи пÑоблемÑ. Ðи можеÑе вилÑÑиÑи конÑÑденÑÑÐ¹Ð½Ñ ÑаÑÑини, а Ñакож познаÑиÑи облаÑÑÑ Ð´Ðµ пÑиÑÑÑÐ½Ñ Ð¿Ñоблема. Щоб Ñе зÑобиÑи, клаÑнÑÑÑ Ð¿Ð¾ вÑдповÑднÑй клавÑÑÑ Ñа вибеÑÑÑÑ Ð¾Ð±Ð»Ð°ÑÑÑ Ð·Ð¾Ð±ÑÐ°Ð¶ÐµÐ½Ð½Ñ Ð¼Ð¸ÑкоÑ.">
-<!ENTITY screenshot.attach.label "ÐодаÑи зобÑÐ°Ð¶ÐµÐ½Ð½Ñ ÑÑоÑÑнки до звÑÑÑ">
-<!ENTITY screenshot.attach.accesskey "Ð">
-<!ENTITY screenshot.mark.label "ÐознаÑиÑи пÑоблемÑ">
-<!ENTITY screenshot.mark.accesskey "з">
-<!ENTITY screenshot.remove.label "ÐилÑÑиÑи конÑÑденÑÑÐ¹Ð½Ñ Ð´Ð°Ð½Ñ">
-<!ENTITY screenshot.remove.accesskey "Ð">
-<!ENTITY screenshot.undo.label "ÐовеÑнÑÑи">
-<!ENTITY screenshot.undo.accesskey "Ð">
-<!ENTITY commentPage.heading "ÐвеÑÑи коменÑаÑ">
-<!ENTITY commentPage.description "ÐижÑе ви можеÑе ввеÑÑи коменÑÐ°Ñ Ñоб допомогÑи нам зÑозÑмÑÑи пÑоблемÑ. Цей кÑок необовâÑзковий, пÑоÑе Ñекомендований коли пÑоблема не ÑамооÑевидна. Ðи можеÑе Ñакож пеÑеглÑнÑÑи ÑвÑй коменÑÐ°Ñ Ð¿ÐµÑед надÑиланнÑм.">
-<!ENTITY comment.label "ÐоменÑÐ°Ñ (необовâÑзково):">
-<!ENTITY comment.accesskey "Ð">
-<!ENTITY comment.lengthWarning "Ðовжина коменÑаÑÑ Ð¿ÐµÑевиÑÑÑ 1000 ÑимволÑв. ÐÑдÑÑÑ Ð¿Ð¾ÑÐ»Ð°Ð½Ñ Ð»Ð¸Ñе пеÑÑÑ 1000 ÑимволÑв.">
-<!ENTITY email.label "Ðл.поÑÑа Ð´Ð»Ñ Ð´Ð°Ð»ÑÑого звâÑÐ·ÐºÑ (необовâÑзково):">
-<!ENTITY email.accesskey "Ð">
-<!ENTITY attachExtensions.label "ÐолÑÑиÑи до звÑÑÑ ÑпиÑок акÑивниÑ
ÑозÑиÑÐµÐ½Ñ â на випадок ÑкÑо пÑиÑÐ¸Ð½Ð¾Ñ Ð¿Ñоблеми Ñ ÐºÐ¾Ð½ÑлÑÐºÑ ÑозÑиÑенÑ">
-<!ENTITY attachExtensions.accesskey "Ñ">
-<!ENTITY sendButton.label "ÐадÑÑлаÑи звÑÑ">
-<!ENTITY sendButton.accesskey "Ð">
-<!ENTITY showData.label "ÐоказаÑи Ð´Ð°Ð½Ñ Ð·Ð²ÑÑÑ">
-<!ENTITY data.label "ÐÐ°Ð½Ñ Ð·Ð²ÑÑÑ:">
-<!ENTITY data.accesskey "д">
-<!ENTITY sendPage.heading "ÐадÑÑлаÑи звÑÑ">
-<!ENTITY sendPage.waitMessage "ÐаждÑÑÑ Ð´Ð¾ÐºÐ¸ Adblock Plus надÑÐ¸Ð»Ð°Ñ Ð²Ð°Ñ Ð·Ð²ÑÑ.">
-<!ENTITY sendPage.confirmation "ÐвÑÑ Ð±Ñло запиÑано. Ðи можеÑе пеÑеглÑнÑÑи його за поÑиланнÑм:">
-<!ENTITY sendPage.knownIssue "ÐÑоблема пÑо ÑÐºÑ Ð²Ð¸ повÑдомили вже вÑдома. ÐеÑалÑнÑÑе:">
-<!ENTITY sendPage.errorMessage "Ðомилка вÑдпÑавки звÑÑÑ: «?1?». УпевнÑÑÑÑÑ Ñо ви пÑдâÑÐ´Ð½Ð°Ð½Ñ Ð´Ð¾ ÑнÑеÑнеÑÑ Ñа ÑпÑобÑйÑе Ñе Ñаз. ЯкÑо пÑоблема не зникаÑ, бÑÐ´Ñ Ð»Ð°Ñка поÑÑкайÑе допомоги на [link]ÑоÑÑÐ¼Ñ Adblock Plus[/link].">
-<!ENTITY sendPage.retry.label "ÐадÑÑлаÑи Ñе Ñаз">
-<!ENTITY copyLink.label "СкопÑÑваÑи поÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð·Ð²ÑÑÑ">
-<!ENTITY copyLink.accesskey "к">
diff --git a/chrome/locale/uk/settings.dtd b/chrome/locale/uk/settings.dtd
deleted file mode 100644
index 7ecd001..0000000
--- a/chrome/locale/uk/settings.dtd
+++ /dev/null
@@ -1,87 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus - ÐалаÑÑÑваннÑ">
-<!ENTITY filters.label "ФÑлÑÑÑи">
-<!ENTITY filters.accesskey "Ñ">
-<!ENTITY add.label "ÐодаÑи ÑÑлÑÑÑ">
-<!ENTITY add.accesskey "д">
-<!ENTITY addsubscription.label "ÐодаÑи пÑдпиÑкÑ">
-<!ENTITY addsubscription.accesskey "о">
-<!ENTITY synchsubscriptions.label "ÐикаÑаÑи вÑÑ Ð¿ÑдпиÑки">
-<!ENTITY synchsubscriptions.accesskey "п">
-<!ENTITY import.label "ÐмпоÑÑ ÑÑлÑÑÑÑв">
-<!ENTITY import.accesskey "м">
-<!ENTITY export.label "ÐкÑпоÑÑ ÑÑлÑÑÑÑв">
-<!ENTITY export.accesskey "к">
-<!ENTITY clearall.label "СÑеÑÑи вÑÑ ÑÑлÑÑÑи">
-<!ENTITY clearall.accesskey "и">
-<!ENTITY resethitcounts.label "ÐбнÑлиÑи ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ñ">
-<!ENTITY resethitcounts.accesskey "Ñ">
-<!ENTITY edit.label "ÐÑавка">
-<!ENTITY edit.accesskey "Ñ">
-<!ENTITY cut.label "ÐиÑÑзаÑи">
-<!ENTITY cut.accesskey "Ñ">
-<!ENTITY copy.label "ÐопÑÑваÑи">
-<!ENTITY copy.accesskey "о">
-<!ENTITY paste.label "ÐÑÑавиÑи">
-<!ENTITY paste.accesskey "а">
-<!ENTITY remove.label "ÐилÑÑиÑи">
-<!ENTITY remove.accesskey "и">
-<!ENTITY menu.find.label "ÐнайÑи ÑÑлÑÑÑ">
-<!ENTITY menu.find.accesskey "н">
-<!ENTITY menu.findagain.label "ÐнайÑи наÑÑÑпний">
-<!ENTITY menu.findagain.accesskey "Ñ">
-<!ENTITY view.label "ÐиглÑд">
-<!ENTITY view.accesskey "Ð">
-<!ENTITY sort.label "СоÑÑÑваÑи за">
-<!ENTITY sort.accesskey "С">
-<!ENTITY sort.none.label "ÐеÑоÑÑовано">
-<!ENTITY sort.none.accesskey "Ð">
-<!ENTITY sort.ascending.label "ÐÑд Рдо Я">
-<!ENTITY sort.ascending.accesskey "Ð">
-<!ENTITY sort.descending.label "ÐÑд Я до Ð">
-<!ENTITY sort.descending.accesskey "Я">
-<!ENTITY options.label "ÐалаÑÑÑваннÑ">
-<!ENTITY options.accesskey "а">
-<!ENTITY enable.label "УвÑмкнÑÑи Adblock Plus">
-<!ENTITY enable.accesskey "У">
-<!ENTITY showintoolbar.label "ÐоказÑваÑи в Ð¿Ð°Ð½ÐµÐ»Ñ ÑнÑÑÑÑменÑÑв">
-<!ENTITY showintoolbar.accesskey "к">
-<!ENTITY showinstatusbar.label "ÐоказÑваÑи в ÑÑÐ´ÐºÑ ÑÑанÑ">
-<!ENTITY showinstatusbar.accesskey "Ñ">
-<!ENTITY objecttabs.label "ÐоказÑваÑи ÑÑлик на Flash Ñ Java">
-<!ENTITY objecttabs.accesskey "Ñ">
-<!ENTITY collapse.label "ÐгоÑÑаÑи Ð·Ð°Ð±Ð»Ð¾ÐºÐ¾Ð²Ð°Ð½Ñ ÐµÐ»ÐµÐ¼ÐµÐ½Ñи">
-<!ENTITY collapse.accesskey "о">
-<!ENTITY help.label "ÐовÑдка">
-<!ENTITY help.accesskey "о">
-<!ENTITY gettingStarted.label "ÐоÑаÑкÑвÑÑм">
-<!ENTITY gettingStarted.accesskey "Ð">
-<!ENTITY faq.label "ÐиÑаннÑ, Ñо ÑаÑÑо ÑÑавлÑÑÑÑÑ (англÑйÑÑкоÑ)">
-<!ENTITY faq.accesskey "и">
-<!ENTITY filterdoc.label "Ð¡ÐºÐ»Ð°Ð´Ð°Ð½Ð½Ñ ÑÑлÑÑÑÑв Ð´Ð»Ñ Adblock Plus (англÑйÑÑкоÑ)">
-<!ENTITY filterdoc.accesskey "а">
-<!ENTITY about.label "ÐÑо Adblock Plus">
-<!ENTITY about.accesskey "о">
-<!ENTITY description "ÐаÑÑÑÐ¿Ð½Ñ ÑÑлÑÑÑи визнаÑаÑÑÑ ÑÐºÑ Ð°Ð´ÑеÑи блокÑÑÑÑÑÑ Ñа ÑÐºÑ Ð´Ð¾Ð·Ð²Ð¾Ð»ÑÑÑÑÑÑ:">
-<!ENTITY filter.column "ÐÑавило ÑÑлÑÑÑÑваннÑ">
-<!ENTITY filter.accesskey "Ñ">
-<!ENTITY slow.column "ÐовÑлÑÐ½Ñ ÑÑлÑÑÑи">
-<!ENTITY slow.accesskey "Ñ">
-<!ENTITY enabled.column "УвÑмкнено">
-<!ENTITY enabled.accesskey "в">
-<!ENTITY hitcount.column "ÐопаданÑ">
-<!ENTITY hitcount.accesskey "п">
-<!ENTITY lasthit.column "ÐÑÑÐ°Ð½Ð½Ñ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ð½Ñ">
-<!ENTITY lasthit.accesskey "Ð">
-<!ENTITY context.edit.label "РедагÑваÑи ÑÑлÑÑÑ">
-<!ENTITY context.resethitcount.label "ÐбнÑлиÑи ÑÑаÑиÑÑÐ¸ÐºÑ Ð¿Ð¾Ð¿Ð°Ð´Ð°Ð½Ñ Ð´Ð»Ñ ÑÑлÑÑÑÑ">
-<!ENTITY context.synchsubscription.label "ÐикаÑаÑи ÑÑлÑÑÑи наново">
-<!ENTITY context.editsubscription.label "РедагÑваÑи пÑдпиÑкÑ">
-<!ENTITY context.moveup.label "ÐÑÑÑиÑи вгоÑÑ">
-<!ENTITY context.movedown.label "ÐÑÑÑиÑи вниз">
-<!ENTITY context.movegroupup.label "ÐÑÑÑиÑи гÑÑÐ¿Ñ Ð²Ð³Ð¾ÑÑ">
-<!ENTITY context.movegroupdown.label "ÐÑÑÑиÑи гÑÑÐ¿Ñ Ð²Ð½Ð¸Ð·">
-<!ENTITY context.enable.label "УвÑмкнÑÑи">
-<!ENTITY context.disable.label "ÐимкнÑÑи">
-<!ENTITY apply.label "ÐаÑÑоÑÑваÑи">
-<!ENTITY apply.accesskey "Ñ">
-<!ENTITY fennec.subscription.label "ФÑлÑÑÑÐ¾Ð²Ñ Ð¿ÑдпиÑки">
diff --git a/chrome/locale/vi/meta.properties b/chrome/locale/vi/meta.properties
deleted file mode 100644
index f3c2597..0000000
--- a/chrome/locale/vi/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Nguyá»
n Mạnh Hùng
-name=Adblock Plus
-description=Quảng cáo Äã là dÄ© vãng!
-description.short=Bá»±c bá»i vì quảng cáo? Khó chá»u vì bá» theo dõi? Phiá»n vì biá»u ngữ (banner)? Cà i Äặt Adblock Plus ngay Äá» già nh lại quyá»n kiá»m soát internet và thay Äá»i cách thức mà bạn xem web.\n\nXem Äoạn phim giá»i thiá»u á» http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus cho phép bạn già nh lại quyá»n kiá»m soát internet và xem web theo cách bạn muá»n. Tiá»n Ãch nà y ÄÆ°á»£c há» trợ bá»i hÆ¡n bá»n mươi bá» lá»c trá»n gói vá»i hà ng chục ngôn ngữ, sẽ tá»± Äá»ng cấu hình cho các mục ÄÃch từ gỡ bá» quảng cáo trá»±c tuyến cho Äến viá»c chặn các tên miá»n chứa phần má»m Äá»c hại. Adblock Plus cÅ©ng cho phép bạn tùy biến bá» lá»c vá»i sá»± há» trợ cá»§a nhiá»u tÃnh nÄng hữu Ãch khác nhau, bao gá»m tùy chá»n ngữ cảnh cho hình ảnh, thẻ chặn Äá»i vá»i các Äá»i tượng Flash và Java, và má»t danh sách các mục có thá» chặn ÄÆ°á»£c Äá» gỡ bá» script và stylesheet.
diff --git a/chrome/locale/zh-CN/meta.properties b/chrome/locale/zh-CN/meta.properties
deleted file mode 100644
index 3f4a721..0000000
--- a/chrome/locale/zh-CN/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=blackdire
-name=Adblock Plus
-description=广åå·²æå¾äºï¼
-description.short=被广åå¼å¾æç«åï¼è¢«è·éé¼ æ çæ è¯å¼å¾ç¦å¿åï¼è¢«æ¨ªå¹
å¼å¾æå°åæ¶åï¼ç«å³å®è£
Adblock Plus æ¥éæ°åå¾ Internet çæ§å¶æå¹¶ä¸æ¹åæ¨æµè§ç½é¡µçæ¹å¼ã\n\nå¨ http://www.youtube.com/watch?v=oNvb2SjVjjI 䏿ç®ççè§é¢å¯ä¾åè
-description.long=Adblock Plus 让æ¨éæ°åå¾ Internet çæ§å¶æåæ¨æ¥çç½é¡µçæ¹å¼ãæ¬éå ç»ä»¶æ¯æå¤è¯è¨ï¼æè¶
è¿40个çè¿æ»¤è§å订é
ï¼è¿äºè¿æ»¤è§åä¼è¿è¡èªå¨é
ç½®ï¼ä¸ºæ¨è¿æ»¤æææ¥èªå·²ç¥ææ¶æåçå¨çº¿å¹¿åãAdblock Plus ä¹å
许æ¨éè¿åç§æç¨çç¹æ§æ¥èªå®ä¹æ¨çè¿æ»¤è§åï¼è¿äºç¹æ§å
æ¬ï¼å¾ççå³é®èåãFlash å Java 对象çè¿æ»¤æ ç¾ãç¨äºç§»é¤èæ¬åæ ·å¼è¡¨çå¯è¿æ»¤é¡¹ç®å表ã
diff --git a/chrome/locale/zh-TW/meta.properties b/chrome/locale/zh-TW/meta.properties
deleted file mode 100644
index eddecb9..0000000
--- a/chrome/locale/zh-TW/meta.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-translator=Jose Sun,knight00931
-name=Adblock Plus
-description=廣åå·²æéå»å¼ï¼
-description.short=è¨åæ¾äººç廣ååï¼å®³æè¢«è¿½è¹¤åï¼çæ¨ä¸å¤§ççæ©«å¹
廣ååï¼å¿«å®è£ Adblock Plus è®æ¨éæ¾ç¶²è·¯æ§å¶æ¬ï¼èªå·±æ±ºå®æ³ççå
§å®¹ã\n\nAdblock Plus çä¸åéå½±çä»ç´¹ï¼è±æï¼ï¼http://www.youtube.com/watch?v=oNvb2SjVjjI
-description.long=Adblock Plus è®æ¨éæ¾ç¶²è·¯æ§å¶æ¬ï¼èªå·±æ±ºå®æ³ççå
§å®¹ãæ¤éå å
ä»¶å
§å« 40 種以ä¸ä¸ååå®¶åèªè¨çéæ¿¾æ¢ä»¶éï¼è½èªåè¨å®å¾ç§»é¤ç·ä¸å»£åå°å°éæ¡æç¶²åçéæ¿¾ç¯åãAdblock Plus ä¹å
許èªè¨æ¨èªå·±çéæ¿¾æ¢ä»¶ï¼ä¸¦æè¨±å¤å¥½ç¨çåè½å婿¨é»æå»£åï¼ä¾å¦åçå³éµé»æãFlash å Java ç©ä»¶çé ç±¤é»æãæä¾å¯é»æé
ç®æ¸
å®ä»¥ä¾¿æ¨ç§»é¤ç¨å¼ç¢¼å樣å¼è¡¨ã
diff --git a/chrome/locale/zh-TW/overlay.dtd b/chrome/locale/zh-TW/overlay.dtd
deleted file mode 100644
index 2481f8c..0000000
--- a/chrome/locale/zh-TW/overlay.dtd
+++ /dev/null
@@ -1,27 +0,0 @@
-<!ENTITY status.tooltip "çæ
:">
-<!ENTITY blocked.tooltip "æ¤é å·²å°éé
ç®:">
-<!ENTITY filters.tooltip "æå¸¸ç¨çæ¢ä»¶:">
-<!ENTITY menuitem.label "Adblock Plus å好è¨å®">
-<!ENTITY menuitem.accesskey "b">
-<!ENTITY toolbarbutton.label "Adblock Plus">
-<!ENTITY view.blockableItems.label "Adblock Plus: å¯é»æé
ç®">
-<!ENTITY context.image.label "Adblock Plus: 黿åç">
-<!ENTITY context.object.label "Adblock Plus: 黿ç©ä»¶">
-<!ENTITY context.frame.label "Adblock Plus: é»æé æ¡">
-<!ENTITY context.media.label "Adblock Plus: 黿影é³">
-<!ENTITY context.removeWhitelist.label "Adblock Plus: æ¤é ä¸è¨çºç½åå®">
-<!ENTITY sidebar.title "æ¬é å¯é»æé
ç®">
-<!ENTITY sendReport.label "åå ±æ¤é é¢é¯èª¤">
-<!ENTITY sendReport.accesskey "R">
-<!ENTITY settings.label "å好è¨å®">
-<!ENTITY settings.accesskey "f">
-<!ENTITY opensidebar.label "éåå¯é»æé
ç®">
-<!ENTITY opensidebar.accesskey "b">
-<!ENTITY closesidebar.label "ééå¯é»æé
ç®">
-<!ENTITY closesidebar.accesskey "b">
-<!ENTITY whitelist.site.label "æ¤ç¶²åè¨çºç½åå®: ?1?">
-<!ENTITY whitelist.page.label "åªå°æ¤é é¢è¨çºç½åå®">
-<!ENTITY disable.label "å
¨é¨åç¨">
-<!ENTITY recommend.label "å¨ Facebook ä¸çµ¦æå建è°">
-<!ENTITY objecttab.title "å°é">
-<!ENTITY objecttab.tooltip "è«æéè£¡ç¨ Adblock Plus å°éæ¤ç©ä»¶">
diff --git a/chrome/locale/zh-TW/sendReport.dtd b/chrome/locale/zh-TW/sendReport.dtd
deleted file mode 100644
index c168cd8..0000000
--- a/chrome/locale/zh-TW/sendReport.dtd
+++ /dev/null
@@ -1,94 +0,0 @@
-<!ENTITY wizard.title "é¯èª¤åå ±å¨">
-<!ENTITY privacyPolicy.label "é±ç§æ¿ç">
-<!ENTITY dataCollector.heading "æ¡è¿ä½¿ç¨é¯èª¤åå ±å¨">
-<!ENTITY dataCollector.description "è«ç¨åï¼Adblock Plus æ£å¨èéå¿
è¦çè³æã">
-<!ENTITY typeSelector.heading "鏿åé¡é¡å">
-<!ENTITY typeSelector.description "æ¬è¦çªæä¸æ¥æ¥æå°æ¨å³éä¸ä»½ Adblock Plus é¯èª¤å ±åã
- é¦å
ï¼è«å
鏿æ¨éå°çé¯èª¤é¡å:">
-<!ENTITY typeSelector.falsePositive.label "Adblock Plus æå°ä¸è©²æçå
§å®¹">
-<!ENTITY typeSelector.falsePositive.accesskey "m">
-<!ENTITY typeSelector.falsePositive.description "鏿æ¤é¸é
表示網é 缺å°äºä¸»è¦å
§å®¹ã顯示é¯èª¤æåè½ç°å¸¸ã
- æ¨å¯ä»¥æ«æåç¨ Adblock Plus å¾åè©¦ä¸æ¬¡ï¼è¥åç¨å¾å顿¶å¤±ï¼
- åå¾å¯è½å°±æ¯ Adblock Plus çåé¡ã">
-<!ENTITY typeSelector.falseNegative.label "Adblock Plus æä¸ä½å»£å">
-<!ENTITY typeSelector.falseNegative.accesskey "v">
-<!ENTITY typeSelector.falseNegative.description "鏿æ¤é¸é
表示éç¶å·²åç¨ Adblock Plusï¼ä½å»£åä¾ç¶é¡¯ç¤ºå¨ç¶²é ä¸ã">
-<!ENTITY typeSelector.other.label "å
¶ä»é¯èª¤">
-<!ENTITY typeSelector.other.accesskey "t">
-<!ENTITY typeSelector.other.description "鏿æ¤é¸é
表示æå
¶ä»é¯èª¤ç¼çï¼è䏿¨æ·çæ¯ Adblock Plus æ¬èº«é æèééæ¿¾æ¢ä»¶å¼èµ·çé¯èª¤ã">
-<!ENTITY showRecentReports.label "顯示æè¿å³éçé¯èª¤å ±å">
-<!ENTITY recentReports.label "æ¨æè¿çé¯èª¤å ±å">
-<!ENTITY recentReports.clear.label "ç§»é¤ææé¯èª¤å ±å">
-<!ENTITY recentReports.clear.accesskey "R">
-<!ENTITY issues.description "Adblock Plus 嵿¸¬å°æäºè¨å®å¼å¯è½æé æè©²é¯èª¤ï¼ææ¯å½±é¿åæçµæã">
-<!ENTITY issues.whitelist.description "æ¨åå ±çé é¢å¨ Adblock Plus æ«æåç¨çæ¸
å®ï¼ç½åå®ï¼ä¸ã
- çºäºåå©åæé¯èª¤ï¼å¿
é å¨å³éé¯èª¤å ±ååéæ°åç¨ä¸¦éæ°è¼å
¥è©²é é¢ã">
-<!ENTITY issues.whitelist.remove.label "éæ°åç¨ Adblock Plus æ¼æ¤é é¢">
-<!ENTITY issues.disabled.description "Adblock Plus å·²åç¨ï¼ç®åçæ
ä¸ä¸æé»æä»»ä½ç¶²é å
§å®¹ã">
-<!ENTITY issues.disabled.enable.label "åç¨ Adblock Plus">
-<!ENTITY issues.nofilters.description "Adblock Plus æ¼æ¤é 颿²æé»æä»»ä½å
§å®¹ã
- æ¨åå ±çé¯èª¤å¯è½å Adblock Plus ç¡éã">
-<!ENTITY issues.nosubscriptions.description "æ¨ä¼¼ä¹æ²æè¨é±ä»»ä½é濾æ¢ä»¶éï¼è¨é±é濾æ¢ä»¶éå¯èªåç§»é¤èç¶²é å
§å®¹ç¡éç廣åã">
-<!ENTITY issues.nosubscriptions.add.label "è¨é±é濾æ¢ä»¶é">
-<!ENTITY issues.subscriptionCount.description "æ¨ä¼¼ä¹è¨é±äºéå¤çéæ¿¾æ¢ä»¶éãæåä¸å»ºè°é麼åï¼å çºéå¯è½æå¢å ç¼çé¯èª¤çæ©çãåææåç¡æ³æ¥åæ¨çé¯èª¤åå ±ï¼å çºå¾é£å辨æ¯åªåæ¢ä»¶éåºäºåé¡ãè«ç§»é¤ä¸éè¦çéæ¿¾æ¢ä»¶éå¾åæ¸¬è©¦ä¸æ¬¡ï¼ççé¯èª¤æ¯å¦ä»æç¼çã">
-<!ENTITY issues.openPreferences.label "éåéæ¿¾æ¢ä»¶è¨å®è¦çª">
-<!ENTITY issues.ownfilters.description "該é é¢çæäºé濾æ¢ä»¶æ¯æ¨èªå·±æåè¨å®çã
- è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
-<!ENTITY issues.ownfilters.disable.label "åç¨é濾æ¢ä»¶">
-<!ENTITY issues.disabledgroups.description "ä¸åéæ¿¾æ¢ä»¶é/éæ¿¾æ¢ä»¶çµå·²åç¨ï¼
- è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
-<!ENTITY issues.disabledgroups.enable.label "åç¨é濾æ¢ä»¶é/éæ¿¾æ¢ä»¶çµ">
-<!ENTITY issues.disabledfilters.description "ä¸åéæ¿¾æ¢ä»¶å·²åç¨ï¼
- è«åç¨éäºé濾æ¢ä»¶ï¼éå¾å¯è½å°±æ¯å°è´é¯èª¤ç¼ççåå :">
-<!ENTITY issues.disabledfilters.enable.label "åç¨é濾æ¢ä»¶">
-<!ENTITY issues.override.label "è¨å®å¼ç¡èª¤ï¼ç¹¼çºåå ±é¯èª¤">
-<!ENTITY issues.override.accesskey "c">
-<!ENTITY issues.change.description "æ¨çè¨å®å¼å·²è®æ´ãè«éæ°è¼å
¥é 颿¸¬è©¦é¯èª¤æ¯å¦ä»ç¶åå¨ï¼
- è¥é¯èª¤ä¾èåå¨ï¼åå¿
é å³éé¯èª¤å ±åã">
-<!ENTITY typeWarning.description "æ¨è¡¨ç¤ºæ¨è¦åå ±çé¯èª¤æ¯ Adblock Plus æ¬èº«çé¯èª¤èééæ¿¾æ¢ä»¶å¼èµ·çé¯èª¤ã
- è«æ³¨æï¼éé¡ç¨å¼é¯èª¤æå¥½è½å° [link]Adblock Plus è¨è«å[/link] ä¸åå ±ã
- æ¬åå ±å¨å°éé¡é¯èª¤åªè½ç¨æ¼è¨è«åä¸å·²åå¨æç« çè£å
說æï¼
- æ¨å¿
é å¨ Adblock Plus è¨è«åçæç« ä¸è²¼ä¸é次åå ±çé¯èª¤å ±åé£çµï¼å¦åç¡äººæç¼ç¾æ¤é¯èª¤å ±åã
- é¯èª¤å ±åé£çµå¨å³éæåä¹å¾æèªåç¢çã">
-<!ENTITY typeWarning.override.label "æäºè§£ä¸¦è¦å³éé¯èª¤å ±å">
-<!ENTITY typeWarning.override.accesskey "s">
-<!ENTITY reloadButton.label "éæ°è¼å
¥é é¢">
-<!ENTITY reloadButton.accesskey "R">
-<!ENTITY screenshot.heading "éå è¢å¹æå">
-<!ENTITY screenshot.description "忍£çé 颿¯å人çå°çæ
æ³å¯è½é½ä¸åãéå è¢å¹æåå°å ±åä¸å¯ä»¥å¹«æåæ´è½äºè§£å顿å¨ã
- æ¨å¯ä»¥å
ç§»é¤å
§å«ææ (ç§äºº) è³è¨çé¨ä»½ã並æ¨ç¤ºåºé¯èª¤ç¼ççæ®µè½ã
- åªè¦æä¸å°æçæéä¸¦ç¨æ»é¼ 鏿æ¨è¦ç§»é¤/æ¨ç¤ºç段è½å³å¯ã">
-<!ENTITY screenshot.attach.label "éå é é¢åçå°å ±åä¸">
-<!ENTITY screenshot.attach.accesskey "t">
-<!ENTITY screenshot.mark.label "æ¨ç¤ºå顿å¨">
-<!ENTITY screenshot.mark.accesskey "M">
-<!ENTITY screenshot.remove.label "ç§»é¤ææ (ç§äºº) è³è¨">
-<!ENTITY screenshot.remove.accesskey "R">
-<!ENTITY screenshot.undo.label "復å">
-<!ENTITY screenshot.undo.accesskey "U">
-<!ENTITY commentPage.heading "輸å
¥å註">
-<!ENTITY commentPage.description "ä¸é¢çæåæ¹å¡å¯ä»¥è®æ¨è¼¸å
¥é¡å¤çå註ï¼ä»¥å¹«å©æåæ´è½äºè§£å顿å¨ã
- é忥é©ä¸æ¯å¿
é çï¼ä½è¥åé¡ä¸å¤ªæé¡¯ææ¯è¼è¤éï¼å»ºè°æ¨éæ¯å¯«ä¸é¯èª¤ç詳細說æã
- å¨åå ±ä¹åæ¨ä¹å¯ä»¥æª¢è¦å ±åè³æã">
-<!ENTITY comment.label "å註 (é¸ç¨):">
-<!ENTITY comment.accesskey "C">
-<!ENTITY comment.lengthWarning "æ¨è¼¸å
¥çå註è¶
é 1000 ååå
ï¼å註æ¬ä½åªè½å³é 1000 ååå
ã">
-<!ENTITY email.label "é²ä¸æ¥è¯ç¹«ç Email å°å (é¸ç¨):">
-<!ENTITY email.accesskey "m">
-<!ENTITY attachExtensions.label "éå ç®ååç¨çå¥ä»¶æ¸
å®å°å ±åä¸ï¼ä»¥ä¾¿æé¤æ¯å¥ä»¶è¡çªæé æçé¯èª¤">
-<!ENTITY attachExtensions.accesskey "x">
-<!ENTITY sendButton.label "å³éå ±å">
-<!ENTITY sendButton.accesskey "n">
-<!ENTITY showData.label "é¡¯ç¤ºå ±åè³æ">
-<!ENTITY data.label "å ±åè³æ:">
-<!ENTITY data.accesskey "p">
-<!ENTITY sendPage.heading "å³éå ±å">
-<!ENTITY sendPage.waitMessage "è«ç¨åï¼Adblock Plus æ£å¨å³éæ¨çå ±åã">
-<!ENTITY sendPage.confirmation "æ¨çå ±åå·²å²åï¼æ¨å¯ä»¥é»é¸ä¸åç¶²åæª¢è¦å ±å:">
-<!ENTITY sendPage.knownIssue "æ¨åå ±çé¯èª¤å·²éè¤ï¼æª¢è¦æ´å¤è³è¨:">
-<!ENTITY sendPage.errorMessage "å³éé¯èª¤å ±å失æï¼é¯èª¤ç¢¼ "?1?"ã
- è«ç¢ºå®æ¨å·²é£ä¸ç¶²è·¯å¾åè©¦ä¸æ¬¡ãè¥ä¾è失æï¼
- è«é£ä¸ [link]Adblock Plus è¨è«å[/link] å°æ±å¹«å©ã">
-<!ENTITY sendPage.retry.label "忬¡å³é">
-<!ENTITY copyLink.label "è¤è£½å ±åé£çµ">
-<!ENTITY copyLink.accesskey "C">
diff --git a/chrome/locale/zh-TW/settings.dtd b/chrome/locale/zh-TW/settings.dtd
deleted file mode 100644
index 571f980..0000000
--- a/chrome/locale/zh-TW/settings.dtd
+++ /dev/null
@@ -1,89 +0,0 @@
-<!ENTITY dialog.title "Adblock Plus å好è¨å®">
-<!ENTITY filters.label "éæ¿¾æ¢ä»¶">
-<!ENTITY filters.accesskey "F">
-<!ENTITY add.label "æ°å¢é濾æ¢ä»¶">
-<!ENTITY add.accesskey "A">
-<!ENTITY addsubscription.label "è¨é±é濾æ¢ä»¶é">
-<!ENTITY addsubscription.accesskey "S">
-<!ENTITY synchsubscriptions.label "æ´æ°æææ¢ä»¶é">
-<!ENTITY synchsubscriptions.accesskey "D">
-<!ENTITY import.label "å¯å
¥é濾æ¢ä»¶">
-<!ENTITY import.accesskey "M">
-<!ENTITY export.label "å¯åºé濾æ¢ä»¶">
-<!ENTITY export.accesskey "X">
-<!ENTITY clearall.label "åªé¤ææèªè¨æ¢ä»¶">
-<!ENTITY clearall.accesskey "L">
-<!ENTITY resethitcounts.label "éè¨å½ä¸çµ±è¨è³æ">
-<!ENTITY resethitcounts.accesskey "R">
-<!ENTITY edit.label "編輯">
-<!ENTITY edit.accesskey "E">
-<!ENTITY cut.label "åªä¸">
-<!ENTITY cut.accesskey "T">
-<!ENTITY copy.label "è¤è£½">
-<!ENTITY copy.accesskey "C">
-<!ENTITY paste.label "è²¼ä¸">
-<!ENTITY paste.accesskey "P">
-<!ENTITY remove.label "åªé¤">
-<!ENTITY remove.accesskey "D">
-<!ENTITY menu.find.label "å°æ¾">
-<!ENTITY menu.find.accesskey "F">
-<!ENTITY menu.findagain.label "éæ°å°æ¾">
-<!ENTITY menu.findagain.accesskey "G">
-<!ENTITY view.label "檢è¦">
-<!ENTITY view.accesskey "V">
-<!ENTITY sort.label "æåº">
-<!ENTITY sort.accesskey "S">
-<!ENTITY sort.none.label "䏿åº">
-<!ENTITY sort.none.accesskey "U">
-<!ENTITY sort.ascending.label "éå¢æåº (A > Z)">
-<!ENTITY sort.ascending.accesskey "A">
-<!ENTITY sort.descending.label "éå¢æåº (Z > A)">
-<!ENTITY sort.descending.accesskey "Z">
-<!ENTITY options.label "é¸é
">
-<!ENTITY options.accesskey "O">
-<!ENTITY enable.label "åç¨ Adblock Plus">
-<!ENTITY enable.accesskey "N">
-<!ENTITY showintoolbar.label "顯示工å
·åæé">
-<!ENTITY showintoolbar.accesskey "B">
-<!ENTITY showinstatusbar.label "顯示çæ
åå示">
-<!ENTITY showinstatusbar.accesskey "S">
-<!ENTITY objecttabs.label "å¨ Flash å Java ç©ä»¶ä¸é¡¯ç¤ºé 籤">
-<!ENTITY objecttabs.accesskey "T">
-<!ENTITY collapse.label "éæ¾ç©ä»¶æä½ç¨ç空é">
-<!ENTITY collapse.accesskey "L">
-<!ENTITY sync.label "忥 Adblock è¨å®å¼">
-<!ENTITY sync.accesskey "c">
-<!ENTITY help.label "說æ">
-<!ENTITY help.accesskey "H">
-<!ENTITY gettingStarted.label "æ°æä¸è·¯ (è±æç¶²é )">
-<!ENTITY gettingStarted.accesskey "s">
-<!ENTITY faq.label "常è¦åé¡é (è±æç¶²é )">
-<!ENTITY faq.accesskey "F">
-<!ENTITY filterdoc.label "å¦ä½æ°å¯«é濾æ¢ä»¶ (è±æç¶²é )">
-<!ENTITY filterdoc.accesskey "R">
-<!ENTITY about.label "éæ¼ Adblock Plus">
-<!ENTITY about.accesskey "B">
-<!ENTITY description "ä¸é¢ååºçéæ¿¾æ¢ä»¶ææ±ºå®åªäºç¶²åæè¢«é»æãåªäºç¶²åæå
許顯示:">
-<!ENTITY filter.column "éæ¿¾è¦å">
-<!ENTITY filter.accesskey "F">
-<!ENTITY slow.column "ç·©æ
¢é濾æ¢ä»¶">
-<!ENTITY slow.accesskey "w">
-<!ENTITY enabled.column "å·²åç¨">
-<!ENTITY enabled.accesskey "n">
-<!ENTITY hitcount.column "å½ä¸æ¸">
-<!ENTITY hitcount.accesskey "H">
-<!ENTITY lasthit.column "æå¾ä½¿ç¨">
-<!ENTITY lasthit.accesskey "L">
-<!ENTITY context.edit.label "ç·¨è¼¯éæ¿¾æ¢ä»¶">
-<!ENTITY context.resethitcount.label "éè¨æ¤æ¢ä»¶çµ±è¨è³æ">
-<!ENTITY context.synchsubscription.label "ç«å³æ´æ°è¨é±æ¢ä»¶é">
-<!ENTITY context.editsubscription.label "編輯è¨é±æ¸
å®">
-<!ENTITY context.moveup.label "åä¸ç§»">
-<!ENTITY context.movedown.label "åä¸ç§»">
-<!ENTITY context.movegroupup.label "æ´çµåä¸ç§»">
-<!ENTITY context.movegroupdown.label "æ´çµåä¸ç§»">
-<!ENTITY context.enable.label "åç¨">
-<!ENTITY context.disable.label "åç¨">
-<!ENTITY apply.label "å¥ç¨">
-<!ENTITY apply.accesskey "P">
-<!ENTITY fennec.subscription.label "éæ¿¾æ¢ä»¶è¨é±">
diff --git a/chrome/skin/about.css b/chrome/skin/about.css
deleted file mode 100644
index b748b5d..0000000
--- a/chrome/skin/about.css
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-#mainBox
-{
- visibility: hidden;
-}
-#mainBox[loaded]
-{
- visibility: visible;
-}
-
-#title
-{
- font-size: 48px;
- font-weight: bold;
-}
-
-#mainGroup
-{
- margin-top: 15px;
- width: 450px;
- height: 400px;
- overflow: auto;
-}
-
-#homepageTitle, #authorsTitle, #contributorsTitle, #subscriptionAuthorsTitle, #translatorsTitle
-{
- font-weight: bold;
-}
-
-#description, #homepage, #authorsBox, #contributorsBox, #subscriptionAuthorsBox
-{
- margin-bottom: 10px;
-}
diff --git a/chrome/skin/composer.css b/chrome/skin/composer.css
deleted file mode 100644
index bc9ef69..0000000
--- a/chrome/skin/composer.css
+++ /dev/null
@@ -1,84 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
- at namespace html url("http://www.w3.org/1999/xhtml");
-
-/*
- * Force left-to-right everywhere where we are displaying addresses
- */
-.suggestion > .radio-label-box:-moz-locale-dir(rtl),
-html|*.textbox-input:-moz-locale-dir(rtl)
-{
- direction: ltr;
- text-align: end;
-}
-
-#patternGroup {
- overflow: auto;
-}
-
-#anchorGroup {
- padding-left: 20px;
-}
-
-#typeGroupLabel {
- margin-top: 10px;
-}
-
-#typeGroup {
- overflow: auto;
- margin-bottom: 10px
-}
-
-:root:not([advancedMode="true"]) #options {
- display: none;
-}
-
-#disabledWarning, #groupDisabledWarning, #regexpWarning, #shortpatternWarning, #matchWarning {
- color: #E00000;
-}
-
-#disabledWarning > *, #groupDisabledWarning > * {
- margin: 0px;
- font-size: inherit;
-}
-
-.text-link {
- font-size: 80%;
- -moz-user-focus: ignore;
-}
-
-.help {
- color: #0000E0;
- border-bottom: 1px dotted #0000E0;
- cursor: help;
- margin: 0px;
- padding: 0px;
-}
-
-tooltip {
- /* Gecko 1.8.1 doesn't support multiline tooltips :-( */
- max-width: none;
-}
diff --git a/chrome/skin/overlay.css b/chrome/skin/overlay.css
deleted file mode 100644
index 5b49034..0000000
--- a/chrome/skin/overlay.css
+++ /dev/null
@@ -1,190 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-#abp-status
-{
- cursor: pointer;
-}
-
-toolbar[iconsize="small"] #abp-toolbarbutton,
-#PersonalToolbar #abp-toolbarbutton,
-#header-view-toolbar > #abp-toolbarbutton,
-#abp-status {
- list-style-image: url("abp-status-16.png");
- -moz-image-region: rect(0px, 16px, 16px, 0px);
-}
-toolbar[iconsize="small"] #abp-toolbarbutton[abpstate="disabled"],
-#PersonalToolbar #abp-toolbarbutton[abpstate="disabled"],
-#header-view-toolbar > #abp-toolbarbutton[abpstate="disabled"],
-#abp-status[abpstate="disabled"],
-toolbar[iconsize="small"] #abp-toolbarbutton[abpstate="whitelisted"],
-#PersonalToolbar #abp-toolbarbutton[abpstate="whitelisted"],
-#header-view-toolbar > #abp-toolbarbutton[abpstate="whitelisted"],
-#abp-status[abpstate="whitelisted"] {
- -moz-image-region: rect(16px, 16px, 32px, 0px);
-}
-
-#abp-toolbar-popup {
- list-style-image: none;
- -moz-image-region: rect(0px, 0px, 0px, 0px);
-}
-
-toolbox[vertical="true"] toolbar #abp-toolbarbutton dropmarker {
- display: none !important;
-}
-
-menuitem[default="true"] {
- font-weight: bold;
-}
-
-#abp-toolbarbutton,
-#abp-site-info {
- list-style-image: url("abp-status.png");
- -moz-image-region: rect(0px, 24px, 24px, 0px);
-}
-#abp-toolbarbutton[abpstate="disabled"],
-#abp-toolbarbutton[abpstate="whitelisted"],
-#abp-site-info[abpstate="disabled"],
-#abp-site-info[abpstate="disabled_site"] {
- -moz-image-region: rect(24px, 24px, 48px, 0px);
-}
-
-/* Hack: force the label to be displayed below icon for type="menu" */
-#abp-toolbarbutton[type="menu"]
-{
- -moz-box-orient: horizontal;
-}
-toolbar[mode="full"] #abp-toolbarbutton[type="menu"]
-{
- -moz-binding: url("chrome://global/content/bindings/toolbarbutton.xml#menu-vertical");
-}
-
-/* Thunderbird-specific toolbar icon styles */
-#header-view-toolbar > #abp-toolbarbutton
-{
- -moz-appearance: dualbutton;
- padding: 0px !important;
-}
-
-/* Hide toolbar icon text in Thunderbird to save space */
-#header-view-toolbar > #abp-toolbarbutton .toolbarbutton-text
-{
- display: none;
-}
-
-/* SeaMonkey expects the icon to be rather large, add margin */
-#mail-toolbox #abp-toolbarbutton .toolbarbutton-icon
-{
- margin-top: 5px;
-}
-
-#abp-status-image {
- margin-left: 10px;
- margin-right: 10px;
-}
-
-#abp-site-info .pageaction-image {
- width: 32px;
- height: 32px;
- padding: 4px;
-}
-
-#abp-toolbarbutton > toolbarbutton {
- /* Argh, Songbird defines image region directly on the anonymous toolbarbutton element */
- -moz-image-region: inherit !important;
-}
-
-#abp-tooltip {
- max-width: none;
-}
-
-#abp-tooltip label {
- font-weight: bold;
- margin-bottom: 0px;
-}
-
-#abp-tooltip description:not([hidden="true"])+label {
- margin-top: 10px;
-}
-
-#abp-sidebar-title {
- padding-left: 4px;
-}
-
-#abp-sidebar-toolbar {
- display: -moz-box !important;
- visibility: visible !important;
-}
-
-#abp-sidebar-close {
- padding: 4px 2px;
- border-style: none !important;
- -moz-user-focus: normal;
- list-style-image: url("close.png");
- -moz-appearance: none;
- -moz-image-region: rect(0px, 14px, 14px, 0px);
-}
-
-#abp-sidebar-close:hover {
- -moz-image-region: rect(0px, 28px, 14px, 14px);
-}
-
-#abp-sidebar-close:hover:active {
- -moz-image-region: rect(0px, 42px, 14px, 28px);
-}
-
-.abp-recommendbutton
-{
- opacity: 0.7;
- margin-top: 20px;
-}
-
-.abp-recommendbutton:hover
-{
- opacity: 1;
-}
-
-.abp-recommendbutton-btn
-{
- font-size: 80%;
- margin-left: 40px;
- margin-right: 40px;
- list-style-image: url("data:image/gif;base64,R0lGODlhEAAQAKIAAGF5rEVinmB4q%2Bvu9G2EtP%2F%2F%2FztZmAAAACH5BAAAAAAALAAAAAAQABAAAAM4WLrcCibKGYGiWN4sxt6Y9xWZAZpkdp6R06bTIMpvucLUbeNKQPxAggIY6AWBw1%2BxAClJLI7oIgEAOw%3D%3D");
-}
-
-.abp-recommendbutton-close
-{
- border-style: none !important;
- -moz-user-focus: normal;
- list-style-image: url("close.png");
- -moz-appearance: none;
- -moz-image-region: rect(0px, 14px, 14px, 0px);
-}
-
-.abp-recommendbutton-close:hover
-{
- -moz-image-region: rect(0px, 28px, 14px, 14px);
-}
diff --git a/chrome/skin/sendReport.css b/chrome/skin/sendReport.css
deleted file mode 100644
index 205c871..0000000
--- a/chrome/skin/sendReport.css
+++ /dev/null
@@ -1,124 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-.wizard-header
-{
- -moz-binding: url(chrome://adblockplus/content/ui/sendReport.xul#headerBinding) !important;
- padding: 10px 5px !important;
-}
-
-.progressLabel
-{
- margin: 5px 0px;
- text-align: center;
- font-size: 110%;
- font-weight: normal;
-}
-
-.progressLabel.active
-{
- font-weight: bold;
-}
-
-progressmeter
-{
- margin-top: 100px;
-}
-
-.radioDescription
-{
- -moz-margin-start: 32px;
-}
-
-radio, checkbox, .topLabel, #dataDeck
-{
- margin-top: 15px;
-}
-
-#recentReports
-{
- margin-top: 15px;
-}
-
-#recentReportsList
-{
- overflow-x: hidden;
- overflow-y: auto;
-}
-
-#issuesBox
-{
- overflow: auto;
-}
-
-#issuesChangeMessage
-{
- color: red;
-}
-
-#screenshotButtons
-{
- margin-top: 10px;
-}
-
-#screenshotBox
-{
- overflow-y: scroll;
-}
-
-#commentLengthWarning
-{
- color: red;
-}
-
-#commentLengthWarning[visible="false"]
-{
- visibility: hidden;
-}
-
-/*
- * Force left-to-right everywhere where we are displaying addresses
- */
-#data:-moz-locale-dir(rtl)
-{
- direction: ltr;
-}
-
-#sendReportError
-{
- color: red;
- font-size: 150%;
-}
-
-#sendReportErrorLinks, #typeWarningTextLink
-{
- margin: 0px;
-}
-
-#sendReportErrorBox
-{
- margin-bottom: 10px;
-}
diff --git a/chrome/skin/settings.css b/chrome/skin/settings.css
deleted file mode 100644
index 6c49394..0000000
--- a/chrome/skin/settings.css
+++ /dev/null
@@ -1,165 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
- at namespace html url("http://www.w3.org/1999/xhtml");
-
-dialog {
- padding: 0px;
-}
-
-.dialog-button-box, #introduction, #listarea {
- margin: 8px;
-}
-
-deck, deck * {
- margin: 0px;
-}
-
-#listEditor menupopup description {
- margin: 1px 3px;
-}
-
-#listEditorIcon {
- list-style-image: url("close.png");
- -moz-image-region: rect(0px, 14px, 14px, 0px);
- margin-left: 2px;
-}
-#listEditorIcon:hover {
- -moz-image-region: rect(0px, 28px, 14px, 14px);
-}
-#listEditorIcon:hover:active {
- -moz-image-region: rect(0px, 42px, 14px, 28px);
-}
-
-#col-slow {
- text-align: center;
-}
-
-#col-hitcount, #col-lasthit {
- text-align: right;
-}
-
-#col-hitcount {
- min-width: 60px;
-}
-#col-enabled {
- min-width: 16px;
-}
-#col-slow {
- min-width: 30px;
-}
-
-/*
- * Force left-to-right everywhere where we are displaying addresses
- */
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-invalid),
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-whitelist),
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-filterlist),
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter, type-elemhide)
-{
- direction: ltr;
- text-align: end;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, description-true, selected-false) {
- font-size: 80%;
- color: #808080;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, filter-true, type-whitelist, selected-false) {
- color: #008000;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, filter-true, type-elemhide, selected-false) {
- color: #000080;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, filter-false, subscription-upgradeRequired-true, selected-false) {
- color: #FF0000;
-}
-
-treechildren::-moz-tree-cell-text(col-slow) {
- font-size: 0px;
-}
-
-treechildren::-moz-tree-row(filter-true, filter-disabled-true, selected-false),
-treechildren::-moz-tree-row(subscription-disabled-true, selected-false) {
- background-color: #E0E0E0;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, filter-true, type-comment, selected-false) {
- color: #808080;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, filter-true, type-invalid, selected-false) {
- color: #C00000;
-}
-
-treechildren::-moz-tree-cell-text(col-filter, subscription-true) {
- font-weight: bold;
-}
-
-treechildren::-moz-tree-image(col-enabled, filter-true, subscription-disabled-false, filter-disabled-true),
-treechildren::-moz-tree-image(col-enabled, subscription-true, subscription-disabled-true) {
- list-style-image: url(checkbox.png);
- -moz-image-region: rect(13px 13px 26px 0px);
-}
-
-treechildren::-moz-tree-image(col-enabled, filter-true, subscription-disabled-false, filter-disabled-false),
-treechildren::-moz-tree-image(col-enabled, subscription-true, subscription-disabled-false, subscription-dummy-false) {
- list-style-image: url(checkbox.png);
- -moz-image-region: rect(0px 13px 13px 0px);
-}
-
-treechildren::-moz-tree-image(col-slow, filter-true, filter-regexp-true) {
- list-style-image: url(slow.png);
-}
-
-treechildren::-moz-tree-image(col-enabled) {
- margin-left: 7px;
-}
-#col-enabled {
- min-width: 24px;
-}
-
-.whitelisted:not([_moz-menuactive="true"]) {
- color: #008000;
-}
-
-.filtered:not([_moz-menuactive="true"]) {
- color: #C00000;
-}
-
-#findbar {
- border: none !important;
-}
-
-#findbar .findbar-highlight {
- display: none;
-}
-
-tooltip {
- max-width: none;
-}
diff --git a/chrome/skin/sidebar.css b/chrome/skin/sidebar.css
deleted file mode 100644
index 76ab341..0000000
--- a/chrome/skin/sidebar.css
+++ /dev/null
@@ -1,117 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-#suggestionsList {
- margin: 0px;
-}
-
-#detachButton, #reattachButton:not([disabled="true"]) {
- text-decoration: underline;
- cursor: pointer;
-}
-
-#reattachButton[disabled="true"] {
- color: GrayText;
-}
-
-#detachButton, #reattachButton {
- font-size: 90%;
-}
-
-tooltip {
- max-width: none;
-}
-
-#tooltipPreview {
- margin:10px;
- max-width: 300px;
- max-height: 300px;
-}
-
-#tooltip label {
- font-weight: bold;
-}
-
-#contextBlock,
-#contextWhitelist {
- font-weight: bold;
-}
-
-#state {
- min-width: 16px;
-}
-
-#size {
- text-align: end;
-}
-
-/*
- * Force left-to-right everywhere where we are displaying addresses
- */
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-filter),
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-address),
-treechildren:-moz-locale-dir(rtl)::-moz-tree-cell(col-size)
-{
- direction: ltr;
- text-align: end;
-}
-
-.disabledTextLabel
-{
- font-style: italic;
-}
-
-treechildren::-moz-tree-cell-text(state-filtered, selected-false),
-treechildren::-moz-tree-cell-text(state-hidden, selected-false) {
- color: #C00000;
-}
-treechildren::-moz-tree-cell-text(state-whitelisted, selected-false) {
- color: #008000;
-}
-
-treechildren::-moz-tree-image(col-state, dummy-false)
-{
- list-style-image: url(item-state.png);
- -moz-image-region: rect(0px 10px 10px 0px);
- margin-left: 3px;
-}
-treechildren::-moz-tree-image(col-state, filter-disabled-true, dummy-false) {
- -moz-image-region: rect(10px 10px 20px 0px);
-}
-treechildren::-moz-tree-image(col-state, state-filtered, dummy-false),
-treechildren::-moz-tree-image(col-state, state-hidden, dummy-false) {
- -moz-image-region: rect(20px 10px 30px 0px);
-}
-treechildren::-moz-tree-image(col-state, state-whitelisted, dummy-false) {
- -moz-image-region: rect(30px 10px 40px 0px);
-}
-
-treechildren::-moz-tree-cell-text(col-filter, state-hidden, selected-false) {
- color: #000080;
-}
-treechildren::-moz-tree-cell-text(col-filter, filter-disabled-true, selected-false) {
- color: #C0C0C0;
-}
diff --git a/chrome/skin/subscriptionSelection.css b/chrome/skin/subscriptionSelection.css
deleted file mode 100644
index 192a6f8..0000000
--- a/chrome/skin/subscriptionSelection.css
+++ /dev/null
@@ -1,98 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-dialog
-{
- min-width: 550px;
-}
-
-dialog[newInstall]
-{
- background-image: url(abp-icon-big.png);
- background-repeat: no-repeat;
- background-position: 95% 5%;
-}
-
-dialog[newInstall] .dialog-content-box,
-dialog[newInstall] #content-scroll
-{
- min-height: 150px;
-}
-
-#description-newInstall,
-#adblock-warning,
-#filtersetg-warning
-{
- margin-bottom: 10px;
-}
-
-*[invisible="true"]
-{
- visibility: hidden;
-}
-
-#adblock-warning,
-#filtersetg-warning,
-#supplementMessage
-{
- color: #F00000;
-}
-
-.localeMatch
-{
- font-weight: bold;
-}
-
-#all-subscriptions-loading
-{
- margin: 50px;
-}
-
-#all-subscriptions
-{
- min-height: 200px;
-}
-#all-subscriptions > richlistitem > .variant
-{
- width: 200px;
-}
-#all-subscriptions > richlistitem:not(:first-child) > .subscriptionTitle,
-#all-subscriptions > richlistitem:not(:first-child) > .subscriptionTitle + .variant
-{
- border-top: 1px dashed black;
- margin-top: 0px;
- padding-top: 4px;
-}
-
-#supplementMessage
-{
- margin-top: 5px;
-}
-#supplementMessage > label
-{
- margin-left: 0px;
- margin-right: 0px;
-}
diff --git a/chrome/skin/subscriptionSelectionFennec.css b/chrome/skin/subscriptionSelectionFennec.css
deleted file mode 100644
index 6621cdc..0000000
--- a/chrome/skin/subscriptionSelectionFennec.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
- at import url("chrome://browser/skin/platform.css");
-
- at namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
-
-dialog
-{
- min-width: 0px;
-}
-
-#all-subscriptions-container
-{
- font-size: 60%;
-}
diff --git a/components/Initializer.js b/components/Initializer.js
index 27f4f52..c44a98a 100644
--- a/components/Initializer.js
+++ b/components/Initializer.js
@@ -32,14 +32,14 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
// Gecko 1.9.0/1.9.1 compatibility - add XPCOMUtils.defineLazyServiceGetter
if (!("defineLazyServiceGetter" in XPCOMUtils))
{
- XPCOMUtils.defineLazyServiceGetter = function XPCU_defineLazyServiceGetter(obj, prop, contract, iface)
- {
- obj.__defineGetter__(prop, function XPCU_serviceGetter()
- {
- delete obj[prop];
- return obj[prop] = Cc[contract].getService(Ci[iface]);
- });
- };
+ XPCOMUtils.defineLazyServiceGetter = function XPCU_defineLazyServiceGetter(obj, prop, contract, iface)
+ {
+ obj.__defineGetter__(prop, function XPCU_serviceGetter()
+ {
+ delete obj[prop];
+ return obj[prop] = Cc[contract].getService(Ci[iface]);
+ });
+ };
}
/**
@@ -49,62 +49,62 @@ if (!("defineLazyServiceGetter" in XPCOMUtils))
function Initializer() {}
Initializer.prototype =
{
- classDescription: "Adblock Plus initializer",
- contractID: "@adblockplus.org/abp/startup;1",
- classID: Components.ID("{d32a3c00-4ed3-11de-8a39-0800200c9a66}"),
- _xpcom_categories: [{ category: "app-startup", service: true }],
+ classDescription: "Adblock Plus initializer",
+ contractID: "@adblockplus.org/abp/startup;1",
+ classID: Components.ID("{d32a3c00-4ed3-11de-8a39-0800200c9a66}"),
+ _xpcom_categories: [{ category: "app-startup", service: true }],
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
- observe: function(subject, topic, data)
- {
- let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- switch (topic)
- {
- case "app-startup":
- observerService.addObserver(this, "profile-after-change", true);
- break;
- case "profile-after-change":
- observerService.addObserver(this, "quit-application", true);
+ observe: function(subject, topic, data)
+ {
+ let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ switch (topic)
+ {
+ case "app-startup":
+ observerService.addObserver(this, "profile-after-change", true);
+ break;
+ case "profile-after-change":
+ observerService.addObserver(this, "quit-application", true);
- // Don't init in Fennec, initialization will happen when UI is ready
- let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
- if (appInfo.ID != "{a23983c0-fd0e-11dc-95ff-0800200c9a66}")
- {
- try
- {
- // Gecko 2.0 and higher - chrome URLs can be loaded directly
- Cu.import("chrome://adblockplus-modules/content/Bootstrap.jsm");
- }
- catch (e)
- {
- // Gecko 1.9.x - have to convert chrome URLs to file URLs first
- let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
- let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
- let bootstrapURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Bootstrap.jsm", null, null));
- Cu.import(bootstrapURL.spec);
- }
- Bootstrap.startup();
- }
- break;
- case "quit-application":
- try {
- // This will fail if component was added via chrome.manifest (Gecko 2.0)
- observerService.removeObserver(this, "profile-after-change");
- }catch(e) {}
- observerService.removeObserver(this, "quit-application");
- if ("@adblockplus.org/abp/private;1" in Cc)
- {
- let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
- Cu.import(baseURL.spec + "Bootstrap.jsm");
- Bootstrap.shutdown(false);
- }
- break;
- }
- }
+ // Don't init in Fennec, initialization will happen when UI is ready
+ let appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+ if (appInfo.ID != "{a23983c0-fd0e-11dc-95ff-0800200c9a66}")
+ {
+ try
+ {
+ // Gecko 2.0 and higher - chrome URLs can be loaded directly
+ Cu.import("chrome://adblockplus-modules/content/Bootstrap.jsm");
+ }
+ catch (e)
+ {
+ // Gecko 1.9.x - have to convert chrome URLs to file URLs first
+ let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
+ let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+ let bootstrapURL = chromeRegistry.convertChromeURL(ioService.newURI("chrome://adblockplus-modules/content/Bootstrap.jsm", null, null));
+ Cu.import(bootstrapURL.spec);
+ }
+ Bootstrap.startup();
+ }
+ break;
+ case "quit-application":
+ try {
+ // This will fail if component was added via chrome.manifest (Gecko 2.0)
+ observerService.removeObserver(this, "profile-after-change");
+ }catch(e) {}
+ observerService.removeObserver(this, "quit-application");
+ if ("@adblockplus.org/abp/private;1" in Cc)
+ {
+ let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
+ Cu.import(baseURL.spec + "Bootstrap.jsm");
+ Bootstrap.shutdown(false);
+ }
+ break;
+ }
+ }
};
if (XPCOMUtils.generateNSGetFactory)
- var NSGetFactory = XPCOMUtils.generateNSGetFactory([Initializer]);
+ var NSGetFactory = XPCOMUtils.generateNSGetFactory([Initializer]);
else
- var NSGetModule = XPCOMUtils.generateNSGetModule([Initializer]);
+ var NSGetModule = XPCOMUtils.generateNSGetModule([Initializer]);
diff --git a/debian/adblock-plus.upstream-changelog b/debian/adblock-plus.upstream-changelog
index 53575bd..dade970 100644
--- a/debian/adblock-plus.upstream-changelog
+++ b/debian/adblock-plus.upstream-changelog
@@ -1,9 +1,8 @@
Detailed changelog for Adblock Plus 1.3.9
- * Added experimental support for Firefox Sync, enabled via "Sync Adblock Plus settings" option (only visible if Firefox Sync is set up).
- * New extension icons (forum topic).
- * Updated for changes in Thunderbird 5.
- * Fixed: Disabled filters might stay effective if enabled from list of blockable items (forum topic).
- * Fixed: Disabling on a page should ignore fragment identifier (forum topic).
- * Fixed: Do-Not-Track feature causes an error message to appear (bug 24078).
- * Two minor code bugs fixed.
+ * Added Latvian and Albanian translations.
+ * Fixed: No preview in the list of blockable items if the image matches a disabled filter.
+ * Fixed: Failure to save filters cache in Firefox 8, affects startup performance (forum topic).
+ * Fixed: More issues caused by corrupted patterns.ini file (forum topic).
+ * Fixed: Blockable items list might delay garbage collection of compartments (bug 679675).
+ * Some users will be asked to complete a survey about Adblock Plus (forum topic).
diff --git a/debian/changelog b/debian/changelog
index 7395ecf..2a3ebc4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+adblock-plus (1.3.10-1) unstable; urgency=low
+
+ * New upstream release. (Closes: #635983)
+ * debian/control:
+ - add myself as an Uploader.
+ * adblock-plus.upstream-changelog:
+ - updated with latest release's details.
+ * debian/rules:
+ - cleaned up and updated with a new build system. Upstream
+ does not include a build.py anymore so we'll use m-ds to
+ do everything for us.
+
+ -- Andrea Veri <and at debian.org> Fri, 30 Sep 2011 00:30:26 +0200
+
adblock-plus (1.3.9-2) unstable; urgency=low
* Added upstream changelog (Closes: #580362)
diff --git a/debian/control b/debian/control
index a68a2e9..e493b14 100644
--- a/debian/control
+++ b/debian/control
@@ -4,7 +4,8 @@ Priority: optional
Maintainer: Dmitry E. Oboukhov <unera at debian.org>
Uploaders: Debian Mozilla Extension Maintainers <pkg-mozext-maintainers at lists.alioth.debian.org>,
Benjamin Drung <bdrung at debian.org>,
- Fabrizio Regalli <fabreg at fabreg.it>
+ Fabrizio Regalli <fabreg at fabreg.it>,
+ Andrea Veri <and at debian.org>
Build-Depends: debhelper (>= 8),
mercurial,
mozilla-devscripts (>= 0.19~),
diff --git a/debian/rules b/debian/rules
index a68f439..b1c7888 100755
--- a/debian/rules
+++ b/debian/rules
@@ -4,13 +4,13 @@
dh $@ --with xul-ext
override_dh_auto_build:
- python build.py build --release
+ xpi-pack . adblock-plus.xpi
override_dh_auto_install:
- install-xpi adblockplus*.xpi
+ install-xpi adblock-plus.xpi
override_dh_installchangelogs:
dh_installchangelogs $(CURDIR)/debian/adblock-plus.upstream-changelog
override_dh_auto_clean:
- rm -f adblockplus*.xpi buildtools/*.pyc
+ rm -f adblock-plus.xpi
diff --git a/debian/source/local-options b/debian/source/local-options
deleted file mode 100644
index 4aceb10..0000000
--- a/debian/source/local-options
+++ /dev/null
@@ -1 +0,0 @@
-unapply-patches
diff --git a/generateDocs.pl b/generateDocs.pl
deleted file mode 100755
index 3075dec..0000000
--- a/generateDocs.pl
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/perl
-
-# This script runs jsrun.pl script in jsdoc-toolkit repository to generate
-# source code documentation. Perl module JavaScript has to be installed.
-
-die "Usage: $^X $0 output-directory\n" unless @ARGV;
-my $target = $ARGV[0];
-
-$0 =~ s/(.*[\\\/])//g;
-chdir($1) if $1;
-
-system("hg", "clone", "https://hg.adblockplus.org/jsdoc-toolkit/") unless -e "jsdoc-toolkit";
-
- at ARGV = ('-t=jsdoc-toolkit/templates/jsdoc/',
- '-d=' . $target,
- '-a',
- '-p',
- '-x=js,jsm',
- 'modules/', 'components/Initializer.js');
-
-$0 = "jsdoc-toolkit/jsrun.pl";
-do $0;
-die $@ if $@;
diff --git a/install.rdf b/install.rdf
new file mode 100644
index 0000000..e57ff21
--- /dev/null
+++ b/install.rdf
@@ -0,0 +1,581 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+ <Description about="urn:mozilla:install-manifest">
+ <em:id>{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}</em:id>
+ <em:version>1.3.10</em:version>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Ads were yesterday!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ <em:type>2</em:type>
+ <em:iconURL>chrome://adblockplus/skin/adblockplus.png</em:iconURL>
+ <em:aboutURL>chrome://adblockplus/content/ui/about.xul</em:aboutURL>
+ <em:optionsURL>chrome://adblockplus/content/ui/settings.xul</em:optionsURL>
+ <em:contributor>Claude Lespagnol aka Efdur</em:contributor>
+ <em:contributor>Nickolay Ponomarev</em:contributor>
+ <em:contributor>Kevin Keller</em:contributor>
+ <em:contributor>Fabrice Desré</em:contributor>
+ <em:contributor>Günther Beyer (opoloo.de)</em:contributor>
+ <em:translator>Ahmet Serkan Tıratacı</em:translator>
+ <em:translator>Aivo Kuhlberg</em:translator>
+ <em:translator>AlleyKat</em:translator>
+ <em:translator>Dagobert_78</em:translator>
+ <em:translator>Genti Ereqi</em:translator>
+ <em:translator>Hrvoje Majer</em:translator>
+ <em:translator>Jakub Tománek</em:translator>
+ <em:translator>Joni Heinonen</em:translator>
+ <em:translator>Jose Sun</em:translator>
+ <em:translator>Ján Kendi (Jacen)</em:translator>
+ <em:translator>KNTRO</em:translator>
+ <em:translator>Ken</em:translator>
+ <em:translator>Kristján Bjarni Guðmundsson</em:translator>
+ <em:translator>Leonid</em:translator>
+ <em:translator>Leszek(teo)Życzkowski</em:translator>
+ <em:translator>Luana Di Muzio</em:translator>
+ <em:translator>Manuel Meixide</em:translator>
+ <em:translator>Mark Tyndall</em:translator>
+ <em:translator>Martin Srebotnjak</em:translator>
+ <em:translator>Mauro José da Silva</em:translator>
+ <em:translator>Maybee</em:translator>
+ <em:translator>Mikael Hiort af Ornäs</em:translator>
+ <em:translator>Mikes Kaszmán István</em:translator>
+ <em:translator>Milupo</em:translator>
+ <em:translator>Nguyá»
n Mạnh Hùng</em:translator>
+ <em:translator>Ninnetyer</em:translator>
+ <em:translator>Premier</em:translator>
+ <em:translator>Raul Pimentel</em:translator>
+ <em:translator>Regmos</em:translator>
+ <em:translator>Reza_NA</em:translator>
+ <em:translator>Schuzak</em:translator>
+ <em:translator>SiiiE</em:translator>
+ <em:translator>Stefan Lewitas</em:translator>
+ <em:translator>Teboga</em:translator>
+ <em:translator>Toni Barrera</em:translator>
+ <em:translator>Urko</em:translator>
+ <em:translator>Wim Benes</em:translator>
+ <em:translator>Wladimir Palant</em:translator>
+ <em:translator>anonymous74100</em:translator>
+ <em:translator>bahramm</em:translator>
+ <em:translator>blackdire</em:translator>
+ <em:translator>catcat</em:translator>
+ <em:translator>el_libre</em:translator>
+ <em:translator>jojaba</em:translator>
+ <em:translator>k2jp</em:translator>
+ <em:translator>kapetance</em:translator>
+ <em:translator>knight00931</em:translator>
+ <em:translator>markh</em:translator>
+ <em:translator>pirlouy</em:translator>
+ <em:translator>pitdicker</em:translator>
+ <em:translator>rookie</em:translator>
+ <em:translator>sushizang</em:translator>
+ <em:translator>temperror</em:translator>
+ <em:translator>ultravioletu</em:translator>
+ <em:translator>ÐаÑÑжан ÐÑÑÑаÑ
идинов</em:translator>
+ <em:translator>ÐаÑÑÑайÑ
ан ÐнÑ
Ñайван</em:translator>
+ <em:translator>ÐакСРÐÐÐÐ</em:translator>
+ <em:translator>Ðвайло ÐовÑев (s0urce)</em:translator>
+ <em:translator>ТимоÑÑй ÐабиÑ</em:translator>
+ <em:translator>Ô·Õ¤Õ¸ÖÕ¡ÖÕ¤ Ô²Õ¡Õ¢Õ¡ÕµÕ¡Õ¶ (edo248)</em:translator>
+ <em:translator>Ù
Ø¤ÙØ¯ Ù
اردÙÙÙ</em:translator>
+ <em:localized>
+ <Description>
+ <em:locale>ar</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Ø§ÙØ¥Ø¹ÙØ§ÙØ§Øª Ø£ØµØ¨ØØª Ù
Ù Ø§ÙØ£Ù
س!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/ar/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>bg</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>РекламиÑе бÑÑ
а вÑеÑа!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ca</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Els anuncis eren ahir</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>cs</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>A reklamy jsou minulostÃ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>da</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklamer er fortid!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>de</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Werbung war gestern!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/de/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>el</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>ÎÏήÏÏε ÏÎ¹Ï Î´Î¹Î±ÏημίÏÎµÎ¹Ï ÏÏο ÏθεÏ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>en-GB</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Ads were yesterday!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/en/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>en-US</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Ads were yesterday!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/en/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>eo</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Anoncoj estis hieraÅ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>es-AR</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>¡La publicidad es cosa del pasado!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/es/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>es-ES</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>La publicidad es cosa del ayer</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/es/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>es-MX</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Los Anuncios son cosa del Ayer!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/es/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>et</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklaamid on nüüd eilne päev!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fa</em:locale>
+ <em:name>ÙÙ٠تبÙÛØº Ø´Ú©Ù</em:name>
+ <em:description>تبÙÛØºØª Ù
تعÙÙ Ø¨Ù Ø¯ÛØ±Ùز Ø¨ÙØ¯!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fi</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Mainokset ovat menneisyyttä!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fr</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Les publicités, c'est du passé !</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/fr/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>fy-NL</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Fan no ôf gjin reklames mear!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>gl</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Os anuncios son cousa do pasado!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>he</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>×פרס×××ת ש××××ת ××¢×ר!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/he/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>hr</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Oglasi su prošlost!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>hsb-DE</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklama bÄ wÄera!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>hu</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>A reklám a múlté!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>hy-AM</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Ô³Õ¸Õ¾Õ¡Õ¦Õ¤Õ¶Õ¥ÖÕ¨ Õ¥ÖÕ¥Õ¯ Õ§Õ«Õ¶!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>is</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Auglýsingar eru hluti af fortÃðinni!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>it</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Permette di dire 'no' alla pubblicità presente nelle pagine web!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ja</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>åºåããã£ãã®ã¯éå»ã®è©±ã§ãï¼</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>kk-KZ</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>ÐаÑнамаÒа жол жоÒ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ko</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>ì½í
ì¸ ì´ì©ì ë°©í´íê³ ë¶ê±´ì í ê´ê³ , ì´ì ìë
!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/ko/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>lv</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>ReklÄmas bija vakardiena!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>mn</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>СÑÑÑалÑилгаа бол Ó©ÑÐ¸Ð³Ð´Ó©Ñ Ð±Ð°Ð¹Ð»Ð°Ð°!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ms-MY</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Iklan hanyalah zaman dulu!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>nl</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reclames behoren tot het verleden!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pl</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Powiedz NIE! reklamom</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pt-BR</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Propaganda indesejada é coisa do passado!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>pt-PT</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Publicidade... já era!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ro</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>EliminÄ publicitatea din paginile web.</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>ru</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Скажи "неÑ" Ñекламе!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/ru/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sk</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklamy sú minulosťou!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sl</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Oglasi so preteklost!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sq</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklamat jane e kaluara!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sr</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Рекламе ÑÑ Ð¿ÑоÑлоÑÑ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>sv-SE</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Säg farväl till all reklam!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>th</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>ลาà¸à¹à¸à¸à¸à¸§à¸à¹à¸à¸©à¸à¸²!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>tr</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Reklamlar geçmiÅte kaldı!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>uk</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Скажи «Ðл ÑекламÑ!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>vi</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>Quảng cáo Äã là dÄ© vãng!</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>http://adblockplus.org/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>zh-CN</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>广åå·²æå¾äºï¼</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>https://adblockplus.org/zh_CN/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:localized>
+ <Description>
+ <em:locale>zh-TW</em:locale>
+ <em:name>Adblock Plus</em:name>
+ <em:description>廣åå·²æéå»å¼ï¼</em:description>
+ <em:creator>Wladimir Palant</em:creator>
+ <em:homepageURL>https://adblockplus.org/zh_TW/</em:homepageURL>
+ </Description>
+ </em:localized>
+ <em:targetApplication>
+ <Description>
+ <!-- conkeror -->
+ <em:id>{a79fe89b-6662-4ff4-8e88-09950ad4dfde}</em:id>
+ <em:minVersion>0.1</em:minVersion>
+ <em:maxVersion>100.0</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- fennec -->
+ <em:id>{a23983c0-fd0e-11dc-95ff-0800200c9a66}</em:id>
+ <em:minVersion>1.1</em:minVersion>
+ <em:maxVersion>9.0a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- firefox -->
+ <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
+ <em:minVersion>3.5</em:minVersion>
+ <em:maxVersion>9.0a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- prism -->
+ <em:id>prism at developer.mozilla.org</em:id>
+ <em:minVersion>1.0b1</em:minVersion>
+ <em:maxVersion>1.0.*</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- seamonkey -->
+ <em:id>{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}</em:id>
+ <em:minVersion>2.0</em:minVersion>
+ <em:maxVersion>2.6a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- songbird -->
+ <em:id>songbird at songbirdnest.com</em:id>
+ <em:minVersion>1.9.0a</em:minVersion>
+ <em:maxVersion>1.11.0a</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ <em:targetApplication>
+ <Description>
+ <!-- thunderbird -->
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
+ <em:minVersion>3.0</em:minVersion>
+ <em:maxVersion>9.0a1</em:maxVersion>
+ </Description>
+ </em:targetApplication>
+ </Description>
+</RDF>
\ No newline at end of file
diff --git a/metadata b/metadata
deleted file mode 100644
index ad2942b..0000000
--- a/metadata
+++ /dev/null
@@ -1,38 +0,0 @@
-[general]
-id={d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}
-basename=adblockplus
-branchname=ADBLOCK_PLUS
-version=1.3.9
-author=Wladimir Palant
-icon=chrome://adblockplus/skin/adblockplus.png
-about=chrome://adblockplus/content/ui/about.xul
-options=chrome://adblockplus/content/ui/settings.xul
-
-[contributors]
-1=Claude Lespagnol aka Efdur
-2=Nickolay Ponomarev
-3=Kevin Keller
-4=Fabrice Desré
-5=Günther Beyer (opoloo.de)
-
-[homepage]
-default=http://adblockplus.org/
-ar=http://adblockplus.org/ar/
-de=http://adblockplus.org/de/
-en=http://adblockplus.org/en/
-es=http://adblockplus.org/es/
-fr=http://adblockplus.org/fr/
-he=http://adblockplus.org/he/
-ko=http://adblockplus.org/ko/
-ru=http://adblockplus.org/ru/
-zh-CN=https://adblockplus.org/zh_CN/
-zh-TW=https://adblockplus.org/zh_TW/
-
-[compat]
-firefox=3.5/7.0a1
-seamonkey=2.0/2.4a1
-thunderbird=3.0/7.0a1
-songbird=1.9.0a/1.11.0a
-conkeror=0.1/100.0
-prism=1.0b1/1.0.*
-fennec=1.1/7.0a1
diff --git a/mochitest/MochiKit/Async.js b/mochitest/MochiKit/Async.js
deleted file mode 100644
index 8ffaad2..0000000
--- a/mochitest/MochiKit/Async.js
+++ /dev/null
@@ -1,681 +0,0 @@
-/***
-
-MochiKit.Async 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide("MochiKit.Async");
- dojo.require("MochiKit.Base");
-}
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Async depends on MochiKit.Base!";
-}
-
-if (typeof(MochiKit.Async) == 'undefined') {
- MochiKit.Async = {};
-}
-
-MochiKit.Async.NAME = "MochiKit.Async";
-MochiKit.Async.VERSION = "1.4";
-MochiKit.Async.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-MochiKit.Async.toString = function () {
- return this.__repr__();
-};
-
-/** @id MochiKit.Async.Deferred */
-MochiKit.Async.Deferred = function (/* optional */ canceller) {
- this.chain = [];
- this.id = this._nextId();
- this.fired = -1;
- this.paused = 0;
- this.results = [null, null];
- this.canceller = canceller;
- this.silentlyCancelled = false;
- this.chained = false;
-};
-
-MochiKit.Async.Deferred.prototype = {
- /** @id MochiKit.Async.Deferred.prototype.repr */
- repr: function () {
- var state;
- if (this.fired == -1) {
- state = 'unfired';
- } else if (this.fired === 0) {
- state = 'success';
- } else {
- state = 'error';
- }
- return 'Deferred(' + this.id + ', ' + state + ')';
- },
-
- toString: MochiKit.Base.forwardCall("repr"),
-
- _nextId: MochiKit.Base.counter(),
-
- /** @id MochiKit.Async.Deferred.prototype.cancel */
- cancel: function () {
- var self = MochiKit.Async;
- if (this.fired == -1) {
- if (this.canceller) {
- this.canceller(this);
- } else {
- this.silentlyCancelled = true;
- }
- if (this.fired == -1) {
- this.errback(new self.CancelledError(this));
- }
- } else if ((this.fired === 0) && (this.results[0] instanceof self.Deferred)) {
- this.results[0].cancel();
- }
- },
-
- _resback: function (res) {
- /***
-
- The primitive that means either callback or errback
-
- ***/
- this.fired = ((res instanceof Error) ? 1 : 0);
- this.results[this.fired] = res;
- this._fire();
- },
-
- _check: function () {
- if (this.fired != -1) {
- if (!this.silentlyCancelled) {
- throw new MochiKit.Async.AlreadyCalledError(this);
- }
- this.silentlyCancelled = false;
- return;
- }
- },
-
- /** @id MochiKit.Async.Deferred.prototype.callback */
- callback: function (res) {
- this._check();
- if (res instanceof MochiKit.Async.Deferred) {
- throw new Error("Deferred instances can only be chained if they are the result of a callback");
- }
- this._resback(res);
- },
-
- /** @id MochiKit.Async.Deferred.prototype.errback */
- errback: function (res) {
- this._check();
- var self = MochiKit.Async;
- if (res instanceof self.Deferred) {
- throw new Error("Deferred instances can only be chained if they are the result of a callback");
- }
- if (!(res instanceof Error)) {
- res = new self.GenericError(res);
- }
- this._resback(res);
- },
-
- /** @id MochiKit.Async.Deferred.prototype.addBoth */
- addBoth: function (fn) {
- if (arguments.length > 1) {
- fn = MochiKit.Base.partial.apply(null, arguments);
- }
- return this.addCallbacks(fn, fn);
- },
-
- /** @id MochiKit.Async.Deferred.prototype.addCallback */
- addCallback: function (fn) {
- if (arguments.length > 1) {
- fn = MochiKit.Base.partial.apply(null, arguments);
- }
- return this.addCallbacks(fn, null);
- },
-
- /** @id MochiKit.Async.Deferred.prototype.addErrback */
- addErrback: function (fn) {
- if (arguments.length > 1) {
- fn = MochiKit.Base.partial.apply(null, arguments);
- }
- return this.addCallbacks(null, fn);
- },
-
- /** @id MochiKit.Async.Deferred.prototype.addCallbacks */
- addCallbacks: function (cb, eb) {
- if (this.chained) {
- throw new Error("Chained Deferreds can not be re-used");
- }
- this.chain.push([cb, eb]);
- if (this.fired >= 0) {
- this._fire();
- }
- return this;
- },
-
- _fire: function () {
- /***
-
- Used internally to exhaust the callback sequence when a result
- is available.
-
- ***/
- var chain = this.chain;
- var fired = this.fired;
- var res = this.results[fired];
- var self = this;
- var cb = null;
- while (chain.length > 0 && this.paused === 0) {
- // Array
- var pair = chain.shift();
- var f = pair[fired];
- if (f === null) {
- continue;
- }
- try {
- res = f(res);
- fired = ((res instanceof Error) ? 1 : 0);
- if (res instanceof MochiKit.Async.Deferred) {
- cb = function (res) {
- self._resback(res);
- self.paused--;
- if ((self.paused === 0) && (self.fired >= 0)) {
- self._fire();
- }
- };
- this.paused++;
- }
- } catch (err) {
- fired = 1;
- if (!(err instanceof Error)) {
- err = new MochiKit.Async.GenericError(err);
- }
- res = err;
- }
- }
- this.fired = fired;
- this.results[fired] = res;
- if (cb && this.paused) {
- // this is for "tail recursion" in case the dependent deferred
- // is already fired
- res.addBoth(cb);
- res.chained = true;
- }
- }
-};
-
-MochiKit.Base.update(MochiKit.Async, {
- /** @id MochiKit.Async.evalJSONRequest */
- evalJSONRequest: function (/* req */) {
- return eval('(' + arguments[0].responseText + ')');
- },
-
- /** @id MochiKit.Async.succeed */
- succeed: function (/* optional */result) {
- var d = new MochiKit.Async.Deferred();
- d.callback.apply(d, arguments);
- return d;
- },
-
- /** @id MochiKit.Async.fail */
- fail: function (/* optional */result) {
- var d = new MochiKit.Async.Deferred();
- d.errback.apply(d, arguments);
- return d;
- },
-
- /** @id MochiKit.Async.getXMLHttpRequest */
- getXMLHttpRequest: function () {
- var self = arguments.callee;
- if (!self.XMLHttpRequest) {
- var tryThese = [
- function () { return new XMLHttpRequest(); },
- function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
- function () { return new ActiveXObject('Microsoft.XMLHTTP'); },
- function () { return new ActiveXObject('Msxml2.XMLHTTP.4.0'); },
- function () {
- throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
- }
- ];
- for (var i = 0; i < tryThese.length; i++) {
- var func = tryThese[i];
- try {
- self.XMLHttpRequest = func;
- return func();
- } catch (e) {
- // pass
- }
- }
- }
- return self.XMLHttpRequest();
- },
-
- _xhr_onreadystatechange: function (d) {
- // MochiKit.Logging.logDebug('this.readyState', this.readyState);
- var m = MochiKit.Base;
- if (this.readyState == 4) {
- // IE SUCKS
- try {
- this.onreadystatechange = null;
- } catch (e) {
- try {
- this.onreadystatechange = m.noop;
- } catch (e) {
- }
- }
- var status = null;
- try {
- status = this.status;
- if (!status && m.isNotEmpty(this.responseText)) {
- // 0 or undefined seems to mean cached or local
- status = 304;
- }
- } catch (e) {
- // pass
- // MochiKit.Logging.logDebug('error getting status?', repr(items(e)));
- }
- // 200 is OK, 304 is NOT_MODIFIED
- if (status == 200 || status == 304) { // OK
- d.callback(this);
- } else {
- var err = new MochiKit.Async.XMLHttpRequestError(this, "Request failed");
- if (err.number) {
- // XXX: This seems to happen on page change
- d.errback(err);
- } else {
- // XXX: this seems to happen when the server is unreachable
- d.errback(err);
- }
- }
- }
- },
-
- _xhr_canceller: function (req) {
- // IE SUCKS
- try {
- req.onreadystatechange = null;
- } catch (e) {
- try {
- req.onreadystatechange = MochiKit.Base.noop;
- } catch (e) {
- }
- }
- req.abort();
- },
-
-
- /** @id MochiKit.Async.sendXMLHttpRequest */
- sendXMLHttpRequest: function (req, /* optional */ sendContent) {
- if (typeof(sendContent) == "undefined" || sendContent === null) {
- sendContent = "";
- }
-
- var m = MochiKit.Base;
- var self = MochiKit.Async;
- var d = new self.Deferred(m.partial(self._xhr_canceller, req));
-
- try {
- req.onreadystatechange = m.bind(self._xhr_onreadystatechange,
- req, d);
- req.send(sendContent);
- } catch (e) {
- try {
- req.onreadystatechange = null;
- } catch (ignore) {
- // pass
- }
- d.errback(e);
- }
-
- return d;
-
- },
-
- /** @id MochiKit.Async.doXHR */
- doXHR: function (url, opts) {
- var m = MochiKit.Base;
- opts = m.update({
- method: 'GET',
- sendContent: ''
- /*
- queryString: undefined,
- username: undefined,
- password: undefined,
- headers: undefined,
- mimeType: undefined
- */
- }, opts);
- var self = MochiKit.Async;
- var req = self.getXMLHttpRequest();
- if (opts.queryString) {
- var qs = m.queryString(opts.queryString);
- if (qs) {
- url += "?" + qs;
- }
- }
- req.open(opts.method, url, true, opts.username, opts.password);
- if (req.overrideMimeType && opts.mimeType) {
- req.overrideMimeType(opts.mimeType);
- }
- if (opts.headers) {
- var headers = opts.headers;
- if (!m.isArrayLike(headers)) {
- headers = m.items(headers);
- }
- for (var i = 0; i < headers.length; i++) {
- var header = headers[i];
- var name = header[0];
- var value = header[1];
- req.setRequestHeader(name, value);
- }
- }
- return self.sendXMLHttpRequest(req, opts.sendContent);
- },
-
- _buildURL: function (url/*, ...*/) {
- if (arguments.length > 1) {
- var m = MochiKit.Base;
- var qs = m.queryString.apply(null, m.extend(null, arguments, 1));
- if (qs) {
- return url + "?" + qs;
- }
- }
- return url;
- },
-
- /** @id MochiKit.Async.doSimpleXMLHttpRequest */
- doSimpleXMLHttpRequest: function (url/*, ...*/) {
- var self = MochiKit.Async;
- url = self._buildURL.apply(self, arguments);
- return self.doXHR(url);
- },
-
- /** @id MochiKit.Async.loadJSONDoc */
- loadJSONDoc: function (url/*, ...*/) {
- var self = MochiKit.Async;
- url = self._buildURL.apply(self, arguments);
- var d = self.doXHR(url, {
- 'mimeType': 'text/plain',
- 'headers': [['Accept', 'application/json']]
- });
- d = d.addCallback(self.evalJSONRequest);
- return d;
- },
-
- /** @id MochiKit.Async.wait */
- wait: function (seconds, /* optional */value) {
- var d = new MochiKit.Async.Deferred();
- var m = MochiKit.Base;
- if (typeof(value) != 'undefined') {
- d.addCallback(function () { return value; });
- }
- var timeout = setTimeout(
- m.bind("callback", d),
- Math.floor(seconds * 1000));
- d.canceller = function () {
- try {
- clearTimeout(timeout);
- } catch (e) {
- // pass
- }
- };
- return d;
- },
-
- /** @id MochiKit.Async.callLater */
- callLater: function (seconds, func) {
- var m = MochiKit.Base;
- var pfunc = m.partial.apply(m, m.extend(null, arguments, 1));
- return MochiKit.Async.wait(seconds).addCallback(
- function (res) { return pfunc(); }
- );
- }
-});
-
-
-/** @id MochiKit.Async.DeferredLock */
-MochiKit.Async.DeferredLock = function () {
- this.waiting = [];
- this.locked = false;
- this.id = this._nextId();
-};
-
-MochiKit.Async.DeferredLock.prototype = {
- __class__: MochiKit.Async.DeferredLock,
- /** @id MochiKit.Async.DeferredLock.prototype.acquire */
- acquire: function () {
- var d = new MochiKit.Async.Deferred();
- if (this.locked) {
- this.waiting.push(d);
- } else {
- this.locked = true;
- d.callback(this);
- }
- return d;
- },
- /** @id MochiKit.Async.DeferredLock.prototype.release */
- release: function () {
- if (!this.locked) {
- throw TypeError("Tried to release an unlocked DeferredLock");
- }
- this.locked = false;
- if (this.waiting.length > 0) {
- this.locked = true;
- this.waiting.shift().callback(this);
- }
- },
- _nextId: MochiKit.Base.counter(),
- repr: function () {
- var state;
- if (this.locked) {
- state = 'locked, ' + this.waiting.length + ' waiting';
- } else {
- state = 'unlocked';
- }
- return 'DeferredLock(' + this.id + ', ' + state + ')';
- },
- toString: MochiKit.Base.forwardCall("repr")
-
-};
-
-/** @id MochiKit.Async.DeferredList */
-MochiKit.Async.DeferredList = function (list, /* optional */fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller) {
-
- // call parent constructor
- MochiKit.Async.Deferred.apply(this, [canceller]);
-
- this.list = list;
- var resultList = [];
- this.resultList = resultList;
-
- this.finishedCount = 0;
- this.fireOnOneCallback = fireOnOneCallback;
- this.fireOnOneErrback = fireOnOneErrback;
- this.consumeErrors = consumeErrors;
-
- var cb = MochiKit.Base.bind(this._cbDeferred, this);
- for (var i = 0; i < list.length; i++) {
- var d = list[i];
- resultList.push(undefined);
- d.addCallback(cb, i, true);
- d.addErrback(cb, i, false);
- }
-
- if (list.length === 0 && !fireOnOneCallback) {
- this.callback(this.resultList);
- }
-
-};
-
-MochiKit.Async.DeferredList.prototype = new MochiKit.Async.Deferred();
-
-MochiKit.Async.DeferredList.prototype._cbDeferred = function (index, succeeded, result) {
- this.resultList[index] = [succeeded, result];
- this.finishedCount += 1;
- if (this.fired == -1) {
- if (succeeded && this.fireOnOneCallback) {
- this.callback([index, result]);
- } else if (!succeeded && this.fireOnOneErrback) {
- this.errback(result);
- } else if (this.finishedCount == this.list.length) {
- this.callback(this.resultList);
- }
- }
- if (!succeeded && this.consumeErrors) {
- result = null;
- }
- return result;
-};
-
-/** @id MochiKit.Async.gatherResults */
-MochiKit.Async.gatherResults = function (deferredList) {
- var d = new MochiKit.Async.DeferredList(deferredList, false, true, false);
- d.addCallback(function (results) {
- var ret = [];
- for (var i = 0; i < results.length; i++) {
- ret.push(results[i][1]);
- }
- return ret;
- });
- return d;
-};
-
-/** @id MochiKit.Async.maybeDeferred */
-MochiKit.Async.maybeDeferred = function (func) {
- var self = MochiKit.Async;
- var result;
- try {
- var r = func.apply(null, MochiKit.Base.extend([], arguments, 1));
- if (r instanceof self.Deferred) {
- result = r;
- } else if (r instanceof Error) {
- result = self.fail(r);
- } else {
- result = self.succeed(r);
- }
- } catch (e) {
- result = self.fail(e);
- }
- return result;
-};
-
-
-MochiKit.Async.EXPORT = [
- "AlreadyCalledError",
- "CancelledError",
- "BrowserComplianceError",
- "GenericError",
- "XMLHttpRequestError",
- "Deferred",
- "succeed",
- "fail",
- "getXMLHttpRequest",
- "doSimpleXMLHttpRequest",
- "loadJSONDoc",
- "wait",
- "callLater",
- "sendXMLHttpRequest",
- "DeferredLock",
- "DeferredList",
- "gatherResults",
- "maybeDeferred",
- "doXHR"
-];
-
-MochiKit.Async.EXPORT_OK = [
- "evalJSONRequest"
-];
-
-MochiKit.Async.__new__ = function () {
- var m = MochiKit.Base;
- var ne = m.partial(m._newNamedError, this);
-
- ne("AlreadyCalledError",
- /** @id MochiKit.Async.AlreadyCalledError */
- function (deferred) {
- /***
-
- Raised by the Deferred if callback or errback happens
- after it was already fired.
-
- ***/
- this.deferred = deferred;
- }
- );
-
- ne("CancelledError",
- /** @id MochiKit.Async.CancelledError */
- function (deferred) {
- /***
-
- Raised by the Deferred cancellation mechanism.
-
- ***/
- this.deferred = deferred;
- }
- );
-
- ne("BrowserComplianceError",
- /** @id MochiKit.Async.BrowserComplianceError */
- function (msg) {
- /***
-
- Raised when the JavaScript runtime is not capable of performing
- the given function. Technically, this should really never be
- raised because a non-conforming JavaScript runtime probably
- isn't going to support exceptions in the first place.
-
- ***/
- this.message = msg;
- }
- );
-
- ne("GenericError",
- /** @id MochiKit.Async.GenericError */
- function (msg) {
- this.message = msg;
- }
- );
-
- ne("XMLHttpRequestError",
- /** @id MochiKit.Async.XMLHttpRequestError */
- function (req, msg) {
- /***
-
- Raised when an XMLHttpRequest does not complete for any reason.
-
- ***/
- this.req = req;
- this.message = msg;
- try {
- // Strange but true that this can raise in some cases.
- this.number = req.status;
- } catch (e) {
- // pass
- }
- }
- );
-
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-
-};
-
-MochiKit.Async.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.Async);
diff --git a/mochitest/MochiKit/Base.js b/mochitest/MochiKit/Base.js
deleted file mode 100644
index 742fa95..0000000
--- a/mochitest/MochiKit/Base.js
+++ /dev/null
@@ -1,1398 +0,0 @@
-/***
-
-MochiKit.Base 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide("MochiKit.Base");
-}
-if (typeof(MochiKit) == 'undefined') {
- MochiKit = {};
-}
-if (typeof(MochiKit.Base) == 'undefined') {
- MochiKit.Base = {};
-}
-if (typeof(MochiKit.__export__) == "undefined") {
- MochiKit.__export__ = (MochiKit.__compat__ ||
- (typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
- );
-}
-
-MochiKit.Base.VERSION = "1.4";
-MochiKit.Base.NAME = "MochiKit.Base";
-/** @id MochiKit.Base.update */
-MochiKit.Base.update = function (self, obj/*, ... */) {
- if (self === null) {
- self = {};
- }
- for (var i = 1; i < arguments.length; i++) {
- var o = arguments[i];
- if (typeof(o) != 'undefined' && o !== null) {
- for (var k in o) {
- self[k] = o[k];
- }
- }
- }
- return self;
-};
-
-MochiKit.Base.update(MochiKit.Base, {
- __repr__: function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
- },
-
- toString: function () {
- return this.__repr__();
- },
-
- /** @id MochiKit.Base.camelize */
- camelize: function (selector) {
- /* from dojo.style.toCamelCase */
- var arr = selector.split('-');
- var cc = arr[0];
- for (var i = 1; i < arr.length; i++) {
- cc += arr[i].charAt(0).toUpperCase() + arr[i].substring(1);
- }
- return cc;
- },
-
- /** @id MochiKit.Base.counter */
- counter: function (n/* = 1 */) {
- if (arguments.length === 0) {
- n = 1;
- }
- return function () {
- return n++;
- };
- },
-
- /** @id MochiKit.Base.clone */
- clone: function (obj) {
- var me = arguments.callee;
- if (arguments.length == 1) {
- me.prototype = obj;
- return new me();
- }
- },
-
- _flattenArray: function (res, lst) {
- for (var i = 0; i < lst.length; i++) {
- var o = lst[i];
- if (o instanceof Array) {
- arguments.callee(res, o);
- } else {
- res.push(o);
- }
- }
- return res;
- },
-
- /** @id MochiKit.Base.flattenArray */
- flattenArray: function (lst) {
- return MochiKit.Base._flattenArray([], lst);
- },
-
- /** @id MochiKit.Base.flattenArguments */
- flattenArguments: function (lst/* ...*/) {
- var res = [];
- var m = MochiKit.Base;
- var args = m.extend(null, arguments);
- while (args.length) {
- var o = args.shift();
- if (o && typeof(o) == "object" && typeof(o.length) == "number") {
- for (var i = o.length - 1; i >= 0; i--) {
- args.unshift(o[i]);
- }
- } else {
- res.push(o);
- }
- }
- return res;
- },
-
- /** @id MochiKit.Base.extend */
- extend: function (self, obj, /* optional */skip) {
- // Extend an array with an array-like object starting
- // from the skip index
- if (!skip) {
- skip = 0;
- }
- if (obj) {
- // allow iterable fall-through, but skip the full isArrayLike
- // check for speed, this is called often.
- var l = obj.length;
- if (typeof(l) != 'number' /* !isArrayLike(obj) */) {
- if (typeof(MochiKit.Iter) != "undefined") {
- obj = MochiKit.Iter.list(obj);
- l = obj.length;
- } else {
- throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
- }
- }
- if (!self) {
- self = [];
- }
- for (var i = skip; i < l; i++) {
- self.push(obj[i]);
- }
- }
- // This mutates, but it's convenient to return because
- // it's often used like a constructor when turning some
- // ghetto array-like to a real array
- return self;
- },
-
-
- /** @id MochiKit.Base.updatetree */
- updatetree: function (self, obj/*, ...*/) {
- if (self === null) {
- self = {};
- }
- for (var i = 1; i < arguments.length; i++) {
- var o = arguments[i];
- if (typeof(o) != 'undefined' && o !== null) {
- for (var k in o) {
- var v = o[k];
- if (typeof(self[k]) == 'object' && typeof(v) == 'object') {
- arguments.callee(self[k], v);
- } else {
- self[k] = v;
- }
- }
- }
- }
- return self;
- },
-
- /** @id MochiKit.Base.setdefault */
- setdefault: function (self, obj/*, ...*/) {
- if (self === null) {
- self = {};
- }
- for (var i = 1; i < arguments.length; i++) {
- var o = arguments[i];
- for (var k in o) {
- if (!(k in self)) {
- self[k] = o[k];
- }
- }
- }
- return self;
- },
-
- /** @id MochiKit.Base.keys */
- keys: function (obj) {
- var rval = [];
- for (var prop in obj) {
- rval.push(prop);
- }
- return rval;
- },
-
- /** @id MochiKit.Base.values */
- values: function (obj) {
- var rval = [];
- for (var prop in obj) {
- rval.push(obj[prop]);
- }
- return rval;
- },
-
- /** @id MochiKit.Base.items */
- items: function (obj) {
- var rval = [];
- var e;
- for (var prop in obj) {
- var v;
- try {
- v = obj[prop];
- } catch (e) {
- continue;
- }
- rval.push([prop, v]);
- }
- return rval;
- },
-
-
- _newNamedError: function (module, name, func) {
- func.prototype = new MochiKit.Base.NamedError(module.NAME + "." + name);
- module[name] = func;
- },
-
-
- /** @id MochiKit.Base.operator */
- operator: {
- // unary logic operators
- /** @id MochiKit.Base.truth */
- truth: function (a) { return !!a; },
- /** @id MochiKit.Base.lognot */
- lognot: function (a) { return !a; },
- /** @id MochiKit.Base.identity */
- identity: function (a) { return a; },
-
- // bitwise unary operators
- /** @id MochiKit.Base.not */
- not: function (a) { return ~a; },
- /** @id MochiKit.Base.neg */
- neg: function (a) { return -a; },
-
- // binary operators
- /** @id MochiKit.Base.add */
- add: function (a, b) { return a + b; },
- /** @id MochiKit.Base.sub */
- sub: function (a, b) { return a - b; },
- /** @id MochiKit.Base.div */
- div: function (a, b) { return a / b; },
- /** @id MochiKit.Base.mod */
- mod: function (a, b) { return a % b; },
- /** @id MochiKit.Base.mul */
- mul: function (a, b) { return a * b; },
-
- // bitwise binary operators
- /** @id MochiKit.Base.and */
- and: function (a, b) { return a & b; },
- /** @id MochiKit.Base.or */
- or: function (a, b) { return a | b; },
- /** @id MochiKit.Base.xor */
- xor: function (a, b) { return a ^ b; },
- /** @id MochiKit.Base.lshift */
- lshift: function (a, b) { return a << b; },
- /** @id MochiKit.Base.rshift */
- rshift: function (a, b) { return a >> b; },
- /** @id MochiKit.Base.zrshift */
- zrshift: function (a, b) { return a >>> b; },
-
- // near-worthless built-in comparators
- /** @id MochiKit.Base.eq */
- eq: function (a, b) { return a == b; },
- /** @id MochiKit.Base.ne */
- ne: function (a, b) { return a != b; },
- /** @id MochiKit.Base.gt */
- gt: function (a, b) { return a > b; },
- /** @id MochiKit.Base.ge */
- ge: function (a, b) { return a >= b; },
- /** @id MochiKit.Base.lt */
- lt: function (a, b) { return a < b; },
- /** @id MochiKit.Base.le */
- le: function (a, b) { return a <= b; },
-
- // strict built-in comparators
- seq: function (a, b) { return a === b; },
- sne: function (a, b) { return a !== b; },
-
- // compare comparators
- /** @id MochiKit.Base.ceq */
- ceq: function (a, b) { return MochiKit.Base.compare(a, b) === 0; },
- /** @id MochiKit.Base.cne */
- cne: function (a, b) { return MochiKit.Base.compare(a, b) !== 0; },
- /** @id MochiKit.Base.cgt */
- cgt: function (a, b) { return MochiKit.Base.compare(a, b) == 1; },
- /** @id MochiKit.Base.cge */
- cge: function (a, b) { return MochiKit.Base.compare(a, b) != -1; },
- /** @id MochiKit.Base.clt */
- clt: function (a, b) { return MochiKit.Base.compare(a, b) == -1; },
- /** @id MochiKit.Base.cle */
- cle: function (a, b) { return MochiKit.Base.compare(a, b) != 1; },
-
- // binary logical operators
- /** @id MochiKit.Base.logand */
- logand: function (a, b) { return a && b; },
- /** @id MochiKit.Base.logor */
- logor: function (a, b) { return a || b; },
- /** @id MochiKit.Base.contains */
- contains: function (a, b) { return b in a; }
- },
-
- /** @id MochiKit.Base.forwardCall */
- forwardCall: function (func) {
- return function () {
- return this[func].apply(this, arguments);
- };
- },
-
- /** @id MochiKit.Base.itemgetter */
- itemgetter: function (func) {
- return function (arg) {
- return arg[func];
- };
- },
-
- /** @id MochiKit.Base.typeMatcher */
- typeMatcher: function (/* typ */) {
- var types = {};
- for (var i = 0; i < arguments.length; i++) {
- var typ = arguments[i];
- types[typ] = typ;
- }
- return function () {
- for (var i = 0; i < arguments.length; i++) {
- if (!(typeof(arguments[i]) in types)) {
- return false;
- }
- }
- return true;
- };
- },
-
- /** @id MochiKit.Base.isNull */
- isNull: function (/* ... */) {
- for (var i = 0; i < arguments.length; i++) {
- if (arguments[i] !== null) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.Base.isUndefinedOrNull */
- isUndefinedOrNull: function (/* ... */) {
- for (var i = 0; i < arguments.length; i++) {
- var o = arguments[i];
- if (!(typeof(o) == 'undefined' || o === null)) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.Base.isEmpty */
- isEmpty: function (obj) {
- return !MochiKit.Base.isNotEmpty.apply(this, arguments);
- },
-
- /** @id MochiKit.Base.isNotEmpty */
- isNotEmpty: function (obj) {
- for (var i = 0; i < arguments.length; i++) {
- var o = arguments[i];
- if (!(o && o.length)) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.Base.isArrayLike */
- isArrayLike: function () {
- for (var i = 0; i < arguments.length; i++) {
- var o = arguments[i];
- var typ = typeof(o);
- if (
- (typ != 'object' && !(typ == 'function' && typeof(o.item) == 'function')) ||
- o === null ||
- typeof(o.length) != 'number' ||
- o.nodeType === 3
- ) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.Base.isDateLike */
- isDateLike: function () {
- for (var i = 0; i < arguments.length; i++) {
- var o = arguments[i];
- if (typeof(o) != "object" || o === null
- || typeof(o.getTime) != 'function') {
- return false;
- }
- }
- return true;
- },
-
-
- /** @id MochiKit.Base.xmap */
- xmap: function (fn/*, obj... */) {
- if (fn === null) {
- return MochiKit.Base.extend(null, arguments, 1);
- }
- var rval = [];
- for (var i = 1; i < arguments.length; i++) {
- rval.push(fn(arguments[i]));
- }
- return rval;
- },
-
- /** @id MochiKit.Base.map */
- map: function (fn, lst/*, lst... */) {
- var m = MochiKit.Base;
- var itr = MochiKit.Iter;
- var isArrayLike = m.isArrayLike;
- if (arguments.length <= 2) {
- // allow an iterable to be passed
- if (!isArrayLike(lst)) {
- if (itr) {
- // fast path for map(null, iterable)
- lst = itr.list(lst);
- if (fn === null) {
- return lst;
- }
- } else {
- throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
- }
- }
- // fast path for map(null, lst)
- if (fn === null) {
- return m.extend(null, lst);
- }
- // disabled fast path for map(fn, lst)
- /*
- if (false && typeof(Array.prototype.map) == 'function') {
- // Mozilla fast-path
- return Array.prototype.map.call(lst, fn);
- }
- */
- var rval = [];
- for (var i = 0; i < lst.length; i++) {
- rval.push(fn(lst[i]));
- }
- return rval;
- } else {
- // default for map(null, ...) is zip(...)
- if (fn === null) {
- fn = Array;
- }
- var length = null;
- for (i = 1; i < arguments.length; i++) {
- // allow iterables to be passed
- if (!isArrayLike(arguments[i])) {
- if (itr) {
- return itr.list(itr.imap.apply(null, arguments));
- } else {
- throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
- }
- }
- // find the minimum length
- var l = arguments[i].length;
- if (length === null || length > l) {
- length = l;
- }
- }
- rval = [];
- for (i = 0; i < length; i++) {
- var args = [];
- for (var j = 1; j < arguments.length; j++) {
- args.push(arguments[j][i]);
- }
- rval.push(fn.apply(this, args));
- }
- return rval;
- }
- },
-
- /** @id MochiKit.Base.xfilter */
- xfilter: function (fn/*, obj... */) {
- var rval = [];
- if (fn === null) {
- fn = MochiKit.Base.operator.truth;
- }
- for (var i = 1; i < arguments.length; i++) {
- var o = arguments[i];
- if (fn(o)) {
- rval.push(o);
- }
- }
- return rval;
- },
-
- /** @id MochiKit.Base.filter */
- filter: function (fn, lst, self) {
- var rval = [];
- // allow an iterable to be passed
- var m = MochiKit.Base;
- if (!m.isArrayLike(lst)) {
- if (MochiKit.Iter) {
- lst = MochiKit.Iter.list(lst);
- } else {
- throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
- }
- }
- if (fn === null) {
- fn = m.operator.truth;
- }
- if (typeof(Array.prototype.filter) == 'function') {
- // Mozilla fast-path
- return Array.prototype.filter.call(lst, fn, self);
- } else if (typeof(self) == 'undefined' || self === null) {
- for (var i = 0; i < lst.length; i++) {
- var o = lst[i];
- if (fn(o)) {
- rval.push(o);
- }
- }
- } else {
- for (i = 0; i < lst.length; i++) {
- o = lst[i];
- if (fn.call(self, o)) {
- rval.push(o);
- }
- }
- }
- return rval;
- },
-
-
- _wrapDumbFunction: function (func) {
- return function () {
- // fast path!
- switch (arguments.length) {
- case 0: return func();
- case 1: return func(arguments[0]);
- case 2: return func(arguments[0], arguments[1]);
- case 3: return func(arguments[0], arguments[1], arguments[2]);
- }
- var args = [];
- for (var i = 0; i < arguments.length; i++) {
- args.push("arguments[" + i + "]");
- }
- return eval("(func(" + args.join(",") + "))");
- };
- },
-
- /** @id MochiKit.Base.methodcaller */
- methodcaller: function (func/*, args... */) {
- var args = MochiKit.Base.extend(null, arguments, 1);
- if (typeof(func) == "function") {
- return function (obj) {
- return func.apply(obj, args);
- };
- } else {
- return function (obj) {
- return obj[func].apply(obj, args);
- };
- }
- },
-
- /** @id MochiKit.Base.method */
- method: function (self, func) {
- var m = MochiKit.Base;
- return m.bind.apply(this, m.extend([func, self], arguments, 2));
- },
-
- /** @id MochiKit.Base.compose */
- compose: function (f1, f2/*, f3, ... fN */) {
- var fnlist = [];
- var m = MochiKit.Base;
- if (arguments.length === 0) {
- throw new TypeError("compose() requires at least one argument");
- }
- for (var i = 0; i < arguments.length; i++) {
- var fn = arguments[i];
- if (typeof(fn) != "function") {
- throw new TypeError(m.repr(fn) + " is not a function");
- }
- fnlist.push(fn);
- }
- return function () {
- var args = arguments;
- for (var i = fnlist.length - 1; i >= 0; i--) {
- args = [fnlist[i].apply(this, args)];
- }
- return args[0];
- };
- },
-
- /** @id MochiKit.Base.bind */
- bind: function (func, self/* args... */) {
- if (typeof(func) == "string") {
- func = self[func];
- }
- var im_func = func.im_func;
- var im_preargs = func.im_preargs;
- var im_self = func.im_self;
- var m = MochiKit.Base;
- if (typeof(func) == "function" && typeof(func.apply) == "undefined") {
- // this is for cases where JavaScript sucks ass and gives you a
- // really dumb built-in function like alert() that doesn't have
- // an apply
- func = m._wrapDumbFunction(func);
- }
- if (typeof(im_func) != 'function') {
- im_func = func;
- }
- if (typeof(self) != 'undefined') {
- im_self = self;
- }
- if (typeof(im_preargs) == 'undefined') {
- im_preargs = [];
- } else {
- im_preargs = im_preargs.slice();
- }
- m.extend(im_preargs, arguments, 2);
- var newfunc = function () {
- var args = arguments;
- var me = arguments.callee;
- if (me.im_preargs.length > 0) {
- args = m.concat(me.im_preargs, args);
- }
- var self = me.im_self;
- if (!self) {
- self = this;
- }
- return me.im_func.apply(self, args);
- };
- newfunc.im_self = im_self;
- newfunc.im_func = im_func;
- newfunc.im_preargs = im_preargs;
- return newfunc;
- },
-
- /** @id MochiKit.Base.bindMethods */
- bindMethods: function (self) {
- var bind = MochiKit.Base.bind;
- for (var k in self) {
- var func = self[k];
- if (typeof(func) == 'function') {
- self[k] = bind(func, self);
- }
- }
- },
-
- /** @id MochiKit.Base.registerComparator */
- registerComparator: function (name, check, comparator, /* optional */ override) {
- MochiKit.Base.comparatorRegistry.register(name, check, comparator, override);
- },
-
- _primitives: {'boolean': true, 'string': true, 'number': true},
-
- /** @id MochiKit.Base.compare */
- compare: function (a, b) {
- if (a == b) {
- return 0;
- }
- var aIsNull = (typeof(a) == 'undefined' || a === null);
- var bIsNull = (typeof(b) == 'undefined' || b === null);
- if (aIsNull && bIsNull) {
- return 0;
- } else if (aIsNull) {
- return -1;
- } else if (bIsNull) {
- return 1;
- }
- var m = MochiKit.Base;
- // bool, number, string have meaningful comparisons
- var prim = m._primitives;
- if (!(typeof(a) in prim && typeof(b) in prim)) {
- try {
- return m.comparatorRegistry.match(a, b);
- } catch (e) {
- if (e != m.NotFound) {
- throw e;
- }
- }
- }
- if (a < b) {
- return -1;
- } else if (a > b) {
- return 1;
- }
- // These types can't be compared
- var repr = m.repr;
- throw new TypeError(repr(a) + " and " + repr(b) + " can not be compared");
- },
-
- /** @id MochiKit.Base.compareDateLike */
- compareDateLike: function (a, b) {
- return MochiKit.Base.compare(a.getTime(), b.getTime());
- },
-
- /** @id MochiKit.Base.compareArrayLike */
- compareArrayLike: function (a, b) {
- var compare = MochiKit.Base.compare;
- var count = a.length;
- var rval = 0;
- if (count > b.length) {
- rval = 1;
- count = b.length;
- } else if (count < b.length) {
- rval = -1;
- }
- for (var i = 0; i < count; i++) {
- var cmp = compare(a[i], b[i]);
- if (cmp) {
- return cmp;
- }
- }
- return rval;
- },
-
- /** @id MochiKit.Base.registerRepr */
- registerRepr: function (name, check, wrap, /* optional */override) {
- MochiKit.Base.reprRegistry.register(name, check, wrap, override);
- },
-
- /** @id MochiKit.Base.repr */
- repr: function (o) {
- if (typeof(o) == "undefined") {
- return "undefined";
- } else if (o === null) {
- return "null";
- }
- try {
- if (typeof(o.__repr__) == 'function') {
- return o.__repr__();
- } else if (typeof(o.repr) == 'function' && o.repr != arguments.callee) {
- return o.repr();
- }
- return MochiKit.Base.reprRegistry.match(o);
- } catch (e) {
- if (typeof(o.NAME) == 'string' && (
- o.toString == Function.prototype.toString ||
- o.toString == Object.prototype.toString
- )) {
- return o.NAME;
- }
- }
- try {
- var ostring = (o + "");
- } catch (e) {
- return "[" + typeof(o) + "]";
- }
- if (typeof(o) == "function") {
- o = ostring.replace(/^\s+/, "");
- var idx = o.indexOf("{");
- if (idx != -1) {
- o = o.substr(0, idx) + "{...}";
- }
- }
- return ostring;
- },
-
- /** @id MochiKit.Base.reprArrayLike */
- reprArrayLike: function (o) {
- var m = MochiKit.Base;
- return "[" + m.map(m.repr, o).join(", ") + "]";
- },
-
- /** @id MochiKit.Base.reprString */
- reprString: function (o) {
- return ('"' + o.replace(/(["\\])/g, '\\$1') + '"'
- ).replace(/[\f]/g, "\\f"
- ).replace(/[\b]/g, "\\b"
- ).replace(/[\n]/g, "\\n"
- ).replace(/[\t]/g, "\\t"
- ).replace(/[\r]/g, "\\r");
- },
-
- /** @id MochiKit.Base.reprNumber */
- reprNumber: function (o) {
- return o + "";
- },
-
- /** @id MochiKit.Base.registerJSON */
- registerJSON: function (name, check, wrap, /* optional */override) {
- MochiKit.Base.jsonRegistry.register(name, check, wrap, override);
- },
-
-
- /** @id MochiKit.Base.evalJSON */
- evalJSON: function () {
- return eval("(" + arguments[0] + ")");
- },
-
- /** @id MochiKit.Base.serializeJSON */
- serializeJSON: function (o) {
- var objtype = typeof(o);
- if (objtype == "number" || objtype == "boolean") {
- return o + "";
- } else if (o === null) {
- return "null";
- }
- var m = MochiKit.Base;
- var reprString = m.reprString;
- if (objtype == "string") {
- return reprString(o);
- }
- // recurse
- var me = arguments.callee;
- // short-circuit for objects that support "json" serialization
- // if they return "self" then just pass-through...
- var newObj;
- if (typeof(o.__json__) == "function") {
- newObj = o.__json__();
- if (o !== newObj) {
- return me(newObj);
- }
- }
- if (typeof(o.json) == "function") {
- newObj = o.json();
- if (o !== newObj) {
- return me(newObj);
- }
- }
- // array
- if (objtype != "function" && typeof(o.length) == "number") {
- var res = [];
- for (var i = 0; i < o.length; i++) {
- var val = me(o[i]);
- if (typeof(val) != "string") {
- val = "undefined";
- }
- res.push(val);
- }
- return "[" + res.join(", ") + "]";
- }
- // look in the registry
- try {
- newObj = m.jsonRegistry.match(o);
- if (o !== newObj) {
- return me(newObj);
- }
- } catch (e) {
- if (e != m.NotFound) {
- // something really bad happened
- throw e;
- }
- }
- // undefined is outside of the spec
- if (objtype == "undefined") {
- throw new TypeError("undefined can not be serialized as JSON");
- }
- // it's a function with no adapter, bad
- if (objtype == "function") {
- return null;
- }
- // generic object code path
- res = [];
- for (var k in o) {
- var useKey;
- if (typeof(k) == "number") {
- useKey = '"' + k + '"';
- } else if (typeof(k) == "string") {
- useKey = reprString(k);
- } else {
- // skip non-string or number keys
- continue;
- }
- val = me(o[k]);
- if (typeof(val) != "string") {
- // skip non-serializable values
- continue;
- }
- res.push(useKey + ":" + val);
- }
- return "{" + res.join(", ") + "}";
- },
-
-
- /** @id MochiKit.Base.objEqual */
- objEqual: function (a, b) {
- return (MochiKit.Base.compare(a, b) === 0);
- },
-
- /** @id MochiKit.Base.arrayEqual */
- arrayEqual: function (self, arr) {
- if (self.length != arr.length) {
- return false;
- }
- return (MochiKit.Base.compare(self, arr) === 0);
- },
-
- /** @id MochiKit.Base.concat */
- concat: function (/* lst... */) {
- var rval = [];
- var extend = MochiKit.Base.extend;
- for (var i = 0; i < arguments.length; i++) {
- extend(rval, arguments[i]);
- }
- return rval;
- },
-
- /** @id MochiKit.Base.keyComparator */
- keyComparator: function (key/* ... */) {
- // fast-path for single key comparisons
- var m = MochiKit.Base;
- var compare = m.compare;
- if (arguments.length == 1) {
- return function (a, b) {
- return compare(a[key], b[key]);
- };
- }
- var compareKeys = m.extend(null, arguments);
- return function (a, b) {
- var rval = 0;
- // keep comparing until something is inequal or we run out of
- // keys to compare
- for (var i = 0; (rval === 0) && (i < compareKeys.length); i++) {
- var key = compareKeys[i];
- rval = compare(a[key], b[key]);
- }
- return rval;
- };
- },
-
- /** @id MochiKit.Base.reverseKeyComparator */
- reverseKeyComparator: function (key) {
- var comparator = MochiKit.Base.keyComparator.apply(this, arguments);
- return function (a, b) {
- return comparator(b, a);
- };
- },
-
- /** @id MochiKit.Base.partial */
- partial: function (func) {
- var m = MochiKit.Base;
- return m.bind.apply(this, m.extend([func, undefined], arguments, 1));
- },
-
- /** @id MochiKit.Base.listMinMax */
- listMinMax: function (which, lst) {
- if (lst.length === 0) {
- return null;
- }
- var cur = lst[0];
- var compare = MochiKit.Base.compare;
- for (var i = 1; i < lst.length; i++) {
- var o = lst[i];
- if (compare(o, cur) == which) {
- cur = o;
- }
- }
- return cur;
- },
-
- /** @id MochiKit.Base.objMax */
- objMax: function (/* obj... */) {
- return MochiKit.Base.listMinMax(1, arguments);
- },
-
- /** @id MochiKit.Base.objMin */
- objMin: function (/* obj... */) {
- return MochiKit.Base.listMinMax(-1, arguments);
- },
-
- /** @id MochiKit.Base.findIdentical */
- findIdentical: function (lst, value, start/* = 0 */, /* optional */end) {
- if (typeof(end) == "undefined" || end === null) {
- end = lst.length;
- }
- if (typeof(start) == "undefined" || start === null) {
- start = 0;
- }
- for (var i = start; i < end; i++) {
- if (lst[i] === value) {
- return i;
- }
- }
- return -1;
- },
-
- /** @id MochiKit.Base.mean */
- mean: function(/* lst... */) {
- /* http://www.nist.gov/dads/HTML/mean.html */
- var sum = 0;
-
- var m = MochiKit.Base;
- var args = m.extend(null, arguments);
- var count = args.length;
-
- while (args.length) {
- var o = args.shift();
- if (o && typeof(o) == "object" && typeof(o.length) == "number") {
- count += o.length - 1;
- for (var i = o.length - 1; i >= 0; i--) {
- sum += o[i];
- }
- } else {
- sum += o;
- }
- }
-
- if (count <= 0) {
- throw new TypeError('mean() requires at least one argument');
- }
-
- return sum/count;
- },
-
- /** @id MochiKit.Base.median */
- median: function(/* lst... */) {
- /* http://www.nist.gov/dads/HTML/median.html */
- var data = MochiKit.Base.flattenArguments(arguments);
- if (data.length === 0) {
- throw new TypeError('median() requires at least one argument');
- }
- data.sort(compare);
- if (data.length % 2 == 0) {
- var upper = data.length / 2;
- return (data[upper] + data[upper - 1]) / 2;
- } else {
- return data[(data.length - 1) / 2];
- }
- },
-
- /** @id MochiKit.Base.findValue */
- findValue: function (lst, value, start/* = 0 */, /* optional */end) {
- if (typeof(end) == "undefined" || end === null) {
- end = lst.length;
- }
- if (typeof(start) == "undefined" || start === null) {
- start = 0;
- }
- var cmp = MochiKit.Base.compare;
- for (var i = start; i < end; i++) {
- if (cmp(lst[i], value) === 0) {
- return i;
- }
- }
- return -1;
- },
-
- /** @id MochiKit.Base.nodeWalk */
- nodeWalk: function (node, visitor) {
- var nodes = [node];
- var extend = MochiKit.Base.extend;
- while (nodes.length) {
- var res = visitor(nodes.shift());
- if (res) {
- extend(nodes, res);
- }
- }
- },
-
-
- /** @id MochiKit.Base.nameFunctions */
- nameFunctions: function (namespace) {
- var base = namespace.NAME;
- if (typeof(base) == 'undefined') {
- base = '';
- } else {
- base = base + '.';
- }
- for (var name in namespace) {
- var o = namespace[name];
- if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
- try {
- o.NAME = base + name;
- } catch (e) {
- // pass
- }
- }
- }
- },
-
-
- /** @id MochiKit.Base.queryString */
- queryString: function (names, values) {
- // check to see if names is a string or a DOM element, and if
- // MochiKit.DOM is available. If so, drop it like it's a form
- // Ugliest conditional in MochiKit? Probably!
- if (typeof(MochiKit.DOM) != "undefined" && arguments.length == 1
- && (typeof(names) == "string" || (
- typeof(names.nodeType) != "undefined" && names.nodeType > 0
- ))
- ) {
- var kv = MochiKit.DOM.formContents(names);
- names = kv[0];
- values = kv[1];
- } else if (arguments.length == 1) {
- var o = names;
- names = [];
- values = [];
- for (var k in o) {
- var v = o[k];
- if (typeof(v) == "function") {
- continue;
- } else if (typeof(v) != "string" &&
- typeof(v.length) == "number") {
- for (var i = 0; i < v.length; i++) {
- names.push(k);
- values.push(v[i]);
- }
- } else {
- names.push(k);
- values.push(v);
- }
- }
- }
- var rval = [];
- var len = Math.min(names.length, values.length);
- var urlEncode = MochiKit.Base.urlEncode;
- for (var i = 0; i < len; i++) {
- v = values[i];
- if (typeof(v) != 'undefined' && v !== null) {
- rval.push(urlEncode(names[i]) + "=" + urlEncode(v));
- }
- }
- return rval.join("&");
- },
-
-
- /** @id MochiKit.Base.parseQueryString */
- parseQueryString: function (encodedString, useArrays) {
- // strip a leading '?' from the encoded string
- var qstr = (encodedString[0] == "?") ? encodedString.substring(1) :
- encodedString;
- var pairs = qstr.replace(/\+/g, "%20").split(/(\&\;|\&\#38\;|\&|\&)/);
- var o = {};
- var decode;
- if (typeof(decodeURIComponent) != "undefined") {
- decode = decodeURIComponent;
- } else {
- decode = unescape;
- }
- if (useArrays) {
- for (var i = 0; i < pairs.length; i++) {
- var pair = pairs[i].split("=");
- if (pair.length !== 2) {
- continue;
- }
- var name = decode(pair[0]);
- var arr = o[name];
- if (!(arr instanceof Array)) {
- arr = [];
- o[name] = arr;
- }
- arr.push(decode(pair[1]));
- }
- } else {
- for (i = 0; i < pairs.length; i++) {
- pair = pairs[i].split("=");
- if (pair.length !== 2) {
- continue;
- }
- o[decode(pair[0])] = decode(pair[1]);
- }
- }
- return o;
- }
-});
-
-/** @id MochiKit.Base.AdapterRegistry */
-MochiKit.Base.AdapterRegistry = function () {
- this.pairs = [];
-};
-
-MochiKit.Base.AdapterRegistry.prototype = {
- /** @id MochiKit.Base.AdapterRegistry.prototype.register */
- register: function (name, check, wrap, /* optional */ override) {
- if (override) {
- this.pairs.unshift([name, check, wrap]);
- } else {
- this.pairs.push([name, check, wrap]);
- }
- },
-
- /** @id MochiKit.Base.AdapterRegistry.prototype.match */
- match: function (/* ... */) {
- for (var i = 0; i < this.pairs.length; i++) {
- var pair = this.pairs[i];
- if (pair[1].apply(this, arguments)) {
- return pair[2].apply(this, arguments);
- }
- }
- throw MochiKit.Base.NotFound;
- },
-
- /** @id MochiKit.Base.AdapterRegistry.prototype.unregister */
- unregister: function (name) {
- for (var i = 0; i < this.pairs.length; i++) {
- var pair = this.pairs[i];
- if (pair[0] == name) {
- this.pairs.splice(i, 1);
- return true;
- }
- }
- return false;
- }
-};
-
-
-MochiKit.Base.EXPORT = [
- "flattenArray",
- "noop",
- "camelize",
- "counter",
- "clone",
- "extend",
- "update",
- "updatetree",
- "setdefault",
- "keys",
- "values",
- "items",
- "NamedError",
- "operator",
- "forwardCall",
- "itemgetter",
- "typeMatcher",
- "isCallable",
- "isUndefined",
- "isUndefinedOrNull",
- "isNull",
- "isEmpty",
- "isNotEmpty",
- "isArrayLike",
- "isDateLike",
- "xmap",
- "map",
- "xfilter",
- "filter",
- "methodcaller",
- "compose",
- "bind",
- "bindMethods",
- "NotFound",
- "AdapterRegistry",
- "registerComparator",
- "compare",
- "registerRepr",
- "repr",
- "objEqual",
- "arrayEqual",
- "concat",
- "keyComparator",
- "reverseKeyComparator",
- "partial",
- "merge",
- "listMinMax",
- "listMax",
- "listMin",
- "objMax",
- "objMin",
- "nodeWalk",
- "zip",
- "urlEncode",
- "queryString",
- "serializeJSON",
- "registerJSON",
- "evalJSON",
- "parseQueryString",
- "findValue",
- "findIdentical",
- "flattenArguments",
- "method",
- "average",
- "mean",
- "median"
-];
-
-MochiKit.Base.EXPORT_OK = [
- "nameFunctions",
- "comparatorRegistry",
- "reprRegistry",
- "jsonRegistry",
- "compareDateLike",
- "compareArrayLike",
- "reprArrayLike",
- "reprString",
- "reprNumber"
-];
-
-MochiKit.Base._exportSymbols = function (globals, module) {
- if (!MochiKit.__export__) {
- return;
- }
- var all = module.EXPORT_TAGS[":all"];
- for (var i = 0; i < all.length; i++) {
- globals[all[i]] = module[all[i]];
- }
-};
-
-MochiKit.Base.__new__ = function () {
- // A singleton raised when no suitable adapter is found
- var m = this;
-
- // convenience
- /** @id MochiKit.Base.noop */
- m.noop = m.operator.identity;
-
- // Backwards compat
- m.forward = m.forwardCall;
- m.find = m.findValue;
-
- if (typeof(encodeURIComponent) != "undefined") {
- /** @id MochiKit.Base.urlEncode */
- m.urlEncode = function (unencoded) {
- return encodeURIComponent(unencoded).replace(/\'/g, '%27');
- };
- } else {
- m.urlEncode = function (unencoded) {
- return escape(unencoded
- ).replace(/\+/g, '%2B'
- ).replace(/\"/g,'%22'
- ).rval.replace(/\'/g, '%27');
- };
- }
-
- /** @id MochiKit.Base.NamedError */
- m.NamedError = function (name) {
- this.message = name;
- this.name = name;
- };
- m.NamedError.prototype = new Error();
- m.update(m.NamedError.prototype, {
- repr: function () {
- if (this.message && this.message != this.name) {
- return this.name + "(" + m.repr(this.message) + ")";
- } else {
- return this.name + "()";
- }
- },
- toString: m.forwardCall("repr")
- });
-
- /** @id MochiKit.Base.NotFound */
- m.NotFound = new m.NamedError("MochiKit.Base.NotFound");
-
-
- /** @id MochiKit.Base.listMax */
- m.listMax = m.partial(m.listMinMax, 1);
- /** @id MochiKit.Base.listMin */
- m.listMin = m.partial(m.listMinMax, -1);
-
- /** @id MochiKit.Base.isCallable */
- m.isCallable = m.typeMatcher('function');
- /** @id MochiKit.Base.isUndefined */
- m.isUndefined = m.typeMatcher('undefined');
-
- /** @id MochiKit.Base.merge */
- m.merge = m.partial(m.update, null);
- /** @id MochiKit.Base.zip */
- m.zip = m.partial(m.map, null);
-
- /** @id MochiKit.Base.average */
- m.average = m.mean;
-
- /** @id MochiKit.Base.comparatorRegistry */
- m.comparatorRegistry = new m.AdapterRegistry();
- m.registerComparator("dateLike", m.isDateLike, m.compareDateLike);
- m.registerComparator("arrayLike", m.isArrayLike, m.compareArrayLike);
-
- /** @id MochiKit.Base.reprRegistry */
- m.reprRegistry = new m.AdapterRegistry();
- m.registerRepr("arrayLike", m.isArrayLike, m.reprArrayLike);
- m.registerRepr("string", m.typeMatcher("string"), m.reprString);
- m.registerRepr("numbers", m.typeMatcher("number", "boolean"), m.reprNumber);
-
- /** @id MochiKit.Base.jsonRegistry */
- m.jsonRegistry = new m.AdapterRegistry();
-
- var all = m.concat(m.EXPORT, m.EXPORT_OK);
- m.EXPORT_TAGS = {
- ":common": m.concat(m.EXPORT_OK),
- ":all": all
- };
-
- m.nameFunctions(this);
-
-};
-
-MochiKit.Base.__new__();
-
-//
-// XXX: Internet Explorer blows
-//
-if (MochiKit.__export__) {
- compare = MochiKit.Base.compare;
- compose = MochiKit.Base.compose;
- serializeJSON = MochiKit.Base.serializeJSON;
-}
-
-MochiKit.Base._exportSymbols(this, MochiKit.Base);
diff --git a/mochitest/MochiKit/Color.js b/mochitest/MochiKit/Color.js
deleted file mode 100644
index 50e7acf..0000000
--- a/mochitest/MochiKit/Color.js
+++ /dev/null
@@ -1,902 +0,0 @@
-/***
-
-MochiKit.Color 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito and others. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Color');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Style');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
- JSAN.use("MochiKit.DOM", []);
- JSAN.use("MochiKit.Style", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Color depends on MochiKit.Base";
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Color depends on MochiKit.DOM";
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Color depends on MochiKit.Style";
-}
-
-if (typeof(MochiKit.Color) == "undefined") {
- MochiKit.Color = {};
-}
-
-MochiKit.Color.NAME = "MochiKit.Color";
-MochiKit.Color.VERSION = "1.4";
-
-MochiKit.Color.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-MochiKit.Color.toString = function () {
- return this.__repr__();
-};
-
-
-/** @id MochiKit.Color.Color */
-MochiKit.Color.Color = function (red, green, blue, alpha) {
- if (typeof(alpha) == 'undefined' || alpha === null) {
- alpha = 1.0;
- }
- this.rgb = {
- r: red,
- g: green,
- b: blue,
- a: alpha
- };
-};
-
-
-// Prototype methods
-
-MochiKit.Color.Color.prototype = {
-
- __class__: MochiKit.Color.Color,
-
- /** @id MochiKit.Color.Color.prototype.colorWithAlpha */
- colorWithAlpha: function (alpha) {
- var rgb = this.rgb;
- var m = MochiKit.Color;
- return m.Color.fromRGB(rgb.r, rgb.g, rgb.b, alpha);
- },
-
- /** @id MochiKit.Color.Color.prototype.colorWithHue */
- colorWithHue: function (hue) {
- // get an HSL model, and set the new hue...
- var hsl = this.asHSL();
- hsl.h = hue;
- var m = MochiKit.Color;
- // convert back to RGB...
- return m.Color.fromHSL(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.colorWithSaturation */
- colorWithSaturation: function (saturation) {
- // get an HSL model, and set the new hue...
- var hsl = this.asHSL();
- hsl.s = saturation;
- var m = MochiKit.Color;
- // convert back to RGB...
- return m.Color.fromHSL(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.colorWithLightness */
- colorWithLightness: function (lightness) {
- // get an HSL model, and set the new hue...
- var hsl = this.asHSL();
- hsl.l = lightness;
- var m = MochiKit.Color;
- // convert back to RGB...
- return m.Color.fromHSL(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.darkerColorWithLevel */
- darkerColorWithLevel: function (level) {
- var hsl = this.asHSL();
- hsl.l = Math.max(hsl.l - level, 0);
- var m = MochiKit.Color;
- return m.Color.fromHSL(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.lighterColorWithLevel */
- lighterColorWithLevel: function (level) {
- var hsl = this.asHSL();
- hsl.l = Math.min(hsl.l + level, 1);
- var m = MochiKit.Color;
- return m.Color.fromHSL(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.blendedColor */
- blendedColor: function (other, /* optional */ fraction) {
- if (typeof(fraction) == 'undefined' || fraction === null) {
- fraction = 0.5;
- }
- var sf = 1.0 - fraction;
- var s = this.rgb;
- var d = other.rgb;
- var df = fraction;
- return MochiKit.Color.Color.fromRGB(
- (s.r * sf) + (d.r * df),
- (s.g * sf) + (d.g * df),
- (s.b * sf) + (d.b * df),
- (s.a * sf) + (d.a * df)
- );
- },
-
- /** @id MochiKit.Color.Color.prototype.compareRGB */
- compareRGB: function (other) {
- var a = this.asRGB();
- var b = other.asRGB();
- return MochiKit.Base.compare(
- [a.r, a.g, a.b, a.a],
- [b.r, b.g, b.b, b.a]
- );
- },
-
- /** @id MochiKit.Color.Color.prototype.isLight */
- isLight: function () {
- return this.asHSL().b > 0.5;
- },
-
- /** @id MochiKit.Color.Color.prototype.isDark */
- isDark: function () {
- return (!this.isLight());
- },
-
- /** @id MochiKit.Color.Color.prototype.toHSLString */
- toHSLString: function () {
- var c = this.asHSL();
- var ccc = MochiKit.Color.clampColorComponent;
- var rval = this._hslString;
- if (!rval) {
- var mid = (
- ccc(c.h, 360).toFixed(0)
- + "," + ccc(c.s, 100).toPrecision(4) + "%"
- + "," + ccc(c.l, 100).toPrecision(4) + "%"
- );
- var a = c.a;
- if (a >= 1) {
- a = 1;
- rval = "hsl(" + mid + ")";
- } else {
- if (a <= 0) {
- a = 0;
- }
- rval = "hsla(" + mid + "," + a + ")";
- }
- this._hslString = rval;
- }
- return rval;
- },
-
- /** @id MochiKit.Color.Color.prototype.toRGBString */
- toRGBString: function () {
- var c = this.rgb;
- var ccc = MochiKit.Color.clampColorComponent;
- var rval = this._rgbString;
- if (!rval) {
- var mid = (
- ccc(c.r, 255).toFixed(0)
- + "," + ccc(c.g, 255).toFixed(0)
- + "," + ccc(c.b, 255).toFixed(0)
- );
- if (c.a != 1) {
- rval = "rgba(" + mid + "," + c.a + ")";
- } else {
- rval = "rgb(" + mid + ")";
- }
- this._rgbString = rval;
- }
- return rval;
- },
-
- /** @id MochiKit.Color.Color.prototype.asRGB */
- asRGB: function () {
- return MochiKit.Base.clone(this.rgb);
- },
-
- /** @id MochiKit.Color.Color.prototype.toHexString */
- toHexString: function () {
- var m = MochiKit.Color;
- var c = this.rgb;
- var ccc = MochiKit.Color.clampColorComponent;
- var rval = this._hexString;
- if (!rval) {
- rval = ("#" +
- m.toColorPart(ccc(c.r, 255)) +
- m.toColorPart(ccc(c.g, 255)) +
- m.toColorPart(ccc(c.b, 255))
- );
- this._hexString = rval;
- }
- return rval;
- },
-
- /** @id MochiKit.Color.Color.prototype.asHSV */
- asHSV: function () {
- var hsv = this.hsv;
- var c = this.rgb;
- if (typeof(hsv) == 'undefined' || hsv === null) {
- hsv = MochiKit.Color.rgbToHSV(this.rgb);
- this.hsv = hsv;
- }
- return MochiKit.Base.clone(hsv);
- },
-
- /** @id MochiKit.Color.Color.prototype.asHSL */
- asHSL: function () {
- var hsl = this.hsl;
- var c = this.rgb;
- if (typeof(hsl) == 'undefined' || hsl === null) {
- hsl = MochiKit.Color.rgbToHSL(this.rgb);
- this.hsl = hsl;
- }
- return MochiKit.Base.clone(hsl);
- },
-
- /** @id MochiKit.Color.Color.prototype.toString */
- toString: function () {
- return this.toRGBString();
- },
-
- /** @id MochiKit.Color.Color.prototype.repr */
- repr: function () {
- var c = this.rgb;
- var col = [c.r, c.g, c.b, c.a];
- return this.__class__.NAME + "(" + col.join(", ") + ")";
- }
-
-};
-
-// Constructor methods
-
-MochiKit.Base.update(MochiKit.Color.Color, {
- /** @id MochiKit.Color.Color.fromRGB */
- fromRGB: function (red, green, blue, alpha) {
- // designated initializer
- var Color = MochiKit.Color.Color;
- if (arguments.length == 1) {
- var rgb = red;
- red = rgb.r;
- green = rgb.g;
- blue = rgb.b;
- if (typeof(rgb.a) == 'undefined') {
- alpha = undefined;
- } else {
- alpha = rgb.a;
- }
- }
- return new Color(red, green, blue, alpha);
- },
-
- /** @id MochiKit.Color.Color.fromHSL */
- fromHSL: function (hue, saturation, lightness, alpha) {
- var m = MochiKit.Color;
- return m.Color.fromRGB(m.hslToRGB.apply(m, arguments));
- },
-
- /** @id MochiKit.Color.Color.fromHSV */
- fromHSV: function (hue, saturation, value, alpha) {
- var m = MochiKit.Color;
- return m.Color.fromRGB(m.hsvToRGB.apply(m, arguments));
- },
-
- /** @id MochiKit.Color.Color.fromName */
- fromName: function (name) {
- var Color = MochiKit.Color.Color;
- // Opera 9 seems to "quote" named colors(?!)
- if (name.charAt(0) == '"') {
- name = name.substr(1, name.length - 2);
- }
- var htmlColor = Color._namedColors[name.toLowerCase()];
- if (typeof(htmlColor) == 'string') {
- return Color.fromHexString(htmlColor);
- } else if (name == "transparent") {
- return Color.transparentColor();
- }
- return null;
- },
-
- /** @id MochiKit.Color.Color.fromString */
- fromString: function (colorString) {
- var self = MochiKit.Color.Color;
- var three = colorString.substr(0, 3);
- if (three == "rgb") {
- return self.fromRGBString(colorString);
- } else if (three == "hsl") {
- return self.fromHSLString(colorString);
- } else if (colorString.charAt(0) == "#") {
- return self.fromHexString(colorString);
- }
- return self.fromName(colorString);
- },
-
-
- /** @id MochiKit.Color.Color.fromHexString */
- fromHexString: function (hexCode) {
- if (hexCode.charAt(0) == '#') {
- hexCode = hexCode.substring(1);
- }
- var components = [];
- var i, hex;
- if (hexCode.length == 3) {
- for (i = 0; i < 3; i++) {
- hex = hexCode.substr(i, 1);
- components.push(parseInt(hex + hex, 16) / 255.0);
- }
- } else {
- for (i = 0; i < 6; i += 2) {
- hex = hexCode.substr(i, 2);
- components.push(parseInt(hex, 16) / 255.0);
- }
- }
- var Color = MochiKit.Color.Color;
- return Color.fromRGB.apply(Color, components);
- },
-
-
- _fromColorString: function (pre, method, scales, colorCode) {
- // parses either HSL or RGB
- if (colorCode.indexOf(pre) === 0) {
- colorCode = colorCode.substring(colorCode.indexOf("(", 3) + 1, colorCode.length - 1);
- }
- var colorChunks = colorCode.split(/\s*,\s*/);
- var colorFloats = [];
- for (var i = 0; i < colorChunks.length; i++) {
- var c = colorChunks[i];
- var val;
- var three = c.substring(c.length - 3);
- if (c.charAt(c.length - 1) == '%') {
- val = 0.01 * parseFloat(c.substring(0, c.length - 1));
- } else if (three == "deg") {
- val = parseFloat(c) / 360.0;
- } else if (three == "rad") {
- val = parseFloat(c) / (Math.PI * 2);
- } else {
- val = scales[i] * parseFloat(c);
- }
- colorFloats.push(val);
- }
- return this[method].apply(this, colorFloats);
- },
-
- /** @id MochiKit.Color.Color.fromComputedStyle */
- fromComputedStyle: function (elem, style) {
- var d = MochiKit.DOM;
- var cls = MochiKit.Color.Color;
- for (elem = d.getElement(elem); elem; elem = elem.parentNode) {
- var actualColor = MochiKit.Style.computedStyle.apply(d, arguments);
- if (!actualColor) {
- continue;
- }
- var color = cls.fromString(actualColor);
- if (!color) {
- break;
- }
- if (color.asRGB().a > 0) {
- return color;
- }
- }
- return null;
- },
-
- /** @id MochiKit.Color.Color.fromBackground */
- fromBackground: function (elem) {
- var cls = MochiKit.Color.Color;
- return cls.fromComputedStyle(
- elem, "backgroundColor", "background-color") || cls.whiteColor();
- },
-
- /** @id MochiKit.Color.Color.fromText */
- fromText: function (elem) {
- var cls = MochiKit.Color.Color;
- return cls.fromComputedStyle(
- elem, "color", "color") || cls.blackColor();
- },
-
- /** @id MochiKit.Color.Color.namedColors */
- namedColors: function () {
- return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
- }
-});
-
-
-// Module level functions
-
-MochiKit.Base.update(MochiKit.Color, {
- /** @id MochiKit.Color.clampColorComponent */
- clampColorComponent: function (v, scale) {
- v *= scale;
- if (v < 0) {
- return 0;
- } else if (v > scale) {
- return scale;
- } else {
- return v;
- }
- },
-
- _hslValue: function (n1, n2, hue) {
- if (hue > 6.0) {
- hue -= 6.0;
- } else if (hue < 0.0) {
- hue += 6.0;
- }
- var val;
- if (hue < 1.0) {
- val = n1 + (n2 - n1) * hue;
- } else if (hue < 3.0) {
- val = n2;
- } else if (hue < 4.0) {
- val = n1 + (n2 - n1) * (4.0 - hue);
- } else {
- val = n1;
- }
- return val;
- },
-
- /** @id MochiKit.Color.hsvToRGB */
- hsvToRGB: function (hue, saturation, value, alpha) {
- if (arguments.length == 1) {
- var hsv = hue;
- hue = hsv.h;
- saturation = hsv.s;
- value = hsv.v;
- alpha = hsv.a;
- }
- var red;
- var green;
- var blue;
- if (saturation === 0) {
- red = 0;
- green = 0;
- blue = 0;
- } else {
- var i = Math.floor(hue * 6);
- var f = (hue * 6) - i;
- var p = value * (1 - saturation);
- var q = value * (1 - (saturation * f));
- var t = value * (1 - (saturation * (1 - f)));
- switch (i) {
- case 1: red = q; green = value; blue = p; break;
- case 2: red = p; green = value; blue = t; break;
- case 3: red = p; green = q; blue = value; break;
- case 4: red = t; green = p; blue = value; break;
- case 5: red = value; green = p; blue = q; break;
- case 6: // fall through
- case 0: red = value; green = t; blue = p; break;
- }
- }
- return {
- r: red,
- g: green,
- b: blue,
- a: alpha
- };
- },
-
- /** @id MochiKit.Color.hslToRGB */
- hslToRGB: function (hue, saturation, lightness, alpha) {
- if (arguments.length == 1) {
- var hsl = hue;
- hue = hsl.h;
- saturation = hsl.s;
- lightness = hsl.l;
- alpha = hsl.a;
- }
- var red;
- var green;
- var blue;
- if (saturation === 0) {
- red = lightness;
- green = lightness;
- blue = lightness;
- } else {
- var m2;
- if (lightness <= 0.5) {
- m2 = lightness * (1.0 + saturation);
- } else {
- m2 = lightness + saturation - (lightness * saturation);
- }
- var m1 = (2.0 * lightness) - m2;
- var f = MochiKit.Color._hslValue;
- var h6 = hue * 6.0;
- red = f(m1, m2, h6 + 2);
- green = f(m1, m2, h6);
- blue = f(m1, m2, h6 - 2);
- }
- return {
- r: red,
- g: green,
- b: blue,
- a: alpha
- };
- },
-
- /** @id MochiKit.Color.rgbToHSV */
- rgbToHSV: function (red, green, blue, alpha) {
- if (arguments.length == 1) {
- var rgb = red;
- red = rgb.r;
- green = rgb.g;
- blue = rgb.b;
- alpha = rgb.a;
- }
- var max = Math.max(Math.max(red, green), blue);
- var min = Math.min(Math.min(red, green), blue);
- var hue;
- var saturation;
- var value = max;
- if (min == max) {
- hue = 0;
- saturation = 0;
- } else {
- var delta = (max - min);
- saturation = delta / max;
-
- if (red == max) {
- hue = (green - blue) / delta;
- } else if (green == max) {
- hue = 2 + ((blue - red) / delta);
- } else {
- hue = 4 + ((red - green) / delta);
- }
- hue /= 6;
- if (hue < 0) {
- hue += 1;
- }
- if (hue > 1) {
- hue -= 1;
- }
- }
- return {
- h: hue,
- s: saturation,
- v: value,
- a: alpha
- };
- },
-
- /** @id MochiKit.Color.rgbToHSL */
- rgbToHSL: function (red, green, blue, alpha) {
- if (arguments.length == 1) {
- var rgb = red;
- red = rgb.r;
- green = rgb.g;
- blue = rgb.b;
- alpha = rgb.a;
- }
- var max = Math.max(red, Math.max(green, blue));
- var min = Math.min(red, Math.min(green, blue));
- var hue;
- var saturation;
- var lightness = (max + min) / 2.0;
- var delta = max - min;
- if (delta === 0) {
- hue = 0;
- saturation = 0;
- } else {
- if (lightness <= 0.5) {
- saturation = delta / (max + min);
- } else {
- saturation = delta / (2 - max - min);
- }
- if (red == max) {
- hue = (green - blue) / delta;
- } else if (green == max) {
- hue = 2 + ((blue - red) / delta);
- } else {
- hue = 4 + ((red - green) / delta);
- }
- hue /= 6;
- if (hue < 0) {
- hue += 1;
- }
- if (hue > 1) {
- hue -= 1;
- }
-
- }
- return {
- h: hue,
- s: saturation,
- l: lightness,
- a: alpha
- };
- },
-
- /** @id MochiKit.Color.toColorPart */
- toColorPart: function (num) {
- num = Math.round(num);
- var digits = num.toString(16);
- if (num < 16) {
- return '0' + digits;
- }
- return digits;
- },
-
- __new__: function () {
- var m = MochiKit.Base;
- /** @id MochiKit.Color.fromRGBString */
- this.Color.fromRGBString = m.bind(
- this.Color._fromColorString, this.Color, "rgb", "fromRGB",
- [1.0/255.0, 1.0/255.0, 1.0/255.0, 1]
- );
- /** @id MochiKit.Color.fromHSLString */
- this.Color.fromHSLString = m.bind(
- this.Color._fromColorString, this.Color, "hsl", "fromHSL",
- [1.0/360.0, 0.01, 0.01, 1]
- );
-
- var third = 1.0 / 3.0;
- /** @id MochiKit.Color.colors */
- var colors = {
- // NSColor colors plus transparent
- /** @id MochiKit.Color.blackColor */
- black: [0, 0, 0],
- /** @id MochiKit.Color.blueColor */
- blue: [0, 0, 1],
- /** @id MochiKit.Color.brownColor */
- brown: [0.6, 0.4, 0.2],
- /** @id MochiKit.Color.cyanColor */
- cyan: [0, 1, 1],
- /** @id MochiKit.Color.darkGrayColor */
- darkGray: [third, third, third],
- /** @id MochiKit.Color.grayColor */
- gray: [0.5, 0.5, 0.5],
- /** @id MochiKit.Color.greenColor */
- green: [0, 1, 0],
- /** @id MochiKit.Color.lightGrayColor */
- lightGray: [2 * third, 2 * third, 2 * third],
- /** @id MochiKit.Color.magentaColor */
- magenta: [1, 0, 1],
- /** @id MochiKit.Color.orangeColor */
- orange: [1, 0.5, 0],
- /** @id MochiKit.Color.purpleColor */
- purple: [0.5, 0, 0.5],
- /** @id MochiKit.Color.redColor */
- red: [1, 0, 0],
- /** @id MochiKit.Color.transparentColor */
- transparent: [0, 0, 0, 0],
- /** @id MochiKit.Color.whiteColor */
- white: [1, 1, 1],
- /** @id MochiKit.Color.yellowColor */
- yellow: [1, 1, 0]
- };
-
- var makeColor = function (name, r, g, b, a) {
- var rval = this.fromRGB(r, g, b, a);
- this[name] = function () { return rval; };
- return rval;
- };
-
- for (var k in colors) {
- var name = k + "Color";
- var bindArgs = m.concat(
- [makeColor, this.Color, name],
- colors[k]
- );
- this.Color[name] = m.bind.apply(null, bindArgs);
- }
-
- var isColor = function () {
- for (var i = 0; i < arguments.length; i++) {
- if (!(arguments[i] instanceof Color)) {
- return false;
- }
- }
- return true;
- };
-
- var compareColor = function (a, b) {
- return a.compareRGB(b);
- };
-
- m.nameFunctions(this);
-
- m.registerComparator(this.Color.NAME, isColor, compareColor);
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- }
-});
-
-MochiKit.Color.EXPORT = [
- "Color"
-];
-
-MochiKit.Color.EXPORT_OK = [
- "clampColorComponent",
- "rgbToHSL",
- "hslToRGB",
- "rgbToHSV",
- "hsvToRGB",
- "toColorPart"
-];
-
-MochiKit.Color.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.Color);
-
-// Full table of css3 X11 colors <http://www.w3.org/TR/css3-color/#X11COLORS>
-
-MochiKit.Color.Color._namedColors = {
- aliceblue: "#f0f8ff",
- antiquewhite: "#faebd7",
- aqua: "#00ffff",
- aquamarine: "#7fffd4",
- azure: "#f0ffff",
- beige: "#f5f5dc",
- bisque: "#ffe4c4",
- black: "#000000",
- blanchedalmond: "#ffebcd",
- blue: "#0000ff",
- blueviolet: "#8a2be2",
- brown: "#a52a2a",
- burlywood: "#deb887",
- cadetblue: "#5f9ea0",
- chartreuse: "#7fff00",
- chocolate: "#d2691e",
- coral: "#ff7f50",
- cornflowerblue: "#6495ed",
- cornsilk: "#fff8dc",
- crimson: "#dc143c",
- cyan: "#00ffff",
- darkblue: "#00008b",
- darkcyan: "#008b8b",
- darkgoldenrod: "#b8860b",
- darkgray: "#a9a9a9",
- darkgreen: "#006400",
- darkgrey: "#a9a9a9",
- darkkhaki: "#bdb76b",
- darkmagenta: "#8b008b",
- darkolivegreen: "#556b2f",
- darkorange: "#ff8c00",
- darkorchid: "#9932cc",
- darkred: "#8b0000",
- darksalmon: "#e9967a",
- darkseagreen: "#8fbc8f",
- darkslateblue: "#483d8b",
- darkslategray: "#2f4f4f",
- darkslategrey: "#2f4f4f",
- darkturquoise: "#00ced1",
- darkviolet: "#9400d3",
- deeppink: "#ff1493",
- deepskyblue: "#00bfff",
- dimgray: "#696969",
- dimgrey: "#696969",
- dodgerblue: "#1e90ff",
- firebrick: "#b22222",
- floralwhite: "#fffaf0",
- forestgreen: "#228b22",
- fuchsia: "#ff00ff",
- gainsboro: "#dcdcdc",
- ghostwhite: "#f8f8ff",
- gold: "#ffd700",
- goldenrod: "#daa520",
- gray: "#808080",
- green: "#008000",
- greenyellow: "#adff2f",
- grey: "#808080",
- honeydew: "#f0fff0",
- hotpink: "#ff69b4",
- indianred: "#cd5c5c",
- indigo: "#4b0082",
- ivory: "#fffff0",
- khaki: "#f0e68c",
- lavender: "#e6e6fa",
- lavenderblush: "#fff0f5",
- lawngreen: "#7cfc00",
- lemonchiffon: "#fffacd",
- lightblue: "#add8e6",
- lightcoral: "#f08080",
- lightcyan: "#e0ffff",
- lightgoldenrodyellow: "#fafad2",
- lightgray: "#d3d3d3",
- lightgreen: "#90ee90",
- lightgrey: "#d3d3d3",
- lightpink: "#ffb6c1",
- lightsalmon: "#ffa07a",
- lightseagreen: "#20b2aa",
- lightskyblue: "#87cefa",
- lightslategray: "#778899",
- lightslategrey: "#778899",
- lightsteelblue: "#b0c4de",
- lightyellow: "#ffffe0",
- lime: "#00ff00",
- limegreen: "#32cd32",
- linen: "#faf0e6",
- magenta: "#ff00ff",
- maroon: "#800000",
- mediumaquamarine: "#66cdaa",
- mediumblue: "#0000cd",
- mediumorchid: "#ba55d3",
- mediumpurple: "#9370db",
- mediumseagreen: "#3cb371",
- mediumslateblue: "#7b68ee",
- mediumspringgreen: "#00fa9a",
- mediumturquoise: "#48d1cc",
- mediumvioletred: "#c71585",
- midnightblue: "#191970",
- mintcream: "#f5fffa",
- mistyrose: "#ffe4e1",
- moccasin: "#ffe4b5",
- navajowhite: "#ffdead",
- navy: "#000080",
- oldlace: "#fdf5e6",
- olive: "#808000",
- olivedrab: "#6b8e23",
- orange: "#ffa500",
- orangered: "#ff4500",
- orchid: "#da70d6",
- palegoldenrod: "#eee8aa",
- palegreen: "#98fb98",
- paleturquoise: "#afeeee",
- palevioletred: "#db7093",
- papayawhip: "#ffefd5",
- peachpuff: "#ffdab9",
- peru: "#cd853f",
- pink: "#ffc0cb",
- plum: "#dda0dd",
- powderblue: "#b0e0e6",
- purple: "#800080",
- red: "#ff0000",
- rosybrown: "#bc8f8f",
- royalblue: "#4169e1",
- saddlebrown: "#8b4513",
- salmon: "#fa8072",
- sandybrown: "#f4a460",
- seagreen: "#2e8b57",
- seashell: "#fff5ee",
- sienna: "#a0522d",
- silver: "#c0c0c0",
- skyblue: "#87ceeb",
- slateblue: "#6a5acd",
- slategray: "#708090",
- slategrey: "#708090",
- snow: "#fffafa",
- springgreen: "#00ff7f",
- steelblue: "#4682b4",
- tan: "#d2b48c",
- teal: "#008080",
- thistle: "#d8bfd8",
- tomato: "#ff6347",
- turquoise: "#40e0d0",
- violet: "#ee82ee",
- wheat: "#f5deb3",
- white: "#ffffff",
- whitesmoke: "#f5f5f5",
- yellow: "#ffff00",
- yellowgreen: "#9acd32"
-};
diff --git a/mochitest/MochiKit/Controls.js b/mochitest/MochiKit/Controls.js
deleted file mode 100644
index 539b09d..0000000
--- a/mochitest/MochiKit/Controls.js
+++ /dev/null
@@ -1,1388 +0,0 @@
-/***
-Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
- (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)
- (c) 2005 Jon Tirsen (http://www.tirsen.com)
-Contributors:
- Richard Livsey
- Rahul Bhargava
- Rob Wills
- Mochi-ized By Thomas Herve (_firstname_ at nimail.org)
-
-See scriptaculous.js for full license.
-
-Autocompleter.Base handles all the autocompletion functionality
-that's independent of the data source for autocompletion. This
-includes drawing the autocompletion menu, observing keyboard
-and mouse events, and similar.
-
-Specific autocompleters need to provide, at the very least,
-a getUpdatedChoices function that will be invoked every time
-the text inside the monitored textbox changes. This method
-should get the text for which to provide autocompletion by
-invoking this.getToken(), NOT by directly accessing
-this.element.value. This is to allow incremental tokenized
-autocompletion. Specific auto-completion logic (AJAX, etc)
-belongs in getUpdatedChoices.
-
-Tokenized incremental autocompletion is enabled automatically
-when an autocompleter is instantiated with the 'tokens' option
-in the options parameter, e.g.:
-new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });
-will incrementally autocomplete with a comma as the token.
-Additionally, ',' in the above example can be replaced with
-a token array, e.g. { tokens: [',', '\n'] } which
-enables autocompletion on multiple tokens. This is most
-useful when one of the tokens is \n (a newline), as it
-allows smart autocompletion after linebreaks.
-
-***/
-
-MochiKit.Base.update(MochiKit.Base, {
- ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
-
-/** @id MochiKit.Base.stripScripts */
- stripScripts: function (str) {
- return str.replace(new RegExp(MochiKit.Base.ScriptFragment, 'img'), '');
- },
-
-/** @id MochiKit.Base.stripTags */
- stripTags: function(str) {
- return str.replace(/<\/?[^>]+>/gi, '');
- },
-
-/** @id MochiKit.Base.extractScripts */
- extractScripts: function (str) {
- var matchAll = new RegExp(MochiKit.Base.ScriptFragment, 'img');
- var matchOne = new RegExp(MochiKit.Base.ScriptFragment, 'im');
- return MochiKit.Base.map(function (scriptTag) {
- return (scriptTag.match(matchOne) || ['', ''])[1];
- }, str.match(matchAll) || []);
- },
-
-/** @id MochiKit.Base.evalScripts */
- evalScripts: function (str) {
- return MochiKit.Base.map(function (scr) {
- eval(scr);
- }, MochiKit.Base.extractScripts(str));
- }
-});
-
-MochiKit.Form = {
-
-/** @id MochiKit.Form.serialize */
- serialize: function (form) {
- var elements = MochiKit.Form.getElements(form);
- var queryComponents = [];
-
- for (var i = 0; i < elements.length; i++) {
- var queryComponent = MochiKit.Form.serializeElement(elements[i]);
- if (queryComponent) {
- queryComponents.push(queryComponent);
- }
- }
-
- return queryComponents.join('&');
- },
-
-/** @id MochiKit.Form.getElements */
- getElements: function (form) {
- form = MochiKit.DOM.getElement(form);
- var elements = [];
-
- for (tagName in MochiKit.Form.Serializers) {
- var tagElements = form.getElementsByTagName(tagName);
- for (var j = 0; j < tagElements.length; j++) {
- elements.push(tagElements[j]);
- }
- }
- return elements;
- },
-
-/** @id MochiKit.Form.serializeElement */
- serializeElement: function (element) {
- element = MochiKit.DOM.getElement(element);
- var method = element.tagName.toLowerCase();
- var parameter = MochiKit.Form.Serializers[method](element);
-
- if (parameter) {
- var key = encodeURIComponent(parameter[0]);
- if (key.length === 0) {
- return;
- }
-
- if (!(parameter[1] instanceof Array)) {
- parameter[1] = [parameter[1]];
- }
-
- return parameter[1].map(function (value) {
- return key + '=' + encodeURIComponent(value);
- }).join('&');
- }
- }
-};
-
-MochiKit.Form.Serializers = {
-
-/** @id MochiKit.Form.Serializers.input */
- input: function (element) {
- switch (element.type.toLowerCase()) {
- case 'submit':
- case 'hidden':
- case 'password':
- case 'text':
- return MochiKit.Form.Serializers.textarea(element);
- case 'checkbox':
- case 'radio':
- return MochiKit.Form.Serializers.inputSelector(element);
- }
- return false;
- },
-
-/** @id MochiKit.Form.Serializers.inputSelector */
- inputSelector: function (element) {
- if (element.checked) {
- return [element.name, element.value];
- }
- },
-
-/** @id MochiKit.Form.Serializers.textarea */
- textarea: function (element) {
- return [element.name, element.value];
- },
-
-/** @id MochiKit.Form.Serializers.select */
- select: function (element) {
- return MochiKit.Form.Serializers[element.type == 'select-one' ?
- 'selectOne' : 'selectMany'](element);
- },
-
-/** @id MochiKit.Form.Serializers.selectOne */
- selectOne: function (element) {
- var value = '', opt, index = element.selectedIndex;
- if (index >= 0) {
- opt = element.options[index];
- value = opt.value;
- if (!value && !('value' in opt)) {
- value = opt.text;
- }
- }
- return [element.name, value];
- },
-
-/** @id MochiKit.Form.Serializers.selectMany */
- selectMany: function (element) {
- var value = [];
- for (var i = 0; i < element.length; i++) {
- var opt = element.options[i];
- if (opt.selected) {
- var optValue = opt.value;
- if (!optValue && !('value' in opt)) {
- optValue = opt.text;
- }
- value.push(optValue);
- }
- }
- return [element.name, value];
- }
-};
-
-/** @id Ajax */
-var Ajax = {
- activeRequestCount: 0
-};
-
-Ajax.Responders = {
- responders: [],
-
-/** @id Ajax.Responders.register */
- register: function (responderToAdd) {
- if (MochiKit.Base.find(this.responders, responderToAdd) == -1) {
- this.responders.push(responderToAdd);
- }
- },
-
-/** @id Ajax.Responders.unregister */
- unregister: function (responderToRemove) {
- this.responders = this.responders.without(responderToRemove);
- },
-
-/** @id Ajax.Responders.dispatch */
- dispatch: function (callback, request, transport, json) {
- MochiKit.Iter.forEach(this.responders, function (responder) {
- if (responder[callback] &&
- typeof(responder[callback]) == 'function') {
- try {
- responder[callback].apply(responder, [request, transport, json]);
- } catch (e) {}
- }
- });
- }
-};
-
-Ajax.Responders.register({
-
-/** @id Ajax.Responders.onCreate */
- onCreate: function () {
- Ajax.activeRequestCount++;
- },
-
-/** @id Ajax.Responders.onComplete */
- onComplete: function () {
- Ajax.activeRequestCount--;
- }
-});
-
-/** @id Ajax.Base */
-Ajax.Base = function () {};
-
-Ajax.Base.prototype = {
-
-/** @id Ajax.Base.prototype.setOptions */
- setOptions: function (options) {
- this.options = {
- method: 'post',
- asynchronous: true,
- parameters: ''
- }
- MochiKit.Base.update(this.options, options || {});
- },
-
-/** @id Ajax.Base.prototype.responseIsSuccess */
- responseIsSuccess: function () {
- return this.transport.status == undefined
- || this.transport.status === 0
- || (this.transport.status >= 200 && this.transport.status < 300);
- },
-
-/** @id Ajax.Base.prototype.responseIsFailure */
- responseIsFailure: function () {
- return !this.responseIsSuccess();
- }
-};
-
-/** @id Ajax.Request */
-Ajax.Request = function (url, options) {
- this.__init__(url, options);
-};
-
-/** @id Ajax.Events */
-Ajax.Request.Events = ['Uninitialized', 'Loading', 'Loaded',
- 'Interactive', 'Complete'];
-
-MochiKit.Base.update(Ajax.Request.prototype, Ajax.Base.prototype);
-
-MochiKit.Base.update(Ajax.Request.prototype, {
- __init__: function (url, options) {
- this.transport = MochiKit.Async.getXMLHttpRequest();
- this.setOptions(options);
- this.request(url);
- },
-
-/** @id Ajax.Request.prototype.request */
- request: function (url) {
- var parameters = this.options.parameters || '';
- if (parameters.length > 0){
- parameters += '&_=';
- }
-
- try {
- this.url = url;
- if (this.options.method == 'get' && parameters.length > 0) {
- this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
- }
- Ajax.Responders.dispatch('onCreate', this, this.transport);
-
- this.transport.open(this.options.method, this.url,
- this.options.asynchronous);
-
- if (this.options.asynchronous) {
- this.transport.onreadystatechange = MochiKit.Base.bind(this.onStateChange, this);
- setTimeout(MochiKit.Base.bind(function () {
- this.respondToReadyState(1);
- }, this), 10);
- }
-
- this.setRequestHeaders();
-
- var body = this.options.postBody ? this.options.postBody : parameters;
- this.transport.send(this.options.method == 'post' ? body : null);
-
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
-/** @id Ajax.Request.prototype.setRequestHeaders */
- setRequestHeaders: function () {
- var requestHeaders = ['X-Requested-With', 'XMLHttpRequest'];
-
- if (this.options.method == 'post') {
- requestHeaders.push('Content-type',
- 'application/x-www-form-urlencoded');
-
- /* Force 'Connection: close' for Mozilla browsers to work around
- * a bug where XMLHttpRequest sends an incorrect Content-length
- * header. See Mozilla Bugzilla #246651.
- */
- if (this.transport.overrideMimeType) {
- requestHeaders.push('Connection', 'close');
- }
- }
-
- if (this.options.requestHeaders) {
- requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
- }
-
- for (var i = 0; i < requestHeaders.length; i += 2) {
- this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
- }
- },
-
-/** @id Ajax.Request.prototype.onStateChange */
- onStateChange: function () {
- var readyState = this.transport.readyState;
- if (readyState != 1) {
- this.respondToReadyState(this.transport.readyState);
- }
- },
-
-/** @id Ajax.Request.prototype.header */
- header: function (name) {
- try {
- return this.transport.getResponseHeader(name);
- } catch (e) {}
- },
-
-/** @id Ajax.Request.prototype.evalJSON */
- evalJSON: function () {
- try {
- return eval(this.header('X-JSON'));
- } catch (e) {}
- },
-
-/** @id Ajax.Request.prototype.evalResponse */
- evalResponse: function () {
- try {
- return eval(this.transport.responseText);
- } catch (e) {
- this.dispatchException(e);
- }
- },
-
-/** @id Ajax.Request.prototype.respondToReadyState */
- respondToReadyState: function (readyState) {
- var event = Ajax.Request.Events[readyState];
- var transport = this.transport, json = this.evalJSON();
-
- if (event == 'Complete') {
- try {
- (this.options['on' + this.transport.status]
- || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
- || MochiKit.Base.noop)(transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- if ((this.header('Content-type') || '').match(/^text\/javascript/i)) {
- this.evalResponse();
- }
- }
-
- try {
- (this.options['on' + event] || MochiKit.Base.noop)(transport, json);
- Ajax.Responders.dispatch('on' + event, this, transport, json);
- } catch (e) {
- this.dispatchException(e);
- }
-
- /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
- if (event == 'Complete') {
- this.transport.onreadystatechange = MochiKit.Base.noop;
- }
- },
-
-/** @id Ajax.Request.prototype.dispatchException */
- dispatchException: function (exception) {
- (this.options.onException || MochiKit.Base.noop)(this, exception);
- Ajax.Responders.dispatch('onException', this, exception);
- }
-});
-
-/** @id Ajax.Updater */
-Ajax.Updater = function (container, url, options) {
- this.__init__(container, url, options);
-};
-
-MochiKit.Base.update(Ajax.Updater.prototype, Ajax.Request.prototype);
-
-MochiKit.Base.update(Ajax.Updater.prototype, {
- __init__: function (container, url, options) {
- this.containers = {
- success: container.success ? MochiKit.DOM.getElement(container.success) : MochiKit.DOM.getElement(container),
- failure: container.failure ? MochiKit.DOM.getElement(container.failure) :
- (container.success ? null : MochiKit.DOM.getElement(container))
- }
- this.transport = MochiKit.Async.getXMLHttpRequest();
- this.setOptions(options);
-
- var onComplete = this.options.onComplete || MochiKit.Base.noop;
- this.options.onComplete = MochiKit.Base.bind(function (transport, object) {
- this.updateContent();
- onComplete(transport, object);
- }, this);
-
- this.request(url);
- },
-
-/** @id Ajax.Updater.prototype.updateContent */
- updateContent: function () {
- var receiver = this.responseIsSuccess() ?
- this.containers.success : this.containers.failure;
- var response = this.transport.responseText;
-
- if (!this.options.evalScripts) {
- response = MochiKit.Base.stripScripts(response);
- }
-
- if (receiver) {
- if (this.options.insertion) {
- new this.options.insertion(receiver, response);
- } else {
- MochiKit.DOM.getElement(receiver).innerHTML =
- MochiKit.Base.stripScripts(response);
- setTimeout(function () {
- MochiKit.Base.evalScripts(response);
- }, 10);
- }
- }
-
- if (this.responseIsSuccess()) {
- if (this.onComplete) {
- setTimeout(MochiKit.Base.bind(this.onComplete, this), 10);
- }
- }
- }
-});
-
-/** @id Field */
-var Field = {
-
-/** @id clear */
- clear: function () {
- for (var i = 0; i < arguments.length; i++) {
- MochiKit.DOM.getElement(arguments[i]).value = '';
- }
- },
-
-/** @id focus */
- focus: function (element) {
- MochiKit.DOM.getElement(element).focus();
- },
-
-/** @id present */
- present: function () {
- for (var i = 0; i < arguments.length; i++) {
- if (MochiKit.DOM.getElement(arguments[i]).value == '') {
- return false;
- }
- }
- return true;
- },
-
-/** @id select */
- select: function (element) {
- MochiKit.DOM.getElement(element).select();
- },
-
-/** @id activate */
- activate: function (element) {
- element = MochiKit.DOM.getElement(element);
- element.focus();
- if (element.select) {
- element.select();
- }
- },
-
-/** @id scrollFreeActivate */
- scrollFreeActivate: function (field) {
- setTimeout(function () {
- Field.activate(field);
- }, 1);
- }
-};
-
-
-/** @id Autocompleter */
-var Autocompleter = {};
-
-/** @id Autocompleter.Base */
-Autocompleter.Base = function () {};
-
-Autocompleter.Base.prototype = {
-
-/** @id Autocompleter.Base.prototype.baseInitialize */
- baseInitialize: function (element, update, options) {
- this.element = MochiKit.DOM.getElement(element);
- this.update = MochiKit.DOM.getElement(update);
- this.hasFocus = false;
- this.changed = false;
- this.active = false;
- this.index = 0;
- this.entryCount = 0;
-
- if (this.setOptions) {
- this.setOptions(options);
- }
- else {
- this.options = options || {};
- }
-
- this.options.paramName = this.options.paramName || this.element.name;
- this.options.tokens = this.options.tokens || [];
- this.options.frequency = this.options.frequency || 0.4;
- this.options.minChars = this.options.minChars || 1;
- this.options.onShow = this.options.onShow || function (element, update) {
- if (!update.style.position || update.style.position == 'absolute') {
- update.style.position = 'absolute';
- MochiKit.Position.clone(element, update, {
- setHeight: false,
- offsetTop: element.offsetHeight
- });
- }
- MochiKit.Visual.appear(update, {duration:0.15});
- };
- this.options.onHide = this.options.onHide || function (element, update) {
- MochiKit.Visual.fade(update, {duration: 0.15});
- };
-
- if (typeof(this.options.tokens) == 'string') {
- this.options.tokens = new Array(this.options.tokens);
- }
-
- this.observer = null;
-
- this.element.setAttribute('autocomplete', 'off');
-
- MochiKit.Style.hideElement(this.update);
-
- MochiKit.Signal.connect(this.element, 'onblur', this, this.onBlur);
- MochiKit.Signal.connect(this.element, 'onkeypress', this, this.onKeyPress, this);
- },
-
-/** @id Autocompleter.Base.prototype.show */
- show: function () {
- if (MochiKit.Style.getStyle(this.update, 'display') == 'none') {
- this.options.onShow(this.element, this.update);
- }
- if (!this.iefix && /MSIE/.test(navigator.userAgent &&
- (MochiKit.Style.getStyle(this.update, 'position') == 'absolute')) {
- new Insertion.After(this.update,
- '<iframe id="' + this.update.id + '_iefix" '+
- 'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
- 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
- this.iefix = MochiKit.DOM.getElement(this.update.id + '_iefix');
- }
- if (this.iefix) {
- setTimeout(MochiKit.Base.bind(this.fixIEOverlapping, this), 50);
- }
- },
-
-/** @id Autocompleter.Base.prototype.fixIEOverlapping */
- fixIEOverlapping: function () {
- MochiKit.Position.clone(this.update, this.iefix);
- this.iefix.style.zIndex = 1;
- this.update.style.zIndex = 2;
- MochiKit.Style.showElement(this.iefix);
- },
-
-/** @id Autocompleter.Base.prototype.hide */
- hide: function () {
- this.stopIndicator();
- if (MochiKit.Style.getStyle(this.update, 'display') != 'none') {
- this.options.onHide(this.element, this.update);
- }
- if (this.iefix) {
- MochiKit.Style.hideElement(this.iefix);
- }
- },
-
-/** @id Autocompleter.Base.prototype.startIndicator */
- startIndicator: function () {
- if (this.options.indicator) {
- MochiKit.Style.showElement(this.options.indicator);
- }
- },
-
-/** @id Autocompleter.Base.prototype.stopIndicator */
- stopIndicator: function () {
- if (this.options.indicator) {
- MochiKit.Style.hideElement(this.options.indicator);
- }
- },
-
-/** @id Autocompleter.Base.prototype.onKeyPress */
- onKeyPress: function (event) {
- if (this.active) {
- if (event.key().string == "KEY_TAB" || event.key().string == "KEY_RETURN") {
- this.selectEntry();
- MochiKit.Event.stop(event);
- } else if (event.key().string == "KEY_ESCAPE") {
- this.hide();
- this.active = false;
- MochiKit.Event.stop(event);
- return;
- } else if (event.key().string == "KEY_LEFT" || event.key().string == "KEY_RIGHT") {
- return;
- } else if (event.key().string == "KEY_UP") {
- this.markPrevious();
- this.render();
- if (/AppleWebKit'/.test(navigator.appVersion)) {
- event.stop();
- }
- return;
- } else if (event.key().string == "KEY_DOWN") {
- this.markNext();
- this.render();
- if (/AppleWebKit'/.test(navigator.appVersion)) {
- event.stop();
- }
- return;
- }
- } else {
- if (event.key().string == "KEY_TAB" || event.key().string == "KEY_RETURN") {
- return;
- }
- }
-
- this.changed = true;
- this.hasFocus = true;
-
- if (this.observer) {
- clearTimeout(this.observer);
- }
- this.observer = setTimeout(MochiKit.Base.bind(this.onObserverEvent, this),
- this.options.frequency*1000);
- },
-
-/** @id Autocompleter.Base.prototype.findElement */
- findElement: function (event, tagName) {
- var element = event.target;
- while (element.parentNode && (!element.tagName ||
- (element.tagName.toUpperCase() != tagName.toUpperCase()))) {
- element = element.parentNode;
- }
- return element;
- },
-
-/** @id Autocompleter.Base.prototype.hover */
- onHover: function (event) {
- var element = this.findElement(event, 'LI');
- if (this.index != element.autocompleteIndex) {
- this.index = element.autocompleteIndex;
- this.render();
- }
- event.stop();
- },
-
-/** @id Autocompleter.Base.prototype.onClick */
- onClick: function (event) {
- var element = this.findElement(event, 'LI');
- this.index = element.autocompleteIndex;
- this.selectEntry();
- this.hide();
- },
-
-/** @id Autocompleter.Base.prototype.onBlur */
- onBlur: function (event) {
- // needed to make click events working
- setTimeout(MochiKit.Base.bind(this.hide, this), 250);
- this.hasFocus = false;
- this.active = false;
- },
-
-/** @id Autocompleter.Base.prototype.render */
- render: function () {
- if (this.entryCount > 0) {
- for (var i = 0; i < this.entryCount; i++) {
- this.index == i ?
- MochiKit.DOM.addElementClass(this.getEntry(i), 'selected') :
- MochiKit.DOM.removeElementClass(this.getEntry(i), 'selected');
- }
- if (this.hasFocus) {
- this.show();
- this.active = true;
- }
- } else {
- this.active = false;
- this.hide();
- }
- },
-
-/** @id Autocompleter.Base.prototype.markPrevious */
- markPrevious: function () {
- if (this.index > 0) {
- this.index--
- } else {
- this.index = this.entryCount-1;
- }
- },
-
-/** @id Autocompleter.Base.prototype.markNext */
- markNext: function () {
- if (this.index < this.entryCount-1) {
- this.index++
- } else {
- this.index = 0;
- }
- },
-
-/** @id Autocompleter.Base.prototype.getEntry */
- getEntry: function (index) {
- return this.update.firstChild.childNodes[index];
- },
-
-/** @id Autocompleter.Base.prototype.getCurrentEntry */
- getCurrentEntry: function () {
- return this.getEntry(this.index);
- },
-
-/** @id Autocompleter.Base.prototype.selectEntry */
- selectEntry: function () {
- this.active = false;
- this.updateElement(this.getCurrentEntry());
- },
-
-/** @id Autocompleter.Base.prototype.collectTextNodesIgnoreClass */
- collectTextNodesIgnoreClass: function (element, className) {
- return MochiKit.Base.flattenArray(MochiKit.Base.map(function (node) {
- if (node.nodeType == 3) {
- return node.nodeValue;
- } else if (node.hasChildNodes() && !MochiKit.DOM.hasElementClass(node, className)) {
- return this.collectTextNodesIgnoreClass(node, className);
- }
- return '';
- }, MochiKit.DOM.getElement(element).childNodes)).join('');
- },
-
-/** @id Autocompleter.Base.prototype.updateElement */
- updateElement: function (selectedElement) {
- if (this.options.updateElement) {
- this.options.updateElement(selectedElement);
- return;
- }
- var value = '';
- if (this.options.select) {
- var nodes = document.getElementsByClassName(this.options.select, selectedElement) || [];
- if (nodes.length > 0) {
- value = MochiKit.DOM.scrapeText(nodes[0]);
- }
- } else {
- value = this.collectTextNodesIgnoreClass(selectedElement, 'informal');
- }
- var lastTokenPos = this.findLastToken();
- if (lastTokenPos != -1) {
- var newValue = this.element.value.substr(0, lastTokenPos + 1);
- var whitespace = this.element.value.substr(lastTokenPos + 1).match(/^\s+/);
- if (whitespace) {
- newValue += whitespace[0];
- }
- this.element.value = newValue + value;
- } else {
- this.element.value = value;
- }
- this.element.focus();
-
- if (this.options.afterUpdateElement) {
- this.options.afterUpdateElement(this.element, selectedElement);
- }
- },
-
-/** @id Autocompleter.Base.prototype.updateChoices */
- updateChoices: function (choices) {
- if (!this.changed && this.hasFocus) {
- this.update.innerHTML = choices;
- var d = MochiKit.DOM;
- d.removeEmptyTextNodes(this.update);
- d.removeEmptyTextNodes(this.update.firstChild);
-
- if (this.update.firstChild && this.update.firstChild.childNodes) {
- this.entryCount = this.update.firstChild.childNodes.length;
- for (var i = 0; i < this.entryCount; i++) {
- var entry = this.getEntry(i);
- entry.autocompleteIndex = i;
- this.addObservers(entry);
- }
- } else {
- this.entryCount = 0;
- }
-
- this.stopIndicator();
-
- this.index = 0;
- this.render();
- }
- },
-
-/** @id Autocompleter.Base.prototype.addObservers */
- addObservers: function (element) {
- MochiKit.Signal.connect(element, 'onmouseover', this, this.onHover);
- MochiKit.Signal.connect(element, 'onclick', this, this.onClick);
- },
-
-/** @id Autocompleter.Base.prototype.onObserverEvent */
- onObserverEvent: function () {
- this.changed = false;
- if (this.getToken().length >= this.options.minChars) {
- this.startIndicator();
- this.getUpdatedChoices();
- } else {
- this.active = false;
- this.hide();
- }
- },
-
-/** @id Autocompleter.Base.prototype.getToken */
- getToken: function () {
- var tokenPos = this.findLastToken();
- if (tokenPos != -1) {
- var ret = this.element.value.substr(tokenPos + 1).replace(/^\s+/,'').replace(/\s+$/,'');
- } else {
- var ret = this.element.value;
- }
- return /\n/.test(ret) ? '' : ret;
- },
-
-/** @id Autocompleter.Base.prototype.findLastToken */
- findLastToken: function () {
- var lastTokenPos = -1;
-
- for (var i = 0; i < this.options.tokens.length; i++) {
- var thisTokenPos = this.element.value.lastIndexOf(this.options.tokens[i]);
- if (thisTokenPos > lastTokenPos) {
- lastTokenPos = thisTokenPos;
- }
- }
- return lastTokenPos;
- }
-}
-
-/** @id Ajax.Autocompleter */
-Ajax.Autocompleter = function (element, update, url, options) {
- this.__init__(element, update, url, options);
-};
-
-MochiKit.Base.update(Ajax.Autocompleter.prototype, Autocompleter.Base.prototype);
-
-MochiKit.Base.update(Ajax.Autocompleter.prototype, {
- __init__: function (element, update, url, options) {
- this.baseInitialize(element, update, options);
- this.options.asynchronous = true;
- this.options.onComplete = MochiKit.Base.bind(this.onComplete, this);
- this.options.defaultParams = this.options.parameters || null;
- this.url = url;
- },
-
-/** @id Ajax.Autocompleter.prototype.getUpdatedChoices */
- getUpdatedChoices: function () {
- var entry = encodeURIComponent(this.options.paramName) + '=' +
- encodeURIComponent(this.getToken());
-
- this.options.parameters = this.options.callback ?
- this.options.callback(this.element, entry) : entry;
-
- if (this.options.defaultParams) {
- this.options.parameters += '&' + this.options.defaultParams;
- }
- new Ajax.Request(this.url, this.options);
- },
-
-/** @id Ajax.Autocompleter.prototype.onComplete */
- onComplete: function (request) {
- this.updateChoices(request.responseText);
- }
-});
-
-/***
-
-The local array autocompleter. Used when you'd prefer to
-inject an array of autocompletion options into the page, rather
-than sending out Ajax queries, which can be quite slow sometimes.
-
-The constructor takes four parameters. The first two are, as usual,
-the id of the monitored textbox, and id of the autocompletion menu.
-The third is the array you want to autocomplete from, and the fourth
-is the options block.
-
-Extra local autocompletion options:
-- choices - How many autocompletion choices to offer
-
-- partialSearch - If false, the autocompleter will match entered
- text only at the beginning of strings in the
- autocomplete array. Defaults to true, which will
- match text at the beginning of any *word* in the
- strings in the autocomplete array. If you want to
- search anywhere in the string, additionally set
- the option fullSearch to true (default: off).
-
-- fullSsearch - Search anywhere in autocomplete array strings.
-
-- partialChars - How many characters to enter before triggering
- a partial match (unlike minChars, which defines
- how many characters are required to do any match
- at all). Defaults to 2.
-
-- ignoreCase - Whether to ignore case when autocompleting.
- Defaults to true.
-
-It's possible to pass in a custom function as the 'selector'
-option, if you prefer to write your own autocompletion logic.
-In that case, the other options above will not apply unless
-you support them.
-
-***/
-
-/** @id Autocompleter.Local */
-Autocompleter.Local = function (element, update, array, options) {
- this.__init__(element, update, array, options);
-};
-
-MochiKit.Base.update(Autocompleter.Local.prototype, Autocompleter.Base.prototype);
-
-MochiKit.Base.update(Autocompleter.Local.prototype, {
- __init__: function (element, update, array, options) {
- this.baseInitialize(element, update, options);
- this.options.array = array;
- },
-
-/** @id Autocompleter.Local.prototype.getUpdatedChoices */
- getUpdatedChoices: function () {
- this.updateChoices(this.options.selector(this));
- },
-
-/** @id Autocompleter.Local.prototype.setOptions */
- setOptions: function (options) {
- this.options = MochiKit.Base.update({
- choices: 10,
- partialSearch: true,
- partialChars: 2,
- ignoreCase: true,
- fullSearch: false,
- selector: function (instance) {
- var ret = []; // Beginning matches
- var partial = []; // Inside matches
- var entry = instance.getToken();
- var count = 0;
-
- for (var i = 0; i < instance.options.array.length &&
- ret.length < instance.options.choices ; i++) {
-
- var elem = instance.options.array[i];
- var foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase()) :
- elem.indexOf(entry);
-
- while (foundPos != -1) {
- if (foundPos === 0 && elem.length != entry.length) {
- ret.push('<li><strong>' + elem.substr(0, entry.length) + '</strong>' +
- elem.substr(entry.length) + '</li>');
- break;
- } else if (entry.length >= instance.options.partialChars &&
- instance.options.partialSearch && foundPos != -1) {
- if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos - 1, 1))) {
- partial.push('<li>' + elem.substr(0, foundPos) + '<strong>' +
- elem.substr(foundPos, entry.length) + '</strong>' + elem.substr(
- foundPos + entry.length) + '</li>');
- break;
- }
- }
-
- foundPos = instance.options.ignoreCase ?
- elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
- elem.indexOf(entry, foundPos + 1);
-
- }
- }
- if (partial.length) {
- ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
- }
- return '<ul>' + ret.join('') + '</ul>';
- }
- }, options || {});
- }
-});
-
-/***
-
-AJAX in-place editor
-
-see documentation on http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor
-
-Use this if you notice weird scrolling problems on some browsers,
-the DOM might be a bit confused when this gets called so do this
-waits 1 ms (with setTimeout) until it does the activation
-
-***/
-
-/** @id Ajax.InPlaceEditor */
-Ajax.InPlaceEditor = function (element, url, options) {
- this.__init__(element, url, options);
-};
-
-/** @id Ajax.InPlaceEditor.defaultHighlightColor */
-Ajax.InPlaceEditor.defaultHighlightColor = '#FFFF99';
-
-Ajax.InPlaceEditor.prototype = {
- __init__: function (element, url, options) {
- this.url = url;
- this.element = MochiKit.DOM.getElement(element);
-
- this.options = MochiKit.Base.update({
- okButton: true,
- okText: 'ok',
- cancelLink: true,
- cancelText: 'cancel',
- savingText: 'Saving...',
- clickToEditText: 'Click to edit',
- okText: 'ok',
- rows: 1,
- onComplete: function (transport, element) {
- new MochiKit.Visual.Highlight(element, {startcolor: this.options.highlightcolor});
- },
- onFailure: function (transport) {
- alert('Error communicating with the server: ' + MochiKit.Base.stripTags(transport.responseText));
- },
- callback: function (form) {
- return MochiKit.DOM.formContents(form);
- },
- handleLineBreaks: true,
- loadingText: 'Loading...',
- savingClassName: 'inplaceeditor-saving',
- loadingClassName: 'inplaceeditor-loading',
- formClassName: 'inplaceeditor-form',
- highlightcolor: Ajax.InPlaceEditor.defaultHighlightColor,
- highlightendcolor: '#FFFFFF',
- externalControl: null,
- submitOnBlur: false,
- ajaxOptions: {}
- }, options || {});
-
- if (!this.options.formId && this.element.id) {
- this.options.formId = this.element.id + '-inplaceeditor';
- if (MochiKit.DOM.getElement(this.options.formId)) {
- // there's already a form with that name, don't specify an id
- this.options.formId = null;
- }
- }
-
- if (this.options.externalControl) {
- this.options.externalControl = MochiKit.DOM.getElement(this.options.externalControl);
- }
-
- this.originalBackground = MochiKit.Style.getStyle(this.element, 'background-color');
- if (!this.originalBackground) {
- this.originalBackground = 'transparent';
- }
-
- this.element.title = this.options.clickToEditText;
-
- this.onclickListener = MochiKit.Signal.connect(this.element, 'onclick', this, this.enterEditMode);
- this.mouseoverListener = MochiKit.Signal.connect(this.element, 'onmouseover', this, this.enterHover);
- this.mouseoutListener = MochiKit.Signal.connect(this.element, 'onmouseout', this, this.leaveHover);
- if (this.options.externalControl) {
- this.onclickListenerExternal = MochiKit.Signal.connect(this.options.externalControl,
- 'onclick', this, this.enterEditMode);
- this.mouseoverListenerExternal = MochiKit.Signal.connect(this.options.externalControl,
- 'onmouseover', this, this.enterHover);
- this.mouseoutListenerExternal = MochiKit.Signal.connect(this.options.externalControl,
- 'onmouseout', this, this.leaveHover);
- }
- },
-
-/** @id Ajax.InPlaceEditor.prototype.enterEditMode */
- enterEditMode: function (evt) {
- if (this.saving) {
- return;
- }
- if (this.editing) {
- return;
- }
- this.editing = true;
- this.onEnterEditMode();
- if (this.options.externalControl) {
- MochiKit.Style.hideElement(this.options.externalControl);
- }
- MochiKit.Style.hideElement(this.element);
- this.createForm();
- this.element.parentNode.insertBefore(this.form, this.element);
- Field.scrollFreeActivate(this.editField);
- // stop the event to avoid a page refresh in Safari
- if (evt) {
- evt.stop();
- }
- return false;
- },
-
-/** @id Ajax.InPlaceEditor.prototype.createForm */
- createForm: function () {
- this.form = document.createElement('form');
- this.form.id = this.options.formId;
- MochiKit.DOM.addElementClass(this.form, this.options.formClassName)
- this.form.onsubmit = MochiKit.Base.bind(this.onSubmit, this);
-
- this.createEditField();
-
- if (this.options.textarea) {
- var br = document.createElement('br');
- this.form.appendChild(br);
- }
-
- if (this.options.okButton) {
- okButton = document.createElement('input');
- okButton.type = 'submit';
- okButton.value = this.options.okText;
- this.form.appendChild(okButton);
- }
-
- if (this.options.cancelLink) {
- cancelLink = document.createElement('a');
- cancelLink.href = '#';
- cancelLink.appendChild(document.createTextNode(this.options.cancelText));
- cancelLink.onclick = MochiKit.Base.bind(this.onclickCancel, this);
- this.form.appendChild(cancelLink);
- }
- },
-
-/** @id Ajax.InPlaceEditor.prototype.hasHTMLLineBreaks */
- hasHTMLLineBreaks: function (string) {
- if (!this.options.handleLineBreaks) {
- return false;
- }
- return string.match(/<br/i) || string.match(/<p>/i);
- },
-
-/** @id Ajax.InPlaceEditor.prototype.convertHTMLLineBreaks */
- convertHTMLLineBreaks: function (string) {
- return string.replace(/<br>/gi, '\n').replace(/<br\/>/gi, '\n').replace(/<\/p>/gi, '\n').replace(/<p>/gi, '');
- },
-
-/** @id Ajax.InPlaceEditor.prototype.createEditField */
- createEditField: function () {
- var text;
- if (this.options.loadTextURL) {
- text = this.options.loadingText;
- } else {
- text = this.getText();
- }
-
- var obj = this;
-
- if (this.options.rows == 1 && !this.hasHTMLLineBreaks(text)) {
- this.options.textarea = false;
- var textField = document.createElement('input');
- textField.obj = this;
- textField.type = 'text';
- textField.name = 'value';
- textField.value = text;
- textField.style.backgroundColor = this.options.highlightcolor;
- var size = this.options.size || this.options.cols || 0;
- if (size !== 0) {
- textField.size = size;
- }
- if (this.options.submitOnBlur) {
- textField.onblur = MochiKit.Base.bind(this.onSubmit, this);
- }
- this.editField = textField;
- } else {
- this.options.textarea = true;
- var textArea = document.createElement('textarea');
- textArea.obj = this;
- textArea.name = 'value';
- textArea.value = this.convertHTMLLineBreaks(text);
- textArea.rows = this.options.rows;
- textArea.cols = this.options.cols || 40;
- if (this.options.submitOnBlur) {
- textArea.onblur = MochiKit.Base.bind(this.onSubmit, this);
- }
- this.editField = textArea;
- }
-
- if (this.options.loadTextURL) {
- this.loadExternalText();
- }
- this.form.appendChild(this.editField);
- },
-
-/** @id Ajax.InPlaceEditor.prototype.getText */
- getText: function () {
- return this.element.innerHTML;
- },
-
-/** @id Ajax.InPlaceEditor.prototype.loadExternalText */
- loadExternalText: function () {
- MochiKit.DOM.addElementClass(this.form, this.options.loadingClassName);
- this.editField.disabled = true;
- new Ajax.Request(
- this.options.loadTextURL,
- MochiKit.Base.update({
- asynchronous: true,
- onComplete: MochiKit.Base.bind(this.onLoadedExternalText, this)
- }, this.options.ajaxOptions)
- );
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onLoadedExternalText */
- onLoadedExternalText: function (transport) {
- MochiKit.DOM.removeElementClass(this.form, this.options.loadingClassName);
- this.editField.disabled = false;
- this.editField.value = MochiKit.Base.stripTags(transport);
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onclickCancel */
- onclickCancel: function () {
- this.onComplete();
- this.leaveEditMode();
- return false;
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onFailure */
- onFailure: function (transport) {
- this.options.onFailure(transport);
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- this.oldInnerHTML = null;
- }
- return false;
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onSubmit */
- onSubmit: function () {
- // onLoading resets these so we need to save them away for the Ajax call
- var form = this.form;
- var value = this.editField.value;
-
- // do this first, sometimes the ajax call returns before we get a
- // chance to switch on Saving which means this will actually switch on
- // Saving *after* we have left edit mode causing Saving to be
- // displayed indefinitely
- this.onLoading();
-
- new Ajax.Updater(
- {
- success: this.element,
- // dont update on failure (this could be an option)
- failure: null
- },
- this.url,
- MochiKit.Base.update({
- parameters: this.options.callback(form, value),
- onComplete: MochiKit.Base.bind(this.onComplete, this),
- onFailure: MochiKit.Base.bind(this.onFailure, this)
- }, this.options.ajaxOptions)
- );
- // stop the event to avoid a page refresh in Safari
- if (arguments.length > 1) {
- arguments[0].stop();
- }
- return false;
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onLoading */
- onLoading: function () {
- this.saving = true;
- this.removeForm();
- this.leaveHover();
- this.showSaving();
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onSaving */
- showSaving: function () {
- this.oldInnerHTML = this.element.innerHTML;
- this.element.innerHTML = this.options.savingText;
- MochiKit.DOM.addElementClass(this.element, this.options.savingClassName);
- this.element.style.backgroundColor = this.originalBackground;
- MochiKit.Style.showElement(this.element);
- },
-
-/** @id Ajax.InPlaceEditor.prototype.removeForm */
- removeForm: function () {
- if (this.form) {
- if (this.form.parentNode) {
- MochiKit.DOM.removeElement(this.form);
- }
- this.form = null;
- }
- },
-
-/** @id Ajax.InPlaceEditor.prototype.enterHover */
- enterHover: function () {
- if (this.saving) {
- return;
- }
- this.element.style.backgroundColor = this.options.highlightcolor;
- if (this.effect) {
- this.effect.cancel();
- }
- MochiKit.DOM.addElementClass(this.element, this.options.hoverClassName)
- },
-
-/** @id Ajax.InPlaceEditor.prototype.leaveHover */
- leaveHover: function () {
- if (this.options.backgroundColor) {
- this.element.style.backgroundColor = this.oldBackground;
- }
- MochiKit.DOM.removeElementClass(this.element, this.options.hoverClassName)
- if (this.saving) {
- return;
- }
- this.effect = new MochiKit.Visual.Highlight(this.element, {
- startcolor: this.options.highlightcolor,
- endcolor: this.options.highlightendcolor,
- restorecolor: this.originalBackground
- });
- },
-
-/** @id Ajax.InPlaceEditor.prototype.leaveEditMode */
- leaveEditMode: function () {
- MochiKit.DOM.removeElementClass(this.element, this.options.savingClassName);
- this.removeForm();
- this.leaveHover();
- this.element.style.backgroundColor = this.originalBackground;
- MochiKit.Style.showElement(this.element);
- if (this.options.externalControl) {
- MochiKit.Style.showElement(this.options.externalControl);
- }
- this.editing = false;
- this.saving = false;
- this.oldInnerHTML = null;
- this.onLeaveEditMode();
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onComplete */
- onComplete: function (transport) {
- this.leaveEditMode();
- MochiKit.Base.bind(this.options.onComplete, this)(transport, this.element);
- },
-
-/** @id Ajax.InPlaceEditor.prototype.onEnterEditMode */
- onEnterEditMode: function () {},
-
-/** @id Ajax.InPlaceEditor.prototype.onLeaveEditMode */
- onLeaveEditMode: function () {},
-
- /** @id Ajax.InPlaceEditor.prototype.dispose */
- dispose: function () {
- if (this.oldInnerHTML) {
- this.element.innerHTML = this.oldInnerHTML;
- }
- this.leaveEditMode();
- MochiKit.Signal.disconnect(this.onclickListener);
- MochiKit.Signal.disconnect(this.mouseoverListener);
- MochiKit.Signal.disconnect(this.mouseoutListener);
- if (this.options.externalControl) {
- MochiKit.Signal.disconnect(this.onclickListenerExternal);
- MochiKit.Signal.disconnect(this.mouseoverListenerExternal);
- MochiKit.Signal.disconnect(this.mouseoutListenerExternal);
- }
- }
-};
-
diff --git a/mochitest/MochiKit/DOM.js b/mochitest/MochiKit/DOM.js
deleted file mode 100644
index caff07e..0000000
--- a/mochitest/MochiKit/DOM.js
+++ /dev/null
@@ -1,1043 +0,0 @@
-/***
-
-MochiKit.DOM 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide("MochiKit.DOM");
- dojo.require("MochiKit.Base");
-}
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.DOM depends on MochiKit.Base!";
-}
-
-if (typeof(MochiKit.DOM) == 'undefined') {
- MochiKit.DOM = {};
-}
-
-MochiKit.DOM.NAME = "MochiKit.DOM";
-MochiKit.DOM.VERSION = "1.4";
-MochiKit.DOM.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-MochiKit.DOM.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.DOM.EXPORT = [
- "removeEmptyTextNodes",
- "formContents",
- "currentWindow",
- "currentDocument",
- "withWindow",
- "withDocument",
- "registerDOMConverter",
- "coerceToDOM",
- "createDOM",
- "createDOMFunc",
- "isChildNode",
- "getNodeAttribute",
- "setNodeAttribute",
- "updateNodeAttributes",
- "appendChildNodes",
- "replaceChildNodes",
- "removeElement",
- "swapDOM",
- "BUTTON",
- "TT",
- "PRE",
- "H1",
- "H2",
- "H3",
- "BR",
- "CANVAS",
- "HR",
- "LABEL",
- "TEXTAREA",
- "FORM",
- "STRONG",
- "SELECT",
- "OPTION",
- "OPTGROUP",
- "LEGEND",
- "FIELDSET",
- "P",
- "UL",
- "OL",
- "LI",
- "TD",
- "TR",
- "THEAD",
- "TBODY",
- "TFOOT",
- "TABLE",
- "TH",
- "INPUT",
- "SPAN",
- "A",
- "DIV",
- "IMG",
- "getElement",
- "$",
- "getElementsByTagAndClassName",
- "addToCallStack",
- "addLoadEvent",
- "focusOnLoad",
- "setElementClass",
- "toggleElementClass",
- "addElementClass",
- "removeElementClass",
- "swapElementClass",
- "hasElementClass",
- "escapeHTML",
- "toHTML",
- "emitHTML",
- "scrapeText"
-];
-
-MochiKit.DOM.EXPORT_OK = [
- "domConverters"
-];
-
-MochiKit.DOM.DEPRECATED = [
- ['computedStyle', 'MochiKit.Style.computedStyle', '1.4'],
- /** @id MochiKit.DOM.elementDimensions */
- ['elementDimensions', 'MochiKit.Style.getElementDimensions', '1.4'],
- /** @id MochiKit.DOM.elementPosition */
- ['elementPosition', 'MochiKit.Style.getElementPosition', '1.4'],
- ['hideElement', 'MochiKit.Style.hideElement', '1.4'],
- /** @id MochiKit.DOM.setElementDimensions */
- ['setElementDimensions', 'MochiKit.Style.setElementDimensions', '1.4'],
- /** @id MochiKit.DOM.setElementPosition */
- ['setElementPosition', 'MochiKit.Style.setElementPosition', '1.4'],
- ['setDisplayForElement', 'MochiKit.Style.setDisplayForElement', '1.4'],
- /** @id MochiKit.DOM.setOpacity */
- ['setOpacity', 'MochiKit.Style.setOpacity', '1.4'],
- ['showElement', 'MochiKit.Style.showElement', '1.4'],
- /** @id MochiKit.DOM.Coordinates */
- ['Coordinates', 'MochiKit.Style.Coordinates', '1.4'], // FIXME: broken
- /** @id MochiKit.DOM.Dimensions */
- ['Dimensions', 'MochiKit.Style.Dimensions', '1.4'] // FIXME: broken
-];
-
-/** @id MochiKit.DOM.getViewportDimensions */
-MochiKit.DOM.getViewportDimensions = new Function('' +
- 'if (!MochiKit["Style"]) {' +
- ' throw new Error("This function has been deprecated and depends on MochiKit.Style.");' +
- '}' +
- 'return MochiKit.Style.getViewportDimensions.apply(this, arguments);');
-
-MochiKit.Base.update(MochiKit.DOM, {
-
- /** @id MochiKit.DOM.currentWindow */
- currentWindow: function () {
- return MochiKit.DOM._window;
- },
-
- /** @id MochiKit.DOM.currentDocument */
- currentDocument: function () {
- return MochiKit.DOM._document;
- },
-
- /** @id MochiKit.DOM.withWindow */
- withWindow: function (win, func) {
- var self = MochiKit.DOM;
- var oldDoc = self._document;
- var oldWin = self._win;
- var rval;
- try {
- self._window = win;
- self._document = win.document;
- rval = func();
- } catch (e) {
- self._window = oldWin;
- self._document = oldDoc;
- throw e;
- }
- self._window = oldWin;
- self._document = oldDoc;
- return rval;
- },
-
- /** @id MochiKit.DOM.formContents */
- formContents: function (elem/* = document */) {
- var names = [];
- var values = [];
- var m = MochiKit.Base;
- var self = MochiKit.DOM;
- if (typeof(elem) == "undefined" || elem === null) {
- elem = self._document;
- } else {
- elem = self.getElement(elem);
- }
- m.nodeWalk(elem, function (elem) {
- var name = elem.name;
- if (m.isNotEmpty(name)) {
- var tagName = elem.tagName.toUpperCase();
- if (tagName === "INPUT"
- && (elem.type == "radio" || elem.type == "checkbox")
- && !elem.checked
- ) {
- return null;
- }
- if (tagName === "SELECT") {
- if (elem.type == "select-one") {
- if (elem.selectedIndex >= 0) {
- var opt = elem.options[elem.selectedIndex];
- names.push(name);
- values.push(opt.value);
- return null;
- }
- // no form elements?
- names.push(name);
- values.push("");
- return null;
- } else {
- var opts = elem.options;
- if (!opts.length) {
- names.push(name);
- values.push("");
- return null;
- }
- for (var i = 0; i < opts.length; i++) {
- var opt = opts[i];
- if (!opt.selected) {
- continue;
- }
- names.push(name);
- values.push(opt.value);
- }
- return null;
- }
- }
- if (tagName === "FORM" || tagName === "P" || tagName === "SPAN"
- || tagName === "DIV"
- ) {
- return elem.childNodes;
- }
- names.push(name);
- values.push(elem.value || '');
- return null;
- }
- return elem.childNodes;
- });
- return [names, values];
- },
-
- /** @id MochiKit.DOM.withDocument */
- withDocument: function (doc, func) {
- var self = MochiKit.DOM;
- var oldDoc = self._document;
- var rval;
- try {
- self._document = doc;
- rval = func();
- } catch (e) {
- self._document = oldDoc;
- throw e;
- }
- self._document = oldDoc;
- return rval;
- },
-
- /** @id MochiKit.DOM.registerDOMConverter */
- registerDOMConverter: function (name, check, wrap, /* optional */override) {
- MochiKit.DOM.domConverters.register(name, check, wrap, override);
- },
-
- /** @id MochiKit.DOM.coerceToDOM */
- coerceToDOM: function (node, ctx) {
- var m = MochiKit.Base;
- var im = MochiKit.Iter;
- var self = MochiKit.DOM;
- if (im) {
- var iter = im.iter;
- var repeat = im.repeat;
- var map = m.map;
- }
- var domConverters = self.domConverters;
- var coerceToDOM = arguments.callee;
- var NotFound = m.NotFound;
- while (true) {
- if (typeof(node) == 'undefined' || node === null) {
- return null;
- }
- if (typeof(node.nodeType) != 'undefined' && node.nodeType > 0) {
- return node;
- }
- if (typeof(node) == 'number' || typeof(node) == 'boolean') {
- node = node.toString();
- // FALL THROUGH
- }
- if (typeof(node) == 'string') {
- return self._document.createTextNode(node);
- }
- if (typeof(node.__dom__) == 'function') {
- node = node.__dom__(ctx);
- continue;
- }
- if (typeof(node.dom) == 'function') {
- node = node.dom(ctx);
- continue;
- }
- if (typeof(node) == 'function') {
- node = node.apply(ctx, [ctx]);
- continue;
- }
-
- if (im) {
- // iterable
- var iterNodes = null;
- try {
- iterNodes = iter(node);
- } catch (e) {
- // pass
- }
- if (iterNodes) {
- return map(coerceToDOM, iterNodes, repeat(ctx));
- }
- }
-
- // adapter
- try {
- node = domConverters.match(node, ctx);
- continue;
- } catch (e) {
- if (e != NotFound) {
- throw e;
- }
- }
-
- // fallback
- return self._document.createTextNode(node.toString());
- }
- // mozilla warnings aren't too bright
- return undefined;
- },
-
- /** @id MochiKit.DOM.isChildNode */
- isChildNode: function (node, maybeparent) {
- var self = MochiKit.DOM;
- if (typeof(node) == "string") {
- node = self.getElement(node);
- }
- if (typeof(maybeparent) == "string") {
- maybeparent = self.getElement(maybeparent);
- }
- if (node === maybeparent) {
- return true;
- }
- while (node && node.tagName.toUpperCase() != "BODY") {
- node = node.parentNode;
- if (node === maybeparent) {
- return true;
- }
- }
- return false;
- },
-
- /** @id MochiKit.DOM.setNodeAttribute */
- setNodeAttribute: function (node, attr, value) {
- var o = {};
- o[attr] = value;
- try {
- return MochiKit.DOM.updateNodeAttributes(node, o);
- } catch (e) {
- // pass
- }
- return null;
- },
-
- /** @id MochiKit.DOM.getNodeAttribute */
- getNodeAttribute: function (node, attr) {
- var self = MochiKit.DOM;
- var rename = self.attributeArray.renames[attr];
- node = self.getElement(node);
- try {
- if (rename) {
- return node[rename];
- }
- return node.getAttribute(attr);
- } catch (e) {
- // pass
- }
- return null;
- },
-
- /** @id MochiKit.DOM.updateNodeAttributes */
- updateNodeAttributes: function (node, attrs) {
- var elem = node;
- var self = MochiKit.DOM;
- if (typeof(node) == 'string') {
- elem = self.getElement(node);
- }
- if (attrs) {
- var updatetree = MochiKit.Base.updatetree;
- if (self.attributeArray.compliant) {
- // not IE, good.
- for (var k in attrs) {
- var v = attrs[k];
- if (typeof(v) == 'object' && typeof(elem[k]) == 'object') {
- updatetree(elem[k], v);
- } else if (k.substring(0, 2) == "on") {
- if (typeof(v) == "string") {
- v = new Function(v);
- }
- elem[k] = v;
- } else {
- elem.setAttribute(k, v);
- }
- }
- } else {
- // IE is insane in the membrane
- var renames = self.attributeArray.renames;
- for (k in attrs) {
- v = attrs[k];
- var renamed = renames[k];
- if (k == "style" && typeof(v) == "string") {
- elem.style.cssText = v;
- } else if (typeof(renamed) == "string") {
- elem[renamed] = v;
- } else if (typeof(elem[k]) == 'object'
- && typeof(v) == 'object') {
- updatetree(elem[k], v);
- } else if (k.substring(0, 2) == "on") {
- if (typeof(v) == "string") {
- v = new Function(v);
- }
- elem[k] = v;
- } else {
- elem.setAttribute(k, v);
- }
- }
- }
- }
- return elem;
- },
-
- /** @id MochiKit.DOM.appendChildNodes */
- appendChildNodes: function (node/*, nodes...*/) {
- var elem = node;
- var self = MochiKit.DOM;
- if (typeof(node) == 'string') {
- elem = self.getElement(node);
- }
- var nodeStack = [
- self.coerceToDOM(
- MochiKit.Base.extend(null, arguments, 1),
- elem
- )
- ];
- var concat = MochiKit.Base.concat;
- while (nodeStack.length) {
- var n = nodeStack.shift();
- if (typeof(n) == 'undefined' || n === null) {
- // pass
- } else if (typeof(n.nodeType) == 'number') {
- elem.appendChild(n);
- } else {
- nodeStack = concat(n, nodeStack);
- }
- }
- return elem;
- },
-
- /** @id MochiKit.DOM.replaceChildNodes */
- replaceChildNodes: function (node/*, nodes...*/) {
- var elem = node;
- var self = MochiKit.DOM;
- if (typeof(node) == 'string') {
- elem = self.getElement(node);
- arguments[0] = elem;
- }
- var child;
- while ((child = elem.firstChild)) {
- elem.removeChild(child);
- }
- if (arguments.length < 2) {
- return elem;
- } else {
- return self.appendChildNodes.apply(this, arguments);
- }
- },
-
- /** @id MochiKit.DOM.createDOM */
- createDOM: function (name, attrs/*, nodes... */) {
- var elem;
- var self = MochiKit.DOM;
- var m = MochiKit.Base;
- if (typeof(attrs) == "string" || typeof(attrs) == "number") {
- var args = m.extend([name, null], arguments, 1);
- return arguments.callee.apply(this, args);
- }
- if (typeof(name) == 'string') {
- // Internet Explorer is dumb
- var xhtml = self._xhtml;
- if (attrs && !self.attributeArray.compliant) {
- // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/name_2.asp
- var contents = "";
- if ('name' in attrs) {
- contents += ' name="' + self.escapeHTML(attrs.name) + '"';
- }
- if (name == 'input' && 'type' in attrs) {
- contents += ' type="' + self.escapeHTML(attrs.type) + '"';
- }
- if (contents) {
- name = "<" + name + contents + ">";
- xhtml = false;
- }
- }
- var d = self._document;
- if (xhtml && d === document) {
- elem = d.createElementNS("http://www.w3.org/1999/xhtml", name);
- } else {
- elem = d.createElement(name);
- }
- } else {
- elem = name;
- }
- if (attrs) {
- self.updateNodeAttributes(elem, attrs);
- }
- if (arguments.length <= 2) {
- return elem;
- } else {
- var args = m.extend([elem], arguments, 2);
- return self.appendChildNodes.apply(this, args);
- }
- },
-
- /** @id MochiKit.DOM.createDOMFunc */
- createDOMFunc: function (/* tag, attrs, *nodes */) {
- var m = MochiKit.Base;
- return m.partial.apply(
- this,
- m.extend([MochiKit.DOM.createDOM], arguments)
- );
- },
-
- /** @id MochiKit.DOM.removeElement */
- removeElement: function (elem) {
- var e = MochiKit.DOM.getElement(elem);
- e.parentNode.removeChild(e);
- return e;
- },
-
- /** @id MochiKit.DOM.swapDOM */
- swapDOM: function (dest, src) {
- var self = MochiKit.DOM;
- dest = self.getElement(dest);
- var parent = dest.parentNode;
- if (src) {
- src = self.getElement(src);
- parent.replaceChild(src, dest);
- } else {
- parent.removeChild(dest);
- }
- return src;
- },
-
- /** @id MochiKit.DOM.getElement */
- getElement: function (id) {
- var self = MochiKit.DOM;
- if (arguments.length == 1) {
- return ((typeof(id) == "string") ?
- self._document.getElementById(id) : id);
- } else {
- return MochiKit.Base.map(self.getElement, arguments);
- }
- },
-
- /** @id MochiKit.DOM.getElementsByTagAndClassName */
- getElementsByTagAndClassName: function (tagName, className,
- /* optional */parent) {
- var self = MochiKit.DOM;
- if (typeof(tagName) == 'undefined' || tagName === null) {
- tagName = '*';
- }
- if (typeof(parent) == 'undefined' || parent === null) {
- parent = self._document;
- }
- parent = self.getElement(parent);
- var children = (parent.getElementsByTagName(tagName)
- || self._document.all);
- if (typeof(className) == 'undefined' || className === null) {
- return MochiKit.Base.extend(null, children);
- }
-
- var elements = [];
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- var cls = child.className;
- if (!cls) {
- continue;
- }
- var classNames = cls.split(' ');
- for (var j = 0; j < classNames.length; j++) {
- if (classNames[j] == className) {
- elements.push(child);
- break;
- }
- }
- }
-
- return elements;
- },
-
- _newCallStack: function (path, once) {
- var rval = function () {
- var callStack = arguments.callee.callStack;
- for (var i = 0; i < callStack.length; i++) {
- if (callStack[i].apply(this, arguments) === false) {
- break;
- }
- }
- if (once) {
- try {
- this[path] = null;
- } catch (e) {
- // pass
- }
- }
- };
- rval.callStack = [];
- return rval;
- },
-
- /** @id MochiKit.DOM.addToCallStack */
- addToCallStack: function (target, path, func, once) {
- var self = MochiKit.DOM;
- var existing = target[path];
- var regfunc = existing;
- if (!(typeof(existing) == 'function'
- && typeof(existing.callStack) == "object"
- && existing.callStack !== null)) {
- regfunc = self._newCallStack(path, once);
- if (typeof(existing) == 'function') {
- regfunc.callStack.push(existing);
- }
- target[path] = regfunc;
- }
- regfunc.callStack.push(func);
- },
-
- /** @id MochiKit.DOM.addLoadEvent */
- addLoadEvent: function (func) {
- var self = MochiKit.DOM;
- self.addToCallStack(self._window, "onload", func, true);
-
- },
-
- /** @id MochiKit.DOM.focusOnLoad */
- focusOnLoad: function (element) {
- var self = MochiKit.DOM;
- self.addLoadEvent(function () {
- element = self.getElement(element);
- if (element) {
- element.focus();
- }
- });
- },
-
- /** @id MochiKit.DOM.setElementClass */
- setElementClass: function (element, className) {
- var self = MochiKit.DOM;
- var obj = self.getElement(element);
- if (self.attributeArray.compliant) {
- obj.setAttribute("class", className);
- } else {
- obj.setAttribute("className", className);
- }
- },
-
- /** @id MochiKit.DOM.toggleElementClass */
- toggleElementClass: function (className/*, element... */) {
- var self = MochiKit.DOM;
- for (var i = 1; i < arguments.length; i++) {
- var obj = self.getElement(arguments[i]);
- if (!self.addElementClass(obj, className)) {
- self.removeElementClass(obj, className);
- }
- }
- },
-
- /** @id MochiKit.DOM.addElementClass */
- addElementClass: function (element, className) {
- var self = MochiKit.DOM;
- var obj = self.getElement(element);
- var cls = obj.className;
- // trivial case, no className yet
- if (cls == undefined || cls.length === 0) {
- self.setElementClass(obj, className);
- return true;
- }
- // the other trivial case, already set as the only class
- if (cls == className) {
- return false;
- }
- var classes = cls.split(" ");
- for (var i = 0; i < classes.length; i++) {
- // already present
- if (classes[i] == className) {
- return false;
- }
- }
- // append class
- self.setElementClass(obj, cls + " " + className);
- return true;
- },
-
- /** @id MochiKit.DOM.removeElementClass */
- removeElementClass: function (element, className) {
- var self = MochiKit.DOM;
- var obj = self.getElement(element);
- var cls = obj.className;
- // trivial case, no className yet
- if (cls == undefined || cls.length === 0) {
- return false;
- }
- // other trivial case, set only to className
- if (cls == className) {
- self.setElementClass(obj, "");
- return true;
- }
- var classes = cls.split(" ");
- for (var i = 0; i < classes.length; i++) {
- // already present
- if (classes[i] == className) {
- // only check sane case where the class is used once
- classes.splice(i, 1);
- self.setElementClass(obj, classes.join(" "));
- return true;
- }
- }
- // not found
- return false;
- },
-
- /** @id MochiKit.DOM.swapElementClass */
- swapElementClass: function (element, fromClass, toClass) {
- var obj = MochiKit.DOM.getElement(element);
- var res = MochiKit.DOM.removeElementClass(obj, fromClass);
- if (res) {
- MochiKit.DOM.addElementClass(obj, toClass);
- }
- return res;
- },
-
- /** @id MochiKit.DOM.hasElementClass */
- hasElementClass: function (element, className/*...*/) {
- var obj = MochiKit.DOM.getElement(element);
- var cls = obj.className;
- if (!cls) {
- return false;
- }
- var classes = cls.split(" ");
- for (var i = 1; i < arguments.length; i++) {
- var good = false;
- for (var j = 0; j < classes.length; j++) {
- if (classes[j] == arguments[i]) {
- good = true;
- break;
- }
- }
- if (!good) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.DOM.escapeHTML */
- escapeHTML: function (s) {
- return s.replace(/&/g, "&"
- ).replace(/"/g, """
- ).replace(/</g, "<"
- ).replace(/>/g, ">");
- },
-
- /** @id MochiKit.DOM.toHTML */
- toHTML: function (dom) {
- return MochiKit.DOM.emitHTML(dom).join("");
- },
-
- /** @id MochiKit.DOM.emitHTML */
- emitHTML: function (dom, /* optional */lst) {
- if (typeof(lst) == 'undefined' || lst === null) {
- lst = [];
- }
- // queue is the call stack, we're doing this non-recursively
- var queue = [dom];
- var self = MochiKit.DOM;
- var escapeHTML = self.escapeHTML;
- var attributeArray = self.attributeArray;
- while (queue.length) {
- dom = queue.pop();
- if (typeof(dom) == 'string') {
- lst.push(dom);
- } else if (dom.nodeType == 1) {
- // we're not using higher order stuff here
- // because safari has heisenbugs.. argh.
- //
- // I think it might have something to do with
- // garbage collection and function calls.
- lst.push('<' + dom.tagName.toLowerCase());
- var attributes = [];
- var domAttr = attributeArray(dom);
- for (var i = 0; i < domAttr.length; i++) {
- var a = domAttr[i];
- attributes.push([
- " ",
- a.name,
- '="',
- escapeHTML(a.value),
- '"'
- ]);
- }
- attributes.sort();
- for (i = 0; i < attributes.length; i++) {
- var attrs = attributes[i];
- for (var j = 0; j < attrs.length; j++) {
- lst.push(attrs[j]);
- }
- }
- if (dom.hasChildNodes()) {
- lst.push(">");
- // queue is the FILO call stack, so we put the close tag
- // on first
- queue.push("</" + dom.tagName.toLowerCase() + ">");
- var cnodes = dom.childNodes;
- for (i = cnodes.length - 1; i >= 0; i--) {
- queue.push(cnodes[i]);
- }
- } else {
- lst.push('/>');
- }
- } else if (dom.nodeType == 3) {
- lst.push(escapeHTML(dom.nodeValue));
- }
- }
- return lst;
- },
-
- /** @id MochiKit.DOM.scrapeText */
- scrapeText: function (node, /* optional */asArray) {
- var rval = [];
- (function (node) {
- var cn = node.childNodes;
- if (cn) {
- for (var i = 0; i < cn.length; i++) {
- arguments.callee.call(this, cn[i]);
- }
- }
- var nodeValue = node.nodeValue;
- if (typeof(nodeValue) == 'string') {
- rval.push(nodeValue);
- }
- })(MochiKit.DOM.getElement(node));
- if (asArray) {
- return rval;
- } else {
- return rval.join("");
- }
- },
-
- /** @id MochiKit.DOM.removeEmptyTextNodes */
- removeEmptyTextNodes: function (element) {
- element = MochiKit.DOM.getElement(element);
- for (var i = 0; i < element.childNodes.length; i++) {
- var node = element.childNodes[i];
- if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) {
- node.parentNode.removeChild(node);
- }
- }
- },
-
- __new__: function (win) {
-
- var m = MochiKit.Base;
- if (typeof(document) != "undefined") {
- this._document = document;
- this._xhtml =
- document.createElementNS &&
- document.createElement("testname").localName == "testname";
- } else if (MochiKit.MockDOM) {
- this._document = MochiKit.MockDOM.document;
- }
- this._window = win;
-
- this.domConverters = new m.AdapterRegistry();
-
- var __tmpElement = this._document.createElement("span");
- var attributeArray;
- if (__tmpElement && __tmpElement.attributes &&
- __tmpElement.attributes.length > 0) {
- // for braindead browsers (IE) that insert extra junk
- var filter = m.filter;
- attributeArray = function (node) {
- return filter(attributeArray.ignoreAttrFilter, node.attributes);
- };
- attributeArray.ignoreAttr = {};
- var attrs = __tmpElement.attributes;
- var ignoreAttr = attributeArray.ignoreAttr;
- for (var i = 0; i < attrs.length; i++) {
- var a = attrs[i];
- ignoreAttr[a.name] = a.value;
- }
- attributeArray.ignoreAttrFilter = function (a) {
- return (attributeArray.ignoreAttr[a.name] != a.value);
- };
- attributeArray.compliant = false;
- attributeArray.renames = {
- "class": "className",
- "checked": "defaultChecked",
- "usemap": "useMap",
- "for": "htmlFor",
- "readonly": "readOnly",
- "colspan": "colSpan",
- "bgcolor": "bgColor"
- };
- } else {
- attributeArray = function (node) {
- /***
-
- Return an array of attributes for a given node,
- filtering out attributes that don't belong for
- that are inserted by "Certain Browsers".
-
- ***/
- return node.attributes;
- };
- attributeArray.compliant = true;
- attributeArray.renames = {};
- }
- this.attributeArray = attributeArray;
-
- // FIXME: this really belongs in Base, and could probably be cleaner
- var _deprecated = function(fromModule, arr) {
- var modules = arr[1].split('.');
- var str = '';
- var obj = {};
-
- str += 'if (!MochiKit.' + modules[1] + ') { throw new Error("';
- str += 'This function has been deprecated and depends on MochiKit.';
- str += modules[1] + '.");}';
- str += 'return MochiKit.' + modules[1] + '.' + arr[0];
- str += '.apply(this, arguments);';
-
- obj[modules[2]] = new Function(str);
- MochiKit.Base.update(MochiKit[fromModule], obj);
- }
- for (var i; i < MochiKit.DOM.DEPRECATED.length; i++) {
- _deprecated('DOM', MochiKit.DOM.DEPRECATED[i]);
- }
-
- // shorthand for createDOM syntax
- var createDOMFunc = this.createDOMFunc;
- /** @id MochiKit.DOM.UL */
- this.UL = createDOMFunc("ul");
- /** @id MochiKit.DOM.OL */
- this.OL = createDOMFunc("ol");
- /** @id MochiKit.DOM.LI */
- this.LI = createDOMFunc("li");
- /** @id MochiKit.DOM.TD */
- this.TD = createDOMFunc("td");
- /** @id MochiKit.DOM.TR */
- this.TR = createDOMFunc("tr");
- /** @id MochiKit.DOM.TBODY */
- this.TBODY = createDOMFunc("tbody");
- /** @id MochiKit.DOM.THEAD */
- this.THEAD = createDOMFunc("thead");
- /** @id MochiKit.DOM.TFOOT */
- this.TFOOT = createDOMFunc("tfoot");
- /** @id MochiKit.DOM.TABLE */
- this.TABLE = createDOMFunc("table");
- /** @id MochiKit.DOM.TH */
- this.TH = createDOMFunc("th");
- /** @id MochiKit.DOM.INPUT */
- this.INPUT = createDOMFunc("input");
- /** @id MochiKit.DOM.SPAN */
- this.SPAN = createDOMFunc("span");
- /** @id MochiKit.DOM.A */
- this.A = createDOMFunc("a");
- /** @id MochiKit.DOM.DIV */
- this.DIV = createDOMFunc("div");
- /** @id MochiKit.DOM.IMG */
- this.IMG = createDOMFunc("img");
- /** @id MochiKit.DOM.BUTTON */
- this.BUTTON = createDOMFunc("button");
- /** @id MochiKit.DOM.TT */
- this.TT = createDOMFunc("tt");
- /** @id MochiKit.DOM.PRE */
- this.PRE = createDOMFunc("pre");
- /** @id MochiKit.DOM.H1 */
- this.H1 = createDOMFunc("h1");
- /** @id MochiKit.DOM.H2 */
- this.H2 = createDOMFunc("h2");
- /** @id MochiKit.DOM.H3 */
- this.H3 = createDOMFunc("h3");
- /** @id MochiKit.DOM.BR */
- this.BR = createDOMFunc("br");
- /** @id MochiKit.DOM.HR */
- this.HR = createDOMFunc("hr");
- /** @id MochiKit.DOM.LABEL */
- this.LABEL = createDOMFunc("label");
- /** @id MochiKit.DOM.TEXTAREA */
- this.TEXTAREA = createDOMFunc("textarea");
- /** @id MochiKit.DOM.FORM */
- this.FORM = createDOMFunc("form");
- /** @id MochiKit.DOM.P */
- this.P = createDOMFunc("p");
- /** @id MochiKit.DOM.SELECT */
- this.SELECT = createDOMFunc("select");
- /** @id MochiKit.DOM.OPTION */
- this.OPTION = createDOMFunc("option");
- /** @id MochiKit.DOM.OPTGROUP */
- this.OPTGROUP = createDOMFunc("optgroup");
- /** @id MochiKit.DOM.LEGEND */
- this.LEGEND = createDOMFunc("legend");
- /** @id MochiKit.DOM.FIELDSET */
- this.FIELDSET = createDOMFunc("fieldset");
- /** @id MochiKit.DOM.STRONG */
- this.STRONG = createDOMFunc("strong");
- /** @id MochiKit.DOM.CANVAS */
- this.CANVAS = createDOMFunc("canvas");
-
- /** @id MochiKit.DOM.$ */
- this.$ = this.getElement;
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-
- }
-});
-
-
-MochiKit.DOM.__new__(((typeof(window) == "undefined") ? this : window));
-
-//
-// XXX: Internet Explorer blows
-//
-if (MochiKit.__export__) {
- withWindow = MochiKit.DOM.withWindow;
- withDocument = MochiKit.DOM.withDocument;
-}
-
-MochiKit.Base._exportSymbols(this, MochiKit.DOM);
diff --git a/mochitest/MochiKit/DateTime.js b/mochitest/MochiKit/DateTime.js
deleted file mode 100644
index 1b517b3..0000000
--- a/mochitest/MochiKit/DateTime.js
+++ /dev/null
@@ -1,216 +0,0 @@
-/***
-
-MochiKit.DateTime 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.DateTime');
-}
-
-if (typeof(MochiKit) == 'undefined') {
- MochiKit = {};
-}
-
-if (typeof(MochiKit.DateTime) == 'undefined') {
- MochiKit.DateTime = {};
-}
-
-MochiKit.DateTime.NAME = "MochiKit.DateTime";
-MochiKit.DateTime.VERSION = "1.4";
-MochiKit.DateTime.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-MochiKit.DateTime.toString = function () {
- return this.__repr__();
-};
-
-/** @id MochiKit.DateTime.isoDate */
-MochiKit.DateTime.isoDate = function (str) {
- str = str + "";
- if (typeof(str) != "string" || str.length === 0) {
- return null;
- }
- var iso = str.split('-');
- if (iso.length === 0) {
- return null;
- }
- return new Date(iso[0], iso[1] - 1, iso[2]);
-};
-
-MochiKit.DateTime._isoRegexp = /(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
-
-/** @id MochiKit.DateTime.isoTimestamp */
-MochiKit.DateTime.isoTimestamp = function (str) {
- str = str + "";
- if (typeof(str) != "string" || str.length === 0) {
- return null;
- }
- var res = str.match(MochiKit.DateTime._isoRegexp);
- if (typeof(res) == "undefined" || res === null) {
- return null;
- }
- var year, month, day, hour, min, sec, msec;
- year = parseInt(res[1], 10);
- if (typeof(res[2]) == "undefined" || res[2] === '') {
- return new Date(year);
- }
- month = parseInt(res[2], 10) - 1;
- day = parseInt(res[3], 10);
- if (typeof(res[4]) == "undefined" || res[4] === '') {
- return new Date(year, month, day);
- }
- hour = parseInt(res[4], 10);
- min = parseInt(res[5], 10);
- sec = (typeof(res[6]) != "undefined" && res[6] !== '') ? parseInt(res[6], 10) : 0;
- if (typeof(res[7]) != "undefined" && res[7] !== '') {
- msec = Math.round(1000.0 * parseFloat("0." + res[7]));
- } else {
- msec = 0;
- }
- if ((typeof(res[8]) == "undefined" || res[8] === '') && (typeof(res[9]) == "undefined" || res[9] === '')) {
- return new Date(year, month, day, hour, min, sec, msec);
- }
- var ofs;
- if (typeof(res[9]) != "undefined" && res[9] !== '') {
- ofs = parseInt(res[10], 10) * 3600000;
- if (typeof(res[11]) != "undefined" && res[11] !== '') {
- ofs += parseInt(res[11], 10) * 60000;
- }
- if (res[9] == "-") {
- ofs = -ofs;
- }
- } else {
- ofs = 0;
- }
- return new Date(Date.UTC(year, month, day, hour, min, sec, msec) - ofs);
-};
-
-/** @id MochiKit.DateTime.toISOTime */
-MochiKit.DateTime.toISOTime = function (date, realISO/* = false */) {
- if (typeof(date) == "undefined" || date === null) {
- return null;
- }
- var hh = date.getHours();
- var mm = date.getMinutes();
- var ss = date.getSeconds();
- var lst = [
- ((realISO && (hh < 10)) ? "0" + hh : hh),
- ((mm < 10) ? "0" + mm : mm),
- ((ss < 10) ? "0" + ss : ss)
- ];
- return lst.join(":");
-};
-
-/** @id MochiKit.DateTime.toISOTimeStamp */
-MochiKit.DateTime.toISOTimestamp = function (date, realISO/* = false*/) {
- if (typeof(date) == "undefined" || date === null) {
- return null;
- }
- var sep = realISO ? "T" : " ";
- var foot = realISO ? "Z" : "";
- if (realISO) {
- date = new Date(date.getTime() + (date.getTimezoneOffset() * 60000));
- }
- return MochiKit.DateTime.toISODate(date) + sep + MochiKit.DateTime.toISOTime(date, realISO) + foot;
-};
-
-/** @id MochiKit.DateTime.toISODate */
-MochiKit.DateTime.toISODate = function (date) {
- if (typeof(date) == "undefined" || date === null) {
- return null;
- }
- var _padTwo = MochiKit.DateTime._padTwo;
- return [
- date.getFullYear(),
- _padTwo(date.getMonth() + 1),
- _padTwo(date.getDate())
- ].join("-");
-};
-
-/** @id MochiKit.DateTime.americanDate */
-MochiKit.DateTime.americanDate = function (d) {
- d = d + "";
- if (typeof(d) != "string" || d.length === 0) {
- return null;
- }
- var a = d.split('/');
- return new Date(a[2], a[0] - 1, a[1]);
-};
-
-MochiKit.DateTime._padTwo = function (n) {
- return (n > 9) ? n : "0" + n;
-};
-
-/** @id MochiKit.DateTime.toPaddedAmericanDate */
-MochiKit.DateTime.toPaddedAmericanDate = function (d) {
- if (typeof(d) == "undefined" || d === null) {
- return null;
- }
- var _padTwo = MochiKit.DateTime._padTwo;
- return [
- _padTwo(d.getMonth() + 1),
- _padTwo(d.getDate()),
- d.getFullYear()
- ].join('/');
-};
-
-/** @id MochiKit.DateTime.toAmericanDate */
-MochiKit.DateTime.toAmericanDate = function (d) {
- if (typeof(d) == "undefined" || d === null) {
- return null;
- }
- return [d.getMonth() + 1, d.getDate(), d.getFullYear()].join('/');
-};
-
-MochiKit.DateTime.EXPORT = [
- "isoDate",
- "isoTimestamp",
- "toISOTime",
- "toISOTimestamp",
- "toISODate",
- "americanDate",
- "toPaddedAmericanDate",
- "toAmericanDate"
-];
-
-MochiKit.DateTime.EXPORT_OK = [];
-MochiKit.DateTime.EXPORT_TAGS = {
- ":common": MochiKit.DateTime.EXPORT,
- ":all": MochiKit.DateTime.EXPORT
-};
-
-MochiKit.DateTime.__new__ = function () {
- // MochiKit.Base.nameFunctions(this);
- var base = this.NAME + ".";
- for (var k in this) {
- var o = this[k];
- if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
- try {
- o.NAME = base + k;
- } catch (e) {
- // pass
- }
- }
- }
-};
-
-MochiKit.DateTime.__new__();
-
-if (typeof(MochiKit.Base) != "undefined") {
- MochiKit.Base._exportSymbols(this, MochiKit.DateTime);
-} else {
- (function (globals, module) {
- if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
- || (MochiKit.__export__ === false)) {
- var all = module.EXPORT_TAGS[":all"];
- for (var i = 0; i < all.length; i++) {
- globals[all[i]] = module[all[i]];
- }
- }
- })(this, MochiKit.DateTime);
-}
diff --git a/mochitest/MochiKit/DragAndDrop.js b/mochitest/MochiKit/DragAndDrop.js
deleted file mode 100644
index b23a5ec..0000000
--- a/mochitest/MochiKit/DragAndDrop.js
+++ /dev/null
@@ -1,821 +0,0 @@
-/***
-MochiKit.DragAndDrop 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
- Mochi-ized By Thomas Herve (_firstname_ at nimail.org)
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.DragAndDrop');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Iter');
- dojo.require('MochiKit.Visual');
- dojo.require('MochiKit.Signal');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
- JSAN.use("MochiKit.DOM", []);
- JSAN.use("MochiKit.Visual", []);
- JSAN.use("MochiKit.Iter", []);
- JSAN.use("MochiKit.Signal", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined' ||
- typeof(MochiKit.DOM) == 'undefined' ||
- typeof(MochiKit.Visual) == 'undefined' ||
- typeof(MochiKit.Signal) == 'undefined' ||
- typeof(MochiKit.Iter) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.DragAndDrop depends on MochiKit.Base, MochiKit.DOM, MochiKit.Visual, MochiKit.Signal and MochiKit.Iter!";
-}
-
-if (typeof(MochiKit.DragAndDrop) == 'undefined') {
- MochiKit.DragAndDrop = {};
-}
-
-MochiKit.DragAndDrop.NAME = 'MochiKit.DragAndDrop';
-MochiKit.DragAndDrop.VERSION = '1.4';
-
-MochiKit.DragAndDrop.__repr__ = function () {
- return '[' + this.NAME + ' ' + this.VERSION + ']';
-};
-
-MochiKit.DragAndDrop.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.DragAndDrop.EXPORT = [
- "Droppable",
- "Draggable"
-];
-
-MochiKit.DragAndDrop.EXPORT_OK = [
- "Droppables",
- "Draggables"
-];
-
-MochiKit.DragAndDrop.Droppables = {
- /***
-
- Manage all droppables. Shouldn't be used, use the Droppable object instead.
-
- ***/
- drops: [],
-
- remove: function (element) {
- this.drops = MochiKit.Base.filter(function (d) {
- return d.element != MochiKit.DOM.getElement(element)
- }, this.drops);
- },
-
- register: function (drop) {
- this.drops.push(drop);
- },
-
- unregister: function (drop) {
- this.drops = MochiKit.Base.filter(function (d) {
- return d != drop;
- }, this.drops);
- },
-
- prepare: function (element) {
- MochiKit.Base.map(function (drop) {
- if (drop.isAccepted(element)) {
- if (drop.options.activeclass) {
- MochiKit.DOM.addElementClass(drop.element,
- drop.options.activeclass);
- }
- drop.options.onactive(drop.element, element);
- }
- }, this.drops);
- },
-
- findDeepestChild: function (drops) {
- deepest = drops[0];
-
- for (i = 1; i < drops.length; ++i) {
- if (MochiKit.DOM.isParent(drops[i].element, deepest.element)) {
- deepest = drops[i];
- }
- }
- return deepest;
- },
-
- show: function (point, element) {
- if (!this.drops.length) {
- return;
- }
- var affected = [];
-
- if (this.last_active) {
- this.last_active.deactivate();
- }
- MochiKit.Iter.forEach(this.drops, function (drop) {
- if (drop.isAffected(point, element)) {
- affected.push(drop);
- }
- });
- if (affected.length > 0) {
- drop = this.findDeepestChild(affected);
- MochiKit.Position.within(drop.element, point.page.x, point.page.y);
- drop.options.onhover(element, drop.element,
- MochiKit.Position.overlap(drop.options.overlap, drop.element));
- drop.activate();
- }
- },
-
- fire: function (event, element) {
- if (!this.last_active) {
- return;
- }
- MochiKit.Position.prepare();
-
- if (this.last_active.isAffected(event.mouse(), element)) {
- this.last_active.options.ondrop(element,
- this.last_active.element, event);
- }
- },
-
- reset: function (element) {
- MochiKit.Base.map(function (drop) {
- if (drop.options.activeclass) {
- MochiKit.DOM.removeElementClass(drop.element,
- drop.options.activeclass);
- }
- drop.options.ondesactive(drop.element, element);
- }, this.drops);
- if (this.last_active) {
- this.last_active.deactivate();
- }
- }
-};
-
-/** @id MochiKit.DragAndDrop.Droppable */
-MochiKit.DragAndDrop.Droppable = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.DragAndDrop.Droppable.prototype = {
- /***
-
- A droppable object. Simple use is to create giving an element:
-
- new MochiKit.DragAndDrop.Droppable('myelement');
-
- Generally you'll want to define the 'ondrop' function and maybe the
- 'accept' option to filter draggables.
-
- ***/
- __class__: MochiKit.DragAndDrop.Droppable,
-
- __init__: function (element, /* optional */options) {
- var d = MochiKit.DOM;
- var b = MochiKit.Base;
- this.element = d.getElement(element);
- this.options = b.update({
-
- /** @id MochiKit.DragAndDrop.greedy */
- greedy: true,
-
- /** @id MochiKit.DragAndDrop.hoverclass */
- hoverclass: null,
-
- /** @id MochiKit.DragAndDrop.activeclass */
- activeclass: null,
-
- /** @id MochiKit.DragAndDrop.hoverfunc */
- hoverfunc: b.noop,
-
- /** @id MochiKit.DragAndDrop.accept */
- accept: null,
-
- /** @id MochiKit.DragAndDrop.onactive */
- onactive: b.noop,
-
- /** @id MochiKit.DragAndDrop.ondesactive */
- ondesactive: b.noop,
-
- /** @id MochiKit.DragAndDrop.onhover */
- onhover: b.noop,
-
- /** @id MochiKit.DragAndDrop.ondrop */
- ondrop: b.noop,
-
- /** @id MochiKit.DragAndDrop.containment */
- containment: [],
- tree: false
- }, options || {});
-
- // cache containers
- this.options._containers = [];
- b.map(MochiKit.Base.bind(function (c) {
- this.options._containers.push(d.getElement(c));
- }, this), this.options.containment);
-
- d.makePositioned(this.element); // fix IE
-
- MochiKit.DragAndDrop.Droppables.register(this);
- },
-
- /** @id MochiKit.DragAndDrop.isContained */
- isContained: function (element) {
- if (this.options._containers.length) {
- var containmentNode;
- if (this.options.tree) {
- containmentNode = element.treeNode;
- } else {
- containmentNode = element.parentNode;
- }
- return MochiKit.Iter.some(this.options._containers, function (c) {
- return containmentNode == c;
- });
- } else {
- return true;
- }
- },
-
- /** @id MochiKit.DragAndDrop.isAccepted */
- isAccepted: function (element) {
- return ((!this.options.accept) || MochiKit.Iter.some(
- this.options.accept, function (c) {
- return MochiKit.DOM.hasElementClass(element, c);
- }));
- },
-
- /** @id MochiKit.DragAndDrop.isAffected */
- isAffected: function (point, element) {
- return ((this.element != element) &&
- this.isContained(element) &&
- this.isAccepted(element) &&
- MochiKit.Position.within(this.element, point.page.x,
- point.page.y));
- },
-
- /** @id MochiKit.DragAndDrop.deactivate */
- deactivate: function () {
- /***
-
- A droppable is deactivate when a draggable has been over it and left.
-
- ***/
- if (this.options.hoverclass) {
- MochiKit.DOM.removeElementClass(this.element,
- this.options.hoverclass);
- }
- this.options.hoverfunc(this.element, false);
- MochiKit.DragAndDrop.Droppables.last_active = null;
- },
-
- /** @id MochiKit.DragAndDrop.activate */
- activate: function () {
- /***
-
- A droppable is active when a draggable is over it.
-
- ***/
- if (this.options.hoverclass) {
- MochiKit.DOM.addElementClass(this.element, this.options.hoverclass);
- }
- this.options.hoverfunc(this.element, true);
- MochiKit.DragAndDrop.Droppables.last_active = this;
- },
-
- /** @id MochiKit.DragAndDrop.destroy */
- destroy: function () {
- /***
-
- Delete this droppable.
-
- ***/
- MochiKit.DragAndDrop.Droppables.unregister(this);
- },
-
- /** @id MochiKit.DragAndDrop.repr */
- repr: function () {
- return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
- }
-};
-
-MochiKit.DragAndDrop.Draggables = {
- /***
-
- Manage draggables elements. Not intended to direct use.
-
- ***/
- drags: [],
-
- register: function (draggable) {
- if (this.drags.length === 0) {
- var conn = MochiKit.Signal.connect;
- this.eventMouseUp = conn(document, 'onmouseup', this, this.endDrag);
- this.eventMouseMove = conn(document, 'onmousemove', this,
- this.updateDrag);
- this.eventKeypress = conn(document, 'onkeypress', this,
- this.keyPress);
- }
- this.drags.push(draggable);
- },
-
- unregister: function (draggable) {
- this.drags = MochiKit.Base.filter(function (d) {
- return d != draggable;
- }, this.drags);
- if (this.drags.length === 0) {
- var disc = MochiKit.Signal.disconnect
- disc(this.eventMouseUp);
- disc(this.eventMouseMove);
- disc(this.eventKeypress);
- }
- },
-
- activate: function (draggable) {
- // allows keypress events if window is not currently focused
- // fails for Safari
- window.focus();
- this.activeDraggable = draggable;
- },
-
- deactivate: function () {
- this.activeDraggable = null;
- },
-
- updateDrag: function (event) {
- if (!this.activeDraggable) {
- return;
- }
- var pointer = event.mouse();
- // Mozilla-based browsers fire successive mousemove events with
- // the same coordinates, prevent needless redrawing (moz bug?)
- if (this._lastPointer && (MochiKit.Base.repr(this._lastPointer.page) ==
- MochiKit.Base.repr(pointer.page))) {
- return;
- }
- this._lastPointer = pointer;
- this.activeDraggable.updateDrag(event, pointer);
- },
-
- endDrag: function (event) {
- if (!this.activeDraggable) {
- return;
- }
- this._lastPointer = null;
- this.activeDraggable.endDrag(event);
- this.activeDraggable = null;
- },
-
- keyPress: function (event) {
- if (this.activeDraggable) {
- this.activeDraggable.keyPress(event);
- }
- },
-
- notify: function (eventName, draggable, event) {
- MochiKit.Signal.signal(this, eventName, draggable, event);
- }
-};
-
-/** @id MochiKit.DragAndDrop.Draggable */
-MochiKit.DragAndDrop.Draggable = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.DragAndDrop.Draggable.prototype = {
- /***
-
- A draggable object. Simple instantiate :
-
- new MochiKit.DragAndDrop.Draggable('myelement');
-
- ***/
- __class__ : MochiKit.DragAndDrop.Draggable,
-
- __init__: function (element, /* optional */options) {
- var v = MochiKit.Visual;
- var b = MochiKit.Base;
- options = b.update({
-
- /** @id MochiKit.DragAndDrop.handle */
- handle: false,
-
- /** @id MochiKit.DragAndDrop.starteffect */
- starteffect: function (innerelement) {
- this._savedOpacity = MochiKit.Style.getOpacity(innerelement) || 1.0;
- new v.Opacity(innerelement, {duration:0.2, from:this._savedOpacity, to:0.7});
- },
- /** @id MochiKit.DragAndDrop.reverteffect */
- reverteffect: function (innerelement, top_offset, left_offset) {
- var dur = Math.sqrt(Math.abs(top_offset^2) +
- Math.abs(left_offset^2))*0.02;
- return new v.Move(innerelement,
- {x: -left_offset, y: -top_offset, duration: dur});
- },
-
- /** @id MochiKit.DragAndDrop.endeffect */
- endeffect: function (innerelement) {
- new v.Opacity(innerelement, {duration:0.2, from:0.7, to:this._savedOpacity});
- },
-
- /** @id MochiKit.DragAndDrop.onchange */
- onchange: b.noop,
-
- /** @id MochiKit.DragAndDrop.zindex */
- zindex: 1000,
-
- /** @id MochiKit.DragAndDrop.revert */
- revert: false,
-
- /** @id MochiKit.DragAndDrop.scroll */
- scroll: false,
-
- /** @id MochiKit.DragAndDrop.scrollSensitivity */
- scrollSensitivity: 20,
-
- /** @id MochiKit.DragAndDrop.scrollSpeed */
- scrollSpeed: 15,
- // false, or xy or [x, y] or function (x, y){return [x, y];}
-
- /** @id MochiKit.DragAndDrop.snap */
- snap: false
- }, options || {});
-
- var d = MochiKit.DOM;
- this.element = d.getElement(element);
-
- if (options.handle && (typeof(options.handle) == 'string')) {
- this.handle = d.getFirstElementByTagAndClassName(null,
- options.handle, this.element);
- }
- if (!this.handle) {
- this.handle = d.getElement(options.handle);
- }
- if (!this.handle) {
- this.handle = this.element;
- }
-
- if (options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
- options.scroll = d.getElement(options.scroll);
- this._isScrollChild = MochiKit.DOM.isChildNode(this.element, options.scroll);
- }
-
- d.makePositioned(this.element); // fix IE
-
- this.delta = this.currentDelta();
- this.options = options;
- this.dragging = false;
-
- this.eventMouseDown = MochiKit.Signal.connect(this.handle,
- 'onmousedown', this, this.initDrag);
- MochiKit.DragAndDrop.Draggables.register(this);
- },
-
- /** @id MochiKit.DragAndDrop.destroy */
- destroy: function () {
- MochiKit.Signal.disconnect(this.eventMouseDown);
- MochiKit.DragAndDrop.Draggables.unregister(this);
- },
-
- /** @id MochiKit.DragAndDrop.currentDelta */
- currentDelta: function () {
- var s = MochiKit.Style.getStyle;
- return [
- parseInt(s(this.element, 'left') || '0'),
- parseInt(s(this.element, 'top') || '0')];
- },
-
- /** @id MochiKit.DragAndDrop.initDrag */
- initDrag: function (event) {
- if (!event.mouse().button.left) {
- return;
- }
- // abort on form elements, fixes a Firefox issue
- var src = event.target();
- var tagName = (src.tagName || '').toUpperCase();
- if (tagName === 'INPUT' || tagName === 'SELECT' ||
- tagName === 'OPTION' || tagName === 'BUTTON' ||
- tagName === 'TEXTAREA') {
- return;
- }
-
- if (this._revert) {
- this._revert.cancel();
- this._revert = null;
- }
-
- var pointer = event.mouse();
- var pos = MochiKit.Position.cumulativeOffset(this.element);
- this.offset = [pointer.page.x - pos.x, pointer.page.y - pos.y]
-
- MochiKit.DragAndDrop.Draggables.activate(this);
- event.stop();
- },
-
- /** @id MochiKit.DragAndDrop.startDrag */
- startDrag: function (event) {
- this.dragging = true;
- if (this.options.selectclass) {
- MochiKit.DOM.addElementClass(this.element,
- this.options.selectclass);
- }
- if (this.options.zindex) {
- this.originalZ = parseInt(MochiKit.Style.getStyle(this.element,
- 'z-index') || '0');
- this.element.style.zIndex = this.options.zindex;
- }
-
- if (this.options.ghosting) {
- this._clone = this.element.cloneNode(true);
- this.ghostPosition = MochiKit.Position.absolutize(this.element);
- this.element.parentNode.insertBefore(this._clone, this.element);
- }
-
- if (this.options.scroll) {
- if (this.options.scroll == window) {
- var where = this._getWindowScroll(this.options.scroll);
- this.originalScrollLeft = where.left;
- this.originalScrollTop = where.top;
- } else {
- this.originalScrollLeft = this.options.scroll.scrollLeft;
- this.originalScrollTop = this.options.scroll.scrollTop;
- }
- }
-
- MochiKit.DragAndDrop.Droppables.prepare(this.element);
- MochiKit.DragAndDrop.Draggables.notify('start', this, event);
- if (this.options.starteffect) {
- this.options.starteffect(this.element);
- }
- },
-
- /** @id MochiKit.DragAndDrop.updateDrag */
- updateDrag: function (event, pointer) {
- if (!this.dragging) {
- this.startDrag(event);
- }
- MochiKit.Position.prepare();
- MochiKit.DragAndDrop.Droppables.show(pointer, this.element);
- MochiKit.DragAndDrop.Draggables.notify('drag', this, event);
- this.draw(pointer);
- this.options.onchange(this);
-
- if (this.options.scroll) {
- this.stopScrolling();
- var p, q;
- if (this.options.scroll == window) {
- var s = this._getWindowScroll(this.options.scroll);
- p = new MochiKit.Style.Coordinates(s.left, s.top);
- q = new MochiKit.Style.Coordinates(s.left + s.width,
- s.top + s.height);
- } else {
- p = MochiKit.Position.page(this.options.scroll);
- p.x += this.options.scroll.scrollLeft;
- p.y += this.options.scroll.scrollTop;
- p.x += (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0);
- p.y += (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0);
- q = new MochiKit.Style.Coordinates(p.x + this.options.scroll.offsetWidth,
- p.y + this.options.scroll.offsetHeight);
- }
- var speed = [0, 0];
- if (pointer.page.x > (q.x - this.options.scrollSensitivity)) {
- speed[0] = pointer.page.x - (q.x - this.options.scrollSensitivity);
- } else if (pointer.page.x < (p.x + this.options.scrollSensitivity)) {
- speed[0] = pointer.page.x - (p.x + this.options.scrollSensitivity);
- }
- if (pointer.page.y > (q.y - this.options.scrollSensitivity)) {
- speed[1] = pointer.page.y - (q.y - this.options.scrollSensitivity);
- } else if (pointer.page.y < (p.y + this.options.scrollSensitivity)) {
- speed[1] = pointer.page.y - (p.y + this.options.scrollSensitivity);
- }
- this.startScrolling(speed);
- }
-
- // fix AppleWebKit rendering
- if (/AppleWebKit'/.test(navigator.appVersion)) {
- window.scrollBy(0, 0);
- }
- event.stop();
- },
-
- /** @id MochiKit.DragAndDrop.finishDrag */
- finishDrag: function (event, success) {
- var dr = MochiKit.DragAndDrop;
- this.dragging = false;
- if (this.options.selectclass) {
- MochiKit.DOM.removeElementClass(this.element,
- this.options.selectclass);
- }
-
- if (this.options.ghosting) {
- // XXX: from a user point of view, it would be better to remove
- // the node only *after* the MochiKit.Visual.Move end when used
- // with revert.
- MochiKit.Position.relativize(this.element, this.ghostPosition);
- MochiKit.DOM.removeElement(this._clone);
- this._clone = null;
- }
-
- if (success) {
- dr.Droppables.fire(event, this.element);
- }
- dr.Draggables.notify('end', this, event);
-
- var revert = this.options.revert;
- if (revert && typeof(revert) == 'function') {
- revert = revert(this.element);
- }
-
- var d = this.currentDelta();
- if (revert && this.options.reverteffect) {
- this._revert = this.options.reverteffect(this.element,
- d[1] - this.delta[1], d[0] - this.delta[0]);
- } else {
- this.delta = d;
- }
-
- if (this.options.zindex) {
- this.element.style.zIndex = this.originalZ;
- }
-
- if (this.options.endeffect) {
- this.options.endeffect(this.element);
- }
-
- dr.Draggables.deactivate();
- dr.Droppables.reset(this.element);
- },
-
- /** @id MochiKit.DragAndDrop.keyPress */
- keyPress: function (event) {
- if (event.key().string != "KEY_ESCAPE") {
- return;
- }
- this.finishDrag(event, false);
- event.stop();
- },
-
- /** @id MochiKit.DragAndDrop.endDrag */
- endDrag: function (event) {
- if (!this.dragging) {
- return;
- }
- this.stopScrolling();
- this.finishDrag(event, true);
- event.stop();
- },
-
- /** @id MochiKit.DragAndDrop.draw */
- draw: function (point) {
- var pos = MochiKit.Position.cumulativeOffset(this.element);
- if (this.options.ghosting) {
- var r = MochiKit.Position.realOffset(this.element);
- pos.x += r.x - MochiKit.Position.windowOffset.x;
- pos.y += r.y - MochiKit.Position.windowOffset.y;
- }
- var d = this.currentDelta();
- pos.x -= d[0];
- pos.y -= d[1];
-
- if (this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
- pos.x -= this.options.scroll.scrollLeft - this.originalScrollLeft;
- pos.y -= this.options.scroll.scrollTop - this.originalScrollTop;
- }
-
- var p = [point.page.x - pos.x - this.offset[0],
- point.page.y - pos.y - this.offset[1]]
-
- if (this.options.snap) {
- if (typeof(this.options.snap) == 'function') {
- p = this.options.snap(p[0], p[1]);
- } else {
- if (this.options.snap instanceof Array) {
- var i = -1;
- p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
- i += 1;
- return Math.round(v/this.options.snap[i]) *
- this.options.snap[i]
- }, this), p)
- } else {
- p = MochiKit.Base.map(MochiKit.Base.bind(function (v) {
- return Math.round(v/this.options.snap) *
- this.options.snap
- }, this), p)
- }
- }
- }
- var style = this.element.style;
- if ((!this.options.constraint) ||
- (this.options.constraint == 'horizontal')) {
- style.left = p[0] + 'px';
- }
- if ((!this.options.constraint) ||
- (this.options.constraint == 'vertical')) {
- style.top = p[1] + 'px';
- }
- if (style.visibility == 'hidden') {
- style.visibility = ''; // fix gecko rendering
- }
- },
-
- /** @id MochiKit.DragAndDrop.stopScrolling */
- stopScrolling: function () {
- if (this.scrollInterval) {
- clearInterval(this.scrollInterval);
- this.scrollInterval = null;
- MochiKit.DragAndDrop.Draggables._lastScrollPointer = null;
- }
- },
-
- /** @id MochiKit.DragAndDrop.startScrolling */
- startScrolling: function (speed) {
- if (!speed[0] && !speed[1]) {
- return;
- }
- this.scrollSpeed = [speed[0] * this.options.scrollSpeed,
- speed[1] * this.options.scrollSpeed];
- this.lastScrolled = new Date();
- this.scrollInterval = setInterval(MochiKit.Base.bind(this.scroll, this), 10);
- },
-
- /** @id MochiKit.DragAndDrop.scroll */
- scroll: function () {
- var current = new Date();
- var delta = current - this.lastScrolled;
- this.lastScrolled = current;
-
- if (this.options.scroll == window) {
- var s = this._getWindowScroll(this.options.scroll);
- if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
- var d = delta / 1000;
- this.options.scroll.scrollTo(s.left + d * this.scrollSpeed[0],
- s.top + d * this.scrollSpeed[1]);
- }
- } else {
- this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
- this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
- }
-
- var d = MochiKit.DragAndDrop;
-
- MochiKit.Position.prepare();
- d.Droppables.show(d.Draggables._lastPointer, this.element);
- d.Draggables.notify('drag', this);
- if (this._isScrollChild) {
- d.Draggables._lastScrollPointer = d.Draggables._lastScrollPointer || d.Draggables._lastPointer;
- d.Draggables._lastScrollPointer.x += this.scrollSpeed[0] * delta / 1000;
- d.Draggables._lastScrollPointer.y += this.scrollSpeed[1] * delta / 1000;
- if (d.Draggables._lastScrollPointer.x < 0) {
- d.Draggables._lastScrollPointer.x = 0;
- }
- if (d.Draggables._lastScrollPointer.y < 0) {
- d.Draggables._lastScrollPointer.y = 0;
- }
- this.draw(d.Draggables._lastScrollPointer);
- }
-
- this.options.onchange(this);
- },
-
- _getWindowScroll: function (w) {
- var vp, w, h;
- MochiKit.DOM.withWindow(w, function () {
- vp = MochiKit.Style.getViewportPosition(w.document);
- });
- if (w.innerWidth) {
- w = w.innerWidth;
- h = w.innerHeight;
- } else if (w.document.documentElement && w.document.documentElement.clientWidth) {
- w = w.document.documentElement.clientWidth;
- h = w.document.documentElement.clientHeight;
- } else {
- w = w.document.body.offsetWidth;
- h = w.document.body.offsetHeight
- }
- return {top: vp.x, left: vp.y, width: w, height: h};
- },
-
- /** @id MochiKit.DragAndDrop.repr */
- repr: function () {
- return '[' + this.__class__.NAME + ", options:" + MochiKit.Base.repr(this.options) + "]";
- }
-};
-
-MochiKit.DragAndDrop.__new__ = function () {
- MochiKit.Base.nameFunctions(this);
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK)
- };
-};
-
-MochiKit.DragAndDrop.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.DragAndDrop);
-
diff --git a/mochitest/MochiKit/Format.js b/mochitest/MochiKit/Format.js
deleted file mode 100644
index 8890bd5..0000000
--- a/mochitest/MochiKit/Format.js
+++ /dev/null
@@ -1,304 +0,0 @@
-/***
-
-MochiKit.Format 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Format');
-}
-
-if (typeof(MochiKit) == 'undefined') {
- MochiKit = {};
-}
-
-if (typeof(MochiKit.Format) == 'undefined') {
- MochiKit.Format = {};
-}
-
-MochiKit.Format.NAME = "MochiKit.Format";
-MochiKit.Format.VERSION = "1.4";
-MochiKit.Format.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-MochiKit.Format.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.Format._numberFormatter = function (placeholder, header, footer, locale, isPercent, precision, leadingZeros, separatorAt, trailingZeros) {
- return function (num) {
- num = parseFloat(num);
- if (typeof(num) == "undefined" || num === null || isNaN(num)) {
- return placeholder;
- }
- var curheader = header;
- var curfooter = footer;
- if (num < 0) {
- num = -num;
- } else {
- curheader = curheader.replace(/-/, "");
- }
- var me = arguments.callee;
- var fmt = MochiKit.Format.formatLocale(locale);
- if (isPercent) {
- num = num * 100.0;
- curfooter = fmt.percent + curfooter;
- }
- num = MochiKit.Format.roundToFixed(num, precision);
- var parts = num.split(/\./);
- var whole = parts[0];
- var frac = (parts.length == 1) ? "" : parts[1];
- var res = "";
- while (whole.length < leadingZeros) {
- whole = "0" + whole;
- }
- if (separatorAt) {
- while (whole.length > separatorAt) {
- var i = whole.length - separatorAt;
- //res = res + fmt.separator + whole.substring(i, whole.length);
- res = fmt.separator + whole.substring(i, whole.length) + res;
- whole = whole.substring(0, i);
- }
- }
- res = whole + res;
- if (precision > 0) {
- while (frac.length < trailingZeros) {
- frac = frac + "0";
- }
- res = res + fmt.decimal + frac;
- }
- return curheader + res + curfooter;
- };
-};
-
-/** @id MochiKit.Format.numberFormatter */
-MochiKit.Format.numberFormatter = function (pattern, placeholder/* = "" */, locale/* = "default" */) {
- // http://java.sun.com/docs/books/tutorial/i18n/format/numberpattern.html
- // | 0 | leading or trailing zeros
- // | # | just the number
- // | , | separator
- // | . | decimal separator
- // | % | Multiply by 100 and format as percent
- if (typeof(placeholder) == "undefined") {
- placeholder = "";
- }
- var match = pattern.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
- if (!match) {
- throw TypeError("Invalid pattern");
- }
- var header = pattern.substr(0, match.index);
- var footer = pattern.substr(match.index + match[0].length);
- if (header.search(/-/) == -1) {
- header = header + "-";
- }
- var whole = match[1];
- var frac = (typeof(match[2]) == "string" && match[2] != "") ? match[2] : "";
- var isPercent = (typeof(match[3]) == "string" && match[3] != "");
- var tmp = whole.split(/,/);
- var separatorAt;
- if (typeof(locale) == "undefined") {
- locale = "default";
- }
- if (tmp.length == 1) {
- separatorAt = null;
- } else {
- separatorAt = tmp[1].length;
- }
- var leadingZeros = whole.length - whole.replace(/0/g, "").length;
- var trailingZeros = frac.length - frac.replace(/0/g, "").length;
- var precision = frac.length;
- var rval = MochiKit.Format._numberFormatter(
- placeholder, header, footer, locale, isPercent, precision,
- leadingZeros, separatorAt, trailingZeros
- );
- var m = MochiKit.Base;
- if (m) {
- var fn = arguments.callee;
- var args = m.concat(arguments);
- rval.repr = function () {
- return [
- self.NAME,
- "(",
- map(m.repr, args).join(", "),
- ")"
- ].join("");
- };
- }
- return rval;
-};
-
-/** @id MochiKit.Format.formatLocale */
-MochiKit.Format.formatLocale = function (locale) {
- if (typeof(locale) == "undefined" || locale === null) {
- locale = "default";
- }
- if (typeof(locale) == "string") {
- var rval = MochiKit.Format.LOCALE[locale];
- if (typeof(rval) == "string") {
- rval = arguments.callee(rval);
- MochiKit.Format.LOCALE[locale] = rval;
- }
- return rval;
- } else {
- return locale;
- }
-};
-
-/** @id MochiKit.Format.twoDigitAverage */
-MochiKit.Format.twoDigitAverage = function (numerator, denominator) {
- if (denominator) {
- var res = numerator / denominator;
- if (!isNaN(res)) {
- return MochiKit.Format.twoDigitFloat(numerator / denominator);
- }
- }
- return "0";
-};
-
-/** @id MochiKit.Format.twoDigitFloat */
-MochiKit.Format.twoDigitFloat = function (someFloat) {
- var sign = (someFloat < 0 ? '-' : '');
- var s = Math.floor(Math.abs(someFloat) * 100).toString();
- if (s == '0') {
- return s;
- }
- if (s.length < 3) {
- while (s.charAt(s.length - 1) == '0') {
- s = s.substring(0, s.length - 1);
- }
- return sign + '0.' + s;
- }
- var head = sign + s.substring(0, s.length - 2);
- var tail = s.substring(s.length - 2, s.length);
- if (tail == '00') {
- return head;
- } else if (tail.charAt(1) == '0') {
- return head + '.' + tail.charAt(0);
- } else {
- return head + '.' + tail;
- }
-};
-
-/** @id MochiKit.Format.lstrip */
-MochiKit.Format.lstrip = function (str, /* optional */chars) {
- str = str + "";
- if (typeof(str) != "string") {
- return null;
- }
- if (!chars) {
- return str.replace(/^\s+/, "");
- } else {
- return str.replace(new RegExp("^[" + chars + "]+"), "");
- }
-};
-
-/** @id MochiKit.Format.rstrip */
-MochiKit.Format.rstrip = function (str, /* optional */chars) {
- str = str + "";
- if (typeof(str) != "string") {
- return null;
- }
- if (!chars) {
- return str.replace(/\s+$/, "");
- } else {
- return str.replace(new RegExp("[" + chars + "]+$"), "");
- }
-};
-
-/** @id MochiKit.Format.strip */
-MochiKit.Format.strip = function (str, /* optional */chars) {
- var self = MochiKit.Format;
- return self.rstrip(self.lstrip(str, chars), chars);
-};
-
-/** @id MochiKit.Format.truncToFixed */
-MochiKit.Format.truncToFixed = function (aNumber, precision) {
- aNumber = Math.floor(aNumber * Math.pow(10, precision));
- var res = (aNumber * Math.pow(10, -precision)).toFixed(precision);
- if (res.charAt(0) == ".") {
- res = "0" + res;
- }
- return res;
-};
-
-/** @id MochiKit.Format.roundToFixed */
-MochiKit.Format.roundToFixed = function (aNumber, precision) {
- return MochiKit.Format.truncToFixed(
- aNumber + 0.5 * Math.pow(10, -precision),
- precision
- );
-};
-
-/** @id MochiKit.Format.percentFormat */
-MochiKit.Format.percentFormat = function (someFloat) {
- return MochiKit.Format.twoDigitFloat(100 * someFloat) + '%';
-};
-
-MochiKit.Format.EXPORT = [
- "truncToFixed",
- "roundToFixed",
- "numberFormatter",
- "formatLocale",
- "twoDigitAverage",
- "twoDigitFloat",
- "percentFormat",
- "lstrip",
- "rstrip",
- "strip"
-];
-
-MochiKit.Format.LOCALE = {
- en_US: {separator: ",", decimal: ".", percent: "%"},
- de_DE: {separator: ".", decimal: ",", percent: "%"},
- fr_FR: {separator: " ", decimal: ",", percent: "%"},
- "default": "en_US"
-};
-
-MochiKit.Format.EXPORT_OK = [];
-MochiKit.Format.EXPORT_TAGS = {
- ':all': MochiKit.Format.EXPORT,
- ':common': MochiKit.Format.EXPORT
-};
-
-MochiKit.Format.__new__ = function () {
- // MochiKit.Base.nameFunctions(this);
- var base = this.NAME + ".";
- var k, v, o;
- for (k in this.LOCALE) {
- o = this.LOCALE[k];
- if (typeof(o) == "object") {
- o.repr = function () { return this.NAME; };
- o.NAME = base + "LOCALE." + k;
- }
- }
- for (k in this) {
- o = this[k];
- if (typeof(o) == 'function' && typeof(o.NAME) == 'undefined') {
- try {
- o.NAME = base + k;
- } catch (e) {
- // pass
- }
- }
- }
-};
-
-MochiKit.Format.__new__();
-
-if (typeof(MochiKit.Base) != "undefined") {
- MochiKit.Base._exportSymbols(this, MochiKit.Format);
-} else {
- (function (globals, module) {
- if ((typeof(JSAN) == 'undefined' && typeof(dojo) == 'undefined')
- || (MochiKit.__export__ === false)) {
- var all = module.EXPORT_TAGS[":all"];
- for (var i = 0; i < all.length; i++) {
- globals[all[i]] = module[all[i]];
- }
- }
- })(this, MochiKit.Format);
-}
diff --git a/mochitest/MochiKit/Iter.js b/mochitest/MochiKit/Iter.js
deleted file mode 100644
index bb3767d..0000000
--- a/mochitest/MochiKit/Iter.js
+++ /dev/null
@@ -1,843 +0,0 @@
-/***
-
-MochiKit.Iter 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Iter');
- dojo.require('MochiKit.Base');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Iter depends on MochiKit.Base!";
-}
-
-if (typeof(MochiKit.Iter) == 'undefined') {
- MochiKit.Iter = {};
-}
-
-MochiKit.Iter.NAME = "MochiKit.Iter";
-MochiKit.Iter.VERSION = "1.4";
-MochiKit.Base.update(MochiKit.Iter, {
- __repr__: function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
- },
- toString: function () {
- return this.__repr__();
- },
-
- /** @id MochiKit.Iter.registerIteratorFactory */
- registerIteratorFactory: function (name, check, iterfactory, /* optional */ override) {
- MochiKit.Iter.iteratorRegistry.register(name, check, iterfactory, override);
- },
-
- /** @id MochiKit.Iter.iter */
- iter: function (iterable, /* optional */ sentinel) {
- var self = MochiKit.Iter;
- if (arguments.length == 2) {
- return self.takewhile(
- function (a) { return a != sentinel; },
- iterable
- );
- }
- if (typeof(iterable.next) == 'function') {
- return iterable;
- } else if (typeof(iterable.iter) == 'function') {
- return iterable.iter();
- /*
- } else if (typeof(iterable.__iterator__) == 'function') {
- //
- // XXX: We can't support JavaScript 1.7 __iterator__ directly
- // because of Object.prototype.__iterator__
- //
- return iterable.__iterator__();
- */
- }
-
- try {
- return self.iteratorRegistry.match(iterable);
- } catch (e) {
- var m = MochiKit.Base;
- if (e == m.NotFound) {
- e = new TypeError(typeof(iterable) + ": " + m.repr(iterable) + " is not iterable");
- }
- throw e;
- }
- },
-
- /** @id MochiKit.Iter.count */
- count: function (n) {
- if (!n) {
- n = 0;
- }
- var m = MochiKit.Base;
- return {
- repr: function () { return "count(" + n + ")"; },
- toString: m.forwardCall("repr"),
- next: m.counter(n)
- };
- },
-
- /** @id MochiKit.Iter.cycle */
- cycle: function (p) {
- var self = MochiKit.Iter;
- var m = MochiKit.Base;
- var lst = [];
- var iterator = self.iter(p);
- return {
- repr: function () { return "cycle(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- try {
- var rval = iterator.next();
- lst.push(rval);
- return rval;
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- if (lst.length === 0) {
- this.next = function () {
- throw self.StopIteration;
- };
- } else {
- var i = -1;
- this.next = function () {
- i = (i + 1) % lst.length;
- return lst[i];
- };
- }
- return this.next();
- }
- }
- };
- },
-
- /** @id MochiKit.Iter.repeat */
- repeat: function (elem, /* optional */n) {
- var m = MochiKit.Base;
- if (typeof(n) == 'undefined') {
- return {
- repr: function () {
- return "repeat(" + m.repr(elem) + ")";
- },
- toString: m.forwardCall("repr"),
- next: function () {
- return elem;
- }
- };
- }
- return {
- repr: function () {
- return "repeat(" + m.repr(elem) + ", " + n + ")";
- },
- toString: m.forwardCall("repr"),
- next: function () {
- if (n <= 0) {
- throw MochiKit.Iter.StopIteration;
- }
- n -= 1;
- return elem;
- }
- };
- },
-
- /** @id MochiKit.Iter.next */
- next: function (iterator) {
- return iterator.next();
- },
-
- /** @id MochiKit.Iter.izip */
- izip: function (p, q/*, ...*/) {
- var m = MochiKit.Base;
- var self = MochiKit.Iter;
- var next = self.next;
- var iterables = m.map(self.iter, arguments);
- return {
- repr: function () { return "izip(...)"; },
- toString: m.forwardCall("repr"),
- next: function () { return m.map(next, iterables); }
- };
- },
-
- /** @id MochiKit.Iter.ifilter */
- ifilter: function (pred, seq) {
- var m = MochiKit.Base;
- seq = MochiKit.Iter.iter(seq);
- if (pred === null) {
- pred = m.operator.truth;
- }
- return {
- repr: function () { return "ifilter(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- while (true) {
- var rval = seq.next();
- if (pred(rval)) {
- return rval;
- }
- }
- // mozilla warnings aren't too bright
- return undefined;
- }
- };
- },
-
- /** @id MochiKit.Iter.ifilterfalse */
- ifilterfalse: function (pred, seq) {
- var m = MochiKit.Base;
- seq = MochiKit.Iter.iter(seq);
- if (pred === null) {
- pred = m.operator.truth;
- }
- return {
- repr: function () { return "ifilterfalse(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- while (true) {
- var rval = seq.next();
- if (!pred(rval)) {
- return rval;
- }
- }
- // mozilla warnings aren't too bright
- return undefined;
- }
- };
- },
-
- /** @id MochiKit.Iter.islice */
- islice: function (seq/*, [start,] stop[, step] */) {
- var self = MochiKit.Iter;
- var m = MochiKit.Base;
- seq = self.iter(seq);
- var start = 0;
- var stop = 0;
- var step = 1;
- var i = -1;
- if (arguments.length == 2) {
- stop = arguments[1];
- } else if (arguments.length == 3) {
- start = arguments[1];
- stop = arguments[2];
- } else {
- start = arguments[1];
- stop = arguments[2];
- step = arguments[3];
- }
- return {
- repr: function () {
- return "islice(" + ["...", start, stop, step].join(", ") + ")";
- },
- toString: m.forwardCall("repr"),
- next: function () {
- var rval;
- while (i < start) {
- rval = seq.next();
- i++;
- }
- if (start >= stop) {
- throw self.StopIteration;
- }
- start += step;
- return rval;
- }
- };
- },
-
- /** @id MochiKit.Iter.imap */
- imap: function (fun, p, q/*, ...*/) {
- var m = MochiKit.Base;
- var self = MochiKit.Iter;
- var iterables = m.map(self.iter, m.extend(null, arguments, 1));
- var map = m.map;
- var next = self.next;
- return {
- repr: function () { return "imap(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- return fun.apply(this, map(next, iterables));
- }
- };
- },
-
- /** @id MochiKit.Iter.applymap */
- applymap: function (fun, seq, self) {
- seq = MochiKit.Iter.iter(seq);
- var m = MochiKit.Base;
- return {
- repr: function () { return "applymap(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- return fun.apply(self, seq.next());
- }
- };
- },
-
- /** @id MochiKit.Iter.chain */
- chain: function (p, q/*, ...*/) {
- // dumb fast path
- var self = MochiKit.Iter;
- var m = MochiKit.Base;
- if (arguments.length == 1) {
- return self.iter(arguments[0]);
- }
- var argiter = m.map(self.iter, arguments);
- return {
- repr: function () { return "chain(...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- while (argiter.length > 1) {
- try {
- return argiter[0].next();
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- argiter.shift();
- }
- }
- if (argiter.length == 1) {
- // optimize last element
- var arg = argiter.shift();
- this.next = m.bind("next", arg);
- return this.next();
- }
- throw self.StopIteration;
- }
- };
- },
-
- /** @id MochiKit.Iter.takewhile */
- takewhile: function (pred, seq) {
- var self = MochiKit.Iter;
- seq = self.iter(seq);
- return {
- repr: function () { return "takewhile(...)"; },
- toString: MochiKit.Base.forwardCall("repr"),
- next: function () {
- var rval = seq.next();
- if (!pred(rval)) {
- this.next = function () {
- throw self.StopIteration;
- };
- this.next();
- }
- return rval;
- }
- };
- },
-
- /** @id MochiKit.Iter.dropwhile */
- dropwhile: function (pred, seq) {
- seq = MochiKit.Iter.iter(seq);
- var m = MochiKit.Base;
- var bind = m.bind;
- return {
- "repr": function () { return "dropwhile(...)"; },
- "toString": m.forwardCall("repr"),
- "next": function () {
- while (true) {
- var rval = seq.next();
- if (!pred(rval)) {
- break;
- }
- }
- this.next = bind("next", seq);
- return rval;
- }
- };
- },
-
- _tee: function (ident, sync, iterable) {
- sync.pos[ident] = -1;
- var m = MochiKit.Base;
- var listMin = m.listMin;
- return {
- repr: function () { return "tee(" + ident + ", ...)"; },
- toString: m.forwardCall("repr"),
- next: function () {
- var rval;
- var i = sync.pos[ident];
-
- if (i == sync.max) {
- rval = iterable.next();
- sync.deque.push(rval);
- sync.max += 1;
- sync.pos[ident] += 1;
- } else {
- rval = sync.deque[i - sync.min];
- sync.pos[ident] += 1;
- if (i == sync.min && listMin(sync.pos) != sync.min) {
- sync.min += 1;
- sync.deque.shift();
- }
- }
- return rval;
- }
- };
- },
-
- /** @id MochiKit.Iter.tee */
- tee: function (iterable, n/* = 2 */) {
- var rval = [];
- var sync = {
- "pos": [],
- "deque": [],
- "max": -1,
- "min": -1
- };
- if (arguments.length == 1 || typeof(n) == "undefined" || n === null) {
- n = 2;
- }
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- var _tee = self._tee;
- for (var i = 0; i < n; i++) {
- rval.push(_tee(i, sync, iterable));
- }
- return rval;
- },
-
- /** @id MochiKit.Iter.list */
- list: function (iterable) {
- // Fast-path for Array and Array-like
- var m = MochiKit.Base;
- if (typeof(iterable.slice) == 'function') {
- return iterable.slice();
- } else if (m.isArrayLike(iterable)) {
- return m.concat(iterable);
- }
-
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- var rval = [];
- try {
- while (true) {
- rval.push(iterable.next());
- }
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- return rval;
- }
- // mozilla warnings aren't too bright
- return undefined;
- },
-
-
- /** @id MochiKit.Iter.reduce */
- reduce: function (fn, iterable, /* optional */initial) {
- var i = 0;
- var x = initial;
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- if (arguments.length < 3) {
- try {
- x = iterable.next();
- } catch (e) {
- if (e == self.StopIteration) {
- e = new TypeError("reduce() of empty sequence with no initial value");
- }
- throw e;
- }
- i++;
- }
- try {
- while (true) {
- x = fn(x, iterable.next());
- }
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- }
- return x;
- },
-
- /** @id MochiKit.Iter.range */
- range: function (/* [start,] stop[, step] */) {
- var start = 0;
- var stop = 0;
- var step = 1;
- if (arguments.length == 1) {
- stop = arguments[0];
- } else if (arguments.length == 2) {
- start = arguments[0];
- stop = arguments[1];
- } else if (arguments.length == 3) {
- start = arguments[0];
- stop = arguments[1];
- step = arguments[2];
- } else {
- throw new TypeError("range() takes 1, 2, or 3 arguments!");
- }
- if (step === 0) {
- throw new TypeError("range() step must not be 0");
- }
- return {
- next: function () {
- if ((step > 0 && start >= stop) || (step < 0 && start <= stop)) {
- throw MochiKit.Iter.StopIteration;
- }
- var rval = start;
- start += step;
- return rval;
- },
- repr: function () {
- return "range(" + [start, stop, step].join(", ") + ")";
- },
- toString: MochiKit.Base.forwardCall("repr")
- };
- },
-
- /** @id MochiKit.Iter.sum */
- sum: function (iterable, start/* = 0 */) {
- if (typeof(start) == "undefined" || start === null) {
- start = 0;
- }
- var x = start;
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- try {
- while (true) {
- x += iterable.next();
- }
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- }
- return x;
- },
-
- /** @id MochiKit.Iter.exhaust */
- exhaust: function (iterable) {
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- try {
- while (true) {
- iterable.next();
- }
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- }
- },
-
- /** @id MochiKit.Iter.forEach */
- forEach: function (iterable, func, /* optional */self) {
- var m = MochiKit.Base;
- if (arguments.length > 2) {
- func = m.bind(func, self);
- }
- // fast path for array
- if (m.isArrayLike(iterable)) {
- try {
- for (var i = 0; i < iterable.length; i++) {
- func(iterable[i]);
- }
- } catch (e) {
- if (e != MochiKit.Iter.StopIteration) {
- throw e;
- }
- }
- } else {
- self = MochiKit.Iter;
- self.exhaust(self.imap(func, iterable));
- }
- },
-
- /** @id MochiKit.Iter.every */
- every: function (iterable, func) {
- var self = MochiKit.Iter;
- try {
- self.ifilterfalse(func, iterable).next();
- return false;
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- return true;
- }
- },
-
- /** @id MochiKit.Iter.sorted */
- sorted: function (iterable, /* optional */cmp) {
- var rval = MochiKit.Iter.list(iterable);
- if (arguments.length == 1) {
- cmp = MochiKit.Base.compare;
- }
- rval.sort(cmp);
- return rval;
- },
-
- /** @id MochiKit.Iter.reversed */
- reversed: function (iterable) {
- var rval = MochiKit.Iter.list(iterable);
- rval.reverse();
- return rval;
- },
-
- /** @id MochiKit.Iter.some */
- some: function (iterable, func) {
- var self = MochiKit.Iter;
- try {
- self.ifilter(func, iterable).next();
- return true;
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- return false;
- }
- },
-
- /** @id MochiKit.Iter.iextend */
- iextend: function (lst, iterable) {
- if (MochiKit.Base.isArrayLike(iterable)) {
- // fast-path for array-like
- for (var i = 0; i < iterable.length; i++) {
- lst.push(iterable[i]);
- }
- } else {
- var self = MochiKit.Iter;
- iterable = self.iter(iterable);
- try {
- while (true) {
- lst.push(iterable.next());
- }
- } catch (e) {
- if (e != self.StopIteration) {
- throw e;
- }
- }
- }
- return lst;
- },
-
- /** @id MochiKit.Iter.groupby */
- groupby: function(iterable, /* optional */ keyfunc) {
- var m = MochiKit.Base;
- var self = MochiKit.Iter;
- if (arguments.length < 2) {
- keyfunc = m.operator.identity;
- }
- iterable = self.iter(iterable);
-
- // shared
- var pk = undefined;
- var k = undefined;
- var v;
-
- function fetch() {
- v = iterable.next();
- k = keyfunc(v);
- };
-
- function eat() {
- var ret = v;
- v = undefined;
- return ret;
- };
-
- var first = true;
- var compare = m.compare;
- return {
- repr: function () { return "groupby(...)"; },
- next: function() {
- // iterator-next
-
- // iterate until meet next group
- while (compare(k, pk) === 0) {
- fetch();
- if (first) {
- first = false;
- break;
- }
- }
- pk = k;
- return [k, {
- next: function() {
- // subiterator-next
- if (v == undefined) { // Is there something to eat?
- fetch();
- }
- if (compare(k, pk) !== 0) {
- throw self.StopIteration;
- }
- return eat();
- }
- }];
- }
- };
- },
-
- /** @id MochiKit.Iter.groupby_as_array */
- groupby_as_array: function (iterable, /* optional */ keyfunc) {
- var m = MochiKit.Base;
- var self = MochiKit.Iter;
- if (arguments.length < 2) {
- keyfunc = m.operator.identity;
- }
-
- iterable = self.iter(iterable);
- var result = [];
- var first = true;
- var prev_key;
- var compare = m.compare;
- while (true) {
- try {
- var value = iterable.next();
- var key = keyfunc(value);
- } catch (e) {
- if (e == self.StopIteration) {
- break;
- }
- throw e;
- }
- if (first || compare(key, prev_key) !== 0) {
- var values = [];
- result.push([key, values]);
- }
- values.push(value);
- first = false;
- prev_key = key;
- }
- return result;
- },
-
- /** @id MochiKit.Iter.arrayLikeIter */
- arrayLikeIter: function (iterable) {
- var i = 0;
- return {
- repr: function () { return "arrayLikeIter(...)"; },
- toString: MochiKit.Base.forwardCall("repr"),
- next: function () {
- if (i >= iterable.length) {
- throw MochiKit.Iter.StopIteration;
- }
- return iterable[i++];
- }
- };
- },
-
- /** @id MochiKit.Iter.hasIterateNext */
- hasIterateNext: function (iterable) {
- return (iterable && typeof(iterable.iterateNext) == "function");
- },
-
- /** @id MochiKit.Iter.iterateNextIter */
- iterateNextIter: function (iterable) {
- return {
- repr: function () { return "iterateNextIter(...)"; },
- toString: MochiKit.Base.forwardCall("repr"),
- next: function () {
- var rval = iterable.iterateNext();
- if (rval === null || rval === undefined) {
- throw MochiKit.Iter.StopIteration;
- }
- return rval;
- }
- };
- }
-});
-
-
-MochiKit.Iter.EXPORT_OK = [
- "iteratorRegistry",
- "arrayLikeIter",
- "hasIterateNext",
- "iterateNextIter",
-];
-
-MochiKit.Iter.EXPORT = [
- "StopIteration",
- "registerIteratorFactory",
- "iter",
- "count",
- "cycle",
- "repeat",
- "next",
- "izip",
- "ifilter",
- "ifilterfalse",
- "islice",
- "imap",
- "applymap",
- "chain",
- "takewhile",
- "dropwhile",
- "tee",
- "list",
- "reduce",
- "range",
- "sum",
- "exhaust",
- "forEach",
- "every",
- "sorted",
- "reversed",
- "some",
- "iextend",
- "groupby",
- "groupby_as_array"
-];
-
-MochiKit.Iter.__new__ = function () {
- var m = MochiKit.Base;
- // Re-use StopIteration if exists (e.g. SpiderMonkey)
- if (typeof(StopIteration) != "undefined") {
- this.StopIteration = StopIteration;
- } else {
- /** @id MochiKit.Iter.StopIteration */
- this.StopIteration = new m.NamedError("StopIteration");
- }
- this.iteratorRegistry = new m.AdapterRegistry();
- // Register the iterator factory for arrays
- this.registerIteratorFactory(
- "arrayLike",
- m.isArrayLike,
- this.arrayLikeIter
- );
-
- this.registerIteratorFactory(
- "iterateNext",
- this.hasIterateNext,
- this.iterateNextIter
- );
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-
-};
-
-MochiKit.Iter.__new__();
-
-//
-// XXX: Internet Explorer blows
-//
-if (MochiKit.__export__) {
- reduce = MochiKit.Iter.reduce;
-}
-
-MochiKit.Base._exportSymbols(this, MochiKit.Iter);
diff --git a/mochitest/MochiKit/LICENSE.txt b/mochitest/MochiKit/LICENSE.txt
deleted file mode 100644
index 4d0065b..0000000
--- a/mochitest/MochiKit/LICENSE.txt
+++ /dev/null
@@ -1,69 +0,0 @@
-MochiKit is dual-licensed software. It is available under the terms of the
-MIT License, or the Academic Free License version 2.1. The full text of
-each license is included below.
-
-MIT License
-===========
-
-Copyright (c) 2005 Bob Ippolito. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-
-Academic Free License v. 2.1
-============================
-
-Copyright (c) 2005 Bob Ippolito. All rights reserved.
-
-This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work:
-
-Licensed under the Academic Free License version 2.1
-
-1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following:
-
-a) to reproduce the Original Work in copies;
-
-b) to prepare derivative works ("Derivative Works") based upon the Original Work;
-
-c) to distribute copies of the Original Work and Derivative Works to the public;
-
-d) to perform the Original Work publicly; and
-
-e) to display the Original Work publicly.
-
-2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works.
-
-3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work.
-
-4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license.
-
-5) This section intentionally omitted.
-
-6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
-
-7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer.
-
-8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You.
-
-9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions.
-
-10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
-
-11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License.
-
-12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
-
-13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
-
-14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
-
-15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
-
-This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner.
-
-
-
diff --git a/mochitest/MochiKit/Logging.js b/mochitest/MochiKit/Logging.js
deleted file mode 100644
index b3aed96..0000000
--- a/mochitest/MochiKit/Logging.js
+++ /dev/null
@@ -1,321 +0,0 @@
-/***
-
-MochiKit.Logging 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Logging');
- dojo.require('MochiKit.Base');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Logging depends on MochiKit.Base!";
-}
-
-if (typeof(MochiKit.Logging) == 'undefined') {
- MochiKit.Logging = {};
-}
-
-MochiKit.Logging.NAME = "MochiKit.Logging";
-MochiKit.Logging.VERSION = "1.4";
-MochiKit.Logging.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-MochiKit.Logging.toString = function () {
- return this.__repr__();
-};
-
-
-MochiKit.Logging.EXPORT = [
- "LogLevel",
- "LogMessage",
- "Logger",
- "alertListener",
- "logger",
- "log",
- "logError",
- "logDebug",
- "logFatal",
- "logWarning"
-];
-
-
-MochiKit.Logging.EXPORT_OK = [
- "logLevelAtLeast",
- "isLogMessage",
- "compareLogMessage"
-];
-
-
-/** @id MochiKit.Logging.LogMessage */
-MochiKit.Logging.LogMessage = function (num, level, info) {
- this.num = num;
- this.level = level;
- this.info = info;
- this.timestamp = new Date();
-};
-
-MochiKit.Logging.LogMessage.prototype = {
- /** @id MochiKit.Logging.LogMessage.prototype.repr */
- repr: function () {
- var m = MochiKit.Base;
- return 'LogMessage(' +
- m.map(
- m.repr,
- [this.num, this.level, this.info]
- ).join(', ') + ')';
- },
- /** @id MochiKit.Logging.LogMessage.prototype.toString */
- toString: MochiKit.Base.forwardCall("repr")
-};
-
-MochiKit.Base.update(MochiKit.Logging, {
- /** @id MochiKit.Logging.logLevelAtLeast */
- logLevelAtLeast: function (minLevel) {
- var self = MochiKit.Logging;
- if (typeof(minLevel) == 'string') {
- minLevel = self.LogLevel[minLevel];
- }
- return function (msg) {
- var msgLevel = msg.level;
- if (typeof(msgLevel) == 'string') {
- msgLevel = self.LogLevel[msgLevel];
- }
- return msgLevel >= minLevel;
- };
- },
-
- /** @id MochiKit.Logging.isLogMessage */
- isLogMessage: function (/* ... */) {
- var LogMessage = MochiKit.Logging.LogMessage;
- for (var i = 0; i < arguments.length; i++) {
- if (!(arguments[i] instanceof LogMessage)) {
- return false;
- }
- }
- return true;
- },
-
- /** @id MochiKit.Logging.compareLogMessage */
- compareLogMessage: function (a, b) {
- return MochiKit.Base.compare([a.level, a.info], [b.level, b.info]);
- },
-
- /** @id MochiKit.Logging.alertListener */
- alertListener: function (msg) {
- alert(
- "num: " + msg.num +
- "\nlevel: " + msg.level +
- "\ninfo: " + msg.info.join(" ")
- );
- }
-
-});
-
-/** @id MochiKit.Logging.Logger */
-MochiKit.Logging.Logger = function (/* optional */maxSize) {
- this.counter = 0;
- if (typeof(maxSize) == 'undefined' || maxSize === null) {
- maxSize = -1;
- }
- this.maxSize = maxSize;
- this._messages = [];
- this.listeners = {};
- this.useNativeConsole = false;
-};
-
-MochiKit.Logging.Logger.prototype = {
- /** @id MochiKit.Logging.Logger.prototype.clear */
- clear: function () {
- this._messages.splice(0, this._messages.length);
- },
-
- /** @id MochiKit.Logging.Logger.prototype.logToConsole */
- logToConsole: function (msg) {
- if (typeof(window) != "undefined" && window.console
- && window.console.log) {
- // Safari and FireBug 0.4
- // Percent replacement is a workaround for cute Safari crashing bug
- window.console.log(msg.replace(/%/g, '\uFF05'));
- } else if (typeof(opera) != "undefined" && opera.postError) {
- // Opera
- opera.postError(msg);
- } else if (typeof(printfire) == "function") {
- // FireBug 0.3 and earlier
- printfire(msg);
- } else if (typeof(Debug) != "undefined" && Debug.writeln) {
- // IE Web Development Helper (?)
- // http://www.nikhilk.net/Entry.aspx?id=93
- Debug.writeln(msg);
- } else if (typeof(debug) != "undefined" && debug.trace) {
- // Atlas framework (?)
- // http://www.nikhilk.net/Entry.aspx?id=93
- debug.trace(msg);
- }
- },
-
- /** @id MochiKit.Logging.Logger.prototype.dispatchListeners */
- dispatchListeners: function (msg) {
- for (var k in this.listeners) {
- var pair = this.listeners[k];
- if (pair.ident != k || (pair[0] && !pair[0](msg))) {
- continue;
- }
- pair[1](msg);
- }
- },
-
- /** @id MochiKit.Logging.Logger.prototype.addListener */
- addListener: function (ident, filter, listener) {
- if (typeof(filter) == 'string') {
- filter = MochiKit.Logging.logLevelAtLeast(filter);
- }
- var entry = [filter, listener];
- entry.ident = ident;
- this.listeners[ident] = entry;
- },
-
- /** @id MochiKit.Logging.Logger.prototype.removeListener */
- removeListener: function (ident) {
- delete this.listeners[ident];
- },
-
- /** @id MochiKit.Logging.Logger.prototype.baseLog */
- baseLog: function (level, message/*, ...*/) {
- var msg = new MochiKit.Logging.LogMessage(
- this.counter,
- level,
- MochiKit.Base.extend(null, arguments, 1)
- );
- this._messages.push(msg);
- this.dispatchListeners(msg);
- if (this.useNativeConsole) {
- this.logToConsole(msg.level + ": " + msg.info.join(" "));
- }
- this.counter += 1;
- while (this.maxSize >= 0 && this._messages.length > this.maxSize) {
- this._messages.shift();
- }
- },
-
- /** @id MochiKit.Logging.Logger.prototype.getMessages */
- getMessages: function (howMany) {
- var firstMsg = 0;
- if (!(typeof(howMany) == 'undefined' || howMany === null)) {
- firstMsg = Math.max(0, this._messages.length - howMany);
- }
- return this._messages.slice(firstMsg);
- },
-
- /** @id MochiKit.Logging.Logger.prototype.getMessageText */
- getMessageText: function (howMany) {
- if (typeof(howMany) == 'undefined' || howMany === null) {
- howMany = 30;
- }
- var messages = this.getMessages(howMany);
- if (messages.length) {
- var lst = map(function (m) {
- return '\n [' + m.num + '] ' + m.level + ': ' + m.info.join(' ');
- }, messages);
- lst.unshift('LAST ' + messages.length + ' MESSAGES:');
- return lst.join('');
- }
- return '';
- },
-
- /** @id MochiKit.Logging.Logger.prototype.debuggingBookmarklet */
- debuggingBookmarklet: function (inline) {
- if (typeof(MochiKit.LoggingPane) == "undefined") {
- alert(this.getMessageText());
- } else {
- MochiKit.LoggingPane.createLoggingPane(inline || false);
- }
- }
-};
-
-MochiKit.Logging.__new__ = function () {
- this.LogLevel = {
- ERROR: 40,
- FATAL: 50,
- WARNING: 30,
- INFO: 20,
- DEBUG: 10
- };
-
- var m = MochiKit.Base;
- m.registerComparator("LogMessage",
- this.isLogMessage,
- this.compareLogMessage
- );
-
- var partial = m.partial;
-
- var Logger = this.Logger;
- var baseLog = Logger.prototype.baseLog;
- m.update(this.Logger.prototype, {
- debug: partial(baseLog, 'DEBUG'),
- log: partial(baseLog, 'INFO'),
- error: partial(baseLog, 'ERROR'),
- fatal: partial(baseLog, 'FATAL'),
- warning: partial(baseLog, 'WARNING')
- });
-
- // indirectly find logger so it can be replaced
- var self = this;
- var connectLog = function (name) {
- return function () {
- self.logger[name].apply(self.logger, arguments);
- };
- };
-
- /** @id MochiKit.Logging.log */
- this.log = connectLog('log');
- /** @id MochiKit.Logging.logError */
- this.logError = connectLog('error');
- /** @id MochiKit.Logging.logDebug */
- this.logDebug = connectLog('debug');
- /** @id MochiKit.Logging.logFatal */
- this.logFatal = connectLog('fatal');
- /** @id MochiKit.Logging.logWarning */
- this.logWarning = connectLog('warning');
- this.logger = new Logger();
- this.logger.useNativeConsole = true;
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-
-};
-
-if (typeof(printfire) == "undefined" &&
- typeof(document) != "undefined" && document.createEvent &&
- typeof(dispatchEvent) != "undefined") {
- // FireBug really should be less lame about this global function
- printfire = function () {
- printfire.args = arguments;
- var ev = document.createEvent("Events");
- ev.initEvent("printfire", false, true);
- dispatchEvent(ev);
- };
-}
-
-MochiKit.Logging.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.Logging);
diff --git a/mochitest/MochiKit/LoggingPane.js b/mochitest/MochiKit/LoggingPane.js
deleted file mode 100644
index 8ecf410..0000000
--- a/mochitest/MochiKit/LoggingPane.js
+++ /dev/null
@@ -1,371 +0,0 @@
-/***
-
-MochiKit.LoggingPane 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.LoggingPane');
- dojo.require('MochiKit.Logging');
- dojo.require('MochiKit.Base');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Logging", []);
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined' || typeof(MochiKit.Logging) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!";
-}
-
-if (typeof(MochiKit.LoggingPane) == 'undefined') {
- MochiKit.LoggingPane = {};
-}
-
-MochiKit.LoggingPane.NAME = "MochiKit.LoggingPane";
-MochiKit.LoggingPane.VERSION = "1.4";
-MochiKit.LoggingPane.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-MochiKit.LoggingPane.toString = function () {
- return this.__repr__();
-};
-
-/** @id MochiKit.LoggingPane.createLoggingPane */
-MochiKit.LoggingPane.createLoggingPane = function (inline/* = false */) {
- var m = MochiKit.LoggingPane;
- inline = !(!inline);
- if (m._loggingPane && m._loggingPane.inline != inline) {
- m._loggingPane.closePane();
- m._loggingPane = null;
- }
- if (!m._loggingPane || m._loggingPane.closed) {
- m._loggingPane = new m.LoggingPane(inline, MochiKit.Logging.logger);
- }
- return m._loggingPane;
-};
-
-/** @id MochiKit.LoggingPane.LoggingPane */
-MochiKit.LoggingPane.LoggingPane = function (inline/* = false */, logger/* = MochiKit.Logging.logger */) {
-
- /* Use a div if inline, pop up a window if not */
- /* Create the elements */
- if (typeof(logger) == "undefined" || logger === null) {
- logger = MochiKit.Logging.logger;
- }
- this.logger = logger;
- var update = MochiKit.Base.update;
- var updatetree = MochiKit.Base.updatetree;
- var bind = MochiKit.Base.bind;
- var clone = MochiKit.Base.clone;
- var win = window;
- var uid = "_MochiKit_LoggingPane";
- if (typeof(MochiKit.DOM) != "undefined") {
- win = MochiKit.DOM.currentWindow();
- }
- if (!inline) {
- // name the popup with the base URL for uniqueness
- var url = win.location.href.split("?")[0].replace(/[#:\/.><&-]/g, "_");
- var name = uid + "_" + url;
- var nwin = win.open("", name, "dependent,resizable,height=200");
- if (!nwin) {
- alert("Not able to open debugging window due to pop-up blocking.");
- return undefined;
- }
- nwin.document.write(
- '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" '
- + '"http://www.w3.org/TR/html4/loose.dtd">'
- + '<html><head><title>[MochiKit.LoggingPane]</title></head>'
- + '<body></body></html>'
- );
- nwin.document.close();
- nwin.document.title += ' ' + win.document.title;
- win = nwin;
- }
- var doc = win.document;
- this.doc = doc;
-
- // Connect to the debug pane if it already exists (i.e. in a window orphaned by the page being refreshed)
- var debugPane = doc.getElementById(uid);
- var existing_pane = !!debugPane;
- if (debugPane && typeof(debugPane.loggingPane) != "undefined") {
- debugPane.loggingPane.logger = this.logger;
- debugPane.loggingPane.buildAndApplyFilter();
- return debugPane.loggingPane;
- }
-
- if (existing_pane) {
- // clear any existing contents
- var child;
- while ((child = debugPane.firstChild)) {
- debugPane.removeChild(child);
- }
- } else {
- debugPane = doc.createElement("div");
- debugPane.id = uid;
- }
- debugPane.loggingPane = this;
- var levelFilterField = doc.createElement("input");
- var infoFilterField = doc.createElement("input");
- var filterButton = doc.createElement("button");
- var loadButton = doc.createElement("button");
- var clearButton = doc.createElement("button");
- var closeButton = doc.createElement("button");
- var logPaneArea = doc.createElement("div");
- var logPane = doc.createElement("div");
-
- /* Set up the functions */
- var listenerId = uid + "_Listener";
- this.colorTable = clone(this.colorTable);
- var messages = [];
- var messageFilter = null;
-
- /** @id MochiKit.LoggingPane.messageLevel */
- var messageLevel = function (msg) {
- var level = msg.level;
- if (typeof(level) == "number") {
- level = MochiKit.Logging.LogLevel[level];
- }
- return level;
- };
-
- /** @id MochiKit.LoggingPane.messageText */
- var messageText = function (msg) {
- return msg.info.join(" ");
- };
-
- /** @id MochiKit.LoggingPane.addMessageText */
- var addMessageText = bind(function (msg) {
- var level = messageLevel(msg);
- var text = messageText(msg);
- var c = this.colorTable[level];
- var p = doc.createElement("span");
- p.className = "MochiKit-LogMessage MochiKit-LogLevel-" + level;
- p.style.cssText = "margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: " + c;
- p.appendChild(doc.createTextNode(level + ": " + text));
- logPane.appendChild(p);
- logPane.appendChild(doc.createElement("br"));
- if (logPaneArea.offsetHeight > logPaneArea.scrollHeight) {
- logPaneArea.scrollTop = 0;
- } else {
- logPaneArea.scrollTop = logPaneArea.scrollHeight;
- }
- }, this);
-
- /** @id MochiKit.LoggingPane.addMessage */
- var addMessage = function (msg) {
- messages[messages.length] = msg;
- addMessageText(msg);
- };
-
- /** @id MochiKit.LoggingPane.buildMessageFilter */
- var buildMessageFilter = function () {
- var levelre, infore;
- try {
- /* Catch any exceptions that might arise due to invalid regexes */
- levelre = new RegExp(levelFilterField.value);
- infore = new RegExp(infoFilterField.value);
- } catch(e) {
- /* If there was an error with the regexes, do no filtering */
- logDebug("Error in filter regex: " + e.message);
- return null;
- }
-
- return function (msg) {
- return (
- levelre.test(messageLevel(msg)) &&
- infore.test(messageText(msg))
- );
- };
- };
-
- /** @id MochiKit.LoggingPane.clearMessagePane */
- var clearMessagePane = function () {
- while (logPane.firstChild) {
- logPane.removeChild(logPane.firstChild);
- }
- };
-
- /** @id MochiKit.LoggingPane.clearMessages */
- var clearMessages = function () {
- messages = [];
- clearMessagePane();
- };
-
- /** @id MochiKit.LoggingPane.closePane */
- var closePane = bind(function () {
- if (this.closed) {
- return;
- }
- this.closed = true;
- if (MochiKit.LoggingPane._loggingPane == this) {
- MochiKit.LoggingPane._loggingPane = null;
- }
- this.logger.removeListener(listenerId);
-
- debugPane.loggingPane = null;
-
- if (inline) {
- debugPane.parentNode.removeChild(debugPane);
- } else {
- this.win.close();
- }
- }, this);
-
- /** @id MochiKit.LoggingPane.filterMessages */
- var filterMessages = function () {
- clearMessagePane();
-
- for (var i = 0; i < messages.length; i++) {
- var msg = messages[i];
- if (messageFilter === null || messageFilter(msg)) {
- addMessageText(msg);
- }
- }
- };
-
- this.buildAndApplyFilter = function () {
- messageFilter = buildMessageFilter();
-
- filterMessages();
-
- this.logger.removeListener(listenerId);
- this.logger.addListener(listenerId, messageFilter, addMessage);
- };
-
-
- /** @id MochiKit.LoggingPane.loadMessages */
- var loadMessages = bind(function () {
- messages = this.logger.getMessages();
- filterMessages();
- }, this);
-
- /** @id MochiKit.LoggingPane.filterOnEnter */
- var filterOnEnter = bind(function (event) {
- event = event || window.event;
- key = event.which || event.keyCode;
- if (key == 13) {
- this.buildAndApplyFilter();
- }
- }, this);
-
- /* Create the debug pane */
- var style = "display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: " + this.logFont;
- if (inline) {
- style += "; height: 10em; border-top: 2px solid black";
- } else {
- style += "; height: 100%;";
- }
- debugPane.style.cssText = style;
-
- if (!existing_pane) {
- doc.body.appendChild(debugPane);
- }
-
- /* Create the filter fields */
- style = {"cssText": "width: 33%; display: inline; font: " + this.logFont};
-
- updatetree(levelFilterField, {
- "value": "FATAL|ERROR|WARNING|INFO|DEBUG",
- "onkeypress": filterOnEnter,
- "style": style
- });
- debugPane.appendChild(levelFilterField);
-
- updatetree(infoFilterField, {
- "value": ".*",
- "onkeypress": filterOnEnter,
- "style": style
- });
- debugPane.appendChild(infoFilterField);
-
- /* Create the buttons */
- style = "width: 8%; display:inline; font: " + this.logFont;
-
- filterButton.appendChild(doc.createTextNode("Filter"));
- filterButton.onclick = bind("buildAndApplyFilter", this);
- filterButton.style.cssText = style;
- debugPane.appendChild(filterButton);
-
- loadButton.appendChild(doc.createTextNode("Load"));
- loadButton.onclick = loadMessages;
- loadButton.style.cssText = style;
- debugPane.appendChild(loadButton);
-
- clearButton.appendChild(doc.createTextNode("Clear"));
- clearButton.onclick = clearMessages;
- clearButton.style.cssText = style;
- debugPane.appendChild(clearButton);
-
- closeButton.appendChild(doc.createTextNode("Close"));
- closeButton.onclick = closePane;
- closeButton.style.cssText = style;
- debugPane.appendChild(closeButton);
-
- /* Create the logging pane */
- logPaneArea.style.cssText = "overflow: auto; width: 100%";
- logPane.style.cssText = "width: 100%; height: " + (inline ? "8em" : "100%");
-
- logPaneArea.appendChild(logPane);
- debugPane.appendChild(logPaneArea);
-
- this.buildAndApplyFilter();
- loadMessages();
-
- if (inline) {
- this.win = undefined;
- } else {
- this.win = win;
- }
- this.inline = inline;
- this.closePane = closePane;
- this.closed = false;
-
- return this;
-};
-
-MochiKit.LoggingPane.LoggingPane.prototype = {
- "logFont": "8pt Verdana,sans-serif",
- "colorTable": {
- "ERROR": "red",
- "FATAL": "darkred",
- "WARNING": "blue",
- "INFO": "black",
- "DEBUG": "green"
- }
-};
-
-
-MochiKit.LoggingPane.EXPORT_OK = [
- "LoggingPane"
-];
-
-MochiKit.LoggingPane.EXPORT = [
- "createLoggingPane"
-];
-
-MochiKit.LoggingPane.__new__ = function () {
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": MochiKit.Base.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- MochiKit.Base.nameFunctions(this);
-
- MochiKit.LoggingPane._loggingPane = null;
-
-};
-
-MochiKit.LoggingPane.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.LoggingPane);
diff --git a/mochitest/MochiKit/MochiKit.js b/mochitest/MochiKit/MochiKit.js
deleted file mode 100644
index d0935e3..0000000
--- a/mochitest/MochiKit/MochiKit.js
+++ /dev/null
@@ -1,152 +0,0 @@
-/***
-
-MochiKit.MochiKit 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(MochiKit) == 'undefined') {
- MochiKit = {};
-}
-
-if (typeof(MochiKit.MochiKit) == 'undefined') {
- /** @id MochiKit.MochiKit */
- MochiKit.MochiKit = {};
-}
-
-MochiKit.MochiKit.NAME = "MochiKit.MochiKit";
-MochiKit.MochiKit.VERSION = "1.4";
-MochiKit.MochiKit.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-/** @id MochiKit.MochiKit.toString */
-MochiKit.MochiKit.toString = function () {
- return this.__repr__();
-};
-
-/** @id MochiKit.MochiKit.SUBMODULES */
-MochiKit.MochiKit.SUBMODULES = [
- "Base",
- "Iter",
- "Logging",
- "DateTime",
- "Format",
- "Async",
- "DOM",
- "Style",
- "LoggingPane",
- "Color",
- "Signal",
- "Visual"
-];
-
-if (typeof(JSAN) != 'undefined' || typeof(dojo) != 'undefined') {
- if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.MochiKit');
- dojo.require("MochiKit.*");
- }
- if (typeof(JSAN) != 'undefined') {
- (function (lst) {
- for (var i = 0; i < lst.length; i++) {
- JSAN.use("MochiKit." + lst[i], []);
- }
- })(MochiKit.MochiKit.SUBMODULES);
- }
- (function () {
- var extend = MochiKit.Base.extend;
- var self = MochiKit.MochiKit;
- var modules = self.SUBMODULES;
- var EXPORT = [];
- var EXPORT_OK = [];
- var EXPORT_TAGS = {};
- var i, k, m, all;
- for (i = 0; i < modules.length; i++) {
- m = MochiKit[modules[i]];
- extend(EXPORT, m.EXPORT);
- extend(EXPORT_OK, m.EXPORT_OK);
- for (k in m.EXPORT_TAGS) {
- EXPORT_TAGS[k] = extend(EXPORT_TAGS[k], m.EXPORT_TAGS[k]);
- }
- all = m.EXPORT_TAGS[":all"];
- if (!all) {
- all = extend(null, m.EXPORT, m.EXPORT_OK);
- }
- var j;
- for (j = 0; j < all.length; j++) {
- k = all[j];
- self[k] = m[k];
- }
- }
- self.EXPORT = EXPORT;
- self.EXPORT_OK = EXPORT_OK;
- self.EXPORT_TAGS = EXPORT_TAGS;
- }());
-
-} else {
- if (typeof(MochiKit.__compat__) == 'undefined') {
- MochiKit.__compat__ = true;
- }
- (function () {
- if (typeof(document) == "undefined") {
- return;
- }
- var scripts = document.getElementsByTagName("script");
- var kXULNSURI = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var base = null;
- var baseElem = null;
- var allScripts = {};
- var i;
- for (i = 0; i < scripts.length; i++) {
- var src = scripts[i].getAttribute("src");
- if (!src) {
- continue;
- }
- allScripts[src] = true;
- if (src.match(/MochiKit.js$/)) {
- base = src.substring(0, src.lastIndexOf('MochiKit.js'));
- baseElem = scripts[i];
- }
- }
- if (base === null) {
- return;
- }
- var modules = MochiKit.MochiKit.SUBMODULES;
- for (var i = 0; i < modules.length; i++) {
- if (MochiKit[modules[i]]) {
- continue;
- }
- var uri = base + modules[i] + '.js';
- if (uri in allScripts) {
- continue;
- }
- if (document.documentElement &&
- document.documentElement.namespaceURI == kXULNSURI) {
- // XUL
- var s = document.createElementNS(kXULNSURI, 'script');
- s.setAttribute("id", "MochiKit_" + base + modules[i]);
- s.setAttribute("src", uri);
- s.setAttribute("type", "application/x-javascript");
- baseElem.parentNode.appendChild(s);
- } else {
- // HTML
- /*
- DOM can not be used here because Safari does
- deferred loading of scripts unless they are
- in the document or inserted with document.write
-
- This is not XHTML compliant. If you want XHTML
- compliance then you must use the packed version of MochiKit
- or include each script individually (basically unroll
- these document.write calls into your XHTML source)
-
- */
- document.write('<script src="' + uri +
- '" type="text/javascript"></script>');
- }
- };
- })();
-}
diff --git a/mochitest/MochiKit/MockDOM.js b/mochitest/MochiKit/MockDOM.js
deleted file mode 100644
index 3f8654a..0000000
--- a/mochitest/MochiKit/MockDOM.js
+++ /dev/null
@@ -1,100 +0,0 @@
-/***
-
-MochiKit.MockDOM 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(MochiKit) == "undefined") {
- MochiKit = {};
-}
-
-if (typeof(MochiKit.MockDOM) == "undefined") {
- MochiKit.MockDOM = {};
-}
-
-MochiKit.MockDOM.NAME = "MochiKit.MockDOM";
-MochiKit.MockDOM.VERSION = "1.4";
-
-MochiKit.MockDOM.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-/** @id MochiKit.MockDOM.toString */
-MochiKit.MockDOM.toString = function () {
- return this.__repr__();
-};
-
-/** @id MochiKit.MockDOM.createDocument */
-MochiKit.MockDOM.createDocument = function () {
- var doc = new MochiKit.MockDOM.MockElement("DOCUMENT");
- doc.body = doc.createElement("BODY");
- doc.appendChild(doc.body);
- return doc;
-};
-
-/** @id MochiKit.MockDOM.MockElement */
-MochiKit.MockDOM.MockElement = function (name, data) {
- this.tagName = this.nodeName = name.toUpperCase();
- if (typeof(data) == "string") {
- this.nodeValue = data;
- this.nodeType = 3;
- } else {
- this.nodeType = 1;
- this.childNodes = [];
- }
- if (name.substring(0, 1) == "<") {
- var nameattr = name.substring(
- name.indexOf('"') + 1, name.lastIndexOf('"'));
- name = name.substring(1, name.indexOf(" "));
- this.tagName = this.nodeName = name.toUpperCase();
- this.setAttribute("name", nameattr);
- }
-};
-
-MochiKit.MockDOM.MockElement.prototype = {
- /** @id MochiKit.MockDOM.MockElement.prototype.createElement */
- createElement: function (tagName) {
- return new MochiKit.MockDOM.MockElement(tagName);
- },
- /** @id MochiKit.MockDOM.MockElement.prototype.createTextNode */
- createTextNode: function (text) {
- return new MochiKit.MockDOM.MockElement("text", text);
- },
- /** @id MochiKit.MockDOM.MockElement.prototype.setAttribute */
- setAttribute: function (name, value) {
- this[name] = value;
- },
- /** @id MochiKit.MockDOM.MockElement.prototype.getAttribute */
- getAttribute: function (name) {
- return this[name];
- },
- /** @id MochiKit.MockDOM.MockElement.prototype.appendChild */
- appendChild: function (child) {
- this.childNodes.push(child);
- },
- /** @id MochiKit.MockDOM.MockElement.prototype.toString */
- toString: function () {
- return "MockElement(" + this.tagName + ")";
- }
-};
-
- /** @id MochiKit.MockDOM.EXPORT_OK */
-MochiKit.MockDOM.EXPORT_OK = [
- "mockElement",
- "createDocument"
-];
-
- /** @id MochiKit.MockDOM.EXPORT */
-MochiKit.MockDOM.EXPORT = [
- "document"
-];
-
-MochiKit.MockDOM.__new__ = function () {
- this.document = this.createDocument();
-};
-
-MochiKit.MockDOM.__new__();
diff --git a/mochitest/MochiKit/New.js b/mochitest/MochiKit/New.js
deleted file mode 100644
index 529f1e7..0000000
--- a/mochitest/MochiKit/New.js
+++ /dev/null
@@ -1,283 +0,0 @@
-
-MochiKit.Base.update(MochiKit.DOM, {
- /** @id MochiKit.DOM.makeClipping */
- makeClipping: function (element) {
- element = MochiKit.DOM.getElement(element);
- var oldOverflow = element.style.overflow;
- if ((MochiKit.Style.getStyle(element, 'overflow') || 'visible') != 'hidden') {
- element.style.overflow = 'hidden';
- }
- return oldOverflow;
- },
-
- /** @id MochiKit.DOM.undoClipping */
- undoClipping: function (element, overflow) {
- element = MochiKit.DOM.getElement(element);
- if (!overflow) {
- return;
- }
- element.style.overflow = overflow;
- },
-
- /** @id MochiKit.DOM.makePositioned */
- makePositioned: function (element) {
- element = MochiKit.DOM.getElement(element);
- var pos = MochiKit.Style.getStyle(element, 'position');
- if (pos == 'static' || !pos) {
- element.style.position = 'relative';
- // Opera returns the offset relative to the positioning context,
- // when an element is position relative but top and left have
- // not been defined
- if (/Opera/.test(navigator.userAgent)) {
- element.style.top = 0;
- element.style.left = 0;
- }
- }
- },
-
- /** @id MochiKit.DOM.undoPositioned */
- undoPositioned: function (element) {
- element = MochiKit.DOM.getElement(element);
- if (element.style.position == 'relative') {
- element.style.position = element.style.top = element.style.left = element.style.bottom = element.style.right = '';
- }
- },
-
- /** @id MochiKit.DOM.getFirstElementByTagAndClassName */
- getFirstElementByTagAndClassName: function (tagName, className,
- /* optional */parent) {
- var self = MochiKit.DOM;
- if (typeof(tagName) == 'undefined' || tagName === null) {
- tagName = '*';
- }
- if (typeof(parent) == 'undefined' || parent === null) {
- parent = self._document;
- }
- parent = self.getElement(parent);
- var children = (parent.getElementsByTagName(tagName)
- || self._document.all);
- if (typeof(className) == 'undefined' || className === null) {
- return children[0];
- }
-
- for (var i = 0; i < children.length; i++) {
- var child = children[i];
- var classNames = child.className.split(' ');
- for (var j = 0; j < classNames.length; j++) {
- if (classNames[j] == className) {
- return child;
- }
- }
- }
- },
-
- /** @id MochiKit.DOM.isParent */
- isParent: function (child, element) {
- if (!child.parentNode || child == element) {
- return false;
- }
-
- if (child.parentNode == element) {
- return true;
- }
-
- return MochiKit.DOM.isParent(child.parentNode, element);
- }
-});
-
-MochiKit.Position = {
- // set to true if needed, warning: firefox performance problems
- // NOT neeeded for page scrolling, only if draggable contained in
- // scrollable elements
- includeScrollOffsets: false,
-
- /** @id MochiKit.Position.prepare */
- prepare: function () {
- var deltaX = window.pageXOffset
- || document.documentElement.scrollLeft
- || document.body.scrollLeft
- || 0;
- var deltaY = window.pageYOffset
- || document.documentElement.scrollTop
- || document.body.scrollTop
- || 0;
- this.windowOffset = new MochiKit.Style.Coordinates(deltaX, deltaY);
- },
-
- /** @id MochiKit.Position.cumulativeOffset */
- cumulativeOffset: function (element) {
- var valueT = 0;
- var valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- } while (element);
- return new MochiKit.Style.Coordinates(valueL, valueT);
- },
-
- /** @id MochiKit.Position.realOffset */
- realOffset: function (element) {
- var valueT = 0;
- var valueL = 0;
- do {
- valueT += element.scrollTop || 0;
- valueL += element.scrollLeft || 0;
- element = element.parentNode;
- } while (element);
- return new MochiKit.Style.Coordinates(valueL, valueT);
- },
-
- /** @id MochiKit.Position.within */
- within: function (element, x, y) {
- if (this.includeScrollOffsets) {
- return this.withinIncludingScrolloffsets(element, x, y);
- }
- this.xcomp = x;
- this.ycomp = y;
- this.offset = this.cumulativeOffset(element);
- if (element.style.position == "fixed") {
- this.offset.x += this.windowOffset.x;
- this.offset.y += this.windowOffset.y;
- }
-
- return (y >= this.offset.y &&
- y < this.offset.y + element.offsetHeight &&
- x >= this.offset.x &&
- x < this.offset.x + element.offsetWidth);
- },
-
- /** @id MochiKit.Position.withinIncludingScrolloffsets */
- withinIncludingScrolloffsets: function (element, x, y) {
- var offsetcache = this.realOffset(element);
-
- this.xcomp = x + offsetcache.x - this.windowOffset.x;
- this.ycomp = y + offsetcache.y - this.windowOffset.y;
- this.offset = this.cumulativeOffset(element);
-
- return (this.ycomp >= this.offset.y &&
- this.ycomp < this.offset.y + element.offsetHeight &&
- this.xcomp >= this.offset.x &&
- this.xcomp < this.offset.x + element.offsetWidth);
- },
-
- // within must be called directly before
- /** @id MochiKit.Position.overlap */
- overlap: function (mode, element) {
- if (!mode) {
- return 0;
- }
- if (mode == 'vertical') {
- return ((this.offset.y + element.offsetHeight) - this.ycomp) /
- element.offsetHeight;
- }
- if (mode == 'horizontal') {
- return ((this.offset.x + element.offsetWidth) - this.xcomp) /
- element.offsetWidth;
- }
- },
-
- /** @id MochiKit.Position.absolutize */
- absolutize: function (element) {
- element = MochiKit.DOM.getElement(element);
- if (element.style.position == 'absolute') {
- return;
- }
- MochiKit.Position.prepare();
-
- var offsets = MochiKit.Position.positionedOffset(element);
- var width = element.clientWidth;
- var height = element.clientHeight;
-
- var oldStyle = {
- 'position': element.style.position,
- 'left': offsets.x - parseFloat(element.style.left || 0),
- 'top': offsets.y - parseFloat(element.style.top || 0),
- 'width': element.style.width,
- 'height': element.style.height
- };
-
- element.style.position = 'absolute';
- element.style.top = offsets.y + 'px';
- element.style.left = offsets.x + 'px';
- element.style.width = width + 'px';
- element.style.height = height + 'px';
-
- return oldStyle;
- },
-
- /** @id MochiKit.Position.positionedOffset */
- positionedOffset: function (element) {
- var valueT = 0, valueL = 0;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
- element = element.offsetParent;
- if (element) {
- p = MochiKit.Style.getStyle(element, 'position');
- if (p == 'relative' || p == 'absolute') {
- break;
- }
- }
- } while (element);
- return new MochiKit.Style.Coordinates(valueL, valueT);
- },
-
- /** @id MochiKit.Position.relativize */
- relativize: function (element, oldPos) {
- element = MochiKit.DOM.getElement(element);
- if (element.style.position == 'relative') {
- return;
- }
- MochiKit.Position.prepare();
-
- var top = parseFloat(element.style.top || 0) -
- (oldPos['top'] || 0);
- var left = parseFloat(element.style.left || 0) -
- (oldPos['left'] || 0);
-
- element.style.position = oldPos['position'];
- element.style.top = top + 'px';
- element.style.left = left + 'px';
- element.style.width = oldPos['width'];
- element.style.height = oldPos['height'];
- },
-
- /** @id MochiKit.Position.clone */
- clone: function (source, target) {
- source = MochiKit.DOM.getElement(source);
- target = MochiKit.DOM.getElement(target);
- target.style.position = 'absolute';
- var offsets = this.cumulativeOffset(source);
- target.style.top = offsets.y + 'px';
- target.style.left = offsets.x + 'px';
- target.style.width = source.offsetWidth + 'px';
- target.style.height = source.offsetHeight + 'px';
- },
-
- /** @id MochiKit.Position.page */
- page: function (forElement) {
- var valueT = 0;
- var valueL = 0;
-
- var element = forElement;
- do {
- valueT += element.offsetTop || 0;
- valueL += element.offsetLeft || 0;
-
- // Safari fix
- if (element.offsetParent == document.body && MochiKit.Style.getStyle(element, 'position') == 'absolute') {
- break;
- }
- } while (element = element.offsetParent);
-
- element = forElement;
- do {
- valueT -= element.scrollTop || 0;
- valueL -= element.scrollLeft || 0;
- } while (element = element.parentNode);
-
- return new MochiKit.Style.Coordinates(valueL, valueT);
- }
-};
-
diff --git a/mochitest/MochiKit/Signal.js b/mochitest/MochiKit/Signal.js
deleted file mode 100644
index 74199c1..0000000
--- a/mochitest/MochiKit/Signal.js
+++ /dev/null
@@ -1,857 +0,0 @@
-/***
-
-MochiKit.Signal 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2006 Jonathan Gardner, Beau Hartshorne, Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Signal');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Style');
-}
-if (typeof(JSAN) != 'undefined') {
- JSAN.use('MochiKit.Base', []);
- JSAN.use('MochiKit.DOM', []);
- JSAN.use('MochiKit.Style', []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw '';
- }
-} catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.Base!';
-}
-
-try {
- if (typeof(MochiKit.DOM) == 'undefined') {
- throw '';
- }
-} catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.DOM!';
-}
-
-try {
- if (typeof(MochiKit.Style) == 'undefined') {
- throw '';
- }
-} catch (e) {
- throw 'MochiKit.Signal depends on MochiKit.Style!';
-}
-
-if (typeof(MochiKit.Signal) == 'undefined') {
- MochiKit.Signal = {};
-}
-
-MochiKit.Signal.NAME = 'MochiKit.Signal';
-MochiKit.Signal.VERSION = '1.4';
-
-MochiKit.Signal._observers = [];
-
-/** @id MochiKit.Signal.Event */
-MochiKit.Signal.Event = function (src, e) {
- this._event = e || window.event;
- this._src = src;
-};
-
-MochiKit.Base.update(MochiKit.Signal.Event.prototype, {
-
- __repr__: function () {
- var repr = MochiKit.Base.repr;
- var str = '{event(): ' + repr(this.event()) +
- ', src(): ' + repr(this.src()) +
- ', type(): ' + repr(this.type()) +
- ', target(): ' + repr(this.target()) +
- ', modifier(): ' + '{alt: ' + repr(this.modifier().alt) +
- ', ctrl: ' + repr(this.modifier().ctrl) +
- ', meta: ' + repr(this.modifier().meta) +
- ', shift: ' + repr(this.modifier().shift) +
- ', any: ' + repr(this.modifier().any) + '}';
-
- if (this.type() && this.type().indexOf('key') === 0) {
- str += ', key(): {code: ' + repr(this.key().code) +
- ', string: ' + repr(this.key().string) + '}';
- }
-
- if (this.type() && (
- this.type().indexOf('mouse') === 0 ||
- this.type().indexOf('click') != -1 ||
- this.type() == 'contextmenu')) {
-
- str += ', mouse(): {page: ' + repr(this.mouse().page) +
- ', client: ' + repr(this.mouse().client);
-
- if (this.type() != 'mousemove') {
- str += ', button: {left: ' + repr(this.mouse().button.left) +
- ', middle: ' + repr(this.mouse().button.middle) +
- ', right: ' + repr(this.mouse().button.right) + '}}';
- } else {
- str += '}';
- }
- }
- if (this.type() == 'mouseover' || this.type() == 'mouseout') {
- str += ', relatedTarget(): ' + repr(this.relatedTarget());
- }
- str += '}';
- return str;
- },
-
- /** @id MochiKit.Signal.Event.prototype.toString */
- toString: function () {
- return this.__repr__();
- },
-
- /** @id MochiKit.Signal.Event.prototype.src */
- src: function () {
- return this._src;
- },
-
- /** @id MochiKit.Signal.Event.prototype.event */
- event: function () {
- return this._event;
- },
-
- /** @id MochiKit.Signal.Event.prototype.type */
- type: function () {
- return this._event.type || undefined;
- },
-
- /** @id MochiKit.Signal.Event.prototype.target */
- target: function () {
- return this._event.target || this._event.srcElement;
- },
-
- _relatedTarget: null,
- /** @id MochiKit.Signal.Event.prototype.relatedTarget */
- relatedTarget: function () {
- if (this._relatedTarget !== null) {
- return this._relatedTarget;
- }
-
- var elem = null;
- if (this.type() == 'mouseover') {
- elem = (this._event.relatedTarget ||
- this._event.fromElement);
- } else if (this.type() == 'mouseout') {
- elem = (this._event.relatedTarget ||
- this._event.toElement);
- }
- if (elem !== null) {
- this._relatedTarget = elem;
- return elem;
- }
-
- return undefined;
- },
-
- _modifier: null,
- /** @id MochiKit.Signal.Event.prototype.modifier */
- modifier: function () {
- if (this._modifier !== null) {
- return this._modifier;
- }
- var m = {};
- m.alt = this._event.altKey;
- m.ctrl = this._event.ctrlKey;
- m.meta = this._event.metaKey || false; // IE and Opera punt here
- m.shift = this._event.shiftKey;
- m.any = m.alt || m.ctrl || m.shift || m.meta;
- this._modifier = m;
- return m;
- },
-
- _key: null,
- /** @id MochiKit.Signal.Event.prototype.key */
- key: function () {
- if (this._key !== null) {
- return this._key;
- }
- var k = {};
- if (this.type() && this.type().indexOf('key') === 0) {
-
- /*
-
- If you're looking for a special key, look for it in keydown or
- keyup, but never keypress. If you're looking for a Unicode
- chracter, look for it with keypress, but never keyup or
- keydown.
-
- Notes:
-
- FF key event behavior:
- key event charCode keyCode
- DOWN ku,kd 0 40
- DOWN kp 0 40
- ESC ku,kd 0 27
- ESC kp 0 27
- a ku,kd 0 65
- a kp 97 0
- shift+a ku,kd 0 65
- shift+a kp 65 0
- 1 ku,kd 0 49
- 1 kp 49 0
- shift+1 ku,kd 0 0
- shift+1 kp 33 0
-
- IE key event behavior:
- (IE doesn't fire keypress events for special keys.)
- key event keyCode
- DOWN ku,kd 40
- DOWN kp undefined
- ESC ku,kd 27
- ESC kp 27
- a ku,kd 65
- a kp 97
- shift+a ku,kd 65
- shift+a kp 65
- 1 ku,kd 49
- 1 kp 49
- shift+1 ku,kd 49
- shift+1 kp 33
-
- Safari key event behavior:
- (Safari sets charCode and keyCode to something crazy for
- special keys.)
- key event charCode keyCode
- DOWN ku,kd 63233 40
- DOWN kp 63233 63233
- ESC ku,kd 27 27
- ESC kp 27 27
- a ku,kd 97 65
- a kp 97 97
- shift+a ku,kd 65 65
- shift+a kp 65 65
- 1 ku,kd 49 49
- 1 kp 49 49
- shift+1 ku,kd 33 49
- shift+1 kp 33 33
-
- */
-
- /* look for special keys here */
- if (this.type() == 'keydown' || this.type() == 'keyup') {
- k.code = this._event.keyCode;
- k.string = (MochiKit.Signal._specialKeys[k.code] ||
- 'KEY_UNKNOWN');
- this._key = k;
- return k;
-
- /* look for characters here */
- } else if (this.type() == 'keypress') {
-
- /*
-
- Special key behavior:
-
- IE: does not fire keypress events for special keys
- FF: sets charCode to 0, and sets the correct keyCode
- Safari: sets keyCode and charCode to something stupid
-
- */
-
- k.code = 0;
- k.string = '';
-
- if (typeof(this._event.charCode) != 'undefined' &&
- this._event.charCode !== 0 &&
- !MochiKit.Signal._specialMacKeys[this._event.charCode]) {
- k.code = this._event.charCode;
- k.string = String.fromCharCode(k.code);
- } else if (this._event.keyCode &&
- typeof(this._event.charCode) == 'undefined') { // IE
- k.code = this._event.keyCode;
- k.string = String.fromCharCode(k.code);
- }
-
- this._key = k;
- return k;
- }
- }
- return undefined;
- },
-
- _mouse: null,
- /** @id MochiKit.Signal.Event.prototype.mouse */
- mouse: function () {
- if (this._mouse !== null) {
- return this._mouse;
- }
-
- var m = {};
- var e = this._event;
-
- if (this.type() && (
- this.type().indexOf('mouse') === 0 ||
- this.type().indexOf('click') != -1 ||
- this.type() == 'contextmenu')) {
-
- m.client = new MochiKit.Style.Coordinates(0, 0);
- if (e.clientX || e.clientY) {
- m.client.x = (!e.clientX || e.clientX < 0) ? 0 : e.clientX;
- m.client.y = (!e.clientY || e.clientY < 0) ? 0 : e.clientY;
- }
-
- m.page = new MochiKit.Style.Coordinates(0, 0);
- if (e.pageX || e.pageY) {
- m.page.x = (!e.pageX || e.pageX < 0) ? 0 : e.pageX;
- m.page.y = (!e.pageY || e.pageY < 0) ? 0 : e.pageY;
- } else {
- /*
-
- The IE shortcut can be off by two. We fix it. See:
- http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
-
- This is similar to the method used in
- MochiKit.Style.getElementPosition().
-
- */
- var de = MochiKit.DOM._document.documentElement;
- var b = MochiKit.DOM._document.body;
-
- m.page.x = e.clientX +
- (de.scrollLeft || b.scrollLeft) -
- (de.clientLeft || 0);
-
- m.page.y = e.clientY +
- (de.scrollTop || b.scrollTop) -
- (de.clientTop || 0);
-
- }
- if (this.type() != 'mousemove') {
- m.button = {};
- m.button.left = false;
- m.button.right = false;
- m.button.middle = false;
-
- /* we could check e.button, but which is more consistent */
- if (e.which) {
- m.button.left = (e.which == 1);
- m.button.middle = (e.which == 2);
- m.button.right = (e.which == 3);
-
- /*
-
- Mac browsers and right click:
-
- - Safari doesn't fire any click events on a right
- click:
- http://bugzilla.opendarwin.org/show_bug.cgi?id=6595
-
- - Firefox fires the event, and sets ctrlKey = true
-
- - Opera fires the event, and sets metaKey = true
-
- oncontextmenu is fired on right clicks between
- browsers and across platforms.
-
- */
-
- } else {
- m.button.left = !!(e.button & 1);
- m.button.right = !!(e.button & 2);
- m.button.middle = !!(e.button & 4);
- }
- }
- this._mouse = m;
- return m;
- }
- return undefined;
- },
-
- /** @id MochiKit.Signal.Event.prototype.stop */
- stop: function () {
- this.stopPropagation();
- this.preventDefault();
- },
-
- /** @id MochiKit.Signal.Event.prototype.stopPropagation */
- stopPropagation: function () {
- if (this._event.stopPropagation) {
- this._event.stopPropagation();
- } else {
- this._event.cancelBubble = true;
- }
- },
-
- /** @id MochiKit.Signal.Event.prototype.preventDefault */
- preventDefault: function () {
- if (this._event.preventDefault) {
- this._event.preventDefault();
- } else if (this._confirmUnload === null) {
- this._event.returnValue = false;
- }
- },
-
- _confirmUnload: null,
-
- /** @id MochiKit.Signal.Event.prototype.confirmUnload */
- confirmUnload: function (msg) {
- if (this.type() == 'beforeunload') {
- this._confirmUnload = msg;
- this._event.returnValue = msg;
- }
- }
-});
-
-/* Safari sets keyCode to these special values onkeypress. */
-MochiKit.Signal._specialMacKeys = {
- 3: 'KEY_ENTER',
- 63289: 'KEY_NUM_PAD_CLEAR',
- 63276: 'KEY_PAGE_UP',
- 63277: 'KEY_PAGE_DOWN',
- 63275: 'KEY_END',
- 63273: 'KEY_HOME',
- 63234: 'KEY_ARROW_LEFT',
- 63232: 'KEY_ARROW_UP',
- 63235: 'KEY_ARROW_RIGHT',
- 63233: 'KEY_ARROW_DOWN',
- 63302: 'KEY_INSERT',
- 63272: 'KEY_DELETE'
-};
-
-/* for KEY_F1 - KEY_F12 */
-(function () {
- var _specialMacKeys = MochiKit.Signal._specialMacKeys;
- for (i = 63236; i <= 63242; i++) {
- // no F0
- _specialMacKeys[i] = 'KEY_F' + (i - 63236 + 1);
- }
-})();
-
-/* Standard keyboard key codes. */
-MochiKit.Signal._specialKeys = {
- 8: 'KEY_BACKSPACE',
- 9: 'KEY_TAB',
- 12: 'KEY_NUM_PAD_CLEAR', // weird, for Safari and Mac FF only
- 13: 'KEY_ENTER',
- 16: 'KEY_SHIFT',
- 17: 'KEY_CTRL',
- 18: 'KEY_ALT',
- 19: 'KEY_PAUSE',
- 20: 'KEY_CAPS_LOCK',
- 27: 'KEY_ESCAPE',
- 32: 'KEY_SPACEBAR',
- 33: 'KEY_PAGE_UP',
- 34: 'KEY_PAGE_DOWN',
- 35: 'KEY_END',
- 36: 'KEY_HOME',
- 37: 'KEY_ARROW_LEFT',
- 38: 'KEY_ARROW_UP',
- 39: 'KEY_ARROW_RIGHT',
- 40: 'KEY_ARROW_DOWN',
- 44: 'KEY_PRINT_SCREEN',
- 45: 'KEY_INSERT',
- 46: 'KEY_DELETE',
- 59: 'KEY_SEMICOLON', // weird, for Safari and IE only
- 91: 'KEY_WINDOWS_LEFT',
- 92: 'KEY_WINDOWS_RIGHT',
- 93: 'KEY_SELECT',
- 106: 'KEY_NUM_PAD_ASTERISK',
- 107: 'KEY_NUM_PAD_PLUS_SIGN',
- 109: 'KEY_NUM_PAD_HYPHEN-MINUS',
- 110: 'KEY_NUM_PAD_FULL_STOP',
- 111: 'KEY_NUM_PAD_SOLIDUS',
- 144: 'KEY_NUM_LOCK',
- 145: 'KEY_SCROLL_LOCK',
- 186: 'KEY_SEMICOLON',
- 187: 'KEY_EQUALS_SIGN',
- 188: 'KEY_COMMA',
- 189: 'KEY_HYPHEN-MINUS',
- 190: 'KEY_FULL_STOP',
- 191: 'KEY_SOLIDUS',
- 192: 'KEY_GRAVE_ACCENT',
- 219: 'KEY_LEFT_SQUARE_BRACKET',
- 220: 'KEY_REVERSE_SOLIDUS',
- 221: 'KEY_RIGHT_SQUARE_BRACKET',
- 222: 'KEY_APOSTROPHE'
- // undefined: 'KEY_UNKNOWN'
-};
-
-(function () {
- /* for KEY_0 - KEY_9 */
- var _specialKeys = MochiKit.Signal._specialKeys;
- for (var i = 48; i <= 57; i++) {
- _specialKeys[i] = 'KEY_' + (i - 48);
- }
-
- /* for KEY_A - KEY_Z */
- for (i = 65; i <= 90; i++) {
- _specialKeys[i] = 'KEY_' + String.fromCharCode(i);
- }
-
- /* for KEY_NUM_PAD_0 - KEY_NUM_PAD_9 */
- for (i = 96; i <= 105; i++) {
- _specialKeys[i] = 'KEY_NUM_PAD_' + (i - 96);
- }
-
- /* for KEY_F1 - KEY_F12 */
- for (i = 112; i <= 123; i++) {
- // no F0
- _specialKeys[i] = 'KEY_F' + (i - 112 + 1);
- }
-})();
-
-MochiKit.Base.update(MochiKit.Signal, {
-
- __repr__: function () {
- return '[' + this.NAME + ' ' + this.VERSION + ']';
- },
-
- toString: function () {
- return this.__repr__();
- },
-
- _unloadCache: function () {
- var self = MochiKit.Signal;
- var observers = self._observers;
-
- for (var i = 0; i < observers.length; i++) {
- self._disconnect(observers[i]);
- }
-
- delete self._observers;
-
- try {
- window.onload = undefined;
- } catch(e) {
- // pass
- }
-
- try {
- window.onunload = undefined;
- } catch(e) {
- // pass
- }
- },
-
- _listener: function (src, func, obj, isDOM) {
- var self = MochiKit.Signal;
- var E = self.Event;
- if (!isDOM) {
- return MochiKit.Base.bind(func, obj);
- }
- obj = obj || src;
- if (typeof(func) == "string") {
- return function (nativeEvent) {
- obj[func].apply(obj, [new E(src, nativeEvent)]);
- };
- } else {
- return function (nativeEvent) {
- func.apply(obj, [new E(src, nativeEvent)]);
- };
- }
- },
-
- _browserAlreadyHasMouseEnterAndLeave: function () {
- return /MSIE/.test(navigator.userAgent);
- },
-
- _mouseEnterListener: function (src, sig, func, obj) {
- var E = MochiKit.Signal.Event;
- return function (nativeEvent) {
- var e = new E(src, nativeEvent);
- try {
- e.relatedTarget().nodeName;
- } catch (err) {
- /* probably hit a permission denied error; possibly one of
- * firefox's screwy anonymous DIVs inside an input element.
- * Allow this event to propogate up.
- */
- return;
- }
- e.stop();
- if (MochiKit.DOM.isChildNode(e.relatedTarget(), src)) {
- /* We've moved between our node and a child. Ignore. */
- return;
- }
- e.type = function () { return sig; };
- if (typeof(func) == "string") {
- return obj[func].apply(obj, [e]);
- } else {
- return func.apply(obj, [e]);
- }
- };
- },
-
- _getDestPair: function (objOrFunc, funcOrStr) {
- var obj = null;
- var func = null;
- if (typeof(funcOrStr) != 'undefined') {
- obj = objOrFunc;
- func = funcOrStr;
- if (typeof(funcOrStr) == 'string') {
- if (typeof(objOrFunc[funcOrStr]) != "function") {
- throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
- }
- } else if (typeof(funcOrStr) != 'function') {
- throw new Error("'funcOrStr' must be a function or string");
- }
- } else if (typeof(objOrFunc) != "function") {
- throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
- } else {
- func = objOrFunc;
- }
- return [obj, func];
-
- },
-
- /** @id MochiKit.Signal.connect */
- connect: function (src, sig, objOrFunc/* optional */, funcOrStr) {
- src = MochiKit.DOM.getElement(src);
- var self = MochiKit.Signal;
-
- if (typeof(sig) != 'string') {
- throw new Error("'sig' must be a string");
- }
-
- var destPair = self._getDestPair(objOrFunc, funcOrStr);
- var obj = destPair[0];
- var func = destPair[1];
- if (typeof(obj) == 'undefined' || obj === null) {
- obj = src;
- }
-
- var isDOM = !!(src.addEventListener || src.attachEvent);
- if (isDOM && (sig === "onmouseenter" || sig === "onmouseleave")
- && !self._browserAlreadyHasMouseEnterAndLeave()) {
- var listener = self._mouseEnterListener(src, sig.substr(2), func, obj);
- if (sig === "onmouseenter") {
- sig = "onmouseover";
- } else {
- sig = "onmouseout";
- }
- } else {
- var listener = self._listener(src, func, obj, isDOM);
- }
-
- if (src.addEventListener) {
- src.addEventListener(sig.substr(2), listener, false);
- } else if (src.attachEvent) {
- src.attachEvent(sig, listener); // useCapture unsupported
- }
-
- var ident = [src, sig, listener, isDOM, objOrFunc, funcOrStr, true];
- self._observers.push(ident);
-
-
- if (!isDOM && typeof(src.__connect__) == 'function') {
- var args = MochiKit.Base.extend([ident], arguments, 1);
- src.__connect__.apply(src, args);
- }
-
-
- return ident;
- },
-
- _disconnect: function (ident) {
- // already disconnected
- if (!ident[6]) { return; }
- ident[6] = false;
- // check isDOM
- if (!ident[3]) { return; }
- var src = ident[0];
- var sig = ident[1];
- var listener = ident[2];
- if (src.removeEventListener) {
- src.removeEventListener(sig.substr(2), listener, false);
- } else if (src.detachEvent) {
- src.detachEvent(sig, listener); // useCapture unsupported
- } else {
- throw new Error("'src' must be a DOM element");
- }
- },
-
- /** @id MochiKit.Signal.disconnect */
- disconnect: function (ident) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- var m = MochiKit.Base;
- if (arguments.length > 1) {
- // compatibility API
- var src = MochiKit.DOM.getElement(arguments[0]);
- var sig = arguments[1];
- var obj = arguments[2];
- var func = arguments[3];
- for (var i = observers.length - 1; i >= 0; i--) {
- var o = observers[i];
- if (o[0] === src && o[1] === sig && o[4] === obj && o[5] === func) {
- self._disconnect(o);
- if (!self._lock) {
- observers.splice(i, 1);
- } else {
- self._dirty = true;
- }
- return true;
- }
- }
- } else {
- var idx = m.findIdentical(observers, ident);
- if (idx >= 0) {
- self._disconnect(ident);
- if (!self._lock) {
- observers.splice(idx, 1);
- } else {
- self._dirty = true;
- }
- return true;
- }
- }
- return false;
- },
-
- /** @id MochiKit.Signal.disconnectAllTo */
- disconnectAllTo: function (objOrFunc, /* optional */funcOrStr) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- var disconnect = self._disconnect;
- var locked = self._lock;
- var dirty = self._dirty;
- if (typeof(funcOrStr) === 'undefined') {
- funcOrStr = null;
- }
- for (var i = observers.length - 1; i >= 0; i--) {
- var ident = observers[i];
- if (ident[4] === objOrFunc &&
- (funcOrStr === null || ident[5] === funcOrStr)) {
- disconnect(ident);
- if (locked) {
- dirty = true;
- } else {
- observers.splice(i, 1);
- }
- }
- }
- self._dirty = dirty;
- },
-
- /** @id MochiKit.Signal.disconnectAll */
- disconnectAll: function (src/* optional */, sig) {
- src = MochiKit.DOM.getElement(src);
- var m = MochiKit.Base;
- var signals = m.flattenArguments(m.extend(null, arguments, 1));
- var self = MochiKit.Signal;
- var disconnect = self._disconnect;
- var observers = self._observers;
- var i, ident;
- var locked = self._lock;
- var dirty = self._dirty;
- if (signals.length === 0) {
- // disconnect all
- for (i = observers.length - 1; i >= 0; i--) {
- ident = observers[i];
- if (ident[0] === src) {
- disconnect(ident);
- if (!locked) {
- observers.splice(i, 1);
- } else {
- dirty = true;
- }
- }
- }
- } else {
- var sigs = {};
- for (i = 0; i < signals.length; i++) {
- sigs[signals[i]] = true;
- }
- for (i = observers.length - 1; i >= 0; i--) {
- ident = observers[i];
- if (ident[0] === src && ident[1] in sigs) {
- disconnect(ident);
- if (!locked) {
- observers.splice(i, 1);
- } else {
- dirty = true;
- }
- }
- }
- }
- self._dirty = dirty;
- },
-
- /** @id MochiKit.Signal.signal */
- signal: function (src, sig) {
- var self = MochiKit.Signal;
- var observers = self._observers;
- src = MochiKit.DOM.getElement(src);
- var args = MochiKit.Base.extend(null, arguments, 2);
- var errors = [];
- self._lock = true;
- for (var i = 0; i < observers.length; i++) {
- var ident = observers[i];
- if (ident[0] === src && ident[1] === sig) {
- try {
- ident[2].apply(src, args);
- } catch (e) {
- errors.push(e);
- }
- }
- }
- self._lock = false;
- if (self._dirty) {
- self._dirty = false;
- for (var i = observers.length - 1; i >= 0; i--) {
- if (!observers[i][6]) {
- observers.splice(i, 1);
- }
- }
- }
- if (errors.length == 1) {
- throw errors[0];
- } else if (errors.length > 1) {
- var e = new Error("Multiple errors thrown in handling 'sig', see errors property");
- e.errors = errors;
- throw e;
- }
- }
-
-});
-
-MochiKit.Signal.EXPORT_OK = [];
-
-MochiKit.Signal.EXPORT = [
- 'connect',
- 'disconnect',
- 'signal',
- 'disconnectAll',
- 'disconnectAllTo'
-];
-
-MochiKit.Signal.__new__ = function (win) {
- var m = MochiKit.Base;
- this._document = document;
- this._window = win;
- this._lock = false;
- this._dirty = false;
-
- try {
- this.connect(window, 'onunload', this._unloadCache);
- } catch (e) {
- // pass: might not be a browser
- }
-
- this.EXPORT_TAGS = {
- ':common': this.EXPORT,
- ':all': m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-};
-
-MochiKit.Signal.__new__(this);
-
-//
-// XXX: Internet Explorer blows
-//
-if (MochiKit.__export__) {
- connect = MochiKit.Signal.connect;
- disconnect = MochiKit.Signal.disconnect;
- disconnectAll = MochiKit.Signal.disconnectAll;
- signal = MochiKit.Signal.signal;
-}
-
-MochiKit.Base._exportSymbols(this, MochiKit.Signal);
diff --git a/mochitest/MochiKit/Sortable.js b/mochitest/MochiKit/Sortable.js
deleted file mode 100644
index 2bee90b..0000000
--- a/mochitest/MochiKit/Sortable.js
+++ /dev/null
@@ -1,588 +0,0 @@
-/***
-Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)
- Mochi-ized By Thomas Herve (_firstname_ at nimail.org)
-
-See scriptaculous.js for full license.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.DragAndDrop');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Iter');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
- JSAN.use("MochiKit.DOM", []);
- JSAN.use("MochiKit.Iter", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined' ||
- typeof(MochiKit.DOM) == 'undefined' ||
- typeof(MochiKit.Iter) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.DragAndDrop depends on MochiKit.Base, MochiKit.DOM and MochiKit.Iter!";
-}
-
-if (typeof(MochiKit.Sortable) == 'undefined') {
- MochiKit.Sortable = {};
-}
-
-MochiKit.Sortable.NAME = 'MochiKit.Sortable';
-MochiKit.Sortable.VERSION = '1.4';
-
-MochiKit.Sortable.__repr__ = function () {
- return '[' + this.NAME + ' ' + this.VERSION + ']';
-};
-
-MochiKit.Sortable.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.Sortable.EXPORT = [
-];
-
-MochiKit.DragAndDrop.EXPORT_OK = [
- "Sortable"
-];
-
-MochiKit.Sortable.Sortable = {
- /***
-
- Manage sortables. Mainly use the create function to add a sortable.
-
- ***/
- sortables: {},
-
- _findRootElement: function (element) {
- while (element.tagName.toUpperCase() != "BODY") {
- if (element.id && MochiKit.Sortable.Sortable.sortables[element.id]) {
- return element;
- }
- element = element.parentNode;
- }
- },
-
- /** @id MochiKit.Sortable.Sortable.options */
- options: function (element) {
- element = MochiKit.Sortable.Sortable._findRootElement(MochiKit.DOM.getElement(element));
- if (!element) {
- return;
- }
- return MochiKit.Sortable.Sortable.sortables[element.id];
- },
-
- /** @id MochiKit.Sortable.Sortable.destroy */
- destroy: function (element){
- var s = MochiKit.Sortable.Sortable.options(element);
- var b = MochiKit.Base;
- var d = MochiKit.DragAndDrop;
-
- if (s) {
- MochiKit.Signal.disconnect(s.startHandle);
- MochiKit.Signal.disconnect(s.endHandle);
- b.map(function (dr) {
- d.Droppables.remove(dr);
- }, s.droppables);
- b.map(function (dr) {
- dr.destroy();
- }, s.draggables);
-
- delete MochiKit.Sortable.Sortable.sortables[s.element.id];
- }
- },
-
- /** @id MochiKit.Sortable.Sortable.create */
- create: function (element, options) {
- element = MochiKit.DOM.getElement(element);
- var self = MochiKit.Sortable.Sortable;
-
- /** @id MochiKit.Sortable.Sortable.options */
- options = MochiKit.Base.update({
-
- /** @id MochiKit.Sortable.Sortable.element */
- element: element,
-
- /** @id MochiKit.Sortable.Sortable.tag */
- tag: 'li', // assumes li children, override with tag: 'tagname'
-
- /** @id MochiKit.Sortable.Sortable.dropOnEmpty */
- dropOnEmpty: false,
-
- /** @id MochiKit.Sortable.Sortable.tree */
- tree: false,
-
- /** @id MochiKit.Sortable.Sortable.treeTag */
- treeTag: 'ul',
-
- /** @id MochiKit.Sortable.Sortable.overlap */
- overlap: 'vertical', // one of 'vertical', 'horizontal'
-
- /** @id MochiKit.Sortable.Sortable.constraint */
- constraint: 'vertical', // one of 'vertical', 'horizontal', false
- // also takes array of elements (or ids); or false
-
- /** @id MochiKit.Sortable.Sortable.containment */
- containment: [element],
-
- /** @id MochiKit.Sortable.Sortable.handle */
- handle: false, // or a CSS class
-
- /** @id MochiKit.Sortable.Sortable.only */
- only: false,
-
- /** @id MochiKit.Sortable.Sortable.hoverclass */
- hoverclass: null,
-
- /** @id MochiKit.Sortable.Sortable.ghosting */
- ghosting: false,
-
- /** @id MochiKit.Sortable.Sortable.scroll */
- scroll: false,
-
- /** @id MochiKit.Sortable.Sortable.scrollSensitivity */
- scrollSensitivity: 20,
-
- /** @id MochiKit.Sortable.Sortable.scrollSpeed */
- scrollSpeed: 15,
-
- /** @id MochiKit.Sortable.Sortable.format */
- format: /^[^_]*_(.*)$/,
-
- /** @id MochiKit.Sortable.Sortable.onChange */
- onChange: MochiKit.Base.noop,
-
- /** @id MochiKit.Sortable.Sortable.onUpdate */
- onUpdate: MochiKit.Base.noop,
-
- /** @id MochiKit.Sortable.Sortable.accept */
- accept: null
- }, options);
-
- // clear any old sortable with same element
- self.destroy(element);
-
- // build options for the draggables
- var options_for_draggable = {
- revert: true,
- ghosting: options.ghosting,
- scroll: options.scroll,
- scrollSensitivity: options.scrollSensitivity,
- scrollSpeed: options.scrollSpeed,
- constraint: options.constraint,
- handle: options.handle
- };
-
- if (options.starteffect) {
- options_for_draggable.starteffect = options.starteffect;
- }
-
- if (options.reverteffect) {
- options_for_draggable.reverteffect = options.reverteffect;
- } else if (options.ghosting) {
- options_for_draggable.reverteffect = function (innerelement) {
- innerelement.style.top = 0;
- innerelement.style.left = 0;
- };
- }
-
- if (options.endeffect) {
- options_for_draggable.endeffect = options.endeffect;
- }
-
- if (options.zindex) {
- options_for_draggable.zindex = options.zindex;
- }
-
- // build options for the droppables
- var options_for_droppable = {
- overlap: options.overlap,
- containment: options.containment,
- hoverclass: options.hoverclass,
- onhover: self.onHover,
- tree: options.tree,
- accept: options.accept
- }
-
- var options_for_tree = {
- onhover: self.onEmptyHover,
- overlap: options.overlap,
- containment: options.containment,
- hoverclass: options.hoverclass,
- accept: options.accept
- }
-
- // fix for gecko engine
- MochiKit.DOM.removeEmptyTextNodes(element);
-
- options.draggables = [];
- options.droppables = [];
-
- // drop on empty handling
- if (options.dropOnEmpty || options.tree) {
- new MochiKit.DragAndDrop.Droppable(element, options_for_tree);
- options.droppables.push(element);
- }
- MochiKit.Base.map(function (e) {
- // handles are per-draggable
- var handle = options.handle ?
- MochiKit.DOM.getFirstElementByTagAndClassName(null,
- options.handle, e) : e;
- options.draggables.push(
- new MochiKit.DragAndDrop.Draggable(e,
- MochiKit.Base.update(options_for_draggable,
- {handle: handle})));
- new MochiKit.DragAndDrop.Droppable(e, options_for_droppable);
- if (options.tree) {
- e.treeNode = element;
- }
- options.droppables.push(e);
- }, (self.findElements(element, options) || []));
-
- if (options.tree) {
- MochiKit.Base.map(function (e) {
- new MochiKit.DragAndDrop.Droppable(e, options_for_tree);
- e.treeNode = element;
- options.droppables.push(e);
- }, (self.findTreeElements(element, options) || []));
- }
-
- // keep reference
- self.sortables[element.id] = options;
-
- options.lastValue = self.serialize(element);
- options.startHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'start',
- MochiKit.Base.partial(self.onStart, element));
- options.endHandle = MochiKit.Signal.connect(MochiKit.DragAndDrop.Draggables, 'end',
- MochiKit.Base.partial(self.onEnd, element));
- },
-
- /** @id MochiKit.Sortable.Sortable.onStart */
- onStart: function (element, draggable) {
- var self = MochiKit.Sortable.Sortable;
- var options = self.options(element);
- options.lastValue = self.serialize(options.element);
- },
-
- /** @id MochiKit.Sortable.Sortable.onEnd */
- onEnd: function (element, draggable) {
- var self = MochiKit.Sortable.Sortable;
- self.unmark();
- var options = self.options(element);
- if (options.lastValue != self.serialize(options.element)) {
- options.onUpdate(options.element);
- }
- },
-
- // return all suitable-for-sortable elements in a guaranteed order
-
- /** @id MochiKit.Sortable.Sortable.findElements */
- findElements: function (element, options) {
- return MochiKit.Sortable.Sortable.findChildren(
- element, options.only, options.tree ? true : false, options.tag);
- },
-
- /** @id MochiKit.Sortable.Sortable.findTreeElements */
- findTreeElements: function (element, options) {
- return MochiKit.Sortable.Sortable.findChildren(
- element, options.only, options.tree ? true : false, options.treeTag);
- },
-
- /** @id MochiKit.Sortable.Sortable.findChildren */
- findChildren: function (element, only, recursive, tagName) {
- if (!element.hasChildNodes()) {
- return null;
- }
- tagName = tagName.toUpperCase();
- if (only) {
- only = MochiKit.Base.flattenArray([only]);
- }
- var elements = [];
- MochiKit.Base.map(function (e) {
- if (e.tagName &&
- e.tagName.toUpperCase() == tagName &&
- (!only ||
- MochiKit.Iter.some(only, function (c) {
- return MochiKit.DOM.hasElementClass(e, c);
- }))) {
- elements.push(e);
- }
- if (recursive) {
- var grandchildren = MochiKit.Sortable.Sortable.findChildren(e, only, recursive, tagName);
- if (grandchildren && grandchildren.length > 0) {
- elements = elements.concat(grandchildren);
- }
- }
- }, element.childNodes);
- return elements;
- },
-
- /** @id MochiKit.Sortable.Sortable.onHover */
- onHover: function (element, dropon, overlap) {
- if (MochiKit.DOM.isParent(dropon, element)) {
- return;
- }
- var self = MochiKit.Sortable.Sortable;
-
- if (overlap > .33 && overlap < .66 && self.options(dropon).tree) {
- return;
- } else if (overlap > 0.5) {
- self.mark(dropon, 'before');
- if (dropon.previousSibling != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = 'hidden'; // fix gecko rendering
- dropon.parentNode.insertBefore(element, dropon);
- if (dropon.parentNode != oldParentNode) {
- self.options(oldParentNode).onChange(element);
- }
- self.options(dropon.parentNode).onChange(element);
- }
- } else {
- self.mark(dropon, 'after');
- var nextElement = dropon.nextSibling || null;
- if (nextElement != element) {
- var oldParentNode = element.parentNode;
- element.style.visibility = 'hidden'; // fix gecko rendering
- dropon.parentNode.insertBefore(element, nextElement);
- if (dropon.parentNode != oldParentNode) {
- self.options(oldParentNode).onChange(element);
- }
- self.options(dropon.parentNode).onChange(element);
- }
- }
- },
-
- _offsetSize: function (element, type) {
- if (type == 'vertical' || type == 'height') {
- return element.offsetHeight;
- } else {
- return element.offsetWidth;
- }
- },
-
- /** @id MochiKit.Sortable.Sortable.onEmptyHover */
- onEmptyHover: function (element, dropon, overlap) {
- var oldParentNode = element.parentNode;
- var self = MochiKit.Sortable.Sortable;
- var droponOptions = self.options(dropon);
-
- if (!MochiKit.DOM.isParent(dropon, element)) {
- var index;
-
- var children = self.findElements(dropon, {tag: droponOptions.tag,
- only: droponOptions.only});
- var child = null;
-
- if (children) {
- var offset = self._offsetSize(dropon, droponOptions.overlap) * (1.0 - overlap);
-
- for (index = 0; index < children.length; index += 1) {
- if (offset - self._offsetSize(children[index], droponOptions.overlap) >= 0) {
- offset -= self._offsetSize(children[index], droponOptions.overlap);
- } else if (offset - (self._offsetSize (children[index], droponOptions.overlap) / 2) >= 0) {
- child = index + 1 < children.length ? children[index + 1] : null;
- break;
- } else {
- child = children[index];
- break;
- }
- }
- }
-
- dropon.insertBefore(element, child);
-
- self.options(oldParentNode).onChange(element);
- droponOptions.onChange(element);
- }
- },
-
- /** @id MochiKit.Sortable.Sortable.unmark */
- unmark: function () {
- var m = MochiKit.Sortable.Sortable._marker;
- if (m) {
- MochiKit.Style.hideElement(m);
- }
- },
-
- /** @id MochiKit.Sortable.Sortable.mark */
- mark: function (dropon, position) {
- // mark on ghosting only
- var d = MochiKit.DOM;
- var self = MochiKit.Sortable.Sortable;
- var sortable = self.options(dropon.parentNode);
- if (sortable && !sortable.ghosting) {
- return;
- }
-
- if (!self._marker) {
- self._marker = d.getElement('dropmarker') ||
- document.createElement('DIV');
- MochiKit.Style.hideElement(self._marker);
- d.addElementClass(self._marker, 'dropmarker');
- self._marker.style.position = 'absolute';
- document.getElementsByTagName('body').item(0).appendChild(self._marker);
- }
- var offsets = MochiKit.Position.cumulativeOffset(dropon);
- self._marker.style.left = offsets.x + 'px';
- self._marker.style.top = offsets.y + 'px';
-
- if (position == 'after') {
- if (sortable.overlap == 'horizontal') {
- self._marker.style.left = (offsets.x + dropon.clientWidth) + 'px';
- } else {
- self._marker.style.top = (offsets.y + dropon.clientHeight) + 'px';
- }
- }
- MochiKit.Style.showElement(self._marker);
- },
-
- _tree: function (element, options, parent) {
- var self = MochiKit.Sortable.Sortable;
- var children = self.findElements(element, options) || [];
-
- for (var i = 0; i < children.length; ++i) {
- var match = children[i].id.match(options.format);
-
- if (!match) {
- continue;
- }
-
- var child = {
- id: encodeURIComponent(match ? match[1] : null),
- element: element,
- parent: parent,
- children: [],
- position: parent.children.length,
- container: self._findChildrenElement(children[i], options.treeTag.toUpperCase())
- }
-
- /* Get the element containing the children and recurse over it */
- if (child.container) {
- self._tree(child.container, options, child)
- }
-
- parent.children.push (child);
- }
-
- return parent;
- },
-
- /* Finds the first element of the given tag type within a parent element.
- Used for finding the first LI[ST] within a L[IST]I[TEM].*/
- _findChildrenElement: function (element, containerTag) {
- if (element && element.hasChildNodes) {
- containerTag = containerTag.toUpperCase();
- for (var i = 0; i < element.childNodes.length; ++i) {
- if (element.childNodes[i].tagName.toUpperCase() == containerTag) {
- return element.childNodes[i];
- }
- }
- }
- return null;
- },
-
- /** @id MochiKit.Sortable.Sortable.tree */
- tree: function (element, options) {
- element = MochiKit.DOM.getElement(element);
- var sortableOptions = MochiKit.Sortable.Sortable.options(element);
- options = MochiKit.Base.update({
- tag: sortableOptions.tag,
- treeTag: sortableOptions.treeTag,
- only: sortableOptions.only,
- name: element.id,
- format: sortableOptions.format
- }, options || {});
-
- var root = {
- id: null,
- parent: null,
- children: new Array,
- container: element,
- position: 0
- }
-
- return MochiKit.Sortable.Sortable._tree(element, options, root);
- },
-
- /**
- * Specifies the sequence for the Sortable.
- * @param {Node} element Element to use as the Sortable.
- * @param {Object} newSequence New sequence to use.
- * @param {Object} options Options to use fro the Sortable.
- */
- setSequence: function (element, newSequence, options) {
- var self = MochiKit.Sortable.Sortable;
- var b = MochiKit.Base;
- element = MochiKit.DOM.getElement(element);
- options = b.update(self.options(element), options || {});
-
- var nodeMap = {};
- b.map(function (n) {
- var m = n.id.match(options.format);
- if (m) {
- nodeMap[m[1]] = [n, n.parentNode];
- }
- n.parentNode.removeChild(n);
- }, self.findElements(element, options));
-
- b.map(function (ident) {
- var n = nodeMap[ident];
- if (n) {
- n[1].appendChild(n[0]);
- delete nodeMap[ident];
- }
- }, newSequence);
- },
-
- /* Construct a [i] index for a particular node */
- _constructIndex: function (node) {
- var index = '';
- do {
- if (node.id) {
- index = '[' + node.position + ']' + index;
- }
- } while ((node = node.parent) != null);
- return index;
- },
-
- /** @id MochiKit.Sortable.Sortable.sequence */
- sequence: function (element, options) {
- element = MochiKit.DOM.getElement(element);
- var self = MochiKit.Sortable.Sortable;
- var options = MochiKit.Base.update(self.options(element), options || {});
-
- return MochiKit.Base.map(function (item) {
- return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
- }, MochiKit.DOM.getElement(self.findElements(element, options) || []));
- },
-
- /**
- * Serializes the content of a Sortable. Useful to send this content through a XMLHTTPRequest.
- * These options override the Sortable options for the serialization only.
- * @param {Node} element Element to serialize.
- * @param {Object} options Serialization options.
- */
- serialize: function (element, options) {
- element = MochiKit.DOM.getElement(element);
- var self = MochiKit.Sortable.Sortable;
- options = MochiKit.Base.update(self.options(element), options || {});
- var name = encodeURIComponent(options.name || element.id);
-
- if (options.tree) {
- return MochiKit.Base.flattenArray(MochiKit.Base.map(function (item) {
- return [name + self._constructIndex(item) + "[id]=" +
- encodeURIComponent(item.id)].concat(item.children.map(arguments.callee));
- }, self.tree(element, options).children)).join('&');
- } else {
- return MochiKit.Base.map(function (item) {
- return name + "[]=" + encodeURIComponent(item);
- }, self.sequence(element, options)).join('&');
- }
- }
-};
-
diff --git a/mochitest/MochiKit/Style.js b/mochitest/MochiKit/Style.js
deleted file mode 100644
index 6abf6d7..0000000
--- a/mochitest/MochiKit/Style.js
+++ /dev/null
@@ -1,475 +0,0 @@
-/***
-
-MochiKit.Style 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005-2006 Bob Ippolito, Beau Hartshorne. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Style');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
-}
-if (typeof(JSAN) != 'undefined') {
- JSAN.use('MochiKit.Base', []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw '';
- }
-} catch (e) {
- throw 'MochiKit.Style depends on MochiKit.Base!';
-}
-
-try {
- if (typeof(MochiKit.DOM) == 'undefined') {
- throw '';
- }
-} catch (e) {
- throw 'MochiKit.Style depends on MochiKit.DOM!';
-}
-
-
-if (typeof(MochiKit.Style) == 'undefined') {
- MochiKit.Style = {};
-}
-
-MochiKit.Style.NAME = 'MochiKit.Style';
-MochiKit.Style.VERSION = '1.4';
-MochiKit.Style.__repr__ = function () {
- return '[' + this.NAME + ' ' + this.VERSION + ']';
-};
-MochiKit.Style.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.Style.EXPORT_OK = [];
-
-MochiKit.Style.EXPORT = [
- 'setOpacity',
- 'getOpacity',
- 'setStyle',
- 'getStyle', // temporary
- 'computedStyle',
- 'getElementDimensions',
- 'elementDimensions', // deprecated
- 'setElementDimensions',
- 'getElementPosition',
- 'elementPosition', // deprecated
- 'setElementPosition',
- 'setDisplayForElement',
- 'hideElement',
- 'showElement',
- 'getViewportDimensions',
- 'getViewportPosition',
- 'Dimensions',
- 'Coordinates'
-];
-
-
-/*
-
- Dimensions
-
-*/
-/** @id MochiKit.Style.Dimensions */
-MochiKit.Style.Dimensions = function (w, h) {
- this.w = w;
- this.h = h;
-};
-
-MochiKit.Style.Dimensions.prototype.__repr__ = function () {
- var repr = MochiKit.Base.repr;
- return '{w: ' + repr(this.w) + ', h: ' + repr(this.h) + '}';
-};
-
-MochiKit.Style.Dimensions.prototype.toString = function () {
- return this.__repr__();
-};
-
-
-/*
-
- Coordinates
-
-*/
-/** @id MochiKit.Style.Coordinates */
-MochiKit.Style.Coordinates = function (x, y) {
- this.x = x;
- this.y = y;
-};
-
-MochiKit.Style.Coordinates.prototype.__repr__ = function () {
- var repr = MochiKit.Base.repr;
- return '{x: ' + repr(this.x) + ', y: ' + repr(this.y) + '}';
-};
-
-MochiKit.Style.Coordinates.prototype.toString = function () {
- return this.__repr__();
-};
-
-
-MochiKit.Base.update(MochiKit.Style, {
-
- /** @id MochiKit.Style.computedStyle */
- computedStyle: function (elem, cssProperty) {
- var dom = MochiKit.DOM;
- var d = dom._document;
-
- elem = dom.getElement(elem);
- cssProperty = MochiKit.Base.camelize(cssProperty);
-
- if (!elem || elem == d) {
- return undefined;
- }
-
- /* from YUI 0.10.0 */
- if (cssProperty == 'opacity' && elem.filters) { // IE opacity
- try {
- return elem.filters.item('DXImageTransform.Microsoft.Alpha'
- ).opacity / 100;
- } catch(e) {
- try {
- return elem.filters.item('alpha').opacity / 100;
- } catch(e) {}
- }
- }
-
- if (elem.currentStyle) {
- return elem.currentStyle[cssProperty];
- }
- if (typeof(d.defaultView) == 'undefined') {
- return undefined;
- }
- if (d.defaultView === null) {
- return undefined;
- }
- var style = d.defaultView.getComputedStyle(elem, null);
- if (typeof(style) == 'undefined' || style === null) {
- return undefined;
- }
-
- var selectorCase = cssProperty.replace(/([A-Z])/g, '-$1'
- ).toLowerCase(); // from dojo.style.toSelectorCase
-
- return style.getPropertyValue(selectorCase);
- },
-
- /** @id MochiKit.Style.getStyle */
- getStyle: function (elem, style) {
- elem = MochiKit.DOM.getElement(elem);
- var value = elem.style[MochiKit.Base.camelize(style)];
- if (!value) {
- if (document.defaultView && document.defaultView.getComputedStyle) {
- var css = document.defaultView.getComputedStyle(elem, null);
- value = css ? css.getPropertyValue(style) : null;
- } else if (elem.currentStyle) {
- value = elem.currentStyle[MochiKit.Base.camelize(style)];
- }
- }
-
- if (/Opera/.test(navigator.userAgent) && (MochiKit.Base.find(['left', 'top', 'right', 'bottom'], style) != -1)) {
- if (MochiKit.Style.getStyle(elem, 'position') == 'static') {
- value = 'auto';
- }
- }
-
- return value == 'auto' ? null : value;
- },
-
- /** @id MochiKit.Style.setStyle */
- setStyle: function (elem, style) {
- elem = MochiKit.DOM.getElement(elem);
- for (name in style) {
- elem.style[MochiKit.Base.camelize(name)] = style[name];
- }
- },
-
- /** @id MochiKit.Style.getOpacity */
- getOpacity: function (elem) {
- var opacity;
- if (opacity = MochiKit.Style.getStyle(elem, 'opacity')) {
- return parseFloat(opacity);
- }
- if (opacity = (MochiKit.Style.getStyle(elem, 'filter') || '').match(/alpha\(opacity=(.*)\)/)) {
- if (opacity[1]) {
- return parseFloat(opacity[1]) / 100;
- }
- }
- return 1.0;
- },
- /** @id MochiKit.Style.setOpacity */
- setOpacity: function(elem, o) {
- elem = MochiKit.DOM.getElement(elem);
- var self = MochiKit.Style;
- if (o == 1) {
- var toSet = /Gecko/.test(navigator.userAgent) && !(/Konqueror|Safari|KHTML/.test(navigator.userAgent));
- self.setStyle(elem, {opacity: toSet ? 0.999999 : 1.0});
- if (/MSIE/.test(navigator.userAgent)) {
- self.setStyle(elem, {filter:
- self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '')});
- }
- } else {
- if (o < 0.00001) {
- o = 0;
- }
- self.setStyle(elem, {opacity: o});
- if (/MSIE/.test(navigator.userAgent)) {
- self.setStyle(elem,
- {filter: self.getStyle(elem, 'filter').replace(/alpha\([^\)]*\)/gi, '') + 'alpha(opacity=' + o * 100 + ')' });
- }
- }
- },
-
- /*
-
- getElementPosition is adapted from YAHOO.util.Dom.getXY v0.9.0.
- Copyright: Copyright (c) 2006, Yahoo! Inc. All rights reserved.
- License: BSD, http://developer.yahoo.net/yui/license.txt
-
- */
-
- /** @id MochiKit.Style.getElementPosition */
- getElementPosition: function (elem, /* optional */relativeTo) {
- var self = MochiKit.Style;
- var dom = MochiKit.DOM;
- elem = dom.getElement(elem);
-
- if (!elem ||
- (!(elem.x && elem.y) &&
- (!elem.parentNode == null ||
- self.computedStyle(elem, 'display') == 'none'))) {
- return undefined;
- }
-
- var c = new self.Coordinates(0, 0);
- var box = null;
- var parent = null;
-
- var d = MochiKit.DOM._document;
- var de = d.documentElement;
- var b = d.body;
-
- if (!elem.parentNode && elem.x && elem.y) {
- /* it's just a MochiKit.Style.Coordinates object */
- c.x += elem.x || 0;
- c.y += elem.y || 0;
- } else if (elem.getBoundingClientRect) { // IE shortcut
- /*
-
- The IE shortcut can be off by two. We fix it. See:
- http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/getboundingclientrect.asp
-
- This is similar to the method used in
- MochiKit.Signal.Event.mouse().
-
- */
- box = elem.getBoundingClientRect();
-
- c.x += box.left +
- (de.scrollLeft || b.scrollLeft) -
- (de.clientLeft || 0);
-
- c.y += box.top +
- (de.scrollTop || b.scrollTop) -
- (de.clientTop || 0);
-
- } else if (elem.offsetParent) {
- c.x += elem.offsetLeft;
- c.y += elem.offsetTop;
- parent = elem.offsetParent;
-
- if (parent != elem) {
- while (parent) {
- c.x += parent.offsetLeft;
- c.y += parent.offsetTop;
- parent = parent.offsetParent;
- }
- }
-
- /*
-
- Opera < 9 and old Safari (absolute) incorrectly account for
- body offsetTop and offsetLeft.
-
- */
- var ua = navigator.userAgent.toLowerCase();
- if ((typeof(opera) != 'undefined' &&
- parseFloat(opera.version()) < 9) ||
- (ua.indexOf('safari') != -1 &&
- self.computedStyle(elem, 'position') == 'absolute')) {
-
- c.x -= b.offsetLeft;
- c.y -= b.offsetTop;
-
- }
- }
-
- if (typeof(relativeTo) != 'undefined') {
- relativeTo = arguments.callee(relativeTo);
- if (relativeTo) {
- c.x -= (relativeTo.x || 0);
- c.y -= (relativeTo.y || 0);
- }
- }
-
- if (elem.parentNode) {
- parent = elem.parentNode;
- } else {
- parent = null;
- }
-
- while (parent) {
- var tagName = parent.tagName.toUpperCase();
- if (tagName === 'BODY' || tagName === 'HTML') {
- break;
- }
- c.x -= parent.scrollLeft;
- c.y -= parent.scrollTop;
- if (parent.parentNode) {
- parent = parent.parentNode;
- } else {
- parent = null;
- }
- }
-
- return c;
- },
-
- /** @id MochiKit.Style.setElementPosition */
- setElementPosition: function (elem, newPos/* optional */, units) {
- elem = MochiKit.DOM.getElement(elem);
- if (typeof(units) == 'undefined') {
- units = 'px';
- }
- var newStyle = {};
- var isUndefNull = MochiKit.Base.isUndefinedOrNull;
- if (!isUndefNull(newPos.x)) {
- newStyle['left'] = newPos.x + units;
- }
- if (!isUndefNull(newPos.y)) {
- newStyle['top'] = newPos.y + units;
- }
- MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
- },
-
- /** @id MochiKit.Style.getElementDimensions */
- getElementDimensions: function (elem) {
- var self = MochiKit.Style;
- var dom = MochiKit.DOM;
- if (typeof(elem.w) == 'number' || typeof(elem.h) == 'number') {
- return new self.Dimensions(elem.w || 0, elem.h || 0);
- }
- elem = dom.getElement(elem);
- if (!elem) {
- return undefined;
- }
- var disp = self.computedStyle(elem, 'display');
- // display can be empty/undefined on WebKit/KHTML
- if (disp != 'none' && disp != '' && typeof(disp) != 'undefined') {
- return new self.Dimensions(elem.offsetWidth || 0,
- elem.offsetHeight || 0);
- }
- var s = elem.style;
- var originalVisibility = s.visibility;
- var originalPosition = s.position;
- s.visibility = 'hidden';
- s.position = 'absolute';
- s.display = '';
- var originalWidth = elem.offsetWidth;
- var originalHeight = elem.offsetHeight;
- s.display = 'none';
- s.position = originalPosition;
- s.visibility = originalVisibility;
- return new self.Dimensions(originalWidth, originalHeight);
- },
-
- /** @id MochiKit.Style.setElementDimensions */
- setElementDimensions: function (elem, newSize/* optional */, units) {
- elem = MochiKit.DOM.getElement(elem);
- if (typeof(units) == 'undefined') {
- units = 'px';
- }
- var newStyle = {};
- var isUndefNull = MochiKit.Base.isUndefinedOrNull;
- if (!isUndefNull(newSize.w)) {
- newStyle['width'] = newSize.w + units;
- }
- if (!isUndefNull(newSize.h)) {
- newStyle['height'] = newSize.h + units;
- }
- MochiKit.DOM.updateNodeAttributes(elem, {'style': newStyle});
- },
-
- /** @id MochiKit.Style.setDisplayForElement */
- setDisplayForElement: function (display, element/*, ...*/) {
- var elements = MochiKit.Base.extend(null, arguments, 1);
- var getElement = MochiKit.DOM.getElement;
- for (var i = 0; i < elements.length; i++) {
- var element = getElement(elements[i]);
- if (element) {
- element.style.display = display;
- }
- }
- },
-
- /** @id MochiKit.Style.getViewportDimensions */
- getViewportDimensions: function () {
- var d = new MochiKit.Style.Dimensions();
-
- var w = MochiKit.DOM._window;
- var b = MochiKit.DOM._document.body;
-
- if (w.innerWidth) {
- d.w = w.innerWidth;
- d.h = w.innerHeight;
- } else if (b.parentElement.clientWidth) {
- d.w = b.parentElement.clientWidth;
- d.h = b.parentElement.clientHeight;
- } else if (b && b.clientWidth) {
- d.w = b.clientWidth;
- d.h = b.clientHeight;
- }
- return d;
- },
-
- /** @id MochiKit.Style.getViewportPosition */
- getViewportPosition: function () {
- var c = new MochiKit.Style.Coordinates(0, 0);
- var d = MochiKit.DOM._document;
- var de = d.documentElement;
- var db = d.body;
- if (de && (de.scrollTop || de.scrollLeft)) {
- c.x = de.scrollLeft;
- c.y = de.scrollTop;
- } else if (db) {
- c.x = db.scrollLeft;
- c.y = db.scrollTop;
- }
- return c;
- },
-
- __new__: function () {
- var m = MochiKit.Base;
-
- this.elementPosition = this.getElementPosition;
- this.elementDimensions = this.getElementDimensions;
-
- this.hideElement = m.partial(this.setDisplayForElement, 'none');
- this.showElement = m.partial(this.setDisplayForElement, 'block');
-
- this.EXPORT_TAGS = {
- ':common': this.EXPORT,
- ':all': m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
- }
-});
-
-MochiKit.Style.__new__();
-MochiKit.Base._exportSymbols(this, MochiKit.Style);
diff --git a/mochitest/MochiKit/Test.js b/mochitest/MochiKit/Test.js
deleted file mode 100644
index 632356a..0000000
--- a/mochitest/MochiKit/Test.js
+++ /dev/null
@@ -1,181 +0,0 @@
-/***
-
-MochiKit.Test 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Test');
- dojo.require('MochiKit.Base');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
-}
-
-try {
- if (typeof(MochiKit.Base) == 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Test depends on MochiKit.Base!";
-}
-
-if (typeof(MochiKit.Test) == 'undefined') {
- MochiKit.Test = {};
-}
-
-MochiKit.Test.NAME = "MochiKit.Test";
-MochiKit.Test.VERSION = "1.4";
-MochiKit.Test.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-MochiKit.Test.toString = function () {
- return this.__repr__();
-};
-
-
-MochiKit.Test.EXPORT = ["runTests"];
-MochiKit.Test.EXPORT_OK = [];
-
-MochiKit.Test.runTests = function (obj) {
- if (typeof(obj) == "string") {
- obj = JSAN.use(obj);
- }
- var suite = new MochiKit.Test.Suite();
- suite.run(obj);
-};
-
-MochiKit.Test.Suite = function () {
- this.testIndex = 0;
- MochiKit.Base.bindMethods(this);
-};
-
-MochiKit.Test.Suite.prototype = {
- run: function (obj) {
- try {
- obj(this);
- } catch (e) {
- this.traceback(e);
- }
- },
- traceback: function (e) {
- var items = MochiKit.Iter.sorted(MochiKit.Base.items(e));
- print("not ok " + this.testIndex + " - Error thrown");
- for (var i = 0; i < items.length; i++) {
- var kv = items[i];
- if (kv[0] == "stack") {
- kv[1] = kv[1].split(/\n/)[0];
- }
- this.print("# " + kv.join(": "));
- }
- },
- print: function (s) {
- print(s);
- },
- is: function (got, expected, /* optional */message) {
- var res = 1;
- var msg = null;
- try {
- res = MochiKit.Base.compare(got, expected);
- } catch (e) {
- msg = "Can not compare " + typeof(got) + ":" + typeof(expected);
- }
- if (res) {
- msg = "Expected value did not compare equal";
- }
- if (!res) {
- return this.testResult(true, message);
- }
- return this.testResult(false, message,
- [[msg], ["got:", got], ["expected:", expected]]);
- },
-
- testResult: function (pass, msg, failures) {
- this.testIndex += 1;
- if (pass) {
- this.print("ok " + this.testIndex + " - " + msg);
- return;
- }
- this.print("not ok " + this.testIndex + " - " + msg);
- if (failures) {
- for (var i = 0; i < failures.length; i++) {
- this.print("# " + failures[i].join(" "));
- }
- }
- },
-
- isDeeply: function (got, expected, /* optional */message) {
- var m = MochiKit.Base;
- var res = 1;
- try {
- res = m.compare(got, expected);
- } catch (e) {
- // pass
- }
- if (res === 0) {
- return this.ok(true, message);
- }
- var gk = m.keys(got);
- var ek = m.keys(expected);
- gk.sort();
- ek.sort();
- if (m.compare(gk, ek)) {
- // differing keys
- var cmp = {};
- var i;
- for (i = 0; i < gk.length; i++) {
- cmp[gk[i]] = "got";
- }
- for (i = 0; i < ek.length; i++) {
- if (ek[i] in cmp) {
- delete cmp[ek[i]];
- } else {
- cmp[ek[i]] = "expected";
- }
- }
- var diffkeys = m.keys(cmp);
- diffkeys.sort();
- var gotkeys = [];
- var expkeys = [];
- while (diffkeys.length) {
- var k = diffkeys.shift();
- if (k in Object.prototype) {
- continue;
- }
- (cmp[k] == "got" ? gotkeys : expkeys).push(k);
- }
-
-
- }
-
- return this.testResult((!res), msg,
- (msg ? [["got:", got], ["expected:", expected]] : undefined)
- );
- },
-
- ok: function (res, message) {
- return this.testResult(res, message);
- }
-};
-
-MochiKit.Test.__new__ = function () {
- var m = MochiKit.Base;
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
- m.nameFunctions(this);
-
-};
-
-MochiKit.Test.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.Test);
diff --git a/mochitest/MochiKit/Visual.js b/mochitest/MochiKit/Visual.js
deleted file mode 100644
index bf8b3df..0000000
--- a/mochitest/MochiKit/Visual.js
+++ /dev/null
@@ -1,1823 +0,0 @@
-/***
-
-MochiKit.Visual 1.4
-
-See <http://mochikit.com/> for documentation, downloads, license, etc.
-
-(c) 2005 Bob Ippolito and others. All rights Reserved.
-
-***/
-
-if (typeof(dojo) != 'undefined') {
- dojo.provide('MochiKit.Visual');
- dojo.require('MochiKit.Base');
- dojo.require('MochiKit.DOM');
- dojo.require('MochiKit.Style');
- dojo.require('MochiKit.Color');
-}
-
-if (typeof(JSAN) != 'undefined') {
- JSAN.use("MochiKit.Base", []);
- JSAN.use("MochiKit.DOM", []);
- JSAN.use("MochiKit.Style", []);
- JSAN.use("MochiKit.Color", []);
-}
-
-try {
- if (typeof(MochiKit.Base) === 'undefined' ||
- typeof(MochiKit.DOM) === 'undefined' ||
- typeof(MochiKit.Style) === 'undefined' ||
- typeof(MochiKit.Color) === 'undefined') {
- throw "";
- }
-} catch (e) {
- throw "MochiKit.Visual depends on MochiKit.Base, MochiKit.DOM, MochiKit.Style and MochiKit.Color!";
-}
-
-if (typeof(MochiKit.Visual) == "undefined") {
- MochiKit.Visual = {};
-}
-
-MochiKit.Visual.NAME = "MochiKit.Visual";
-MochiKit.Visual.VERSION = "1.4";
-
-MochiKit.Visual.__repr__ = function () {
- return "[" + this.NAME + " " + this.VERSION + "]";
-};
-
-MochiKit.Visual.toString = function () {
- return this.__repr__();
-};
-
-MochiKit.Visual._RoundCorners = function (e, options) {
- e = MochiKit.DOM.getElement(e);
- this._setOptions(options);
- if (this.options.__unstable__wrapElement) {
- e = this._doWrap(e);
- }
-
- var color = this.options.color;
- var C = MochiKit.Color.Color;
- if (this.options.color === "fromElement") {
- color = C.fromBackground(e);
- } else if (!(color instanceof C)) {
- color = C.fromString(color);
- }
- this.isTransparent = (color.asRGB().a <= 0);
-
- var bgColor = this.options.bgColor;
- if (this.options.bgColor === "fromParent") {
- bgColor = C.fromBackground(e.offsetParent);
- } else if (!(bgColor instanceof C)) {
- bgColor = C.fromString(bgColor);
- }
-
- this._roundCornersImpl(e, color, bgColor);
-};
-
-MochiKit.Visual._RoundCorners.prototype = {
- _doWrap: function (e) {
- var parent = e.parentNode;
- var doc = MochiKit.DOM.currentDocument();
- if (typeof(doc.defaultView) === "undefined"
- || doc.defaultView === null) {
- return e;
- }
- var style = doc.defaultView.getComputedStyle(e, null);
- if (typeof(style) === "undefined" || style === null) {
- return e;
- }
- var wrapper = MochiKit.DOM.DIV({"style": {
- display: "block",
- // convert padding to margin
- marginTop: style.getPropertyValue("padding-top"),
- marginRight: style.getPropertyValue("padding-right"),
- marginBottom: style.getPropertyValue("padding-bottom"),
- marginLeft: style.getPropertyValue("padding-left"),
- // remove padding so the rounding looks right
- padding: "0px"
- /*
- paddingRight: "0px",
- paddingLeft: "0px"
- */
- }});
- wrapper.innerHTML = e.innerHTML;
- e.innerHTML = "";
- e.appendChild(wrapper);
- return e;
- },
-
- _roundCornersImpl: function (e, color, bgColor) {
- if (this.options.border) {
- this._renderBorder(e, bgColor);
- }
- if (this._isTopRounded()) {
- this._roundTopCorners(e, color, bgColor);
- }
- if (this._isBottomRounded()) {
- this._roundBottomCorners(e, color, bgColor);
- }
- },
-
- _renderBorder: function (el, bgColor) {
- var borderValue = "1px solid " + this._borderColor(bgColor);
- var borderL = "border-left: " + borderValue;
- var borderR = "border-right: " + borderValue;
- var style = "style='" + borderL + ";" + borderR + "'";
- el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>";
- },
-
- _roundTopCorners: function (el, color, bgColor) {
- var corner = this._createCorner(bgColor);
- for (var i = 0; i < this.options.numSlices; i++) {
- corner.appendChild(
- this._createCornerSlice(color, bgColor, i, "top")
- );
- }
- el.style.paddingTop = 0;
- el.insertBefore(corner, el.firstChild);
- },
-
- _roundBottomCorners: function (el, color, bgColor) {
- var corner = this._createCorner(bgColor);
- for (var i = (this.options.numSlices - 1); i >= 0; i--) {
- corner.appendChild(
- this._createCornerSlice(color, bgColor, i, "bottom")
- );
- }
- el.style.paddingBottom = 0;
- el.appendChild(corner);
- },
-
- _createCorner: function (bgColor) {
- var dom = MochiKit.DOM;
- return dom.DIV({style: {backgroundColor: bgColor.toString()}});
- },
-
- _createCornerSlice: function (color, bgColor, n, position) {
- var slice = MochiKit.DOM.SPAN();
-
- var inStyle = slice.style;
- inStyle.backgroundColor = color.toString();
- inStyle.display = "block";
- inStyle.height = "1px";
- inStyle.overflow = "hidden";
- inStyle.fontSize = "1px";
-
- var borderColor = this._borderColor(color, bgColor);
- if (this.options.border && n === 0) {
- inStyle.borderTopStyle = "solid";
- inStyle.borderTopWidth = "1px";
- inStyle.borderLeftWidth = "0px";
- inStyle.borderRightWidth = "0px";
- inStyle.borderBottomWidth = "0px";
- // assumes css compliant box model
- inStyle.height = "0px";
- inStyle.borderColor = borderColor.toString();
- } else if (borderColor) {
- inStyle.borderColor = borderColor.toString();
- inStyle.borderStyle = "solid";
- inStyle.borderWidth = "0px 1px";
- }
-
- if (!this.options.compact && (n == (this.options.numSlices - 1))) {
- inStyle.height = "2px";
- }
-
- this._setMargin(slice, n, position);
- this._setBorder(slice, n, position);
-
- return slice;
- },
-
- _setOptions: function (options) {
- this.options = {
- corners: "all",
- color: "fromElement",
- bgColor: "fromParent",
- blend: true,
- border: false,
- compact: false,
- __unstable__wrapElement: false
- };
- MochiKit.Base.update(this.options, options);
-
- this.options.numSlices = (this.options.compact ? 2 : 4);
- },
-
- _whichSideTop: function () {
- var corners = this.options.corners;
- if (this._hasString(corners, "all", "top")) {
- return "";
- }
-
- var has_tl = (corners.indexOf("tl") != -1);
- var has_tr = (corners.indexOf("tr") != -1);
- if (has_tl && has_tr) {
- return "";
- }
- if (has_tl) {
- return "left";
- }
- if (has_tr) {
- return "right";
- }
- return "";
- },
-
- _whichSideBottom: function () {
- var corners = this.options.corners;
- if (this._hasString(corners, "all", "bottom")) {
- return "";
- }
-
- var has_bl = (corners.indexOf('bl') != -1);
- var has_br = (corners.indexOf('br') != -1);
- if (has_bl && has_br) {
- return "";
- }
- if (has_bl) {
- return "left";
- }
- if (has_br) {
- return "right";
- }
- return "";
- },
-
- _borderColor: function (color, bgColor) {
- if (color == "transparent") {
- return bgColor;
- } else if (this.options.border) {
- return this.options.border;
- } else if (this.options.blend) {
- return bgColor.blendedColor(color);
- }
- return "";
- },
-
-
- _setMargin: function (el, n, corners) {
- var marginSize = this._marginSize(n) + "px";
- var whichSide = (
- corners == "top" ? this._whichSideTop() : this._whichSideBottom()
- );
- var style = el.style;
-
- if (whichSide == "left") {
- style.marginLeft = marginSize;
- style.marginRight = "0px";
- } else if (whichSide == "right") {
- style.marginRight = marginSize;
- style.marginLeft = "0px";
- } else {
- style.marginLeft = marginSize;
- style.marginRight = marginSize;
- }
- },
-
- _setBorder: function (el, n, corners) {
- var borderSize = this._borderSize(n) + "px";
- var whichSide = (
- corners == "top" ? this._whichSideTop() : this._whichSideBottom()
- );
-
- var style = el.style;
- if (whichSide == "left") {
- style.borderLeftWidth = borderSize;
- style.borderRightWidth = "0px";
- } else if (whichSide == "right") {
- style.borderRightWidth = borderSize;
- style.borderLeftWidth = "0px";
- } else {
- style.borderLeftWidth = borderSize;
- style.borderRightWidth = borderSize;
- }
- },
-
- _marginSize: function (n) {
- if (this.isTransparent) {
- return 0;
- }
-
- var o = this.options;
- if (o.compact && o.blend) {
- var smBlendedMarginSizes = [1, 0];
- return smBlendedMarginSizes[n];
- } else if (o.compact) {
- var compactMarginSizes = [2, 1];
- return compactMarginSizes[n];
- } else if (o.blend) {
- var blendedMarginSizes = [3, 2, 1, 0];
- return blendedMarginSizes[n];
- } else {
- var marginSizes = [5, 3, 2, 1];
- return marginSizes[n];
- }
- },
-
- _borderSize: function (n) {
- var o = this.options;
- var borderSizes;
- if (o.compact && (o.blend || this.isTransparent)) {
- return 1;
- } else if (o.compact) {
- borderSizes = [1, 0];
- } else if (o.blend) {
- borderSizes = [2, 1, 1, 1];
- } else if (o.border) {
- borderSizes = [0, 2, 0, 0];
- } else if (this.isTransparent) {
- borderSizes = [5, 3, 2, 1];
- } else {
- return 0;
- }
- return borderSizes[n];
- },
-
- _hasString: function (str) {
- for (var i = 1; i< arguments.length; i++) {
- if (str.indexOf(arguments[i]) != -1) {
- return true;
- }
- }
- return false;
- },
-
- _isTopRounded: function () {
- return this._hasString(this.options.corners,
- "all", "top", "tl", "tr"
- );
- },
-
- _isBottomRounded: function () {
- return this._hasString(this.options.corners,
- "all", "bottom", "bl", "br"
- );
- },
-
- _hasSingleTextChild: function (el) {
- return (el.childNodes.length == 1 && el.childNodes[0].nodeType == 3);
- }
-};
-
-/** @id MochiKit.Visual.roundElement */
-MochiKit.Visual.roundElement = function (e, options) {
- new MochiKit.Visual._RoundCorners(e, options);
-};
-
-/** @id MochiKit.Visual.roundClass */
-MochiKit.Visual.roundClass = function (tagName, className, options) {
- var elements = MochiKit.DOM.getElementsByTagAndClassName(
- tagName, className
- );
- for (var i = 0; i < elements.length; i++) {
- MochiKit.Visual.roundElement(elements[i], options);
- }
-};
-
-/** @id MochiKit.Visual.tagifyText */
-MochiKit.Visual.tagifyText = function (element, /* optional */tagifyStyle) {
- /***
-
- Change a node text to character in tags.
-
- @param tagifyStyle: the style to apply to character nodes, default to
- 'position: relative'.
-
- ***/
- var tagifyStyle = tagifyStyle || 'position:relative';
- if (/MSIE/.test(navigator.userAgent)) {
- tagifyStyle += ';zoom:1';
- }
- element = MochiKit.DOM.getElement(element);
- var ma = MochiKit.Base.map;
- ma(function (child) {
- if (child.nodeType == 3) {
- ma(function (character) {
- element.insertBefore(
- MochiKit.DOM.SPAN({style: tagifyStyle},
- character == ' ' ? String.fromCharCode(160) : character), child);
- }, child.nodeValue.split(''));
- MochiKit.DOM.removeElement(child);
- }
- }, element.childNodes);
-};
-
-/** @id MochiKit.Visual.forceRerendering */
-MochiKit.Visual.forceRerendering = function (element) {
- try {
- element = MochiKit.DOM.getElement(element);
- var n = document.createTextNode(' ');
- element.appendChild(n);
- element.removeChild(n);
- } catch(e) {
- }
-};
-
-/** @id MochiKit.Visual.multiple */
-MochiKit.Visual.multiple = function (elements, effect, /* optional */options) {
- /***
-
- Launch the same effect subsequently on given elements.
-
- ***/
- options = MochiKit.Base.update({
- speed: 0.1, delay: 0.0
- }, options || {});
- var masterDelay = options.delay;
- var index = 0;
- MochiKit.Base.map(function (innerelement) {
- options.delay = index * options.speed + masterDelay;
- new effect(innerelement, options);
- index += 1;
- }, elements);
-};
-
-MochiKit.Visual.PAIRS = {
- 'slide': ['slideDown', 'slideUp'],
- 'blind': ['blindDown', 'blindUp'],
- 'appear': ['appear', 'fade'],
- 'size': ['grow', 'shrink']
-};
-
-/** @id MochiKit.Visual.toggle */
-MochiKit.Visual.toggle = function (element, /* optional */effect, /* optional */options) {
- /***
-
- Toggle an item between two state depending of its visibility, making
- a effect between these states. Default effect is 'appear', can be
- 'slide' or 'blind'.
-
- ***/
- element = MochiKit.DOM.getElement(element);
- effect = (effect || 'appear').toLowerCase();
- options = MochiKit.Base.update({
- queue: {position: 'end', scope: (element.id || 'global'), limit: 1}
- }, options || {});
- var v = MochiKit.Visual;
- v[element.style.display != 'none' ?
- v.PAIRS[effect][1] : v.PAIRS[effect][0]](element, options);
-};
-
-/***
-
-Transitions: define functions calculating variations depending of a position.
-
-***/
-
-MochiKit.Visual.Transitions = {}
-
-/** @id MochiKit.Visual.Transitions.linear */
-MochiKit.Visual.Transitions.linear = function (pos) {
- return pos;
-};
-
-/** @id MochiKit.Visual.Transitions.sinoidal */
-MochiKit.Visual.Transitions.sinoidal = function (pos) {
- return (-Math.cos(pos*Math.PI)/2) + 0.5;
-};
-
-/** @id MochiKit.Visual.Transitions.reverse */
-MochiKit.Visual.Transitions.reverse = function (pos) {
- return 1 - pos;
-};
-
-/** @id MochiKit.Visual.Transitions.flicker */
-MochiKit.Visual.Transitions.flicker = function (pos) {
- return ((-Math.cos(pos*Math.PI)/4) + 0.75) + Math.random()/4;
-};
-
-/** @id MochiKit.Visual.Transitions.wobble */
-MochiKit.Visual.Transitions.wobble = function (pos) {
- return (-Math.cos(pos*Math.PI*(9*pos))/2) + 0.5;
-};
-
-/** @id MochiKit.Visual.Transitions.pulse */
-MochiKit.Visual.Transitions.pulse = function (pos) {
- return (Math.floor(pos*10) % 2 == 0 ?
- (pos*10 - Math.floor(pos*10)) : 1 - (pos*10 - Math.floor(pos*10)));
-};
-
-/** @id MochiKit.Visual.Transitions.none */
-MochiKit.Visual.Transitions.none = function (pos) {
- return 0;
-};
-
-/** @id MochiKit.Visual.Transitions.full */
-MochiKit.Visual.Transitions.full = function (pos) {
- return 1;
-};
-
-/***
-
-Core effects
-
-***/
-
-MochiKit.Visual.ScopedQueue = function () {
- this.__init__();
-};
-
-MochiKit.Base.update(MochiKit.Visual.ScopedQueue.prototype, {
- __init__: function () {
- this.effects = [];
- this.interval = null;
- },
-
- /** @id MochiKit.Visual.ScopedQueue.prototype.add */
- add: function (effect) {
- var timestamp = new Date().getTime();
-
- var position = (typeof(effect.options.queue) == 'string') ?
- effect.options.queue : effect.options.queue.position;
-
- var ma = MochiKit.Base.map;
- switch (position) {
- case 'front':
- // move unstarted effects after this effect
- ma(function (e) {
- if (e.state == 'idle') {
- e.startOn += effect.finishOn;
- e.finishOn += effect.finishOn;
- }
- }, this.effects);
- break;
- case 'end':
- var finish;
- // start effect after last queued effect has finished
- ma(function (e) {
- var i = e.finishOn;
- if (i >= (finish || i)) {
- finish = i;
- }
- }, this.effects);
- timestamp = finish || timestamp;
- break;
- case 'break':
- ma(function (e) {
- e.finalize();
- }, this.effects);
- break;
- }
-
- effect.startOn += timestamp;
- effect.finishOn += timestamp;
- if (!effect.options.queue.limit ||
- this.effects.length < effect.options.queue.limit) {
- this.effects.push(effect);
- }
-
- if (!this.interval) {
- this.interval = this.startLoop(MochiKit.Base.bind(this.loop, this),
- 40);
- }
- },
-
- /** @id MochiKit.Visual.ScopedQueue.prototype.startLoop */
- startLoop: function (func, interval) {
- return setInterval(func, interval)
- },
-
- /** @id MochiKit.Visual.ScopedQueue.prototype.remove */
- remove: function (effect) {
- this.effects = MochiKit.Base.filter(function (e) {
- return e != effect;
- }, this.effects);
- if (this.effects.length == 0) {
- this.stopLoop(this.interval);
- this.interval = null;
- }
- },
-
- /** @id MochiKit.Visual.ScopedQueue.prototype.stopLoop */
- stopLoop: function (interval) {
- clearInterval(interval)
- },
-
- /** @id MochiKit.Visual.ScopedQueue.prototype.loop */
- loop: function () {
- var timePos = new Date().getTime();
- MochiKit.Base.map(function (effect) {
- effect.loop(timePos);
- }, this.effects);
- }
-});
-
-MochiKit.Visual.Queues = {
- instances: {},
-
- get: function (queueName) {
- if (typeof(queueName) != 'string') {
- return queueName;
- }
-
- if (!this.instances[queueName]) {
- this.instances[queueName] = new MochiKit.Visual.ScopedQueue();
- }
- return this.instances[queueName];
- }
-};
-
-MochiKit.Visual.Queue = MochiKit.Visual.Queues.get('global');
-
-MochiKit.Visual.DefaultOptions = {
- transition: MochiKit.Visual.Transitions.sinoidal,
- duration: 1.0, // seconds
- fps: 25.0, // max. 25fps due to MochiKit.Visual.Queue implementation
- sync: false, // true for combining
- from: 0.0,
- to: 1.0,
- delay: 0.0,
- queue: 'parallel'
-};
-
-MochiKit.Visual.Base = function () {};
-
-MochiKit.Visual.Base.prototype = {
- /***
-
- Basic class for all Effects. Define a looping mechanism called for each step
- of an effect. Don't instantiate it, only subclass it.
-
- ***/
-
- __class__ : MochiKit.Visual.Base,
-
- /** @id MochiKit.Visual.Base.prototype.start */
- start: function (options) {
- var v = MochiKit.Visual;
- this.options = MochiKit.Base.setdefault(options || {},
- v.DefaultOptions);
- this.currentFrame = 0;
- this.state = 'idle';
- this.startOn = this.options.delay*1000;
- this.finishOn = this.startOn + (this.options.duration*1000);
- this.event('beforeStart');
- if (!this.options.sync) {
- v.Queues.get(typeof(this.options.queue) == 'string' ?
- 'global' : this.options.queue.scope).add(this);
- }
- },
-
- /** @id MochiKit.Visual.Base.prototype.loop */
- loop: function (timePos) {
- if (timePos >= this.startOn) {
- if (timePos >= this.finishOn) {
- return this.finalize();
- }
- var pos = (timePos - this.startOn) / (this.finishOn - this.startOn);
- var frame =
- Math.round(pos * this.options.fps * this.options.duration);
- if (frame > this.currentFrame) {
- this.render(pos);
- this.currentFrame = frame;
- }
- }
- },
-
- /** @id MochiKit.Visual.Base.prototype.render */
- render: function (pos) {
- if (this.state == 'idle') {
- this.state = 'running';
- this.event('beforeSetup');
- this.setup();
- this.event('afterSetup');
- }
- if (this.state == 'running') {
- if (this.options.transition) {
- pos = this.options.transition(pos);
- }
- pos *= (this.options.to - this.options.from);
- pos += this.options.from;
- this.event('beforeUpdate');
- this.update(pos);
- this.event('afterUpdate');
- }
- },
-
- /** @id MochiKit.Visual.Base.prototype.cancel */
- cancel: function () {
- if (!this.options.sync) {
- MochiKit.Visual.Queues.get(typeof(this.options.queue) == 'string' ?
- 'global' : this.options.queue.scope).remove(this);
- }
- this.state = 'finished';
- },
-
- /** @id MochiKit.Visual.Base.prototype.finalize */
- finalize: function () {
- this.render(1.0);
- this.cancel();
- this.event('beforeFinish');
- this.finish();
- this.event('afterFinish');
- },
-
- setup: function () {
- },
-
- finish: function () {
- },
-
- update: function (position) {
- },
-
- /** @id MochiKit.Visual.Base.prototype.event */
- event: function (eventName) {
- if (this.options[eventName + 'Internal']) {
- this.options[eventName + 'Internal'](this);
- }
- if (this.options[eventName]) {
- this.options[eventName](this);
- }
- },
-
- /** @id MochiKit.Visual.Base.prototype.repr */
- repr: function () {
- return '[' + this.__class__.NAME + ', options:' +
- MochiKit.Base.repr(this.options) + ']';
- }
-}
-
- /** @id MochiKit.Visual.Parallel */
-MochiKit.Visual.Parallel = function (effects, options) {
- this.__init__(effects, options);
-};
-
-MochiKit.Visual.Parallel.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.Parallel.prototype, {
- /***
-
- Run multiple effects at the same time.
-
- ***/
- __init__: function (effects, options) {
- this.effects = effects || [];
- this.start(options);
- },
-
- /** @id MochiKit.Visual.Parallel.prototype.update */
- update: function (position) {
- MochiKit.Base.map(function (effect) {
- effect.render(position);
- }, this.effects);
- },
-
- /** @id MochiKit.Visual.Parallel.prototype.finish */
- finish: function () {
- MochiKit.Base.map(function (effect) {
- effect.finalize();
- }, this.effects);
- }
-});
-
-/** @id MochiKit.Visual.Opacity */
-MochiKit.Visual.Opacity = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.Visual.Opacity.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.Opacity.prototype, {
- /***
-
- Change the opacity of an element.
-
- @param options: 'from' and 'to' change the starting and ending opacities.
- Must be between 0.0 and 1.0. Default to current opacity and 1.0.
-
- ***/
- __init__: function (element, /* optional */options) {
- var b = MochiKit.Base;
- var s = MochiKit.Style;
- this.element = MochiKit.DOM.getElement(element);
- // make this work on IE on elements without 'layout'
- if (this.element.currentStyle &&
- (!this.element.currentStyle.hasLayout)) {
- s.setStyle(this.element, {zoom: 1});
- }
- options = b.update({
- from: s.getOpacity(this.element) || 0.0,
- to: 1.0
- }, options || {});
- this.start(options);
- },
-
- /** @id MochiKit.Visual.Opacity.prototype.update */
- update: function (position) {
- MochiKit.Style.setOpacity(this.element, position);
- }
-});
-
-/** @id MochiKit.Visual.Opacity.prototype.Move */
-MochiKit.Visual.Move = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.Visual.Move.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.Move.prototype, {
- /***
-
- Move an element between its current position to a defined position
-
- @param options: 'x' and 'y' for final positions, default to 0, 0.
-
- ***/
- __init__: function (element, /* optional */options) {
- this.element = MochiKit.DOM.getElement(element);
- options = MochiKit.Base.update({
- x: 0,
- y: 0,
- mode: 'relative'
- }, options || {});
- this.start(options);
- },
-
- /** @id MochiKit.Visual.Move.prototype.setup */
- setup: function () {
- // Bug in Opera: Opera returns the 'real' position of a static element
- // or relative element that does not have top/left explicitly set.
- // ==> Always set top and left for position relative elements in your
- // stylesheets (to 0 if you do not need them)
- MochiKit.DOM.makePositioned(this.element);
-
- var s = this.element.style;
- var originalVisibility = s.visibility;
- var originalDisplay = s.display;
- if (originalDisplay == 'none') {
- s.visibility = 'hidden';
- s.display = '';
- }
-
- this.originalLeft = parseFloat(MochiKit.Style.getStyle(this.element, 'left') || '0');
- this.originalTop = parseFloat(MochiKit.Style.getStyle(this.element, 'top') || '0');
-
- if (this.options.mode == 'absolute') {
- // absolute movement, so we need to calc deltaX and deltaY
- this.options.x -= this.originalLeft;
- this.options.y -= this.originalTop;
- }
- if (originalDisplay == 'none') {
- s.visibility = originalVisibility;
- s.display = originalDisplay;
- }
- },
-
- /** @id MochiKit.Visual.Move.prototype.update */
- update: function (position) {
- MochiKit.Style.setStyle(this.element, {
- left: Math.round(this.options.x * position + this.originalLeft) + 'px',
- top: Math.round(this.options.y * position + this.originalTop) + 'px'
- });
- }
-});
-
-/** @id MochiKit.Visual.Scale */
-MochiKit.Visual.Scale = function (element, percent, options) {
- this.__init__(element, percent, options);
-};
-
-MochiKit.Visual.Scale.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.Scale.prototype, {
- /***
-
- Change the size of an element.
-
- @param percent: final_size = percent*original_size
-
- @param options: several options changing scale behaviour
-
- ***/
- __init__: function (element, percent, /* optional */options) {
- this.element = MochiKit.DOM.getElement(element)
- options = MochiKit.Base.update({
- scaleX: true,
- scaleY: true,
- scaleContent: true,
- scaleFromCenter: false,
- scaleMode: 'box', // 'box' or 'contents' or {} with provided values
- scaleFrom: 100.0,
- scaleTo: percent
- }, options || {});
- this.start(options);
- },
-
- /** @id MochiKit.Visual.Scale.prototype.setup */
- setup: function () {
- this.restoreAfterFinish = this.options.restoreAfterFinish || false;
- this.elementPositioning = MochiKit.Style.getStyle(this.element,
- 'position');
-
- var ma = MochiKit.Base.map;
- var b = MochiKit.Base.bind;
- this.originalStyle = {};
- ma(b(function (k) {
- this.originalStyle[k] = this.element.style[k];
- }, this), ['top', 'left', 'width', 'height', 'fontSize']);
-
- this.originalTop = this.element.offsetTop;
- this.originalLeft = this.element.offsetLeft;
-
- var fontSize = MochiKit.Style.getStyle(this.element,
- 'font-size') || '100%';
- ma(b(function (fontSizeType) {
- if (fontSize.indexOf(fontSizeType) > 0) {
- this.fontSize = parseFloat(fontSize);
- this.fontSizeType = fontSizeType;
- }
- }, this), ['em', 'px', '%']);
-
- this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
-
- if (/^content/.test(this.options.scaleMode)) {
- this.dims = [this.element.scrollHeight, this.element.scrollWidth];
- } else if (this.options.scaleMode == 'box') {
- this.dims = [this.element.offsetHeight, this.element.offsetWidth];
- } else {
- this.dims = [this.options.scaleMode.originalHeight,
- this.options.scaleMode.originalWidth];
- }
- },
-
- /** @id MochiKit.Visual.Scale.prototype.update */
- update: function (position) {
- var currentScale = (this.options.scaleFrom/100.0) +
- (this.factor * position);
- if (this.options.scaleContent && this.fontSize) {
- MochiKit.Style.setStyle(this.element, {
- fontSize: this.fontSize * currentScale + this.fontSizeType
- });
- }
- this.setDimensions(this.dims[0] * currentScale,
- this.dims[1] * currentScale);
- },
-
- /** @id MochiKit.Visual.Scale.prototype.finish */
- finish: function () {
- if (this.restoreAfterFinish) {
- MochiKit.Style.setStyle(this.element, this.originalStyle);
- }
- },
-
- /** @id MochiKit.Visual.Scale.prototype.setDimensions */
- setDimensions: function (height, width) {
- var d = {};
- var r = Math.round;
- if (/MSIE/.test(navigator.userAgent)) {
- r = Math.ceil;
- }
- if (this.options.scaleX) {
- d.width = r(width) + 'px';
- }
- if (this.options.scaleY) {
- d.height = r(height) + 'px';
- }
- if (this.options.scaleFromCenter) {
- var topd = (height - this.dims[0])/2;
- var leftd = (width - this.dims[1])/2;
- if (this.elementPositioning == 'absolute') {
- if (this.options.scaleY) {
- d.top = this.originalTop - topd + 'px';
- }
- if (this.options.scaleX) {
- d.left = this.originalLeft - leftd + 'px';
- }
- } else {
- if (this.options.scaleY) {
- d.top = -topd + 'px';
- }
- if (this.options.scaleX) {
- d.left = -leftd + 'px';
- }
- }
- }
- MochiKit.Style.setStyle(this.element, d);
- }
-});
-
-/** @id MochiKit.Visual.Highlight */
-MochiKit.Visual.Highlight = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.Visual.Highlight.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.Highlight.prototype, {
- /***
-
- Highlight an item of the page.
-
- @param options: 'startcolor' for choosing highlighting color, default
- to '#ffff99'.
-
- ***/
- __init__: function (element, /* optional */options) {
- this.element = MochiKit.DOM.getElement(element);
- options = MochiKit.Base.update({
- startcolor: '#ffff99'
- }, options || {});
- this.start(options);
- },
-
- /** @id MochiKit.Visual.Highlight.prototype.setup */
- setup: function () {
- var b = MochiKit.Base;
- var s = MochiKit.Style;
- // Prevent executing on elements not in the layout flow
- if (s.getStyle(this.element, 'display') == 'none') {
- this.cancel();
- return;
- }
- // Disable background image during the effect
- this.oldStyle = {
- backgroundImage: s.getStyle(this.element, 'background-image')
- };
- s.setStyle(this.element, {
- backgroundImage: 'none'
- });
-
- if (!this.options.endcolor) {
- this.options.endcolor =
- MochiKit.Color.Color.fromBackground(this.element).toHexString();
- }
- if (b.isUndefinedOrNull(this.options.restorecolor)) {
- this.options.restorecolor = s.getStyle(this.element,
- 'background-color');
- }
- // init color calculations
- this._base = b.map(b.bind(function (i) {
- return parseInt(
- this.options.startcolor.slice(i*2 + 1, i*2 + 3), 16);
- }, this), [0, 1, 2]);
- this._delta = b.map(b.bind(function (i) {
- return parseInt(this.options.endcolor.slice(i*2 + 1, i*2 + 3), 16)
- - this._base[i];
- }, this), [0, 1, 2]);
- },
-
- /** @id MochiKit.Visual.Highlight.prototype.update */
- update: function (position) {
- var m = '#';
- MochiKit.Base.map(MochiKit.Base.bind(function (i) {
- m += MochiKit.Color.toColorPart(Math.round(this._base[i] +
- this._delta[i]*position));
- }, this), [0, 1, 2]);
- MochiKit.Style.setStyle(this.element, {
- backgroundColor: m
- });
- },
-
- /** @id MochiKit.Visual.Highlight.prototype.finish */
- finish: function () {
- MochiKit.Style.setStyle(this.element,
- MochiKit.Base.update(this.oldStyle, {
- backgroundColor: this.options.restorecolor
- }));
- }
-});
-
-/** @id MochiKit.Visual.ScrollTo */
-MochiKit.Visual.ScrollTo = function (element, options) {
- this.__init__(element, options);
-};
-
-MochiKit.Visual.ScrollTo.prototype = new MochiKit.Visual.Base();
-
-MochiKit.Base.update(MochiKit.Visual.ScrollTo.prototype, {
- /***
-
- Scroll to an element in the page.
-
- ***/
- __init__: function (element, /* optional */options) {
- this.element = MochiKit.DOM.getElement(element);
- this.start(options || {});
- },
-
- /** @id MochiKit.Visual.ScrollTo.prototype.setup */
- setup: function () {
- var p = MochiKit.Position;
- p.prepare();
- var offsets = p.cumulativeOffset(this.element);
- if (this.options.offset) {
- offsets.y += this.options.offset;
- }
- var max;
- if (window.innerHeight) {
- max = window.innerHeight - window.height;
- } else if (document.documentElement &&
- document.documentElement.clientHeight) {
- max = document.documentElement.clientHeight -
- document.body.scrollHeight;
- } else if (document.body) {
- max = document.body.clientHeight - document.body.scrollHeight;
- }
- this.scrollStart = p.windowOffset.y;
- this.delta = (offsets.y > max ? max : offsets.y) - this.scrollStart;
- },
-
- /** @id MochiKit.Visual.ScrollTo.prototype.update */
- update: function (position) {
- var p = MochiKit.Position;
- p.prepare();
- window.scrollTo(p.windowOffset.x, this.scrollStart + (position * this.delta));
- }
-});
-
-/***
-
-Combination effects.
-
-***/
-
-/** @id MochiKit.Visual.fade */
-MochiKit.Visual.fade = function (element, /* optional */ options) {
- /***
-
- Fade a given element: change its opacity and hide it in the end.
-
- @param options: 'to' and 'from' to change opacity.
-
- ***/
- var s = MochiKit.Style;
- var oldOpacity = MochiKit.DOM.getElement(element).style.opacity || '';
- options = MochiKit.Base.update({
- from: s.getOpacity(element) || 1.0,
- to: 0.0,
- afterFinishInternal: function (effect) {
- if (effect.options.to !== 0) {
- return;
- }
- s.hideElement(effect.element);
- s.setStyle(effect.element, {opacity: oldOpacity});
- }
- }, options || {});
- return new MochiKit.Visual.Opacity(element, options);
-};
-
-/** @id MochiKit.Visual.appear */
-MochiKit.Visual.appear = function (element, /* optional */ options) {
- /***
-
- Make an element appear.
-
- @param options: 'to' and 'from' to change opacity.
-
- ***/
- var s = MochiKit.Style;
- var v = MochiKit.Visual;
- options = MochiKit.Base.update({
- from: (s.getStyle(element, 'display') == 'none' ? 0.0 :
- s.getOpacity(element) || 0.0),
- to: 1.0,
- // force Safari to render floated elements properly
- afterFinishInternal: function (effect) {
- v.forceRerendering(effect.element);
- },
- beforeSetupInternal: function (effect) {
- s.setOpacity(effect.element, effect.options.from);
- s.showElement(effect.element);
- }
- }, options || {});
- return new v.Opacity(element, options);
-};
-
-/** @id MochiKit.Visual.puff */
-MochiKit.Visual.puff = function (element, /* optional */ options) {
- /***
-
- 'Puff' an element: grow it to double size, fading it and make it hidden.
-
- ***/
- var s = MochiKit.Style;
- var v = MochiKit.Visual;
- element = MochiKit.DOM.getElement(element);
- var oldStyle = {
- opacity: element.style.opacity || '',
- position: s.getStyle(element, 'position'),
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height
- };
- options = MochiKit.Base.update({
- beforeSetupInternal: function (effect) {
- MochiKit.Position.absolutize(effect.effects[0].element)
- },
- afterFinishInternal: function (effect) {
- s.hideElement(effect.effects[0].element);
- s.setStyle(effect.effects[0].element, oldStyle);
- }
- }, options || {});
- return new v.Parallel(
- [new v.Scale(element, 200,
- {sync: true, scaleFromCenter: true,
- scaleContent: true, restoreAfterFinish: true}),
- new v.Opacity(element, {sync: true, to: 0.0 })],
- options);
-};
-
-/** @id MochiKit.Visual.blindUp */
-MochiKit.Visual.blindUp = function (element, /* optional */ options) {
- /***
-
- Blind an element up: change its vertical size to 0.
-
- ***/
- var d = MochiKit.DOM;
- element = d.getElement(element);
- var elemClip = d.makeClipping(element);
- options = MochiKit.Base.update({
- scaleContent: false,
- scaleX: false,
- restoreAfterFinish: true,
- afterFinishInternal: function (effect) {
- MochiKit.Style.hideElement(effect.element);
- d.undoClipping(effect.element, elemClip);
- }
- }, options || {});
-
- return new MochiKit.Visual.Scale(element, 0, options);
-};
-
-/** @id MochiKit.Visual.blindDown */
-MochiKit.Visual.blindDown = function (element, /* optional */ options) {
- /***
-
- Blind an element down: restore its vertical size.
-
- ***/
- var d = MochiKit.DOM;
- var s = MochiKit.Style;
- element = d.getElement(element);
- var elementDimensions = s.getElementDimensions(element);
- var elemClip;
- options = MochiKit.Base.update({
- scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.h,
- originalWidth: elementDimensions.w},
- restoreAfterFinish: true,
- afterSetupInternal: function (effect) {
- elemClip = d.makeClipping(effect.element);
- s.setStyle(effect.element, {height: '0px'});
- s.showElement(effect.element);
- },
- afterFinishInternal: function (effect) {
- d.undoClipping(effect.element, elemClip);
- }
- }, options || {});
- return new MochiKit.Visual.Scale(element, 100, options);
-};
-
-/** @id MochiKit.Visual.switchOff */
-MochiKit.Visual.switchOff = function (element, /* optional */ options) {
- /***
-
- Apply a switch-off-like effect.
-
- ***/
- var d = MochiKit.DOM;
- element = d.getElement(element);
- var oldOpacity = element.style.opacity || '';
- var elemClip;
- var options = MochiKit.Base.update({
- duration: 0.3,
- scaleFromCenter: true,
- scaleX: false,
- scaleContent: false,
- restoreAfterFinish: true,
- beforeSetupInternal: function (effect) {
- d.makePositioned(effect.element);
- elemClip = d.makeClipping(effect.element);
- },
- afterFinishInternal: function (effect) {
- MochiKit.Style.hideElement(effect.element);
- d.undoClipping(effect.element, elemClip);
- d.undoPositioned(effect.element);
- MochiKit.Style.setStyle(effect.element, {opacity: oldOpacity});
- }
- }, options || {});
- var v = MochiKit.Visual;
- return new v.appear(element, {
- duration: 0.4,
- from: 0,
- transition: v.Transitions.flicker,
- afterFinishInternal: function (effect) {
- new v.Scale(effect.element, 1, options)
- }
- });
-};
-
-/** @id MochiKit.Visual.dropOut */
-MochiKit.Visual.dropOut = function (element, /* optional */ options) {
- /***
-
- Make an element fall and disappear.
-
- ***/
- var d = MochiKit.DOM;
- var s = MochiKit.Style;
- element = d.getElement(element);
- var oldStyle = {
- top: s.getStyle(element, 'top'),
- left: s.getStyle(element, 'left'),
- opacity: element.style.opacity || ''
- };
-
- options = MochiKit.Base.update({
- duration: 0.5,
- beforeSetupInternal: function (effect) {
- d.makePositioned(effect.effects[0].element);
- },
- afterFinishInternal: function (effect) {
- s.hideElement(effect.effects[0].element);
- d.undoPositioned(effect.effects[0].element);
- s.setStyle(effect.effects[0].element, oldStyle);
- }
- }, options || {});
- var v = MochiKit.Visual;
- return new v.Parallel(
- [new v.Move(element, {x: 0, y: 100, sync: true}),
- new v.Opacity(element, {sync: true, to: 0.0})],
- options);
-};
-
-/** @id MochiKit.Visual.shake */
-MochiKit.Visual.shake = function (element, /* optional */ options) {
- /***
-
- Move an element from left to right several times.
-
- ***/
- var d = MochiKit.DOM;
- var v = MochiKit.Visual;
- var s = MochiKit.Style;
- element = d.getElement(element);
- options = MochiKit.Base.update({
- x: -20,
- y: 0,
- duration: 0.05,
- afterFinishInternal: function (effect) {
- d.undoPositioned(effect.element);
- s.setStyle(effect.element, oldStyle);
- }
- }, options || {});
- var oldStyle = {
- top: s.getStyle(element, 'top'),
- left: s.getStyle(element, 'left') };
- return new v.Move(element,
- {x: 20, y: 0, duration: 0.05, afterFinishInternal: function (effect) {
- new v.Move(effect.element,
- {x: -40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
- new v.Move(effect.element,
- {x: 40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
- new v.Move(effect.element,
- {x: -40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
- new v.Move(effect.element,
- {x: 40, y: 0, duration: 0.1, afterFinishInternal: function (effect) {
- new v.Move(effect.element, options
- ) }}) }}) }}) }}) }});
-};
-
-/** @id MochiKit.Visual.slideDown */
-MochiKit.Visual.slideDown = function (element, /* optional */ options) {
- /***
-
- Slide an element down.
- It needs to have the content of the element wrapped in a container
- element with fixed height.
-
- ***/
- var d = MochiKit.DOM;
- var b = MochiKit.Base;
- var s = MochiKit.Style;
- element = d.getElement(element);
- if (!element.firstChild) {
- throw "MochiKit.Visual.slideDown must be used on a element with a child";
- }
- d.removeEmptyTextNodes(element);
- var oldInnerBottom = s.getStyle(element.firstChild, 'bottom') || 0;
- var elementDimensions = s.getElementDimensions(element);
- var elemClip;
- options = b.update({
- scaleContent: false,
- scaleX: false,
- scaleFrom: 0,
- scaleMode: {originalHeight: elementDimensions.h,
- originalWidth: elementDimensions.w},
- restoreAfterFinish: true,
- afterSetupInternal: function (effect) {
- d.makePositioned(effect.element);
- d.makePositioned(effect.element.firstChild);
- if (/Opera/.test(navigator.userAgent)) {
- s.setStyle(effect.element, {top: ''});
- }
- elemClip = d.makeClipping(effect.element);
- s.setStyle(effect.element, {height: '0px'});
- s.showElement(effect.element);
- },
- afterUpdateInternal: function (effect) {
- s.setStyle(effect.element.firstChild,
- {bottom: (effect.dims[0] - effect.element.clientHeight) + 'px'})
- },
- afterFinishInternal: function (effect) {
- d.undoClipping(effect.element, elemClip);
- // IE will crash if child is undoPositioned first
- if (/MSIE/.test(navigator.userAgent)) {
- d.undoPositioned(effect.element);
- d.undoPositioned(effect.element.firstChild);
- } else {
- d.undoPositioned(effect.element.firstChild);
- d.undoPositioned(effect.element);
- }
- s.setStyle(effect.element.firstChild,
- {bottom: oldInnerBottom});
- }
- }, options || {});
-
- return new MochiKit.Visual.Scale(element, 100, options);
-};
-
-/** @id MochiKit.Visual.slideUp */
-MochiKit.Visual.slideUp = function (element, /* optional */ options) {
- /***
-
- Slide an element up.
- It needs to have the content of the element wrapped in a container
- element with fixed height.
-
- ***/
- var d = MochiKit.DOM;
- var b = MochiKit.Base;
- var s = MochiKit.Style;
- element = d.getElement(element);
- if (!element.firstChild) {
- throw "MochiKit.Visual.slideUp must be used on a element with a child";
- }
- d.removeEmptyTextNodes(element);
- var oldInnerBottom = s.getStyle(element.firstChild, 'bottom');
- var elemClip;
- options = b.update({
- scaleContent: false,
- scaleX: false,
- scaleMode: 'box',
- scaleFrom: 100,
- restoreAfterFinish: true,
- beforeStartInternal: function (effect) {
- d.makePositioned(effect.element);
- d.makePositioned(effect.element.firstChild);
- if (/Opera/.test(navigator.userAgent)) {
- s.setStyle(effect.element, {top: ''});
- }
- elemClip = d.makeClipping(effect.element);
- s.showElement(effect.element);
- },
- afterUpdateInternal: function (effect) {
- s.setStyle(effect.element.firstChild,
- {bottom: (effect.dims[0] - effect.element.clientHeight) + 'px'});
- },
- afterFinishInternal: function (effect) {
- s.hideElement(effect.element);
- d.undoClipping(effect.element, elemClip);
- d.undoPositioned(effect.element.firstChild);
- d.undoPositioned(effect.element);
- s.setStyle(effect.element.firstChild, {bottom: oldInnerBottom});
- }
- }, options || {});
- return new MochiKit.Visual.Scale(element, 0, options);
-};
-
-// Bug in opera makes the TD containing this element expand for a instance
-// after finish
-/** @id MochiKit.Visual.squish */
-MochiKit.Visual.squish = function (element, /* optional */ options) {
- /***
-
- Reduce an element and make it disappear.
-
- ***/
- var d = MochiKit.DOM;
- var b = MochiKit.Base;
- var elemClip;
- options = b.update({
- restoreAfterFinish: true,
- beforeSetupInternal: function (effect) {
- elemClip = d.makeClipping(effect.element);
- },
- afterFinishInternal: function (effect) {
- MochiKit.Style.hideElement(effect.element);
- d.undoClipping(effect.element, elemClip);
- }
- }, options || {});
-
- return new MochiKit.Visual.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, options);
-};
-
-/** @id MochiKit.Visual.grow */
-MochiKit.Visual.grow = function (element, /* optional */ options) {
- /***
-
- Grow an element to its original size. Make it zero-sized before
- if necessary.
-
- ***/
- var d = MochiKit.DOM;
- var v = MochiKit.Visual;
- var s = MochiKit.Style;
- element = d.getElement(element);
- options = MochiKit.Base.update({
- direction: 'center',
- moveTransition: v.Transitions.sinoidal,
- scaleTransition: v.Transitions.sinoidal,
- opacityTransition: v.Transitions.full
- }, options || {});
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.style.opacity || ''
- };
-
- var dims = s.getElementDimensions(element);
- var initialMoveX, initialMoveY;
- var moveX, moveY;
-
- switch (options.direction) {
- case 'top-left':
- initialMoveX = initialMoveY = moveX = moveY = 0;
- break;
- case 'top-right':
- initialMoveX = dims.w;
- initialMoveY = moveY = 0;
- moveX = -dims.w;
- break;
- case 'bottom-left':
- initialMoveX = moveX = 0;
- initialMoveY = dims.h;
- moveY = -dims.h;
- break;
- case 'bottom-right':
- initialMoveX = dims.w;
- initialMoveY = dims.h;
- moveX = -dims.w;
- moveY = -dims.h;
- break;
- case 'center':
- initialMoveX = dims.w / 2;
- initialMoveY = dims.h / 2;
- moveX = -dims.w / 2;
- moveY = -dims.h / 2;
- break;
- }
-
- var optionsParallel = MochiKit.Base.update({
- beforeSetupInternal: function (effect) {
- s.setStyle(effect.effects[0].element, {height: '0px'});
- s.showElement(effect.effects[0].element);
- },
- afterFinishInternal: function (effect) {
- d.undoClipping(effect.effects[0].element);
- d.undoPositioned(effect.effects[0].element);
- s.setStyle(effect.effects[0].element, oldStyle);
- }
- }, options || {});
-
- return new v.Move(element, {
- x: initialMoveX,
- y: initialMoveY,
- duration: 0.01,
- beforeSetupInternal: function (effect) {
- s.hideElement(effect.element);
- d.makeClipping(effect.element);
- d.makePositioned(effect.element);
- },
- afterFinishInternal: function (effect) {
- new v.Parallel(
- [new v.Opacity(effect.element, {
- sync: true, to: 1.0, from: 0.0,
- transition: options.opacityTransition
- }),
- new v.Move(effect.element, {
- x: moveX, y: moveY, sync: true,
- transition: options.moveTransition
- }),
- new v.Scale(effect.element, 100, {
- scaleMode: {originalHeight: dims.h,
- originalWidth: dims.w},
- sync: true,
- scaleFrom: /Opera/.test(navigator.userAgent) ? 1 : 0,
- transition: options.scaleTransition,
- restoreAfterFinish: true
- })
- ], optionsParallel
- );
- }
- });
-};
-
-/** @id MochiKit.Visual.shrink */
-MochiKit.Visual.shrink = function (element, /* optional */ options) {
- /***
-
- Shrink an element and make it disappear.
-
- ***/
- var d = MochiKit.DOM;
- var v = MochiKit.Visual;
- var s = MochiKit.Style;
- element = d.getElement(element);
- options = MochiKit.Base.update({
- direction: 'center',
- moveTransition: v.Transitions.sinoidal,
- scaleTransition: v.Transitions.sinoidal,
- opacityTransition: v.Transitions.none
- }, options || {});
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- height: element.style.height,
- width: element.style.width,
- opacity: element.style.opacity || ''
- };
-
- var dims = s.getElementDimensions(element);
- var moveX, moveY;
-
- switch (options.direction) {
- case 'top-left':
- moveX = moveY = 0;
- break;
- case 'top-right':
- moveX = dims.w;
- moveY = 0;
- break;
- case 'bottom-left':
- moveX = 0;
- moveY = dims.h;
- break;
- case 'bottom-right':
- moveX = dims.w;
- moveY = dims.h;
- break;
- case 'center':
- moveX = dims.w / 2;
- moveY = dims.h / 2;
- break;
- }
- var elemClip;
-
- var optionsParallel = MochiKit.Base.update({
- beforeStartInternal: function (effect) {
- elemClip = d.makePositioned(effect.effects[0].element);
- d.makeClipping(effect.effects[0].element);
- },
- afterFinishInternal: function (effect) {
- s.hideElement(effect.effects[0].element);
- d.undoClipping(effect.effects[0].element, elemClip);
- d.undoPositioned(effect.effects[0].element);
- s.setStyle(effect.effects[0].element, oldStyle);
- }
- }, options || {});
-
- return new v.Parallel(
- [new v.Opacity(element, {
- sync: true, to: 0.0, from: 1.0,
- transition: options.opacityTransition
- }),
- new v.Scale(element, /Opera/.test(navigator.userAgent) ? 1 : 0, {
- sync: true, transition: options.scaleTransition,
- restoreAfterFinish: true
- }),
- new v.Move(element, {
- x: moveX, y: moveY, sync: true, transition: options.moveTransition
- })
- ], optionsParallel
- );
-};
-
-/** @id MochiKit.Visual.pulsate */
-MochiKit.Visual.pulsate = function (element, /* optional */ options) {
- /***
-
- Pulse an element between appear/fade.
-
- ***/
- var d = MochiKit.DOM;
- var v = MochiKit.Visual;
- var b = MochiKit.Base;
- var oldOpacity = d.getElement(element).style.opacity || '';
- options = b.update({
- duration: 3.0,
- from: 0,
- afterFinishInternal: function (effect) {
- MochiKit.Style.setStyle(effect.element, {opacity: oldOpacity});
- }
- }, options || {});
- var transition = options.transition || v.Transitions.sinoidal;
- var reverser = b.bind(function (pos) {
- return transition(1 - v.Transitions.pulse(pos));
- }, transition);
- b.bind(reverser, transition);
- return new v.Opacity(element, b.update({
- transition: reverser}, options));
-};
-
-/** @id MochiKit.Visual.fold */
-MochiKit.Visual.fold = function (element, /* optional */ options) {
- /***
-
- Fold an element, first vertically, then horizontally.
-
- ***/
- var d = MochiKit.DOM;
- var v = MochiKit.Visual;
- var s = MochiKit.Style;
- element = d.getElement(element);
- var oldStyle = {
- top: element.style.top,
- left: element.style.left,
- width: element.style.width,
- height: element.style.height
- };
- var elemClip = d.makeClipping(element);
- options = MochiKit.Base.update({
- scaleContent: false,
- scaleX: false,
- afterFinishInternal: function (effect) {
- new v.Scale(element, 1, {
- scaleContent: false,
- scaleY: false,
- afterFinishInternal: function (effect) {
- s.hideElement(effect.element);
- d.undoClipping(effect.element, elemClip);
- s.setStyle(effect.element, oldStyle);
- }
- });
- }
- }, options || {});
- return new v.Scale(element, 5, options);
-};
-
-
-// Compatibility with MochiKit 1.0
-MochiKit.Visual.Color = MochiKit.Color.Color;
-MochiKit.Visual.getElementsComputedStyle = MochiKit.DOM.computedStyle;
-
-/* end of Rico adaptation */
-
-MochiKit.Visual.__new__ = function () {
- var m = MochiKit.Base;
-
- m.nameFunctions(this);
-
- this.EXPORT_TAGS = {
- ":common": this.EXPORT,
- ":all": m.concat(this.EXPORT, this.EXPORT_OK)
- };
-
-};
-
-MochiKit.Visual.EXPORT = [
- "roundElement",
- "roundClass",
- "tagifyText",
- "multiple",
- "toggle",
- "Base",
- "Parallel",
- "Opacity",
- "Move",
- "Scale",
- "Highlight",
- "ScrollTo",
- "fade",
- "appear",
- "puff",
- "blindUp",
- "blindDown",
- "switchOff",
- "dropOut",
- "shake",
- "slideDown",
- "slideUp",
- "squish",
- "grow",
- "shrink",
- "pulsate",
- "fold"
-];
-
-MochiKit.Visual.EXPORT_OK = [
- "PAIRS"
-];
-
-MochiKit.Visual.__new__();
-
-MochiKit.Base._exportSymbols(this, MochiKit.Visual);
diff --git a/mochitest/MochiKit/__package__.js b/mochitest/MochiKit/__package__.js
deleted file mode 100644
index 4c58c39..0000000
--- a/mochitest/MochiKit/__package__.js
+++ /dev/null
@@ -1,19 +0,0 @@
-dojo.hostenv.conditionalLoadModule({
- "common": [
- "MochiKit.Base",
- "MochiKit.Iter",
- "MochiKit.Logging",
- "MochiKit.DateTime",
- "MochiKit.Format",
- "MochiKit.Async",
- "MochiKit.Color"
- ],
- "browser": [
- "MochiKit.DOM",
- "MochiKit.Style",
- "MochiKit.Signal",
- "MochiKit.LoggingPane",
- "MochiKit.Visual"
- ]
-});
-dojo.hostenv.moduleLoaded("MochiKit.*");
diff --git a/mochitest/MochiKit/packed.js b/mochitest/MochiKit/packed.js
deleted file mode 100644
index 7dd8d1a..0000000
--- a/mochitest/MochiKit/packed.js
+++ /dev/null
@@ -1,6112 +0,0 @@
-/***
-
- MochiKit.MochiKit 1.4 : PACKED VERSION
-
- THIS FILE IS AUTOMATICALLY GENERATED. If creating patches, please
- diff against the source tree, not this file.
-
- See <http://mochikit.com/> for documentation, downloads, license, etc.
-
- (c) 2005 Bob Ippolito. All rights Reserved.
-
-***/
-
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Base");
-}
-if(typeof (MochiKit)=="undefined"){
-MochiKit={};
-}
-if(typeof (MochiKit.Base)=="undefined"){
-MochiKit.Base={};
-}
-if(typeof (MochiKit.__export__)=="undefined"){
-MochiKit.__export__=(MochiKit.__compat__||(typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined"));
-}
-MochiKit.Base.VERSION="1.4";
-MochiKit.Base.NAME="MochiKit.Base";
-MochiKit.Base.update=function(_1,_2){
-if(_1===null){
-_1={};
-}
-for(var i=1;i<arguments.length;i++){
-var o=arguments[i];
-if(typeof (o)!="undefined"&&o!==null){
-for(var k in o){
-_1[k]=o[k];
-}
-}
-}
-return _1;
-};
-MochiKit.Base.update(MochiKit.Base,{__repr__:function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-},toString:function(){
-return this.__repr__();
-},camelize:function(_6){
-var _7=_6.split("-");
-var cc=_7[0];
-for(var i=1;i<_7.length;i++){
-cc+=_7[i].charAt(0).toUpperCase()+_7[i].substring(1);
-}
-return cc;
-},counter:function(n){
-if(arguments.length===0){
-n=1;
-}
-return function(){
-return n++;
-};
-},clone:function(_b){
-var me=arguments.callee;
-if(arguments.length==1){
-me.prototype=_b;
-return new me();
-}
-},_flattenArray:function(_d,_e){
-for(var i=0;i<_e.length;i++){
-var o=_e[i];
-if(o instanceof Array){
-arguments.callee(_d,o);
-}else{
-_d.push(o);
-}
-}
-return _d;
-},flattenArray:function(lst){
-return MochiKit.Base._flattenArray([],lst);
-},flattenArguments:function(lst){
-var res=[];
-var m=MochiKit.Base;
-var _15=m.extend(null,arguments);
-while(_15.length){
-var o=_15.shift();
-if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
-for(var i=o.length-1;i>=0;i--){
-_15.unshift(o[i]);
-}
-}else{
-res.push(o);
-}
-}
-return res;
-},extend:function(_18,obj,_1a){
-if(!_1a){
-_1a=0;
-}
-if(obj){
-var l=obj.length;
-if(typeof (l)!="number"){
-if(typeof (MochiKit.Iter)!="undefined"){
-obj=MochiKit.Iter.list(obj);
-l=obj.length;
-}else{
-throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
-}
-}
-if(!_18){
-_18=[];
-}
-for(var i=_1a;i<l;i++){
-_18.push(obj[i]);
-}
-}
-return _18;
-},updatetree:function(_1d,obj){
-if(_1d===null){
-_1d={};
-}
-for(var i=1;i<arguments.length;i++){
-var o=arguments[i];
-if(typeof (o)!="undefined"&&o!==null){
-for(var k in o){
-var v=o[k];
-if(typeof (_1d[k])=="object"&&typeof (v)=="object"){
-arguments.callee(_1d[k],v);
-}else{
-_1d[k]=v;
-}
-}
-}
-}
-return _1d;
-},setdefault:function(_23,obj){
-if(_23===null){
-_23={};
-}
-for(var i=1;i<arguments.length;i++){
-var o=arguments[i];
-for(var k in o){
-if(!(k in _23)){
-_23[k]=o[k];
-}
-}
-}
-return _23;
-},keys:function(obj){
-var _29=[];
-for(var _2a in obj){
-_29.push(_2a);
-}
-return _29;
-},values:function(obj){
-var _2c=[];
-for(var _2d in obj){
-_2c.push(obj[_2d]);
-}
-return _2c;
-},items:function(obj){
-var _2f=[];
-var e;
-for(var _31 in obj){
-var v;
-try{
-v=obj[_31];
-}
-catch(e){
-continue;
-}
-_2f.push([_31,v]);
-}
-return _2f;
-},_newNamedError:function(_33,_34,_35){
-_35.prototype=new MochiKit.Base.NamedError(_33.NAME+"."+_34);
-_33[_34]=_35;
-},operator:{truth:function(a){
-return !!a;
-},lognot:function(a){
-return !a;
-},identity:function(a){
-return a;
-},not:function(a){
-return ~a;
-},neg:function(a){
-return -a;
-},add:function(a,b){
-return a+b;
-},sub:function(a,b){
-return a-b;
-},div:function(a,b){
-return a/b;
-},mod:function(a,b){
-return a%b;
-},mul:function(a,b){
-return a*b;
-},and:function(a,b){
-return a&b;
-},or:function(a,b){
-return a|b;
-},xor:function(a,b){
-return a^b;
-},lshift:function(a,b){
-return a<<b;
-},rshift:function(a,b){
-return a>>b;
-},zrshift:function(a,b){
-return a>>>b;
-},eq:function(a,b){
-return a==b;
-},ne:function(a,b){
-return a!=b;
-},gt:function(a,b){
-return a>b;
-},ge:function(a,b){
-return a>=b;
-},lt:function(a,b){
-return a<b;
-},le:function(a,b){
-return a<=b;
-},seq:function(a,b){
-return a===b;
-},sne:function(a,b){
-return a!==b;
-},ceq:function(a,b){
-return MochiKit.Base.compare(a,b)===0;
-},cne:function(a,b){
-return MochiKit.Base.compare(a,b)!==0;
-},cgt:function(a,b){
-return MochiKit.Base.compare(a,b)==1;
-},cge:function(a,b){
-return MochiKit.Base.compare(a,b)!=-1;
-},clt:function(a,b){
-return MochiKit.Base.compare(a,b)==-1;
-},cle:function(a,b){
-return MochiKit.Base.compare(a,b)!=1;
-},logand:function(a,b){
-return a&&b;
-},logor:function(a,b){
-return a||b;
-},contains:function(a,b){
-return b in a;
-}},forwardCall:function(_73){
-return function(){
-return this[_73].apply(this,arguments);
-};
-},itemgetter:function(_74){
-return function(arg){
-return arg[_74];
-};
-},typeMatcher:function(){
-var _76={};
-for(var i=0;i<arguments.length;i++){
-var typ=arguments[i];
-_76[typ]=typ;
-}
-return function(){
-for(var i=0;i<arguments.length;i++){
-if(!(typeof (arguments[i]) in _76)){
-return false;
-}
-}
-return true;
-};
-},isNull:function(){
-for(var i=0;i<arguments.length;i++){
-if(arguments[i]!==null){
-return false;
-}
-}
-return true;
-},isUndefinedOrNull:function(){
-for(var i=0;i<arguments.length;i++){
-var o=arguments[i];
-if(!(typeof (o)=="undefined"||o===null)){
-return false;
-}
-}
-return true;
-},isEmpty:function(obj){
-return !MochiKit.Base.isNotEmpty.apply(this,arguments);
-},isNotEmpty:function(obj){
-for(var i=0;i<arguments.length;i++){
-var o=arguments[i];
-if(!(o&&o.length)){
-return false;
-}
-}
-return true;
-},isArrayLike:function(){
-for(var i=0;i<arguments.length;i++){
-var o=arguments[i];
-var typ=typeof (o);
-if((typ!="object"&&!(typ=="function"&&typeof (o.item)=="function"))||o===null||typeof (o.length)!="number"||o.nodeType===3){
-return false;
-}
-}
-return true;
-},isDateLike:function(){
-for(var i=0;i<arguments.length;i++){
-var o=arguments[i];
-if(typeof (o)!="object"||o===null||typeof (o.getTime)!="function"){
-return false;
-}
-}
-return true;
-},xmap:function(fn){
-if(fn===null){
-return MochiKit.Base.extend(null,arguments,1);
-}
-var _87=[];
-for(var i=1;i<arguments.length;i++){
-_87.push(fn(arguments[i]));
-}
-return _87;
-},map:function(fn,lst){
-var m=MochiKit.Base;
-var itr=MochiKit.Iter;
-var _8d=m.isArrayLike;
-if(arguments.length<=2){
-if(!_8d(lst)){
-if(itr){
-lst=itr.list(lst);
-if(fn===null){
-return lst;
-}
-}else{
-throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
-}
-}
-if(fn===null){
-return m.extend(null,lst);
-}
-var _8e=[];
-for(var i=0;i<lst.length;i++){
-_8e.push(fn(lst[i]));
-}
-return _8e;
-}else{
-if(fn===null){
-fn=Array;
-}
-var _90=null;
-for(i=1;i<arguments.length;i++){
-if(!_8d(arguments[i])){
-if(itr){
-return itr.list(itr.imap.apply(null,arguments));
-}else{
-throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
-}
-}
-var l=arguments[i].length;
-if(_90===null||_90>l){
-_90=l;
-}
-}
-_8e=[];
-for(i=0;i<_90;i++){
-var _92=[];
-for(var j=1;j<arguments.length;j++){
-_92.push(arguments[j][i]);
-}
-_8e.push(fn.apply(this,_92));
-}
-return _8e;
-}
-},xfilter:function(fn){
-var _95=[];
-if(fn===null){
-fn=MochiKit.Base.operator.truth;
-}
-for(var i=1;i<arguments.length;i++){
-var o=arguments[i];
-if(fn(o)){
-_95.push(o);
-}
-}
-return _95;
-},filter:function(fn,lst,_9a){
-var _9b=[];
-var m=MochiKit.Base;
-if(!m.isArrayLike(lst)){
-if(MochiKit.Iter){
-lst=MochiKit.Iter.list(lst);
-}else{
-throw new TypeError("Argument not an array-like and MochiKit.Iter not present");
-}
-}
-if(fn===null){
-fn=m.operator.truth;
-}
-if(typeof (Array.prototype.filter)=="function"){
-return Array.prototype.filter.call(lst,fn,_9a);
-}else{
-if(typeof (_9a)=="undefined"||_9a===null){
-for(var i=0;i<lst.length;i++){
-var o=lst[i];
-if(fn(o)){
-_9b.push(o);
-}
-}
-}else{
-for(i=0;i<lst.length;i++){
-o=lst[i];
-if(fn.call(_9a,o)){
-_9b.push(o);
-}
-}
-}
-}
-return _9b;
-},_wrapDumbFunction:function(_9f){
-return function(){
-switch(arguments.length){
-case 0:
-return _9f();
-case 1:
-return _9f(arguments[0]);
-case 2:
-return _9f(arguments[0],arguments[1]);
-case 3:
-return _9f(arguments[0],arguments[1],arguments[2]);
-}
-var _a0=[];
-for(var i=0;i<arguments.length;i++){
-_a0.push("arguments["+i+"]");
-}
-return eval("(func("+_a0.join(",")+"))");
-};
-},methodcaller:function(_a2){
-var _a3=MochiKit.Base.extend(null,arguments,1);
-if(typeof (_a2)=="function"){
-return function(obj){
-return _a2.apply(obj,_a3);
-};
-}else{
-return function(obj){
-return obj[_a2].apply(obj,_a3);
-};
-}
-},method:function(_a6,_a7){
-var m=MochiKit.Base;
-return m.bind.apply(this,m.extend([_a7,_a6],arguments,2));
-},compose:function(f1,f2){
-var _ab=[];
-var m=MochiKit.Base;
-if(arguments.length===0){
-throw new TypeError("compose() requires at least one argument");
-}
-for(var i=0;i<arguments.length;i++){
-var fn=arguments[i];
-if(typeof (fn)!="function"){
-throw new TypeError(m.repr(fn)+" is not a function");
-}
-_ab.push(fn);
-}
-return function(){
-var _af=arguments;
-for(var i=_ab.length-1;i>=0;i--){
-_af=[_ab[i].apply(this,_af)];
-}
-return _af[0];
-};
-},bind:function(_b1,_b2){
-if(typeof (_b1)=="string"){
-_b1=_b2[_b1];
-}
-var _b3=_b1.im_func;
-var _b4=_b1.im_preargs;
-var _b5=_b1.im_self;
-var m=MochiKit.Base;
-if(typeof (_b1)=="function"&&typeof (_b1.apply)=="undefined"){
-_b1=m._wrapDumbFunction(_b1);
-}
-if(typeof (_b3)!="function"){
-_b3=_b1;
-}
-if(typeof (_b2)!="undefined"){
-_b5=_b2;
-}
-if(typeof (_b4)=="undefined"){
-_b4=[];
-}else{
-_b4=_b4.slice();
-}
-m.extend(_b4,arguments,2);
-var _b7=function(){
-var _b8=arguments;
-var me=arguments.callee;
-if(me.im_preargs.length>0){
-_b8=m.concat(me.im_preargs,_b8);
-}
-var _ba=me.im_self;
-if(!_ba){
-_ba=this;
-}
-return me.im_func.apply(_ba,_b8);
-};
-_b7.im_self=_b5;
-_b7.im_func=_b3;
-_b7.im_preargs=_b4;
-return _b7;
-},bindMethods:function(_bb){
-var _bc=MochiKit.Base.bind;
-for(var k in _bb){
-var _be=_bb[k];
-if(typeof (_be)=="function"){
-_bb[k]=_bc(_be,_bb);
-}
-}
-},registerComparator:function(_bf,_c0,_c1,_c2){
-MochiKit.Base.comparatorRegistry.register(_bf,_c0,_c1,_c2);
-},_primitives:{"boolean":true,"string":true,"number":true},compare:function(a,b){
-if(a==b){
-return 0;
-}
-var _c5=(typeof (a)=="undefined"||a===null);
-var _c6=(typeof (b)=="undefined"||b===null);
-if(_c5&&_c6){
-return 0;
-}else{
-if(_c5){
-return -1;
-}else{
-if(_c6){
-return 1;
-}
-}
-}
-var m=MochiKit.Base;
-var _c8=m._primitives;
-if(!(typeof (a) in _c8&&typeof (b) in _c8)){
-try{
-return m.comparatorRegistry.match(a,b);
-}
-catch(e){
-if(e!=m.NotFound){
-throw e;
-}
-}
-}
-if(a<b){
-return -1;
-}else{
-if(a>b){
-return 1;
-}
-}
-var _c9=m.repr;
-throw new TypeError(_c9(a)+" and "+_c9(b)+" can not be compared");
-},compareDateLike:function(a,b){
-return MochiKit.Base.compare(a.getTime(),b.getTime());
-},compareArrayLike:function(a,b){
-var _ce=MochiKit.Base.compare;
-var _cf=a.length;
-var _d0=0;
-if(_cf>b.length){
-_d0=1;
-_cf=b.length;
-}else{
-if(_cf<b.length){
-_d0=-1;
-}
-}
-for(var i=0;i<_cf;i++){
-var cmp=_ce(a[i],b[i]);
-if(cmp){
-return cmp;
-}
-}
-return _d0;
-},registerRepr:function(_d3,_d4,_d5,_d6){
-MochiKit.Base.reprRegistry.register(_d3,_d4,_d5,_d6);
-},repr:function(o){
-if(typeof (o)=="undefined"){
-return "undefined";
-}else{
-if(o===null){
-return "null";
-}
-}
-try{
-if(typeof (o.__repr__)=="function"){
-return o.__repr__();
-}else{
-if(typeof (o.repr)=="function"&&o.repr!=arguments.callee){
-return o.repr();
-}
-}
-return MochiKit.Base.reprRegistry.match(o);
-}
-catch(e){
-if(typeof (o.NAME)=="string"&&(o.toString==Function.prototype.toString||o.toString==Object.prototype.toString)){
-return o.NAME;
-}
-}
-try{
-var _d8=(o+"");
-}
-catch(e){
-return "["+typeof (o)+"]";
-}
-if(typeof (o)=="function"){
-o=_d8.replace(/^\s+/,"");
-var idx=o.indexOf("{");
-if(idx!=-1){
-o=o.substr(0,idx)+"{...}";
-}
-}
-return _d8;
-},reprArrayLike:function(o){
-var m=MochiKit.Base;
-return "["+m.map(m.repr,o).join(", ")+"]";
-},reprString:function(o){
-return ("\""+o.replace(/(["\\])/g,"\\$1")+"\"").replace(/[\f]/g,"\\f").replace(/[\b]/g,"\\b").replace(/[\n]/g,"\\n").replace(/[\t]/g,"\\t").replace(/[\r]/g,"\\r");
-},reprNumber:function(o){
-return o+"";
-},registerJSON:function(_de,_df,_e0,_e1){
-MochiKit.Base.jsonRegistry.register(_de,_df,_e0,_e1);
-},evalJSON:function(){
-return eval("("+arguments[0]+")");
-},serializeJSON:function(o){
-var _e3=typeof (o);
-if(_e3=="number"||_e3=="boolean"){
-return o+"";
-}else{
-if(o===null){
-return "null";
-}
-}
-var m=MochiKit.Base;
-var _e5=m.reprString;
-if(_e3=="string"){
-return _e5(o);
-}
-var me=arguments.callee;
-var _e7;
-if(typeof (o.__json__)=="function"){
-_e7=o.__json__();
-if(o!==_e7){
-return me(_e7);
-}
-}
-if(typeof (o.json)=="function"){
-_e7=o.json();
-if(o!==_e7){
-return me(_e7);
-}
-}
-if(_e3!="function"&&typeof (o.length)=="number"){
-var res=[];
-for(var i=0;i<o.length;i++){
-var val=me(o[i]);
-if(typeof (val)!="string"){
-val="undefined";
-}
-res.push(val);
-}
-return "["+res.join(", ")+"]";
-}
-try{
-_e7=m.jsonRegistry.match(o);
-if(o!==_e7){
-return me(_e7);
-}
-}
-catch(e){
-if(e!=m.NotFound){
-throw e;
-}
-}
-if(_e3=="undefined"){
-throw new TypeError("undefined can not be serialized as JSON");
-}
-if(_e3=="function"){
-return null;
-}
-res=[];
-for(var k in o){
-var _ec;
-if(typeof (k)=="number"){
-_ec="\""+k+"\"";
-}else{
-if(typeof (k)=="string"){
-_ec=_e5(k);
-}else{
-continue;
-}
-}
-val=me(o[k]);
-if(typeof (val)!="string"){
-continue;
-}
-res.push(_ec+":"+val);
-}
-return "{"+res.join(", ")+"}";
-},objEqual:function(a,b){
-return (MochiKit.Base.compare(a,b)===0);
-},arrayEqual:function(_ef,arr){
-if(_ef.length!=arr.length){
-return false;
-}
-return (MochiKit.Base.compare(_ef,arr)===0);
-},concat:function(){
-var _f1=[];
-var _f2=MochiKit.Base.extend;
-for(var i=0;i<arguments.length;i++){
-_f2(_f1,arguments[i]);
-}
-return _f1;
-},keyComparator:function(key){
-var m=MochiKit.Base;
-var _f6=m.compare;
-if(arguments.length==1){
-return function(a,b){
-return _f6(a[key],b[key]);
-};
-}
-var _f9=m.extend(null,arguments);
-return function(a,b){
-var _fc=0;
-for(var i=0;(_fc===0)&&(i<_f9.length);i++){
-var key=_f9[i];
-_fc=_f6(a[key],b[key]);
-}
-return _fc;
-};
-},reverseKeyComparator:function(key){
-var _100=MochiKit.Base.keyComparator.apply(this,arguments);
-return function(a,b){
-return _100(b,a);
-};
-},partial:function(func){
-var m=MochiKit.Base;
-return m.bind.apply(this,m.extend([func,undefined],arguments,1));
-},listMinMax:function(_105,lst){
-if(lst.length===0){
-return null;
-}
-var cur=lst[0];
-var _108=MochiKit.Base.compare;
-for(var i=1;i<lst.length;i++){
-var o=lst[i];
-if(_108(o,cur)==_105){
-cur=o;
-}
-}
-return cur;
-},objMax:function(){
-return MochiKit.Base.listMinMax(1,arguments);
-},objMin:function(){
-return MochiKit.Base.listMinMax(-1,arguments);
-},findIdentical:function(lst,_10c,_10d,end){
-if(typeof (end)=="undefined"||end===null){
-end=lst.length;
-}
-if(typeof (_10d)=="undefined"||_10d===null){
-_10d=0;
-}
-for(var i=_10d;i<end;i++){
-if(lst[i]===_10c){
-return i;
-}
-}
-return -1;
-},mean:function(){
-var sum=0;
-var m=MochiKit.Base;
-var args=m.extend(null,arguments);
-var _113=args.length;
-while(args.length){
-var o=args.shift();
-if(o&&typeof (o)=="object"&&typeof (o.length)=="number"){
-_113+=o.length-1;
-for(var i=o.length-1;i>=0;i--){
-sum+=o[i];
-}
-}else{
-sum+=o;
-}
-}
-if(_113<=0){
-throw new TypeError("mean() requires at least one argument");
-}
-return sum/_113;
-},median:function(){
-var data=MochiKit.Base.flattenArguments(arguments);
-if(data.length===0){
-throw new TypeError("median() requires at least one argument");
-}
-data.sort(compare);
-if(data.length%2==0){
-var _117=data.length/2;
-return (data[_117]+data[_117-1])/2;
-}else{
-return data[(data.length-1)/2];
-}
-},findValue:function(lst,_119,_11a,end){
-if(typeof (end)=="undefined"||end===null){
-end=lst.length;
-}
-if(typeof (_11a)=="undefined"||_11a===null){
-_11a=0;
-}
-var cmp=MochiKit.Base.compare;
-for(var i=_11a;i<end;i++){
-if(cmp(lst[i],_119)===0){
-return i;
-}
-}
-return -1;
-},nodeWalk:function(node,_11f){
-var _120=[node];
-var _121=MochiKit.Base.extend;
-while(_120.length){
-var res=_11f(_120.shift());
-if(res){
-_121(_120,res);
-}
-}
-},nameFunctions:function(_123){
-var base=_123.NAME;
-if(typeof (base)=="undefined"){
-base="";
-}else{
-base=base+".";
-}
-for(var name in _123){
-var o=_123[name];
-if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
-try{
-o.NAME=base+name;
-}
-catch(e){
-}
-}
-}
-},queryString:function(_127,_128){
-if(typeof (MochiKit.DOM)!="undefined"&&arguments.length==1&&(typeof (_127)=="string"||(typeof (_127.nodeType)!="undefined"&&_127.nodeType>0))){
-var kv=MochiKit.DOM.formContents(_127);
-_127=kv[0];
-_128=kv[1];
-}else{
-if(arguments.length==1){
-var o=_127;
-_127=[];
-_128=[];
-for(var k in o){
-var v=o[k];
-if(typeof (v)=="function"){
-continue;
-}else{
-if(typeof (v)!="string"&&typeof (v.length)=="number"){
-for(var i=0;i<v.length;i++){
-_127.push(k);
-_128.push(v[i]);
-}
-}else{
-_127.push(k);
-_128.push(v);
-}
-}
-}
-}
-}
-var rval=[];
-var len=Math.min(_127.length,_128.length);
-var _130=MochiKit.Base.urlEncode;
-for(var i=0;i<len;i++){
-v=_128[i];
-if(typeof (v)!="undefined"&&v!==null){
-rval.push(_130(_127[i])+"="+_130(v));
-}
-}
-return rval.join("&");
-},parseQueryString:function(_131,_132){
-var qstr=(_131[0]=="?")?_131.substring(1):_131;
-var _134=qstr.replace(/\+/g,"%20").split(/(\&\;|\&\#38\;|\&|\&)/);
-var o={};
-var _136;
-if(typeof (decodeURIComponent)!="undefined"){
-_136=decodeURIComponent;
-}else{
-_136=unescape;
-}
-if(_132){
-for(var i=0;i<_134.length;i++){
-var pair=_134[i].split("=");
-if(pair.length!==2){
-continue;
-}
-var name=_136(pair[0]);
-var arr=o[name];
-if(!(arr instanceof Array)){
-arr=[];
-o[name]=arr;
-}
-arr.push(_136(pair[1]));
-}
-}else{
-for(i=0;i<_134.length;i++){
-pair=_134[i].split("=");
-if(pair.length!==2){
-continue;
-}
-o[_136(pair[0])]=_136(pair[1]);
-}
-}
-return o;
-}});
-MochiKit.Base.AdapterRegistry=function(){
-this.pairs=[];
-};
-MochiKit.Base.AdapterRegistry.prototype={register:function(name,_13c,wrap,_13e){
-if(_13e){
-this.pairs.unshift([name,_13c,wrap]);
-}else{
-this.pairs.push([name,_13c,wrap]);
-}
-},match:function(){
-for(var i=0;i<this.pairs.length;i++){
-var pair=this.pairs[i];
-if(pair[1].apply(this,arguments)){
-return pair[2].apply(this,arguments);
-}
-}
-throw MochiKit.Base.NotFound;
-},unregister:function(name){
-for(var i=0;i<this.pairs.length;i++){
-var pair=this.pairs[i];
-if(pair[0]==name){
-this.pairs.splice(i,1);
-return true;
-}
-}
-return false;
-}};
-MochiKit.Base.EXPORT=["flattenArray","noop","camelize","counter","clone","extend","update","updatetree","setdefault","keys","values","items","NamedError","operator","forwardCall","itemgetter","typeMatcher","isCallable","isUndefined","isUndefinedOrNull","isNull","isEmpty","isNotEmpty","isArrayLike","isDateLike","xmap","map","xfilter","filter","methodcaller","compose","bind","bindMethods","NotFound","AdapterRegistry","registerComparator","compare","registerRepr","repr","objEqual","arrayEqual","concat","keyComparator","reverseKeyComparator","partial","merge","listMinMax","listMax","listMin","objMax","objMin","nodeWalk","zip","urlEncode","queryString","serializeJSON","registerJSON","evalJSON","parseQueryString","findValue","findIdentical","flattenArguments","method","average","mean","median"];
-MochiKit.Base.EXPORT_OK=["nameFunctions","comparatorRegistry","reprRegistry","jsonRegistry","compareDateLike","compareArrayLike","reprArrayLike","reprString","reprNumber"];
-MochiKit.Base._exportSymbols=function(_144,_145){
-if(!MochiKit.__export__){
-return;
-}
-var all=_145.EXPORT_TAGS[":all"];
-for(var i=0;i<all.length;i++){
-_144[all[i]]=_145[all[i]];
-}
-};
-MochiKit.Base.__new__=function(){
-var m=this;
-m.noop=m.operator.identity;
-m.forward=m.forwardCall;
-m.find=m.findValue;
-if(typeof (encodeURIComponent)!="undefined"){
-m.urlEncode=function(_149){
-return encodeURIComponent(_149).replace(/\'/g,"%27");
-};
-}else{
-m.urlEncode=function(_14a){
-return escape(_14a).replace(/\+/g,"%2B").replace(/\"/g,"%22").rval.replace(/\'/g,"%27");
-};
-}
-m.NamedError=function(name){
-this.message=name;
-this.name=name;
-};
-m.NamedError.prototype=new Error();
-m.update(m.NamedError.prototype,{repr:function(){
-if(this.message&&this.message!=this.name){
-return this.name+"("+m.repr(this.message)+")";
-}else{
-return this.name+"()";
-}
-},toString:m.forwardCall("repr")});
-m.NotFound=new m.NamedError("MochiKit.Base.NotFound");
-m.listMax=m.partial(m.listMinMax,1);
-m.listMin=m.partial(m.listMinMax,-1);
-m.isCallable=m.typeMatcher("function");
-m.isUndefined=m.typeMatcher("undefined");
-m.merge=m.partial(m.update,null);
-m.zip=m.partial(m.map,null);
-m.average=m.mean;
-m.comparatorRegistry=new m.AdapterRegistry();
-m.registerComparator("dateLike",m.isDateLike,m.compareDateLike);
-m.registerComparator("arrayLike",m.isArrayLike,m.compareArrayLike);
-m.reprRegistry=new m.AdapterRegistry();
-m.registerRepr("arrayLike",m.isArrayLike,m.reprArrayLike);
-m.registerRepr("string",m.typeMatcher("string"),m.reprString);
-m.registerRepr("numbers",m.typeMatcher("number","boolean"),m.reprNumber);
-m.jsonRegistry=new m.AdapterRegistry();
-var all=m.concat(m.EXPORT,m.EXPORT_OK);
-m.EXPORT_TAGS={":common":m.concat(m.EXPORT_OK),":all":all};
-m.nameFunctions(this);
-};
-MochiKit.Base.__new__();
-if(MochiKit.__export__){
-compare=MochiKit.Base.compare;
-compose=MochiKit.Base.compose;
-serializeJSON=MochiKit.Base.serializeJSON;
-}
-MochiKit.Base._exportSymbols(this,MochiKit.Base);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Iter");
-dojo.require("MochiKit.Base");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Iter depends on MochiKit.Base!";
-}
-if(typeof (MochiKit.Iter)=="undefined"){
-MochiKit.Iter={};
-}
-MochiKit.Iter.NAME="MochiKit.Iter";
-MochiKit.Iter.VERSION="1.4";
-MochiKit.Base.update(MochiKit.Iter,{__repr__:function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-},toString:function(){
-return this.__repr__();
-},registerIteratorFactory:function(name,_14e,_14f,_150){
-MochiKit.Iter.iteratorRegistry.register(name,_14e,_14f,_150);
-},iter:function(_151,_152){
-var self=MochiKit.Iter;
-if(arguments.length==2){
-return self.takewhile(function(a){
-return a!=_152;
-},_151);
-}
-if(typeof (_151.next)=="function"){
-return _151;
-}else{
-if(typeof (_151.iter)=="function"){
-return _151.iter();
-}
-}
-try{
-return self.iteratorRegistry.match(_151);
-}
-catch(e){
-var m=MochiKit.Base;
-if(e==m.NotFound){
-e=new TypeError(typeof (_151)+": "+m.repr(_151)+" is not iterable");
-}
-throw e;
-}
-},count:function(n){
-if(!n){
-n=0;
-}
-var m=MochiKit.Base;
-return {repr:function(){
-return "count("+n+")";
-},toString:m.forwardCall("repr"),next:m.counter(n)};
-},cycle:function(p){
-var self=MochiKit.Iter;
-var m=MochiKit.Base;
-var lst=[];
-var _15c=self.iter(p);
-return {repr:function(){
-return "cycle(...)";
-},toString:m.forwardCall("repr"),next:function(){
-try{
-var rval=_15c.next();
-lst.push(rval);
-return rval;
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-if(lst.length===0){
-this.next=function(){
-throw self.StopIteration;
-};
-}else{
-var i=-1;
-this.next=function(){
-i=(i+1)%lst.length;
-return lst[i];
-};
-}
-return this.next();
-}
-}};
-},repeat:function(elem,n){
-var m=MochiKit.Base;
-if(typeof (n)=="undefined"){
-return {repr:function(){
-return "repeat("+m.repr(elem)+")";
-},toString:m.forwardCall("repr"),next:function(){
-return elem;
-}};
-}
-return {repr:function(){
-return "repeat("+m.repr(elem)+", "+n+")";
-},toString:m.forwardCall("repr"),next:function(){
-if(n<=0){
-throw MochiKit.Iter.StopIteration;
-}
-n-=1;
-return elem;
-}};
-},next:function(_162){
-return _162.next();
-},izip:function(p,q){
-var m=MochiKit.Base;
-var self=MochiKit.Iter;
-var next=self.next;
-var _168=m.map(self.iter,arguments);
-return {repr:function(){
-return "izip(...)";
-},toString:m.forwardCall("repr"),next:function(){
-return m.map(next,_168);
-}};
-},ifilter:function(pred,seq){
-var m=MochiKit.Base;
-seq=MochiKit.Iter.iter(seq);
-if(pred===null){
-pred=m.operator.truth;
-}
-return {repr:function(){
-return "ifilter(...)";
-},toString:m.forwardCall("repr"),next:function(){
-while(true){
-var rval=seq.next();
-if(pred(rval)){
-return rval;
-}
-}
-return undefined;
-}};
-},ifilterfalse:function(pred,seq){
-var m=MochiKit.Base;
-seq=MochiKit.Iter.iter(seq);
-if(pred===null){
-pred=m.operator.truth;
-}
-return {repr:function(){
-return "ifilterfalse(...)";
-},toString:m.forwardCall("repr"),next:function(){
-while(true){
-var rval=seq.next();
-if(!pred(rval)){
-return rval;
-}
-}
-return undefined;
-}};
-},islice:function(seq){
-var self=MochiKit.Iter;
-var m=MochiKit.Base;
-seq=self.iter(seq);
-var _174=0;
-var stop=0;
-var step=1;
-var i=-1;
-if(arguments.length==2){
-stop=arguments[1];
-}else{
-if(arguments.length==3){
-_174=arguments[1];
-stop=arguments[2];
-}else{
-_174=arguments[1];
-stop=arguments[2];
-step=arguments[3];
-}
-}
-return {repr:function(){
-return "islice("+["...",_174,stop,step].join(", ")+")";
-},toString:m.forwardCall("repr"),next:function(){
-var rval;
-while(i<_174){
-rval=seq.next();
-i++;
-}
-if(_174>=stop){
-throw self.StopIteration;
-}
-_174+=step;
-return rval;
-}};
-},imap:function(fun,p,q){
-var m=MochiKit.Base;
-var self=MochiKit.Iter;
-var _17e=m.map(self.iter,m.extend(null,arguments,1));
-var map=m.map;
-var next=self.next;
-return {repr:function(){
-return "imap(...)";
-},toString:m.forwardCall("repr"),next:function(){
-return fun.apply(this,map(next,_17e));
-}};
-},applymap:function(fun,seq,self){
-seq=MochiKit.Iter.iter(seq);
-var m=MochiKit.Base;
-return {repr:function(){
-return "applymap(...)";
-},toString:m.forwardCall("repr"),next:function(){
-return fun.apply(self,seq.next());
-}};
-},chain:function(p,q){
-var self=MochiKit.Iter;
-var m=MochiKit.Base;
-if(arguments.length==1){
-return self.iter(arguments[0]);
-}
-var _189=m.map(self.iter,arguments);
-return {repr:function(){
-return "chain(...)";
-},toString:m.forwardCall("repr"),next:function(){
-while(_189.length>1){
-try{
-return _189[0].next();
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-_189.shift();
-}
-}
-if(_189.length==1){
-var arg=_189.shift();
-this.next=m.bind("next",arg);
-return this.next();
-}
-throw self.StopIteration;
-}};
-},takewhile:function(pred,seq){
-var self=MochiKit.Iter;
-seq=self.iter(seq);
-return {repr:function(){
-return "takewhile(...)";
-},toString:MochiKit.Base.forwardCall("repr"),next:function(){
-var rval=seq.next();
-if(!pred(rval)){
-this.next=function(){
-throw self.StopIteration;
-};
-this.next();
-}
-return rval;
-}};
-},dropwhile:function(pred,seq){
-seq=MochiKit.Iter.iter(seq);
-var m=MochiKit.Base;
-var bind=m.bind;
-return {"repr":function(){
-return "dropwhile(...)";
-},"toString":m.forwardCall("repr"),"next":function(){
-while(true){
-var rval=seq.next();
-if(!pred(rval)){
-break;
-}
-}
-this.next=bind("next",seq);
-return rval;
-}};
-},_tee:function(_194,sync,_196){
-sync.pos[_194]=-1;
-var m=MochiKit.Base;
-var _198=m.listMin;
-return {repr:function(){
-return "tee("+_194+", ...)";
-},toString:m.forwardCall("repr"),next:function(){
-var rval;
-var i=sync.pos[_194];
-if(i==sync.max){
-rval=_196.next();
-sync.deque.push(rval);
-sync.max+=1;
-sync.pos[_194]+=1;
-}else{
-rval=sync.deque[i-sync.min];
-sync.pos[_194]+=1;
-if(i==sync.min&&_198(sync.pos)!=sync.min){
-sync.min+=1;
-sync.deque.shift();
-}
-}
-return rval;
-}};
-},tee:function(_19b,n){
-var rval=[];
-var sync={"pos":[],"deque":[],"max":-1,"min":-1};
-if(arguments.length==1||typeof (n)=="undefined"||n===null){
-n=2;
-}
-var self=MochiKit.Iter;
-_19b=self.iter(_19b);
-var _tee=self._tee;
-for(var i=0;i<n;i++){
-rval.push(_tee(i,sync,_19b));
-}
-return rval;
-},list:function(_1a2){
-var m=MochiKit.Base;
-if(typeof (_1a2.slice)=="function"){
-return _1a2.slice();
-}else{
-if(m.isArrayLike(_1a2)){
-return m.concat(_1a2);
-}
-}
-var self=MochiKit.Iter;
-_1a2=self.iter(_1a2);
-var rval=[];
-try{
-while(true){
-rval.push(_1a2.next());
-}
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-return rval;
-}
-return undefined;
-},reduce:function(fn,_1a7,_1a8){
-var i=0;
-var x=_1a8;
-var self=MochiKit.Iter;
-_1a7=self.iter(_1a7);
-if(arguments.length<3){
-try{
-x=_1a7.next();
-}
-catch(e){
-if(e==self.StopIteration){
-e=new TypeError("reduce() of empty sequence with no initial value");
-}
-throw e;
-}
-i++;
-}
-try{
-while(true){
-x=fn(x,_1a7.next());
-}
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-}
-return x;
-},range:function(){
-var _1ac=0;
-var stop=0;
-var step=1;
-if(arguments.length==1){
-stop=arguments[0];
-}else{
-if(arguments.length==2){
-_1ac=arguments[0];
-stop=arguments[1];
-}else{
-if(arguments.length==3){
-_1ac=arguments[0];
-stop=arguments[1];
-step=arguments[2];
-}else{
-throw new TypeError("range() takes 1, 2, or 3 arguments!");
-}
-}
-}
-if(step===0){
-throw new TypeError("range() step must not be 0");
-}
-return {next:function(){
-if((step>0&&_1ac>=stop)||(step<0&&_1ac<=stop)){
-throw MochiKit.Iter.StopIteration;
-}
-var rval=_1ac;
-_1ac+=step;
-return rval;
-},repr:function(){
-return "range("+[_1ac,stop,step].join(", ")+")";
-},toString:MochiKit.Base.forwardCall("repr")};
-},sum:function(_1b0,_1b1){
-if(typeof (_1b1)=="undefined"||_1b1===null){
-_1b1=0;
-}
-var x=_1b1;
-var self=MochiKit.Iter;
-_1b0=self.iter(_1b0);
-try{
-while(true){
-x+=_1b0.next();
-}
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-}
-return x;
-},exhaust:function(_1b4){
-var self=MochiKit.Iter;
-_1b4=self.iter(_1b4);
-try{
-while(true){
-_1b4.next();
-}
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-}
-},forEach:function(_1b6,func,self){
-var m=MochiKit.Base;
-if(arguments.length>2){
-func=m.bind(func,self);
-}
-if(m.isArrayLike(_1b6)){
-try{
-for(var i=0;i<_1b6.length;i++){
-func(_1b6[i]);
-}
-}
-catch(e){
-if(e!=MochiKit.Iter.StopIteration){
-throw e;
-}
-}
-}else{
-self=MochiKit.Iter;
-self.exhaust(self.imap(func,_1b6));
-}
-},every:function(_1bb,func){
-var self=MochiKit.Iter;
-try{
-self.ifilterfalse(func,_1bb).next();
-return false;
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-return true;
-}
-},sorted:function(_1be,cmp){
-var rval=MochiKit.Iter.list(_1be);
-if(arguments.length==1){
-cmp=MochiKit.Base.compare;
-}
-rval.sort(cmp);
-return rval;
-},reversed:function(_1c1){
-var rval=MochiKit.Iter.list(_1c1);
-rval.reverse();
-return rval;
-},some:function(_1c3,func){
-var self=MochiKit.Iter;
-try{
-self.ifilter(func,_1c3).next();
-return true;
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-return false;
-}
-},iextend:function(lst,_1c7){
-if(MochiKit.Base.isArrayLike(_1c7)){
-for(var i=0;i<_1c7.length;i++){
-lst.push(_1c7[i]);
-}
-}else{
-var self=MochiKit.Iter;
-_1c7=self.iter(_1c7);
-try{
-while(true){
-lst.push(_1c7.next());
-}
-}
-catch(e){
-if(e!=self.StopIteration){
-throw e;
-}
-}
-}
-return lst;
-},groupby:function(_1ca,_1cb){
-var m=MochiKit.Base;
-var self=MochiKit.Iter;
-if(arguments.length<2){
-_1cb=m.operator.identity;
-}
-_1ca=self.iter(_1ca);
-var pk=undefined;
-var k=undefined;
-var v;
-function fetch(){
-v=_1ca.next();
-k=_1cb(v);
-}
-function eat(){
-var ret=v;
-v=undefined;
-return ret;
-}
-var _1d2=true;
-var _1d3=m.compare;
-return {repr:function(){
-return "groupby(...)";
-},next:function(){
-while(_1d3(k,pk)===0){
-fetch();
-if(_1d2){
-_1d2=false;
-break;
-}
-}
-pk=k;
-return [k,{next:function(){
-if(v==undefined){
-fetch();
-}
-if(_1d3(k,pk)!==0){
-throw self.StopIteration;
-}
-return eat();
-}}];
-}};
-},groupby_as_array:function(_1d4,_1d5){
-var m=MochiKit.Base;
-var self=MochiKit.Iter;
-if(arguments.length<2){
-_1d5=m.operator.identity;
-}
-_1d4=self.iter(_1d4);
-var _1d8=[];
-var _1d9=true;
-var _1da;
-var _1db=m.compare;
-while(true){
-try{
-var _1dc=_1d4.next();
-var key=_1d5(_1dc);
-}
-catch(e){
-if(e==self.StopIteration){
-break;
-}
-throw e;
-}
-if(_1d9||_1db(key,_1da)!==0){
-var _1de=[];
-_1d8.push([key,_1de]);
-}
-_1de.push(_1dc);
-_1d9=false;
-_1da=key;
-}
-return _1d8;
-},arrayLikeIter:function(_1df){
-var i=0;
-return {repr:function(){
-return "arrayLikeIter(...)";
-},toString:MochiKit.Base.forwardCall("repr"),next:function(){
-if(i>=_1df.length){
-throw MochiKit.Iter.StopIteration;
-}
-return _1df[i++];
-}};
-},hasIterateNext:function(_1e1){
-return (_1e1&&typeof (_1e1.iterateNext)=="function");
-},iterateNextIter:function(_1e2){
-return {repr:function(){
-return "iterateNextIter(...)";
-},toString:MochiKit.Base.forwardCall("repr"),next:function(){
-var rval=_1e2.iterateNext();
-if(rval===null||rval===undefined){
-throw MochiKit.Iter.StopIteration;
-}
-return rval;
-}};
-}});
-MochiKit.Iter.EXPORT_OK=["iteratorRegistry","arrayLikeIter","hasIterateNext","iterateNextIter",];
-MochiKit.Iter.EXPORT=["StopIteration","registerIteratorFactory","iter","count","cycle","repeat","next","izip","ifilter","ifilterfalse","islice","imap","applymap","chain","takewhile","dropwhile","tee","list","reduce","range","sum","exhaust","forEach","every","sorted","reversed","some","iextend","groupby","groupby_as_array"];
-MochiKit.Iter.__new__=function(){
-var m=MochiKit.Base;
-if(typeof (StopIteration)!="undefined"){
-this.StopIteration=StopIteration;
-}else{
-this.StopIteration=new m.NamedError("StopIteration");
-}
-this.iteratorRegistry=new m.AdapterRegistry();
-this.registerIteratorFactory("arrayLike",m.isArrayLike,this.arrayLikeIter);
-this.registerIteratorFactory("iterateNext",this.hasIterateNext,this.iterateNextIter);
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-};
-MochiKit.Iter.__new__();
-if(MochiKit.__export__){
-reduce=MochiKit.Iter.reduce;
-}
-MochiKit.Base._exportSymbols(this,MochiKit.Iter);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Logging");
-dojo.require("MochiKit.Base");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Logging depends on MochiKit.Base!";
-}
-if(typeof (MochiKit.Logging)=="undefined"){
-MochiKit.Logging={};
-}
-MochiKit.Logging.NAME="MochiKit.Logging";
-MochiKit.Logging.VERSION="1.4";
-MochiKit.Logging.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Logging.toString=function(){
-return this.__repr__();
-};
-MochiKit.Logging.EXPORT=["LogLevel","LogMessage","Logger","alertListener","logger","log","logError","logDebug","logFatal","logWarning"];
-MochiKit.Logging.EXPORT_OK=["logLevelAtLeast","isLogMessage","compareLogMessage"];
-MochiKit.Logging.LogMessage=function(num,_1e6,info){
-this.num=num;
-this.level=_1e6;
-this.info=info;
-this.timestamp=new Date();
-};
-MochiKit.Logging.LogMessage.prototype={repr:function(){
-var m=MochiKit.Base;
-return "LogMessage("+m.map(m.repr,[this.num,this.level,this.info]).join(", ")+")";
-},toString:MochiKit.Base.forwardCall("repr")};
-MochiKit.Base.update(MochiKit.Logging,{logLevelAtLeast:function(_1e9){
-var self=MochiKit.Logging;
-if(typeof (_1e9)=="string"){
-_1e9=self.LogLevel[_1e9];
-}
-return function(msg){
-var _1ec=msg.level;
-if(typeof (_1ec)=="string"){
-_1ec=self.LogLevel[_1ec];
-}
-return _1ec>=_1e9;
-};
-},isLogMessage:function(){
-var _1ed=MochiKit.Logging.LogMessage;
-for(var i=0;i<arguments.length;i++){
-if(!(arguments[i] instanceof _1ed)){
-return false;
-}
-}
-return true;
-},compareLogMessage:function(a,b){
-return MochiKit.Base.compare([a.level,a.info],[b.level,b.info]);
-},alertListener:function(msg){
-alert("num: "+msg.num+"\nlevel: "+msg.level+"\ninfo: "+msg.info.join(" "));
-}});
-MochiKit.Logging.Logger=function(_1f2){
-this.counter=0;
-if(typeof (_1f2)=="undefined"||_1f2===null){
-_1f2=-1;
-}
-this.maxSize=_1f2;
-this._messages=[];
-this.listeners={};
-this.useNativeConsole=false;
-};
-MochiKit.Logging.Logger.prototype={clear:function(){
-this._messages.splice(0,this._messages.length);
-},logToConsole:function(msg){
-if(typeof (window)!="undefined"&&window.console&&window.console.log){
-window.console.log(msg.replace(/%/g,"\uff05"));
-}else{
-if(typeof (opera)!="undefined"&&opera.postError){
-opera.postError(msg);
-}else{
-if(typeof (printfire)=="function"){
-printfire(msg);
-}else{
-if(typeof (Debug)!="undefined"&&Debug.writeln){
-Debug.writeln(msg);
-}else{
-if(typeof (debug)!="undefined"&&debug.trace){
-debug.trace(msg);
-}
-}
-}
-}
-}
-},dispatchListeners:function(msg){
-for(var k in this.listeners){
-var pair=this.listeners[k];
-if(pair.ident!=k||(pair[0]&&!pair[0](msg))){
-continue;
-}
-pair[1](msg);
-}
-},addListener:function(_1f7,_1f8,_1f9){
-if(typeof (_1f8)=="string"){
-_1f8=MochiKit.Logging.logLevelAtLeast(_1f8);
-}
-var _1fa=[_1f8,_1f9];
-_1fa.ident=_1f7;
-this.listeners[_1f7]=_1fa;
-},removeListener:function(_1fb){
-delete this.listeners[_1fb];
-},baseLog:function(_1fc,_1fd){
-var msg=new MochiKit.Logging.LogMessage(this.counter,_1fc,MochiKit.Base.extend(null,arguments,1));
-this._messages.push(msg);
-this.dispatchListeners(msg);
-if(this.useNativeConsole){
-this.logToConsole(msg.level+": "+msg.info.join(" "));
-}
-this.counter+=1;
-while(this.maxSize>=0&&this._messages.length>this.maxSize){
-this._messages.shift();
-}
-},getMessages:function(_1ff){
-var _200=0;
-if(!(typeof (_1ff)=="undefined"||_1ff===null)){
-_200=Math.max(0,this._messages.length-_1ff);
-}
-return this._messages.slice(_200);
-},getMessageText:function(_201){
-if(typeof (_201)=="undefined"||_201===null){
-_201=30;
-}
-var _202=this.getMessages(_201);
-if(_202.length){
-var lst=map(function(m){
-return "\n ["+m.num+"] "+m.level+": "+m.info.join(" ");
-},_202);
-lst.unshift("LAST "+_202.length+" MESSAGES:");
-return lst.join("");
-}
-return "";
-},debuggingBookmarklet:function(_205){
-if(typeof (MochiKit.LoggingPane)=="undefined"){
-alert(this.getMessageText());
-}else{
-MochiKit.LoggingPane.createLoggingPane(_205||false);
-}
-}};
-MochiKit.Logging.__new__=function(){
-this.LogLevel={ERROR:40,FATAL:50,WARNING:30,INFO:20,DEBUG:10};
-var m=MochiKit.Base;
-m.registerComparator("LogMessage",this.isLogMessage,this.compareLogMessage);
-var _207=m.partial;
-var _208=this.Logger;
-var _209=_208.prototype.baseLog;
-m.update(this.Logger.prototype,{debug:_207(_209,"DEBUG"),log:_207(_209,"INFO"),error:_207(_209,"ERROR"),fatal:_207(_209,"FATAL"),warning:_207(_209,"WARNING")});
-var self=this;
-var _20b=function(name){
-return function(){
-self.logger[name].apply(self.logger,arguments);
-};
-};
-this.log=_20b("log");
-this.logError=_20b("error");
-this.logDebug=_20b("debug");
-this.logFatal=_20b("fatal");
-this.logWarning=_20b("warning");
-this.logger=new _208();
-this.logger.useNativeConsole=true;
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-};
-if(typeof (printfire)=="undefined"&&typeof (document)!="undefined"&&document.createEvent&&typeof (dispatchEvent)!="undefined"){
-printfire=function(){
-printfire.args=arguments;
-var ev=document.createEvent("Events");
-ev.initEvent("printfire",false,true);
-dispatchEvent(ev);
-};
-}
-MochiKit.Logging.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.Logging);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.DateTime");
-}
-if(typeof (MochiKit)=="undefined"){
-MochiKit={};
-}
-if(typeof (MochiKit.DateTime)=="undefined"){
-MochiKit.DateTime={};
-}
-MochiKit.DateTime.NAME="MochiKit.DateTime";
-MochiKit.DateTime.VERSION="1.4";
-MochiKit.DateTime.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.DateTime.toString=function(){
-return this.__repr__();
-};
-MochiKit.DateTime.isoDate=function(str){
-str=str+"";
-if(typeof (str)!="string"||str.length===0){
-return null;
-}
-var iso=str.split("-");
-if(iso.length===0){
-return null;
-}
-return new Date(iso[0],iso[1]-1,iso[2]);
-};
-MochiKit.DateTime._isoRegexp=/(\d{4,})(?:-(\d{1,2})(?:-(\d{1,2})(?:[T ](\d{1,2}):(\d{1,2})(?::(\d{1,2})(?:\.(\d+))?)?(?:(Z)|([+-])(\d{1,2})(?::(\d{1,2}))?)?)?)?)?/;
-MochiKit.DateTime.isoTimestamp=function(str){
-str=str+"";
-if(typeof (str)!="string"||str.length===0){
-return null;
-}
-var res=str.match(MochiKit.DateTime._isoRegexp);
-if(typeof (res)=="undefined"||res===null){
-return null;
-}
-var year,_213,day,hour,min,sec,msec;
-year=parseInt(res[1],10);
-if(typeof (res[2])=="undefined"||res[2]===""){
-return new Date(year);
-}
-_213=parseInt(res[2],10)-1;
-day=parseInt(res[3],10);
-if(typeof (res[4])=="undefined"||res[4]===""){
-return new Date(year,_213,day);
-}
-hour=parseInt(res[4],10);
-min=parseInt(res[5],10);
-sec=(typeof (res[6])!="undefined"&&res[6]!=="")?parseInt(res[6],10):0;
-if(typeof (res[7])!="undefined"&&res[7]!==""){
-msec=Math.round(1000*parseFloat("0."+res[7]));
-}else{
-msec=0;
-}
-if((typeof (res[8])=="undefined"||res[8]==="")&&(typeof (res[9])=="undefined"||res[9]==="")){
-return new Date(year,_213,day,hour,min,sec,msec);
-}
-var ofs;
-if(typeof (res[9])!="undefined"&&res[9]!==""){
-ofs=parseInt(res[10],10)*3600000;
-if(typeof (res[11])!="undefined"&&res[11]!==""){
-ofs+=parseInt(res[11],10)*60000;
-}
-if(res[9]=="-"){
-ofs=-ofs;
-}
-}else{
-ofs=0;
-}
-return new Date(Date.UTC(year,_213,day,hour,min,sec,msec)-ofs);
-};
-MochiKit.DateTime.toISOTime=function(date,_21b){
-if(typeof (date)=="undefined"||date===null){
-return null;
-}
-var hh=date.getHours();
-var mm=date.getMinutes();
-var ss=date.getSeconds();
-var lst=[((_21b&&(hh<10))?"0"+hh:hh),((mm<10)?"0"+mm:mm),((ss<10)?"0"+ss:ss)];
-return lst.join(":");
-};
-MochiKit.DateTime.toISOTimestamp=function(date,_221){
-if(typeof (date)=="undefined"||date===null){
-return null;
-}
-var sep=_221?"T":" ";
-var foot=_221?"Z":"";
-if(_221){
-date=new Date(date.getTime()+(date.getTimezoneOffset()*60000));
-}
-return MochiKit.DateTime.toISODate(date)+sep+MochiKit.DateTime.toISOTime(date,_221)+foot;
-};
-MochiKit.DateTime.toISODate=function(date){
-if(typeof (date)=="undefined"||date===null){
-return null;
-}
-var _225=MochiKit.DateTime._padTwo;
-return [date.getFullYear(),_225(date.getMonth()+1),_225(date.getDate())].join("-");
-};
-MochiKit.DateTime.americanDate=function(d){
-d=d+"";
-if(typeof (d)!="string"||d.length===0){
-return null;
-}
-var a=d.split("/");
-return new Date(a[2],a[0]-1,a[1]);
-};
-MochiKit.DateTime._padTwo=function(n){
-return (n>9)?n:"0"+n;
-};
-MochiKit.DateTime.toPaddedAmericanDate=function(d){
-if(typeof (d)=="undefined"||d===null){
-return null;
-}
-var _22a=MochiKit.DateTime._padTwo;
-return [_22a(d.getMonth()+1),_22a(d.getDate()),d.getFullYear()].join("/");
-};
-MochiKit.DateTime.toAmericanDate=function(d){
-if(typeof (d)=="undefined"||d===null){
-return null;
-}
-return [d.getMonth()+1,d.getDate(),d.getFullYear()].join("/");
-};
-MochiKit.DateTime.EXPORT=["isoDate","isoTimestamp","toISOTime","toISOTimestamp","toISODate","americanDate","toPaddedAmericanDate","toAmericanDate"];
-MochiKit.DateTime.EXPORT_OK=[];
-MochiKit.DateTime.EXPORT_TAGS={":common":MochiKit.DateTime.EXPORT,":all":MochiKit.DateTime.EXPORT};
-MochiKit.DateTime.__new__=function(){
-var base=this.NAME+".";
-for(var k in this){
-var o=this[k];
-if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
-try{
-o.NAME=base+k;
-}
-catch(e){
-}
-}
-}
-};
-MochiKit.DateTime.__new__();
-if(typeof (MochiKit.Base)!="undefined"){
-MochiKit.Base._exportSymbols(this,MochiKit.DateTime);
-}else{
-(function(_22f,_230){
-if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(MochiKit.__export__===false)){
-var all=_230.EXPORT_TAGS[":all"];
-for(var i=0;i<all.length;i++){
-_22f[all[i]]=_230[all[i]];
-}
-}
-})(this,MochiKit.DateTime);
-}
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Format");
-}
-if(typeof (MochiKit)=="undefined"){
-MochiKit={};
-}
-if(typeof (MochiKit.Format)=="undefined"){
-MochiKit.Format={};
-}
-MochiKit.Format.NAME="MochiKit.Format";
-MochiKit.Format.VERSION="1.4";
-MochiKit.Format.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Format.toString=function(){
-return this.__repr__();
-};
-MochiKit.Format._numberFormatter=function(_233,_234,_235,_236,_237,_238,_239,_23a,_23b){
-return function(num){
-num=parseFloat(num);
-if(typeof (num)=="undefined"||num===null||isNaN(num)){
-return _233;
-}
-var _23d=_234;
-var _23e=_235;
-if(num<0){
-num=-num;
-}else{
-_23d=_23d.replace(/-/,"");
-}
-var me=arguments.callee;
-var fmt=MochiKit.Format.formatLocale(_236);
-if(_237){
-num=num*100;
-_23e=fmt.percent+_23e;
-}
-num=MochiKit.Format.roundToFixed(num,_238);
-var _241=num.split(/\./);
-var _242=_241[0];
-var frac=(_241.length==1)?"":_241[1];
-var res="";
-while(_242.length<_239){
-_242="0"+_242;
-}
-if(_23a){
-while(_242.length>_23a){
-var i=_242.length-_23a;
-res=fmt.separator+_242.substring(i,_242.length)+res;
-_242=_242.substring(0,i);
-}
-}
-res=_242+res;
-if(_238>0){
-while(frac.length<_23b){
-frac=frac+"0";
-}
-res=res+fmt.decimal+frac;
-}
-return _23d+res+_23e;
-};
-};
-MochiKit.Format.numberFormatter=function(_246,_247,_248){
-if(typeof (_247)=="undefined"){
-_247="";
-}
-var _249=_246.match(/((?:[0#]+,)?[0#]+)(?:\.([0#]+))?(%)?/);
-if(!_249){
-throw TypeError("Invalid pattern");
-}
-var _24a=_246.substr(0,_249.index);
-var _24b=_246.substr(_249.index+_249[0].length);
-if(_24a.search(/-/)==-1){
-_24a=_24a+"-";
-}
-var _24c=_249[1];
-var frac=(typeof (_249[2])=="string"&&_249[2]!="")?_249[2]:"";
-var _24e=(typeof (_249[3])=="string"&&_249[3]!="");
-var tmp=_24c.split(/,/);
-var _250;
-if(typeof (_248)=="undefined"){
-_248="default";
-}
-if(tmp.length==1){
-_250=null;
-}else{
-_250=tmp[1].length;
-}
-var _251=_24c.length-_24c.replace(/0/g,"").length;
-var _252=frac.length-frac.replace(/0/g,"").length;
-var _253=frac.length;
-var rval=MochiKit.Format._numberFormatter(_247,_24a,_24b,_248,_24e,_253,_251,_250,_252);
-var m=MochiKit.Base;
-if(m){
-var fn=arguments.callee;
-var args=m.concat(arguments);
-rval.repr=function(){
-return [self.NAME,"(",map(m.repr,args).join(", "),")"].join("");
-};
-}
-return rval;
-};
-MochiKit.Format.formatLocale=function(_258){
-if(typeof (_258)=="undefined"||_258===null){
-_258="default";
-}
-if(typeof (_258)=="string"){
-var rval=MochiKit.Format.LOCALE[_258];
-if(typeof (rval)=="string"){
-rval=arguments.callee(rval);
-MochiKit.Format.LOCALE[_258]=rval;
-}
-return rval;
-}else{
-return _258;
-}
-};
-MochiKit.Format.twoDigitAverage=function(_25a,_25b){
-if(_25b){
-var res=_25a/_25b;
-if(!isNaN(res)){
-return MochiKit.Format.twoDigitFloat(_25a/_25b);
-}
-}
-return "0";
-};
-MochiKit.Format.twoDigitFloat=function(_25d){
-var sign=(_25d<0?"-":"");
-var s=Math.floor(Math.abs(_25d)*100).toString();
-if(s=="0"){
-return s;
-}
-if(s.length<3){
-while(s.charAt(s.length-1)=="0"){
-s=s.substring(0,s.length-1);
-}
-return sign+"0."+s;
-}
-var head=sign+s.substring(0,s.length-2);
-var tail=s.substring(s.length-2,s.length);
-if(tail=="00"){
-return head;
-}else{
-if(tail.charAt(1)=="0"){
-return head+"."+tail.charAt(0);
-}else{
-return head+"."+tail;
-}
-}
-};
-MochiKit.Format.lstrip=function(str,_263){
-str=str+"";
-if(typeof (str)!="string"){
-return null;
-}
-if(!_263){
-return str.replace(/^\s+/,"");
-}else{
-return str.replace(new RegExp("^["+_263+"]+"),"");
-}
-};
-MochiKit.Format.rstrip=function(str,_265){
-str=str+"";
-if(typeof (str)!="string"){
-return null;
-}
-if(!_265){
-return str.replace(/\s+$/,"");
-}else{
-return str.replace(new RegExp("["+_265+"]+$"),"");
-}
-};
-MochiKit.Format.strip=function(str,_267){
-var self=MochiKit.Format;
-return self.rstrip(self.lstrip(str,_267),_267);
-};
-MochiKit.Format.truncToFixed=function(_269,_26a){
-_269=Math.floor(_269*Math.pow(10,_26a));
-var res=(_269*Math.pow(10,-_26a)).toFixed(_26a);
-if(res.charAt(0)=="."){
-res="0"+res;
-}
-return res;
-};
-MochiKit.Format.roundToFixed=function(_26c,_26d){
-return MochiKit.Format.truncToFixed(_26c+0.5*Math.pow(10,-_26d),_26d);
-};
-MochiKit.Format.percentFormat=function(_26e){
-return MochiKit.Format.twoDigitFloat(100*_26e)+"%";
-};
-MochiKit.Format.EXPORT=["truncToFixed","roundToFixed","numberFormatter","formatLocale","twoDigitAverage","twoDigitFloat","percentFormat","lstrip","rstrip","strip"];
-MochiKit.Format.LOCALE={en_US:{separator:",",decimal:".",percent:"%"},de_DE:{separator:".",decimal:",",percent:"%"},fr_FR:{separator:" ",decimal:",",percent:"%"},"default":"en_US"};
-MochiKit.Format.EXPORT_OK=[];
-MochiKit.Format.EXPORT_TAGS={":all":MochiKit.Format.EXPORT,":common":MochiKit.Format.EXPORT};
-MochiKit.Format.__new__=function(){
-var base=this.NAME+".";
-var k,v,o;
-for(k in this.LOCALE){
-o=this.LOCALE[k];
-if(typeof (o)=="object"){
-o.repr=function(){
-return this.NAME;
-};
-o.NAME=base+"LOCALE."+k;
-}
-}
-for(k in this){
-o=this[k];
-if(typeof (o)=="function"&&typeof (o.NAME)=="undefined"){
-try{
-o.NAME=base+k;
-}
-catch(e){
-}
-}
-}
-};
-MochiKit.Format.__new__();
-if(typeof (MochiKit.Base)!="undefined"){
-MochiKit.Base._exportSymbols(this,MochiKit.Format);
-}else{
-(function(_273,_274){
-if((typeof (JSAN)=="undefined"&&typeof (dojo)=="undefined")||(MochiKit.__export__===false)){
-var all=_274.EXPORT_TAGS[":all"];
-for(var i=0;i<all.length;i++){
-_273[all[i]]=_274[all[i]];
-}
-}
-})(this,MochiKit.Format);
-}
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Async");
-dojo.require("MochiKit.Base");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Async depends on MochiKit.Base!";
-}
-if(typeof (MochiKit.Async)=="undefined"){
-MochiKit.Async={};
-}
-MochiKit.Async.NAME="MochiKit.Async";
-MochiKit.Async.VERSION="1.4";
-MochiKit.Async.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Async.toString=function(){
-return this.__repr__();
-};
-MochiKit.Async.Deferred=function(_277){
-this.chain=[];
-this.id=this._nextId();
-this.fired=-1;
-this.paused=0;
-this.results=[null,null];
-this.canceller=_277;
-this.silentlyCancelled=false;
-this.chained=false;
-};
-MochiKit.Async.Deferred.prototype={repr:function(){
-var _278;
-if(this.fired==-1){
-_278="unfired";
-}else{
-if(this.fired===0){
-_278="success";
-}else{
-_278="error";
-}
-}
-return "Deferred("+this.id+", "+_278+")";
-},toString:MochiKit.Base.forwardCall("repr"),_nextId:MochiKit.Base.counter(),cancel:function(){
-var self=MochiKit.Async;
-if(this.fired==-1){
-if(this.canceller){
-this.canceller(this);
-}else{
-this.silentlyCancelled=true;
-}
-if(this.fired==-1){
-this.errback(new self.CancelledError(this));
-}
-}else{
-if((this.fired===0)&&(this.results[0] instanceof self.Deferred)){
-this.results[0].cancel();
-}
-}
-},_resback:function(res){
-this.fired=((res instanceof Error)?1:0);
-this.results[this.fired]=res;
-this._fire();
-},_check:function(){
-if(this.fired!=-1){
-if(!this.silentlyCancelled){
-throw new MochiKit.Async.AlreadyCalledError(this);
-}
-this.silentlyCancelled=false;
-return;
-}
-},callback:function(res){
-this._check();
-if(res instanceof MochiKit.Async.Deferred){
-throw new Error("Deferred instances can only be chained if they are the result of a callback");
-}
-this._resback(res);
-},errback:function(res){
-this._check();
-var self=MochiKit.Async;
-if(res instanceof self.Deferred){
-throw new Error("Deferred instances can only be chained if they are the result of a callback");
-}
-if(!(res instanceof Error)){
-res=new self.GenericError(res);
-}
-this._resback(res);
-},addBoth:function(fn){
-if(arguments.length>1){
-fn=MochiKit.Base.partial.apply(null,arguments);
-}
-return this.addCallbacks(fn,fn);
-},addCallback:function(fn){
-if(arguments.length>1){
-fn=MochiKit.Base.partial.apply(null,arguments);
-}
-return this.addCallbacks(fn,null);
-},addErrback:function(fn){
-if(arguments.length>1){
-fn=MochiKit.Base.partial.apply(null,arguments);
-}
-return this.addCallbacks(null,fn);
-},addCallbacks:function(cb,eb){
-if(this.chained){
-throw new Error("Chained Deferreds can not be re-used");
-}
-this.chain.push([cb,eb]);
-if(this.fired>=0){
-this._fire();
-}
-return this;
-},_fire:function(){
-var _283=this.chain;
-var _284=this.fired;
-var res=this.results[_284];
-var self=this;
-var cb=null;
-while(_283.length>0&&this.paused===0){
-var pair=_283.shift();
-var f=pair[_284];
-if(f===null){
-continue;
-}
-try{
-res=f(res);
-_284=((res instanceof Error)?1:0);
-if(res instanceof MochiKit.Async.Deferred){
-cb=function(res){
-self._resback(res);
-self.paused--;
-if((self.paused===0)&&(self.fired>=0)){
-self._fire();
-}
-};
-this.paused++;
-}
-}
-catch(err){
-_284=1;
-if(!(err instanceof Error)){
-err=new MochiKit.Async.GenericError(err);
-}
-res=err;
-}
-}
-this.fired=_284;
-this.results[_284]=res;
-if(cb&&this.paused){
-res.addBoth(cb);
-res.chained=true;
-}
-}};
-MochiKit.Base.update(MochiKit.Async,{evalJSONRequest:function(){
-return eval("("+arguments[0].responseText+")");
-},succeed:function(_28b){
-var d=new MochiKit.Async.Deferred();
-d.callback.apply(d,arguments);
-return d;
-},fail:function(_28d){
-var d=new MochiKit.Async.Deferred();
-d.errback.apply(d,arguments);
-return d;
-},getXMLHttpRequest:function(){
-var self=arguments.callee;
-if(!self.XMLHttpRequest){
-var _290=[function(){
-return new XMLHttpRequest();
-},function(){
-return new ActiveXObject("Msxml2.XMLHTTP");
-},function(){
-return new ActiveXObject("Microsoft.XMLHTTP");
-},function(){
-return new ActiveXObject("Msxml2.XMLHTTP.4.0");
-},function(){
-throw new MochiKit.Async.BrowserComplianceError("Browser does not support XMLHttpRequest");
-}];
-for(var i=0;i<_290.length;i++){
-var func=_290[i];
-try{
-self.XMLHttpRequest=func;
-return func();
-}
-catch(e){
-}
-}
-}
-return self.XMLHttpRequest();
-},_xhr_onreadystatechange:function(d){
-var m=MochiKit.Base;
-if(this.readyState==4){
-try{
-this.onreadystatechange=null;
-}
-catch(e){
-try{
-this.onreadystatechange=m.noop;
-}
-catch(e){
-}
-}
-var _295=null;
-try{
-_295=this.status;
-if(!_295&&m.isNotEmpty(this.responseText)){
-_295=304;
-}
-}
-catch(e){
-}
-if(_295==200||_295==304){
-d.callback(this);
-}else{
-var err=new MochiKit.Async.XMLHttpRequestError(this,"Request failed");
-if(err.number){
-d.errback(err);
-}else{
-d.errback(err);
-}
-}
-}
-},_xhr_canceller:function(req){
-try{
-req.onreadystatechange=null;
-}
-catch(e){
-try{
-req.onreadystatechange=MochiKit.Base.noop;
-}
-catch(e){
-}
-}
-req.abort();
-},sendXMLHttpRequest:function(req,_299){
-if(typeof (_299)=="undefined"||_299===null){
-_299="";
-}
-var m=MochiKit.Base;
-var self=MochiKit.Async;
-var d=new self.Deferred(m.partial(self._xhr_canceller,req));
-try{
-req.onreadystatechange=m.bind(self._xhr_onreadystatechange,req,d);
-req.send(_299);
-}
-catch(e){
-try{
-req.onreadystatechange=null;
-}
-catch(ignore){
-}
-d.errback(e);
-}
-return d;
-},doXHR:function(url,opts){
-var m=MochiKit.Base;
-opts=m.update({method:"GET",sendContent:""},opts);
-var self=MochiKit.Async;
-var req=self.getXMLHttpRequest();
-if(opts.queryString){
-var qs=m.queryString(opts.queryString);
-if(qs){
-url+="?"+qs;
-}
-}
-req.open(opts.method,url,true,opts.username,opts.password);
-if(req.overrideMimeType&&opts.mimeType){
-req.overrideMimeType(opts.mimeType);
-}
-if(opts.headers){
-var _2a3=opts.headers;
-if(!m.isArrayLike(_2a3)){
-_2a3=m.items(_2a3);
-}
-for(var i=0;i<_2a3.length;i++){
-var _2a5=_2a3[i];
-var name=_2a5[0];
-var _2a7=_2a5[1];
-req.setRequestHeader(name,_2a7);
-}
-}
-return self.sendXMLHttpRequest(req,opts.sendContent);
-},_buildURL:function(url){
-if(arguments.length>1){
-var m=MochiKit.Base;
-var qs=m.queryString.apply(null,m.extend(null,arguments,1));
-if(qs){
-return url+"?"+qs;
-}
-}
-return url;
-},doSimpleXMLHttpRequest:function(url){
-var self=MochiKit.Async;
-url=self._buildURL.apply(self,arguments);
-return self.doXHR(url);
-},loadJSONDoc:function(url){
-var self=MochiKit.Async;
-url=self._buildURL.apply(self,arguments);
-var d=self.doXHR(url,{"mimeType":"text/plain","headers":[["Accept","application/json"]]});
-d=d.addCallback(self.evalJSONRequest);
-return d;
-},wait:function(_2b0,_2b1){
-var d=new MochiKit.Async.Deferred();
-var m=MochiKit.Base;
-if(typeof (_2b1)!="undefined"){
-d.addCallback(function(){
-return _2b1;
-});
-}
-var _2b4=setTimeout(m.bind("callback",d),Math.floor(_2b0*1000));
-d.canceller=function(){
-try{
-clearTimeout(_2b4);
-}
-catch(e){
-}
-};
-return d;
-},callLater:function(_2b5,func){
-var m=MochiKit.Base;
-var _2b8=m.partial.apply(m,m.extend(null,arguments,1));
-return MochiKit.Async.wait(_2b5).addCallback(function(res){
-return _2b8();
-});
-}});
-MochiKit.Async.DeferredLock=function(){
-this.waiting=[];
-this.locked=false;
-this.id=this._nextId();
-};
-MochiKit.Async.DeferredLock.prototype={__class__:MochiKit.Async.DeferredLock,acquire:function(){
-var d=new MochiKit.Async.Deferred();
-if(this.locked){
-this.waiting.push(d);
-}else{
-this.locked=true;
-d.callback(this);
-}
-return d;
-},release:function(){
-if(!this.locked){
-throw TypeError("Tried to release an unlocked DeferredLock");
-}
-this.locked=false;
-if(this.waiting.length>0){
-this.locked=true;
-this.waiting.shift().callback(this);
-}
-},_nextId:MochiKit.Base.counter(),repr:function(){
-var _2bb;
-if(this.locked){
-_2bb="locked, "+this.waiting.length+" waiting";
-}else{
-_2bb="unlocked";
-}
-return "DeferredLock("+this.id+", "+_2bb+")";
-},toString:MochiKit.Base.forwardCall("repr")};
-MochiKit.Async.DeferredList=function(list,_2bd,_2be,_2bf,_2c0){
-MochiKit.Async.Deferred.apply(this,[_2c0]);
-this.list=list;
-var _2c1=[];
-this.resultList=_2c1;
-this.finishedCount=0;
-this.fireOnOneCallback=_2bd;
-this.fireOnOneErrback=_2be;
-this.consumeErrors=_2bf;
-var cb=MochiKit.Base.bind(this._cbDeferred,this);
-for(var i=0;i<list.length;i++){
-var d=list[i];
-_2c1.push(undefined);
-d.addCallback(cb,i,true);
-d.addErrback(cb,i,false);
-}
-if(list.length===0&&!_2bd){
-this.callback(this.resultList);
-}
-};
-MochiKit.Async.DeferredList.prototype=new MochiKit.Async.Deferred();
-MochiKit.Async.DeferredList.prototype._cbDeferred=function(_2c5,_2c6,_2c7){
-this.resultList[_2c5]=[_2c6,_2c7];
-this.finishedCount+=1;
-if(this.fired==-1){
-if(_2c6&&this.fireOnOneCallback){
-this.callback([_2c5,_2c7]);
-}else{
-if(!_2c6&&this.fireOnOneErrback){
-this.errback(_2c7);
-}else{
-if(this.finishedCount==this.list.length){
-this.callback(this.resultList);
-}
-}
-}
-}
-if(!_2c6&&this.consumeErrors){
-_2c7=null;
-}
-return _2c7;
-};
-MochiKit.Async.gatherResults=function(_2c8){
-var d=new MochiKit.Async.DeferredList(_2c8,false,true,false);
-d.addCallback(function(_2ca){
-var ret=[];
-for(var i=0;i<_2ca.length;i++){
-ret.push(_2ca[i][1]);
-}
-return ret;
-});
-return d;
-};
-MochiKit.Async.maybeDeferred=function(func){
-var self=MochiKit.Async;
-var _2cf;
-try{
-var r=func.apply(null,MochiKit.Base.extend([],arguments,1));
-if(r instanceof self.Deferred){
-_2cf=r;
-}else{
-if(r instanceof Error){
-_2cf=self.fail(r);
-}else{
-_2cf=self.succeed(r);
-}
-}
-}
-catch(e){
-_2cf=self.fail(e);
-}
-return _2cf;
-};
-MochiKit.Async.EXPORT=["AlreadyCalledError","CancelledError","BrowserComplianceError","GenericError","XMLHttpRequestError","Deferred","succeed","fail","getXMLHttpRequest","doSimpleXMLHttpRequest","loadJSONDoc","wait","callLater","sendXMLHttpRequest","DeferredLock","DeferredList","gatherResults","maybeDeferred","doXHR"];
-MochiKit.Async.EXPORT_OK=["evalJSONRequest"];
-MochiKit.Async.__new__=function(){
-var m=MochiKit.Base;
-var ne=m.partial(m._newNamedError,this);
-ne("AlreadyCalledError",function(_2d3){
-this.deferred=_2d3;
-});
-ne("CancelledError",function(_2d4){
-this.deferred=_2d4;
-});
-ne("BrowserComplianceError",function(msg){
-this.message=msg;
-});
-ne("GenericError",function(msg){
-this.message=msg;
-});
-ne("XMLHttpRequestError",function(req,msg){
-this.req=req;
-this.message=msg;
-try{
-this.number=req.status;
-}
-catch(e){
-}
-});
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-};
-MochiKit.Async.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.Async);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.DOM");
-dojo.require("MochiKit.Base");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.DOM depends on MochiKit.Base!";
-}
-if(typeof (MochiKit.DOM)=="undefined"){
-MochiKit.DOM={};
-}
-MochiKit.DOM.NAME="MochiKit.DOM";
-MochiKit.DOM.VERSION="1.4";
-MochiKit.DOM.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.DOM.toString=function(){
-return this.__repr__();
-};
-MochiKit.DOM.EXPORT=["removeEmptyTextNodes","formContents","currentWindow","currentDocument","withWindow","withDocument","registerDOMConverter","coerceToDOM","createDOM","createDOMFunc","isChildNode","getNodeAttribute","setNodeAttribute","updateNodeAttributes","appendChildNodes","replaceChildNodes","removeElement","swapDOM","BUTTON","TT","PRE","H1","H2","H3","BR","CANVAS","HR","LABEL","TEXTAREA","FORM","STRONG","SELECT","OPTION","OPTGROUP","LEGEND","FIELDSET","P","UL","OL","LI","TD","TR","THEAD","TBODY","TFOOT","TABLE","TH","INPUT","SPAN","A","DIV","IMG","getElement","$","getElementsByTagAndClassName","addToCallStack","addLoadEvent","focusOnLoad","setElementClass","toggleElementClass","addElementClass","removeElementClass","swapElementClass","hasElementClass","escapeHTML","toHTML","emitHTML","scrapeText"];
-MochiKit.DOM.EXPORT_OK=["domConverters"];
-MochiKit.DOM.DEPRECATED=[["computedStyle","MochiKit.Style.computedStyle","1.4"],["elementDimensions","MochiKit.Style.getElementDimensions","1.4"],["elementPosition","MochiKit.Style.getElementPosition","1.4"],["hideElement","MochiKit.Style.hideElement","1.4"],["setElementDimensions","MochiKit.Style.setElementDimensions","1.4"],["setElementPosition","MochiKit.Style.setElementPosition","1.4"],["setDisplayForElement","MochiKit.Style.setDisplayForElement","1.4"],["setOpacity","MochiKit.Style.setOpacity","1.4"],["showElement","MochiKit.Style.showElement","1.4"],["Coordinates","MochiKit.Style.Coordinates","1.4"],["Dimensions","MochiKit.Style.Dimensions","1.4"]];
-MochiKit.DOM.getViewportDimensions=new Function(""+"if (!MochiKit[\"Style\"]) {"+" throw new Error(\"This function has been deprecated and depends on MochiKit.Style.\");"+"}"+"return MochiKit.Style.getViewportDimensions.apply(this, arguments);");
-MochiKit.Base.update(MochiKit.DOM,{currentWindow:function(){
-return MochiKit.DOM._window;
-},currentDocument:function(){
-return MochiKit.DOM._document;
-},withWindow:function(win,func){
-var self=MochiKit.DOM;
-var _2dc=self._document;
-var _2dd=self._win;
-var rval;
-try{
-self._window=win;
-self._document=win.document;
-rval=func();
-}
-catch(e){
-self._window=_2dd;
-self._document=_2dc;
-throw e;
-}
-self._window=_2dd;
-self._document=_2dc;
-return rval;
-},formContents:function(elem){
-var _2e0=[];
-var _2e1=[];
-var m=MochiKit.Base;
-var self=MochiKit.DOM;
-if(typeof (elem)=="undefined"||elem===null){
-elem=self._document;
-}else{
-elem=self.getElement(elem);
-}
-m.nodeWalk(elem,function(elem){
-var name=elem.name;
-if(m.isNotEmpty(name)){
-var _2e6=elem.tagName.toUpperCase();
-if(_2e6==="INPUT"&&(elem.type=="radio"||elem.type=="checkbox")&&!elem.checked){
-return null;
-}
-if(_2e6==="SELECT"){
-if(elem.type=="select-one"){
-if(elem.selectedIndex>=0){
-var opt=elem.options[elem.selectedIndex];
-_2e0.push(name);
-_2e1.push(opt.value);
-return null;
-}
-_2e0.push(name);
-_2e1.push("");
-return null;
-}else{
-var opts=elem.options;
-if(!opts.length){
-_2e0.push(name);
-_2e1.push("");
-return null;
-}
-for(var i=0;i<opts.length;i++){
-var opt=opts[i];
-if(!opt.selected){
-continue;
-}
-_2e0.push(name);
-_2e1.push(opt.value);
-}
-return null;
-}
-}
-if(_2e6==="FORM"||_2e6==="P"||_2e6==="SPAN"||_2e6==="DIV"){
-return elem.childNodes;
-}
-_2e0.push(name);
-_2e1.push(elem.value||"");
-return null;
-}
-return elem.childNodes;
-});
-return [_2e0,_2e1];
-},withDocument:function(doc,func){
-var self=MochiKit.DOM;
-var _2ed=self._document;
-var rval;
-try{
-self._document=doc;
-rval=func();
-}
-catch(e){
-self._document=_2ed;
-throw e;
-}
-self._document=_2ed;
-return rval;
-},registerDOMConverter:function(name,_2f0,wrap,_2f2){
-MochiKit.DOM.domConverters.register(name,_2f0,wrap,_2f2);
-},coerceToDOM:function(node,ctx){
-var m=MochiKit.Base;
-var im=MochiKit.Iter;
-var self=MochiKit.DOM;
-if(im){
-var iter=im.iter;
-var _2f9=im.repeat;
-var map=m.map;
-}
-var _2fb=self.domConverters;
-var _2fc=arguments.callee;
-var _2fd=m.NotFound;
-while(true){
-if(typeof (node)=="undefined"||node===null){
-return null;
-}
-if(typeof (node.nodeType)!="undefined"&&node.nodeType>0){
-return node;
-}
-if(typeof (node)=="number"||typeof (node)=="boolean"){
-node=node.toString();
-}
-if(typeof (node)=="string"){
-return self._document.createTextNode(node);
-}
-if(typeof (node.__dom__)=="function"){
-node=node.__dom__(ctx);
-continue;
-}
-if(typeof (node.dom)=="function"){
-node=node.dom(ctx);
-continue;
-}
-if(typeof (node)=="function"){
-node=node.apply(ctx,[ctx]);
-continue;
-}
-if(im){
-var _2fe=null;
-try{
-_2fe=iter(node);
-}
-catch(e){
-}
-if(_2fe){
-return map(_2fc,_2fe,_2f9(ctx));
-}
-}
-try{
-node=_2fb.match(node,ctx);
-continue;
-}
-catch(e){
-if(e!=_2fd){
-throw e;
-}
-}
-return self._document.createTextNode(node.toString());
-}
-return undefined;
-},isChildNode:function(node,_300){
-var self=MochiKit.DOM;
-if(typeof (node)=="string"){
-node=self.getElement(node);
-}
-if(typeof (_300)=="string"){
-_300=self.getElement(_300);
-}
-if(node===_300){
-return true;
-}
-while(node&&node.tagName.toUpperCase()!="BODY"){
-node=node.parentNode;
-if(node===_300){
-return true;
-}
-}
-return false;
-},setNodeAttribute:function(node,attr,_304){
-var o={};
-o[attr]=_304;
-try{
-return MochiKit.DOM.updateNodeAttributes(node,o);
-}
-catch(e){
-}
-return null;
-},getNodeAttribute:function(node,attr){
-var self=MochiKit.DOM;
-var _309=self.attributeArray.renames[attr];
-node=self.getElement(node);
-try{
-if(_309){
-return node[_309];
-}
-return node.getAttribute(attr);
-}
-catch(e){
-}
-return null;
-},updateNodeAttributes:function(node,_30b){
-var elem=node;
-var self=MochiKit.DOM;
-if(typeof (node)=="string"){
-elem=self.getElement(node);
-}
-if(_30b){
-var _30e=MochiKit.Base.updatetree;
-if(self.attributeArray.compliant){
-for(var k in _30b){
-var v=_30b[k];
-if(typeof (v)=="object"&&typeof (elem[k])=="object"){
-_30e(elem[k],v);
-}else{
-if(k.substring(0,2)=="on"){
-if(typeof (v)=="string"){
-v=new Function(v);
-}
-elem[k]=v;
-}else{
-elem.setAttribute(k,v);
-}
-}
-}
-}else{
-var _311=self.attributeArray.renames;
-for(k in _30b){
-v=_30b[k];
-var _312=_311[k];
-if(k=="style"&&typeof (v)=="string"){
-elem.style.cssText=v;
-}else{
-if(typeof (_312)=="string"){
-elem[_312]=v;
-}else{
-if(typeof (elem[k])=="object"&&typeof (v)=="object"){
-_30e(elem[k],v);
-}else{
-if(k.substring(0,2)=="on"){
-if(typeof (v)=="string"){
-v=new Function(v);
-}
-elem[k]=v;
-}else{
-elem.setAttribute(k,v);
-}
-}
-}
-}
-}
-}
-}
-return elem;
-},appendChildNodes:function(node){
-var elem=node;
-var self=MochiKit.DOM;
-if(typeof (node)=="string"){
-elem=self.getElement(node);
-}
-var _316=[self.coerceToDOM(MochiKit.Base.extend(null,arguments,1),elem)];
-var _317=MochiKit.Base.concat;
-while(_316.length){
-var n=_316.shift();
-if(typeof (n)=="undefined"||n===null){
-}else{
-if(typeof (n.nodeType)=="number"){
-elem.appendChild(n);
-}else{
-_316=_317(n,_316);
-}
-}
-}
-return elem;
-},replaceChildNodes:function(node){
-var elem=node;
-var self=MochiKit.DOM;
-if(typeof (node)=="string"){
-elem=self.getElement(node);
-arguments[0]=elem;
-}
-var _31c;
-while((_31c=elem.firstChild)){
-elem.removeChild(_31c);
-}
-if(arguments.length<2){
-return elem;
-}else{
-return self.appendChildNodes.apply(this,arguments);
-}
-},createDOM:function(name,_31e){
-var elem;
-var self=MochiKit.DOM;
-var m=MochiKit.Base;
-if(typeof (_31e)=="string"||typeof (_31e)=="number"){
-var args=m.extend([name,null],arguments,1);
-return arguments.callee.apply(this,args);
-}
-if(typeof (name)=="string"){
-var _323=self._xhtml;
-if(_31e&&!self.attributeArray.compliant){
-var _324="";
-if("name" in _31e){
-_324+=" name=\""+self.escapeHTML(_31e.name)+"\"";
-}
-if(name=="input"&&"type" in _31e){
-_324+=" type=\""+self.escapeHTML(_31e.type)+"\"";
-}
-if(_324){
-name="<"+name+_324+">";
-_323=false;
-}
-}
-var d=self._document;
-if(_323&&d===document){
-elem=d.createElementNS("http://www.w3.org/1999/xhtml",name);
-}else{
-elem=d.createElement(name);
-}
-}else{
-elem=name;
-}
-if(_31e){
-self.updateNodeAttributes(elem,_31e);
-}
-if(arguments.length<=2){
-return elem;
-}else{
-var args=m.extend([elem],arguments,2);
-return self.appendChildNodes.apply(this,args);
-}
-},createDOMFunc:function(){
-var m=MochiKit.Base;
-return m.partial.apply(this,m.extend([MochiKit.DOM.createDOM],arguments));
-},removeElement:function(elem){
-var e=MochiKit.DOM.getElement(elem);
-e.parentNode.removeChild(e);
-return e;
-},swapDOM:function(dest,src){
-var self=MochiKit.DOM;
-dest=self.getElement(dest);
-var _32c=dest.parentNode;
-if(src){
-src=self.getElement(src);
-_32c.replaceChild(src,dest);
-}else{
-_32c.removeChild(dest);
-}
-return src;
-},getElement:function(id){
-var self=MochiKit.DOM;
-if(arguments.length==1){
-return ((typeof (id)=="string")?self._document.getElementById(id):id);
-}else{
-return MochiKit.Base.map(self.getElement,arguments);
-}
-},getElementsByTagAndClassName:function(_32f,_330,_331){
-var self=MochiKit.DOM;
-if(typeof (_32f)=="undefined"||_32f===null){
-_32f="*";
-}
-if(typeof (_331)=="undefined"||_331===null){
-_331=self._document;
-}
-_331=self.getElement(_331);
-var _333=(_331.getElementsByTagName(_32f)||self._document.all);
-if(typeof (_330)=="undefined"||_330===null){
-return MochiKit.Base.extend(null,_333);
-}
-var _334=[];
-for(var i=0;i<_333.length;i++){
-var _336=_333[i];
-var cls=_336.className;
-if(!cls){
-continue;
-}
-var _338=cls.split(" ");
-for(var j=0;j<_338.length;j++){
-if(_338[j]==_330){
-_334.push(_336);
-break;
-}
-}
-}
-return _334;
-},_newCallStack:function(path,once){
-var rval=function(){
-var _33d=arguments.callee.callStack;
-for(var i=0;i<_33d.length;i++){
-if(_33d[i].apply(this,arguments)===false){
-break;
-}
-}
-if(once){
-try{
-this[path]=null;
-}
-catch(e){
-}
-}
-};
-rval.callStack=[];
-return rval;
-},addToCallStack:function(_33f,path,func,once){
-var self=MochiKit.DOM;
-var _344=_33f[path];
-var _345=_344;
-if(!(typeof (_344)=="function"&&typeof (_344.callStack)=="object"&&_344.callStack!==null)){
-_345=self._newCallStack(path,once);
-if(typeof (_344)=="function"){
-_345.callStack.push(_344);
-}
-_33f[path]=_345;
-}
-_345.callStack.push(func);
-},addLoadEvent:function(func){
-var self=MochiKit.DOM;
-self.addToCallStack(self._window,"onload",func,true);
-},focusOnLoad:function(_348){
-var self=MochiKit.DOM;
-self.addLoadEvent(function(){
-_348=self.getElement(_348);
-if(_348){
-_348.focus();
-}
-});
-},setElementClass:function(_34a,_34b){
-var self=MochiKit.DOM;
-var obj=self.getElement(_34a);
-if(self.attributeArray.compliant){
-obj.setAttribute("class",_34b);
-}else{
-obj.setAttribute("className",_34b);
-}
-},toggleElementClass:function(_34e){
-var self=MochiKit.DOM;
-for(var i=1;i<arguments.length;i++){
-var obj=self.getElement(arguments[i]);
-if(!self.addElementClass(obj,_34e)){
-self.removeElementClass(obj,_34e);
-}
-}
-},addElementClass:function(_352,_353){
-var self=MochiKit.DOM;
-var obj=self.getElement(_352);
-var cls=obj.className;
-if(cls==undefined||cls.length===0){
-self.setElementClass(obj,_353);
-return true;
-}
-if(cls==_353){
-return false;
-}
-var _357=cls.split(" ");
-for(var i=0;i<_357.length;i++){
-if(_357[i]==_353){
-return false;
-}
-}
-self.setElementClass(obj,cls+" "+_353);
-return true;
-},removeElementClass:function(_359,_35a){
-var self=MochiKit.DOM;
-var obj=self.getElement(_359);
-var cls=obj.className;
-if(cls==undefined||cls.length===0){
-return false;
-}
-if(cls==_35a){
-self.setElementClass(obj,"");
-return true;
-}
-var _35e=cls.split(" ");
-for(var i=0;i<_35e.length;i++){
-if(_35e[i]==_35a){
-_35e.splice(i,1);
-self.setElementClass(obj,_35e.join(" "));
-return true;
-}
-}
-return false;
-},swapElementClass:function(_360,_361,_362){
-var obj=MochiKit.DOM.getElement(_360);
-var res=MochiKit.DOM.removeElementClass(obj,_361);
-if(res){
-MochiKit.DOM.addElementClass(obj,_362);
-}
-return res;
-},hasElementClass:function(_365,_366){
-var obj=MochiKit.DOM.getElement(_365);
-var cls=obj.className;
-if(!cls){
-return false;
-}
-var _369=cls.split(" ");
-for(var i=1;i<arguments.length;i++){
-var good=false;
-for(var j=0;j<_369.length;j++){
-if(_369[j]==arguments[i]){
-good=true;
-break;
-}
-}
-if(!good){
-return false;
-}
-}
-return true;
-},escapeHTML:function(s){
-return s.replace(/&/g,"&").replace(/"/g,""").replace(/</g,"<").replace(/>/g,">");
-},toHTML:function(dom){
-return MochiKit.DOM.emitHTML(dom).join("");
-},emitHTML:function(dom,lst){
-if(typeof (lst)=="undefined"||lst===null){
-lst=[];
-}
-var _371=[dom];
-var self=MochiKit.DOM;
-var _373=self.escapeHTML;
-var _374=self.attributeArray;
-while(_371.length){
-dom=_371.pop();
-if(typeof (dom)=="string"){
-lst.push(dom);
-}else{
-if(dom.nodeType==1){
-lst.push("<"+dom.tagName.toLowerCase());
-var _375=[];
-var _376=_374(dom);
-for(var i=0;i<_376.length;i++){
-var a=_376[i];
-_375.push([" ",a.name,"=\"",_373(a.value),"\""]);
-}
-_375.sort();
-for(i=0;i<_375.length;i++){
-var _379=_375[i];
-for(var j=0;j<_379.length;j++){
-lst.push(_379[j]);
-}
-}
-if(dom.hasChildNodes()){
-lst.push(">");
-_371.push("</"+dom.tagName.toLowerCase()+">");
-var _37b=dom.childNodes;
-for(i=_37b.length-1;i>=0;i--){
-_371.push(_37b[i]);
-}
-}else{
-lst.push("/>");
-}
-}else{
-if(dom.nodeType==3){
-lst.push(_373(dom.nodeValue));
-}
-}
-}
-}
-return lst;
-},scrapeText:function(node,_37d){
-var rval=[];
-(function(node){
-var cn=node.childNodes;
-if(cn){
-for(var i=0;i<cn.length;i++){
-arguments.callee.call(this,cn[i]);
-}
-}
-var _382=node.nodeValue;
-if(typeof (_382)=="string"){
-rval.push(_382);
-}
-})(MochiKit.DOM.getElement(node));
-if(_37d){
-return rval;
-}else{
-return rval.join("");
-}
-},removeEmptyTextNodes:function(_383){
-_383=MochiKit.DOM.getElement(_383);
-for(var i=0;i<_383.childNodes.length;i++){
-var node=_383.childNodes[i];
-if(node.nodeType==3&&!/\S/.test(node.nodeValue)){
-node.parentNode.removeChild(node);
-}
-}
-},__new__:function(win){
-var m=MochiKit.Base;
-if(typeof (document)!="undefined"){
-this._document=document;
-this._xhtml=document.createElementNS&&document.createElement("testname").localName=="testname";
-}else{
-if(MochiKit.MockDOM){
-this._document=MochiKit.MockDOM.document;
-}
-}
-this._window=win;
-this.domConverters=new m.AdapterRegistry();
-var _388=this._document.createElement("span");
-var _389;
-if(_388&&_388.attributes&&_388.attributes.length>0){
-var _38a=m.filter;
-_389=function(node){
-return _38a(_389.ignoreAttrFilter,node.attributes);
-};
-_389.ignoreAttr={};
-var _38c=_388.attributes;
-var _38d=_389.ignoreAttr;
-for(var i=0;i<_38c.length;i++){
-var a=_38c[i];
-_38d[a.name]=a.value;
-}
-_389.ignoreAttrFilter=function(a){
-return (_389.ignoreAttr[a.name]!=a.value);
-};
-_389.compliant=false;
-_389.renames={"class":"className","checked":"defaultChecked","usemap":"useMap","for":"htmlFor","readonly":"readOnly","colspan":"colSpan","bgcolor":"bgColor"};
-}else{
-_389=function(node){
-return node.attributes;
-};
-_389.compliant=true;
-_389.renames={};
-}
-this.attributeArray=_389;
-var _392=function(_393,arr){
-var _395=arr[1].split(".");
-var str="";
-var obj={};
-str+="if (!MochiKit."+_395[1]+") { throw new Error(\"";
-str+="This function has been deprecated and depends on MochiKit.";
-str+=_395[1]+".\");}";
-str+="return MochiKit."+_395[1]+"."+arr[0];
-str+=".apply(this, arguments);";
-obj[_395[2]]=new Function(str);
-MochiKit.Base.update(MochiKit[_393],obj);
-};
-for(var i;i<MochiKit.DOM.DEPRECATED.length;i++){
-_392("DOM",MochiKit.DOM.DEPRECATED[i]);
-}
-var _398=this.createDOMFunc;
-this.UL=_398("ul");
-this.OL=_398("ol");
-this.LI=_398("li");
-this.TD=_398("td");
-this.TR=_398("tr");
-this.TBODY=_398("tbody");
-this.THEAD=_398("thead");
-this.TFOOT=_398("tfoot");
-this.TABLE=_398("table");
-this.TH=_398("th");
-this.INPUT=_398("input");
-this.SPAN=_398("span");
-this.A=_398("a");
-this.DIV=_398("div");
-this.IMG=_398("img");
-this.BUTTON=_398("button");
-this.TT=_398("tt");
-this.PRE=_398("pre");
-this.H1=_398("h1");
-this.H2=_398("h2");
-this.H3=_398("h3");
-this.BR=_398("br");
-this.HR=_398("hr");
-this.LABEL=_398("label");
-this.TEXTAREA=_398("textarea");
-this.FORM=_398("form");
-this.P=_398("p");
-this.SELECT=_398("select");
-this.OPTION=_398("option");
-this.OPTGROUP=_398("optgroup");
-this.LEGEND=_398("legend");
-this.FIELDSET=_398("fieldset");
-this.STRONG=_398("strong");
-this.CANVAS=_398("canvas");
-this.$=this.getElement;
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-}});
-MochiKit.DOM.__new__(((typeof (window)=="undefined")?this:window));
-if(MochiKit.__export__){
-withWindow=MochiKit.DOM.withWindow;
-withDocument=MochiKit.DOM.withDocument;
-}
-MochiKit.Base._exportSymbols(this,MochiKit.DOM);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Style");
-dojo.require("MochiKit.Base");
-dojo.require("MochiKit.DOM");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Style depends on MochiKit.Base!";
-}
-try{
-if(typeof (MochiKit.DOM)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Style depends on MochiKit.DOM!";
-}
-if(typeof (MochiKit.Style)=="undefined"){
-MochiKit.Style={};
-}
-MochiKit.Style.NAME="MochiKit.Style";
-MochiKit.Style.VERSION="1.4";
-MochiKit.Style.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Style.toString=function(){
-return this.__repr__();
-};
-MochiKit.Style.EXPORT_OK=[];
-MochiKit.Style.EXPORT=["setOpacity","getOpacity","setStyle","getStyle","computedStyle","getElementDimensions","elementDimensions","setElementDimensions","getElementPosition","elementPosition","setElementPosition","setDisplayForElement","hideElement","showElement","getViewportDimensions","getViewportPosition","Dimensions","Coordinates"];
-MochiKit.Style.Dimensions=function(w,h){
-this.w=w;
-this.h=h;
-};
-MochiKit.Style.Dimensions.prototype.__repr__=function(){
-var repr=MochiKit.Base.repr;
-return "{w: "+repr(this.w)+", h: "+repr(this.h)+"}";
-};
-MochiKit.Style.Dimensions.prototype.toString=function(){
-return this.__repr__();
-};
-MochiKit.Style.Coordinates=function(x,y){
-this.x=x;
-this.y=y;
-};
-MochiKit.Style.Coordinates.prototype.__repr__=function(){
-var repr=MochiKit.Base.repr;
-return "{x: "+repr(this.x)+", y: "+repr(this.y)+"}";
-};
-MochiKit.Style.Coordinates.prototype.toString=function(){
-return this.__repr__();
-};
-MochiKit.Base.update(MochiKit.Style,{computedStyle:function(elem,_3a0){
-var dom=MochiKit.DOM;
-var d=dom._document;
-elem=dom.getElement(elem);
-_3a0=MochiKit.Base.camelize(_3a0);
-if(!elem||elem==d){
-return undefined;
-}
-if(_3a0=="opacity"&&elem.filters){
-try{
-return elem.filters.item("DXImageTransform.Microsoft.Alpha").opacity/100;
-}
-catch(e){
-try{
-return elem.filters.item("alpha").opacity/100;
-}
-catch(e){
-}
-}
-}
-if(elem.currentStyle){
-return elem.currentStyle[_3a0];
-}
-if(typeof (d.defaultView)=="undefined"){
-return undefined;
-}
-if(d.defaultView===null){
-return undefined;
-}
-var _3a3=d.defaultView.getComputedStyle(elem,null);
-if(typeof (_3a3)=="undefined"||_3a3===null){
-return undefined;
-}
-var _3a4=_3a0.replace(/([A-Z])/g,"-$1").toLowerCase();
-return _3a3.getPropertyValue(_3a4);
-},getStyle:function(elem,_3a6){
-elem=MochiKit.DOM.getElement(elem);
-var _3a7=elem.style[MochiKit.Base.camelize(_3a6)];
-if(!_3a7){
-if(document.defaultView&&document.defaultView.getComputedStyle){
-var css=document.defaultView.getComputedStyle(elem,null);
-_3a7=css?css.getPropertyValue(_3a6):null;
-}else{
-if(elem.currentStyle){
-_3a7=elem.currentStyle[MochiKit.Base.camelize(_3a6)];
-}
-}
-}
-if(/Opera/.test(navigator.userAgent)&&(MochiKit.Base.find(["left","top","right","bottom"],_3a6)!=-1)){
-if(MochiKit.Style.getStyle(elem,"position")=="static"){
-_3a7="auto";
-}
-}
-return _3a7=="auto"?null:_3a7;
-},setStyle:function(elem,_3aa){
-elem=MochiKit.DOM.getElement(elem);
-for(name in _3aa){
-elem.style[MochiKit.Base.camelize(name)]=_3aa[name];
-}
-},getOpacity:function(elem){
-var _3ac;
-if(_3ac=MochiKit.Style.getStyle(elem,"opacity")){
-return parseFloat(_3ac);
-}
-if(_3ac=(MochiKit.Style.getStyle(elem,"filter")||"").match(/alpha\(opacity=(.*)\)/)){
-if(_3ac[1]){
-return parseFloat(_3ac[1])/100;
-}
-}
-return 1;
-},setOpacity:function(elem,o){
-elem=MochiKit.DOM.getElement(elem);
-var self=MochiKit.Style;
-if(o==1){
-var _3b0=/Gecko/.test(navigator.userAgent)&&!(/Konqueror|Safari|KHTML/.test(navigator.userAgent));
-self.setStyle(elem,{opacity:_3b0?0.999999:1});
-if(/MSIE/.test(navigator.userAgent)){
-self.setStyle(elem,{filter:self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"")});
-}
-}else{
-if(o<0.00001){
-o=0;
-}
-self.setStyle(elem,{opacity:o});
-if(/MSIE/.test(navigator.userAgent)){
-self.setStyle(elem,{filter:self.getStyle(elem,"filter").replace(/alpha\([^\)]*\)/gi,"")+"alpha(opacity="+o*100+")"});
-}
-}
-},getElementPosition:function(elem,_3b2){
-var self=MochiKit.Style;
-var dom=MochiKit.DOM;
-elem=dom.getElement(elem);
-if(!elem||(!(elem.x&&elem.y)&&(!elem.parentNode==null||self.computedStyle(elem,"display")=="none"))){
-return undefined;
-}
-var c=new self.Coordinates(0,0);
-var box=null;
-var _3b7=null;
-var d=MochiKit.DOM._document;
-var de=d.documentElement;
-var b=d.body;
-if(!elem.parentNode&&elem.x&&elem.y){
-c.x+=elem.x||0;
-c.y+=elem.y||0;
-}else{
-if(elem.getBoundingClientRect){
-box=elem.getBoundingClientRect();
-c.x+=box.left+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
-c.y+=box.top+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
-}else{
-if(elem.offsetParent){
-c.x+=elem.offsetLeft;
-c.y+=elem.offsetTop;
-_3b7=elem.offsetParent;
-if(_3b7!=elem){
-while(_3b7){
-c.x+=_3b7.offsetLeft;
-c.y+=_3b7.offsetTop;
-_3b7=_3b7.offsetParent;
-}
-}
-var ua=navigator.userAgent.toLowerCase();
-if((typeof (opera)!="undefined"&&parseFloat(opera.version())<9)||(ua.indexOf("safari")!=-1&&self.computedStyle(elem,"position")=="absolute")){
-c.x-=b.offsetLeft;
-c.y-=b.offsetTop;
-}
-}
-}
-}
-if(typeof (_3b2)!="undefined"){
-_3b2=arguments.callee(_3b2);
-if(_3b2){
-c.x-=(_3b2.x||0);
-c.y-=(_3b2.y||0);
-}
-}
-if(elem.parentNode){
-_3b7=elem.parentNode;
-}else{
-_3b7=null;
-}
-while(_3b7){
-var _3bc=_3b7.tagName.toUpperCase();
-if(_3bc==="BODY"||_3bc==="HTML"){
-break;
-}
-c.x-=_3b7.scrollLeft;
-c.y-=_3b7.scrollTop;
-if(_3b7.parentNode){
-_3b7=_3b7.parentNode;
-}else{
-_3b7=null;
-}
-}
-return c;
-},setElementPosition:function(elem,_3be,_3bf){
-elem=MochiKit.DOM.getElement(elem);
-if(typeof (_3bf)=="undefined"){
-_3bf="px";
-}
-var _3c0={};
-var _3c1=MochiKit.Base.isUndefinedOrNull;
-if(!_3c1(_3be.x)){
-_3c0["left"]=_3be.x+_3bf;
-}
-if(!_3c1(_3be.y)){
-_3c0["top"]=_3be.y+_3bf;
-}
-MochiKit.DOM.updateNodeAttributes(elem,{"style":_3c0});
-},getElementDimensions:function(elem){
-var self=MochiKit.Style;
-var dom=MochiKit.DOM;
-if(typeof (elem.w)=="number"||typeof (elem.h)=="number"){
-return new self.Dimensions(elem.w||0,elem.h||0);
-}
-elem=dom.getElement(elem);
-if(!elem){
-return undefined;
-}
-var disp=self.computedStyle(elem,"display");
-if(disp!="none"&&disp!=""&&typeof (disp)!="undefined"){
-return new self.Dimensions(elem.offsetWidth||0,elem.offsetHeight||0);
-}
-var s=elem.style;
-var _3c7=s.visibility;
-var _3c8=s.position;
-s.visibility="hidden";
-s.position="absolute";
-s.display="";
-var _3c9=elem.offsetWidth;
-var _3ca=elem.offsetHeight;
-s.display="none";
-s.position=_3c8;
-s.visibility=_3c7;
-return new self.Dimensions(_3c9,_3ca);
-},setElementDimensions:function(elem,_3cc,_3cd){
-elem=MochiKit.DOM.getElement(elem);
-if(typeof (_3cd)=="undefined"){
-_3cd="px";
-}
-var _3ce={};
-var _3cf=MochiKit.Base.isUndefinedOrNull;
-if(!_3cf(_3cc.w)){
-_3ce["width"]=_3cc.w+_3cd;
-}
-if(!_3cf(_3cc.h)){
-_3ce["height"]=_3cc.h+_3cd;
-}
-MochiKit.DOM.updateNodeAttributes(elem,{"style":_3ce});
-},setDisplayForElement:function(_3d0,_3d1){
-var _3d2=MochiKit.Base.extend(null,arguments,1);
-var _3d3=MochiKit.DOM.getElement;
-for(var i=0;i<_3d2.length;i++){
-var _3d1=_3d3(_3d2[i]);
-if(_3d1){
-_3d1.style.display=_3d0;
-}
-}
-},getViewportDimensions:function(){
-var d=new MochiKit.Style.Dimensions();
-var w=MochiKit.DOM._window;
-var b=MochiKit.DOM._document.body;
-if(w.innerWidth){
-d.w=w.innerWidth;
-d.h=w.innerHeight;
-}else{
-if(b.parentElement.clientWidth){
-d.w=b.parentElement.clientWidth;
-d.h=b.parentElement.clientHeight;
-}else{
-if(b&&b.clientWidth){
-d.w=b.clientWidth;
-d.h=b.clientHeight;
-}
-}
-}
-return d;
-},getViewportPosition:function(){
-var c=new MochiKit.Style.Coordinates(0,0);
-var d=MochiKit.DOM._document;
-var de=d.documentElement;
-var db=d.body;
-if(de&&(de.scrollTop||de.scrollLeft)){
-c.x=de.scrollLeft;
-c.y=de.scrollTop;
-}else{
-if(db){
-c.x=db.scrollLeft;
-c.y=db.scrollTop;
-}
-}
-return c;
-},__new__:function(){
-var m=MochiKit.Base;
-this.elementPosition=this.getElementPosition;
-this.elementDimensions=this.getElementDimensions;
-this.hideElement=m.partial(this.setDisplayForElement,"none");
-this.showElement=m.partial(this.setDisplayForElement,"block");
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-}});
-MochiKit.Style.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.Style);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.LoggingPane");
-dojo.require("MochiKit.Logging");
-dojo.require("MochiKit.Base");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Logging",[]);
-JSAN.use("MochiKit.Base",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"||typeof (MochiKit.Logging)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.LoggingPane depends on MochiKit.Base and MochiKit.Logging!";
-}
-if(typeof (MochiKit.LoggingPane)=="undefined"){
-MochiKit.LoggingPane={};
-}
-MochiKit.LoggingPane.NAME="MochiKit.LoggingPane";
-MochiKit.LoggingPane.VERSION="1.4";
-MochiKit.LoggingPane.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.LoggingPane.toString=function(){
-return this.__repr__();
-};
-MochiKit.LoggingPane.createLoggingPane=function(_3dd){
-var m=MochiKit.LoggingPane;
-_3dd=!(!_3dd);
-if(m._loggingPane&&m._loggingPane.inline!=_3dd){
-m._loggingPane.closePane();
-m._loggingPane=null;
-}
-if(!m._loggingPane||m._loggingPane.closed){
-m._loggingPane=new m.LoggingPane(_3dd,MochiKit.Logging.logger);
-}
-return m._loggingPane;
-};
-MochiKit.LoggingPane.LoggingPane=function(_3df,_3e0){
-if(typeof (_3e0)=="undefined"||_3e0===null){
-_3e0=MochiKit.Logging.logger;
-}
-this.logger=_3e0;
-var _3e1=MochiKit.Base.update;
-var _3e2=MochiKit.Base.updatetree;
-var bind=MochiKit.Base.bind;
-var _3e4=MochiKit.Base.clone;
-var win=window;
-var uid="_MochiKit_LoggingPane";
-if(typeof (MochiKit.DOM)!="undefined"){
-win=MochiKit.DOM.currentWindow();
-}
-if(!_3df){
-var url=win.location.href.split("?")[0].replace(/[#:\/.><&-]/g,"_");
-var name=uid+"_"+url;
-var nwin=win.open("",name,"dependent,resizable,height=200");
-if(!nwin){
-alert("Not able to open debugging window due to pop-up blocking.");
-return undefined;
-}
-nwin.document.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" "+"\"http://www.w3.org/TR/html4/loose.dtd\">"+"<html><head><title>[MochiKit.LoggingPane]</title></head>"+"<body></body></html>");
-nwin.document.close();
-nwin.document.title+=" "+win.document.title;
-win=nwin;
-}
-var doc=win.document;
-this.doc=doc;
-var _3eb=doc.getElementById(uid);
-var _3ec=!!_3eb;
-if(_3eb&&typeof (_3eb.loggingPane)!="undefined"){
-_3eb.loggingPane.logger=this.logger;
-_3eb.loggingPane.buildAndApplyFilter();
-return _3eb.loggingPane;
-}
-if(_3ec){
-var _3ed;
-while((_3ed=_3eb.firstChild)){
-_3eb.removeChild(_3ed);
-}
-}else{
-_3eb=doc.createElement("div");
-_3eb.id=uid;
-}
-_3eb.loggingPane=this;
-var _3ee=doc.createElement("input");
-var _3ef=doc.createElement("input");
-var _3f0=doc.createElement("button");
-var _3f1=doc.createElement("button");
-var _3f2=doc.createElement("button");
-var _3f3=doc.createElement("button");
-var _3f4=doc.createElement("div");
-var _3f5=doc.createElement("div");
-var _3f6=uid+"_Listener";
-this.colorTable=_3e4(this.colorTable);
-var _3f7=[];
-var _3f8=null;
-var _3f9=function(msg){
-var _3fb=msg.level;
-if(typeof (_3fb)=="number"){
-_3fb=MochiKit.Logging.LogLevel[_3fb];
-}
-return _3fb;
-};
-var _3fc=function(msg){
-return msg.info.join(" ");
-};
-var _3fe=bind(function(msg){
-var _400=_3f9(msg);
-var text=_3fc(msg);
-var c=this.colorTable[_400];
-var p=doc.createElement("span");
-p.className="MochiKit-LogMessage MochiKit-LogLevel-"+_400;
-p.style.cssText="margin: 0px; white-space: -moz-pre-wrap; white-space: -o-pre-wrap; white-space: pre-wrap; white-space: pre-line; word-wrap: break-word; wrap-option: emergency; color: "+c;
-p.appendChild(doc.createTextNode(_400+": "+text));
-_3f5.appendChild(p);
-_3f5.appendChild(doc.createElement("br"));
-if(_3f4.offsetHeight>_3f4.scrollHeight){
-_3f4.scrollTop=0;
-}else{
-_3f4.scrollTop=_3f4.scrollHeight;
-}
-},this);
-var _404=function(msg){
-_3f7[_3f7.length]=msg;
-_3fe(msg);
-};
-var _406=function(){
-var _407,_408;
-try{
-_407=new RegExp(_3ee.value);
-_408=new RegExp(_3ef.value);
-}
-catch(e){
-logDebug("Error in filter regex: "+e.message);
-return null;
-}
-return function(msg){
-return (_407.test(_3f9(msg))&&_408.test(_3fc(msg)));
-};
-};
-var _40a=function(){
-while(_3f5.firstChild){
-_3f5.removeChild(_3f5.firstChild);
-}
-};
-var _40b=function(){
-_3f7=[];
-_40a();
-};
-var _40c=bind(function(){
-if(this.closed){
-return;
-}
-this.closed=true;
-if(MochiKit.LoggingPane._loggingPane==this){
-MochiKit.LoggingPane._loggingPane=null;
-}
-this.logger.removeListener(_3f6);
-_3eb.loggingPane=null;
-if(_3df){
-_3eb.parentNode.removeChild(_3eb);
-}else{
-this.win.close();
-}
-},this);
-var _40d=function(){
-_40a();
-for(var i=0;i<_3f7.length;i++){
-var msg=_3f7[i];
-if(_3f8===null||_3f8(msg)){
-_3fe(msg);
-}
-}
-};
-this.buildAndApplyFilter=function(){
-_3f8=_406();
-_40d();
-this.logger.removeListener(_3f6);
-this.logger.addListener(_3f6,_3f8,_404);
-};
-var _410=bind(function(){
-_3f7=this.logger.getMessages();
-_40d();
-},this);
-var _411=bind(function(_412){
-_412=_412||window.event;
-key=_412.which||_412.keyCode;
-if(key==13){
-this.buildAndApplyFilter();
-}
-},this);
-var _413="display: block; z-index: 1000; left: 0px; bottom: 0px; position: fixed; width: 100%; background-color: white; font: "+this.logFont;
-if(_3df){
-_413+="; height: 10em; border-top: 2px solid black";
-}else{
-_413+="; height: 100%;";
-}
-_3eb.style.cssText=_413;
-if(!_3ec){
-doc.body.appendChild(_3eb);
-}
-_413={"cssText":"width: 33%; display: inline; font: "+this.logFont};
-_3e2(_3ee,{"value":"FATAL|ERROR|WARNING|INFO|DEBUG","onkeypress":_411,"style":_413});
-_3eb.appendChild(_3ee);
-_3e2(_3ef,{"value":".*","onkeypress":_411,"style":_413});
-_3eb.appendChild(_3ef);
-_413="width: 8%; display:inline; font: "+this.logFont;
-_3f0.appendChild(doc.createTextNode("Filter"));
-_3f0.onclick=bind("buildAndApplyFilter",this);
-_3f0.style.cssText=_413;
-_3eb.appendChild(_3f0);
-_3f1.appendChild(doc.createTextNode("Load"));
-_3f1.onclick=_410;
-_3f1.style.cssText=_413;
-_3eb.appendChild(_3f1);
-_3f2.appendChild(doc.createTextNode("Clear"));
-_3f2.onclick=_40b;
-_3f2.style.cssText=_413;
-_3eb.appendChild(_3f2);
-_3f3.appendChild(doc.createTextNode("Close"));
-_3f3.onclick=_40c;
-_3f3.style.cssText=_413;
-_3eb.appendChild(_3f3);
-_3f4.style.cssText="overflow: auto; width: 100%";
-_3f5.style.cssText="width: 100%; height: "+(_3df?"8em":"100%");
-_3f4.appendChild(_3f5);
-_3eb.appendChild(_3f4);
-this.buildAndApplyFilter();
-_410();
-if(_3df){
-this.win=undefined;
-}else{
-this.win=win;
-}
-this.inline=_3df;
-this.closePane=_40c;
-this.closed=false;
-return this;
-};
-MochiKit.LoggingPane.LoggingPane.prototype={"logFont":"8pt Verdana,sans-serif","colorTable":{"ERROR":"red","FATAL":"darkred","WARNING":"blue","INFO":"black","DEBUG":"green"}};
-MochiKit.LoggingPane.EXPORT_OK=["LoggingPane"];
-MochiKit.LoggingPane.EXPORT=["createLoggingPane"];
-MochiKit.LoggingPane.__new__=function(){
-this.EXPORT_TAGS={":common":this.EXPORT,":all":MochiKit.Base.concat(this.EXPORT,this.EXPORT_OK)};
-MochiKit.Base.nameFunctions(this);
-MochiKit.LoggingPane._loggingPane=null;
-};
-MochiKit.LoggingPane.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.LoggingPane);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Color");
-dojo.require("MochiKit.Base");
-dojo.require("MochiKit.DOM");
-dojo.require("MochiKit.Style");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-JSAN.use("MochiKit.DOM",[]);
-JSAN.use("MochiKit.Style",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Color depends on MochiKit.Base";
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Color depends on MochiKit.DOM";
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Color depends on MochiKit.Style";
-}
-if(typeof (MochiKit.Color)=="undefined"){
-MochiKit.Color={};
-}
-MochiKit.Color.NAME="MochiKit.Color";
-MochiKit.Color.VERSION="1.4";
-MochiKit.Color.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Color.toString=function(){
-return this.__repr__();
-};
-MochiKit.Color.Color=function(red,_415,blue,_417){
-if(typeof (_417)=="undefined"||_417===null){
-_417=1;
-}
-this.rgb={r:red,g:_415,b:blue,a:_417};
-};
-MochiKit.Color.Color.prototype={__class__:MochiKit.Color.Color,colorWithAlpha:function(_418){
-var rgb=this.rgb;
-var m=MochiKit.Color;
-return m.Color.fromRGB(rgb.r,rgb.g,rgb.b,_418);
-},colorWithHue:function(hue){
-var hsl=this.asHSL();
-hsl.h=hue;
-var m=MochiKit.Color;
-return m.Color.fromHSL(hsl);
-},colorWithSaturation:function(_41e){
-var hsl=this.asHSL();
-hsl.s=_41e;
-var m=MochiKit.Color;
-return m.Color.fromHSL(hsl);
-},colorWithLightness:function(_421){
-var hsl=this.asHSL();
-hsl.l=_421;
-var m=MochiKit.Color;
-return m.Color.fromHSL(hsl);
-},darkerColorWithLevel:function(_424){
-var hsl=this.asHSL();
-hsl.l=Math.max(hsl.l-_424,0);
-var m=MochiKit.Color;
-return m.Color.fromHSL(hsl);
-},lighterColorWithLevel:function(_427){
-var hsl=this.asHSL();
-hsl.l=Math.min(hsl.l+_427,1);
-var m=MochiKit.Color;
-return m.Color.fromHSL(hsl);
-},blendedColor:function(_42a,_42b){
-if(typeof (_42b)=="undefined"||_42b===null){
-_42b=0.5;
-}
-var sf=1-_42b;
-var s=this.rgb;
-var d=_42a.rgb;
-var df=_42b;
-return MochiKit.Color.Color.fromRGB((s.r*sf)+(d.r*df),(s.g*sf)+(d.g*df),(s.b*sf)+(d.b*df),(s.a*sf)+(d.a*df));
-},compareRGB:function(_430){
-var a=this.asRGB();
-var b=_430.asRGB();
-return MochiKit.Base.compare([a.r,a.g,a.b,a.a],[b.r,b.g,b.b,b.a]);
-},isLight:function(){
-return this.asHSL().b>0.5;
-},isDark:function(){
-return (!this.isLight());
-},toHSLString:function(){
-var c=this.asHSL();
-var ccc=MochiKit.Color.clampColorComponent;
-var rval=this._hslString;
-if(!rval){
-var mid=(ccc(c.h,360).toFixed(0)+","+ccc(c.s,100).toPrecision(4)+"%"+","+ccc(c.l,100).toPrecision(4)+"%");
-var a=c.a;
-if(a>=1){
-a=1;
-rval="hsl("+mid+")";
-}else{
-if(a<=0){
-a=0;
-}
-rval="hsla("+mid+","+a+")";
-}
-this._hslString=rval;
-}
-return rval;
-},toRGBString:function(){
-var c=this.rgb;
-var ccc=MochiKit.Color.clampColorComponent;
-var rval=this._rgbString;
-if(!rval){
-var mid=(ccc(c.r,255).toFixed(0)+","+ccc(c.g,255).toFixed(0)+","+ccc(c.b,255).toFixed(0));
-if(c.a!=1){
-rval="rgba("+mid+","+c.a+")";
-}else{
-rval="rgb("+mid+")";
-}
-this._rgbString=rval;
-}
-return rval;
-},asRGB:function(){
-return MochiKit.Base.clone(this.rgb);
-},toHexString:function(){
-var m=MochiKit.Color;
-var c=this.rgb;
-var ccc=MochiKit.Color.clampColorComponent;
-var rval=this._hexString;
-if(!rval){
-rval=("#"+m.toColorPart(ccc(c.r,255))+m.toColorPart(ccc(c.g,255))+m.toColorPart(ccc(c.b,255)));
-this._hexString=rval;
-}
-return rval;
-},asHSV:function(){
-var hsv=this.hsv;
-var c=this.rgb;
-if(typeof (hsv)=="undefined"||hsv===null){
-hsv=MochiKit.Color.rgbToHSV(this.rgb);
-this.hsv=hsv;
-}
-return MochiKit.Base.clone(hsv);
-},asHSL:function(){
-var hsl=this.hsl;
-var c=this.rgb;
-if(typeof (hsl)=="undefined"||hsl===null){
-hsl=MochiKit.Color.rgbToHSL(this.rgb);
-this.hsl=hsl;
-}
-return MochiKit.Base.clone(hsl);
-},toString:function(){
-return this.toRGBString();
-},repr:function(){
-var c=this.rgb;
-var col=[c.r,c.g,c.b,c.a];
-return this.__class__.NAME+"("+col.join(", ")+")";
-}};
-MochiKit.Base.update(MochiKit.Color.Color,{fromRGB:function(red,_447,blue,_449){
-var _44a=MochiKit.Color.Color;
-if(arguments.length==1){
-var rgb=red;
-red=rgb.r;
-_447=rgb.g;
-blue=rgb.b;
-if(typeof (rgb.a)=="undefined"){
-_449=undefined;
-}else{
-_449=rgb.a;
-}
-}
-return new _44a(red,_447,blue,_449);
-},fromHSL:function(hue,_44d,_44e,_44f){
-var m=MochiKit.Color;
-return m.Color.fromRGB(m.hslToRGB.apply(m,arguments));
-},fromHSV:function(hue,_452,_453,_454){
-var m=MochiKit.Color;
-return m.Color.fromRGB(m.hsvToRGB.apply(m,arguments));
-},fromName:function(name){
-var _457=MochiKit.Color.Color;
-if(name.charAt(0)=="\""){
-name=name.substr(1,name.length-2);
-}
-var _458=_457._namedColors[name.toLowerCase()];
-if(typeof (_458)=="string"){
-return _457.fromHexString(_458);
-}else{
-if(name=="transparent"){
-return _457.transparentColor();
-}
-}
-return null;
-},fromString:function(_459){
-var self=MochiKit.Color.Color;
-var _45b=_459.substr(0,3);
-if(_45b=="rgb"){
-return self.fromRGBString(_459);
-}else{
-if(_45b=="hsl"){
-return self.fromHSLString(_459);
-}else{
-if(_459.charAt(0)=="#"){
-return self.fromHexString(_459);
-}
-}
-}
-return self.fromName(_459);
-},fromHexString:function(_45c){
-if(_45c.charAt(0)=="#"){
-_45c=_45c.substring(1);
-}
-var _45d=[];
-var i,hex;
-if(_45c.length==3){
-for(i=0;i<3;i++){
-hex=_45c.substr(i,1);
-_45d.push(parseInt(hex+hex,16)/255);
-}
-}else{
-for(i=0;i<6;i+=2){
-hex=_45c.substr(i,2);
-_45d.push(parseInt(hex,16)/255);
-}
-}
-var _460=MochiKit.Color.Color;
-return _460.fromRGB.apply(_460,_45d);
-},_fromColorString:function(pre,_462,_463,_464){
-if(_464.indexOf(pre)===0){
-_464=_464.substring(_464.indexOf("(",3)+1,_464.length-1);
-}
-var _465=_464.split(/\s*,\s*/);
-var _466=[];
-for(var i=0;i<_465.length;i++){
-var c=_465[i];
-var val;
-var _46a=c.substring(c.length-3);
-if(c.charAt(c.length-1)=="%"){
-val=0.01*parseFloat(c.substring(0,c.length-1));
-}else{
-if(_46a=="deg"){
-val=parseFloat(c)/360;
-}else{
-if(_46a=="rad"){
-val=parseFloat(c)/(Math.PI*2);
-}else{
-val=_463[i]*parseFloat(c);
-}
-}
-}
-_466.push(val);
-}
-return this[_462].apply(this,_466);
-},fromComputedStyle:function(elem,_46c){
-var d=MochiKit.DOM;
-var cls=MochiKit.Color.Color;
-for(elem=d.getElement(elem);elem;elem=elem.parentNode){
-var _46f=MochiKit.Style.computedStyle.apply(d,arguments);
-if(!_46f){
-continue;
-}
-var _470=cls.fromString(_46f);
-if(!_470){
-break;
-}
-if(_470.asRGB().a>0){
-return _470;
-}
-}
-return null;
-},fromBackground:function(elem){
-var cls=MochiKit.Color.Color;
-return cls.fromComputedStyle(elem,"backgroundColor","background-color")||cls.whiteColor();
-},fromText:function(elem){
-var cls=MochiKit.Color.Color;
-return cls.fromComputedStyle(elem,"color","color")||cls.blackColor();
-},namedColors:function(){
-return MochiKit.Base.clone(MochiKit.Color.Color._namedColors);
-}});
-MochiKit.Base.update(MochiKit.Color,{clampColorComponent:function(v,_476){
-v*=_476;
-if(v<0){
-return 0;
-}else{
-if(v>_476){
-return _476;
-}else{
-return v;
-}
-}
-},_hslValue:function(n1,n2,hue){
-if(hue>6){
-hue-=6;
-}else{
-if(hue<0){
-hue+=6;
-}
-}
-var val;
-if(hue<1){
-val=n1+(n2-n1)*hue;
-}else{
-if(hue<3){
-val=n2;
-}else{
-if(hue<4){
-val=n1+(n2-n1)*(4-hue);
-}else{
-val=n1;
-}
-}
-}
-return val;
-},hsvToRGB:function(hue,_47c,_47d,_47e){
-if(arguments.length==1){
-var hsv=hue;
-hue=hsv.h;
-_47c=hsv.s;
-_47d=hsv.v;
-_47e=hsv.a;
-}
-var red;
-var _481;
-var blue;
-if(_47c===0){
-red=0;
-_481=0;
-blue=0;
-}else{
-var i=Math.floor(hue*6);
-var f=(hue*6)-i;
-var p=_47d*(1-_47c);
-var q=_47d*(1-(_47c*f));
-var t=_47d*(1-(_47c*(1-f)));
-switch(i){
-case 1:
-red=q;
-_481=_47d;
-blue=p;
-break;
-case 2:
-red=p;
-_481=_47d;
-blue=t;
-break;
-case 3:
-red=p;
-_481=q;
-blue=_47d;
-break;
-case 4:
-red=t;
-_481=p;
-blue=_47d;
-break;
-case 5:
-red=_47d;
-_481=p;
-blue=q;
-break;
-case 6:
-case 0:
-red=_47d;
-_481=t;
-blue=p;
-break;
-}
-}
-return {r:red,g:_481,b:blue,a:_47e};
-},hslToRGB:function(hue,_489,_48a,_48b){
-if(arguments.length==1){
-var hsl=hue;
-hue=hsl.h;
-_489=hsl.s;
-_48a=hsl.l;
-_48b=hsl.a;
-}
-var red;
-var _48e;
-var blue;
-if(_489===0){
-red=_48a;
-_48e=_48a;
-blue=_48a;
-}else{
-var m2;
-if(_48a<=0.5){
-m2=_48a*(1+_489);
-}else{
-m2=_48a+_489-(_48a*_489);
-}
-var m1=(2*_48a)-m2;
-var f=MochiKit.Color._hslValue;
-var h6=hue*6;
-red=f(m1,m2,h6+2);
-_48e=f(m1,m2,h6);
-blue=f(m1,m2,h6-2);
-}
-return {r:red,g:_48e,b:blue,a:_48b};
-},rgbToHSV:function(red,_495,blue,_497){
-if(arguments.length==1){
-var rgb=red;
-red=rgb.r;
-_495=rgb.g;
-blue=rgb.b;
-_497=rgb.a;
-}
-var max=Math.max(Math.max(red,_495),blue);
-var min=Math.min(Math.min(red,_495),blue);
-var hue;
-var _49c;
-var _49d=max;
-if(min==max){
-hue=0;
-_49c=0;
-}else{
-var _49e=(max-min);
-_49c=_49e/max;
-if(red==max){
-hue=(_495-blue)/_49e;
-}else{
-if(_495==max){
-hue=2+((blue-red)/_49e);
-}else{
-hue=4+((red-_495)/_49e);
-}
-}
-hue/=6;
-if(hue<0){
-hue+=1;
-}
-if(hue>1){
-hue-=1;
-}
-}
-return {h:hue,s:_49c,v:_49d,a:_497};
-},rgbToHSL:function(red,_4a0,blue,_4a2){
-if(arguments.length==1){
-var rgb=red;
-red=rgb.r;
-_4a0=rgb.g;
-blue=rgb.b;
-_4a2=rgb.a;
-}
-var max=Math.max(red,Math.max(_4a0,blue));
-var min=Math.min(red,Math.min(_4a0,blue));
-var hue;
-var _4a7;
-var _4a8=(max+min)/2;
-var _4a9=max-min;
-if(_4a9===0){
-hue=0;
-_4a7=0;
-}else{
-if(_4a8<=0.5){
-_4a7=_4a9/(max+min);
-}else{
-_4a7=_4a9/(2-max-min);
-}
-if(red==max){
-hue=(_4a0-blue)/_4a9;
-}else{
-if(_4a0==max){
-hue=2+((blue-red)/_4a9);
-}else{
-hue=4+((red-_4a0)/_4a9);
-}
-}
-hue/=6;
-if(hue<0){
-hue+=1;
-}
-if(hue>1){
-hue-=1;
-}
-}
-return {h:hue,s:_4a7,l:_4a8,a:_4a2};
-},toColorPart:function(num){
-num=Math.round(num);
-var _4ab=num.toString(16);
-if(num<16){
-return "0"+_4ab;
-}
-return _4ab;
-},__new__:function(){
-var m=MochiKit.Base;
-this.Color.fromRGBString=m.bind(this.Color._fromColorString,this.Color,"rgb","fromRGB",[1/255,1/255,1/255,1]);
-this.Color.fromHSLString=m.bind(this.Color._fromColorString,this.Color,"hsl","fromHSL",[1/360,0.01,0.01,1]);
-var _4ad=1/3;
-var _4ae={black:[0,0,0],blue:[0,0,1],brown:[0.6,0.4,0.2],cyan:[0,1,1],darkGray:[_4ad,_4ad,_4ad],gray:[0.5,0.5,0.5],green:[0,1,0],lightGray:[2*_4ad,2*_4ad,2*_4ad],magenta:[1,0,1],orange:[1,0.5,0],purple:[0.5,0,0.5],red:[1,0,0],transparent:[0,0,0,0],white:[1,1,1],yellow:[1,1,0]};
-var _4af=function(name,r,g,b,a){
-var rval=this.fromRGB(r,g,b,a);
-this[name]=function(){
-return rval;
-};
-return rval;
-};
-for(var k in _4ae){
-var name=k+"Color";
-var _4b8=m.concat([_4af,this.Color,name],_4ae[k]);
-this.Color[name]=m.bind.apply(null,_4b8);
-}
-var _4b9=function(){
-for(var i=0;i<arguments.length;i++){
-if(!(arguments[i] instanceof Color)){
-return false;
-}
-}
-return true;
-};
-var _4bb=function(a,b){
-return a.compareRGB(b);
-};
-m.nameFunctions(this);
-m.registerComparator(this.Color.NAME,_4b9,_4bb);
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-}});
-MochiKit.Color.EXPORT=["Color"];
-MochiKit.Color.EXPORT_OK=["clampColorComponent","rgbToHSL","hslToRGB","rgbToHSV","hsvToRGB","toColorPart"];
-MochiKit.Color.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.Color);
-MochiKit.Color.Color._namedColors={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Signal");
-dojo.require("MochiKit.Base");
-dojo.require("MochiKit.DOM");
-dojo.require("MochiKit.Style");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-JSAN.use("MochiKit.DOM",[]);
-JSAN.use("MochiKit.Style",[]);
-}
-try{
-if(typeof (MochiKit.Base)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Signal depends on MochiKit.Base!";
-}
-try{
-if(typeof (MochiKit.DOM)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Signal depends on MochiKit.DOM!";
-}
-try{
-if(typeof (MochiKit.Style)=="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Signal depends on MochiKit.Style!";
-}
-if(typeof (MochiKit.Signal)=="undefined"){
-MochiKit.Signal={};
-}
-MochiKit.Signal.NAME="MochiKit.Signal";
-MochiKit.Signal.VERSION="1.4";
-MochiKit.Signal._observers=[];
-MochiKit.Signal.Event=function(src,e){
-this._event=e||window.event;
-this._src=src;
-};
-MochiKit.Base.update(MochiKit.Signal.Event.prototype,{__repr__:function(){
-var repr=MochiKit.Base.repr;
-var str="{event(): "+repr(this.event())+", src(): "+repr(this.src())+", type(): "+repr(this.type())+", target(): "+repr(this.target())+", modifier(): "+"{alt: "+repr(this.modifier().alt)+", ctrl: "+repr(this.modifier().ctrl)+", meta: "+repr(this.modifier().meta)+", shift: "+repr(this.modifier().shift)+", any: "+repr(this.modifier().any)+"}";
-if(this.type()&&this.type().indexOf("key")===0){
-str+=", key(): {code: "+repr(this.key().code)+", string: "+repr(this.key().string)+"}";
-}
-if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
-str+=", mouse(): {page: "+repr(this.mouse().page)+", client: "+repr(this.mouse().client);
-if(this.type()!="mousemove"){
-str+=", button: {left: "+repr(this.mouse().button.left)+", middle: "+repr(this.mouse().button.middle)+", right: "+repr(this.mouse().button.right)+"}}";
-}else{
-str+="}";
-}
-}
-if(this.type()=="mouseover"||this.type()=="mouseout"){
-str+=", relatedTarget(): "+repr(this.relatedTarget());
-}
-str+="}";
-return str;
-},toString:function(){
-return this.__repr__();
-},src:function(){
-return this._src;
-},event:function(){
-return this._event;
-},type:function(){
-return this._event.type||undefined;
-},target:function(){
-return this._event.target||this._event.srcElement;
-},_relatedTarget:null,relatedTarget:function(){
-if(this._relatedTarget!==null){
-return this._relatedTarget;
-}
-var elem=null;
-if(this.type()=="mouseover"){
-elem=(this._event.relatedTarget||this._event.fromElement);
-}else{
-if(this.type()=="mouseout"){
-elem=(this._event.relatedTarget||this._event.toElement);
-}
-}
-if(elem!==null){
-this._relatedTarget=elem;
-return elem;
-}
-return undefined;
-},_modifier:null,modifier:function(){
-if(this._modifier!==null){
-return this._modifier;
-}
-var m={};
-m.alt=this._event.altKey;
-m.ctrl=this._event.ctrlKey;
-m.meta=this._event.metaKey||false;
-m.shift=this._event.shiftKey;
-m.any=m.alt||m.ctrl||m.shift||m.meta;
-this._modifier=m;
-return m;
-},_key:null,key:function(){
-if(this._key!==null){
-return this._key;
-}
-var k={};
-if(this.type()&&this.type().indexOf("key")===0){
-if(this.type()=="keydown"||this.type()=="keyup"){
-k.code=this._event.keyCode;
-k.string=(MochiKit.Signal._specialKeys[k.code]||"KEY_UNKNOWN");
-this._key=k;
-return k;
-}else{
-if(this.type()=="keypress"){
-k.code=0;
-k.string="";
-if(typeof (this._event.charCode)!="undefined"&&this._event.charCode!==0&&!MochiKit.Signal._specialMacKeys[this._event.charCode]){
-k.code=this._event.charCode;
-k.string=String.fromCharCode(k.code);
-}else{
-if(this._event.keyCode&&typeof (this._event.charCode)=="undefined"){
-k.code=this._event.keyCode;
-k.string=String.fromCharCode(k.code);
-}
-}
-this._key=k;
-return k;
-}
-}
-}
-return undefined;
-},_mouse:null,mouse:function(){
-if(this._mouse!==null){
-return this._mouse;
-}
-var m={};
-var e=this._event;
-if(this.type()&&(this.type().indexOf("mouse")===0||this.type().indexOf("click")!=-1||this.type()=="contextmenu")){
-m.client=new MochiKit.Style.Coordinates(0,0);
-if(e.clientX||e.clientY){
-m.client.x=(!e.clientX||e.clientX<0)?0:e.clientX;
-m.client.y=(!e.clientY||e.clientY<0)?0:e.clientY;
-}
-m.page=new MochiKit.Style.Coordinates(0,0);
-if(e.pageX||e.pageY){
-m.page.x=(!e.pageX||e.pageX<0)?0:e.pageX;
-m.page.y=(!e.pageY||e.pageY<0)?0:e.pageY;
-}else{
-var de=MochiKit.DOM._document.documentElement;
-var b=MochiKit.DOM._document.body;
-m.page.x=e.clientX+(de.scrollLeft||b.scrollLeft)-(de.clientLeft||0);
-m.page.y=e.clientY+(de.scrollTop||b.scrollTop)-(de.clientTop||0);
-}
-if(this.type()!="mousemove"){
-m.button={};
-m.button.left=false;
-m.button.right=false;
-m.button.middle=false;
-if(e.which){
-m.button.left=(e.which==1);
-m.button.middle=(e.which==2);
-m.button.right=(e.which==3);
-}else{
-m.button.left=!!(e.button&1);
-m.button.right=!!(e.button&2);
-m.button.middle=!!(e.button&4);
-}
-}
-this._mouse=m;
-return m;
-}
-return undefined;
-},stop:function(){
-this.stopPropagation();
-this.preventDefault();
-},stopPropagation:function(){
-if(this._event.stopPropagation){
-this._event.stopPropagation();
-}else{
-this._event.cancelBubble=true;
-}
-},preventDefault:function(){
-if(this._event.preventDefault){
-this._event.preventDefault();
-}else{
-if(this._confirmUnload===null){
-this._event.returnValue=false;
-}
-}
-},_confirmUnload:null,confirmUnload:function(msg){
-if(this.type()=="beforeunload"){
-this._confirmUnload=msg;
-this._event.returnValue=msg;
-}
-}});
-MochiKit.Signal._specialMacKeys={3:"KEY_ENTER",63289:"KEY_NUM_PAD_CLEAR",63276:"KEY_PAGE_UP",63277:"KEY_PAGE_DOWN",63275:"KEY_END",63273:"KEY_HOME",63234:"KEY_ARROW_LEFT",63232:"KEY_ARROW_UP",63235:"KEY_ARROW_RIGHT",63233:"KEY_ARROW_DOWN",63302:"KEY_INSERT",63272:"KEY_DELETE"};
-(function(){
-var _4ca=MochiKit.Signal._specialMacKeys;
-for(i=63236;i<=63242;i++){
-_4ca[i]="KEY_F"+(i-63236+1);
-}
-})();
-MochiKit.Signal._specialKeys={8:"KEY_BACKSPACE",9:"KEY_TAB",12:"KEY_NUM_PAD_CLEAR",13:"KEY_ENTER",16:"KEY_SHIFT",17:"KEY_CTRL",18:"KEY_ALT",19:"KEY_PAUSE",20:"KEY_CAPS_LOCK",27:"KEY_ESCAPE",32:"KEY_SPACEBAR",33:"KEY_PAGE_UP",34:"KEY_PAGE_DOWN",35:"KEY_END",36:"KEY_HOME",37:"KEY_ARROW_LEFT",38:"KEY_ARROW_UP",39:"KEY_ARROW_RIGHT",40:"KEY_ARROW_DOWN",44:"KEY_PRINT_SCREEN",45:"KEY_INSERT",46:"KEY_DELETE",59:"KEY_SEMICOLON",91:"KEY_WINDOWS_LEFT",92:"KEY_WINDOWS_RIGHT",93:"KEY_SELECT",106:"KEY_NUM_PAD_ASTERISK",107:"KEY_NUM_PAD_PLUS_SIGN",109:"KEY_NUM_PAD_HYPHEN-MINUS",110:"KEY_NUM_PAD_FULL_STOP",111:"KEY_NUM_PAD_SOLIDUS",144:"KEY_NUM_LOCK",145:"KEY_SCROLL_LOCK",186:"KEY_SEMICOLON",187:"KEY_EQUALS_SIGN",188:"KEY_COMMA",189:"KEY_HYPHEN-MINUS",190:"KEY_FULL_STOP",191:"KEY_SOLIDUS",192:"KEY_GRAVE_ACCENT",219:"KEY_LEFT_SQUARE_BRACKET",220:"KEY_REVERSE_SOLIDUS",221:"KEY_RIGHT_SQUARE_BRACKET",222:"KEY_APOSTROPHE"};
-(function(){
-var _4cb=MochiKit.Signal._specialKeys;
-for(var i=48;i<=57;i++){
-_4cb[i]="KEY_"+(i-48);
-}
-for(i=65;i<=90;i++){
-_4cb[i]="KEY_"+String.fromCharCode(i);
-}
-for(i=96;i<=105;i++){
-_4cb[i]="KEY_NUM_PAD_"+(i-96);
-}
-for(i=112;i<=123;i++){
-_4cb[i]="KEY_F"+(i-112+1);
-}
-})();
-MochiKit.Base.update(MochiKit.Signal,{__repr__:function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-},toString:function(){
-return this.__repr__();
-},_unloadCache:function(){
-var self=MochiKit.Signal;
-var _4ce=self._observers;
-for(var i=0;i<_4ce.length;i++){
-self._disconnect(_4ce[i]);
-}
-delete self._observers;
-try{
-window.onload=undefined;
-}
-catch(e){
-}
-try{
-window.onunload=undefined;
-}
-catch(e){
-}
-},_listener:function(src,func,obj,_4d3){
-var self=MochiKit.Signal;
-var E=self.Event;
-if(!_4d3){
-return MochiKit.Base.bind(func,obj);
-}
-obj=obj||src;
-if(typeof (func)=="string"){
-return function(_4d6){
-obj[func].apply(obj,[new E(src,_4d6)]);
-};
-}else{
-return function(_4d7){
-func.apply(obj,[new E(src,_4d7)]);
-};
-}
-},_browserAlreadyHasMouseEnterAndLeave:function(){
-return /MSIE/.test(navigator.userAgent);
-},_mouseEnterListener:function(src,sig,func,obj){
-var E=MochiKit.Signal.Event;
-return function(_4dd){
-var e=new E(src,_4dd);
-try{
-e.relatedTarget().nodeName;
-}
-catch(err){
-return;
-}
-e.stop();
-if(MochiKit.DOM.isChildNode(e.relatedTarget(),src)){
-return;
-}
-e.type=function(){
-return sig;
-};
-if(typeof (func)=="string"){
-return obj[func].apply(obj,[e]);
-}else{
-return func.apply(obj,[e]);
-}
-};
-},_getDestPair:function(_4df,_4e0){
-var obj=null;
-var func=null;
-if(typeof (_4e0)!="undefined"){
-obj=_4df;
-func=_4e0;
-if(typeof (_4e0)=="string"){
-if(typeof (_4df[_4e0])!="function"){
-throw new Error("'funcOrStr' must be a function on 'objOrFunc'");
-}
-}else{
-if(typeof (_4e0)!="function"){
-throw new Error("'funcOrStr' must be a function or string");
-}
-}
-}else{
-if(typeof (_4df)!="function"){
-throw new Error("'objOrFunc' must be a function if 'funcOrStr' is not given");
-}else{
-func=_4df;
-}
-}
-return [obj,func];
-},connect:function(src,sig,_4e5,_4e6){
-src=MochiKit.DOM.getElement(src);
-var self=MochiKit.Signal;
-if(typeof (sig)!="string"){
-throw new Error("'sig' must be a string");
-}
-var _4e8=self._getDestPair(_4e5,_4e6);
-var obj=_4e8[0];
-var func=_4e8[1];
-if(typeof (obj)=="undefined"||obj===null){
-obj=src;
-}
-var _4eb=!!(src.addEventListener||src.attachEvent);
-if(_4eb&&(sig==="onmouseenter"||sig==="onmouseleave")&&!self._browserAlreadyHasMouseEnterAndLeave()){
-var _4ec=self._mouseEnterListener(src,sig.substr(2),func,obj);
-if(sig==="onmouseenter"){
-sig="onmouseover";
-}else{
-sig="onmouseout";
-}
-}else{
-var _4ec=self._listener(src,func,obj,_4eb);
-}
-if(src.addEventListener){
-src.addEventListener(sig.substr(2),_4ec,false);
-}else{
-if(src.attachEvent){
-src.attachEvent(sig,_4ec);
-}
-}
-var _4ed=[src,sig,_4ec,_4eb,_4e5,_4e6,true];
-self._observers.push(_4ed);
-if(!_4eb&&typeof (src.__connect__)=="function"){
-var args=MochiKit.Base.extend([_4ed],arguments,1);
-src.__connect__.apply(src,args);
-}
-return _4ed;
-},_disconnect:function(_4ef){
-if(!_4ef[6]){
-return;
-}
-_4ef[6]=false;
-if(!_4ef[3]){
-return;
-}
-var src=_4ef[0];
-var sig=_4ef[1];
-var _4f2=_4ef[2];
-if(src.removeEventListener){
-src.removeEventListener(sig.substr(2),_4f2,false);
-}else{
-if(src.detachEvent){
-src.detachEvent(sig,_4f2);
-}else{
-throw new Error("'src' must be a DOM element");
-}
-}
-},disconnect:function(_4f3){
-var self=MochiKit.Signal;
-var _4f5=self._observers;
-var m=MochiKit.Base;
-if(arguments.length>1){
-var src=MochiKit.DOM.getElement(arguments[0]);
-var sig=arguments[1];
-var obj=arguments[2];
-var func=arguments[3];
-for(var i=_4f5.length-1;i>=0;i--){
-var o=_4f5[i];
-if(o[0]===src&&o[1]===sig&&o[4]===obj&&o[5]===func){
-self._disconnect(o);
-if(!self._lock){
-_4f5.splice(i,1);
-}else{
-self._dirty=true;
-}
-return true;
-}
-}
-}else{
-var idx=m.findIdentical(_4f5,_4f3);
-if(idx>=0){
-self._disconnect(_4f3);
-if(!self._lock){
-_4f5.splice(idx,1);
-}else{
-self._dirty=true;
-}
-return true;
-}
-}
-return false;
-},disconnectAllTo:function(_4fe,_4ff){
-var self=MochiKit.Signal;
-var _501=self._observers;
-var _502=self._disconnect;
-var _503=self._lock;
-var _504=self._dirty;
-if(typeof (_4ff)==="undefined"){
-_4ff=null;
-}
-for(var i=_501.length-1;i>=0;i--){
-var _506=_501[i];
-if(_506[4]===_4fe&&(_4ff===null||_506[5]===_4ff)){
-_502(_506);
-if(_503){
-_504=true;
-}else{
-_501.splice(i,1);
-}
-}
-}
-self._dirty=_504;
-},disconnectAll:function(src,sig){
-src=MochiKit.DOM.getElement(src);
-var m=MochiKit.Base;
-var _50a=m.flattenArguments(m.extend(null,arguments,1));
-var self=MochiKit.Signal;
-var _50c=self._disconnect;
-var _50d=self._observers;
-var i,_50f;
-var _510=self._lock;
-var _511=self._dirty;
-if(_50a.length===0){
-for(i=_50d.length-1;i>=0;i--){
-_50f=_50d[i];
-if(_50f[0]===src){
-_50c(_50f);
-if(!_510){
-_50d.splice(i,1);
-}else{
-_511=true;
-}
-}
-}
-}else{
-var sigs={};
-for(i=0;i<_50a.length;i++){
-sigs[_50a[i]]=true;
-}
-for(i=_50d.length-1;i>=0;i--){
-_50f=_50d[i];
-if(_50f[0]===src&&_50f[1] in sigs){
-_50c(_50f);
-if(!_510){
-_50d.splice(i,1);
-}else{
-_511=true;
-}
-}
-}
-}
-self._dirty=_511;
-},signal:function(src,sig){
-var self=MochiKit.Signal;
-var _516=self._observers;
-src=MochiKit.DOM.getElement(src);
-var args=MochiKit.Base.extend(null,arguments,2);
-var _518=[];
-self._lock=true;
-for(var i=0;i<_516.length;i++){
-var _51a=_516[i];
-if(_51a[0]===src&&_51a[1]===sig){
-try{
-_51a[2].apply(src,args);
-}
-catch(e){
-_518.push(e);
-}
-}
-}
-self._lock=false;
-if(self._dirty){
-self._dirty=false;
-for(var i=_516.length-1;i>=0;i--){
-if(!_516[i][6]){
-_516.splice(i,1);
-}
-}
-}
-if(_518.length==1){
-throw _518[0];
-}else{
-if(_518.length>1){
-var e=new Error("Multiple errors thrown in handling 'sig', see errors property");
-e.errors=_518;
-throw e;
-}
-}
-}});
-MochiKit.Signal.EXPORT_OK=[];
-MochiKit.Signal.EXPORT=["connect","disconnect","signal","disconnectAll","disconnectAllTo"];
-MochiKit.Signal.__new__=function(win){
-var m=MochiKit.Base;
-this._document=document;
-this._window=win;
-this._lock=false;
-this._dirty=false;
-try{
-this.connect(window,"onunload",this._unloadCache);
-}
-catch(e){
-}
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-m.nameFunctions(this);
-};
-MochiKit.Signal.__new__(this);
-if(MochiKit.__export__){
-connect=MochiKit.Signal.connect;
-disconnect=MochiKit.Signal.disconnect;
-disconnectAll=MochiKit.Signal.disconnectAll;
-signal=MochiKit.Signal.signal;
-}
-MochiKit.Base._exportSymbols(this,MochiKit.Signal);
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.Visual");
-dojo.require("MochiKit.Base");
-dojo.require("MochiKit.DOM");
-dojo.require("MochiKit.Style");
-dojo.require("MochiKit.Color");
-}
-if(typeof (JSAN)!="undefined"){
-JSAN.use("MochiKit.Base",[]);
-JSAN.use("MochiKit.DOM",[]);
-JSAN.use("MochiKit.Style",[]);
-JSAN.use("MochiKit.Color",[]);
-}
-try{
-if(typeof (MochiKit.Base)==="undefined"||typeof (MochiKit.DOM)==="undefined"||typeof (MochiKit.Style)==="undefined"||typeof (MochiKit.Color)==="undefined"){
-throw "";
-}
-}
-catch(e){
-throw "MochiKit.Visual depends on MochiKit.Base, MochiKit.DOM, MochiKit.Style and MochiKit.Color!";
-}
-if(typeof (MochiKit.Visual)=="undefined"){
-MochiKit.Visual={};
-}
-MochiKit.Visual.NAME="MochiKit.Visual";
-MochiKit.Visual.VERSION="1.4";
-MochiKit.Visual.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.Visual.toString=function(){
-return this.__repr__();
-};
-MochiKit.Visual._RoundCorners=function(e,_51f){
-e=MochiKit.DOM.getElement(e);
-this._setOptions(_51f);
-if(this.options.__unstable__wrapElement){
-e=this._doWrap(e);
-}
-var _520=this.options.color;
-var C=MochiKit.Color.Color;
-if(this.options.color==="fromElement"){
-_520=C.fromBackground(e);
-}else{
-if(!(_520 instanceof C)){
-_520=C.fromString(_520);
-}
-}
-this.isTransparent=(_520.asRGB().a<=0);
-var _522=this.options.bgColor;
-if(this.options.bgColor==="fromParent"){
-_522=C.fromBackground(e.offsetParent);
-}else{
-if(!(_522 instanceof C)){
-_522=C.fromString(_522);
-}
-}
-this._roundCornersImpl(e,_520,_522);
-};
-MochiKit.Visual._RoundCorners.prototype={_doWrap:function(e){
-var _524=e.parentNode;
-var doc=MochiKit.DOM.currentDocument();
-if(typeof (doc.defaultView)==="undefined"||doc.defaultView===null){
-return e;
-}
-var _526=doc.defaultView.getComputedStyle(e,null);
-if(typeof (_526)==="undefined"||_526===null){
-return e;
-}
-var _527=MochiKit.DOM.DIV({"style":{display:"block",marginTop:_526.getPropertyValue("padding-top"),marginRight:_526.getPropertyValue("padding-right"),marginBottom:_526.getPropertyValue("padding-bottom"),marginLeft:_526.getPropertyValue("padding-left"),padding:"0px"}});
-_527.innerHTML=e.innerHTML;
-e.innerHTML="";
-e.appendChild(_527);
-return e;
-},_roundCornersImpl:function(e,_529,_52a){
-if(this.options.border){
-this._renderBorder(e,_52a);
-}
-if(this._isTopRounded()){
-this._roundTopCorners(e,_529,_52a);
-}
-if(this._isBottomRounded()){
-this._roundBottomCorners(e,_529,_52a);
-}
-},_renderBorder:function(el,_52c){
-var _52d="1px solid "+this._borderColor(_52c);
-var _52e="border-left: "+_52d;
-var _52f="border-right: "+_52d;
-var _530="style='"+_52e+";"+_52f+"'";
-el.innerHTML="<div "+_530+">"+el.innerHTML+"</div>";
-},_roundTopCorners:function(el,_532,_533){
-var _534=this._createCorner(_533);
-for(var i=0;i<this.options.numSlices;i++){
-_534.appendChild(this._createCornerSlice(_532,_533,i,"top"));
-}
-el.style.paddingTop=0;
-el.insertBefore(_534,el.firstChild);
-},_roundBottomCorners:function(el,_537,_538){
-var _539=this._createCorner(_538);
-for(var i=(this.options.numSlices-1);i>=0;i--){
-_539.appendChild(this._createCornerSlice(_537,_538,i,"bottom"));
-}
-el.style.paddingBottom=0;
-el.appendChild(_539);
-},_createCorner:function(_53b){
-var dom=MochiKit.DOM;
-return dom.DIV({style:{backgroundColor:_53b.toString()}});
-},_createCornerSlice:function(_53d,_53e,n,_540){
-var _541=MochiKit.DOM.SPAN();
-var _542=_541.style;
-_542.backgroundColor=_53d.toString();
-_542.display="block";
-_542.height="1px";
-_542.overflow="hidden";
-_542.fontSize="1px";
-var _543=this._borderColor(_53d,_53e);
-if(this.options.border&&n===0){
-_542.borderTopStyle="solid";
-_542.borderTopWidth="1px";
-_542.borderLeftWidth="0px";
-_542.borderRightWidth="0px";
-_542.borderBottomWidth="0px";
-_542.height="0px";
-_542.borderColor=_543.toString();
-}else{
-if(_543){
-_542.borderColor=_543.toString();
-_542.borderStyle="solid";
-_542.borderWidth="0px 1px";
-}
-}
-if(!this.options.compact&&(n==(this.options.numSlices-1))){
-_542.height="2px";
-}
-this._setMargin(_541,n,_540);
-this._setBorder(_541,n,_540);
-return _541;
-},_setOptions:function(_544){
-this.options={corners:"all",color:"fromElement",bgColor:"fromParent",blend:true,border:false,compact:false,__unstable__wrapElement:false};
-MochiKit.Base.update(this.options,_544);
-this.options.numSlices=(this.options.compact?2:4);
-},_whichSideTop:function(){
-var _545=this.options.corners;
-if(this._hasString(_545,"all","top")){
-return "";
-}
-var _546=(_545.indexOf("tl")!=-1);
-var _547=(_545.indexOf("tr")!=-1);
-if(_546&&_547){
-return "";
-}
-if(_546){
-return "left";
-}
-if(_547){
-return "right";
-}
-return "";
-},_whichSideBottom:function(){
-var _548=this.options.corners;
-if(this._hasString(_548,"all","bottom")){
-return "";
-}
-var _549=(_548.indexOf("bl")!=-1);
-var _54a=(_548.indexOf("br")!=-1);
-if(_549&&_54a){
-return "";
-}
-if(_549){
-return "left";
-}
-if(_54a){
-return "right";
-}
-return "";
-},_borderColor:function(_54b,_54c){
-if(_54b=="transparent"){
-return _54c;
-}else{
-if(this.options.border){
-return this.options.border;
-}else{
-if(this.options.blend){
-return _54c.blendedColor(_54b);
-}
-}
-}
-return "";
-},_setMargin:function(el,n,_54f){
-var _550=this._marginSize(n)+"px";
-var _551=(_54f=="top"?this._whichSideTop():this._whichSideBottom());
-var _552=el.style;
-if(_551=="left"){
-_552.marginLeft=_550;
-_552.marginRight="0px";
-}else{
-if(_551=="right"){
-_552.marginRight=_550;
-_552.marginLeft="0px";
-}else{
-_552.marginLeft=_550;
-_552.marginRight=_550;
-}
-}
-},_setBorder:function(el,n,_555){
-var _556=this._borderSize(n)+"px";
-var _557=(_555=="top"?this._whichSideTop():this._whichSideBottom());
-var _558=el.style;
-if(_557=="left"){
-_558.borderLeftWidth=_556;
-_558.borderRightWidth="0px";
-}else{
-if(_557=="right"){
-_558.borderRightWidth=_556;
-_558.borderLeftWidth="0px";
-}else{
-_558.borderLeftWidth=_556;
-_558.borderRightWidth=_556;
-}
-}
-},_marginSize:function(n){
-if(this.isTransparent){
-return 0;
-}
-var o=this.options;
-if(o.compact&&o.blend){
-var _55b=[1,0];
-return _55b[n];
-}else{
-if(o.compact){
-var _55c=[2,1];
-return _55c[n];
-}else{
-if(o.blend){
-var _55d=[3,2,1,0];
-return _55d[n];
-}else{
-var _55e=[5,3,2,1];
-return _55e[n];
-}
-}
-}
-},_borderSize:function(n){
-var o=this.options;
-var _561;
-if(o.compact&&(o.blend||this.isTransparent)){
-return 1;
-}else{
-if(o.compact){
-_561=[1,0];
-}else{
-if(o.blend){
-_561=[2,1,1,1];
-}else{
-if(o.border){
-_561=[0,2,0,0];
-}else{
-if(this.isTransparent){
-_561=[5,3,2,1];
-}else{
-return 0;
-}
-}
-}
-}
-}
-return _561[n];
-},_hasString:function(str){
-for(var i=1;i<arguments.length;i++){
-if(str.indexOf(arguments[i])!=-1){
-return true;
-}
-}
-return false;
-},_isTopRounded:function(){
-return this._hasString(this.options.corners,"all","top","tl","tr");
-},_isBottomRounded:function(){
-return this._hasString(this.options.corners,"all","bottom","bl","br");
-},_hasSingleTextChild:function(el){
-return (el.childNodes.length==1&&el.childNodes[0].nodeType==3);
-}};
-MochiKit.Visual.roundElement=function(e,_566){
-new MochiKit.Visual._RoundCorners(e,_566);
-};
-MochiKit.Visual.roundClass=function(_567,_568,_569){
-var _56a=MochiKit.DOM.getElementsByTagAndClassName(_567,_568);
-for(var i=0;i<_56a.length;i++){
-MochiKit.Visual.roundElement(_56a[i],_569);
-}
-};
-MochiKit.Visual.tagifyText=function(_56c,_56d){
-var _56d=_56d||"position:relative";
-if(/MSIE/.test(navigator.userAgent)){
-_56d+=";zoom:1";
-}
-_56c=MochiKit.DOM.getElement(_56c);
-var ma=MochiKit.Base.map;
-ma(function(_56f){
-if(_56f.nodeType==3){
-ma(function(_570){
-_56c.insertBefore(MochiKit.DOM.SPAN({style:_56d},_570==" "?String.fromCharCode(160):_570),_56f);
-},_56f.nodeValue.split(""));
-MochiKit.DOM.removeElement(_56f);
-}
-},_56c.childNodes);
-};
-MochiKit.Visual.forceRerendering=function(_571){
-try{
-_571=MochiKit.DOM.getElement(_571);
-var n=document.createTextNode(" ");
-_571.appendChild(n);
-_571.removeChild(n);
-}
-catch(e){
-}
-};
-MochiKit.Visual.multiple=function(_573,_574,_575){
-_575=MochiKit.Base.update({speed:0.1,delay:0},_575||{});
-var _576=_575.delay;
-var _577=0;
-MochiKit.Base.map(function(_578){
-_575.delay=_577*_575.speed+_576;
-new _574(_578,_575);
-_577+=1;
-},_573);
-};
-MochiKit.Visual.PAIRS={"slide":["slideDown","slideUp"],"blind":["blindDown","blindUp"],"appear":["appear","fade"],"size":["grow","shrink"]};
-MochiKit.Visual.toggle=function(_579,_57a,_57b){
-_579=MochiKit.DOM.getElement(_579);
-_57a=(_57a||"appear").toLowerCase();
-_57b=MochiKit.Base.update({queue:{position:"end",scope:(_579.id||"global"),limit:1}},_57b||{});
-var v=MochiKit.Visual;
-v[_579.style.display!="none"?v.PAIRS[_57a][1]:v.PAIRS[_57a][0]](_579,_57b);
-};
-MochiKit.Visual.Transitions={};
-MochiKit.Visual.Transitions.linear=function(pos){
-return pos;
-};
-MochiKit.Visual.Transitions.sinoidal=function(pos){
-return (-Math.cos(pos*Math.PI)/2)+0.5;
-};
-MochiKit.Visual.Transitions.reverse=function(pos){
-return 1-pos;
-};
-MochiKit.Visual.Transitions.flicker=function(pos){
-return ((-Math.cos(pos*Math.PI)/4)+0.75)+Math.random()/4;
-};
-MochiKit.Visual.Transitions.wobble=function(pos){
-return (-Math.cos(pos*Math.PI*(9*pos))/2)+0.5;
-};
-MochiKit.Visual.Transitions.pulse=function(pos){
-return (Math.floor(pos*10)%2==0?(pos*10-Math.floor(pos*10)):1-(pos*10-Math.floor(pos*10)));
-};
-MochiKit.Visual.Transitions.none=function(pos){
-return 0;
-};
-MochiKit.Visual.Transitions.full=function(pos){
-return 1;
-};
-MochiKit.Visual.ScopedQueue=function(){
-this.__init__();
-};
-MochiKit.Base.update(MochiKit.Visual.ScopedQueue.prototype,{__init__:function(){
-this.effects=[];
-this.interval=null;
-},add:function(_585){
-var _586=new Date().getTime();
-var _587=(typeof (_585.options.queue)=="string")?_585.options.queue:_585.options.queue.position;
-var ma=MochiKit.Base.map;
-switch(_587){
-case "front":
-ma(function(e){
-if(e.state=="idle"){
-e.startOn+=_585.finishOn;
-e.finishOn+=_585.finishOn;
-}
-},this.effects);
-break;
-case "end":
-var _58a;
-ma(function(e){
-var i=e.finishOn;
-if(i>=(_58a||i)){
-_58a=i;
-}
-},this.effects);
-_586=_58a||_586;
-break;
-case "break":
-ma(function(e){
-e.finalize();
-},this.effects);
-break;
-}
-_585.startOn+=_586;
-_585.finishOn+=_586;
-if(!_585.options.queue.limit||this.effects.length<_585.options.queue.limit){
-this.effects.push(_585);
-}
-if(!this.interval){
-this.interval=this.startLoop(MochiKit.Base.bind(this.loop,this),40);
-}
-},startLoop:function(func,_58f){
-return setInterval(func,_58f);
-},remove:function(_590){
-this.effects=MochiKit.Base.filter(function(e){
-return e!=_590;
-},this.effects);
-if(this.effects.length==0){
-this.stopLoop(this.interval);
-this.interval=null;
-}
-},stopLoop:function(_592){
-clearInterval(_592);
-},loop:function(){
-var _593=new Date().getTime();
-MochiKit.Base.map(function(_594){
-_594.loop(_593);
-},this.effects);
-}});
-MochiKit.Visual.Queues={instances:{},get:function(_595){
-if(typeof (_595)!="string"){
-return _595;
-}
-if(!this.instances[_595]){
-this.instances[_595]=new MochiKit.Visual.ScopedQueue();
-}
-return this.instances[_595];
-}};
-MochiKit.Visual.Queue=MochiKit.Visual.Queues.get("global");
-MochiKit.Visual.DefaultOptions={transition:MochiKit.Visual.Transitions.sinoidal,duration:1,fps:25,sync:false,from:0,to:1,delay:0,queue:"parallel"};
-MochiKit.Visual.Base=function(){
-};
-MochiKit.Visual.Base.prototype={__class__:MochiKit.Visual.Base,start:function(_596){
-var v=MochiKit.Visual;
-this.options=MochiKit.Base.setdefault(_596||{},v.DefaultOptions);
-this.currentFrame=0;
-this.state="idle";
-this.startOn=this.options.delay*1000;
-this.finishOn=this.startOn+(this.options.duration*1000);
-this.event("beforeStart");
-if(!this.options.sync){
-v.Queues.get(typeof (this.options.queue)=="string"?"global":this.options.queue.scope).add(this);
-}
-},loop:function(_598){
-if(_598>=this.startOn){
-if(_598>=this.finishOn){
-return this.finalize();
-}
-var pos=(_598-this.startOn)/(this.finishOn-this.startOn);
-var _59a=Math.round(pos*this.options.fps*this.options.duration);
-if(_59a>this.currentFrame){
-this.render(pos);
-this.currentFrame=_59a;
-}
-}
-},render:function(pos){
-if(this.state=="idle"){
-this.state="running";
-this.event("beforeSetup");
-this.setup();
-this.event("afterSetup");
-}
-if(this.state=="running"){
-if(this.options.transition){
-pos=this.options.transition(pos);
-}
-pos*=(this.options.to-this.options.from);
-pos+=this.options.from;
-this.event("beforeUpdate");
-this.update(pos);
-this.event("afterUpdate");
-}
-},cancel:function(){
-if(!this.options.sync){
-MochiKit.Visual.Queues.get(typeof (this.options.queue)=="string"?"global":this.options.queue.scope).remove(this);
-}
-this.state="finished";
-},finalize:function(){
-this.render(1);
-this.cancel();
-this.event("beforeFinish");
-this.finish();
-this.event("afterFinish");
-},setup:function(){
-},finish:function(){
-},update:function(_59c){
-},event:function(_59d){
-if(this.options[_59d+"Internal"]){
-this.options[_59d+"Internal"](this);
-}
-if(this.options[_59d]){
-this.options[_59d](this);
-}
-},repr:function(){
-return "["+this.__class__.NAME+", options:"+MochiKit.Base.repr(this.options)+"]";
-}};
-MochiKit.Visual.Parallel=function(_59e,_59f){
-this.__init__(_59e,_59f);
-};
-MochiKit.Visual.Parallel.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.Parallel.prototype,{__init__:function(_5a0,_5a1){
-this.effects=_5a0||[];
-this.start(_5a1);
-},update:function(_5a2){
-MochiKit.Base.map(function(_5a3){
-_5a3.render(_5a2);
-},this.effects);
-},finish:function(){
-MochiKit.Base.map(function(_5a4){
-_5a4.finalize();
-},this.effects);
-}});
-MochiKit.Visual.Opacity=function(_5a5,_5a6){
-this.__init__(_5a5,_5a6);
-};
-MochiKit.Visual.Opacity.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.Opacity.prototype,{__init__:function(_5a7,_5a8){
-var b=MochiKit.Base;
-var s=MochiKit.Style;
-this.element=MochiKit.DOM.getElement(_5a7);
-if(this.element.currentStyle&&(!this.element.currentStyle.hasLayout)){
-s.setStyle(this.element,{zoom:1});
-}
-_5a8=b.update({from:s.getOpacity(this.element)||0,to:1},_5a8||{});
-this.start(_5a8);
-},update:function(_5ab){
-MochiKit.Style.setOpacity(this.element,_5ab);
-}});
-MochiKit.Visual.Move=function(_5ac,_5ad){
-this.__init__(_5ac,_5ad);
-};
-MochiKit.Visual.Move.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.Move.prototype,{__init__:function(_5ae,_5af){
-this.element=MochiKit.DOM.getElement(_5ae);
-_5af=MochiKit.Base.update({x:0,y:0,mode:"relative"},_5af||{});
-this.start(_5af);
-},setup:function(){
-MochiKit.DOM.makePositioned(this.element);
-var s=this.element.style;
-var _5b1=s.visibility;
-var _5b2=s.display;
-if(_5b2=="none"){
-s.visibility="hidden";
-s.display="";
-}
-this.originalLeft=parseFloat(MochiKit.Style.getStyle(this.element,"left")||"0");
-this.originalTop=parseFloat(MochiKit.Style.getStyle(this.element,"top")||"0");
-if(this.options.mode=="absolute"){
-this.options.x-=this.originalLeft;
-this.options.y-=this.originalTop;
-}
-if(_5b2=="none"){
-s.visibility=_5b1;
-s.display=_5b2;
-}
-},update:function(_5b3){
-MochiKit.Style.setStyle(this.element,{left:Math.round(this.options.x*_5b3+this.originalLeft)+"px",top:Math.round(this.options.y*_5b3+this.originalTop)+"px"});
-}});
-MochiKit.Visual.Scale=function(_5b4,_5b5,_5b6){
-this.__init__(_5b4,_5b5,_5b6);
-};
-MochiKit.Visual.Scale.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.Scale.prototype,{__init__:function(_5b7,_5b8,_5b9){
-this.element=MochiKit.DOM.getElement(_5b7);
-_5b9=MochiKit.Base.update({scaleX:true,scaleY:true,scaleContent:true,scaleFromCenter:false,scaleMode:"box",scaleFrom:100,scaleTo:_5b8},_5b9||{});
-this.start(_5b9);
-},setup:function(){
-this.restoreAfterFinish=this.options.restoreAfterFinish||false;
-this.elementPositioning=MochiKit.Style.getStyle(this.element,"position");
-var ma=MochiKit.Base.map;
-var b=MochiKit.Base.bind;
-this.originalStyle={};
-ma(b(function(k){
-this.originalStyle[k]=this.element.style[k];
-},this),["top","left","width","height","fontSize"]);
-this.originalTop=this.element.offsetTop;
-this.originalLeft=this.element.offsetLeft;
-var _5bd=MochiKit.Style.getStyle(this.element,"font-size")||"100%";
-ma(b(function(_5be){
-if(_5bd.indexOf(_5be)>0){
-this.fontSize=parseFloat(_5bd);
-this.fontSizeType=_5be;
-}
-},this),["em","px","%"]);
-this.factor=(this.options.scaleTo-this.options.scaleFrom)/100;
-if(/^content/.test(this.options.scaleMode)){
-this.dims=[this.element.scrollHeight,this.element.scrollWidth];
-}else{
-if(this.options.scaleMode=="box"){
-this.dims=[this.element.offsetHeight,this.element.offsetWidth];
-}else{
-this.dims=[this.options.scaleMode.originalHeight,this.options.scaleMode.originalWidth];
-}
-}
-},update:function(_5bf){
-var _5c0=(this.options.scaleFrom/100)+(this.factor*_5bf);
-if(this.options.scaleContent&&this.fontSize){
-MochiKit.Style.setStyle(this.element,{fontSize:this.fontSize*_5c0+this.fontSizeType});
-}
-this.setDimensions(this.dims[0]*_5c0,this.dims[1]*_5c0);
-},finish:function(){
-if(this.restoreAfterFinish){
-MochiKit.Style.setStyle(this.element,this.originalStyle);
-}
-},setDimensions:function(_5c1,_5c2){
-var d={};
-var r=Math.round;
-if(/MSIE/.test(navigator.userAgent)){
-r=Math.ceil;
-}
-if(this.options.scaleX){
-d.width=r(_5c2)+"px";
-}
-if(this.options.scaleY){
-d.height=r(_5c1)+"px";
-}
-if(this.options.scaleFromCenter){
-var topd=(_5c1-this.dims[0])/2;
-var _5c6=(_5c2-this.dims[1])/2;
-if(this.elementPositioning=="absolute"){
-if(this.options.scaleY){
-d.top=this.originalTop-topd+"px";
-}
-if(this.options.scaleX){
-d.left=this.originalLeft-_5c6+"px";
-}
-}else{
-if(this.options.scaleY){
-d.top=-topd+"px";
-}
-if(this.options.scaleX){
-d.left=-_5c6+"px";
-}
-}
-}
-MochiKit.Style.setStyle(this.element,d);
-}});
-MochiKit.Visual.Highlight=function(_5c7,_5c8){
-this.__init__(_5c7,_5c8);
-};
-MochiKit.Visual.Highlight.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.Highlight.prototype,{__init__:function(_5c9,_5ca){
-this.element=MochiKit.DOM.getElement(_5c9);
-_5ca=MochiKit.Base.update({startcolor:"#ffff99"},_5ca||{});
-this.start(_5ca);
-},setup:function(){
-var b=MochiKit.Base;
-var s=MochiKit.Style;
-if(s.getStyle(this.element,"display")=="none"){
-this.cancel();
-return;
-}
-this.oldStyle={backgroundImage:s.getStyle(this.element,"background-image")};
-s.setStyle(this.element,{backgroundImage:"none"});
-if(!this.options.endcolor){
-this.options.endcolor=MochiKit.Color.Color.fromBackground(this.element).toHexString();
-}
-if(b.isUndefinedOrNull(this.options.restorecolor)){
-this.options.restorecolor=s.getStyle(this.element,"background-color");
-}
-this._base=b.map(b.bind(function(i){
-return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16);
-},this),[0,1,2]);
-this._delta=b.map(b.bind(function(i){
-return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i];
-},this),[0,1,2]);
-},update:function(_5cf){
-var m="#";
-MochiKit.Base.map(MochiKit.Base.bind(function(i){
-m+=MochiKit.Color.toColorPart(Math.round(this._base[i]+this._delta[i]*_5cf));
-},this),[0,1,2]);
-MochiKit.Style.setStyle(this.element,{backgroundColor:m});
-},finish:function(){
-MochiKit.Style.setStyle(this.element,MochiKit.Base.update(this.oldStyle,{backgroundColor:this.options.restorecolor}));
-}});
-MochiKit.Visual.ScrollTo=function(_5d2,_5d3){
-this.__init__(_5d2,_5d3);
-};
-MochiKit.Visual.ScrollTo.prototype=new MochiKit.Visual.Base();
-MochiKit.Base.update(MochiKit.Visual.ScrollTo.prototype,{__init__:function(_5d4,_5d5){
-this.element=MochiKit.DOM.getElement(_5d4);
-this.start(_5d5||{});
-},setup:function(){
-var p=MochiKit.Position;
-p.prepare();
-var _5d7=p.cumulativeOffset(this.element);
-if(this.options.offset){
-_5d7.y+=this.options.offset;
-}
-var max;
-if(window.innerHeight){
-max=window.innerHeight-window.height;
-}else{
-if(document.documentElement&&document.documentElement.clientHeight){
-max=document.documentElement.clientHeight-document.body.scrollHeight;
-}else{
-if(document.body){
-max=document.body.clientHeight-document.body.scrollHeight;
-}
-}
-}
-this.scrollStart=p.windowOffset.y;
-this.delta=(_5d7.y>max?max:_5d7.y)-this.scrollStart;
-},update:function(_5d9){
-var p=MochiKit.Position;
-p.prepare();
-window.scrollTo(p.windowOffset.x,this.scrollStart+(_5d9*this.delta));
-}});
-MochiKit.Visual.fade=function(_5db,_5dc){
-var s=MochiKit.Style;
-var _5de=MochiKit.DOM.getElement(_5db).style.opacity||"";
-_5dc=MochiKit.Base.update({from:s.getOpacity(_5db)||1,to:0,afterFinishInternal:function(_5df){
-if(_5df.options.to!==0){
-return;
-}
-s.hideElement(_5df.element);
-s.setStyle(_5df.element,{opacity:_5de});
-}},_5dc||{});
-return new MochiKit.Visual.Opacity(_5db,_5dc);
-};
-MochiKit.Visual.appear=function(_5e0,_5e1){
-var s=MochiKit.Style;
-var v=MochiKit.Visual;
-_5e1=MochiKit.Base.update({from:(s.getStyle(_5e0,"display")=="none"?0:s.getOpacity(_5e0)||0),to:1,afterFinishInternal:function(_5e4){
-v.forceRerendering(_5e4.element);
-},beforeSetupInternal:function(_5e5){
-s.setOpacity(_5e5.element,_5e5.options.from);
-s.showElement(_5e5.element);
-}},_5e1||{});
-return new v.Opacity(_5e0,_5e1);
-};
-MochiKit.Visual.puff=function(_5e6,_5e7){
-var s=MochiKit.Style;
-var v=MochiKit.Visual;
-_5e6=MochiKit.DOM.getElement(_5e6);
-var _5ea={opacity:_5e6.style.opacity||"",position:s.getStyle(_5e6,"position"),top:_5e6.style.top,left:_5e6.style.left,width:_5e6.style.width,height:_5e6.style.height};
-_5e7=MochiKit.Base.update({beforeSetupInternal:function(_5eb){
-MochiKit.Position.absolutize(_5eb.effects[0].element);
-},afterFinishInternal:function(_5ec){
-s.hideElement(_5ec.effects[0].element);
-s.setStyle(_5ec.effects[0].element,_5ea);
-}},_5e7||{});
-return new v.Parallel([new v.Scale(_5e6,200,{sync:true,scaleFromCenter:true,scaleContent:true,restoreAfterFinish:true}),new v.Opacity(_5e6,{sync:true,to:0})],_5e7);
-};
-MochiKit.Visual.blindUp=function(_5ed,_5ee){
-var d=MochiKit.DOM;
-_5ed=d.getElement(_5ed);
-var _5f0=d.makeClipping(_5ed);
-_5ee=MochiKit.Base.update({scaleContent:false,scaleX:false,restoreAfterFinish:true,afterFinishInternal:function(_5f1){
-MochiKit.Style.hideElement(_5f1.element);
-d.undoClipping(_5f1.element,_5f0);
-}},_5ee||{});
-return new MochiKit.Visual.Scale(_5ed,0,_5ee);
-};
-MochiKit.Visual.blindDown=function(_5f2,_5f3){
-var d=MochiKit.DOM;
-var s=MochiKit.Style;
-_5f2=d.getElement(_5f2);
-var _5f6=s.getElementDimensions(_5f2);
-var _5f7;
-_5f3=MochiKit.Base.update({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:_5f6.h,originalWidth:_5f6.w},restoreAfterFinish:true,afterSetupInternal:function(_5f8){
-_5f7=d.makeClipping(_5f8.element);
-s.setStyle(_5f8.element,{height:"0px"});
-s.showElement(_5f8.element);
-},afterFinishInternal:function(_5f9){
-d.undoClipping(_5f9.element,_5f7);
-}},_5f3||{});
-return new MochiKit.Visual.Scale(_5f2,100,_5f3);
-};
-MochiKit.Visual.switchOff=function(_5fa,_5fb){
-var d=MochiKit.DOM;
-_5fa=d.getElement(_5fa);
-var _5fd=_5fa.style.opacity||"";
-var _5fe;
-var _5fb=MochiKit.Base.update({duration:0.3,scaleFromCenter:true,scaleX:false,scaleContent:false,restoreAfterFinish:true,beforeSetupInternal:function(_5ff){
-d.makePositioned(_5ff.element);
-_5fe=d.makeClipping(_5ff.element);
-},afterFinishInternal:function(_600){
-MochiKit.Style.hideElement(_600.element);
-d.undoClipping(_600.element,_5fe);
-d.undoPositioned(_600.element);
-MochiKit.Style.setStyle(_600.element,{opacity:_5fd});
-}},_5fb||{});
-var v=MochiKit.Visual;
-return new v.appear(_5fa,{duration:0.4,from:0,transition:v.Transitions.flicker,afterFinishInternal:function(_602){
-new v.Scale(_602.element,1,_5fb);
-}});
-};
-MochiKit.Visual.dropOut=function(_603,_604){
-var d=MochiKit.DOM;
-var s=MochiKit.Style;
-_603=d.getElement(_603);
-var _607={top:s.getStyle(_603,"top"),left:s.getStyle(_603,"left"),opacity:_603.style.opacity||""};
-_604=MochiKit.Base.update({duration:0.5,beforeSetupInternal:function(_608){
-d.makePositioned(_608.effects[0].element);
-},afterFinishInternal:function(_609){
-s.hideElement(_609.effects[0].element);
-d.undoPositioned(_609.effects[0].element);
-s.setStyle(_609.effects[0].element,_607);
-}},_604||{});
-var v=MochiKit.Visual;
-return new v.Parallel([new v.Move(_603,{x:0,y:100,sync:true}),new v.Opacity(_603,{sync:true,to:0})],_604);
-};
-MochiKit.Visual.shake=function(_60b,_60c){
-var d=MochiKit.DOM;
-var v=MochiKit.Visual;
-var s=MochiKit.Style;
-_60b=d.getElement(_60b);
-_60c=MochiKit.Base.update({x:-20,y:0,duration:0.05,afterFinishInternal:function(_610){
-d.undoPositioned(_610.element);
-s.setStyle(_610.element,_611);
-}},_60c||{});
-var _611={top:s.getStyle(_60b,"top"),left:s.getStyle(_60b,"left")};
-return new v.Move(_60b,{x:20,y:0,duration:0.05,afterFinishInternal:function(_612){
-new v.Move(_612.element,{x:-40,y:0,duration:0.1,afterFinishInternal:function(_613){
-new v.Move(_613.element,{x:40,y:0,duration:0.1,afterFinishInternal:function(_614){
-new v.Move(_614.element,{x:-40,y:0,duration:0.1,afterFinishInternal:function(_615){
-new v.Move(_615.element,{x:40,y:0,duration:0.1,afterFinishInternal:function(_616){
-new v.Move(_616.element,_60c);
-}});
-}});
-}});
-}});
-}});
-};
-MochiKit.Visual.slideDown=function(_617,_618){
-var d=MochiKit.DOM;
-var b=MochiKit.Base;
-var s=MochiKit.Style;
-_617=d.getElement(_617);
-if(!_617.firstChild){
-throw "MochiKit.Visual.slideDown must be used on a element with a child";
-}
-d.removeEmptyTextNodes(_617);
-var _61c=s.getStyle(_617.firstChild,"bottom")||0;
-var _61d=s.getElementDimensions(_617);
-var _61e;
-_618=b.update({scaleContent:false,scaleX:false,scaleFrom:0,scaleMode:{originalHeight:_61d.h,originalWidth:_61d.w},restoreAfterFinish:true,afterSetupInternal:function(_61f){
-d.makePositioned(_61f.element);
-d.makePositioned(_61f.element.firstChild);
-if(/Opera/.test(navigator.userAgent)){
-s.setStyle(_61f.element,{top:""});
-}
-_61e=d.makeClipping(_61f.element);
-s.setStyle(_61f.element,{height:"0px"});
-s.showElement(_61f.element);
-},afterUpdateInternal:function(_620){
-s.setStyle(_620.element.firstChild,{bottom:(_620.dims[0]-_620.element.clientHeight)+"px"});
-},afterFinishInternal:function(_621){
-d.undoClipping(_621.element,_61e);
-if(/MSIE/.test(navigator.userAgent)){
-d.undoPositioned(_621.element);
-d.undoPositioned(_621.element.firstChild);
-}else{
-d.undoPositioned(_621.element.firstChild);
-d.undoPositioned(_621.element);
-}
-s.setStyle(_621.element.firstChild,{bottom:_61c});
-}},_618||{});
-return new MochiKit.Visual.Scale(_617,100,_618);
-};
-MochiKit.Visual.slideUp=function(_622,_623){
-var d=MochiKit.DOM;
-var b=MochiKit.Base;
-var s=MochiKit.Style;
-_622=d.getElement(_622);
-if(!_622.firstChild){
-throw "MochiKit.Visual.slideUp must be used on a element with a child";
-}
-d.removeEmptyTextNodes(_622);
-var _627=s.getStyle(_622.firstChild,"bottom");
-var _628;
-_623=b.update({scaleContent:false,scaleX:false,scaleMode:"box",scaleFrom:100,restoreAfterFinish:true,beforeStartInternal:function(_629){
-d.makePositioned(_629.element);
-d.makePositioned(_629.element.firstChild);
-if(/Opera/.test(navigator.userAgent)){
-s.setStyle(_629.element,{top:""});
-}
-_628=d.makeClipping(_629.element);
-s.showElement(_629.element);
-},afterUpdateInternal:function(_62a){
-s.setStyle(_62a.element.firstChild,{bottom:(_62a.dims[0]-_62a.element.clientHeight)+"px"});
-},afterFinishInternal:function(_62b){
-s.hideElement(_62b.element);
-d.undoClipping(_62b.element,_628);
-d.undoPositioned(_62b.element.firstChild);
-d.undoPositioned(_62b.element);
-s.setStyle(_62b.element.firstChild,{bottom:_627});
-}},_623||{});
-return new MochiKit.Visual.Scale(_622,0,_623);
-};
-MochiKit.Visual.squish=function(_62c,_62d){
-var d=MochiKit.DOM;
-var b=MochiKit.Base;
-var _630;
-_62d=b.update({restoreAfterFinish:true,beforeSetupInternal:function(_631){
-_630=d.makeClipping(_631.element);
-},afterFinishInternal:function(_632){
-MochiKit.Style.hideElement(_632.element);
-d.undoClipping(_632.element,_630);
-}},_62d||{});
-return new MochiKit.Visual.Scale(_62c,/Opera/.test(navigator.userAgent)?1:0,_62d);
-};
-MochiKit.Visual.grow=function(_633,_634){
-var d=MochiKit.DOM;
-var v=MochiKit.Visual;
-var s=MochiKit.Style;
-_633=d.getElement(_633);
-_634=MochiKit.Base.update({direction:"center",moveTransition:v.Transitions.sinoidal,scaleTransition:v.Transitions.sinoidal,opacityTransition:v.Transitions.full},_634||{});
-var _638={top:_633.style.top,left:_633.style.left,height:_633.style.height,width:_633.style.width,opacity:_633.style.opacity||""};
-var dims=s.getElementDimensions(_633);
-var _63a,_63b;
-var _63c,_63d;
-switch(_634.direction){
-case "top-left":
-_63a=_63b=_63c=_63d=0;
-break;
-case "top-right":
-_63a=dims.w;
-_63b=_63d=0;
-_63c=-dims.w;
-break;
-case "bottom-left":
-_63a=_63c=0;
-_63b=dims.h;
-_63d=-dims.h;
-break;
-case "bottom-right":
-_63a=dims.w;
-_63b=dims.h;
-_63c=-dims.w;
-_63d=-dims.h;
-break;
-case "center":
-_63a=dims.w/2;
-_63b=dims.h/2;
-_63c=-dims.w/2;
-_63d=-dims.h/2;
-break;
-}
-var _63e=MochiKit.Base.update({beforeSetupInternal:function(_63f){
-s.setStyle(_63f.effects[0].element,{height:"0px"});
-s.showElement(_63f.effects[0].element);
-},afterFinishInternal:function(_640){
-d.undoClipping(_640.effects[0].element);
-d.undoPositioned(_640.effects[0].element);
-s.setStyle(_640.effects[0].element,_638);
-}},_634||{});
-return new v.Move(_633,{x:_63a,y:_63b,duration:0.01,beforeSetupInternal:function(_641){
-s.hideElement(_641.element);
-d.makeClipping(_641.element);
-d.makePositioned(_641.element);
-},afterFinishInternal:function(_642){
-new v.Parallel([new v.Opacity(_642.element,{sync:true,to:1,from:0,transition:_634.opacityTransition}),new v.Move(_642.element,{x:_63c,y:_63d,sync:true,transition:_634.moveTransition}),new v.Scale(_642.element,100,{scaleMode:{originalHeight:dims.h,originalWidth:dims.w},sync:true,scaleFrom:/Opera/.test(navigator.userAgent)?1:0,transition:_634.scaleTransition,restoreAfterFinish:true})],_63e);
-}});
-};
-MochiKit.Visual.shrink=function(_643,_644){
-var d=MochiKit.DOM;
-var v=MochiKit.Visual;
-var s=MochiKit.Style;
-_643=d.getElement(_643);
-_644=MochiKit.Base.update({direction:"center",moveTransition:v.Transitions.sinoidal,scaleTransition:v.Transitions.sinoidal,opacityTransition:v.Transitions.none},_644||{});
-var _648={top:_643.style.top,left:_643.style.left,height:_643.style.height,width:_643.style.width,opacity:_643.style.opacity||""};
-var dims=s.getElementDimensions(_643);
-var _64a,_64b;
-switch(_644.direction){
-case "top-left":
-_64a=_64b=0;
-break;
-case "top-right":
-_64a=dims.w;
-_64b=0;
-break;
-case "bottom-left":
-_64a=0;
-_64b=dims.h;
-break;
-case "bottom-right":
-_64a=dims.w;
-_64b=dims.h;
-break;
-case "center":
-_64a=dims.w/2;
-_64b=dims.h/2;
-break;
-}
-var _64c;
-var _64d=MochiKit.Base.update({beforeStartInternal:function(_64e){
-_64c=d.makePositioned(_64e.effects[0].element);
-d.makeClipping(_64e.effects[0].element);
-},afterFinishInternal:function(_64f){
-s.hideElement(_64f.effects[0].element);
-d.undoClipping(_64f.effects[0].element,_64c);
-d.undoPositioned(_64f.effects[0].element);
-s.setStyle(_64f.effects[0].element,_648);
-}},_644||{});
-return new v.Parallel([new v.Opacity(_643,{sync:true,to:0,from:1,transition:_644.opacityTransition}),new v.Scale(_643,/Opera/.test(navigator.userAgent)?1:0,{sync:true,transition:_644.scaleTransition,restoreAfterFinish:true}),new v.Move(_643,{x:_64a,y:_64b,sync:true,transition:_644.moveTransition})],_64d);
-};
-MochiKit.Visual.pulsate=function(_650,_651){
-var d=MochiKit.DOM;
-var v=MochiKit.Visual;
-var b=MochiKit.Base;
-var _655=d.getElement(_650).style.opacity||"";
-_651=b.update({duration:3,from:0,afterFinishInternal:function(_656){
-MochiKit.Style.setStyle(_656.element,{opacity:_655});
-}},_651||{});
-var _657=_651.transition||v.Transitions.sinoidal;
-var _658=b.bind(function(pos){
-return _657(1-v.Transitions.pulse(pos));
-},_657);
-b.bind(_658,_657);
-return new v.Opacity(_650,b.update({transition:_658},_651));
-};
-MochiKit.Visual.fold=function(_65a,_65b){
-var d=MochiKit.DOM;
-var v=MochiKit.Visual;
-var s=MochiKit.Style;
-_65a=d.getElement(_65a);
-var _65f={top:_65a.style.top,left:_65a.style.left,width:_65a.style.width,height:_65a.style.height};
-var _660=d.makeClipping(_65a);
-_65b=MochiKit.Base.update({scaleContent:false,scaleX:false,afterFinishInternal:function(_661){
-new v.Scale(_65a,1,{scaleContent:false,scaleY:false,afterFinishInternal:function(_662){
-s.hideElement(_662.element);
-d.undoClipping(_662.element,_660);
-s.setStyle(_662.element,_65f);
-}});
-}},_65b||{});
-return new v.Scale(_65a,5,_65b);
-};
-MochiKit.Visual.Color=MochiKit.Color.Color;
-MochiKit.Visual.getElementsComputedStyle=MochiKit.DOM.computedStyle;
-MochiKit.Visual.__new__=function(){
-var m=MochiKit.Base;
-m.nameFunctions(this);
-this.EXPORT_TAGS={":common":this.EXPORT,":all":m.concat(this.EXPORT,this.EXPORT_OK)};
-};
-MochiKit.Visual.EXPORT=["roundElement","roundClass","tagifyText","multiple","toggle","Base","Parallel","Opacity","Move","Scale","Highlight","ScrollTo","fade","appear","puff","blindUp","blindDown","switchOff","dropOut","shake","slideDown","slideUp","squish","grow","shrink","pulsate","fold"];
-MochiKit.Visual.EXPORT_OK=["PAIRS"];
-MochiKit.Visual.__new__();
-MochiKit.Base._exportSymbols(this,MochiKit.Visual);
-if(typeof (MochiKit)=="undefined"){
-MochiKit={};
-}
-if(typeof (MochiKit.MochiKit)=="undefined"){
-MochiKit.MochiKit={};
-}
-MochiKit.MochiKit.NAME="MochiKit.MochiKit";
-MochiKit.MochiKit.VERSION="1.4";
-MochiKit.MochiKit.__repr__=function(){
-return "["+this.NAME+" "+this.VERSION+"]";
-};
-MochiKit.MochiKit.toString=function(){
-return this.__repr__();
-};
-MochiKit.MochiKit.SUBMODULES=["Base","Iter","Logging","DateTime","Format","Async","DOM","Style","LoggingPane","Color","Signal","Visual"];
-if(typeof (JSAN)!="undefined"||typeof (dojo)!="undefined"){
-if(typeof (dojo)!="undefined"){
-dojo.provide("MochiKit.MochiKit");
-dojo.require("MochiKit.*");
-}
-if(typeof (JSAN)!="undefined"){
-(function(lst){
-for(var i=0;i<lst.length;i++){
-JSAN.use("MochiKit."+lst[i],[]);
-}
-})(MochiKit.MochiKit.SUBMODULES);
-}
-(function(){
-var _666=MochiKit.Base.extend;
-var self=MochiKit.MochiKit;
-var _668=self.SUBMODULES;
-var _669=[];
-var _66a=[];
-var _66b={};
-var i,k,m,all;
-for(i=0;i<_668.length;i++){
-m=MochiKit[_668[i]];
-_666(_669,m.EXPORT);
-_666(_66a,m.EXPORT_OK);
-for(k in m.EXPORT_TAGS){
-_66b[k]=_666(_66b[k],m.EXPORT_TAGS[k]);
-}
-all=m.EXPORT_TAGS[":all"];
-if(!all){
-all=_666(null,m.EXPORT,m.EXPORT_OK);
-}
-var j;
-for(j=0;j<all.length;j++){
-k=all[j];
-self[k]=m[k];
-}
-}
-self.EXPORT=_669;
-self.EXPORT_OK=_66a;
-self.EXPORT_TAGS=_66b;
-}());
-}else{
-if(typeof (MochiKit.__compat__)=="undefined"){
-MochiKit.__compat__=true;
-}
-(function(){
-if(typeof (document)=="undefined"){
-return;
-}
-var _671=document.getElementsByTagName("script");
-var _672="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
-var base=null;
-var _674=null;
-var _675={};
-var i;
-for(i=0;i<_671.length;i++){
-var src=_671[i].getAttribute("src");
-if(!src){
-continue;
-}
-_675[src]=true;
-if(src.match(/MochiKit.js$/)){
-base=src.substring(0,src.lastIndexOf("MochiKit.js"));
-_674=_671[i];
-}
-}
-if(base===null){
-return;
-}
-var _678=MochiKit.MochiKit.SUBMODULES;
-for(var i=0;i<_678.length;i++){
-if(MochiKit[_678[i]]){
-continue;
-}
-var uri=base+_678[i]+".js";
-if(uri in _675){
-continue;
-}
-if(document.documentElement&&document.documentElement.namespaceURI==_672){
-var s=document.createElementNS(_672,"script");
-s.setAttribute("id","MochiKit_"+base+_678[i]);
-s.setAttribute("src",uri);
-s.setAttribute("type","application/x-javascript");
-_674.parentNode.appendChild(s);
-}else{
-document.write("<script src=\""+uri+"\" type=\"text/javascript\"></script>");
-}
-}
-})();
-}
-
-
diff --git a/mochitest/harness-abp.xul b/mochitest/harness-abp.xul
deleted file mode 100644
index 641929e..0000000
--- a/mochitest/harness-abp.xul
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet href="chrome://mochikit/content/static/harness.css"
- type="text/css"?>
-
-<?xul-overlay href="chrome://mochikit/content/harness-overlay.xul"?>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- title="Adblock Plus Test Harness"
- directory="tests">
-</window>
diff --git a/mochitest/harness-overlay.xul b/mochitest/harness-overlay.xul
deleted file mode 100644
index 70846c1..0000000
--- a/mochitest/harness-overlay.xul
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-
-<overlay id="browserTestOverlay"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-<window>
- <script type="application/javascript"
- src="chrome://mochikit/content/MochiKit/packed.js" />
- <script type="text/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/TestRunner.js"/>
- <script type="text/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/MozillaFileLogger.js"/>
- <script type="text/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/quit.js" />
- <script type="text/javascript"
- src="chrome://mochikit/content/tests/SimpleTest/setup.js" />
- <script type="application/javascript;version=1.7"><![CDATA[
- function loadTests()
- {
- var dir = document.documentElement.getAttribute('directory');
- // Find our chrome dir
- var ios = Cc["@mozilla.org/network/io-service;1"].
- getService(Ci.nsIIOService);
- var chromeURI = ios.newURI("chrome://mochikit/content/",
- null, null);
- var resolvedURI = Cc["@mozilla.org/chrome/chrome-registry;1"].
- getService(Ci.nsIChromeRegistry).
- convertChromeURL(chromeURI);
- var fileHandler = Cc["@mozilla.org/network/protocol;1?name=file"].
- getService(Ci.nsIFileProtocolHandler);
- var chromeDir = fileHandler.getFileFromURLSpec(resolvedURI.spec);
- chromeDir = chromeDir.parent.QueryInterface(Ci.nsILocalFile);
- chromeDir.appendRelativePath(dir);
-
- // load server.js in so we can share template functions
- var scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
- getService(Ci.mozIJSSubScriptLoader);
- var srvScope = {};
- scriptLoader.loadSubScript("chrome://mochikit/content/server.js",
- srvScope);
-
- // generate our test list
- srvScope.makeTags();
- var url = "chrome://mochikit/content/" + dir + "/";
- var [links, count] = srvScope.list(url, chromeDir, true);
- var listContent = srvScope.linksToListItems(links);
- var tableContent = srvScope.linksToTableRows(links);
- function populate() {
- $("list-holder").setAttribute("rowspan", 1 + count);
- $("test-list").innerHTML += listContent;
- $("test-table").innerHTML += tableContent;
- $("wrapper").innerHTML += " "; // redraw the table
- }
- gTestList = eval(srvScope.jsonArrayOfTestFiles(links));
- populate();
- hookup();
-
- // if we got passed a test path, just run that single test
- if ("testPath" in params && params.testPath)
- window.location.href = url + params.testPath;
- }
- window.addEventListener("load", loadTests, false)
- ]]>
- </script>
-
- <vbox>
- <button label="Run Chrome Tests" id="runtests" flex="1"/>
-
- <body xmlns="http://www.w3.org/1999/xhtml" id="xulharness">
- <div class="container">
- <p style="float:right;">
- <small>Based on the MochiKit unit tests.</small>
- </p>
- <div class="status">
- <h1 id="indicator">Status</h1>
- <h2 id="pass">Passed: <span id="pass-count">0</span></h2>
- <h2 id="fail">Failed: <span id="fail-count">0</span></h2>
- <h2 id="fail">Todo: <span id="todo-count">0</span></h2>
- </div>
- <div class="clear"></div>
- <div id="current-test">
- <b>Currently Executing: <span id="current-test-path">_</span></b>
- </div>
- <div class="clear"></div>
- <div class="frameholder">
- <iframe scrolling="no" id="testframe" width="500"></iframe>
- </div>
- <div class="clear"></div>
- <div class="toggle">
- <a href="#" id="toggleNonTests">Show Non-Tests</a>
- <br />
- </div>
- <div id="wrapper">
- <table cellpadding="0" cellspacing="0" id="test-table">
- <tr>
- <td>Passed</td>
- <td>Failed</td>
- <td>Todo</td>
- <td id="list-holder">
- <ul class="top" id="test-list"><li><b>Test Files</b></li></ul>
- </td>
- </tr>
- </table>
- </div>
- </div>
- </body>
- </vbox>
-</window>
-
-</overlay>
diff --git a/mochitest/httpd.js b/mochitest/httpd.js
deleted file mode 100644
index dbd0ea4..0000000
--- a/mochitest/httpd.js
+++ /dev/null
@@ -1,4141 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is the httpd.js server.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Darin Fisher (v1, netwerk/test/TestServ.js)
- * Christian Biesinger (v2, netwerk/test/unit/head_http_server.js)
- * Jeff Walden <jwalden+code at mit.edu> (v3, netwerk/test/httpserver/httpd.js)
- * Robert Sayre <sayrer at gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- * An implementation of an HTTP server both as a loadable script and as an XPCOM
- * component. See the accompanying README file for user documentation on
- * httpd.js.
- */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-const CC = Components.Constructor;
-
-const PR_UINT32_MAX = Math.pow(2, 32) - 1;
-
-/** True if debugging output is enabled, false otherwise. */
-var DEBUG = false; // non-const *only* so tweakable in server tests
-
-var gGlobalObject = this;
-
-/**
- * Asserts that the given condition holds. If it doesn't, the given message is
- * dumped, a stack trace is printed, and an exception is thrown to attempt to
- * stop execution (which unfortunately must rely upon the exception not being
- * accidentally swallowed by the code that uses it).
- */
-function NS_ASSERT(cond, msg)
-{
- if (DEBUG && !cond)
- {
- dumpn("###!!!");
- dumpn("###!!! ASSERTION" + (msg ? ": " + msg : "!"));
- dumpn("###!!! Stack follows:");
-
- var stack = new Error().stack.split(/\n/);
- dumpn(stack.map(function(val) { return "###!!! " + val; }).join("\n"));
-
- throw Cr.NS_ERROR_ABORT;
- }
-}
-
-/** Constructs an HTTP error object. */
-function HttpError(code, description)
-{
- this.code = code;
- this.description = description;
-}
-HttpError.prototype =
-{
- toString: function()
- {
- return this.code + " " + this.description;
- }
-};
-
-/**
- * Errors thrown to trigger specific HTTP server responses.
- */
-const HTTP_400 = new HttpError(400, "Bad Request");
-const HTTP_401 = new HttpError(401, "Unauthorized");
-const HTTP_402 = new HttpError(402, "Payment Required");
-const HTTP_403 = new HttpError(403, "Forbidden");
-const HTTP_404 = new HttpError(404, "Not Found");
-const HTTP_405 = new HttpError(405, "Method Not Allowed");
-const HTTP_406 = new HttpError(406, "Not Acceptable");
-const HTTP_407 = new HttpError(407, "Proxy Authentication Required");
-const HTTP_408 = new HttpError(408, "Request Timeout");
-const HTTP_409 = new HttpError(409, "Conflict");
-const HTTP_410 = new HttpError(410, "Gone");
-const HTTP_411 = new HttpError(411, "Length Required");
-const HTTP_412 = new HttpError(412, "Precondition Failed");
-const HTTP_413 = new HttpError(413, "Request Entity Too Large");
-const HTTP_414 = new HttpError(414, "Request-URI Too Long");
-const HTTP_415 = new HttpError(415, "Unsupported Media Type");
-const HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
-const HTTP_417 = new HttpError(417, "Expectation Failed");
-
-const HTTP_500 = new HttpError(500, "Internal Server Error");
-const HTTP_501 = new HttpError(501, "Not Implemented");
-const HTTP_502 = new HttpError(502, "Bad Gateway");
-const HTTP_503 = new HttpError(503, "Service Unavailable");
-const HTTP_504 = new HttpError(504, "Gateway Timeout");
-const HTTP_505 = new HttpError(505, "HTTP Version Not Supported");
-
-/** Creates a hash with fields corresponding to the values in arr. */
-function array2obj(arr)
-{
- var obj = {};
- for (var i = 0; i < arr.length; i++)
- obj[arr[i]] = arr[i];
- return obj;
-}
-
-/** Returns an array of the integers x through y, inclusive. */
-function range(x, y)
-{
- var arr = [];
- for (var i = x; i <= y; i++)
- arr.push(i);
- return arr;
-}
-
-/** An object (hash) whose fields are the numbers of all HTTP error codes. */
-const HTTP_ERROR_CODES = array2obj(range(400, 417).concat(range(500, 505)));
-
-
-/**
- * The character used to distinguish hidden files from non-hidden files, a la
- * the leading dot in Apache. Since that mechanism also hides files from
- * easy display in LXR, ls output, etc. however, we choose instead to use a
- * suffix character. If a requested file ends with it, we append another
- * when getting the file on the server. If it doesn't, we just look up that
- * file. Therefore, any file whose name ends with exactly one of the character
- * is "hidden" and available for use by the server.
- */
-const HIDDEN_CHAR = "^";
-
-/**
- * The file name suffix indicating the file containing overridden headers for
- * a requested file.
- */
-const HEADERS_SUFFIX = HIDDEN_CHAR + "headers" + HIDDEN_CHAR;
-
-/** Type used to denote SJS scripts for CGI-like functionality. */
-const SJS_TYPE = "sjs";
-
-
-/** dump(str) with a trailing "\n" -- only outputs if DEBUG */
-function dumpn(str)
-{
- if (DEBUG)
- dump(str + "\n");
-}
-
-/** Dumps the current JS stack if DEBUG. */
-function dumpStack()
-{
- // peel off the frames for dumpStack() and Error()
- var stack = new Error().stack.split(/\n/).slice(2);
- stack.forEach(dumpn);
-}
-
-
-/** The XPCOM thread manager. */
-var gThreadManager = null;
-
-
-/**
- * JavaScript constructors for commonly-used classes; precreating these is a
- * speedup over doing the same from base principles. See the docs at
- * http://developer.mozilla.org/en/docs/Components.Constructor for details.
- */
-const ServerSocket = CC("@mozilla.org/network/server-socket;1",
- "nsIServerSocket",
- "init");
-const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
- "nsIBinaryInputStream",
- "setInputStream");
-const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
- "nsIBinaryOutputStream",
- "setOutputStream");
-const ScriptableInputStream = CC("@mozilla.org/scriptableinputstream;1",
- "nsIScriptableInputStream",
- "init");
-const Pipe = CC("@mozilla.org/pipe;1",
- "nsIPipe",
- "init");
-const FileInputStream = CC("@mozilla.org/network/file-input-stream;1",
- "nsIFileInputStream",
- "init");
-const StreamCopier = CC("@mozilla.org/network/async-stream-copier;1",
- "nsIAsyncStreamCopier",
- "init");
-const ConverterInputStream = CC("@mozilla.org/intl/converter-input-stream;1",
- "nsIConverterInputStream",
- "init");
-const WritablePropertyBag = CC("@mozilla.org/hash-property-bag;1",
- "nsIWritablePropertyBag2");
-const SupportsString = CC("@mozilla.org/supports-string;1",
- "nsISupportsString");
-
-
-/**
- * Returns the RFC 822/1123 representation of a date.
- *
- * @param date : Number
- * the date, in milliseconds from midnight (00:00:00), January 1, 1970 GMT
- * @returns string
- * the representation of the given date
- */
-function toDateString(date)
-{
- //
- // rfc1123-date = wkday "," SP date1 SP time SP "GMT"
- // date1 = 2DIGIT SP month SP 4DIGIT
- // ; day month year (e.g., 02 Jun 1982)
- // time = 2DIGIT ":" 2DIGIT ":" 2DIGIT
- // ; 00:00:00 - 23:59:59
- // wkday = "Mon" | "Tue" | "Wed"
- // | "Thu" | "Fri" | "Sat" | "Sun"
- // month = "Jan" | "Feb" | "Mar" | "Apr"
- // | "May" | "Jun" | "Jul" | "Aug"
- // | "Sep" | "Oct" | "Nov" | "Dec"
- //
-
- const wkdayStrings = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
- const monthStrings = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
-
- /**
- * Processes a date and returns the encoded UTC time as a string according to
- * the format specified in RFC 2616.
- *
- * @param date : Date
- * the date to process
- * @returns string
- * a string of the form "HH:MM:SS", ranging from "00:00:00" to "23:59:59"
- */
- function toTime(date)
- {
- var hrs = date.getUTCHours();
- var rv = (hrs < 10) ? "0" + hrs : hrs;
-
- var mins = date.getUTCMinutes();
- rv += ":";
- rv += (mins < 10) ? "0" + mins : mins;
-
- var secs = date.getUTCSeconds();
- rv += ":";
- rv += (secs < 10) ? "0" + secs : secs;
-
- return rv;
- }
-
- /**
- * Processes a date and returns the encoded UTC date as a string according to
- * the date1 format specified in RFC 2616.
- *
- * @param date : Date
- * the date to process
- * @returns string
- * a string of the form "HH:MM:SS", ranging from "00:00:00" to "23:59:59"
- */
- function toDate1(date)
- {
- var day = date.getUTCDate();
- var month = date.getUTCMonth();
- var year = date.getUTCFullYear();
-
- var rv = (day < 10) ? "0" + day : day;
- rv += " " + monthStrings[month];
- rv += " " + year;
-
- return rv;
- }
-
- date = new Date(date);
-
- const fmtString = "%wkday%, %date1% %time% GMT";
- var rv = fmtString.replace("%wkday%", wkdayStrings[date.getUTCDay()]);
- rv = rv.replace("%time%", toTime(date));
- return rv.replace("%date1%", toDate1(date));
-}
-
-/**
- * Prints out a human-readable representation of the object o and its fields,
- * omitting those whose names begin with "_" if showMembers != true (to ignore
- * "private" properties exposed via getters/setters).
- */
-function printObj(o, showMembers)
-{
- var s = "******************************\n";
- s += "o = {\n";
- for (var i in o)
- {
- if (typeof(i) != "string" ||
- (showMembers || (i.length > 0 && i[0] != "_")))
- s+= " " + i + ": " + o[i] + ",\n";
- }
- s += " };\n";
- s += "******************************";
- dumpn(s);
-}
-
-/**
- * Instantiates a new HTTP server.
- */
-function nsHttpServer()
-{
- if (!gThreadManager)
- gThreadManager = Cc["@mozilla.org/thread-manager;1"].getService();
-
- /** The port on which this server listens. */
- this._port = undefined;
-
- /** The socket associated with this. */
- this._socket = null;
-
- /** The handler used to process requests to this server. */
- this._handler = new ServerHandler(this);
-
- /** Naming information for this server. */
- this._identity = new ServerIdentity();
-
- /**
- * Indicates when the server is to be shut down at the end of the request.
- */
- this._doQuit = false;
-
- /**
- * True if the socket in this is closed (and closure notifications have been
- * sent and processed if the socket was ever opened), false otherwise.
- */
- this._socketClosed = true;
-}
-nsHttpServer.prototype =
-{
- // NSISERVERSOCKETLISTENER
-
- /**
- * Processes an incoming request coming in on the given socket and contained
- * in the given transport.
- *
- * @param socket : nsIServerSocket
- * the socket through which the request was served
- * @param trans : nsISocketTransport
- * the transport for the request/response
- * @see nsIServerSocketListener.onSocketAccepted
- */
- onSocketAccepted: function(socket, trans)
- {
- dumpn("*** onSocketAccepted(socket=" + socket + ", trans=" + trans + ")");
-
- dumpn(">>> new connection on " + trans.host + ":" + trans.port);
-
- const SEGMENT_SIZE = 8192;
- const SEGMENT_COUNT = 1024;
- var input = trans.openInputStream(0, SEGMENT_SIZE, SEGMENT_COUNT)
- .QueryInterface(Ci.nsIAsyncInputStream);
- var output = trans.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
-
- var conn = new Connection(input, output, this, socket.port);
- var reader = new RequestReader(conn);
-
- // XXX add request timeout functionality here!
-
- // Note: must use main thread here, or we might get a GC that will cause
- // threadsafety assertions. We really need to fix XPConnect so that
- // you can actually do things in multi-threaded JS. :-(
- input.asyncWait(reader, 0, 0, gThreadManager.mainThread);
- },
-
- /**
- * Called when the socket associated with this is closed.
- *
- * @param socket : nsIServerSocket
- * the socket being closed
- * @param status : nsresult
- * the reason the socket stopped listening (NS_BINDING_ABORTED if the server
- * was stopped using nsIHttpServer.stop)
- * @see nsIServerSocketListener.onStopListening
- */
- onStopListening: function(socket, status)
- {
- dumpn(">>> shutting down server");
- this._socketClosed = true;
- },
-
- // NSIHTTPSERVER
-
- //
- // see nsIHttpServer.start
- //
- start: function(port)
- {
- if (this._socket)
- throw Cr.NS_ERROR_ALREADY_INITIALIZED;
-
- this._port = port;
- this._doQuit = this._socketClosed = false;
-
- var socket = new ServerSocket(this._port,
- true, // loopback only
- -1); // default number of pending connections
-
- dumpn(">>> listening on port " + socket.port);
- socket.asyncListen(this);
- this._identity._initialize(port, true);
- this._socket = socket;
- },
-
- //
- // see nsIHttpServer.stop
- //
- stop: function()
- {
- if (!this._socket)
- return;
-
- dumpn(">>> stopping listening on port " + this._socket.port);
- this._socket.close();
- this._socket = null;
-
- // We can't have this identity any more, and the port on which we're running
- // this server now could be meaningless the next time around.
- this._identity._teardown();
-
- this._doQuit = false;
-
- // spin an event loop and wait for the socket-close notification
- var thr = gThreadManager.currentThread;
- while (!this._socketClosed || this._handler.hasPendingRequests())
- thr.processNextEvent(true);
- },
-
- //
- // see nsIHttpServer.registerFile
- //
- registerFile: function(path, file)
- {
- if (file && (!file.exists() || file.isDirectory()))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- this._handler.registerFile(path, file);
- },
-
- //
- // see nsIHttpServer.registerDirectory
- //
- registerDirectory: function(path, directory)
- {
- // XXX true path validation!
- if (path.charAt(0) != "/" ||
- path.charAt(path.length - 1) != "/" ||
- (directory &&
- (!directory.exists() || !directory.isDirectory())))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // XXX determine behavior of non-existent /foo/bar when a /foo/bar/ mapping
- // exists!
-
- this._handler.registerDirectory(path, directory);
- },
-
- //
- // see nsIHttpServer.registerPathHandler
- //
- registerPathHandler: function(path, handler)
- {
- this._handler.registerPathHandler(path, handler);
- },
-
- //
- // see nsIHttpServer.registerErrorHandler
- //
- registerErrorHandler: function(code, handler)
- {
- this._handler.registerErrorHandler(code, handler);
- },
-
- //
- // see nsIHttpServer.setIndexHandler
- //
- setIndexHandler: function(handler)
- {
- this._handler.setIndexHandler(handler);
- },
-
- //
- // see nsIHttpServer.registerContentType
- //
- registerContentType: function(ext, type)
- {
- this._handler.registerContentType(ext, type);
- },
-
- //
- // see nsIHttpServer.serverIdentity
- //
- get identity()
- {
- return this._identity;
- },
-
- //
- // see nsIHttpServer.getState
- //
- getState: function(path, k)
- {
- return this._handler._getState(path, k);
- },
-
- //
- // see nsIHttpServer.setState
- //
- setState: function(path, k, v)
- {
- return this._handler._setState(path, k, v);
- },
-
- //
- // see nsIHttpServer.getSharedState
- //
- getSharedState: function(k)
- {
- return this._handler._getSharedState(k);
- },
-
- //
- // see nsIHttpServer.setSharedState
- //
- setSharedState: function(k, v)
- {
- return this._handler._setSharedState(k, v);
- },
-
- // NSISUPPORTS
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(iid)
- {
- if (iid.equals(Ci.nsIHttpServer) ||
- iid.equals(Ci.nsIServerSocketListener) ||
- iid.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // NON-XPCOM PUBLIC API
-
- /**
- * Returns true iff this server is not running (and is not in the process of
- * serving any requests still to be processed when the server was last
- * stopped after being run).
- */
- isStopped: function()
- {
- return this._socketClosed && !this._handler.hasPendingRequests();
- },
-
-
- // PRIVATE IMPLEMENTATION
-
- /**
- * Closes the passed-in connection.
- *
- * @param connection : Connection
- * the connection to close
- */
- _endConnection: function(connection)
- {
- //
- // Order is important below: we must decrement handler._pendingRequests
- // BEFORE calling this.stop(), if needed, in connection.destroy().
- // this.stop() returns only when the server socket's closed AND all pending
- // requests are complete, which clearly isn't (and never will be) the case
- // if it were the other way around.
- //
-
- connection.close();
-
- NS_ASSERT(this == connection.server);
-
- this._handler._pendingRequests--;
-
- connection.destroy();
- },
-
- /**
- * Requests that the server be shut down when possible.
- */
- _requestQuit: function()
- {
- dumpn(">>> requesting a quit");
- dumpStack();
- this._doQuit = true;
- }
-
-};
-
-
-//
-// RFC 2396 section 3.2.2:
-//
-// host = hostname | IPv4address
-// hostname = *( domainlabel "." ) toplabel [ "." ]
-// domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum
-// toplabel = alpha | alpha *( alphanum | "-" ) alphanum
-// IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit
-//
-
-const HOST_REGEX =
- new RegExp("^(?:" +
- // *( domainlabel "." )
- "(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)*" +
- // toplabel
- "[a-z](?:[a-z0-9-]*[a-z0-9])?" +
- "|" +
- // IPv4 address
- "\\d+\\.\\d+\\.\\d+\\.\\d+" +
- ")$",
- "i");
-
-
-/**
- * Represents the identity of a server. An identity consists of a set of
- * (scheme, host, port) tuples denoted as locations (allowing a single server to
- * serve multiple sites or to be used behind both HTTP and HTTPS proxies for any
- * host/port). Any incoming request must be to one of these locations, or it
- * will be rejected with an HTTP 400 error. One location, denoted as the
- * primary location, is the location assigned in contexts where a location
- * cannot otherwise be endogenously derived, such as for HTTP/1.0 requests.
- *
- * A single identity may contain at most one location per unique host/port pair;
- * other than that, no restrictions are placed upon what locations may
- * constitute an identity.
- */
-function ServerIdentity()
-{
- /** The scheme of the primary location. */
- this._primaryScheme = "http";
-
- /** The hostname of the primary location. */
- this._primaryHost = "127.0.0.1"
-
- /** The port number of the primary location. */
- this._primaryPort = -1;
-
- /**
- * The current port number for the corresponding server, stored so that a new
- * primary location can always be set if the current one is removed.
- */
- this._defaultPort = -1;
-
- /**
- * Maps hosts to maps of ports to schemes, e.g. the following would represent
- * https://example.com:789/ and http://example.org/:
- *
- * {
- * "xexample.com": { 789: "https" },
- * "xexample.org": { 80: "http" }
- * }
- *
- * Note the "x" prefix on hostnames, which prevents collisions with special
- * JS names like "prototype".
- */
- this._locations = { "xlocalhost": {} };
-}
-ServerIdentity.prototype =
-{
- /**
- * Initializes the primary name for the corresponding server, based on the
- * provided port number.
- */
- _initialize: function(port, addSecondaryDefault)
- {
- if (this._primaryPort !== -1)
- this.add("http", "localhost", port);
- else
- this.setPrimary("http", "localhost", port);
- this._defaultPort = port;
-
- // Only add this if we're being called at server startup
- if (addSecondaryDefault)
- this.add("http", "127.0.0.1", port);
- },
-
- /**
- * Called at server shutdown time, unsets the primary location only if it was
- * the default-assigned location and removes the default location from the
- * set of locations used.
- */
- _teardown: function()
- {
- // Not the default primary location, nothing special to do here
- this.remove("http", "127.0.0.1", this._defaultPort);
-
- // This is a *very* tricky bit of reasoning here; make absolutely sure the
- // tests for this code pass before you commit changes to it.
- if (this._primaryScheme == "http" &&
- this._primaryHost == "localhost" &&
- this._primaryPort == this._defaultPort)
- {
- // Make sure we don't trigger the readding logic in .remove(), then remove
- // the default location.
- var port = this._defaultPort;
- this._defaultPort = -1;
- this.remove("http", "localhost", port);
-
- // Ensure a server start triggers the setPrimary() path in ._initialize()
- this._primaryPort = -1;
- }
- else
- {
- // No reason not to remove directly as it's not our primary location
- this.remove("http", "localhost", this._defaultPort);
- }
- },
-
- //
- // see nsIHttpServerIdentity.primaryScheme
- //
- get primaryScheme()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryScheme;
- },
-
- //
- // see nsIHttpServerIdentity.primaryHost
- //
- get primaryHost()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryHost;
- },
-
- //
- // see nsIHttpServerIdentity.primaryPort
- //
- get primaryPort()
- {
- if (this._primaryPort === -1)
- throw Cr.NS_ERROR_NOT_INITIALIZED;
- return this._primaryPort;
- },
-
- //
- // see nsIHttpServerIdentity.add
- //
- add: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- this._locations["x" + host] = entry = {};
-
- entry[port] = scheme;
- },
-
- //
- // see nsIHttpServerIdentity.remove
- //
- remove: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- return false;
-
- var present = port in entry;
- delete entry[port];
-
- if (this._primaryScheme == scheme &&
- this._primaryHost == host &&
- this._primaryPort == port &&
- this._defaultPort !== -1)
- {
- // Always keep at least one identity in existence at any time, unless
- // we're in the process of shutting down (the last condition above).
- this._primaryPort = -1;
- this._initialize(this._defaultPort, false);
- }
-
- return present;
- },
-
- //
- // see nsIHttpServerIdentity.has
- //
- has: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- return "x" + host in this._locations &&
- scheme === this._locations["x" + host][port];
- },
-
- //
- // see nsIHttpServerIdentity.has
- //
- getScheme: function(host, port)
- {
- this._validate("http", host, port);
-
- var entry = this._locations["x" + host];
- if (!entry)
- return "";
-
- return entry[port] || "";
- },
-
- //
- // see nsIHttpServerIdentity.setPrimary
- //
- setPrimary: function(scheme, host, port)
- {
- this._validate(scheme, host, port);
-
- this.add(scheme, host, port);
-
- this._primaryScheme = scheme;
- this._primaryHost = host;
- this._primaryPort = port;
- },
-
- /**
- * Ensures scheme, host, and port are all valid with respect to RFC 2396.
- *
- * @throws NS_ERROR_ILLEGAL_VALUE
- * if any argument doesn't match the corresponding production
- */
- _validate: function(scheme, host, port)
- {
- if (scheme !== "http" && scheme !== "https")
- {
- dumpn("*** server only supports http/https schemes: '" + scheme + "'");
- dumpStack();
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- if (!HOST_REGEX.test(host))
- {
- dumpn("*** unexpected host: '" + host + "'");
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- if (port < 0 || port > 65535)
- {
- dumpn("*** unexpected port: '" + port + "'");
- throw Cr.NS_ERROR_ILLEGAL_VALUE;
- }
- }
-};
-
-
-/**
- * Represents a connection to the server (and possibly in the future the thread
- * on which the connection is processed).
- *
- * @param input : nsIInputStream
- * stream from which incoming data on the connection is read
- * @param output : nsIOutputStream
- * stream to write data out the connection
- * @param server : nsHttpServer
- * the server handling the connection
- * @param port : int
- * the port on which the server is running
- */
-function Connection(input, output, server, port)
-{
- /** Stream of incoming data. */
- this.input = input;
-
- /** Stream for outgoing data. */
- this.output = output;
-
- /** The server associated with this request. */
- this.server = server;
-
- /** The port on which the server is running. */
- this.port = port;
-
- /** State variables for debugging. */
- this._closed = this._processed = false;
-}
-Connection.prototype =
-{
- /** Closes this connection's input/output streams. */
- close: function()
- {
- this.input.close();
- this.output.close();
- this._closed = true;
- },
-
- /**
- * Initiates processing of this connection, using the data in the given
- * request.
- *
- * @param request : Request
- * the request which should be processed
- */
- process: function(request)
- {
- NS_ASSERT(!this._closed && !this._processed);
-
- this._processed = true;
-
- this.server._handler.handleResponse(this, request);
- },
-
- /**
- * Initiates processing of this connection, generating a response with the
- * given HTTP error code.
- *
- * @param code : uint
- * an HTTP code, so in the range [0, 1000)
- * @param metadata : Request
- * incomplete data about the incoming request (since there were errors
- * during its processing
- */
- processError: function(code, metadata)
- {
- NS_ASSERT(!this._closed && !this._processed);
-
- this._processed = true;
-
- this.server._handler.handleError(code, this, metadata);
- },
-
- /**
- * Ends this connection, destroying the resources it uses. This function
- * should only be called after a response has been completely constructed,
- * response headers have been sent, and the response body remains to be set,
- * which all happens before ServerHandler._pendingRequests is incremented,
- * because it handles the corresponding decrement of that value.
- */
- end: function()
- {
- this.server._endConnection(this);
- },
-
- /** Destroys resources used by this. */
- destroy: function()
- {
- if (!this._closed)
- this.close();
-
- // If an error triggered a server shutdown, act on it now
- var server = this.server;
- if (server._doQuit)
- server.stop();
- }
-};
-
-
-
-/** Returns an array of count bytes from the given input stream. */
-function readBytes(inputStream, count)
-{
- return new BinaryInputStream(inputStream).readByteArray(count);
-}
-
-
-
-/** Request reader processing states; see RequestReader for details. */
-const READER_IN_REQUEST_LINE = 0;
-const READER_IN_HEADERS = 1;
-const READER_IN_BODY = 2;
-const READER_FINISHED = 3;
-
-
-/**
- * Reads incoming request data asynchronously, does any necessary preprocessing,
- * and forwards it to the request handler. Processing occurs in three states:
- *
- * READER_IN_REQUEST_LINE Reading the request's status line
- * READER_IN_HEADERS Reading headers in the request
- * READER_IN_BODY Reading the body of the request
- * READER_FINISHED Entire request has been read and processed
- *
- * During the first two stages, initial metadata about the request is gathered
- * into a Request object. Once the status line and headers have been processed,
- * we start processing the body of the request into the Request. Finally, when
- * the entire body has been read, we create a Response and hand it off to the
- * ServerHandler to be given to the appropriate request handler.
- *
- * @param connection : Connection
- * the connection for the request being read
- */
-function RequestReader(connection)
-{
- /** Connection metadata for this request. */
- this._connection = connection;
-
- /**
- * A container providing line-by-line access to the raw bytes that make up the
- * data which has been read from the connection but has not yet been acted
- * upon (by passing it to the request handler or by extracting request
- * metadata from it).
- */
- this._data = new LineData();
-
- /**
- * The amount of data remaining to be read from the body of this request.
- * After all headers in the request have been read this is the value in the
- * Content-Length header, but as the body is read its value decreases to zero.
- */
- this._contentLength = 0;
-
- /** The current state of parsing the incoming request. */
- this._state = READER_IN_REQUEST_LINE;
-
- /** Metadata constructed from the incoming request for the request handler. */
- this._metadata = new Request(connection.port);
-
- /**
- * Used to preserve state if we run out of line data midway through a
- * multi-line header. _lastHeaderName stores the name of the header, while
- * _lastHeaderValue stores the value we've seen so far for the header.
- *
- * These fields are always either both undefined or both strings.
- */
- this._lastHeaderName = this._lastHeaderValue = undefined;
-}
-RequestReader.prototype =
-{
- // NSIINPUTSTREAMCALLBACK
-
- /**
- * Called when more data from the incoming request is available. This method
- * then reads the available data from input and deals with that data as
- * necessary, depending upon the syntax of already-downloaded data.
- *
- * @param input : nsIAsyncInputStream
- * the stream of incoming data from the connection
- */
- onInputStreamReady: function(input)
- {
- dumpn("*** onInputStreamReady(input=" + input + ") on thread " +
- gThreadManager.currentThread + " (main is " +
- gThreadManager.mainThread + ")");
- dumpn("*** this._state == " + this._state);
-
- // Handle cases where we get more data after a request error has been
- // discovered but *before* we can close the connection.
- var data = this._data;
- if (!data)
- return;
-
- try
- {
- data.appendBytes(readBytes(input, input.available()));
- }
- catch (e)
- {
- if (e.result !== Cr.NS_ERROR_BASE_STREAM_CLOSED)
- {
- dumpn("*** WARNING: unexpected error when reading from socket; will " +
- "be treated as if the input stream had been closed");
- }
-
- // We've lost a race -- input has been closed, but we're still expecting
- // to read more data. available() will throw in this case, and since
- // we're dead in the water now, destroy the connection. NB: we don't use
- // end() here because that has interesting interactions with
- // ServerHandler._pendingRequests.
- dumpn("*** onInputStreamReady called on a closed input, destroying " +
- "connection");
- this._connection.destroy();
- return;
- }
-
- switch (this._state)
- {
- default:
- NS_ASSERT(false);
- break;
-
- case READER_IN_REQUEST_LINE:
- if (!this._processRequestLine())
- break;
- /* fall through */
-
- case READER_IN_HEADERS:
- if (!this._processHeaders())
- break;
- /* fall through */
-
- case READER_IN_BODY:
- this._processBody();
- }
-
- if (this._state != READER_FINISHED)
- input.asyncWait(this, 0, 0, gThreadManager.currentThread);
- },
-
- //
- // see nsISupports.QueryInterface
- //
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIInputStreamCallback) ||
- aIID.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
-
- // PRIVATE API
-
- /**
- * Processes unprocessed, downloaded data as a request line.
- *
- * @returns boolean
- * true iff the request line has been fully processed
- */
- _processRequestLine: function()
- {
- NS_ASSERT(this._state == READER_IN_REQUEST_LINE);
-
-
- // servers SHOULD ignore any empty line(s) received where a Request-Line
- // is expected (section 4.1)
- var data = this._data;
- var line = {};
- var readSuccess;
- while ((readSuccess = data.readLine(line)) && line.value == "")
- dumpn("*** ignoring beginning blank line...");
-
- // if we don't have a full line, wait until we do
- if (!readSuccess)
- return false;
-
- // we have the first non-blank line
- try
- {
- this._parseRequestLine(line.value);
- this._state = READER_IN_HEADERS;
- return true;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
- * Processes stored data, assuming it is either at the beginning or in
- * the middle of processing request headers.
- *
- * @returns boolean
- * true iff header data in the request has been fully processed
- */
- _processHeaders: function()
- {
- NS_ASSERT(this._state == READER_IN_HEADERS);
-
- // XXX things to fix here:
- //
- // - need to support RFC 2047-encoded non-US-ASCII characters
-
- try
- {
- var done = this._parseHeaders();
- if (done)
- {
- var request = this._metadata;
-
- // XXX this is wrong for requests with transfer-encodings applied to
- // them, particularly chunked (which by its nature can have no
- // meaningful Content-Length header)!
- this._contentLength = request.hasHeader("Content-Length")
- ? parseInt(request.getHeader("Content-Length"), 10)
- : 0;
- dumpn("_processHeaders, Content-length=" + this._contentLength);
-
- this._state = READER_IN_BODY;
- }
- return done;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
- * Processes stored data, assuming it is either at the beginning or in
- * the middle of processing the request body.
- *
- * @returns boolean
- * true iff the request body has been fully processed
- */
- _processBody: function()
- {
- NS_ASSERT(this._state == READER_IN_BODY);
-
- // XXX handle chunked transfer-coding request bodies!
-
- try
- {
- if (this._contentLength > 0)
- {
- var data = this._data.purge();
- var count = Math.min(data.length, this._contentLength);
- dumpn("*** loading data=" + data + " len=" + data.length +
- " excess=" + (data.length - count));
-
- var bos = new BinaryOutputStream(this._metadata._bodyOutputStream);
- bos.writeByteArray(data, count);
- this._contentLength -= count;
- }
-
- dumpn("*** remaining body data len=" + this._contentLength);
- if (this._contentLength == 0)
- {
- this._validateRequest();
- this._state = READER_FINISHED;
- this._handleResponse();
- return true;
- }
-
- return false;
- }
- catch (e)
- {
- this._handleError(e);
- return false;
- }
- },
-
- /**
- * Does various post-header checks on the data in this request.
- *
- * @throws : HttpError
- * if the request was malformed in some way
- */
- _validateRequest: function()
- {
- NS_ASSERT(this._state == READER_IN_BODY);
-
- dumpn("*** _validateRequest");
-
- var metadata = this._metadata;
- var headers = metadata._headers;
-
- // 19.6.1.1 -- servers MUST report 400 to HTTP/1.1 requests w/o Host header
- var identity = this._connection.server.identity;
- if (metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1))
- {
- if (!headers.hasHeader("Host"))
- {
- dumpn("*** malformed HTTP/1.1 or greater request with no Host header!");
- throw HTTP_400;
- }
-
- // If the Request-URI wasn't absolute, then we need to determine our host.
- // We have to determine what scheme was used to access us based on the
- // server identity data at this point, because the request just doesn't
- // contain enough data on its own to do this, sadly.
- if (!metadata._host)
- {
- var host, port;
- var hostPort = headers.getHeader("Host");
- var colon = hostPort.indexOf(":");
- if (colon < 0)
- {
- host = hostPort;
- port = "";
- }
- else
- {
- host = hostPort.substring(0, colon);
- port = hostPort.substring(colon + 1);
- }
-
- // NB: We allow an empty port here because, oddly, a colon may be
- // present even without a port number, e.g. "example.com:"; in this
- // case the default port applies.
- if (!HOST_REGEX.test(host) || !/^\d*$/.test(port))
- {
- dumpn("*** malformed hostname (" + hostPort + ") in Host " +
- "header, 400 time");
- throw HTTP_400;
- }
-
- // If we're not given a port, we're stuck, because we don't know what
- // scheme to use to look up the correct port here, in general. Since
- // the HTTPS case requires a tunnel/proxy and thus requires that the
- // requested URI be absolute (and thus contain the necessary
- // information), let's assume HTTP will prevail and use that.
- port = +port || 80;
-
- var scheme = identity.getScheme(host, port);
- if (!scheme)
- {
- dumpn("*** unrecognized hostname (" + hostPort + ") in Host " +
- "header, 400 time");
- throw HTTP_400;
- }
-
- metadata._scheme = scheme;
- metadata._host = host;
- metadata._port = port;
- }
- }
- else
- {
- NS_ASSERT(metadata._host === undefined,
- "HTTP/1.0 doesn't allow absolute paths in the request line!");
-
- metadata._scheme = identity.primaryScheme;
- metadata._host = identity.primaryHost;
- metadata._port = identity.primaryPort;
- }
-
- NS_ASSERT(identity.has(metadata._scheme, metadata._host, metadata._port),
- "must have a location we recognize by now!");
- },
-
- /**
- * Handles responses in case of error, either in the server or in the request.
- *
- * @param e
- * the specific error encountered, which is an HttpError in the case where
- * the request is in some way invalid or cannot be fulfilled; if this isn't
- * an HttpError we're going to be paranoid and shut down, because that
- * shouldn't happen, ever
- */
- _handleError: function(e)
- {
- this._state = READER_FINISHED;
-
- var server = this._connection.server;
- if (e instanceof HttpError)
- {
- var code = e.code;
- }
- else
- {
- // no idea what happened -- be paranoid and shut down
- code = 500;
- server._requestQuit();
- }
-
- // make attempted reuse of data an error
- this._data = null;
-
- this._connection.processError(code, this._metadata);
- },
-
- /**
- * Now that we've read the request line and headers, we can actually hand off
- * the request to be handled.
- *
- * This method is called once per request, after the request line and all
- * headers and the body, if any, have been received.
- */
- _handleResponse: function()
- {
- NS_ASSERT(this._state == READER_FINISHED);
-
- // We don't need the line-based data any more, so make attempted reuse an
- // error.
- this._data = null;
-
- this._connection.process(this._metadata);
- },
-
-
- // PARSING
-
- /**
- * Parses the request line for the HTTP request associated with this.
- *
- * @param line : string
- * the request line
- */
- _parseRequestLine: function(line)
- {
- NS_ASSERT(this._state == READER_IN_REQUEST_LINE);
-
- dumpn("*** _parseRequestLine('" + line + "')");
-
- var metadata = this._metadata;
-
- // clients and servers SHOULD accept any amount of SP or HT characters
- // between fields, even though only a single SP is required (section 19.3)
- var request = line.split(/[ \t]+/);
- if (!request || request.length != 3)
- throw HTTP_400;
-
- metadata._method = request[0];
-
- // get the HTTP version
- var ver = request[2];
- var match = ver.match(/^HTTP\/(\d+\.\d+)$/);
- if (!match)
- throw HTTP_400;
-
- // determine HTTP version
- try
- {
- metadata._httpVersion = new nsHttpVersion(match[1]);
- if (!metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_0))
- throw "unsupported HTTP version";
- }
- catch (e)
- {
- // we support HTTP/1.0 and HTTP/1.1 only
- throw HTTP_501;
- }
-
-
- var fullPath = request[1];
- var serverIdentity = this._connection.server.identity;
-
- var scheme, host, port;
-
- if (fullPath.charAt(0) != "/")
- {
- // No absolute paths in the request line in HTTP prior to 1.1
- if (!metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1))
- throw HTTP_400;
-
- try
- {
- var uri = Cc["@mozilla.org/network/io-service;1"]
- .getService(Ci.nsIIOService)
- .newURI(fullPath, null, null);
- fullPath = uri.path;
- scheme = uri.scheme;
- host = metadata._host = uri.asciiHost;
- port = uri.port;
- if (port === -1)
- {
- if (scheme === "http")
- port = 80;
- else if (scheme === "https")
- port = 443;
- else
- throw HTTP_400;
- }
- }
- catch (e)
- {
- // If the host is not a valid host on the server, the response MUST be a
- // 400 (Bad Request) error message (section 5.2). Alternately, the URI
- // is malformed.
- throw HTTP_400;
- }
-
- if (!serverIdentity.has(scheme, host, port) || fullPath.charAt(0) != "/")
- throw HTTP_400;
- }
-
- var splitter = fullPath.indexOf("?");
- if (splitter < 0)
- {
- // _queryString already set in ctor
- metadata._path = fullPath;
- }
- else
- {
- metadata._path = fullPath.substring(0, splitter);
- metadata._queryString = fullPath.substring(splitter + 1);
- }
-
- metadata._scheme = scheme;
- metadata._host = host;
- metadata._port = port;
- },
-
- /**
- * Parses all available HTTP headers in this until the header-ending CRLFCRLF,
- * adding them to the store of headers in the request.
- *
- * @throws
- * HTTP_400 if the headers are malformed
- * @returns boolean
- * true if all headers have now been processed, false otherwise
- */
- _parseHeaders: function()
- {
- NS_ASSERT(this._state == READER_IN_HEADERS);
-
- dumpn("*** _parseHeaders");
-
- var data = this._data;
-
- var headers = this._metadata._headers;
- var lastName = this._lastHeaderName;
- var lastVal = this._lastHeaderValue;
-
- var line = {};
- while (true)
- {
- NS_ASSERT(!((lastVal === undefined) ^ (lastName === undefined)),
- lastName === undefined ?
- "lastVal without lastName? lastVal: '" + lastVal + "'" :
- "lastName without lastVal? lastName: '" + lastName + "'");
-
- if (!data.readLine(line))
- {
- // save any data we have from the header we might still be processing
- this._lastHeaderName = lastName;
- this._lastHeaderValue = lastVal;
- return false;
- }
-
- var lineText = line.value;
- var firstChar = lineText.charAt(0);
-
- // blank line means end of headers
- if (lineText == "")
- {
- // we're finished with the previous header
- if (lastName)
- {
- try
- {
- headers.setHeader(lastName, lastVal, true);
- }
- catch (e)
- {
- dumpn("*** e == " + e);
- throw HTTP_400;
- }
- }
- else
- {
- // no headers in request -- valid for HTTP/1.0 requests
- }
-
- // either way, we're done processing headers
- this._state = READER_IN_BODY;
- return true;
- }
- else if (firstChar == " " || firstChar == "\t")
- {
- // multi-line header if we've already seen a header line
- if (!lastName)
- {
- // we don't have a header to continue!
- throw HTTP_400;
- }
-
- // append this line's text to the value; starts with SP/HT, so no need
- // for separating whitespace
- lastVal += lineText;
- }
- else
- {
- // we have a new header, so set the old one (if one existed)
- if (lastName)
- {
- try
- {
- headers.setHeader(lastName, lastVal, true);
- }
- catch (e)
- {
- dumpn("*** e == " + e);
- throw HTTP_400;
- }
- }
-
- var colon = lineText.indexOf(":"); // first colon must be splitter
- if (colon < 1)
- {
- // no colon or missing header field-name
- throw HTTP_400;
- }
-
- // set header name, value (to be set in the next loop, usually)
- lastName = lineText.substring(0, colon);
- lastVal = lineText.substring(colon + 1);
- } // empty, continuation, start of header
- } // while (true)
- }
-};
-
-
-/** The character codes for CR and LF. */
-const CR = 0x0D, LF = 0x0A;
-
-/**
- * Calculates the number of characters before the first CRLF pair in array, or
- * -1 if the array contains no CRLF pair.
- *
- * @param array : Array
- * an array of numbers in the range [0, 256), each representing a single
- * character; the first CRLF is the lowest index i where
- * |array[i] == "\r".charCodeAt(0)| and |array[i+1] == "\n".charCodeAt(0)|,
- * if such an |i| exists, and -1 otherwise
- * @returns int
- * the index of the first CRLF if any were present, -1 otherwise
- */
-function findCRLF(array)
-{
- for (var i = array.indexOf(CR); i >= 0; i = array.indexOf(CR, i + 1))
- {
- if (array[i + 1] == LF)
- return i;
- }
- return -1;
-}
-
-
-/**
- * A container which provides line-by-line access to the arrays of bytes with
- * which it is seeded.
- */
-function LineData()
-{
- /** An array of queued bytes from which to get line-based characters. */
- this._data = [];
-}
-LineData.prototype =
-{
- /**
- * Appends the bytes in the given array to the internal data cache maintained
- * by this.
- */
- appendBytes: function(bytes)
- {
- Array.prototype.push.apply(this._data, bytes);
- },
-
- /**
- * Removes and returns a line of data, delimited by CRLF, from this.
- *
- * @param out
- * an object whose "value" property will be set to the first line of text
- * present in this, sans CRLF, if this contains a full CRLF-delimited line
- * of text; if this doesn't contain enough data, the value of the property
- * is undefined
- * @returns boolean
- * true if a full line of data could be read from the data in this, false
- * otherwise
- */
- readLine: function(out)
- {
- var data = this._data;
- var length = findCRLF(data);
- if (length < 0)
- return false;
-
- //
- // We have the index of the CR, so remove all the characters, including
- // CRLF, from the array with splice, and convert the removed array into the
- // corresponding string, from which we then strip the trailing CRLF.
- //
- // Getting the line in this matter acknowledges that substring is an O(1)
- // operation in SpiderMonkey because strings are immutable, whereas two
- // splices, both from the beginning of the data, are less likely to be as
- // cheap as a single splice plus two extra character conversions.
- //
- var line = String.fromCharCode.apply(null, data.splice(0, length + 2));
- out.value = line.substring(0, length);
-
- return true;
- },
-
- /**
- * Removes the bytes currently within this and returns them in an array.
- *
- * @returns Array
- * the bytes within this when this method is called
- */
- purge: function()
- {
- var data = this._data;
- this._data = [];
- return data;
- }
-};
-
-
-
-/**
- * Creates a request-handling function for an nsIHttpRequestHandler object.
- */
-function createHandlerFunc(handler)
-{
- return function(metadata, response) { handler.handle(metadata, response); };
-}
-
-
-/**
- * The default handler for directories; writes an HTML response containing a
- * slightly-formatted directory listing.
- */
-function defaultIndexHandler(metadata, response)
-{
- response.setHeader("Content-Type", "text/html", false);
-
- var path = htmlEscape(decodeURI(metadata.path));
-
- //
- // Just do a very basic bit of directory listings -- no need for too much
- // fanciness, especially since we don't have a style sheet in which we can
- // stick rules (don't want to pollute the default path-space).
- //
-
- var body = '<html>\
- <head>\
- <title>' + path + '</title>\
- </head>\
- <body>\
- <h1>' + path + '</h1>\
- <ol style="list-style-type: none">';
-
- var directory = metadata.getProperty("directory");
- NS_ASSERT(directory && directory.isDirectory());
-
- var fileList = [];
- var files = directory.directoryEntries;
- while (files.hasMoreElements())
- {
- var f = files.getNext().QueryInterface(Ci.nsIFile);
- var name = f.leafName;
- if (!f.isHidden() &&
- (name.charAt(name.length - 1) != HIDDEN_CHAR ||
- name.charAt(name.length - 2) == HIDDEN_CHAR))
- fileList.push(f);
- }
-
- fileList.sort(fileSort);
-
- for (var i = 0; i < fileList.length; i++)
- {
- var file = fileList[i];
- try
- {
- var name = file.leafName;
- if (name.charAt(name.length - 1) == HIDDEN_CHAR)
- name = name.substring(0, name.length - 1);
- var sep = file.isDirectory() ? "/" : "";
-
- // Note: using " to delimit the attribute here because encodeURIComponent
- // passes through '.
- var item = '<li><a href="' + encodeURIComponent(name) + sep + '">' +
- htmlEscape(name) + sep +
- '</a></li>';
-
- body += item;
- }
- catch (e) { /* some file system error, ignore the file */ }
- }
-
- body += ' </ol>\
- </body>\
- </html>';
-
- response.bodyOutputStream.write(body, body.length);
-}
-
-/**
- * Sorts a and b (nsIFile objects) into an aesthetically pleasing order.
- */
-function fileSort(a, b)
-{
- var dira = a.isDirectory(), dirb = b.isDirectory();
-
- if (dira && !dirb)
- return -1;
- if (dirb && !dira)
- return 1;
-
- var namea = a.leafName.toLowerCase(), nameb = b.leafName.toLowerCase();
- return nameb > namea ? -1 : 1;
-}
-
-
-/**
- * Converts an externally-provided path into an internal path for use in
- * determining file mappings.
- *
- * @param path
- * the path to convert
- * @param encoded
- * true if the given path should be passed through decodeURI prior to
- * conversion
- * @throws URIError
- * if path is incorrectly encoded
- */
-function toInternalPath(path, encoded)
-{
- if (encoded)
- path = decodeURI(path);
-
- var comps = path.split("/");
- for (var i = 0, sz = comps.length; i < sz; i++)
- {
- var comp = comps[i];
- if (comp.charAt(comp.length - 1) == HIDDEN_CHAR)
- comps[i] = comp + HIDDEN_CHAR;
- }
- return comps.join("/");
-}
-
-
-/**
- * Adds custom-specified headers for the given file to the given response, if
- * any such headers are specified.
- *
- * @param file
- * the file on the disk which is to be written
- * @param metadata
- * metadata about the incoming request
- * @param response
- * the Response to which any specified headers/data should be written
- * @throws HTTP_500
- * if an error occurred while processing custom-specified headers
- */
-function maybeAddHeaders(file, metadata, response)
-{
- var name = file.leafName;
- if (name.charAt(name.length - 1) == HIDDEN_CHAR)
- name = name.substring(0, name.length - 1);
-
- var headerFile = file.parent;
- headerFile.append(name + HEADERS_SUFFIX);
-
- if (!headerFile.exists())
- return;
-
- const PR_RDONLY = 0x01;
- var fis = new FileInputStream(headerFile, PR_RDONLY, 0444,
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- try
- {
- var lis = new ConverterInputStream(fis, "UTF-8", 1024, 0x0);
- lis.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- var line = {value: ""};
- var more = lis.readLine(line);
-
- if (!more && line.value == "")
- return;
-
-
- // request line
-
- var status = line.value;
- if (status.indexOf("HTTP ") == 0)
- {
- status = status.substring(5);
- var space = status.indexOf(" ");
- var code, description;
- if (space < 0)
- {
- code = status;
- description = "";
- }
- else
- {
- code = status.substring(0, space);
- description = status.substring(space + 1, status.length);
- }
-
- response.setStatusLine(metadata.httpVersion, parseInt(code, 10), description);
-
- line.value = "";
- more = lis.readLine(line);
- }
-
- // headers
- while (more || line.value != "")
- {
- var header = line.value;
- var colon = header.indexOf(":");
-
- response.setHeader(header.substring(0, colon),
- header.substring(colon + 1, header.length),
- false); // allow overriding server-set headers
-
- line.value = "";
- more = lis.readLine(line);
- }
- }
- catch (e)
- {
- dumpn("WARNING: error in headers for " + metadata.path + ": " + e);
- throw HTTP_500;
- }
- finally
- {
- fis.close();
- }
-}
-
-
-/**
- * An object which handles requests for a server, executing default and
- * overridden behaviors as instructed by the code which uses and manipulates it.
- * Default behavior includes the paths / and /trace (diagnostics), with some
- * support for HTTP error pages for various codes and fallback to HTTP 500 if
- * those codes fail for any reason.
- *
- * @param server : nsHttpServer
- * the server in which this handler is being used
- */
-function ServerHandler(server)
-{
- // FIELDS
-
- /**
- * The nsHttpServer instance associated with this handler.
- */
- this._server = server;
-
- /**
- * A variable used to ensure that all requests are fully complete before the
- * server shuts down, to avoid callbacks from compiled code calling back into
- * empty contexts. See also the comment before this field is next modified.
- */
- this._pendingRequests = 0;
-
- /**
- * A FileMap object containing the set of path->nsILocalFile mappings for
- * all directory mappings set in the server (e.g., "/" for /var/www/html/,
- * "/foo/bar/" for /local/path/, and "/foo/bar/baz/" for /local/path2).
- *
- * Note carefully: the leading and trailing "/" in each path (not file) are
- * removed before insertion to simplify the code which uses this. You have
- * been warned!
- */
- this._pathDirectoryMap = new FileMap();
-
- /**
- * Custom request handlers for the server in which this resides. Path-handler
- * pairs are stored as property-value pairs in this property.
- *
- * @see ServerHandler.prototype._defaultPaths
- */
- this._overridePaths = {};
-
- /**
- * Custom request handlers for the error handlers in the server in which this
- * resides. Path-handler pairs are stored as property-value pairs in this
- * property.
- *
- * @see ServerHandler.prototype._defaultErrors
- */
- this._overrideErrors = {};
-
- /**
- * Maps file extensions to their MIME types in the server, overriding any
- * mapping that might or might not exist in the MIME service.
- */
- this._mimeMappings = {};
-
- /**
- * The default handler for requests for directories, used to serve directories
- * when no index file is present.
- */
- this._indexHandler = defaultIndexHandler;
-
- /** Per-path state storage for the server. */
- this._state = {};
-
- /** Entire-server state storage. */
- this._sharedState = {};
-}
-ServerHandler.prototype =
-{
- // PUBLIC API
-
- /**
- * Handles a request to this server, responding to the request appropriately
- * and initiating server shutdown if necessary.
- *
- * This method never throws an exception.
- *
- * @param connection : Connection
- * the connection for this request
- * @param metadata : Request
- * request metadata as generated from the initial request
- */
- handleResponse: function(connection, metadata)
- {
- var response = new Response();
-
- var path = metadata.path;
- dumpn("*** path == " + path);
-
- try
- {
- try
- {
- if (path in this._overridePaths)
- {
- // explicit paths first, then files based on existing directory mappings,
- // then (if the file doesn't exist) built-in server default paths
- dumpn("calling override for " + path);
- this._overridePaths[path](metadata, response);
- }
- else
- this._handleDefault(metadata, response);
- }
- catch (e)
- {
- response.recycle();
-
- if (!(e instanceof HttpError))
- {
- dumpn("*** unexpected error: e == " + e);
- throw HTTP_500;
- }
- if (e.code != 404)
- throw e;
-
- dumpn("*** default: " + (path in this._defaultPaths));
-
- if (path in this._defaultPaths)
- this._defaultPaths[path](metadata, response);
- else
- throw HTTP_404;
- }
- }
- catch (e)
- {
- var errorCode = "internal";
-
- try
- {
- if (!(e instanceof HttpError))
- throw e;
-
- errorCode = e.code;
- dumpn("*** errorCode == " + errorCode);
-
- response.recycle();
-
- this._handleError(errorCode, metadata, response);
- }
- catch (e2)
- {
- dumpn("*** error handling " + errorCode + " error: " +
- "e2 == " + e2 + ", shutting down server");
-
- response.destroy();
- connection.close();
- connection.server.stop();
- return;
- }
- }
-
- this._end(response, connection);
- },
-
- //
- // see nsIHttpServer.registerFile
- //
- registerFile: function(path, file)
- {
- if (!file)
- {
- dumpn("*** unregistering '" + path + "' mapping");
- delete this._overridePaths[path];
- return;
- }
-
- dumpn("*** registering '" + path + "' as mapping to " + file.path);
- file = file.clone();
-
- var self = this;
- this._overridePaths[path] =
- function(metadata, response)
- {
- if (!file.exists())
- throw HTTP_404;
-
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- self._writeFileResponse(metadata, file, response);
- };
- },
-
- //
- // see nsIHttpServer.registerPathHandler
- //
- registerPathHandler: function(path, handler)
- {
- // XXX true path validation!
- if (path.charAt(0) != "/")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- this._handlerToField(handler, this._overridePaths, path);
- },
-
- //
- // see nsIHttpServer.registerDirectory
- //
- registerDirectory: function(path, directory)
- {
- // strip off leading and trailing '/' so that we can use lastIndexOf when
- // determining exactly how a path maps onto a mapped directory --
- // conditional is required here to deal with "/".substring(1, 0) being
- // converted to "/".substring(0, 1) per the JS specification
- var key = path.length == 1 ? "" : path.substring(1, path.length - 1);
-
- // the path-to-directory mapping code requires that the first character not
- // be "/", or it will go into an infinite loop
- if (key.charAt(0) == "/")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- key = toInternalPath(key, false);
-
- if (directory)
- {
- dumpn("*** mapping '" + path + "' to the location " + directory.path);
- this._pathDirectoryMap.put(key, directory);
- }
- else
- {
- dumpn("*** removing mapping for '" + path + "'");
- this._pathDirectoryMap.put(key, null);
- }
- },
-
- //
- // see nsIHttpServer.registerErrorHandler
- //
- registerErrorHandler: function(err, handler)
- {
- if (!(err in HTTP_ERROR_CODES))
- dumpn("*** WARNING: registering non-HTTP/1.1 error code " +
- "(" + err + ") handler -- was this intentional?");
-
- this._handlerToField(handler, this._overrideErrors, err);
- },
-
- //
- // see nsIHttpServer.setIndexHandler
- //
- setIndexHandler: function(handler)
- {
- if (!handler)
- handler = defaultIndexHandler;
- else if (typeof(handler) != "function")
- handler = createHandlerFunc(handler);
-
- this._indexHandler = handler;
- },
-
- //
- // see nsIHttpServer.registerContentType
- //
- registerContentType: function(ext, type)
- {
- if (!type)
- delete this._mimeMappings[ext];
- else
- this._mimeMappings[ext] = headerUtils.normalizeFieldValue(type);
- },
-
- // NON-XPCOM PUBLIC API
-
- /**
- * Returns true if this handler is in the middle of handling any current
- * requests; this must be false before the server in which this is used may be
- * safely shut down.
- */
- hasPendingRequests: function()
- {
- return this._pendingRequests > 0;
- },
-
-
- // PRIVATE API
-
- /**
- * Sets or remove (if handler is null) a handler in an object with a key.
- *
- * @param handler
- * a handler, either function or an nsIHttpRequestHandler
- * @param dict
- * The object to attach the handler to.
- * @param key
- * The field name of the handler.
- */
- _handlerToField: function(handler, dict, key)
- {
- // for convenience, handler can be a function if this is run from xpcshell
- if (typeof(handler) == "function")
- dict[key] = handler;
- else if (handler)
- dict[key] = createHandlerFunc(handler);
- else
- delete dict[key];
- },
-
- /**
- * Handles a request which maps to a file in the local filesystem (if a base
- * path has already been set; otherwise the 404 error is thrown).
- *
- * @param metadata : Request
- * metadata for the incoming request
- * @param response : Response
- * an uninitialized Response to the given request, to be initialized by a
- * request handler
- * @throws HTTP_###
- * if an HTTP error occurred (usually HTTP_404); note that in this case the
- * calling code must handle cleanup of the response by calling .destroy()
- * or .recycle()
- */
- _handleDefault: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
-
- var path = metadata.path;
- NS_ASSERT(path.charAt(0) == "/", "invalid path: <" + path + ">");
-
- // determine the actual on-disk file; this requires finding the deepest
- // path-to-directory mapping in the requested URL
- var file = this._getFileForPath(path);
-
- // the "file" might be a directory, in which case we either serve the
- // contained index.html or make the index handler write the response
- if (file.exists() && file.isDirectory())
- {
- file.append("index.html"); // make configurable?
- if (!file.exists() || file.isDirectory())
- {
- metadata._ensurePropertyBag();
- metadata._bag.setPropertyAsInterface("directory", file.parent);
- this._indexHandler(metadata, response);
- return;
- }
- }
-
- // alternately, the file might not exist
- if (!file.exists())
- throw HTTP_404;
-
- var start, end;
- if (metadata._httpVersion.atLeast(nsHttpVersion.HTTP_1_1) &&
- metadata.hasHeader("Range"))
- {
- var rangeMatch = metadata.getHeader("Range").match(/^bytes=(\d+)?-(\d+)?$/);
- if (!rangeMatch)
- throw HTTP_400;
-
- if (rangeMatch[1] !== undefined)
- start = parseInt(rangeMatch[1], 10);
-
- if (rangeMatch[2] !== undefined)
- end = parseInt(rangeMatch[2], 10);
-
- if (start === undefined && end === undefined)
- throw HTTP_400;
-
- // No start given, so the end is really the count of bytes from the
- // end of the file.
- if (start === undefined)
- {
- start = Math.max(0, file.fileSize - end);
- end = file.fileSize - 1;
- }
-
- // start and end are inclusive
- if (end === undefined || end >= file.fileSize)
- end = file.fileSize - 1;
-
- if (start !== undefined && start >= file.fileSize)
- throw HTTP_416;
-
- if (end < start)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- start = 0;
- end = file.fileSize - 1;
- }
- else
- {
- response.setStatusLine(metadata.httpVersion, 206, "Partial Content");
- var contentRange = "bytes " + start + "-" + end + "/" + file.fileSize;
- response.setHeader("Content-Range", contentRange);
- }
- }
- else
- {
- start = 0;
- end = file.fileSize - 1;
- }
-
- // finally...
- dumpn("*** handling '" + path + "' as mapping to " + file.path + " from " +
- start + " to " + end + " inclusive");
- this._writeFileResponse(metadata, file, response, start, end - start + 1);
- },
-
- /**
- * Writes an HTTP response for the given file, including setting headers for
- * file metadata.
- *
- * @param metadata : Request
- * the Request for which a response is being generated
- * @param file : nsILocalFile
- * the file which is to be sent in the response
- * @param response : Response
- * the response to which the file should be written
- * @param offset: uint
- * the byte offset to skip to when writing
- * @param count: uint
- * the number of bytes to write
- */
- _writeFileResponse: function(metadata, file, response, offset, count)
- {
- const PR_RDONLY = 0x01;
-
- var type = this._getTypeFromFile(file);
- if (type === SJS_TYPE)
- {
- var fis = new FileInputStream(file, PR_RDONLY, 0444,
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- try
- {
- var sis = new ScriptableInputStream(fis);
- var s = Cu.Sandbox(gGlobalObject);
- s.importFunction(dump, "dump");
-
- // Define a basic key-value state-preservation API across requests, with
- // keys initially corresponding to the empty string.
- var self = this;
- s.importFunction(function getState(k) { return self._getState(metadata.path, k); });
- s.importFunction(function setState(k, v) { self._setState(metadata.path, k, v); });
- s.importFunction(function getSharedState(k) { return self._getSharedState(k); });
- s.importFunction(function setSharedState(k, v) { self._setSharedState(k, v); });
-
- try
- {
- // Alas, the line number in errors dumped to console when calling the
- // request handler is simply an offset from where we load the SJS file.
- // Work around this in a reasonably non-fragile way by dynamically
- // getting the line number where we evaluate the SJS file. Don't
- // separate these two lines!
- var line = new Error().lineNumber;
- Cu.evalInSandbox(sis.read(file.fileSize), s);
- }
- catch (e)
- {
- dumpn("*** syntax error in SJS at " + file.path + ": " + e);
- throw HTTP_500;
- }
-
- try
- {
- s.handleRequest(metadata, response);
- }
- catch (e)
- {
- dumpn("*** error running SJS at " + file.path + ": " +
- e + " on line " + (e.lineNumber - line));
- throw HTTP_500;
- }
- }
- finally
- {
- fis.close();
- }
- }
- else
- {
- try
- {
- response.setHeader("Last-Modified",
- toDateString(file.lastModifiedTime),
- false);
- }
- catch (e) { /* lastModifiedTime threw, ignore */ }
-
- response.setHeader("Content-Type", type, false);
-
- var fis = new FileInputStream(file, PR_RDONLY, 0444,
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- try
- {
- offset = offset || 0;
- count = count || file.fileSize;
-
- NS_ASSERT(offset == 0 || offset < file.fileSize, "bad offset");
- NS_ASSERT(count >= 0, "bad count");
-
- if (offset != 0)
- {
- // Read and discard data up to offset so the data sent to
- // the client matches the requested range request.
- var sis = new ScriptableInputStream(fis);
- sis.read(offset);
- }
- response.bodyOutputStream.writeFrom(fis, count);
- }
- finally
- {
- fis.close();
- }
-
- maybeAddHeaders(file, metadata, response);
- }
- },
-
- /**
- * Get the value corresponding to a given key for the given path for SJS state
- * preservation across requests.
- *
- * @param path : string
- * the path from which the given state is to be retrieved
- * @param k : string
- * the key whose corresponding value is to be returned
- * @returns string
- * the corresponding value, which is initially the empty string
- */
- _getState: function(path, k)
- {
- var state = this._state;
- if (path in state && k in state[path])
- return state[path][k];
- return "";
- },
-
- /**
- * Set the value corresponding to a given key for the given path for SJS state
- * preservation across requests.
- *
- * @param path : string
- * the path from which the given state is to be retrieved
- * @param k : string
- * the key whose corresponding value is to be set
- * @param v : string
- * the value to be set
- */
- _setState: function(path, k, v)
- {
- if (typeof v !== "string")
- throw new Exception("non-string value passed");
- var state = this._state;
- if (!(path in state))
- state[path] = {};
- state[path][k] = v;
- },
-
- /**
- * Get the value corresponding to a given key for SJS state preservation
- * across requests.
- *
- * @param k : string
- * the key whose corresponding value is to be returned
- * @returns string
- * the corresponding value, which is initially the empty string
- */
- _getSharedState: function(k)
- {
- var state = this._sharedState;
- if (k in state)
- return state[k];
- return "";
- },
-
- /**
- * Set the value corresponding to a given key for SJS state preservation
- * across requests.
- *
- * @param k : string
- * the key whose corresponding value is to be set
- * @param v : string
- * the value to be set
- */
- _setSharedState: function(k, v)
- {
- if (typeof v !== "string")
- throw new Exception("non-string value passed");
- this._sharedState[k] = v;
- },
-
- /**
- * Gets a content-type for the given file, first by checking for any custom
- * MIME-types registered with this handler for the file's extension, second by
- * asking the global MIME service for a content-type, and finally by failing
- * over to application/octet-stream.
- *
- * @param file : nsIFile
- * the nsIFile for which to get a file type
- * @returns string
- * the best content-type which can be determined for the file
- */
- _getTypeFromFile: function(file)
- {
- try
- {
- var name = file.leafName;
- var dot = name.lastIndexOf(".");
- if (dot > 0)
- {
- var ext = name.slice(dot + 1);
- if (ext in this._mimeMappings)
- return this._mimeMappings[ext];
- }
- return Cc["@mozilla.org/uriloader/external-helper-app-service;1"]
- .getService(Ci.nsIMIMEService)
- .getTypeFromFile(file);
- }
- catch (e)
- {
- return "application/octet-stream";
- }
- },
-
- /**
- * Returns the nsILocalFile which corresponds to the path, as determined using
- * all registered path->directory mappings and any paths which are explicitly
- * overridden.
- *
- * @param path : string
- * the server path for which a file should be retrieved, e.g. "/foo/bar"
- * @throws HttpError
- * when the correct action is the corresponding HTTP error (i.e., because no
- * mapping was found for a directory in path, the referenced file doesn't
- * exist, etc.)
- * @returns nsILocalFile
- * the file to be sent as the response to a request for the path
- */
- _getFileForPath: function(path)
- {
- // decode and add underscores as necessary
- try
- {
- path = toInternalPath(path, true);
- }
- catch (e)
- {
- throw HTTP_400; // malformed path
- }
-
- // next, get the directory which contains this path
- var pathMap = this._pathDirectoryMap;
-
- // An example progression of tmp for a path "/foo/bar/baz/" might be:
- // "foo/bar/baz/", "foo/bar/baz", "foo/bar", "foo", ""
- var tmp = path.substring(1);
- while (true)
- {
- // do we have a match for current head of the path?
- var file = pathMap.get(tmp);
- if (file)
- {
- // XXX hack; basically disable showing mapping for /foo/bar/ when the
- // requested path was /foo/bar, because relative links on the page
- // will all be incorrect -- we really need the ability to easily
- // redirect here instead
- if (tmp == path.substring(1) &&
- tmp.length != 0 &&
- tmp.charAt(tmp.length - 1) != "/")
- file = null;
- else
- break;
- }
-
- // if we've finished trying all prefixes, exit
- if (tmp == "")
- break;
-
- tmp = tmp.substring(0, tmp.lastIndexOf("/"));
- }
-
- // no mapping applies, so 404
- if (!file)
- throw HTTP_404;
-
-
- // last, get the file for the path within the determined directory
- var parentFolder = file.parent;
- var dirIsRoot = (parentFolder == null);
-
- // Strategy here is to append components individually, making sure we
- // never move above the given directory; this allows paths such as
- // "<file>/foo/../bar" but prevents paths such as "<file>/../base-sibling";
- // this component-wise approach also means the code works even on platforms
- // which don't use "/" as the directory separator, such as Windows
- var leafPath = path.substring(tmp.length + 1);
- var comps = leafPath.split("/");
- for (var i = 0, sz = comps.length; i < sz; i++)
- {
- var comp = comps[i];
-
- if (comp == "..")
- file = file.parent;
- else if (comp == "." || comp == "")
- continue;
- else
- file.append(comp);
-
- if (!dirIsRoot && file.equals(parentFolder))
- throw HTTP_403;
- }
-
- return file;
- },
-
- /**
- * Writes the error page for the given HTTP error code over the given
- * connection.
- *
- * @param errorCode : uint
- * the HTTP error code to be used
- * @param connection : Connection
- * the connection on which the error occurred
- */
- handleError: function(errorCode, connection)
- {
- var response = new Response();
-
- dumpn("*** error in request: " + errorCode);
-
- try
- {
- this._handleError(errorCode, new Request(connection.port), response);
- this._end(response, connection);
- }
- catch (e)
- {
- dumpn("*** error in handleError: " + e);
- connection.close();
- connection.server.stop();
- }
- },
-
- /**
- * Handles a request which generates the given error code, using the
- * user-defined error handler if one has been set, gracefully falling back to
- * the x00 status code if the code has no handler, and failing to status code
- * 500 if all else fails.
- *
- * @param errorCode : uint
- * the HTTP error which is to be returned
- * @param metadata : Request
- * metadata for the request, which will often be incomplete since this is an
- * error
- * @param response : Response
- * an uninitialized Response should be initialized when this method
- * completes with information which represents the desired error code in the
- * ideal case or a fallback code in abnormal circumstances (i.e., 500 is a
- * fallback for 505, per HTTP specs)
- */
- _handleError: function(errorCode, metadata, response)
- {
- if (!metadata)
- throw Cr.NS_ERROR_NULL_POINTER;
-
- var errorX00 = errorCode - (errorCode % 100);
-
- try
- {
- if (!(errorCode in HTTP_ERROR_CODES))
- dumpn("*** WARNING: requested invalid error: " + errorCode);
-
- // RFC 2616 says that we should try to handle an error by its class if we
- // can't otherwise handle it -- if that fails, we revert to handling it as
- // a 500 internal server error, and if that fails we throw and shut down
- // the server
-
- // actually handle the error
- try
- {
- if (errorCode in this._overrideErrors)
- this._overrideErrors[errorCode](metadata, response);
- else if (errorCode in this._defaultErrors)
- this._defaultErrors[errorCode](metadata, response);
- }
- catch (e)
- {
- // don't retry the handler that threw
- if (errorX00 == errorCode)
- throw HTTP_500;
-
- dumpn("*** error in handling for error code " + errorCode + ", " +
- "falling back to " + errorX00 + "...");
- if (errorX00 in this._overrideErrors)
- this._overrideErrors[errorX00](metadata, response);
- else if (errorX00 in this._defaultErrors)
- this._defaultErrors[errorX00](metadata, response);
- else
- throw HTTP_500;
- }
- }
- catch (e)
- {
- response.recycle();
-
- // we've tried everything possible for a meaningful error -- now try 500
- dumpn("*** error in handling for error code " + errorX00 + ", falling " +
- "back to 500...");
-
- try
- {
- if (500 in this._overrideErrors)
- this._overrideErrors[500](metadata, response);
- else
- this._defaultErrors[500](metadata, response);
- }
- catch (e2)
- {
- dumpn("*** multiple errors in default error handlers!");
- dumpn("*** e == " + e + ", e2 == " + e2);
- throw e2;
- }
- }
- },
-
- /**
- * Called when all processing necessary for the current request has completed
- * and response headers and data have been determined. This method takes
- * those headers and data, sends them to the HTTP client, and halts further
- * processing. It will also send a quit message to the server if necessary.
- *
- * This method never throws an exception.
- *
- * @param response : Response
- * the desired response
- * @param connection : Connection
- * the connection associated with the given response
- * @note
- * after completion, response must be considered "dead", and none of its
- * methods or properties may be accessed
- */
- _end: function(response, connection)
- {
- // post-processing
- response.setHeader("Connection", "close", false);
- response.setHeader("Server", "httpd.js", false);
- response.setHeader("Date", toDateString(Date.now()), false);
-
- var bodyStream = response.bodyInputStream;
-
- // XXX suckage time!
- //
- // If the body of the response has had no data written to it (or has never
- // been accessed -- same deal internally since we'll create one if we have
- // to access bodyInputStream but have neither an input stream nor an
- // output stream), the in-tree implementation of nsIPipe is such that
- // when we try to close the pipe's output stream with no data in it, this
- // is interpreted as an error and closing the output stream also closes
- // the input stream. .available then throws, so we catch and deal as best
- // as we can.
- //
- // Unfortunately, the easy alternative (substitute a storage stream for a
- // pipe) also doesn't work. There's no problem writing zero bytes to the
- // output end of the stream, but then attempting to get an input stream to
- // read fails because the seek position must be strictly less than the
- // buffer size.
- //
- // Much as I'd like the zero-byte body to be a mostly-unimportant problem,
- // there are some HTTP responses such as 304 Not Modified which MUST have
- // zero-byte bodies, so this *is* a necessary hack.
- try
- {
- var available = bodyStream.available();
- }
- catch (e)
- {
- available = 0;
- }
-
- response.setHeader("Content-Length", available.toString(), false);
-
-
- // construct and send response
-
- // request-line
- var preamble = "HTTP/" + response.httpVersion + " " +
- response.httpCode + " " +
- response.httpDescription + "\r\n";
-
- // headers
- var head = response.headers;
- var headEnum = head.enumerator;
- while (headEnum.hasMoreElements())
- {
- var fieldName = headEnum.getNext()
- .QueryInterface(Ci.nsISupportsString)
- .data;
- var values = head.getHeaderValues(fieldName);
- for (var i = 0, sz = values.length; i < sz; i++)
- preamble += fieldName + ": " + values[i] + "\r\n";
- }
-
- // end request-line/headers
- preamble += "\r\n";
-
- var outStream = connection.output;
- try
- {
- outStream.write(preamble, preamble.length);
- }
- catch (e)
- {
- // Connection closed already? Even if not, failure to write the response
- // means we probably will fail later anyway, so in the interests of
- // avoiding exceptions we'll (possibly) close the connection and return.
- response.destroy();
- connection.close();
- return;
- }
-
- // In certain situations, it's possible for us to have a race between
- // the copy observer's onStopRequest and the listener for a channel
- // opened to this server. Since we include a Content-Length header with
- // every response, if the channel snarfs up all the data we promise,
- // calls onStopRequest on the listener (and the server is shut down
- // by that listener, causing the script to finish executing), and then
- // tries to call onStopRequest on the copyObserver, we'll call into a
- // scope with no Components and cause assertions *and* fail to close the
- // connection properly. To combat this, during server shutdown we delay
- // full shutdown until any pending requests are fully copied using this
- // property on the server handler. We increment before (possibly)
- // starting the copy observer and decrement when the copy completes,
- // ensuring that all copies complete before the server fully shuts down.
- //
- // We do this for every request primarily to simplify maintenance of this
- // property (and also because it's less fragile when we can remove the
- // zero-sized body hack used above).
- this._pendingRequests++;
-
- var server = this._server;
-
- // If we have a body, send it -- if we don't, then don't bother with a
- // heavyweight async copy which doesn't need to happen and just do
- // response post-processing (usually handled by the copy observer)
- // directly
- if (available != 0)
- {
- /**
- * Observer of the copying of data from the body stream generated by a
- * request handler to the output stream for the server socket. It
- * handles all post-request-writing cleanup details, such as closing
- * open streams and shutting down the server in case of errors.
- */
- var copyObserver =
- {
- onStartRequest: function(request, context) { /* don't care */ },
-
- /**
- * Called when the async stream copy completes. This is place where
- * final cleanup should occur, including stream closures and
- * response destruction. Note that errors which are detected here
- * should still shut down the server, for safety.
- */
- onStopRequest: function(request, cx, statusCode)
- {
- // statusCode can indicate user-triggered failures (e.g. if the user
- // closes the connection during the copy, which would cause a status
- // of NS_ERROR_NET_RESET), so don't treat its value being an error
- // code as catastrophic. I can create this situation when running
- // Mochitests in a debug build by clicking the Stop button during
- // test execution, but it's not exactly a surefire way to reproduce
- // the problem.
- if (!Components.isSuccessCode(statusCode))
- {
- dumpn("*** WARNING: non-success statusCode in onStopRequest: " +
- statusCode);
- }
-
- // we're completely finished with this response
- response.destroy();
-
- connection.end();
- },
-
- QueryInterface: function(aIID)
- {
- if (aIID.equals(Ci.nsIRequestObserver) ||
- aIID.equals(Ci.nsISupports))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- };
-
-
- //
- // Now write out the body, async since we might be serving this to
- // ourselves on the same thread, and writing too much data would deadlock.
- //
- var copier = new StreamCopier(bodyStream, outStream,
- null,
- true, true, 8192, true, true);
- copier.asyncCopy(copyObserver, null);
- }
- else
- {
- // finished with the response -- destroy
- response.destroy();
- this._server._endConnection(connection);
- }
- },
-
- // FIELDS
-
- /**
- * This object contains the default handlers for the various HTTP error codes.
- */
- _defaultErrors:
- {
- 400: function(metadata, response)
- {
- // none of the data in metadata is reliable, so hard-code everything here
- response.setStatusLine("1.1", 400, "Bad Request");
- response.setHeader("Content-Type", "text/plain", false);
-
- var body = "Bad request\n";
- response.bodyOutputStream.write(body, body.length);
- },
- 403: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 403, "Forbidden");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>403 Forbidden</title></head>\
- <body>\
- <h1>403 Forbidden</h1>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 404: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 404, "Not Found");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>404 Not Found</title></head>\
- <body>\
- <h1>404 Not Found</h1>\
- <p>\
- <span style='font-family: monospace;'>" +
- htmlEscape(metadata.path) +
- "</span> was not found.\
- </p>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 416: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion,
- 416,
- "Requested Range Not Satisfiable");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head>\
- <title>416 Requested Range Not Satisfiable</title></head>\
- <body>\
- <h1>416 Requested Range Not Satisfiable</h1>\
- <p>The byte range was not valid for the\
- requested resource.\
- </p>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 500: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion,
- 500,
- "Internal Server Error");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>500 Internal Server Error</title></head>\
- <body>\
- <h1>500 Internal Server Error</h1>\
- <p>Something's broken in this server and\
- needs to be fixed.</p>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 501: function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 501, "Not Implemented");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>501 Not Implemented</title></head>\
- <body>\
- <h1>501 Not Implemented</h1>\
- <p>This server is not (yet) Apache.</p>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- },
- 505: function(metadata, response)
- {
- response.setStatusLine("1.1", 505, "HTTP Version Not Supported");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>505 HTTP Version Not Supported</title></head>\
- <body>\
- <h1>505 HTTP Version Not Supported</h1>\
- <p>This server only supports HTTP/1.0 and HTTP/1.1\
- connections.</p>\
- </body>\
- </html>";
- response.bodyOutputStream.write(body, body.length);
- }
- },
-
- /**
- * Contains handlers for the default set of URIs contained in this server.
- */
- _defaultPaths:
- {
- "/": function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/html", false);
-
- var body = "<html>\
- <head><title>httpd.js</title></head>\
- <body>\
- <h1>httpd.js</h1>\
- <p>If you're seeing this page, httpd.js is up and\
- serving requests! Now set a base path and serve some\
- files!</p>\
- </body>\
- </html>";
-
- response.bodyOutputStream.write(body, body.length);
- },
-
- "/trace": function(metadata, response)
- {
- response.setStatusLine(metadata.httpVersion, 200, "OK");
- response.setHeader("Content-Type", "text/plain", false);
-
- var body = "Request-URI: " +
- metadata.scheme + "://" + metadata.host + ":" + metadata.port +
- metadata.path + "\n\n";
- body += "Request (semantically equivalent, slightly reformatted):\n\n";
- body += metadata.method + " " + metadata.path;
-
- if (metadata.queryString)
- body += "?" + metadata.queryString;
-
- body += " HTTP/" + metadata.httpVersion + "\r\n";
-
- var headEnum = metadata.headers;
- while (headEnum.hasMoreElements())
- {
- var fieldName = headEnum.getNext()
- .QueryInterface(Ci.nsISupportsString)
- .data;
- body += fieldName + ": " + metadata.getHeader(fieldName) + "\r\n";
- }
-
- response.bodyOutputStream.write(body, body.length);
- }
- }
-};
-
-
-/**
- * Maps absolute paths to files on the local file system (as nsILocalFiles).
- */
-function FileMap()
-{
- /** Hash which will map paths to nsILocalFiles. */
- this._map = {};
-}
-FileMap.prototype =
-{
- // PUBLIC API
-
- /**
- * Maps key to a clone of the nsILocalFile value if value is non-null;
- * otherwise, removes any extant mapping for key.
- *
- * @param key : string
- * string to which a clone of value is mapped
- * @param value : nsILocalFile
- * the file to map to key, or null to remove a mapping
- */
- put: function(key, value)
- {
- if (value)
- this._map[key] = value.clone();
- else
- delete this._map[key];
- },
-
- /**
- * Returns a clone of the nsILocalFile mapped to key, or null if no such
- * mapping exists.
- *
- * @param key : string
- * key to which the returned file maps
- * @returns nsILocalFile
- * a clone of the mapped file, or null if no mapping exists
- */
- get: function(key)
- {
- var val = this._map[key];
- return val ? val.clone() : null;
- }
-};
-
-
-// Response CONSTANTS
-
-// token = *<any CHAR except CTLs or separators>
-// CHAR = <any US-ASCII character (0-127)>
-// CTL = <any US-ASCII control character (0-31) and DEL (127)>
-// separators = "(" | ")" | "<" | ">" | "@"
-// | "," | ";" | ":" | "\" | <">
-// | "/" | "[" | "]" | "?" | "="
-// | "{" | "}" | SP | HT
-const IS_TOKEN_ARRAY =
- [0, 0, 0, 0, 0, 0, 0, 0, // 0
- 0, 0, 0, 0, 0, 0, 0, 0, // 8
- 0, 0, 0, 0, 0, 0, 0, 0, // 16
- 0, 0, 0, 0, 0, 0, 0, 0, // 24
-
- 0, 1, 0, 1, 1, 1, 1, 1, // 32
- 0, 0, 1, 1, 0, 1, 1, 0, // 40
- 1, 1, 1, 1, 1, 1, 1, 1, // 48
- 1, 1, 0, 0, 0, 0, 0, 0, // 56
-
- 0, 1, 1, 1, 1, 1, 1, 1, // 64
- 1, 1, 1, 1, 1, 1, 1, 1, // 72
- 1, 1, 1, 1, 1, 1, 1, 1, // 80
- 1, 1, 1, 0, 0, 0, 1, 1, // 88
-
- 1, 1, 1, 1, 1, 1, 1, 1, // 96
- 1, 1, 1, 1, 1, 1, 1, 1, // 104
- 1, 1, 1, 1, 1, 1, 1, 1, // 112
- 1, 1, 1, 0, 1, 0, 1]; // 120
-
-
-/**
- * Determines whether the given character code is a CTL.
- *
- * @param code : uint
- * the character code
- * @returns boolean
- * true if code is a CTL, false otherwise
- */
-function isCTL(code)
-{
- return (code >= 0 && code <= 31) || (code == 127);
-}
-
-/**
- * Represents a response to an HTTP request, encapsulating all details of that
- * response. This includes all headers, the HTTP version, status code and
- * explanation, and the entity itself.
- */
-function Response()
-{
- // delegate initialization behavior to .recycle(), for code-sharing;
- // see there for field descriptions as well
- this.recycle();
-}
-Response.prototype =
-{
- // PUBLIC CONSTRUCTION API
-
- //
- // see nsIHttpResponse.bodyOutputStream
- //
- get bodyOutputStream()
- {
- this._ensureAlive();
-
- if (!this._bodyOutputStream && !this._outputProcessed)
- {
- var pipe = new Pipe(false, false, 0, PR_UINT32_MAX, null);
- this._bodyOutputStream = pipe.outputStream;
- this._bodyInputStream = pipe.inputStream;
- }
-
- return this._bodyOutputStream;
- },
-
- //
- // see nsIHttpResponse.write
- //
- write: function(data)
- {
- var dataAsString = String(data);
- this.bodyOutputStream.write(dataAsString, dataAsString.length);
- },
-
- //
- // see nsIHttpResponse.setStatusLine
- //
- setStatusLine: function(httpVersion, code, description)
- {
- this._ensureAlive();
-
- if (!(code >= 0 && code < 1000))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- try
- {
- var httpVer;
- // avoid version construction for the most common cases
- if (!httpVersion || httpVersion == "1.1")
- httpVer = nsHttpVersion.HTTP_1_1;
- else if (httpVersion == "1.0")
- httpVer = nsHttpVersion.HTTP_1_0;
- else
- httpVer = new nsHttpVersion(httpVersion);
- }
- catch (e)
- {
- throw Cr.NS_ERROR_INVALID_ARG;
- }
-
- // Reason-Phrase = *<TEXT, excluding CR, LF>
- // TEXT = <any OCTET except CTLs, but including LWS>
- //
- // XXX this ends up disallowing octets which aren't Unicode, I think -- not
- // much to do if description is IDL'd as string
- if (!description)
- description = "";
- for (var i = 0; i < description.length; i++)
- if (isCTL(description.charCodeAt(i)) && description.charAt(i) != "\t")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // set the values only after validation to preserve atomicity
- this._httpDescription = description;
- this._httpCode = code;
- this._httpVersion = httpVer;
- },
-
- //
- // see nsIHttpResponse.setHeader
- //
- setHeader: function(name, value, merge)
- {
- this._ensureAlive();
-
- this._headers.setHeader(name, value, merge);
- },
-
- // POST-CONSTRUCTION API (not exposed externally)
-
- /**
- * The HTTP version number of this, as a string (e.g. "1.1").
- */
- get httpVersion()
- {
- this._ensureAlive();
- return this._httpVersion.toString();
- },
-
- /**
- * The HTTP status code of this response, as a string of three characters per
- * RFC 2616.
- */
- get httpCode()
- {
- this._ensureAlive();
-
- var codeString = (this._httpCode < 10 ? "0" : "") +
- (this._httpCode < 100 ? "0" : "") +
- this._httpCode;
- return codeString;
- },
-
- /**
- * The description of the HTTP status code of this response, or "" if none is
- * set.
- */
- get httpDescription()
- {
- this._ensureAlive();
-
- return this._httpDescription;
- },
-
- /**
- * The headers in this response, as an nsHttpHeaders object.
- */
- get headers()
- {
- this._ensureAlive();
-
- return this._headers;
- },
-
- //
- // see nsHttpHeaders.getHeader
- //
- getHeader: function(name)
- {
- this._ensureAlive();
-
- return this._headers.getHeader(name);
- },
-
- /**
- * A stream containing the data stored in the body of this response, which is
- * the data written to this.bodyOutputStream. Accessing this property will
- * prevent further writes to bodyOutputStream and will remove that property
- * from this, so the only time this should be accessed should be after this
- * Response has been fully processed by a request handler.
- */
- get bodyInputStream()
- {
- this._ensureAlive();
-
- if (!this._outputProcessed)
- {
- // if nothing was ever written to bodyOutputStream, we never created a
- // pipe -- do so now by writing the empty string to this.bodyOutputStream
- if (!this._bodyOutputStream)
- this.bodyOutputStream.write("", 0);
-
- this._outputProcessed = true;
- }
- if (this._bodyOutputStream)
- {
- this._bodyOutputStream.close(); // flushes buffered data
- this._bodyOutputStream = null; // don't try closing again
- }
- return this._bodyInputStream;
- },
-
- /**
- * Resets this response to its original state, destroying any currently-held
- * resources in the process. Use this method to invalidate an existing
- * response and reuse it later, such as when an arbitrary handler has
- * failed and may have altered the visible state of this (such as by
- * setting headers).
- *
- * This method may be called on Responses which have been .destroy()ed.
- */
- recycle: function()
- {
- if (this._bodyOutputStream)
- {
- this._bodyOutputStream.close();
- this._bodyOutputStream = null;
- }
- if (this._bodyInputStream)
- {
- this._bodyInputStream.close();
- this._bodyInputStream = null;
- }
-
- /**
- * The HTTP version of this response; defaults to 1.1 if not set by the
- * handler.
- */
- this._httpVersion = nsHttpVersion.HTTP_1_1;
-
- /**
- * The HTTP code of this response; defaults to 200.
- */
- this._httpCode = 200;
-
- /**
- * The description of the HTTP code in this response; defaults to "OK".
- */
- this._httpDescription = "OK";
-
- /**
- * An nsIHttpHeaders object in which the headers in this response should be
- * stored.
- */
- this._headers = new nsHttpHeaders();
-
- /**
- * Set to true when this has its .destroy() method called; further actions on
- * this will then fail.
- */
- this._destroyed = false;
-
- /**
- * Flipped when this.bodyOutputStream is closed; prevents the body from being
- * reopened after it has data written to it and has been closed.
- */
- this._outputProcessed = false;
- },
-
- /**
- * Destroys all resources held by this. After this method is called, no other
- * method or property on this must be accessed (except .recycle, which may be
- * used to reuse this Response). Although in many situations resources may be
- * automagically cleaned up, it is highly recommended that this method be
- * called whenever a Response is no longer used, both as a precaution and
- * because this implementation may not always do so.
- *
- * This method is idempotent.
- */
- destroy: function()
- {
- if (this._destroyed)
- return;
-
- if (this._bodyOutputStream)
- {
- this._bodyOutputStream.close();
- this._bodyOutputStream = null;
- }
- if (this._bodyInputStream)
- {
- this._bodyInputStream.close();
- this._bodyInputStream = null;
- }
-
- this._destroyed = true;
- },
-
- // PRIVATE IMPLEMENTATION
-
- /** Ensures that this hasn't had its .destroy() method called. */
- _ensureAlive: function()
- {
- if (this._destroyed)
- throw Cr.NS_ERROR_FAILURE;
- }
-};
-
-
-/**
- * A container for utility functions used with HTTP headers.
- */
-const headerUtils =
-{
- /**
- * Normalizes fieldName (by converting it to lowercase) and ensures it is a
- * valid header field name (although not necessarily one specified in RFC
- * 2616).
- *
- * @throws NS_ERROR_INVALID_ARG
- * if fieldName does not match the field-name production in RFC 2616
- * @returns string
- * fieldName converted to lowercase if it is a valid header, for characters
- * where case conversion is possible
- */
- normalizeFieldName: function(fieldName)
- {
- if (fieldName == "")
- throw Cr.NS_ERROR_INVALID_ARG;
-
- for (var i = 0, sz = fieldName.length; i < sz; i++)
- {
- if (!IS_TOKEN_ARRAY[fieldName.charCodeAt(i)])
- {
- dumpn(fieldName + " is not a valid header field name!");
- throw Cr.NS_ERROR_INVALID_ARG;
- }
- }
-
- return fieldName.toLowerCase();
- },
-
- /**
- * Ensures that fieldValue is a valid header field value (although not
- * necessarily as specified in RFC 2616 if the corresponding field name is
- * part of the HTTP protocol), normalizes the value if it is, and
- * returns the normalized value.
- *
- * @param fieldValue : string
- * a value to be normalized as an HTTP header field value
- * @throws NS_ERROR_INVALID_ARG
- * if fieldValue does not match the field-value production in RFC 2616
- * @returns string
- * fieldValue as a normalized HTTP header field value
- */
- normalizeFieldValue: function(fieldValue)
- {
- // field-value = *( field-content | LWS )
- // field-content = <the OCTETs making up the field-value
- // and consisting of either *TEXT or combinations
- // of token, separators, and quoted-string>
- // TEXT = <any OCTET except CTLs,
- // but including LWS>
- // LWS = [CRLF] 1*( SP | HT )
- //
- // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
- // qdtext = <any TEXT except <">>
- // quoted-pair = "\" CHAR
- // CHAR = <any US-ASCII character (octets 0 - 127)>
-
- // Any LWS that occurs between field-content MAY be replaced with a single
- // SP before interpreting the field value or forwarding the message
- // downstream (section 4.2); we replace 1*LWS with a single SP
- var val = fieldValue.replace(/(?:(?:\r\n)?[ \t]+)+/g, " ");
-
- // remove leading/trailing LWS (which has been converted to SP)
- val = val.replace(/^ +/, "").replace(/ +$/, "");
-
- // that should have taken care of all CTLs, so val should contain no CTLs
- for (var i = 0, len = val.length; i < len; i++)
- if (isCTL(val.charCodeAt(i)))
- throw Cr.NS_ERROR_INVALID_ARG;
-
- // XXX disallows quoted-pair where CHAR is a CTL -- will not invalidly
- // normalize, however, so this can be construed as a tightening of the
- // spec and not entirely as a bug
- return val;
- }
-};
-
-
-
-/**
- * Converts the given string into a string which is safe for use in an HTML
- * context.
- *
- * @param str : string
- * the string to make HTML-safe
- * @returns string
- * an HTML-safe version of str
- */
-function htmlEscape(str)
-{
- // this is naive, but it'll work
- var s = "";
- for (var i = 0; i < str.length; i++)
- s += "&#" + str.charCodeAt(i) + ";";
- return s;
-}
-
-
-/**
- * Constructs an object representing an HTTP version (see section 3.1).
- *
- * @param versionString
- * a string of the form "#.#", where # is an non-negative decimal integer with
- * or without leading zeros
- * @throws
- * if versionString does not specify a valid HTTP version number
- */
-function nsHttpVersion(versionString)
-{
- var matches = /^(\d+)\.(\d+)$/.exec(versionString);
- if (!matches)
- throw "Not a valid HTTP version!";
-
- /** The major version number of this, as a number. */
- this.major = parseInt(matches[1], 10);
-
- /** The minor version number of this, as a number. */
- this.minor = parseInt(matches[2], 10);
-
- if (isNaN(this.major) || isNaN(this.minor) ||
- this.major < 0 || this.minor < 0)
- throw "Not a valid HTTP version!";
-}
-nsHttpVersion.prototype =
-{
- /**
- * Returns the standard string representation of the HTTP version represented
- * by this (e.g., "1.1").
- */
- toString: function ()
- {
- return this.major + "." + this.minor;
- },
-
- /**
- * Returns true if this represents the same HTTP version as otherVersion,
- * false otherwise.
- *
- * @param otherVersion : nsHttpVersion
- * the version to compare against this
- */
- equals: function (otherVersion)
- {
- return this.major == otherVersion.major &&
- this.minor == otherVersion.minor;
- },
-
- /** True if this >= otherVersion, false otherwise. */
- atLeast: function(otherVersion)
- {
- return this.major > otherVersion.major ||
- (this.major == otherVersion.major &&
- this.minor >= otherVersion.minor);
- }
-};
-
-nsHttpVersion.HTTP_1_0 = new nsHttpVersion("1.0");
-nsHttpVersion.HTTP_1_1 = new nsHttpVersion("1.1");
-
-
-/**
- * An object which stores HTTP headers for a request or response.
- *
- * Note that since headers are case-insensitive, this object converts headers to
- * lowercase before storing them. This allows the getHeader and hasHeader
- * methods to work correctly for any case of a header, but it means that the
- * values returned by .enumerator may not be equal case-sensitively to the
- * values passed to setHeader when adding headers to this.
- */
-function nsHttpHeaders()
-{
- /**
- * A hash of headers, with header field names as the keys and header field
- * values as the values. Header field names are case-insensitive, but upon
- * insertion here they are converted to lowercase. Header field values are
- * normalized upon insertion to contain no leading or trailing whitespace.
- *
- * Note also that per RFC 2616, section 4.2, two headers with the same name in
- * a message may be treated as one header with the same field name and a field
- * value consisting of the separate field values joined together with a "," in
- * their original order. This hash stores multiple headers with the same name
- * in this manner.
- */
- this._headers = {};
-}
-nsHttpHeaders.prototype =
-{
- /**
- * Sets the header represented by name and value in this.
- *
- * @param name : string
- * the header name
- * @param value : string
- * the header value
- * @throws NS_ERROR_INVALID_ARG
- * if name or value is not a valid header component
- */
- setHeader: function(fieldName, fieldValue, merge)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
- var value = headerUtils.normalizeFieldValue(fieldValue);
-
- // The following three headers are stored as arrays because their real-world
- // syntax prevents joining individual headers into a single header using
- // ",". See also <http://hg.mozilla.org/mozilla-central/diff/9b2a99adc05e/netwerk/protocol/http/src/nsHttpHeaderArray.cpp#l77>
- if (merge && name in this._headers)
- {
- if (name === "www-authenticate" ||
- name === "proxy-authenticate" ||
- name === "set-cookie")
- {
- this._headers[name].push(value);
- }
- else
- {
- this._headers[name][0] += "," + value;
- NS_ASSERT(this._headers[name].length === 1,
- "how'd a non-special header have multiple values?")
- }
- }
- else
- {
- this._headers[name] = [value];
- }
- },
-
- /**
- * Returns the value for the header specified by this.
- *
- * @throws NS_ERROR_INVALID_ARG
- * if fieldName does not constitute a valid header field name
- * @throws NS_ERROR_NOT_AVAILABLE
- * if the given header does not exist in this
- * @returns string
- * the field value for the given header, possibly with non-semantic changes
- * (i.e., leading/trailing whitespace stripped, whitespace runs replaced
- * with spaces, etc.) at the option of the implementation; multiple
- * instances of the header will be combined with a comma, except for
- * the three headers noted in the description of getHeaderValues
- */
- getHeader: function(fieldName)
- {
- return this.getHeaderValues(fieldName).join("\n");
- },
-
- /**
- * Returns the value for the header specified by fieldName as an array.
- *
- * @throws NS_ERROR_INVALID_ARG
- * if fieldName does not constitute a valid header field name
- * @throws NS_ERROR_NOT_AVAILABLE
- * if the given header does not exist in this
- * @returns [string]
- * an array of all the header values in this for the given
- * header name. Header values will generally be collapsed
- * into a single header by joining all header values together
- * with commas, but certain headers (Proxy-Authenticate,
- * WWW-Authenticate, and Set-Cookie) violate the HTTP spec
- * and cannot be collapsed in this manner. For these headers
- * only, the returned array may contain multiple elements if
- * that header has been added more than once.
- */
- getHeaderValues: function(fieldName)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
-
- if (name in this._headers)
- return this._headers[name];
- else
- throw Cr.NS_ERROR_NOT_AVAILABLE;
- },
-
- /**
- * Returns true if a header with the given field name exists in this, false
- * otherwise.
- *
- * @param fieldName : string
- * the field name whose existence is to be determined in this
- * @throws NS_ERROR_INVALID_ARG
- * if fieldName does not constitute a valid header field name
- * @returns boolean
- * true if the header's present, false otherwise
- */
- hasHeader: function(fieldName)
- {
- var name = headerUtils.normalizeFieldName(fieldName);
- return (name in this._headers);
- },
-
- /**
- * Returns a new enumerator over the field names of the headers in this, as
- * nsISupportsStrings. The names returned will be in lowercase, regardless of
- * how they were input using setHeader (header names are case-insensitive per
- * RFC 2616).
- */
- get enumerator()
- {
- var headers = [];
- for (var i in this._headers)
- {
- var supports = new SupportsString();
- supports.data = i;
- headers.push(supports);
- }
-
- return new nsSimpleEnumerator(headers);
- }
-};
-
-
-/**
- * Constructs an nsISimpleEnumerator for the given array of items.
- *
- * @param items : Array
- * the items, which must all implement nsISupports
- */
-function nsSimpleEnumerator(items)
-{
- this._items = items;
- this._nextIndex = 0;
-}
-nsSimpleEnumerator.prototype =
-{
- hasMoreElements: function()
- {
- return this._nextIndex < this._items.length;
- },
- getNext: function()
- {
- if (!this.hasMoreElements())
- throw Cr.NS_ERROR_NOT_AVAILABLE;
-
- return this._items[this._nextIndex++];
- },
- QueryInterface: function(aIID)
- {
- if (Ci.nsISimpleEnumerator.equals(aIID) ||
- Ci.nsISupports.equals(aIID))
- return this;
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
-};
-
-
-/**
- * A representation of the data in an HTTP request.
- *
- * @param port : uint
- * the port on which the server receiving this request runs
- */
-function Request(port)
-{
- /** Method of this request, e.g. GET or POST. */
- this._method = "";
-
- /** Path of the requested resource; empty paths are converted to '/'. */
- this._path = "";
-
- /** Query string, if any, associated with this request (not including '?'). */
- this._queryString = "";
-
- /** Scheme of requested resource, usually http, always lowercase. */
- this._scheme = "http";
-
- /** Hostname on which the requested resource resides. */
- this._host = undefined;
-
- /** Port number over which the request was received. */
- this._port = port;
-
- var bodyPipe = new Pipe(false, false, 0, PR_UINT32_MAX, null);
-
- /** Stream from which data in this request's body may be read. */
- this._bodyInputStream = bodyPipe.inputStream;
-
- /** Stream to which data in this request's body is written. */
- this._bodyOutputStream = bodyPipe.outputStream;
-
- /**
- * The headers in this request.
- */
- this._headers = new nsHttpHeaders();
-
- /**
- * For the addition of ad-hoc properties and new functionality without having
- * to change nsIHttpRequestMetadata every time; currently lazily created,
- * as its only use is in directory listings.
- */
- this._bag = null;
-}
-Request.prototype =
-{
- // SERVER METADATA
-
- //
- // see nsIHttpRequestMetadata.scheme
- //
- get scheme()
- {
- return this._scheme;
- },
-
- //
- // see nsIHttpRequestMetadata.host
- //
- get host()
- {
- return this._host;
- },
-
- //
- // see nsIHttpRequestMetadata.port
- //
- get port()
- {
- return this._port;
- },
-
- // REQUEST LINE
-
- //
- // see nsIHttpRequestMetadata.method
- //
- get method()
- {
- return this._method;
- },
-
- //
- // see nsIHttpRequestMetadata.httpVersion
- //
- get httpVersion()
- {
- return this._httpVersion.toString();
- },
-
- //
- // see nsIHttpRequestMetadata.path
- //
- get path()
- {
- return this._path;
- },
-
- //
- // see nsIHttpRequestMetadata.queryString
- //
- get queryString()
- {
- return this._queryString;
- },
-
- // HEADERS
-
- //
- // see nsIHttpRequestMetadata.getHeader
- //
- getHeader: function(name)
- {
- return this._headers.getHeader(name);
- },
-
- //
- // see nsIHttpRequestMetadata.hasHeader
- //
- hasHeader: function(name)
- {
- return this._headers.hasHeader(name);
- },
-
- //
- // see nsIHttpRequestMetadata.headers
- //
- get headers()
- {
- return this._headers.enumerator;
- },
-
- //
- // see nsIPropertyBag.enumerator
- //
- get enumerator()
- {
- this._ensurePropertyBag();
- return this._bag.enumerator;
- },
-
- //
- // see nsIHttpRequestMetadata.headers
- //
- get bodyInputStream()
- {
- return this._bodyInputStream;
- },
-
- //
- // see nsIPropertyBag.getProperty
- //
- getProperty: function(name)
- {
- this._ensurePropertyBag();
- return this._bag.getProperty(name);
- },
-
- /** Ensures a property bag has been created for ad-hoc behaviors. */
- _ensurePropertyBag: function()
- {
- if (!this._bag)
- this._bag = new WritablePropertyBag();
- }
-};
-
-
-// XPCOM trappings
-
-/**
- * Creates a factory for instances of an object created using the passed-in
- * constructor.
- */
-function makeFactory(ctor)
-{
- function ci(outer, iid)
- {
- if (outer != null)
- throw Components.results.NS_ERROR_NO_AGGREGATION;
- return (new ctor()).QueryInterface(iid);
- }
-
- return {
- createInstance: ci,
- lockFactory: function(lock) { },
- QueryInterface: function(aIID)
- {
- if (Ci.nsIFactory.equals(aIID) ||
- Ci.nsISupports.equals(aIID))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- }
- };
-}
-
-/** The XPCOM module containing the HTTP server. */
-const module =
-{
- // nsISupports
- QueryInterface: function(aIID)
- {
- if (Ci.nsIModule.equals(aIID) ||
- Ci.nsISupports.equals(aIID))
- return this;
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
- // nsIModule
- registerSelf: function(compMgr, fileSpec, location, type)
- {
- compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
-
- for (var key in this._objects)
- {
- var obj = this._objects[key];
- compMgr.registerFactoryLocation(obj.CID, obj.className, obj.contractID,
- fileSpec, location, type);
- }
- },
- unregisterSelf: function (compMgr, location, type)
- {
- compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
-
- for (var key in this._objects)
- {
- var obj = this._objects[key];
- compMgr.unregisterFactoryLocation(obj.CID, location);
- }
- },
- getClassObject: function(compMgr, cid, iid)
- {
- if (!iid.equals(Ci.nsIFactory))
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-
- for (var key in this._objects)
- {
- if (cid.equals(this._objects[key].CID))
- return this._objects[key].factory;
- }
-
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
- canUnload: function(compMgr)
- {
- return true;
- },
-
- // private implementation
- _objects:
- {
- server:
- {
- CID: Components.ID("{54ef6f81-30af-4b1d-ac55-8ba811293e41}"),
- contractID: "@mozilla.org/server/jshttp;1",
- className: "httpd.js server",
- factory: makeFactory(nsHttpServer)
- }
- }
-};
-
-
-/** NSGetModule, so this code can be used as a JS component. */
-function NSGetModule(compMgr, fileSpec)
-{
- return module;
-}
-
-
-/**
- * Creates a new HTTP server listening for loopback traffic on the given port,
- * starts it, and runs the server until the server processes a shutdown request,
- * spinning an event loop so that events posted by the server's socket are
- * processed.
- *
- * This method is primarily intended for use in running this script from within
- * xpcshell and running a functional HTTP server without having to deal with
- * non-essential details.
- *
- * Note that running multiple servers using variants of this method probably
- * doesn't work, simply due to how the internal event loop is spun and stopped.
- *
- * @note
- * This method only works with Mozilla 1.9 (i.e., Firefox 3 or trunk code);
- * you should use this server as a component in Mozilla 1.8.
- * @param port
- * the port on which the server will run, or -1 if there exists no preference
- * for a specific port; note that attempting to use some values for this
- * parameter (particularly those below 1024) may cause this method to throw or
- * may result in the server being prematurely shut down
- * @param basePath
- * a local directory from which requests will be served (i.e., if this is
- * "/home/jwalden/" then a request to /index.html will load
- * /home/jwalden/index.html); if this is omitted, only the default URLs in
- * this server implementation will be functional
- */
-function server(port, basePath)
-{
- if (basePath)
- {
- var lp = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- lp.initWithPath(basePath);
- }
-
- // if you're running this, you probably want to see debugging info
- DEBUG = true;
-
- var srv = new nsHttpServer();
- if (lp)
- srv.registerDirectory("/", lp);
- srv.registerContentType("sjs", SJS_TYPE);
- srv.identity.setPrimary("http", "localhost", port);
- srv.start(port);
-
- var thread = gThreadManager.currentThread;
- while (!srv.isStopped())
- thread.processNextEvent(true);
-
- // get rid of any pending requests
- while (thread.hasPendingEvents())
- thread.processNextEvent(true);
-
- DEBUG = false;
-}
diff --git a/mochitest/server.js b/mochitest/server.js
deleted file mode 100644
index 5defa9e..0000000
--- a/mochitest/server.js
+++ /dev/null
@@ -1,565 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is MozJSHTTP code.
- *
- * The Initial Developer of the Original Code is
- * Jeff Walden <jwalden+code at mit.edu>.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Robert Sayre <sayrer at gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-// Note that the server script itself already defines Cc, Ci, and Cr for us,
-// and because they're constants it's not safe to redefine them. Scope leakage
-// sucks.
-
-const SERVER_PORT = 8888;
-var server; // for use in the shutdown handler, if necessary
-
-//
-// HTML GENERATION
-//
-var tags = ['A', 'ABBR', 'ACRONYM', 'ADDRESS', 'APPLET', 'AREA', 'B', 'BASE',
- 'BASEFONT', 'BDO', 'BIG', 'BLOCKQUOTE', 'BODY', 'BR', 'BUTTON',
- 'CAPTION', 'CENTER', 'CITE', 'CODE', 'COL', 'COLGROUP', 'DD',
- 'DEL', 'DFN', 'DIR', 'DIV', 'DL', 'DT', 'EM', 'FIELDSET', 'FONT',
- 'FORM', 'FRAME', 'FRAMESET', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6',
- 'HEAD', 'HR', 'HTML', 'I', 'IFRAME', 'IMG', 'INPUT', 'INS',
- 'ISINDEX', 'KBD', 'LABEL', 'LEGEND', 'LI', 'LINK', 'MAP', 'MENU',
- 'META', 'NOFRAMES', 'NOSCRIPT', 'OBJECT', 'OL', 'OPTGROUP',
- 'OPTION', 'P', 'PARAM', 'PRE', 'Q', 'S', 'SAMP', 'SCRIPT',
- 'SELECT', 'SMALL', 'SPAN', 'STRIKE', 'STRONG', 'STYLE', 'SUB',
- 'SUP', 'TABLE', 'TBODY', 'TD', 'TEXTAREA', 'TFOOT', 'TH', 'THEAD',
- 'TITLE', 'TR', 'TT', 'U', 'UL', 'VAR'];
-
-/**
- * Below, we'll use makeTagFunc to create a function for each of the
- * strings in 'tags'. This will allow us to use s-expression like syntax
- * to create HTML.
- */
-function makeTagFunc(tagName)
-{
- return function (attrs /* rest... */)
- {
- var startChildren = 0;
- var response = "";
-
- // write the start tag and attributes
- response += "<" + tagName;
- // if attr is an object, write attributes
- if (attrs && typeof attrs == 'object') {
- startChildren = 1;
- for (var key in attrs) {
- var val = "" + attrs[key];
- response += " " + key + '="' + val.replace('"','"') + '"';
- }
- }
- response += ">";
-
- // iterate through the rest of the args
- for (var i = startChildren; i < arguments.length; i++) {
- if (typeof arguments[i] == 'function') {
- response += arguments[i]();
- } else {
- response += arguments[i];
- }
- }
-
- // write the close tag
- response += "</" + tagName + ">\n";
- return response;
- }
-}
-
-function makeTags() {
- // map our global HTML generation functions
- for each (var tag in tags) {
- this[tag] = makeTagFunc(tag.toLowerCase());
- }
-}
-
-// only run the "main" section if httpd.js was loaded ahead of us
-if (this["nsHttpServer"]) {
- //
- // SCRIPT CODE
- //
- runServer();
-
- // We can only have gotten here if the /server/shutdown path was requested,
- // and we can shut down the xpcshell now that all testing requests have been
- // served.
- quit(0);
-}
-
-var serverBasePath;
-
-//
-// SERVER SETUP
-//
-function runServer()
-{
- serverBasePath = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- var procDir = Cc["@mozilla.org/file/directory_service;1"]
- .getService(Ci.nsIProperties).get("CurProcD", Ci.nsIFile);
- serverBasePath.initWithPath(procDir.parent.parent.path);
- serverBasePath.append("_tests");
- serverBasePath.append("testing");
- serverBasePath.append("mochitest");
-
- server = createMochitestServer(serverBasePath);
- server.start(SERVER_PORT);
-
- // touch a file in the profile directory to indicate we're alive
- var foStream = Cc["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Ci.nsIFileOutputStream);
- var serverAlive = Cc["@mozilla.org/file/local;1"]
- .createInstance(Ci.nsILocalFile);
- serverAlive.initWithFile(serverBasePath);
- serverAlive.append("mochitesttestingprofile");
-
- // If we're running outside of the test harness, there might
- // not be a test profile directory present
- if (serverAlive.exists()) {
- serverAlive.append("server_alive.txt");
- foStream.init(serverAlive,
- 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
- data = "It's alive!";
- foStream.write(data, data.length);
- foStream.close();
- }
-
- makeTags();
-
- //
- // The following is threading magic to spin an event loop -- this has to
- // happen manually in xpcshell for the server to actually work.
- //
- var thread = Cc["@mozilla.org/thread-manager;1"]
- .getService()
- .currentThread;
- while (!server.isStopped())
- thread.processNextEvent(true);
-
- // Server stopped by /server/shutdown handler -- go through pending events
- // and return.
-
- // get rid of any pending requests
- while (thread.hasPendingEvents())
- thread.processNextEvent(true);
-}
-
-/** Creates and returns an HTTP server configured to serve Mochitests. */
-function createMochitestServer(serverBasePath)
-{
- var server = new nsHttpServer();
-
- server.registerDirectory("/", serverBasePath);
- server.registerPathHandler("/server/shutdown", serverShutdown);
- server.registerContentType("sjs", "sjs"); // .sjs == CGI-like functionality
- server.registerContentType("jar", "application/x-jar");
- server.setIndexHandler(defaultDirHandler);
-
- processLocations(server);
-
- return server;
-}
-
-/**
- * Notifies the HTTP server about all the locations at which it might receive
- * requests, so that it can properly respond to requests on any of the hosts it
- * serves.
- */
-function processLocations(server)
-{
- var serverLocations = serverBasePath.clone();
- serverLocations.append("server-locations.txt");
-
- const PR_RDONLY = 0x01;
- var fis = new FileInputStream(serverLocations, PR_RDONLY, 0444,
- Ci.nsIFileInputStream.CLOSE_ON_EOF);
-
- var lis = new ConverterInputStream(fis, "UTF-8", 1024, 0x0);
- lis.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- const LINE_REGEXP =
- new RegExp("^([a-z][-a-z0-9+.]*)" +
- "://" +
- "(" +
- "\\d+\\.\\d+\\.\\d+\\.\\d+" +
- "|" +
- "(?:[a-z0-9](?:[-a-z0-9]*[a-z0-9])?\\.)*" +
- "[a-z](?:[-a-z0-9]*[a-z0-9])?" +
- ")" +
- ":" +
- "(\\d+)" +
- "(?:" +
- "\\s+" +
- "(\\S+(?:,\\S+)*)" +
- ")?$");
-
- var line = {};
- var lineno = 0;
- var seenPrimary = false;
- do
- {
- var more = lis.readLine(line);
- lineno++;
-
- var lineValue = line.value;
- if (lineValue.charAt(0) == "#" || lineValue == "")
- continue;
-
- var match = LINE_REGEXP.exec(lineValue);
- if (!match)
- throw "Syntax error in server-locations.txt, line " + lineno;
-
- var [, scheme, host, port, options] = match;
- if (options)
- {
- if (options.split(",").indexOf("primary") >= 0)
- {
- if (seenPrimary)
- {
- throw "Multiple primary locations in server-locations.txt, " +
- "line " + lineno;
- }
-
- server.identity.setPrimary(scheme, host, port);
- seenPrimary = true;
- continue;
- }
- }
-
- server.identity.add(scheme, host, port);
- }
- while (more);
-}
-
-
-// PATH HANDLERS
-
-// /server/shutdown
-function serverShutdown(metadata, response)
-{
- response.setStatusLine("1.1", 200, "OK");
- response.setHeader("Content-type", "text/plain", false);
-
- var body = "Server shut down.";
- response.bodyOutputStream.write(body, body.length);
-
- // Note: this doesn't disrupt the current request.
- server.stop();
-}
-
-//
-// DIRECTORY LISTINGS
-//
-
-/**
- * Creates a generator that iterates over the contents of
- * an nsIFile directory.
- */
-function dirIter(dir)
-{
- var en = dir.directoryEntries;
- while (en.hasMoreElements()) {
- var file = en.getNext();
- yield file.QueryInterface(Ci.nsILocalFile);
- }
-}
-
-/**
- * Builds an optionally nested object containing links to the
- * files and directories within dir.
- */
-function list(requestPath, directory, recurse)
-{
- var count = 0;
- var path = requestPath;
- if (path.charAt(path.length - 1) != "/") {
- path += "/";
- }
-
- var dir = directory.QueryInterface(Ci.nsIFile);
- var links = {};
-
- // The SimpleTest directory is hidden
- var files = [file for (file in dirIter(dir))
- if (file.exists() && file.path.indexOf("SimpleTest") == -1)];
-
- // Sort files by name, so that tests can be run in a pre-defined order inside
- // a given directory (see bug 384823)
- function leafNameComparator(first, second) {
- if (first.leafName < second.leafName)
- return -1;
- if (first.leafName > second.leafName)
- return 1;
- return 0;
- }
- files.sort(leafNameComparator);
-
- count = files.length;
- for each (var file in files) {
- var key = path + file.leafName;
- var childCount = 0;
- if (file.isDirectory()) {
- key += "/";
- }
- if (recurse && file.isDirectory()) {
- [links[key], childCount] = list(key, file, recurse);
- count += childCount;
- } else {
- if (file.leafName.charAt(0) != '.') {
- links[key] = true;
- }
- }
- }
-
- return [links, count];
-}
-
-/**
- * Heuristic function that determines whether a given path
- * is a test case to be executed in the harness, or just
- * a supporting file.
- */
-function isTest(filename, pattern)
-{
- if (pattern)
- return pattern.test(filename);
-
- return filename.indexOf("test_") > -1 &&
- filename.indexOf(".js") == -1 &&
- filename.indexOf(".css") == -1 &&
- !/\^headers\^$/.test(filename);
-}
-
-/**
- * Transform nested hashtables of paths to nested HTML lists.
- */
-function linksToListItems(links)
-{
- var response = "";
- var children = "";
- for (var link in links) {
- var value = links[link];
- var classVal = (!isTest(link) && !(value instanceof Object))
- ? "non-test invisible"
- : "test";
- if (value instanceof Object) {
- children = UL({class: "testdir"}, linksToListItems(value));
- } else {
- children = "";
- }
-
- var bug_title = link.match(/test_bug\S+/);
- var bug_num = null;
- if (bug_title != null) {
- bug_num = bug_title[0].match(/\d+/);
- }
-
- if ((bug_title == null) || (bug_num == null)) {
- response += LI({class: classVal}, A({href: link}, link), children);
- } else {
- var bug_url = "https://bugzilla.mozilla.org/show_bug.cgi?id="+bug_num;
- response += LI({class: classVal}, A({href: link}, link), " - ", A({href: bug_url}, "Bug "+bug_num), children);
- }
-
- }
- return response;
-}
-
-/**
- * Transform nested hashtables of paths to a flat table rows.
- */
-function linksToTableRows(links)
-{
- var response = "";
- for (var link in links) {
- var value = links[link];
- var classVal = (!isTest(link) && !(value instanceof Object))
- ? "non-test invisible"
- : "";
- if (value instanceof Object) {
- response += TR({class: "dir", id: "tr-" + link },
- TD({colspan: "3"}," "));
- response += linksToTableRows(value);
- } else {
- response += TR({class: classVal, id: "tr-" + link},
- TD("0"), TD("0"), TD("0"));
- }
- }
- return response;
-}
-
-function arrayOfTestFiles(linkArray, fileArray, testPattern) {
- for (var link in linkArray) {
- var value = linkArray[link];
- if (value instanceof Object) {
- arrayOfTestFiles(value, fileArray, testPattern);
- } else if (isTest(link, testPattern)) {
- fileArray.push(link)
- }
- }
-}
-/**
- * Produce a flat array of test file paths to be executed in the harness.
- */
-function jsonArrayOfTestFiles(links)
-{
- var testFiles = [];
- arrayOfTestFiles(links, testFiles);
- testFiles = ['"' + file + '"' for each(file in testFiles)];
- return "[" + testFiles.join(",\n") + "]";
-}
-
-/**
- * Produce a normal directory listing.
- */
-function regularListing(metadata, response)
-{
- var [links, count] = list(metadata.path,
- metadata.getProperty("directory"),
- false);
- response.write(
- HTML(
- HEAD(
- TITLE("mochitest index ", metadata.path)
- ),
- BODY(
- BR(),
- A({href: ".."}, "Up a level"),
- UL(linksToListItems(links))
- )
- )
- );
-}
-
-/**
- * Produce a test harness page containing all the test cases
- * below it, recursively.
- */
-function testListing(metadata, response)
-{
- var [links, count] = list(metadata.path,
- metadata.getProperty("directory"),
- true);
- dumpn("count: " + count);
- var tests = jsonArrayOfTestFiles(links);
- response.write(
- HTML(
- HEAD(
- TITLE("MochiTest | ", metadata.path),
- LINK({rel: "stylesheet",
- type: "text/css", href: "/static/harness.css"}
- ),
- SCRIPT({type: "text/javascript", src: "/MochiKit/packed.js"}),
- SCRIPT({type: "text/javascript",
- src: "/tests/SimpleTest/TestRunner.js"}),
- SCRIPT({type: "text/javascript",
- src: "/tests/SimpleTest/MozillaFileLogger.js"}),
- SCRIPT({type: "text/javascript",
- src: "/tests/SimpleTest/quit.js"}),
- SCRIPT({type: "text/javascript",
- src: "/tests/SimpleTest/setup.js"}),
- SCRIPT({type: "text/javascript"},
- "connect(window, 'onload', hookup); gTestList=" + tests + ";"
- )
- ),
- BODY(
- DIV({class: "container"},
- H2("--> ", A({href: "#", id: "runtests"}, "Run Tests"), " <--"),
- P({style: "float: right;"},
- SMALL(
- "Based on the ",
- A({href:"http://www.mochikit.com/"}, "MochiKit"),
- " unit tests."
- )
- ),
- DIV({class: "status"},
- H1({id: "indicator"}, "Status"),
- H2({id: "pass"}, "Passed: ", SPAN({id: "pass-count"},"0")),
- H2({id: "fail"}, "Failed: ", SPAN({id: "fail-count"},"0")),
- H2({id: "fail"}, "Todo: ", SPAN({id: "todo-count"},"0"))
- ),
- DIV({class: "clear"}),
- DIV({id: "current-test"},
- B("Currently Executing: ",
- SPAN({id: "current-test-path"}, "_")
- )
- ),
- DIV({class: "clear"}),
- DIV({class: "frameholder"},
- IFRAME({scrolling: "no", id: "testframe", width: "500", height: "300"})
- ),
- DIV({class: "clear"}),
- DIV({class: "toggle"},
- A({href: "#", id: "toggleNonTests"}, "Show Non-Tests"),
- BR()
- ),
-
- TABLE({cellpadding: 0, cellspacing: 0, id: "test-table"},
- TR(TD("Passed"), TD("Failed"), TD("Todo"),
- TD({rowspan: count+1},
- UL({class: "top"},
- LI(B("Test Files")),
- linksToListItems(links)
- )
- )
- ),
- linksToTableRows(links)
- ),
- DIV({class: "clear"})
- )
- )
- )
- );
-}
-
-/**
- * Respond to requests that match a file system directory.
- * Under the tests/ directory, return a test harness page.
- */
-function defaultDirHandler(metadata, response)
-{
- response.setStatusLine("1.1", 200, "OK");
- response.setHeader("Content-type", "text/html", false);
- try {
- if (metadata.path.indexOf("/tests") != 0) {
- regularListing(metadata, response);
- } else {
- testListing(metadata, response);
- }
- } catch (ex) {
- response.write(ex);
- }
-}
diff --git a/mochitest/static/harness.css b/mochitest/static/harness.css
deleted file mode 100644
index 3c941ec..0000000
--- a/mochitest/static/harness.css
+++ /dev/null
@@ -1,97 +0,0 @@
-body {
- margin: 0;
- padding: 0;
- font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 11px;
- background-color: #fff;
-}
-
-#xulharness {
- position: fixed;
- top: 30px;
- bottom: 0;
- right: 0px;
- left: 0px;
- overflow:auto;
-}
-
-th, td {
- font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 11px;
- padding-left: .2em;
- padding-right: .2em;
- text-align: left;
- height: 15px;
- margin: 0;
-}
-
-li, li.test, li.dir {
- padding: 0;
- line-height: 15px;
-}
-
-ul {
- list-style: none;
- margin: 0;
- margin-left: 1em;
- padding: 0;
- border: none;
-}
-
-ul.top {
- padding: 0;
- padding-left: 1em;
-}
-
-table#test-table {
- background: #f6f6f6;
- margin-left: 1em;
- padding: 0;
-}
-
-div.container {
- margin: 1em;
-}
-
-a#runtests, a {
- color: #3333cc;
-}
-
-li.non-test a {
- color: #999999;
-}
-
-small a {
- color: #000;
-}
-
-.clear { clear: both;}
-.invisible { display: none;}
-
-div.status {
- min-height: 170px;
- width: 100%;
- border: 1px solid #666;
-}
-div.frameholder {
- min-height: 170px;
- min-width: 500px;
- background-color: #ffffff;
-}
-
-div#current-test {
- margin-top: 1em;
- margin-bottom: 1em;
-}
-
-#indicator {
- color: white;
- background-color: green;
- padding: .5em;
- margin: 0;
-}
-
-#pass, #fail {
- margin: 0;
- padding: .5em;
-}
diff --git a/mochitest/tests/SimpleTest/EventUtils.js b/mochitest/tests/SimpleTest/EventUtils.js
deleted file mode 100644
index deee4cd..0000000
--- a/mochitest/tests/SimpleTest/EventUtils.js
+++ /dev/null
@@ -1,518 +0,0 @@
-/**
- * EventUtils provides some utility methods for creating and sending DOM events.
- * Current methods:
- * sendMouseEvent
- * sendChar
- * sendString
- * sendKey
- */
-
-/**
- * Send a mouse event to the node with id aTarget. The "event" passed in to
- * aEvent is just a JavaScript object with the properties set that the real
- * mouse event object should have. This includes the type of the mouse event.
- * E.g. to send an click event to the node with id 'node' you might do this:
- *
- * sendMouseEvent({type:'click'}, 'node');
- */
-function sendMouseEvent(aEvent, aTarget, aWindow) {
- if (['click', 'mousedown', 'mouseup', 'mouseover', 'mouseout'].indexOf(aEvent.type) == -1) {
- throw new Error("sendMouseEvent doesn't know about event type '"+aEvent.type+"'");
- }
-
- if (!aWindow) {
- aWindow = window;
- }
-
- // For events to trigger the UA's default actions they need to be "trusted"
- netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserWrite');
-
- var event = aWindow.document.createEvent('MouseEvent');
-
- var typeArg = aEvent.type;
- var canBubbleArg = true;
- var cancelableArg = true;
- var viewArg = aWindow;
- var detailArg = aEvent.detail || (aEvent.type == 'click' ||
- aEvent.type == 'mousedown' ||
- aEvent.type == 'mouseup' ? 1 : 0);
- var screenXArg = aEvent.screenX || 0;
- var screenYArg = aEvent.screenY || 0;
- var clientXArg = aEvent.clientX || 0;
- var clientYArg = aEvent.clientY || 0;
- var ctrlKeyArg = aEvent.ctrlKey || false;
- var altKeyArg = aEvent.altKey || false;
- var shiftKeyArg = aEvent.shiftKey || false;
- var metaKeyArg = aEvent.metaKey || false;
- var buttonArg = aEvent.button || 0;
- var relatedTargetArg = aEvent.relatedTarget || null;
-
- event.initMouseEvent(typeArg, canBubbleArg, cancelableArg, viewArg, detailArg,
- screenXArg, screenYArg, clientXArg, clientYArg,
- ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
- buttonArg, relatedTargetArg);
-
- aWindow.document.getElementById(aTarget).dispatchEvent(event);
-}
-
-/**
- * Send the char aChar to the node with id aTarget. If aTarget is not
- * provided, use "target". This method handles casing of chars (sends the
- * right charcode, and sends a shift key for uppercase chars). No other
- * modifiers are handled at this point.
- *
- * For now this method only works for English letters (lower and upper case)
- * and the digits 0-9.
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
- */
-function sendChar(aChar, aTarget) {
- // DOM event charcodes match ASCII (JS charcodes) for a-zA-Z0-9.
- var hasShift = (aChar == aChar.toUpperCase());
- var charCode = aChar.charCodeAt(0);
- var keyCode = charCode;
- if (!hasShift) {
- // For lowercase letters, the keyCode is actually 32 less than the charCode
- keyCode -= 0x20;
- }
-
- return __doEventDispatch(aTarget, charCode, keyCode, hasShift);
-}
-
-/**
- * Send the string aStr to the node with id aTarget. If aTarget is not
- * provided, use "target".
- *
- * For now this method only works for English letters (lower and upper case)
- * and the digits 0-9.
- */
-function sendString(aStr, aTarget) {
- for (var i = 0; i < aStr.length; ++i) {
- sendChar(aStr.charAt(i), aTarget);
- }
-}
-
-/**
- * Send the non-character key aKey to the node with id aTarget. If aTarget is
- * not provided, use "target". The name of the key should be a lowercase
- * version of the part that comes after "DOM_VK_" in the KeyEvent constant
- * name for this key. No modifiers are handled at this point.
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
- */
-function sendKey(aKey, aTarget) {
- keyName = "DOM_VK_" + aKey.toUpperCase();
-
- if (!KeyEvent[keyName]) {
- throw "Unknown key: " + keyName;
- }
-
- return __doEventDispatch(aTarget, 0, KeyEvent[keyName], false);
-}
-
-/**
- * Actually perform event dispatch given a charCode, keyCode, and boolean for
- * whether "shift" was pressed. Send the event to the node with id aTarget. If
- * aTarget is not provided, use "target".
- *
- * Returns true if the keypress event was accepted (no calls to preventDefault
- * or anything like that), false otherwise.
- */
-function __doEventDispatch(aTarget, aCharCode, aKeyCode, aHasShift) {
- if (aTarget === undefined) {
- aTarget = "target";
- }
-
- // Make our events trusted
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-
- var event = document.createEvent("KeyEvents");
- event.initKeyEvent("keydown", true, true, document.defaultView,
- false, false, aHasShift, false,
- aKeyCode, 0);
- var accepted = $(aTarget).dispatchEvent(event);
-
- // Preventing the default keydown action also prevents the default
- // keypress action.
- event = document.createEvent("KeyEvents");
- if (aCharCode) {
- event.initKeyEvent("keypress", true, true, document.defaultView,
- false, false, aHasShift, false,
- 0, aCharCode);
- } else {
- event.initKeyEvent("keypress", true, true, document.defaultView,
- false, false, aHasShift, false,
- aKeyCode, 0);
- }
- if (!accepted) {
- event.preventDefault();
- }
- accepted = $(aTarget).dispatchEvent(event);
-
- // Always send keyup
- var event = document.createEvent("KeyEvents");
- event.initKeyEvent("keyup", true, true, document.defaultView,
- false, false, aHasShift, false,
- aKeyCode, 0);
- $(aTarget).dispatchEvent(event);
- return accepted;
-}
-
-/**
- * Parse the key modifier flags from aEvent. Used to share code between
- * synthesizeMouse and synthesizeKey.
- */
-function _parseModifiers(aEvent)
-{
- const masks = Components.interfaces.nsIDOMNSEvent;
- var mval = 0;
- if (aEvent.shiftKey)
- mval |= masks.SHIFT_MASK;
- if (aEvent.ctrlKey)
- mval |= masks.CONTROL_MASK;
- if (aEvent.altKey)
- mval |= masks.ALT_MASK;
- if (aEvent.metaKey)
- mval |= masks.META_MASK;
- if (aEvent.accelKey)
- mval |= (navigator.platform.indexOf("Mac") >= 0) ? masks.META_MASK :
- masks.CONTROL_MASK;
-
- return mval;
-}
-
-/**
- * Synthesize a mouse event on a target. The actual client point is determined
- * by taking the aTarget's client box and offseting it by aOffsetX and
- * aOffsetY. This allows mouse clicks to be simulated by calling this method.
- *
- * aEvent is an object which may contain the properties:
- * shiftKey, ctrlKey, altKey, metaKey, accessKey, clickCount, button, type
- *
- * If the type is specified, an mouse event of that type is fired. Otherwise,
- * a mousedown followed by a mouse up is performed.
- *
- * aWindow is optional, and defaults to the current window object.
- */
-function synthesizeMouse(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
-{
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
- if (!aWindow)
- aWindow = window;
-
- var utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
- getInterface(Components.interfaces.nsIDOMWindowUtils);
- if (utils) {
- var button = aEvent.button || 0;
- var clickCount = aEvent.clickCount || 1;
- var modifiers = _parseModifiers(aEvent);
-
- var rect = aTarget.getBoundingClientRect();
-
- var left = rect.left + aOffsetX;
- var top = rect.top + aOffsetY;
-
- if (aEvent.type) {
- utils.sendMouseEvent(aEvent.type, left, top, button, clickCount, modifiers);
- }
- else {
- utils.sendMouseEvent("mousedown", left, top, button, clickCount, modifiers);
- utils.sendMouseEvent("mouseup", left, top, button, clickCount, modifiers);
- }
- }
-}
-
-/**
- * Synthesize a mouse scroll event on a target. The actual client point is determined
- * by taking the aTarget's client box and offseting it by aOffsetX and
- * aOffsetY.
- *
- * aEvent is an object which may contain the properties:
- * shiftKey, ctrlKey, altKey, metaKey, accessKey, button, type, axis, delta, hasPixels
- *
- * If the type is specified, a mouse scroll event of that type is fired. Otherwise,
- * "DOMMouseScroll" is used.
- *
- * If the axis is specified, it must be one of "horizontal" or "vertical". If not specified,
- * "vertical" is used.
- *
- * 'delta' is the amount to scroll by (can be positive or negative). It must
- * be specified.
- *
- * 'hasPixels' specifies whether kHasPixels should be set in the scrollFlags.
- *
- * aWindow is optional, and defaults to the current window object.
- */
-function synthesizeMouseScroll(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
-{
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
- if (!aWindow)
- aWindow = window;
-
- var utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
- getInterface(Components.interfaces.nsIDOMWindowUtils);
- if (utils) {
- // See nsMouseScrollFlags in nsGUIEvent.h
- const kIsVertical = 0x02;
- const kIsHorizontal = 0x04;
- const kHasPixels = 0x08;
-
- var button = aEvent.button || 0;
- var modifiers = _parseModifiers(aEvent);
-
- var left = aTarget.boxObject.x;
- var top = aTarget.boxObject.y;
-
- var type = aEvent.type || "DOMMouseScroll";
- var axis = aEvent.axis || "vertical";
- var scrollFlags = (axis == "horizontal") ? kIsHorizontal : kIsVertical;
- if (aEvent.hasPixels) {
- scrollFlags |= kHasPixels;
- }
- utils.sendMouseScrollEvent(type, left + aOffsetX, top + aOffsetY, button,
- scrollFlags, aEvent.delta, modifiers);
- }
-}
-
-/**
- * Synthesize a key event. It is targeted at whatever would be targeted by an
- * actual keypress by the user, typically the focused element.
- *
- * aKey should be either a character or a keycode starting with VK_ such as
- * VK_ENTER.
- *
- * aEvent is an object which may contain the properties:
- * shiftKey, ctrlKey, altKey, metaKey, accessKey, type
- *
- * If the type is specified, a key event of that type is fired. Otherwise,
- * a keydown, a keypress and then a keyup event are fired in sequence.
- *
- * aWindow is optional, and defaults to the current window object.
- */
-function synthesizeKey(aKey, aEvent, aWindow)
-{
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
- if (!aWindow)
- aWindow = window;
-
- var utils = aWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
- getInterface(Components.interfaces.nsIDOMWindowUtils);
- if (utils) {
- var keyCode = 0, charCode = 0;
- if (aKey.indexOf("VK_") == 0)
- keyCode = KeyEvent["DOM_" + aKey];
- else
- charCode = aKey.charCodeAt(0);
-
- var modifiers = _parseModifiers(aEvent);
-
- if (aEvent.type) {
- utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
- }
- else {
- var keyDownDefaultHappened =
- utils.sendKeyEvent("keydown", keyCode, charCode, modifiers);
- utils.sendKeyEvent("keypress", keyCode, charCode, modifiers,
- !keyDownDefaultHappened);
- utils.sendKeyEvent("keyup", keyCode, charCode, modifiers);
- }
- }
-}
-
-var _gSeenEvent = false;
-
-/**
- * Indicate that an event with an original target of aExpectedTarget and
- * a type of aExpectedEvent is expected to be fired, or not expected to
- * be fired.
- */
-function _expectEvent(aExpectedTarget, aExpectedEvent, aTestName)
-{
- if (!aExpectedTarget || !aExpectedEvent)
- return null;
-
- _gSeenEvent = false;
-
- var type = (aExpectedEvent.charAt(0) == "!") ?
- aExpectedEvent.substring(1) : aExpectedEvent;
- var eventHandler = function(event) {
- var epassed = (!_gSeenEvent && event.originalTarget == aExpectedTarget &&
- event.type == type);
- is(epassed, true, aTestName + " " + type + " event target " + (_gSeenEvent ? "twice" : ""));
- _gSeenEvent = true;
- };
-
- aExpectedTarget.addEventListener(type, eventHandler, false);
- return eventHandler;
-}
-
-/**
- * Check if the event was fired or not. The event handler aEventHandler
- * will be removed.
- */
-function _checkExpectedEvent(aExpectedTarget, aExpectedEvent, aEventHandler, aTestName)
-{
- if (aEventHandler) {
- var expectEvent = (aExpectedEvent.charAt(0) != "!");
- var type = expectEvent ? aExpectedEvent : aExpectedEvent.substring(1);
- aExpectedTarget.removeEventListener(type, aEventHandler, false);
- var desc = type + " event";
- if (!expectEvent)
- desc += " not";
- is(_gSeenEvent, expectEvent, aTestName + " " + desc + " fired");
- }
-
- _gSeenEvent = false;
-}
-
-/**
- * Similar to synthesizeMouse except that a test is performed to see if an
- * event is fired at the right target as a result.
- *
- * aExpectedTarget - the expected originalTarget of the event.
- * aExpectedEvent - the expected type of the event, such as 'select'.
- * aTestName - the test name when outputing results
- *
- * To test that an event is not fired, use an expected type preceded by an
- * exclamation mark, such as '!select'. This might be used to test that a
- * click on a disabled element doesn't fire certain events for instance.
- *
- * aWindow is optional, and defaults to the current window object.
- */
-function synthesizeMouseExpectEvent(aTarget, aOffsetX, aOffsetY, aEvent,
- aExpectedTarget, aExpectedEvent, aTestName,
- aWindow)
-{
- var eventHandler = _expectEvent(aExpectedTarget, aExpectedEvent, aTestName);
- synthesizeMouse(aTarget, aOffsetX, aOffsetY, aEvent, aWindow);
- _checkExpectedEvent(aExpectedTarget, aExpectedEvent, eventHandler, aTestName);
-}
-
-/**
- * Similar to synthesizeKey except that a test is performed to see if an
- * event is fired at the right target as a result.
- *
- * aExpectedTarget - the expected originalTarget of the event.
- * aExpectedEvent - the expected type of the event, such as 'select'.
- * aTestName - the test name when outputing results
- *
- * To test that an event is not fired, use an expected type preceded by an
- * exclamation mark, such as '!select'.
- *
- * aWindow is optional, and defaults to the current window object.
- */
-function synthesizeKeyExpectEvent(key, aEvent, aExpectedTarget, aExpectedEvent,
- aTestName, aWindow)
-{
- var eventHandler = _expectEvent(aExpectedTarget, aExpectedEvent, aTestName);
- synthesizeKey(key, aEvent, aWindow);
- _checkExpectedEvent(aExpectedTarget, aExpectedEvent, eventHandler, aTestName);
-}
-
-/**
- * Emulate a dragstart event.
- * element - element to fire the dragstart event on
- * expectedDragData - the data you expect the data transfer to contain afterwards
- * This data is in the format:
- * [ [ "type: data", "type: data" ], ... ]
- * Returns the expected data in the same format if it is not correct. Returns null
- * if successful.
- */
-function synthesizeDragStart(element, expectedDragData)
-{
- var failed = null;
-
- var trapDrag = function(event) {
- try {
- var dataTransfer = event.dataTransfer;
- if (dataTransfer.mozItemCount != expectedDragData.length)
- throw "Failed";
-
- for (var t = 0; t < dataTransfer.mozItemCount; t++) {
- var types = dataTransfer.mozTypesAt(t);
- var expecteditem = expectedDragData[t];
- if (types.length != expecteditem.length)
- throw "Failed";
-
- for (var f = 0; f < types.length; f++) {
- if (types[f] != expecteditem[f].substring(0, types[f].length) ||
- dataTransfer.mozGetDataAt(types[f], t) != expecteditem[f].substring(types[f].length + 2))
- throw "Failed";
- }
- }
- } catch(ex) {
- failed = dataTransfer;
- }
-
- event.preventDefault();
- event.stopPropagation();
- }
-
- window.addEventListener("dragstart", trapDrag, false);
- synthesizeMouse(element, 2, 2, { type: "mousedown" });
- synthesizeMouse(element, 9, 9, { type: "mousemove" });
- synthesizeMouse(element, 10, 10, { type: "mousemove" });
- window.removeEventListener("dragstart", trapDrag, false);
- synthesizeMouse(element, 10, 10, { type: "mouseup" });
-
- return failed;
-}
-
-/**
- * Emulate a drop by firing a dragover, dragexit and a drop event.
- * element - the element to fire the dragover, dragexit and drop events on
- * dragData - the data to supply for the data transfer
- * This data is in the format:
- * [ [ "type: data", "type: data" ], ... ]
- * effectAllowed - the allowed effects that the dragstart event would have set
- *
- * Returns the drop effect that was desired.
- */
-function synthesizeDrop(element, dragData, effectAllowed)
-{
- var dataTransfer;
- var trapDrag = function(event) {
- dataTransfer = event.dataTransfer;
- for (var t = 0; t < dragData.length; t++) {
- var item = dragData[t];
- for (var v = 0; v < item.length; v++) {
- var idx = item[v].indexOf(":");
- dataTransfer.mozSetDataAt(item[v].substring(0, idx), item[v].substring(idx + 2), t);
- }
- }
-
- dataTransfer.dropEffect = "move";
- event.preventDefault();
- event.stopPropagation();
- }
-
- // need to use a real
- window.addEventListener("dragstart", trapDrag, true);
- synthesizeMouse(element, 2, 2, { type: "mousedown" });
- synthesizeMouse(element, 9, 9, { type: "mousemove" });
- synthesizeMouse(element, 10, 10, { type: "mousemove" });
- window.removeEventListener("dragstart", trapDrag, true);
- synthesizeMouse(element, 10, 10, { type: "mouseup" });
-
- var event = document.createEvent("DragEvents");
- event.initDragEvent("dragover", true, true, window, 0, dataTransfer);
- if (element.dispatchEvent(event))
- return "none";
-
- event = document.createEvent("DragEvents");
- event.initDragEvent("dragexit", true, true, window, 0, dataTransfer);
- element.dispatchEvent(event);
-
- if (dataTransfer.dropEffect != "none") {
- event = document.createEvent("DragEvents");
- event.initDragEvent("drop", true, true, window, 0, dataTransfer);
- element.dispatchEvent(event);
- }
-
- return dataTransfer.dropEffect;
-}
diff --git a/mochitest/tests/SimpleTest/MozillaFileLogger.js b/mochitest/tests/SimpleTest/MozillaFileLogger.js
deleted file mode 100644
index 4bc1cff..0000000
--- a/mochitest/tests/SimpleTest/MozillaFileLogger.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * MozillaFileLogger, a log listener that can write to a local file.
- */
-try {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- const FOSTREAM_CID = "@mozilla.org/network/file-output-stream;1";
- const LF_CID = "@mozilla.org/file/local;1";
-
- // File status flags. It is a bitwise OR of the following bit flags.
- // Only one of the first three flags below may be used.
- const PR_READ_ONLY = 0x01; // Open for reading only.
- const PR_WRITE_ONLY = 0x02; // Open for writing only.
- const PR_READ_WRITE = 0x04; // Open for reading and writing.
-
- // If the file does not exist, the file is created.
- // If the file exists, this flag has no effect.
- const PR_CREATE_FILE = 0x08;
-
- // The file pointer is set to the end of the file prior to each write.
- const PR_APPEND = 0x10;
-
- // If the file exists, its length is truncated to 0.
- const PR_TRUNCATE = 0x20;
-
- // If set, each write will wait for both the file data
- // and file status to be physically updated.
- const PR_SYNC = 0x40;
-
- // If the file does not exist, the file is created. If the file already
- // exists, no action and NULL is returned.
- const PR_EXCL = 0x80;
-} catch (ex) {
- // probably not running in the test harness
-}
-
-/** Init the file logger with the absolute path to the file.
- It will create and append if the file already exists **/
-var MozillaFileLogger = {}
-
-MozillaFileLogger.init = function(path) {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- MozillaFileLogger._file = Cc[LF_CID].createInstance(Ci.nsILocalFile);
- MozillaFileLogger._file.initWithPath(path);
- MozillaFileLogger._foStream = Cc[FOSTREAM_CID].createInstance(Ci.nsIFileOutputStream);
- MozillaFileLogger._foStream.init(this._file, PR_WRITE_ONLY | PR_CREATE_FILE | PR_APPEND,
- 0664, 0);
-}
-
-MozillaFileLogger.getLogCallback = function() {
- return function (msg) {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- var data = msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n";
- MozillaFileLogger._foStream.write(data, data.length);
- if (data.indexOf("SimpleTest FINISH") >= 0) {
- MozillaFileLogger.close();
- }
- }
-}
-
-MozillaFileLogger.close = function() {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- MozillaFileLogger._foStream.close();
- MozillaFileLogger._foStream = null;
- MozillaFileLogger._file = null;
-}
diff --git a/mochitest/tests/SimpleTest/SimpleTest.js b/mochitest/tests/SimpleTest/SimpleTest.js
deleted file mode 100644
index 50477f6..0000000
--- a/mochitest/tests/SimpleTest/SimpleTest.js
+++ /dev/null
@@ -1,467 +0,0 @@
-/**
- * SimpleTest, a partial Test.Simple/Test.More API compatible test library.
- *
- * Why?
- *
- * Test.Simple doesn't work on IE < 6.
- * TODO:
- * * Support the Test.Simple API used by MochiKit, to be able to test MochiKit
- * itself against IE 5.5
- *
-**/
-
-if (typeof(SimpleTest) == "undefined") {
- var SimpleTest = {};
-}
-
-var parentRunner = null;
-if (typeof(parent) != "undefined" && parent.TestRunner) {
- parentRunner = parent.TestRunner;
-} else if (parent && parent.wrappedJSObject &&
- parent.wrappedJSObject.TestRunner) {
- parentRunner = parent.wrappedJSObject.TestRunner;
-}
-
-// Check to see if the TestRunner is present and has logging
-if (parentRunner) {
- SimpleTest._logEnabled = parentRunner.logEnabled;
-}
-
-SimpleTest._tests = [];
-SimpleTest._stopOnLoad = true;
-
-/**
- * Something like assert.
-**/
-SimpleTest.ok = function (condition, name, diag) {
- var test = {'result': !!condition, 'name': name, 'diag': diag || ""};
- if (SimpleTest._logEnabled)
- SimpleTest._logResult(test, "TEST-PASS", "TEST-UNEXPECTED-FAIL");
- SimpleTest._tests.push(test);
-};
-
-/**
- * Roughly equivalent to ok(a==b, name)
-**/
-SimpleTest.is = function (a, b, name) {
- var repr = MochiKit.Base.repr;
- SimpleTest.ok(a == b, name, "got " + repr(a) + ", expected " + repr(b));
-};
-
-SimpleTest.isnot = function (a, b, name) {
- var repr = MochiKit.Base.repr;
- SimpleTest.ok(a != b, name, "Didn't expect " + repr(a) + ", but got it.");
-};
-
-// --------------- Test.Builder/Test.More todo() -----------------
-
-SimpleTest.todo = function(condition, name, diag) {
- var test = {'result': !!condition, 'name': name, 'diag': diag || "", todo: true};
- if (SimpleTest._logEnabled)
- SimpleTest._logResult(test, "TEST-UNEXPECTED-PASS", "TEST-KNOWN-FAIL");
- SimpleTest._tests.push(test);
-};
-
-SimpleTest._logResult = function(test, passString, failString) {
- var msg = test.result ? passString : failString;
- msg += " | ";
- if (parentRunner.currentTestURL)
- msg += parentRunner.currentTestURL;
- msg += " | " + test.name;
- var diag = "";
- if (test.diag)
- diag = " - " + test.diag;
- if (test.result) {
- if (test.todo)
- parentRunner.logger.error(msg + diag);
- else
- parentRunner.logger.log(msg);
- } else {
- if (test.todo)
- parentRunner.logger.log(msg);
- else
- parentRunner.logger.error(msg + diag);
- }
-};
-
-/**
- * Copies of is and isnot with the call to ok replaced by a call to todo.
-**/
-
-SimpleTest.todo_is = function (a, b, name) {
- var repr = MochiKit.Base.repr;
- SimpleTest.todo(a == b, name, "got " + repr(a) + ", expected " + repr(b));
-};
-
-SimpleTest.todo_isnot = function (a, b, name) {
- var repr = MochiKit.Base.repr;
- SimpleTest.todo(a != b, name, "Didn't expect " + repr(a) + ", but got it.");
-};
-
-
-/**
- * Makes a test report, returns it as a DIV element.
-**/
-SimpleTest.report = function () {
- var DIV = MochiKit.DOM.DIV;
- var passed = 0;
- var failed = 0;
- var todo = 0;
- var results = MochiKit.Base.map(
- function (test) {
- var cls, msg;
- if (test.todo && !test.result) {
- todo++;
- cls = "test_todo";
- msg = "todo - " + test.name + " " + test.diag;
- } else if (test.result &&!test.todo) {
- passed++;
- cls = "test_ok";
- msg = "ok - " + test.name;
- } else {
- failed++;
- cls = "test_not_ok";
- msg = "not ok - " + test.name + " " + test.diag;
- }
- return DIV({"class": cls}, msg);
- },
- SimpleTest._tests
- );
- var summary_class = ((failed == 0) ? 'all_pass' : 'some_fail');
- return DIV({'class': 'tests_report'},
- DIV({'class': 'tests_summary ' + summary_class},
- DIV({'class': 'tests_passed'}, "Passed: " + passed),
- DIV({'class': 'tests_failed'}, "Failed: " + failed),
- DIV({'class': 'tests_todo'}, "Todo: " + todo)),
- results
- );
-};
-
-/**
- * Toggle element visibility
-**/
-SimpleTest.toggle = function(el) {
- if (MochiKit.Style.computedStyle(el, 'display') == 'block') {
- el.style.display = 'none';
- } else {
- el.style.display = 'block';
- }
-};
-
-/**
- * Toggle visibility for divs with a specific class.
-**/
-SimpleTest.toggleByClass = function (cls, evt) {
- var elems = getElementsByTagAndClassName('div', cls);
- MochiKit.Base.map(SimpleTest.toggle, elems);
- if (evt)
- evt.preventDefault();
-};
-
-/**
- * Shows the report in the browser
-**/
-
-SimpleTest.showReport = function() {
- var togglePassed = A({'href': '#'}, "Toggle passed tests");
- var toggleFailed = A({'href': '#'}, "Toggle failed tests");
- togglePassed.onclick = partial(SimpleTest.toggleByClass, 'test_ok');
- toggleFailed.onclick = partial(SimpleTest.toggleByClass, 'test_not_ok');
- var body = document.body; // Handles HTML documents
- if (!body) {
- // Do the XML thing
- body = document.getElementsByTagNameNS("http://www.w3.org/1999/xhtml",
- "body")[0]
- }
- var firstChild = body.childNodes[0];
- var addNode;
- if (firstChild) {
- addNode = function (el) {
- body.insertBefore(el, firstChild);
- };
- } else {
- addNode = function (el) {
- body.appendChild(el)
- };
- }
- addNode(togglePassed);
- addNode(SPAN(null, " "));
- addNode(toggleFailed);
- addNode(SimpleTest.report());
-};
-
-/**
- * Tells SimpleTest to don't finish the test when the document is loaded,
- * useful for asynchronous tests.
- *
- * When SimpleTest.waitForExplicitFinish is called,
- * explicit SimpleTest.finish() is required.
-**/
-SimpleTest.waitForExplicitFinish = function () {
- SimpleTest._stopOnLoad = false;
-};
-
-/**
- * Executes a function shortly after the call, but lets the caller continue
- * working (or finish).
- */
-SimpleTest.executeSoon = function(aFunc) {
- if ("Components" in window && "classes" in window.Components) {
- netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
- var tm = Components.classes["@mozilla.org/thread-manager;1"]
- .getService(Components.interfaces.nsIThreadManager);
-
- tm.mainThread.dispatch({
- run: function() {
- aFunc();
- }
- }, Components.interfaces.nsIThread.DISPATCH_NORMAL);
- } else {
- setTimeout(aFunc, 0);
- }
-}
-
-/**
- * Talks to the TestRunner if being ran on a iframe and the parent has a
- * TestRunner object.
-**/
-SimpleTest.talkToRunner = function () {
- if (parentRunner) {
- parentRunner.testFinished(document);
- }
-};
-
-/**
- * Finishes the tests. This is automatically called, except when
- * SimpleTest.waitForExplicitFinish() has been invoked.
-**/
-SimpleTest.finish = function () {
- SimpleTest.showReport();
- SimpleTest.talkToRunner();
-};
-
-
-addLoadEvent(function() {
- if (SimpleTest._stopOnLoad) {
- SimpleTest.finish();
- }
-});
-
-// --------------- Test.Builder/Test.More isDeeply() -----------------
-
-
-SimpleTest.DNE = {dne: 'Does not exist'};
-SimpleTest.LF = "\r\n";
-SimpleTest._isRef = function (object) {
- var type = typeof(object);
- return type == 'object' || type == 'function';
-};
-
-
-SimpleTest._deepCheck = function (e1, e2, stack, seen) {
- var ok = false;
- // Either they're both references or both not.
- var sameRef = !(!SimpleTest._isRef(e1) ^ !SimpleTest._isRef(e2));
- if (e1 == null && e2 == null) {
- ok = true;
- } else if (e1 != null ^ e2 != null) {
- ok = false;
- } else if (e1 == SimpleTest.DNE ^ e2 == SimpleTest.DNE) {
- ok = false;
- } else if (sameRef && e1 == e2) {
- // Handles primitives and any variables that reference the same
- // object, including functions.
- ok = true;
- } else if (SimpleTest.isa(e1, 'Array') && SimpleTest.isa(e2, 'Array')) {
- ok = SimpleTest._eqArray(e1, e2, stack, seen);
- } else if (typeof e1 == "object" && typeof e2 == "object") {
- ok = SimpleTest._eqAssoc(e1, e2, stack, seen);
- } else {
- // If we get here, they're not the same (function references must
- // always simply rererence the same function).
- stack.push({ vals: [e1, e2] });
- ok = false;
- }
- return ok;
-};
-
-SimpleTest._eqArray = function (a1, a2, stack, seen) {
- // Return if they're the same object.
- if (a1 == a2) return true;
-
- // JavaScript objects have no unique identifiers, so we have to store
- // references to them all in an array, and then compare the references
- // directly. It's slow, but probably won't be much of an issue in
- // practice. Start by making a local copy of the array to as to avoid
- // confusing a reference seen more than once (such as [a, a]) for a
- // circular reference.
- for (var j = 0; j < seen.length; j++) {
- if (seen[j][0] == a1) {
- return seen[j][1] == a2;
- }
- }
-
- // If we get here, we haven't seen a1 before, so store it with reference
- // to a2.
- seen.push([ a1, a2 ]);
-
- var ok = true;
- // Only examines enumerable attributes. Only works for numeric arrays!
- // Associative arrays return 0. So call _eqAssoc() for them, instead.
- var max = a1.length > a2.length ? a1.length : a2.length;
- if (max == 0) return SimpleTest._eqAssoc(a1, a2, stack, seen);
- for (var i = 0; i < max; i++) {
- var e1 = i > a1.length - 1 ? SimpleTest.DNE : a1[i];
- var e2 = i > a2.length - 1 ? SimpleTest.DNE : a2[i];
- stack.push({ type: 'Array', idx: i, vals: [e1, e2] });
- if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
- stack.pop();
- } else {
- break;
- }
- }
- return ok;
-};
-
-SimpleTest._eqAssoc = function (o1, o2, stack, seen) {
- // Return if they're the same object.
- if (o1 == o2) return true;
-
- // JavaScript objects have no unique identifiers, so we have to store
- // references to them all in an array, and then compare the references
- // directly. It's slow, but probably won't be much of an issue in
- // practice. Start by making a local copy of the array to as to avoid
- // confusing a reference seen more than once (such as [a, a]) for a
- // circular reference.
- seen = seen.slice(0);
- for (var j = 0; j < seen.length; j++) {
- if (seen[j][0] == o1) {
- return seen[j][1] == o2;
- }
- }
-
- // If we get here, we haven't seen o1 before, so store it with reference
- // to o2.
- seen.push([ o1, o2 ]);
-
- // They should be of the same class.
-
- var ok = true;
- // Only examines enumerable attributes.
- var o1Size = 0; for (var i in o1) o1Size++;
- var o2Size = 0; for (var i in o2) o2Size++;
- var bigger = o1Size > o2Size ? o1 : o2;
- for (var i in bigger) {
- var e1 = o1[i] == undefined ? SimpleTest.DNE : o1[i];
- var e2 = o2[i] == undefined ? SimpleTest.DNE : o2[i];
- stack.push({ type: 'Object', idx: i, vals: [e1, e2] });
- if (ok = SimpleTest._deepCheck(e1, e2, stack, seen)) {
- stack.pop();
- } else {
- break;
- }
- }
- return ok;
-};
-
-SimpleTest._formatStack = function (stack) {
- var variable = '$Foo';
- for (var i = 0; i < stack.length; i++) {
- var entry = stack[i];
- var type = entry['type'];
- var idx = entry['idx'];
- if (idx != null) {
- if (/^\d+$/.test(idx)) {
- // Numeric array index.
- variable += '[' + idx + ']';
- } else {
- // Associative array index.
- idx = idx.replace("'", "\\'");
- variable += "['" + idx + "']";
- }
- }
- }
-
- var vals = stack[stack.length-1]['vals'].slice(0, 2);
- var vars = [
- variable.replace('$Foo', 'got'),
- variable.replace('$Foo', 'expected')
- ];
-
- var out = "Structures begin differing at:" + SimpleTest.LF;
- for (var i = 0; i < vals.length; i++) {
- var val = vals[i];
- if (val == null) {
- val = 'undefined';
- } else {
- val == SimpleTest.DNE ? "Does not exist" : "'" + val + "'";
- }
- }
-
- out += vars[0] + ' = ' + vals[0] + SimpleTest.LF;
- out += vars[1] + ' = ' + vals[1] + SimpleTest.LF;
-
- return ' ' + out;
-};
-
-
-SimpleTest.isDeeply = function (it, as, name) {
- var ok;
- // ^ is the XOR operator.
- if (SimpleTest._isRef(it) ^ SimpleTest._isRef(as)) {
- // One's a reference, one isn't.
- ok = false;
- } else if (!SimpleTest._isRef(it) && !SimpleTest._isRef(as)) {
- // Neither is an object.
- ok = SimpleTest.is(it, as, name);
- } else {
- // We have two objects. Do a deep comparison.
- var stack = [], seen = [];
- if ( SimpleTest._deepCheck(it, as, stack, seen)) {
- ok = SimpleTest.ok(true, name);
- } else {
- ok = SimpleTest.ok(false, name, SimpleTest._formatStack(stack));
- }
- }
- return ok;
-};
-
-SimpleTest.typeOf = function (object) {
- var c = Object.prototype.toString.apply(object);
- var name = c.substring(8, c.length - 1);
- if (name != 'Object') return name;
- // It may be a non-core class. Try to extract the class name from
- // the constructor function. This may not work in all implementations.
- if (/function ([^(\s]+)/.test(Function.toString.call(object.constructor))) {
- return RegExp.$1;
- }
- // No idea. :-(
- return name;
-};
-
-SimpleTest.isa = function (object, clas) {
- return SimpleTest.typeOf(object) == clas;
-};
-
-// Global symbols:
-var ok = SimpleTest.ok;
-var is = SimpleTest.is;
-var isnot = SimpleTest.isnot;
-var todo = SimpleTest.todo;
-var todo_is = SimpleTest.todo_is;
-var todo_isnot = SimpleTest.todo_isnot;
-var isDeeply = SimpleTest.isDeeply;
-var oldOnError = window.onerror;
-window.onerror = function (ev) {
- is(0, 1, "Error thrown during test: " + ev);
- if (oldOnError) {
- try {
- oldOnError(ev);
- } catch (e) {
- }
- }
- if (SimpleTest._stopOnLoad == false) {
- // Need to finish() manually here
- SimpleTest.finish();
- }
-}
diff --git a/mochitest/tests/SimpleTest/TestRunner.js b/mochitest/tests/SimpleTest/TestRunner.js
deleted file mode 100644
index f6989c9..0000000
--- a/mochitest/tests/SimpleTest/TestRunner.js
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * TestRunner: A test runner for SimpleTest
- * TODO:
- *
- * * Avoid moving iframes: That causes reloads on mozilla and opera.
- *
- *
-**/
-var TestRunner = {};
-TestRunner.logEnabled = false;
-TestRunner._currentTest = 0;
-TestRunner.currentTestURL = "";
-TestRunner._urls = [];
-
-TestRunner.timeout = 300; // seconds
-TestRunner.maxTimeouts = 4; // halt testing after too many timeouts
-
-/**
- * Make sure the tests don't hang indefinitely.
-**/
-TestRunner._numTimeouts = 0;
-TestRunner._currentTestStartTime = new Date().valueOf();
-
-TestRunner._checkForHangs = function() {
- if (TestRunner._currentTest < TestRunner._urls.length) {
- var runtime = (new Date().valueOf() - TestRunner._currentTestStartTime) / 1000;
- if (runtime >= TestRunner.timeout) {
- var frameWindow = $('testframe').contentWindow.wrappedJSObject ||
- $('testframe').contentWindow;
- frameWindow.SimpleTest.ok(false, "Test timed out.");
-
- // If we have too many timeouts, give up. We don't want to wait hours
- // for results if some bug causes lots of tests to time out.
- if (++TestRunner._numTimeouts >= TestRunner.maxTimeouts) {
- TestRunner._haltTests = true;
- frameWindow.SimpleTest.ok(false, "Too many test timeouts, giving up.");
- }
-
- frameWindow.SimpleTest.finish();
- }
- TestRunner.deferred = callLater(30, TestRunner._checkForHangs);
- }
-}
-
-/**
- * This function is called after generating the summary.
-**/
-TestRunner.onComplete = null;
-
-/**
- * If logEnabled is true, this is the logger that will be used.
-**/
-TestRunner.logger = MochiKit.Logging.logger;
-
-/**
- * Toggle element visibility
-**/
-TestRunner._toggle = function(el) {
- if (el.className == "noshow") {
- el.className = "";
- el.style.cssText = "";
- } else {
- el.className = "noshow";
- el.style.cssText = "width:0px; height:0px; border:0px;";
- }
-};
-
-
-/**
- * Creates the iframe that contains a test
-**/
-TestRunner._makeIframe = function (url, retry) {
- var iframe = $('testframe');
- if (url != "about:blank" &&
- (("hasFocus" in document && !document.hasFocus()) ||
- ("activeElement" in document && document.activeElement != iframe))) {
- // typically calling ourselves from setTimeout is sufficient
- // but we'll try focus() just in case that's needed
- window.focus();
- iframe.focus();
- if (retry < 3) {
- window.setTimeout('TestRunner._makeIframe("'+url+'", '+(retry+1)+')', 1000);
- return;
- }
-
- if (TestRunner.logEnabled) {
- var frameWindow = $('testframe').contentWindow.wrappedJSObject ||
- $('testframe').contentWindow;
- TestRunner.logger.log("Error: Unable to restore focus, expect failures and timeouts.");
- }
- }
- window.scrollTo(0, $('indicator').offsetTop);
- iframe.src = url;
- iframe.name = url;
- iframe.width = "500";
- return iframe;
-};
-
-/**
- * TestRunner entry point.
- *
- * The arguments are the URLs of the test to be ran.
- *
-**/
-TestRunner.runTests = function (/*url...*/) {
- if (TestRunner.logEnabled)
- TestRunner.logger.log("SimpleTest START");
-
- TestRunner._urls = flattenArguments(arguments);
- $('testframe').src="";
- TestRunner._checkForHangs();
- window.focus();
- $('testframe').focus();
- TestRunner.runNextTest();
-};
-
-/**
- * Run the next test. If no test remains, calls makeSummary
-**/
-TestRunner._haltTests = false;
-TestRunner.runNextTest = function() {
- if (TestRunner._currentTest < TestRunner._urls.length &&
- !TestRunner._haltTests) {
- var url = TestRunner._urls[TestRunner._currentTest];
- TestRunner.currentTestURL = url;
-
- $("current-test-path").innerHTML = url;
-
- TestRunner._currentTestStartTime = new Date().valueOf();
-
- if (TestRunner.logEnabled)
- TestRunner.logger.log("Running " + url + "...");
-
- TestRunner._makeIframe(url, 0);
- } else {
- $("current-test").innerHTML = "<b>Finished</b>";
- TestRunner._makeIframe("about:blank", 0);
- if (TestRunner.logEnabled) {
- TestRunner.logger.log("Passed: " + $("pass-count").innerHTML);
- TestRunner.logger.log("Failed: " + $("fail-count").innerHTML);
- TestRunner.logger.log("Todo: " + $("todo-count").innerHTML);
- TestRunner.logger.log("SimpleTest FINISHED");
- }
- if (TestRunner.onComplete)
- TestRunner.onComplete();
- }
-};
-
-/**
- * This stub is called by SimpleTest when a test is finished.
-**/
-TestRunner.testFinished = function(doc) {
- var finishedURL = TestRunner._urls[TestRunner._currentTest];
-
- if (TestRunner.logEnabled)
- TestRunner.logger.debug("SimpleTest finished " + finishedURL);
-
- TestRunner.updateUI();
- TestRunner._currentTest++;
- TestRunner.runNextTest();
-};
-
-/**
- * Get the results.
- */
-TestRunner.countResults = function(doc) {
- var nOK = withDocument(doc,
- partial(getElementsByTagAndClassName, 'div', 'test_ok')
- ).length;
- var nNotOK = withDocument(doc,
- partial(getElementsByTagAndClassName, 'div', 'test_not_ok')
- ).length;
- var nTodo = withDocument(doc,
- partial(getElementsByTagAndClassName, 'div', 'test_todo')
- ).length;
- return {"OK": nOK, "notOK": nNotOK, "todo": nTodo};
-}
-
-TestRunner.updateUI = function() {
- var results = TestRunner.countResults($('testframe').contentDocument);
- var passCount = parseInt($("pass-count").innerHTML) + results.OK;
- var failCount = parseInt($("fail-count").innerHTML) + results.notOK;
- var todoCount = parseInt($("todo-count").innerHTML) + results.todo;
- $("pass-count").innerHTML = passCount;
- $("fail-count").innerHTML = failCount;
- $("todo-count").innerHTML = todoCount;
-
- // Set the top Green/Red bar
- var indicator = $("indicator");
- if (failCount > 0) {
- indicator.innerHTML = "Status: Fail";
- indicator.style.backgroundColor = "red";
- } else if (passCount > 0) {
- indicator.innerHTML = "Status: Pass";
- indicator.style.backgroundColor = "green";
- }
-
- // Set the table values
- var trID = "tr-" + $('current-test-path').innerHTML;
- var row = $(trID);
- replaceChildNodes(row,
- TD({'style':
- {'backgroundColor': results.notOK > 0 ? "#f00":"#0d0"}}, results.OK),
- TD({'style':
- {'backgroundColor': results.notOK > 0 ? "#f00":"#0d0"}}, results.notOK),
- TD({'style': {'backgroundColor':
- results.todo > 0 ? "orange":"#0d0"}}, results.todo)
- );
-}
diff --git a/mochitest/tests/SimpleTest/WindowSnapshot.js b/mochitest/tests/SimpleTest/WindowSnapshot.js
deleted file mode 100644
index 0357e2e..0000000
--- a/mochitest/tests/SimpleTest/WindowSnapshot.js
+++ /dev/null
@@ -1,47 +0,0 @@
-netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
-var gWindowUtils;
-
-try {
- gWindowUtils = window.QueryInterface(CI.nsIInterfaceRequestor).getInterface(CI.nsIDOMWindowUtils);
- if (gWindowUtils && !gWindowUtils.compareCanvases)
- gWindowUtils = null;
-} catch (e) {
- gWindowUtils = null;
-}
-
-function snapshotWindow(win) {
- var el = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
- el.width = win.innerWidth;
- el.height = win.innerHeight;
-
- // drawWindow requires privileges
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
- el.getContext("2d").drawWindow(win, win.scrollX, win.scrollY,
- win.innerWidth, win.innerHeight,
- "rgb(255,255,255)");
- return el;
-}
-
-// If the two snapshots aren't equal, returns their serializations as data URIs.
-function compareSnapshots(s1, s2) {
- netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
-
- var s1Str, s2Str;
- var equal = false;
- if (gWindowUtils) {
- equal = (gWindowUtils.compareCanvases(s1, s2, {}) == 0);
- }
-
- if (!equal) {
- s1Str = s1.toDataURL();
- s2Str = s2.toDataURL();
-
- if (!gWindowUtils) {
- equal = (s1Str == s2Str);
- }
- }
-
- return [equal, s1Str, s2Str];
-}
diff --git a/mochitest/tests/SimpleTest/quit.js b/mochitest/tests/SimpleTest/quit.js
deleted file mode 100644
index 360ba2d..0000000
--- a/mochitest/tests/SimpleTest/quit.js
+++ /dev/null
@@ -1,136 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Automated Testing Code.
- *
- * The Initial Developer of the Original Code is
- * Mozilla Corporation.
- * Portions created by the Initial Developer are Copyright (C) 2005
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Bob Clary <bob at bclary.com>
- * Jeff Walden <jwalden+code at mit.edu>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/*
- From mozilla/toolkit/content
- These files did not have a license
-*/
-
-function quitHook()
-{
- var xhr = new XMLHttpRequest();
- xhr.open("GET", "http://" + location.host + "/server/shutdown", true);
- xhr.onreadystatechange = function (event)
- {
- if (xhr.readyState == 4)
- goQuitApplication();
- };
- xhr.send(null);
-}
-
-function canQuitApplication()
-{
- var os = Components.classes["@mozilla.org/observer-service;1"]
- .getService(Components.interfaces.nsIObserverService);
- if (!os)
- {
- return true;
- }
-
- try
- {
- var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"]
- .createInstance(Components.interfaces.nsISupportsPRBool);
- os.notifyObservers(cancelQuit, "quit-application-requested", null);
-
- // Something aborted the quit process.
- if (cancelQuit.data)
- {
- return false;
- }
- }
- catch (ex)
- {
- }
- return true;
-}
-
-function goQuitApplication()
-{
- const privs = 'UniversalXPConnect';
-
- try
- {
- netscape.security.PrivilegeManager.enablePrivilege(privs);
- }
- catch(ex)
- {
- throw('goQuitApplication: privilege failure ' + ex);
- }
-
- if (!canQuitApplication())
- {
- return false;
- }
-
- const kAppStartup = '@mozilla.org/toolkit/app-startup;1';
- const kAppShell = '@mozilla.org/appshell/appShellService;1';
- var appService;
- var forceQuit;
-
- if (kAppStartup in Components.classes)
- {
- appService = Components.classes[kAppStartup].
- getService(Components.interfaces.nsIAppStartup);
- forceQuit = Components.interfaces.nsIAppStartup.eForceQuit;
-
- }
- else if (kAppShell in Components.classes)
- {
- appService = Components.classes[kAppShell].
- getService(Components.interfaces.nsIAppShellService);
- forceQuit = Components.interfaces.nsIAppShellService.eForceQuit;
- }
- else
- {
- throw 'goQuitApplication: no AppStartup/appShell';
- }
-
- try
- {
- appService.quit(forceQuit);
- }
- catch(ex)
- {
- throw('goQuitApplication: ' + ex);
- }
-
- return true;
-}
-
diff --git a/mochitest/tests/SimpleTest/setup.js b/mochitest/tests/SimpleTest/setup.js
deleted file mode 100644
index 5667c85..0000000
--- a/mochitest/tests/SimpleTest/setup.js
+++ /dev/null
@@ -1,128 +0,0 @@
-/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is mozilla.org code.
- *
- * The Initial Developer of the Original Code is Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- * Robert Sayre <sayrer at gmail.com>
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-TestRunner.logEnabled = true;
-TestRunner.logger = new Logger();
-
-// Check the query string for arguments
-var params = parseQueryString(location.search.substring(1), true);
-
-// log levels for console and logfile
-var fileLevel = params.fileLevel || null;
-var consoleLevel = params.consoleLevel || null;
-
-// closeWhenDone tells us to call quit.js when complete
-if (params.closeWhenDone) {
- TestRunner.onComplete = goQuitApplication;
-}
-
-// logFile to write our results
-if (params.logFile) {
- MozillaFileLogger.init(params.logFile);
- TestRunner.logger.addListener("mozLogger", fileLevel + "", MozillaFileLogger.getLogCallback());
-}
-
-// if we get a quiet param, don't log to the console
-if (!params.quiet) {
- function dumpListener(msg) {
- dump("*** " + msg.num + " " + msg.level + " " + msg.info.join(' ') + "\n");
- }
- TestRunner.logger.addListener("dumpListener", consoleLevel + "", dumpListener);
-}
-
-var gTestList = [];
-var RunSet = {}
-RunSet.runall = function(e) {
- TestRunner.runTests(gTestList);
-}
-RunSet.reloadAndRunAll = function(e) {
- e.preventDefault();
- //window.location.hash = "";
- var addParam = "";
- if (params.autorun) {
- window.location.search += "";
- window.location.href = window.location.href;
- } else if (window.location.search) {
- window.location.href += "&autorun=1";
- } else {
- window.location.href += "?autorun=1";
- }
-
-};
-
-// UI Stuff
-function toggleVisible(elem) {
- toggleElementClass("invisible", elem);
-}
-
-function makeVisible(elem) {
- removeElementClass(elem, "invisible");
-}
-
-function makeInvisible(elem) {
- addElementClass(elem, "invisible");
-}
-
-function isVisible(elem) {
- // you may also want to check for
- // getElement(elem).style.display == "none"
- return !hasElementClass(elem, "invisible");
-};
-
-function toggleNonTests (e) {
- e.preventDefault();
- var elems = getElementsByTagAndClassName("*", "non-test");
- for (var i="0"; i<elems.length; i++) {
- toggleVisible(elems[i]);
- }
- if (isVisible(elems[0])) {
- $("toggleNonTests").innerHTML = "Hide Non-Tests";
- } else {
- $("toggleNonTests").innerHTML = "Show Non-Tests";
- }
-}
-
-// hook up our buttons
-function hookup() {
- connect("runtests", "onclick", RunSet, "reloadAndRunAll");
- connect("toggleNonTests", "onclick", toggleNonTests);
- // run automatically if
- if (params.autorun) {
- RunSet.runall();
- }
-}
diff --git a/mochitest/tests/SimpleTest/test.css b/mochitest/tests/SimpleTest/test.css
deleted file mode 100644
index d5866ab..0000000
--- a/mochitest/tests/SimpleTest/test.css
+++ /dev/null
@@ -1,29 +0,0 @@
-.test_ok {
- color: green;
- display: none;
-}
-.test_not_ok {
- color: red;
- display: block;
-}
-
-.test_ok, .test_not_ok {
- border-bottom-width: 2px;
- border-bottom-style: solid;
- border-bottom-color: black;
-}
-
-.all_pass {
- background-color: lime;
-}
-
-.some_fail {
- background-color: red;
-}
-
-.tests_report {
- border-width: 2px;
- border-style: solid;
- width: 20em;
- display: table;
-}
diff --git a/mochitest/tests/common.js b/mochitest/tests/common.js
deleted file mode 100644
index f2f9999..0000000
--- a/mochitest/tests/common.js
+++ /dev/null
@@ -1,209 +0,0 @@
-if (typeof Cc == "undefined")
- eval("const Cc = Components.classes");
-if (typeof Ci == "undefined")
- eval("const Ci = Components.interfaces");
-if (typeof Cr == "undefined")
- eval("const Cr = Components.results");
-if (typeof Cu == "undefined")
- eval("const Cu = Components.utils");
-
-let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
-
-var geckoVersion = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).platformVersion;
-function compareGeckoVersion(version)
-{
- Cu.import(baseURL.spec + "Utils.jsm");
- return Utils.versionComparator.compare(geckoVersion, version);
-}
-
-function prepareFilterComponents(keepObservers)
-{
- Cu.import(baseURL.spec + "FilterClasses.jsm");
- Cu.import(baseURL.spec + "SubscriptionClasses.jsm");
- window.FilterStorageGlobal = Cu.import(baseURL.spec + "FilterStorage.jsm");
- Cu.import(baseURL.spec + "Matcher.jsm");
- window.ElemHideGlobal = Cu.import(baseURL.spec + "ElemHide.jsm");
- Cu.import(baseURL.spec + "FilterListener.jsm");
-
- let oldSubscriptions = FilterStorage.subscriptions;
- let oldStorageKnown = FilterStorage.knownSubscriptions;
- let oldSubscriptionsKnown = Subscription.knownSubscriptions;
- let oldFiltersKnown = Filter.knownFilters;
- let oldObservers = FilterStorageGlobal.observers;
- let oldSourceFile = FilterStorage.__lookupGetter__("sourceFile");
-
- FilterStorage.subscriptions = [];
- FilterStorage.knownSubscriptions = {__proto__: null};
- Subscription.knownSubscriptions = {__proto__: null};
- Filter.knownFilters = {__proto__: null};
- if (!keepObservers)
- {
- FilterStorageGlobal.observers = [];
- }
-
- defaultMatcher.clear();
- ElemHide.clear();
-
- window.addEventListener("unload", function()
- {
- FilterStorage.subscriptions = oldSubscriptions;
- FilterStorage.knownSubscriptions = oldStorageKnown;
- Subscription.knownSubscriptions = oldSubscriptionsKnown;
- Filter.knownFilters = oldFiltersKnown;
- FilterStorageGlobal.observers = oldObservers;
- FilterStorage.__defineGetter__("sourceFile", oldSourceFile);
-
- FilterStorage.triggerObservers("load");
- }, false);
-
- try
- {
- // Disable timeline functions, they slow down tests otherwise
- Cu.import(baseURL.spec + "TimeLine.jsm");
-
- let oldTimelineLog = TimeLine.log;
- let oldTimelineEnter = TimeLine.enter;
- let oldTimelineLeave = TimeLine.leave;
-
- TimeLine.log = function(){};
- TimeLine.enter = function(){};
- TimeLine.leave = function(){};
-
- window.addEventListener("unload", function()
- {
- TimeLine.log = oldTimelineLog;
- TimeLine.enter = oldTimelineEnter;
- TimeLine.leave = oldTimelineLeave;
- }, false);
- }
- catch(e)
- {
- // TimeLine module might not be present, catch exceptions
- alert(e);
- }
-}
-
-function preparePrefs()
-{
- Cu.import(baseURL.spec + "Prefs.jsm");
-
- let backup = {__proto__: null};
- let getters = {__proto__: null}
- for (let pref in Prefs)
- {
- if (Prefs.__lookupSetter__(pref))
- backup[pref] = Prefs[pref];
- else if (Prefs.__lookupGetter__(pref))
- getters[pref] = Prefs.__lookupGetter__(pref);
- }
- Prefs.enabled = true;
-
- window.addEventListener("unload", function()
- {
- for (let pref in backup)
- Prefs[pref] = backup[pref];
- for (let pref in getters)
- Prefs.__defineGetter__(pref, getters[pref]);
- }, false);
-}
-
-function showProfilingData(debuggerService)
-{
- let scripts = [];
- debuggerService.enumerateScripts({
- enumerateScript: function(script)
- {
- scripts.push(script);
- }
- });
- scripts = scripts.filter(function(script)
- {
- return script.fileName.indexOf("chrome://adblockplus/") == 0 && script.callCount > 0;
- });
- scripts.sort(function(a, b)
- {
- return b.totalOwnExecutionTime - a.totalOwnExecutionTime;
- });
-
- let table = document.createElement("table");
- table.setAttribute("border", "border");
-
- let header = table.insertRow(-1);
- header.style.fontWeight = "bold";
- header.insertCell(-1).textContent = "Function name";
- header.insertCell(-1).textContent = "Call count";
- header.insertCell(-1).textContent = "Min execution time (total/own)";
- header.insertCell(-1).textContent = "Max execution time (total/own)";
- header.insertCell(-1).textContent = "Total execution time (total/own)";
-
- for each (let script in scripts)
- showProfilingDataForScript(script, table);
-
- document.getElementById("display").appendChild(table);
-}
-
-function showProfilingDataForScript(script, table)
-{
- let functionName = script.functionName;
- if (functionName == "anonymous")
- functionName = guessFunctionName(script.fileName, script.baseLineNumber);
-
- let row = table.insertRow(-1);
- row.insertCell(-1).innerHTML = functionName + "<br/>\n" + script.fileName.replace("chrome://adblockplus/", "") + ":" + script.baseLineNumber;
- row.insertCell(-1).textContent = script.callCount;
- row.insertCell(-1).textContent = script.minExecutionTime.toFixed(2) + "/" + script.minOwnExecutionTime.toFixed(2);
- row.insertCell(-1).textContent = script.maxExecutionTime.toFixed(2) + "/" + script.maxOwnExecutionTime.toFixed(2);
- row.insertCell(-1).textContent = script.totalExecutionTime.toFixed(2) + "/" + script.totalOwnExecutionTime.toFixed(2);
-}
-
-let fileCache = {};
-function guessFunctionName(fileName, lineNumber)
-{
- if (!(fileName in fileCache))
- {
- try
- {
- let request = new XMLHttpRequest();
- request.open("GET", fileName, false);
- request.overrideMimeType("text/plain");
- request.send(null);
- fileCache[fileName] = request.responseText.split(/\n/);
- }
- catch (e)
- {
- return "anonymous";
- }
- }
-
- let data = fileCache[fileName];
-
- lineNumber--;
- if (lineNumber >= 0 && lineNumber < data.length && /(\w+)\s*[:=]\s*function/.test(data[lineNumber]))
- return RegExp.$1;
-
- lineNumber--;
- if (lineNumber >= 0 && lineNumber < data.length && /(\w+)\s*[:=]\s*function/.test(data[lineNumber]))
- return RegExp.$1;
-
- return "anonymous";
-}
-
-if (/[?&]profiler/i.test(location.href))
-{
- let debuggerService = Cc["@mozilla.org/js/jsd/debugger-service;1"].getService(Ci.jsdIDebuggerService);
-
- let oldFinish = SimpleTest.finish;
- SimpleTest.finish = function()
- {
- showProfilingData(debuggerService);
- debuggerService.off();
- return oldFinish.apply(this, arguments);
- }
- window.addEventListener("unload", function()
- {
- debuggerService.off();
- }, true);
- debuggerService.on();
- debuggerService.flags |= debuggerService.COLLECT_PROFILE_DATA;
- debuggerService.clearProfileData();
-}
diff --git a/mochitest/tests/performance/common.js b/mochitest/tests/performance/common.js
deleted file mode 100644
index 6347a32..0000000
--- a/mochitest/tests/performance/common.js
+++ /dev/null
@@ -1,62 +0,0 @@
-function runTests(testFunc, cleanupFunc, finalizeFunc)
-{
- const minRuns = 15;
- const maxRuns = 400;
- const targetConfidenceInterval = 0.04;
-
- let currentRun = 0;
- let results = [];
- function runNextTest()
- {
- currentRun++;
-
- if (currentRun > minRuns)
- {
- let [avg, interval] = getConfidenceInterval(results);
-
- if (currentRun > maxRuns || interval <= avg * targetConfidenceInterval)
- {
- let text = "Average time: " + avg.toFixed(1) + " ms +/- " + interval.toFixed(1) + " ms (95% confidence)\n\n";
- for (let i = 0; i < results.length; i++)
- text += "Run no. " + (i + 1) + ": " + results[i] + " ms\n";
-
- document.getElementById("result").textContent = text;
- if (typeof finalizeFunc == "function")
- finalizeFunc();
- return;
- }
- }
-
- // Make sure garbage collection doesn't run during the test
- Components.utils.forceGC();
-
- let startTime = Date.now();
- testFunc();
- let endTime = Date.now();
- results.push(endTime - startTime);
-
- if (cleanupFunc)
- cleanupFunc();
-
- setTimeout(runNextTest, 0);
- }
-
- setTimeout(runNextTest, 0);
-}
-
-function getConfidenceInterval(results)
-{
- let sum = 0;
- let sqrsum = 0;
-
- for each (let result in results)
- {
- sum += result;
- sqrsum += result * result;
- }
-
- let avg = sum / results.length;
- let stddev = Math.sqrt((sqrsum - 2 * sum * avg + avg * avg * results.length) / results.length);
- let confidence = 1.96 * stddev; // 95% confidence, assuming Gaussian distribution
- return [avg, stddev];
-}
diff --git a/mochitest/tests/performance/data/addresses.txt b/mochitest/tests/performance/data/addresses.txt
deleted file mode 100644
index 8661610..0000000
--- a/mochitest/tests/performance/data/addresses.txt
+++ /dev/null
@@ -1,761 +0,0 @@
-http://a.analytics.yahoo.com/p.pl?a=1000116666777&sid=3788ead&j=1366x768&flv=WIN+10%2C0%2C45
-http://ad-emea.doubleclick.net/ad/N4137.yahoo.de/B4316546.2;sz=1x1;ai=609911305;si=102;ord=1269329333?
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedes300x250.jpg
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedes300x2501.swf
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedes400x60.gif
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedes400x60.swf
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedesexpand.swf
-http://ads.yimg.com/ev/de/hp/mercedes/20100323mercedeswallpaperwide2.jpg
-http://ads.yimg.com/ev/de/hp/mercedes/yadbg4.js
-http://ads.yimg.com/ev/eu/any/pixel4.gif
-http://ads.yimg.com/ev/eu/any/yad20100215min.js
-http://cdn1.eyewonder.com/200125/762024/1248338/ewtrack.gif?ewbust=1269329333
-http://d.yimg.com/a/i/ww/met/gsprite_20100208.png
-http://d.yimg.com/a/i/ww/met/pa_icons/ans_22_041609.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/brig_22_080609.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/facebook_22_063009.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/flickr_22_041609.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/heiseonline_22_072709.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/horoscopes_22_041609.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/kelkoo_22_061809.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/personals_22_041609.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/stern_22_092809.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/tb_22_042009.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/travel_22_063009.gif
-http://d.yimg.com/a/i/ww/met/pa_icons/uk_pa_sprite_063009.png
-http://d.yimg.com/a/i/ww/met/sprite_pg_20100125.png
-http://d.yimg.com/a/i/ww/met/sprite_pg_nontheme_20100125.png
-http://d.yimg.com/a/i/ww/met/sprite_videoicon_20100201.png
-http://d.yimg.com/a/i/ww/met/th/slate/gsprite_pg_slate_20100129.gif
-http://d.yimg.com/a/i/ww/met/th/slate/sprite_masthead_slate_srchbt2_07242009.png
-http://d.yimg.com/a/i/ww/met/th/slate/sprite_pg_slate_20100126.png
-http://l.yimg.com/a/a/1-/flash/promotions/de/intl/100225/50x50mpl.gif
-http://l.yimg.com/a/combo?arc/yui/reset_2.6.5.css&arc/yui/fonts_2.6.4.css&metro/uiplugins/generic_0.1.9.css&metro/error/error_0.1.12.css&metro/fp/fp_zindex_0.0.24.css&metro/fp/fp_0.1.85.css&metro/navbar/navbar_0.1.83.css&metro/navbar/navbar_pageoptions_0.0.21.css&metro/marketindices/marketindices_0.1.33.css&metro/miniad/promoads_0.1.6.css&metro/uiplugins/tablist_service_0.1.6.css&metro/uiplugins/iframeshim_service_0.0.4.css&metro/uiplugins/ulm_service_0.1.8.css&metro/uiplugins/ulm_default_0.1.16.css&metro/uiplugins/tablist_news_0.0.14.css&metro/news/news_0.1.73.css&metro/specialevents/specialevents_0.0.21.css&metro/sda/sda_0.1.22.css&metro/subfooter/subfooter_0.0.6.css&metro/breakingnews/breakingnews_0.0.13.css&metro/uiplugins/carousel_service_0.1.6.css&metro/fptoday/fptoday_0.1.121.css&metro/uiplugins/carousel_default_0.1.11.css&metro/tuc/tuc_common_0.0.24.css&metro/tuc/tuc_embedded_0.0.15.css&metro/masthead/masthead_0.2.63.css&metro/contentcarousel/contentcarousel_0.1.81.css&metro/contentcarousel/contentcarousel_topten_0.1.69.css&metro/contentcarousel/pulse_0.1.60.css&metro/contentcarousel/slideshow1_0.1.24.css&metro/contentcarousel/shopping_0.1.19.css&metro/contentcarousel/contentcarousel_4_0.1.8.css&metro/footer/footer_0.1.53.css&metro/pa/pa_flash_0.1.2.css&metro/pa/pa_0.1.163.css&metro/pa/pa_detached_0.1.69.css&metro/uiplugins/tooltip_default_0.1.14.css&metro/pa/pa_edit_service_0.1.29.css&metro/contentcarousel/contentcarousel_3_0.1.9.css&metro/uiplugins/windowshade_service_0.0.13.css&metro/ipredirect/ipredirect_0.0.6.css
-http://l.yimg.com/a/combo?arc/yui/substitute_0.1.9.js&arc/yui/oop_0.1.10.js&arc/yui/event-custom_0.1.5.js&arc/yui/io-base_0.1.10.js&arc/yui/dom_0.1.10.js&arc/yui/event-base_0.1.4.js&arc/yui/attribute_0.1.11.js&arc/yui/base-base_0.1.10.js&arc/yui/pluginhost_0.1.4.js&arc/yui/node_0.1.25.js&arc/yui/json_0.1.13.js&arc/yui/anim-base_0.1.9.js&arc/yui/anim-easing_0.1.9.js&arc/yui/anim-node-plugin_0.1.8.js&arc/yui/cookie_0.1.9.js&arc/yui/yuidef_0.1.9.js&arc/framework/module_platform_0.1.50.js&arc/framework/resourcemgr_0.1.14.js&metro2/dali/dali_transport_1.1.26.js&arc/framework/module_api_0.1.12.js&metro2/dali/metro_dali_1.0.18.js&metro/uiplugins/userinfo_service_0.1.7.js&metro/uiplugins/metro_viewtype_0.1.14.js&metro/uiplugins/default_viewtype_0.1.50.js&metro/uiplugins/edit_viewtype_0.1.31.js&metro/uiplugins/pa_viewtype_0.1.5.js&arc/util/ylc_1.8.17.js&metro/uiplugins/instrumentation_service_0.1.11.js&metro/uiplugins/metrologger_service_0.1.10.js&metro/sda/sda_bridge_service_0.0.5.js&metro/fp/fp_0.1.60.js&metro/uiplugins/metrics_service_0.1.5.js&metro/uiplugins/metro_performance_0.1.7.js&arc/framework/yui_service_0.1.11.js&metro/uiplugins/autohide_service_0.1.9.js&metro/uiplugins/statemgr_service_0.1.11.js&metro/navbar/navbar_0.1.75.js&metro/marketindices/marketindices_0.1.17.js&metro/uiplugins/aria_service_0.1.12.js&metro/uiplugins/tablist_service_0.1.29.js&metro/uiplugins/iframeshim_service_0.0.12.js&metro/uiplugins/ulm_service_0.1.31.js&metro/news/news_0.1.40.js&metro/sda/sda_deferred_service_0.0.13.js&metro/sda/sda_transport_0.0.9.js&metro/sda/sda_0.1.36.js&metro/uiplugins/carousel_service_0.1.37.js&metro/fptoday/fptoday_hover_0.1.53.js&metro/tuc/tuc_0.0.24.js&metro/masthead/masthead_0.2.114.js&metro/contentcarousel/contentcarousel_0.1.38.js&metro/contentcarousel/contentcarouselslideshow1_0.1.13.js&metro/uiplugins/toolbar_bridge_service_0.1.17.js&metro/uiplugins/tooltip_service_0.1.32.js&metro/pa/pa_0.1.187.js&metro/uiplugins/windowshade_service_0.0.12.js&metro/ipredirect/ipredirect_0.0.8.js
-http://l.yimg.com/a/combo?arc/yui/yui_0.2.4.js
-http://l.yimg.com/a/i/ww/met/mod/ybang_22_111908.png
-http://l.yimg.com/a/i/ww/met/sprite_ip_redirect_052109.gif
-http://l.yimg.com/a/i/ww/met/yahoo_logo_de_061509.png
-http://l.yimg.com/a/lib/metro/apppromo/apppromo_0.0.12.css
-http://l.yimg.com/a/lib/metro/autoapp/autoapp_0.0.36.css
-http://l.yimg.com/a/lib/metro/autoapp/autoapp_0.0.42.js
-http://l.yimg.com/a/lib/metro/ebay/ebay_0.1.25.css
-http://l.yimg.com/a/lib/metro/ebay/ebay_0.1.31.js
-http://l.yimg.com/a/lib/metro/facebook/facebook_0.0.59.js
-http://l.yimg.com/a/lib/metro/facebook/facebook_0.0.63.css
-http://l.yimg.com/a/lib/metro/feed/feed_0.0.10.js
-http://l.yimg.com/a/lib/metro/feed/feed_0.1.4.css
-http://l.yimg.com/a/lib/metro/finance/finance_0.1.62.css
-http://l.yimg.com/a/lib/metro/finance/finance_0.1.77.js
-http://l.yimg.com/a/lib/metro/fpflickr/fpflickr_0.1.38.css
-http://l.yimg.com/a/lib/metro/fpflickr/fpflickr_0.1.43.js
-http://l.yimg.com/a/lib/metro/horoscope/horoscope_0.1.29.js
-http://l.yimg.com/a/lib/metro/horoscope/horoscope_0.1.42.css
-http://l.yimg.com/a/lib/metro/mail/mail_0.0.11.js
-http://l.yimg.com/a/lib/metro/mail/mail_0.0.20.css
-http://l.yimg.com/a/lib/metro/messenger/messenger_0.0.31.css
-http://l.yimg.com/a/lib/metro/messenger/messenger_0.0.40.js
-http://l.yimg.com/a/lib/metro/pacontainer/pacontainer_0.0.31.css
-http://l.yimg.com/a/lib/metro/pacontainer/pacontainer_0.0.41.js
-http://l.yimg.com/a/lib/metro/scoreboard/scoreboard_0.1.53.js
-http://l.yimg.com/a/lib/metro/scoreboard/scoreboard_0.1.62.css
-http://l.yimg.com/a/lib/metro/uiplugins/menu_default_0.1.3.css
-http://l.yimg.com/a/lib/metro/uiplugins/menu_service_0.1.3.css
-http://l.yimg.com/a/lib/metro/uiplugins/tablist_default_0.1.5.css
-http://l.yimg.com/a/lib/metro/weather/weather_0.1.72.css
-http://l.yimg.com/a/lib/metro/weather/weather_0.1.78.js
-http://l.yimg.com/a/lib/metro/yservices/yservices_0.1.25.js
-http://l.yimg.com/a/lib/metro/yservices/yservices_0.1.95.css
-http://l.yimg.com/cv/ae/de/__testing_only__/100320/50x50mpl.jpg
-http://l.yimg.com/d/lib/bc/bcr_2.0.4.js
-http://l.yimg.com/i/i/de/metro/032213.jpg
-http://l.yimg.com/i/i/de/metro/david1.jpg
-http://l.yimg.com/i/i/de/metro/depp5.jpg
-http://l.yimg.com/i/i/de/metro/grins.jpg
-http://l.yimg.com/i/i/de/metro/grins1.jpg
-http://l.yimg.com/i/i/de/metro/klum9.jpg
-http://l.yimg.com/i/i/de/metro/love5.jpg
-http://l.yimg.com/i/i/de/metro/meyer.jpg
-http://l.yimg.com/i/i/de/metro/patti.jpg
-http://pil-de.sensic.net/view.php?id=609&ai=609911305&si=102&z=5169750
-http://row.bc.yahoo.com/b?P=rOH7hlf4enaIjFzES6hqcAVfXMxrqkuobbUABTvY&T=13r3kd8oe%2fX%3d1269329333%2fE%3d2142153770%2fR%3ddehmpg%2fK%3d5%2fV%3d1.1%2fW%3dJR%2fY%3dDE%2fF%3d1627961479%2fS%3d1%2fJ%3d16A1EE4D&U=13odcn28u%2fN%3d3OW.LFf4eEc-%2fC%3d200077449.201936240.203227539.201427407%2fD%3dHDRM%2fB%3d201083721%2fV%3d1&U=12cltcst2%2fN%3d3.W.LFf4eEc-%2fC%3d-1%2fD%3dSTCK%2fB%3d-1%2fV%3d0&U=13oq99igf%2fN%3d3eW.LFf4eEc-%2fC%3d200121811.201962178.203251406.201366517%2fD%3dFPAD%2fB%3d201104189%2fV%3d1&U=13penir9s%2fN%3d4eW.LFf4eEc-%2fC%3d200122020.201964521.203249955.201421270%2fD%3dPROM1%2fB%3d201103196%2fV%3d1&U=13p21m4bp%2fN%3d4OW.LFf4eEc-%2fC%3d200121612.201961030.203250241.201441191%2fD%3dPROM2%2fB%3d201100611%2fV%3d1&U=12ber046v%2fN%3d5OW.LFf4eEc-%2fC%3d-1%2fD%3dSIP%2fB%3d-1%2fV%3d0&U=12dkuuk1c%2fN%3d5uW.LFf4eEc-%2fC%3d-1%2fD%3dYMBCN%2fB%3d-1%2fV%3d0&U=12b7orl19%2fN%3d4uW.LFf4eEc-%2fC%3d-2%2fD%3dRTG%2fB%3d-2%2fV%3d0&U=12cn27umu%2fN%3d4.W.LFf4eEc-%2fC%3d-1%2fD%3dRTG1%2fB%3d-1%2fV%3d0&U=13mgnvhf0%2fN%3d3uW.LFf4eEc-%2fC%3d200066141.201917714.203207718.201419751%2fD%3dRS%2fB%3d201075250%2fV%3d1&Q=0&O=0.2453797040205341
-http://uk.ard.yahoo.com/SIG=15vmnkeq1/M=200121811.201962178.203251406.201366517/D=dehmpg/S=2142153770:FPAD/_ylt=AjU3QcOjT40Ps4X4Pt1qRHkqrK5_/Y=DE/EXP=1269336533/L=rOH7hlf4enaIjFzES6hqcAVfXMxrqkuobbUABTvY/B=3eW.LFf4eEc-/J=1269329333422048/K=c.k.Qwg3F0uysaPXI..55Q/A=201104189/N=-201/id=nu_ad_play/0.26024979463138365/*http://ads.yimg.com/ev/eu/any/pixel4.gif
-http://uk.ard.yahoo.com/SIG=15vmnkeq1/M=200121811.201962178.203251406.201366517/D=dehmpg/S=2142153770:FPAD/_ylt=AjU3QcOjT40Ps4X4Pt1qRHkqrK5_/Y=DE/EXP=1269336533/L=rOH7hlf4enaIjFzES6hqcAVfXMxrqkuobbUABTvY/B=3eW.LFf4eEc-/J=1269329333422048/K=c.k.Qwg3F0uysaPXI..55Q/A=201104189/N=-247/id=nu_bg_on/0.4486526274433831/*http://ads.yimg.com/ev/eu/any/pixel4.gif
-http://yahoo.ivwbox.de/blank.gif
-http://yahoo.ivwbox.de/cgi-bin/ivw/CP/2142153770?r=&d=63214.11222648449
-http://a.ligatus.com/?ids=12384&t=js
-http://ad-emea.doubleclick.net/ad/N4137.heise.de/B4321259.12;sz=1x1;ord=906619961?
-http://ad-emea.doubleclick.net/adj/N5295.111569.7876282795621/B4272309;sz=728x90;click0=http://oas.heise.de/RealMedia/ads/click_lx.ads/www.heise.de/Homepage/842927577/Top/OasDefault/google02_11ros_10/google02_11ros_10_redirect_mod.html/35393338313861373438353862653830?;ord=842927577?
-http://heise.ivwbox.de/2004/01/survey.js
-http://heise.ivwbox.de/blank.gif
-http://heise.ivwbox.de/cgi-bin/ivw/CP/homepage;/?r=&d=75349.14130693086
-http://i.ligatus.com/com_ads/9796_138x115.jpg
-http://i.ligatus.com/com_global_img/logo-ligatus_frei_58x15.gif
-http://just4business.de/images/Asus_Eee_PC_1201N_75x50.jpg
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/137x200/prakti_tr_sales.gif
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/3in1sky_sw/div_close_id_swvz_ad.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/3in1sky_sw/div_open_id_swvz_ad.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/bitdefender13_11sbox_10/bitdefenderav.jpg
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/cyberlink54674_44sbox_09/cyber.jpg
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/default/empty.gif
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/microsoft06_05nbox_10b/logo_sqlserver.jpg
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/microsoft33221_44sbox_09/msoffice.jpg
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/miwibox_hp/div_close.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/miwibox_hp/div_open_id_heise_bottom_4in1_banner.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/mjx/mjx.2009-11-17.0.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/textlinkbox_hp/div_close.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/textlinkbox_hp/div_open_class_teaser_adliste.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/textlinkbox_hp/ul_close.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/textlinkbox_hp/ul_open_class_linkliste.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/textlinkbox_hp/ul_open_class_microsites.js
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/wp06_EMC_51nbox_09/EMC_logo_75_50645575645667.jpg
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/3in1_sw/1406791973/x48/OasDefault/microsoft33221_44sbox_09/microsoft33221_44sbox_09.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/3in1_sw/284216804/x47/OasDefault/bitdefender13_11sbox_10/bitdefender13_44sbox_09.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/3in1_sw/962035171/x49/OasDefault/cyberlink54674_44sbox_09/cyberlink54674_44sbox_09.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/4in1_middle3hp/1292230445/x42/OasDefault/wp06_EMC_51nbox_09/ccp_textads_vorlage645575645667.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/4in1_middle3hp/262322103/x41/OasDefault/microsoft06_05nbox_10b/microsoft06_05nbox_10b_textad_new.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/4in1_middle3hp/814474394/x43/OasDefault/miwieigen06_miwibox/Asus_Eee_PC_1201N_75x50.script.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/1066903666/Middle3/OasDefault/miwibox_hp/miwibox_hp_rahmen.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/12677327/Bottom/OasDefault/default/empty.gif/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/1477879216/Middle/OasDefault/zz_hp/zz_autos_img.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/184013871/Left2/OasDefault/137x200/prakti_tr_sales.gif/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/262818978/Left1/OasDefault/3in1sky_sw/3in1sky_sw_rahmen.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/308630109/Right1/OasDefault/default/empty.gif/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/542677179/Left/OasDefault/ligatus03_ros/google02_nfanwendungen_script.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/60976329/Right2/OasDefault/textlinkbox_hp/textlinkbox_hp.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/842927577/Top/OasDefault/google02_11ros_10/google02_11ros_10_redirect_mod.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/Homepage/911738277/Middle2/OasDefault/zz_free_contentad/zz_autos_img.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1124251766/x51/OasDefault/wc09_checkpoint_08hpnews_10/wc09_checkpoint_08hpnews_10.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1288004340/x54/OasDefault/ms09_05hpnews_10/ms09_05hpnews_10_textlink.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1372532510/x53/OasDefault/ibm09_04hpnews_10/ibm09_04hpnews_10_text.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1392564978/x55/OasDefault/1blu09_04hpnews_10/1blu09_04hpnews_10_textlink.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1415958888/x50/OasDefault/pz_hp09_51hp_09/pz_hp09_51hp_09_textlink.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/1506484795/x52/OasDefault/whitepaper09_24hpnews_09/whitepaper_textlink.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_lx.ads/www.heise.de/textlinks_hp/906619961/x60/OasDefault/strato10_09hp_10/strato10_09hp_10_webhosting.html/35393338313861373438353862653830?_RM_EMPTY_
-http://oas.heise.de/RealMedia/ads/adstream_mjx.ads/www.heise.de/Homepage/1434665888@Bottom,Left,Left1,Left2,Middle,Middle2,Middle3,Right1,Right2,Top,Top1?
-http://qs.ivwbox.de/?heise//CP//homepage
-http://rl.heise.de/images/pic.gif?r=;tp=1073741824%7C1073827193;m=Heise;tid=1073838799;random=25442.718985329073;con=1;json=1;tc=1073741824%7C1073827193%7C1073838799;c=20;b=16;sep=%7C;tce=1;tn=News;tpn=heise%20online%7CRedaktioneller%20Content%7CNews;url=http%3A%2F%2Fwww.heise.de%2F;tit=Startseite;tpu=1;sz=1366x768x24;con=1;cs=1
-http://s0.2mdn.net/viewad/2635444/ROI2_DE_728x90.gif
-http://umw-de.sensic.net/view.php?id=693&ai=7&si=12345&ps0=Heise&ps1=ROS&ps2=TextAd_75x50&ps3=ProdSQLM2&z=262322103
-http://view.atdmt.com/DEM/view/211257741/direct/01/
-http://www.heise.de/RealMedia/ads/adstream_jx.ads/www.heise.de/3in1_sw/1693169649@x47,x48,x49?
-http://www.heise.de/RealMedia/ads/adstream_jx.ads/www.heise.de/4in1_middle3hp/1540744443@x41,x42,x43,x44?
-http://www.heise.de/RealMedia/ads/adstream_jx.ads/www.heise.de/textlinks_hp/1035057110@x50,x51,x52,x53,x54,x55,x56,x57,x58,x59?
-http://www.heise.de/RealMedia/ads/adstream_jx.ads/www.heise.de/textlinks_hp/1035057110@x60,x61,x62,x63,x64,x65,x66,x67,x68,x69?
-http://www.heise.de/defeckerellyinesteetshygolingshetrica/
-http://www.heise.de/favicon.ico
-http://www.heise.de/icons/ho/00on.gif
-http://www.heise.de/icons/ho/background_mitte_40zu60.gif
-http://www.heise.de/icons/ho/background_mitte_links.gif
-http://www.heise.de/icons/ho/background_navi_top.gif
-http://www.heise.de/icons/ho/background_navigation.gif
-http://www.heise.de/icons/ho/background_onlinemarkt.gif
-http://www.heise.de/icons/ho/background_teaser_ecke.png
-http://www.heise.de/icons/ho/background_weitere.gif
-http://www.heise.de/icons/ho/dpunktfoto.gif
-http://www.heise.de/icons/ho/emedia.gif
-http://www.heise.de/icons/ho/heise_online_logo.gif
-http://www.heise.de/icons/ho/low_link.gif
-http://www.heise.de/icons/ho/midot.gif
-http://www.heise.de/icons/ho/mittelstandswiki.gif
-http://www.heise.de/imgs/02/3/9/8/2/3/9/00.jpg-c8df87c7325bb251.jpeg
-http://www.heise.de/imgs/02/3/9/9/5/4/2/ct0510Thinkpad_64746-jow-jg_PR-137-96bc3ad582573fb2.gif
-http://www.heise.de/imgs/02/4/0/2/9/2/7/kde4-gnome-80x80-42caec49ea223795.png
-http://www.heise.de/imgs/02/4/2/6/5/1/1/ir_engine-2.jpg-4d3fb8309d2c3808.jpeg
-http://www.heise.de/imgs/02/4/3/9/0/0/1/Breitband.jpg-ed3b76a2f37c3bbd.jpeg
-http://www.heise.de/imgs/02/4/5/2/8/6/9/update-check-teaser-grau-eb2471c6cbfe8a9e.gif
-http://www.heise.de/imgs/02/4/7/8/8/3/7/tpspecial0110-d01129faf4ab9c46.gif
-http://www.heise.de/imgs/02/4/9/8/7/5/1/Google2-c52f2c091ee665ca.png
-http://www.heise.de/imgs/18/4/9/7/4/9/5/Platine1-7a44dd182f22c0ac.png
-http://www.heise.de/imgs/18/4/9/8/4/3/7/TN_19349274_79671348f6-c162feefc49e954c.png
-http://www.heise.de/imgs/18/4/9/8/5/9/0/nt-mi.jpg-3ef5aa6f33f02d9d.jpeg
-http://www.heise.de/imgs/18/4/9/8/6/1/0/aufmacher_ajax.jpg-5bbbcea175e4cbcc.jpeg
-http://www.heise.de/imgs/18/4/9/8/6/6/4/nt-brown.jpg-4bdb775e5337ed24.jpeg
-http://www.heise.de/imgs/18/4/9/8/6/8/9/kernel-log-75x100-teaser.jpg-9ad4c881273c6e97.jpeg
-http://www.heise.de/imgs/18/4/9/8/6/9/7/Iran2-97230727a4d76307.png
-http://www.heise.de/imgs/18/4/9/8/7/3/1/TV5_StockXChng-MJimanges-3419995169601f3a.png
-http://www.heise.de/imgs/18/4/9/8/7/6/4/TV1-65ed120a09b6758c.png
-http://www.heise.de/imgs/18/4/9/8/8/2/8/Datenschutz_EU-Datenschutzbeauftragter_PeterHustinx2-d0f55c7009e75827.png
-http://www.heise.de/ivw-bin/ivw/CP/
-http://www.heise.de/software/specials/top_downloads_2009.jpeg
-http://www.heise.de/stil/drucken.css
-http://www.heise.de/stil/ho/standard2008.css
-http://www.heise.de/stil/navi_top2008.css
-http://www.heise.de/stil/standard2008.css
-http://www.heise.de/support/lib/external.js
-http://www.heise.de/support/lib/jquery-1.4.1.min.js
-http://www.heise.de/support/lib/jquery/jquery.ui-1.8.ho-teaserbundle.min.js
-http://www.heise.de/support/lib/login_ho.js
-http://www.heise.de/support/lib/mclient/mclient-1.0.js
-http://www.heise.de/support/sales/software/swvz_skyscraper/swvz_ad_verlauf.jpg
-http://www.heise.de/support/sales/software/swvz_skyscraper/swvz_logo.png
-http://www.strato.de/asis/pilot.de.asis?5121844
-http://www.strato.de/asis/pilot.de.asis?906619961
-http://x.ligatus.de/blank.gif
-http://x.ligatus.de/cgi-bin/ivw/CP/33548454
-http://ad.doubleclick.net/ad/N1727.cnn.com/B4080371.3;sz=1x1;ord=coaKddo,bfAqIpmbIqy?
-http://ad.doubleclick.net/ad/N5364.CNN.com/B4366287;sz=300x250;ord=cNeKdzI,bfAqIpmbIut?
-http://ad.doubleclick.net/adj/N3880.SD146.3880/B4087837.11;dcove=o;mtfIFPath=/.element/ssi/ads.iframes/doubleclick/;sz=120x90;click=http://ads.cnn.com/event.ng/Type=click&FlightID=285106&AdID=388426&TargetID=77947&Values=1588&Redirect=;ord=bpxeKwy,bfAqIpmbKhI?
-http://ads.cnn.com/DartRichMedia_1_03.js
-http://ads.cnn.com/DartRichMedia_1_03.js
-http://ads.cnn.com/DartRichMedia_1_03.js
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=352666&FlightID=257771&TargetID=75867&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,16113,17173,17251,18517,18982,20139,23491,31271,31323,32004,32594,32859,33776,33852,34282,34895,35523,36041,36376&Targets=1515,75806,75867&Values=46,60,82,100,1266,1588,2677,2746,4432,52897,56058,57005,57006,58702,59988,60001,61089&RawValues=TIELID%2C9348839239621&random=cvcuzjc,bfAqIpmbIuu
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=388426&FlightID=285106&TargetID=77947&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,4875,6041,9129,9496,9779,9781,9853,10381,16113,17173,17251,18517,18982,20139,23491,30995,31071,32004,32594,32828,32859,33776,33852,34282,34485,34895,35523,36041,36105,36376&Targets=77048,73788,77741,75201,1515,77947,76343,84488,87917&Values=46,60,82,100,1266,1588,2677,2746,4432,48137,52897,56058,57005,57006,58702,59988,61089&RawValues=TIELID%2C9348839239621&random=bpxeKwy,bfAqIpmbKhI
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=390833&FlightID=285031&TargetID=34606&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,12853,16113,17173,17251,18517,18982,19974,20139,23491,32004,32594,32859,33776,33852,34282,34895,35523,36041,36376&Targets=34606,1515,46824&Values=46,60,82,100,1266,1588,2677,2746,4432,52786,52897,56058,57005,57006,58702,59988,61089&RawValues=TIELID%2C9348839239621&random=coaKddo,bfAqIpmbIqy
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=396796&FlightID=272450&TargetID=85456&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,16113,17173,17251,18517,18982,20139,23491,30357,30363,31448,32004,32594,32827,32859,33776,33852,34282,34895,35523,35605,36041,36257,36376&Targets=73787,73789,1515,82547,82806,85456,79630&Values=46,60,82,100,1266,1588,2677,2746,4432,52897,56058,57005,57006,58702,59473,59988,61089&RawValues=TIELID%2C9348839239622&random=ckvbliA,bfAqIpmbKhw
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=396796&FlightID=272450&TargetID=85456&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,16113,17173,17251,18517,18982,20139,23491,30363,30708,31448,32004,32594,32859,33776,33852,34282,34895,35523,35605,36041,36260,36376&Targets=73789,1515,82806,82549,85456&Values=46,60,82,100,1266,1588,2677,2746,4432,52897,56058,57005,57006,58702,59474,59988,61089&RawValues=TIELID%2C9348839239622&random=bKxwbjs,bfAqIpmbKhy
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=396796&FlightID=272450&TargetID=85456&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,16113,17173,17251,18517,18982,20139,23491,30363,30709,31448,32004,32594,32859,33776,33852,34282,34895,35523,35605,36041,36261,36376&Targets=73789,1515,82806,82548,85456&Values=46,60,82,100,1266,1588,2677,2746,4432,52897,56058,57005,57006,58702,59475,59988,61089&RawValues=TIELID%2C9348839239622&random=biqiovA,bfAqIpmbIqI
-http://ads.cnn.com/event.ng/Type=count&ClientType=2&ASeg=&AMod=&AdID=397003&FlightID=292368&TargetID=72775&SiteID=1588&EntityDefResetFlag=0&Segments=730,2247,2743,2823,3285,9496,9779,9781,9853,10381,13086,13087,13088,13090,13091,13303,16113,16337,17173,17251,18517,18887,18901,18904,18982,20139,23491,23793,25535,25538,25544,25547,25550,29699,29776,30401,31073,32004,32594,32736,32825,32859,33776,33852,34253,34282,34895,35523,35895,36040,36041,36310,36376&Targets=73881,72775,72645,1515,70690,88526,86748,86245,86257,85450,76350,79628,82457,85144,85146,86622,88640,86090,87669,87671,82751,85139,82663,84902,86352,88869,82775,84903,82659,84555,84559,84564,87626,87918&Values=46,60,82,100,1266,1588,2677,2746,4432,52897,56058,57005,57006,58702,59477,59988,61089&RawValues=TIELID%2C9348839239621&random=cNeKdzI,bfAqIpmbIut
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=120x90_bot1&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=653357
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=126x31_spon3&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=223595
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=126x31_spon8&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=101386
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=126x31_spon9&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=308194
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=1x1_bot&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=728136
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=230x250_adlinks&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=709129
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=300x100_bot1&cnn_rollup=homepage&page.allowcompete=no¶ms.styles=fs&tile=9348839239622&domId=274828
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=300x100_bot2&cnn_rollup=homepage&page.allowcompete=no¶ms.styles=fs&tile=9348839239622&domId=790397
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=300x100_bot3&cnn_rollup=homepage&page.allowcompete=no¶ms.styles=fs&tile=9348839239622&domId=709102
-http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=300x250_rgt&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=9348839239621&domId=985003
-http://b.scorecardresearch.com/r2?c2=6035748&d.c=gif&d.o=cnn3global&d.x=253275916&d.t=page&d.u=http%3A%2F%2Fwww.cnn.com%2F
-http://b.scorecardresearch.com/r?c2=6035748&d.c=gif&d.o=cnn3global&d.x=253275916&d.t=page&d.u=http%3A%2F%2Fwww.cnn.com%2F
-http://cnn.dyn.cnn.com/cookie.crumb
-http://content.dl-rms.com/rms/mother/5721/nodetag.js
-http://es.optimost.com/es/203/c/3/u/cnn_live.js
-http://gdyn.cnn.com/1.1/1.gif?1269329388870
-http://googleads.g.doubleclick.net/pagead/ads?client=ca-cnn-home_js&output=js&num_ads=3&channel=homepage&ad_type=text&adtest=off&ea=0&oe=utf8&flash=10.0.45&hl=en&url=http%3A%2F%2Fwww.cnn.com%2F&adsafe=high&dt=1269329389465&correlator=1269329389472&frm=1&ga_vid=1045930262.1269329390&ga_sid=1269329390&ga_hid=558562656&ga_fc=0&u_tz=60&u_his=3&u_java=0&u_h=768&u_w=1366&u_ah=768&u_aw=1366&u_cd=24&u_nplug=2&u_nmime=3&biw=1349&bih=390&ifk=806819358&loc=http%3A%2F%2Fwww.cnn.com%2F&fu=4&ifi=1&dtd=210
-http://googleads.g.doubleclick.net/pagead/test_domain.js
-http://i.cdn.turner.com/cnn/.element/css/3.0/common.css
-http://i.cdn.turner.com/cnn/.element/css/3.0/common.css
-http://i.cdn.turner.com/cnn/.element/css/3.0/connect/overlay.css
-http://i.cdn.turner.com/cnn/.element/css/3.0/main.css
-http://i.cdn.turner.com/cnn/.element/css/3.0/personalization.css
-http://i.cdn.turner.com/cnn/.element/img/3.0/1px.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/buttons/Sprite_BT_master.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/buttons/sprite_tabbed.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/arabic.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/footer_cnn_logo.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/footer_google.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/japanese.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/korean.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/footer/pngs/turkish.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/bg-nav.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/hat/arrow_black.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/hat/bg_hat_black_lg.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/hdr-close.jpg
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/hdr-main.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/hdr-search-google.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/nav-arrow.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/header/nav-beta.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/icons/red.carrot.jpg
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/icons/video_icon.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/misc/Numbers_Sprite.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/misc/advertisement.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/misc/filter.line.100px.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/misc/loading.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/red_bull.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/BL_shadow_7x6.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/BR_shadow_1000x6.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/Left_shadow.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/Right_shadow.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/TL_shadow_7x6.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/TR_shadow_1000x6.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/cnn_shdcamtt1.990px.bg.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/cnn_shdcamtt1.990px.header.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/cnn_shdsectbin.990px.bg.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/global/shade/sprite_shades.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/35x35_generic_avatar.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/Green_market_status.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/Module_gradient.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/arrow_down.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/arrow_up.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/hp_market_sprite.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/personalization/popular_bar.jpg
-http://i.cdn.turner.com/cnn/.element/img/3.0/search/bg_ftrsearchfield.lrg.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/search/btn_search_hp_text.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/search/search_btn_footer.gif
-http://i.cdn.turner.com/cnn/.element/img/3.0/video/thumbnail_play.png
-http://i.cdn.turner.com/cnn/.element/img/3.0/weather/03/33.png
-http://i.cdn.turner.com/cnn/.element/js/2.0/ad_head0.js
-http://i.cdn.turner.com/cnn/.element/js/2.0/frame.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/StorageManager.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/connect/connect-lite.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/csiManager.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/edition.vars.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/hpsectiontracking.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/local.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/main.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/protoaculous.1.8.2.min.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/s_code.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/swfobject-2.2.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/video/cvp.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/video/cvp_suppl.js
-http://i.cdn.turner.com/cnn/.element/js/3.0/weather.footer.js
-http://i.cdn.turner.com/cnn/2009/images/11/16/210x80_cnn_Challenge.jpg
-http://i.cdn.turner.com/cnn/2010/HEALTH/03/22/united.nations.water.report/c1main.india.river.afp.gi.jpg
-http://i.cdn.turner.com/cnn/2010/LIVING/03/22/margaret.moth.tributes/tzvids.margaret.moth.courtesy.jpg
-http://i.cdn.turner.com/cnn/2010/LIVING/03/22/real.men.eat.salad/tzvids.salad.cnn.jpg
-http://i.cdn.turner.com/cnn/2010/LIVING/03/22/vegan.food.activists/tzvids.veg.activists.gi.jpg
-http://i.cdn.turner.com/cnn/2010/LIVING/worklife/03/22/cb.job.search.mistakes/tzvids.js.mistakes.gi.jpg
-http://i.cdn.turner.com/cnn/2010/LIVING/worklife/03/22/rs.secrets.working.mother/tzvids.unflappable.mom.gi.jpg
-http://i.cdn.turner.com/cnn/2010/POLITICS/03/16/health.care.immediate/tzvids.benefits.c2.jpg
-http://i.cdn.turner.com/cnn/2010/SHOWBIZ/TV/03/22/rosie.odonnell.show.ppl/tzvids.rosie.odonnell.gi.jpg
-http://i.cdn.turner.com/cnn/2010/SPORT/tennis/03/18/tennis.film.nadal.amritraj.mcenroe/tzvids.rafa.jpg
-http://i.cdn.turner.com/cnn/2010/TRAVEL/03/22/flying.now.then/tzvids.flying.then.gi.jpg
-http://i.cdn.turner.com/cnn/2010/WORLD/africa/03/22/africa.elephants.ivory.trade/tzvids.elephant.poaching.jpg
-http://i.cdn.turner.com/cnn/2010/WORLD/europe/03/22/germany.hitler.letter.cordial/tzvids.hitler.letter.jpg
-http://i.cdn.turner.com/cnn/2010/images/03/22/tzvids.health.effects.irpt.jpg
-http://i.cdn.turner.com/cnn/2010/images/03/22/tzvids.ncaa.upset.gi.jpg
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2008/9/17/2855151x1.gif
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2008/9/17/2855151x1.gif
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2008/9/17/2855151x1.gif
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2009/11/9/56101520090708_DB_IP_DBLEPLUSA_24_300_100.swf
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2009/11/9/56101520090708_DB_IP_DBLEPLUSA_24_300_100.swf
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2009/11/9/56101520090708_DB_IP_DBLEPLUSA_24_300_100.swf
-http://i.cdn.turner.com/cnn/cnn_adspaces/2.0/creatives/2009/6/3/4436122_equifax.143x31.jpg
-http://i.cdn.turner.com/cnn/cnn_adspaces/cnn_adspaces.js
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif
-http://i.cdn.turner.com/cnn/images/1.gif?csiTestMatch=true
-http://i.cdn.turner.com/cnn/video/us/2010/03/22/dnt.cows.drink.more.beer.kval.120x68.jpg
-http://i.cdn.turner.com/xslo/cvp/ads/freewheel/js/fwjslib_1.1.js?version=1.1
-http://i.cnn.net/cnn/.element/js/2.0/csi_include.js
-http://i2.cdn.turner.com/cnn/2009/images/10/27/lking120x68.copy.jpg
-http://i2.cdn.turner.com/cnn/2009/images/10/29/roberts-chetry120x68.copy.jpg
-http://i2.cdn.turner.com/cnn/2010/POLITICS/03/22/health.care.main/t1main.obama.cnn.jpg
-http://i2.cdn.turner.com/cnn/2010/images/03/15/jk_usa_plain_120x68.jpg
-http://i2.cdn.turner.com/cnn/2010/images/03/22/tzvids.kennedy.offcenter.cnn.jpg?hpt=C2
-http://js.revsci.net/gateway/gw.js?csid=A09801
-http://metrics.cnn.com/b/ss/cnn3global/1/H.20.3/s0429878539768?AQB=1&ndh=1&t=23/2/2010%208%3A29%3A48%202%20-60&ns=cnn&pageName=CNN%20Home%20Page&g=http%3A//www.cnn.com/&ch=CNN%20Home%20Page&v1=CNN%20Home%20Page&v2=CNN%20Home%20Page&c5=Homepage&v5=Homepage&c9=03%3A15&c10=Tue&c18=10&c20=03&s=1366x768&c=24&j=1.7&v=N&k=Y&bw=1366&bh=390&p=Mozilla%20Default%20Plug-in%3BShockwave%20Flash%3B&AQE=1
-http://metrics.cnn.com/b/ss/cnn3global/1/H.20.3/s0429878539768?AQB=1&pccr=true&vidn=25D436F5051D16A6-40000105C00092FC&&ndh=1&t=23/2/2010%208%3A29%3A48%202%20-60&ns=cnn&pageName=CNN%20Home%20Page&g=http%3A//www.cnn.com/&ch=CNN%20Home%20Page&v1=CNN%20Home%20Page&v2=CNN%20Home%20Page&c5=Homepage&v5=Homepage&c9=03%3A15&c10=Tue&c18=10&c20=03&s=1366x768&c=24&j=1.7&v=N&k=Y&bw=1366&bh=390&p=Mozilla%20Default%20Plug-in%3BShockwave%20Flash%3B&AQE=1
-http://pagead2.googlesyndication.com/pagead/show_ads.js
-http://pix04.revsci.net/A09801/b3/0/3/0902121/429848602.js?D=DM_LOC%3Dhttp%253A%252F%252Fwww.cnn.com%252F%253Fundefined%253Dundefined%26DM_CAT%3Dcnn%2520%253E%2520homepage%26DM_EOM%3D1&C=A09801
-http://s0.2mdn.net/viewad/1873234/CR7USDS_001_300x250.gif
-http://s0.2mdn.net/viewad/2584085/120x90_Ally_Logo.gif
-http://s0.2mdn.net/viewad/617966/84-1x1.gif
-http://svcs.cnn.com/weather/getForecast?time=59&mode=json_html&zipCode=74446&locCode=MUSX&celcius=false&csiID=csi3
-http://view.atdmt.com/NYC/view/184916056/direct;wi.1;hi.1/01/bKxwbjs,bfAqIpmbKhy
-http://view.atdmt.com/NYC/view/184916056/direct;wi.1;hi.1/01/biqiovA,bfAqIpmbIqI
-http://view.atdmt.com/NYC/view/184916056/direct;wi.1;hi.1/01/ckvbliA,bfAqIpmbKhw
-http://www.cnn.com/
-http://www.cnn.com/.element/ssi/misc/3.0/editionvars.html?csiID=csi2
-http://www.cnn.com/.element/ssi/www/breaking_news/3.0/banner.html?csiID=csi1
-http://www.cnn.com/cnn_adspaces/3.0/homepage/main/bot1.120x90.ad
-http://feeds.feedburner.com/~ff/EavescaMozilla?d=7Q72WNTAKBA
-http://feeds.feedburner.com/~ff/EavescaMozilla?d=qj6IDK7rITs
-http://feeds.feedburner.com/~ff/EavescaMozilla?d=yIl2AUoC8zA
-http://feeds.feedburner.com/~ff/EavescaMozilla?i=y2E_lmaf6Ck:asd0TbmtUec:V_sGLiPBpWU
-http://feeds.feedburner.com/~ff/EavescaMozilla?i=y2E_lmaf6Ck:asd0TbmtUec:gIN9vFwOqvQ
-http://feeds.feedburner.com/~r/EavescaMozilla/~4/y2E_lmaf6Ck
-http://feeds.feedburner.com/~r/HackingForChrist/~4/o6duuVNNMj0
-http://feeds.feedburner.com/~r/HackingForChrist/~4/rSZ4LFlaoUc
-http://feeds.feedburner.com/~r/rumblingedge/~4/Sc2pr3lMIUc
-http://feeds.feedburner.com/~r/rumblingedge/~4/ZFzOR0Yhw5g
-http://feeds.feedburner.com/~r/rumblingedge/~4/ZPYUbaSLYS0
-http://feeds.feedburner.com/~r/rumblingedge/~4/i5dDh9a50Gg
-http://feeds.feedburner.com/~r/rumblingedge/~4/skaTLs46ZS8
-http://stats.wordpress.com/b.gif?host=chickswhoclick.wordpress.com&blog=67108&post=465&subd=chickswhoclick&ref=&feed=1
-http://stats.wordpress.com/b.gif?host=davidwboswell.wordpress.com&blog=1079368&post=2088&subd=davidwboswell&ref=&feed=1
-http://stats.wordpress.com/b.gif?host=elvis314.wordpress.com&blog=7596067&post=276&subd=elvis314&ref=&feed=1
-http://stats.wordpress.com/b.gif?host=jonoscript.wordpress.com&blog=3902169&post=772&subd=jonoscript&ref=&feed=1
-http://stats.wordpress.com/b.gif?host=jonoscript.wordpress.com&blog=3902169&post=774&subd=jonoscript&ref=&feed=1
-http://stats.wordpress.com/b.gif?host=patrickfinch.com&blog=4116262&post=646&subd=patrickfinch&ref=&feed=1
-https://blogger.googleusercontent.com/tracker/3113982014951840128-5331238888011880923?l=mindforks.blogspot.com
-https://blogger.googleusercontent.com/tracker/3693634748032171093-2598694623030968164?l=alanjstr.blogspot.com
-http://blog.mozilla.com/metrics/files/2010/09/new-about-window-300x180.png
-http://blog.mozilla.com/webdev/files/2010/09/stats_new.png
-http://bluegriffon.org/public/shots/videoTag.png
-http://bluegriffon.org/themes/default/smilies/smile.png
-http://chickswhoclick.files.wordpress.com/2010/09/firefox-download-day.jpg?w=300&h=140
-http://davidwboswell.files.wordpress.com/2010/09/bluegriffon.png?w=50&h=50
-http://davidwboswell.files.wordpress.com/2010/09/sogo.png?w=50&h=50
-http://eaves.ca/wp-content/plugins/sociable/images/delicious.png
-http://eaves.ca/wp-content/plugins/sociable/images/digg.png
-http://eaves.ca/wp-content/plugins/sociable/images/email_link.png
-http://eaves.ca/wp-content/plugins/sociable/images/facebook.png
-http://eaves.ca/wp-content/plugins/sociable/images/identica.png
-http://eaves.ca/wp-content/plugins/sociable/images/netvibes.png
-http://eaves.ca/wp-content/plugins/sociable/images/pdf.png
-http://eaves.ca/wp-content/plugins/sociable/images/printfriendly.png
-http://eaves.ca/wp-content/plugins/sociable/images/reddit.png
-http://eaves.ca/wp-content/plugins/sociable/images/slashdot.png
-http://eaves.ca/wp-content/plugins/sociable/images/stumbleupon.png
-http://eaves.ca/wp-content/plugins/sociable/images/techmeme.png
-http://eaves.ca/wp-content/plugins/sociable/images/technorati.png
-http://eaves.ca/wp-content/plugins/sociable/images/twitter.png
-http://ed.agadak.net/wp-includes/images/smilies/icon_smile.gif
-http://farm5.static.flickr.com/4083/5038947835_47045de383.jpg
-http://farm5.static.flickr.com/4083/5038947863_e8df4b8186.jpg
-http://farm5.static.flickr.com/4106/5038947911_379b1873ab.jpg
-http://farm5.static.flickr.com/4107/5038947915_0ac24f0336.jpg
-http://farm5.static.flickr.com/4127/5032249087_31782fff8d.jpg
-http://farm5.static.flickr.com/4131/5038952763_67513d235f.jpg
-http://farm5.static.flickr.com/4144/5038947897_81df8d930a.jpg
-http://feeds.wordpress.com/1.0/comments/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/comments/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/comments/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/comments/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/comments/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/comments/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/delicious/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/delicious/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/delicious/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/delicious/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/delicious/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/delicious/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/digg/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/digg/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/digg/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/digg/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/digg/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/digg/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/facebook/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/facebook/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/facebook/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/facebook/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/facebook/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/facebook/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/reddit/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/reddit/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/reddit/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/reddit/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/reddit/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/reddit/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/stumble/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/stumble/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/stumble/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/stumble/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/stumble/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/stumble/patrickfinch.wordpress.com/646/
-http://feeds.wordpress.com/1.0/twitter/chickswhoclick.wordpress.com/465/
-http://feeds.wordpress.com/1.0/twitter/davidwboswell.wordpress.com/2088/
-http://feeds.wordpress.com/1.0/twitter/elvis314.wordpress.com/276/
-http://feeds.wordpress.com/1.0/twitter/jonoscript.wordpress.com/772/
-http://feeds.wordpress.com/1.0/twitter/jonoscript.wordpress.com/774/
-http://feeds.wordpress.com/1.0/twitter/patrickfinch.wordpress.com/646/
-http://glandium.org/blog/wp-content/uploads/2010/09/libxul.less_.static.initializers.png
-http://glandium.org/blog/wp-content/uploads/2010/09/libxul.png
-http://home.kairo.at/?d=b&p=s_smile
-http://home.kairo.at/?d=b&p=s_wink
-http://home.kairo.at/?d=g&p=22442&f.m=normal
-http://planet.mozilla.org/img/background.jpg
-http://planet.mozilla.org/img/bullet_utility.png
-http://planet.mozilla.org/img/feed-icon-10x10.png
-http://planet.mozilla.org/img/feed-icon.png
-http://planet.mozilla.org/img/foaf-icon.png
-http://planet.mozilla.org/img/footer.jpg
-http://planet.mozilla.org/img/header-bg.jpg
-http://planet.mozilla.org/img/header-dino.jpg
-http://planet.mozilla.org/img/logo.png
-http://planet.mozilla.org/img/mozilla-16.png
-http://planet.mozilla.org/img/opml-icon.png
-http://planet.mozilla.org/img/sidebar-back.png
-http://planet.mozilla.org/img/sidebar-bottom.png
-http://planet.mozilla.org/img/world.png
-http://planet.mozilla.org/personalize.js
-http://planet.mozilla.org/planet.css
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-digg.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-facebook.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-myspace.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-ping.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-su.png
-http://richard.milewski.org/blog/wp-content/plugins/tweet-this/icons/tt-twitter-micro1.png
-http://robert.accettura.com/wp-content/commentCount/2010/09/da2bd66.gif
-http://robert.accettura.com/wp-content/commentCount/2010/10/c2e06e9.gif
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/5DayForecast-444x366.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/AddSearchTerms-444x367.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/BlogSearchResults_CloudClosed1.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/FeaturedImage3-672x112.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/GetStarted-444x301.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/MiniSearchEngines-444x346.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/TagsPhrasesSitesZones-444x340.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/addgraphicicons.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/conditionoverviewonstatusbar.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/configuringsettings1.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/featured-image-672x113.png
-http://rockyourfirefox.com/rockyourfirefox_content/uploads/2010/09/hoverovericonforreport.png
-http://vikingkarwur.com/images/avatar-id-mozilla-twitter.png
-http://www.rumblingedge.com/files/osicons/linuxicon.png
-http://www.rumblingedge.com/files/osicons/macosx.png
-http://www.rumblingedge.com/files/osicons/winicon.png
-http://heise.ivwbox.de/cgi-bin/ivw/CP/homepage;/?r=&d=93391.92622121828
-http://oas.heise.de/RealMedia/ads/Creatives/OasDefault/mjx/mjx.2010-06-14.0.js
-http://rl.heise.de/images/pic.gif?r=;tp=1073741824%7C1073827193;m=Heise;tid=1073838799;random=69289.75360272666;con=1;json=1;tc=1073741824%7C1073827193%7C1073838799;c=20;b=16;sep=%7C;tce=1;tn=News;tpn=heise%20online%7CRedaktioneller%20Content%7CNews;url=http%3A%2F%2Fwww.heise.de%2F;tit=Startseite;tpu=1;sz=1366x768x24;con=1;cs=1
-http://www.heise.de/ivw-bin/ivw/CP/
-http://www.heise.de/defeckerellyinesteetshygolingshetrica/
-http://www.heise.de/favicon.ico
-http://www.heise.de/icons/ho/00on.gif
-http://www.heise.de/icons/ho/background_mitte_40zu60.gif
-http://www.heise.de/icons/ho/background_mitte_links.gif
-http://www.heise.de/icons/ho/background_navi_top.gif
-http://www.heise.de/icons/ho/background_navigation.gif
-http://www.heise.de/icons/ho/background_onlinemarkt.gif
-http://www.heise.de/icons/ho/background_weitere.gif
-http://www.heise.de/icons/ho/dpunktfoto.gif
-http://www.heise.de/icons/ho/emedia.gif
-http://www.heise.de/icons/ho/heise_online_logo.gif
-http://www.heise.de/icons/ho/midot.gif
-http://www.heise.de/icons/ho/mittelstandswiki.gif
-http://www.heise.de/imgs/02/3/9/8/2/8/0/Atom-28e99a3ba6d31b7b.jpeg
-http://www.heise.de/imgs/02/4/0/2/9/2/7/ganten-300x426.JPG-f9d6a1aec8ab7da4.jpeg
-http://www.heise.de/imgs/02/4/2/0/3/5/1/aufmacher_ho-2199599268874ae8.jpg
-http://www.heise.de/imgs/02/4/5/2/8/6/9/update-check-teaser-grau-eb2471c6cbfe8a9e.gif
-http://www.heise.de/imgs/02/4/7/8/8/3/7/TitelbildWindowsWeb_special0710.jpg-cd42c786563005c7.jpeg
-http://www.heise.de/imgs/02/5/3/4/6/6/1/DPF-Uhr_2_teaser.jpg-283e096c2271c4be.jpeg
-http://www.heise.de/imgs/02/5/6/7/9/2/1/header_visual-100.jpg-74e3f883ed77ed70.jpeg
-http://www.heise.de/imgs/02/5/7/7/5/9/1/Zuse_Konrad-Teaser-6d349b3fe45990c6.png
-http://www.heise.de/imgs/18/5/7/6/5/3/4/9333c3eda9694e7a.jpeg
-http://www.heise.de/imgs/18/5/7/7/1/8/3/efa6224cae844431.jpeg
-http://www.heise.de/imgs/18/5/7/7/1/8/5/nt-ubu-003643117f7aade1.gif
-http://www.heise.de/imgs/18/5/7/7/1/9/9/e6e21bdf25049c8e.jpeg
-http://www.heise.de/imgs/18/5/7/7/2/0/8/336313f75a36686d.png
-http://www.heise.de/imgs/18/5/7/7/2/4/6/nt-zumw.jpg-beeb17e3f53eaa0a.jpeg
-http://www.heise.de/imgs/18/5/7/7/2/7/0/imgres-21af9779d81eb459.jpeg
-http://www.heise.de/imgs/18/5/7/7/2/8/1/nt-polyl-269d81b1eaefa71c.gif
-http://www.heise.de/imgs/18/5/7/7/2/9/8/506bdc97f2e04d6e.png
-http://www.heise.de/imgs/18/5/7/7/3/0/5/4bab2a9e920825f6.png
-http://www.heise.de/imgs/18/5/7/7/3/0/9/4dd825b3f20dcb0d.png
-http://www.heise.de/imgs/18/5/7/7/3/5/3/nt-zensus.jpg-d7019bc4c7278a4f.jpeg
-http://www.heise.de/imgs/18/5/7/7/3/8/0/99d553c211ab3d35.jpeg
-http://www.heise.de/imgs/18/5/7/7/3/9/9/1109-Gas_130.jpg-f97e938586473c14.jpeg
-http://www.heise.de/imgs/18/5/7/7/4/4/9/AAA1-664daddd9d655c5d.png
-http://www.heise.de/imgs/18/5/7/7/5/0/1/9f6fbee5dd0d71bd.png
-http://www.heise.de/imgs/18/5/7/7/5/4/6/e2e743388509938b.png
-http://www.heise.de/imgs/18/5/7/7/7/3/6/ooffice-89x91-d43e82a29e0dd081.png
-http://www.heise.de/imgs/18/5/7/7/7/5/3/schmitt_dpa_100-9f6153dce451402d.png
-http://www.heise.de/software/screenshots/sps71.jpg
-http://www.heise.de/stil/drucken.css
-http://www.heise.de/stil/ho/standard2008.css
-http://www.heise.de/stil/navi_top2008.css
-http://www.heise.de/stil/standard2008.css
-http://www.heise.de/support/lib/external.js
-http://www.heise.de/support/lib/jquery-1.4.2.min.js
-http://www.heise.de/support/lib/jquery/jquery.ui-1.8.ho-teaserbundle.min.js
-http://www.heise.de/support/lib/login_ho.js
-http://www.heise.de/support/lib/social_bookmarks.js
-http://www.heise.de/tp/r4/artikel/33/33417/33417_0.gif
-http://ad.doubleclick.net/imp;v1;f;226063238;0-0;0;49906365;1|1;37967833|37985590|1;;cs=e%3fhttp://ad.doubleclick.net/dot.gif?[07072010]1285963100680
-http://adlog.com.com/adlog/i/r=10735&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=01c18-ad-e17:4CA60AB77A02A3&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=12543&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=01c18-ad-e15:4CA61D0F4AC8DD&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=12790&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=300&e=3&rqid=00c18-ad-e18:4CA5C68A8B9990&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=13683&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=00c18-ad-e18:4CA5C68A8B9995&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=18747&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=01c18-ad-e15:4CA61D0F4AC8EA&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=18876&sg=1815&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=01c18-ad-e16:4CA62C8125C892&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=7752&sg=463766&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=01c18-ad-e18:4CA60EB9367D7D&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://adlog.com.com/adlog/i/r=8801&sg=463770&o=1%253a&h=cn&p=2&b=1&l=en_US&site=1&pt=2000&nd=1&pid=&cid=0&pp=100&e=3&rqid=00c18-ad-e14:4CA61A72292B88&orh=&ort=&oepartner=&epartner=&ppartner=&pdom=&cpnmodule=&count=&ra=92.204.64.212&dvar=dvar%255fversion%253d2008&ucat_rsi=%2526&pg=nX9sWQoPjF0AAGGutKkAAAHH&t=2010.10.01.19.58.15/http://i.i.com.com/cnwk.1d/Ads/common/dotclear.gif
-http://b.scorecardresearch.com/beacon.js
-http://c1.zedo.com/jsc/c1/fo.js
-http://c1.zedo.com/jsc/c1/replay_fi.js
-http://dw.com.com/clear/c.gif?ts=1285963095&im=mii1.4&edId=3&ptId=2000&onId=1&sId=1&asId=0&astId=1&pgnbr=1&oid=2000-1_1-0&pguid=nX9sWQoPjF0AAGGutKkAAAHH&ld=www.cnet.com&tcset=ISO-8859-1&title=Product%20reviews%20and%20prices,%20software%20downloads,%20and%20tech%20news%20-%20CNET&srcUrl=http://www.cnet.com/
-http://dw.com.com/js/dw.js
-http://dw.com.com/redir?ontid=1&siteid=1&asId=0&ptId=2000&edId=3&guid=nX9sWQoPjF0AAGGutKkAAAHH&tag=tbJoin&destUrl=/i/b.gif&uniquePingId=1285963101119
-http://dw.com.com/redir?ontid=1&siteid=1&asId=0&ptId=2000&edId=3&guid=nX9sWQoPjF0AAGGutKkAAAHH&tag=toolbar&destUrl=/i/b.gif&uniquePingId=1285963100515
-http://dw.com.com/rubicsimp/c.gif?ver=2&ts=2010.10.01.12.58.15.PDT&edId=3&onId=1&ptId=2000&sId=1&appId=19&unitId=45&poolId=1&f1=1&f2=-0&f3=-0&alg=8&opt=1&off=10629,-1
-http://i.i.com.com/cnwk.1d/Ads/common/adinfo_top.gif
-http://i.i.com.com/cnwk.1d/Ads/common/madUCat/MadUCat.js
-http://i.i.com.com/cnwk.1d/html/rb/js/tron/doors/doors.tron.ad.premiere.compressed.js
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/SamsungLogo_88x31.jpg
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/acer.jpg
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/attLogo_88x31.jpg
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/att_fd_sew350.gif
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/droid.jpg
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/inspiron15.gif
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/machoArrow.gif
-http://i.i.com.com/cnwk.1d/i/tron/doors/ads/superPremier/verizonLogo_88x31.jpg
-http://js.revsci.net/gateway/gw.js?csid=K05540
-http://view.atdmt.com/M0N/iview/258396214/direct;wi.300;hi.250/01?click=
-http://api.cnet.com/restApi/v1.0/videoSearch?viewType=json&partTag=cntv&callback=LiveStreamStatusCheckR2D2.reqs.lssc_0.receiveLiveStatus&videoIds=&iod=broadcast%2Clowcache&broadcastStatus=IN_PROGRESS&orderBy=broadcastStartTime&sortAsc=true
-http://connect.facebook.net/en_US/all.js
-http://i.i.com.com/cnwk.1d/css/rb/tron/fd2010/fd2010.css
-http://i.i.com.com/cnwk.1d/css/rb/tron/matrix.css
-http://i.i.com.com/cnwk.1d/css/rb/tron/print.css
-http://i.i.com.com/cnwk.1d/html/Mockups/rb/fd/2010/zimgz/auxPromoFpo.gif
-http://i.i.com.com/cnwk.1d/html/Mockups/rb/fd/2010/zimgz/facebookBox.gif
-http://i.i.com.com/cnwk.1d/html/pt/pt2.js
-http://i.i.com.com/cnwk.1d/html/rb/js/tron/doors/doors.tron.r2d2.compressed.js
-http://i.i.com.com/cnwk.1d/html/rb/js/tron/oreo.moo.rb.combined.js
-http://i.i.com.com/cnwk.1d/i/News/FrontDoor/about_box_iconsspriteNew.gif
-http://i.i.com.com/cnwk.1d/i/b.gif
-http://i.i.com.com/cnwk.1d/i/fd/06/sponsored.gif
-http://i.i.com.com/cnwk.1d/i/tiburon/hh/187.gif
-http://i.i.com.com/cnwk.1d/i/tiburon/hh/dot3.gif
-http://i.i.com.com/cnwk.1d/i/tim//2009/12/10/donald.jpg
-http://i.i.com.com/cnwk.1d/i/tim//2009/12/10/inafried.jpg
-http://i.i.com.com/cnwk.1d/i/tim//2009/12/10/rafe.jpg
-http://i.i.com.com/cnwk.1d/i/tim//2010/05/11/dell_120x30_90x23.png
-http://i.i.com.com/cnwk.1d/i/tim//2010/07/15/The404_Widescreen_Logo_2_200x150.jpg
-http://i.i.com.com/cnwk.1d/i/tim//2010/08/05/MacFixItAnswersIconF_60x60.png
-http://i.i.com.com/cnwk.1d/i/tim//2010/08/27/askMaggie.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/27/acer_aspire_16_82x62.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/29/NostaDonu_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/29/hp-pavilion-dv7t-3_84x84.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/29/lenovo_t410s_82x62.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/29/panasonic_50_hdtv_84x84.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/29/sony-playstation-3_84x84.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/34167361_OVR_60x60.png
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/3DTVScompared.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/BuzzPlaybook.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/appleTV.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/epicCanonS95.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/epicbeerfroth.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/epiccravekindle.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/epictop5.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/09/30/parisMotorShow2010Maserati.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/41HNsgva%252BhL._SS500__60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/Custom_Dial_6_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/Dome2_1_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/Microsoft_logo_%28blue_background%29_1_60x60.PNG
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/ParisConcept_SS01_88x66.JPG
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/catanipad_60x60.PNG
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/dell_vostro_230__24_lcd_84x84.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/facebook_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/lumixphone_500x375_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/macbook3g_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/medal_of_honor_270x117_60x60.PNG
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/ovi-store_60x60.png
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/pelletclose_88x66.jpg
-http://i.i.com.com/cnwk.1d/i/tim/2010/10/01/stocks_60x60.jpg
-http://i.i.com.com/cnwk.1d/i/tron/autocompleteBg.png
-http://i.i.com.com/cnwk.1d/i/tron/cnet/river/tooltip_info_icon.gif
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/popupArrow.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/popupBkg.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/redball.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/selectorsSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/smlListBkg.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/toolbarAccents.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/toolbarBkg2.png
-http://i.i.com.com/cnwk.1d/i/tron/cnetToolbar/vertListLine.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/187y.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/allCatsSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/auxHedA.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/connectModule.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/ctaShop.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/doormatDivs.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/doormatHed.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/fdSprite.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/headlinesBg.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/headlinesFoot.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/indicators.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/leftNavSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/moreStoriesFlex.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverLoadMore.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverPlayOverlay.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverPost.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverTools-v2.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/riverUpdate.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/social.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/tweetsToggle.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/vertDiv.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/vertDiv2.gif
-http://i.i.com.com/cnwk.1d/i/tron/fd/videoOverIco.png
-http://i.i.com.com/cnwk.1d/i/tron/oreo/rbLogo.png
-http://i.i.com.com/cnwk.1d/i/tron/oreo/site1headerBg.png
-http://i.i.com.com/cnwk.1d/i/tron/oreo/site1rbHeader.png
-http://i.i.com.com/cnwk.1d/i/tron/tips.png
-http://i.i.com.com/cnwk.1d/i/tron/vader/bgBody.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/brandNavPipe.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/go.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/hr.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/neoGo.png
-http://i.i.com.com/cnwk.1d/i/tron/vader/neoLoginSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/vader/neoPipe.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/neoSearchBoxSprite.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/neoSearchWrapSprite.png
-http://i.i.com.com/cnwk.1d/i/tron/vader/rblogoFooter.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/rssFeeds/google.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/rssFeeds/msn.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/rssFeeds/yahoo.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/siteId1hed.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/siteId1hedB.gif
-http://i.i.com.com/cnwk.1d/i/tron/vader/sitenav.png
-http://i.i.com.com/cnwk.1d/sc/33626815-2-60-0.gif
-http://i.i.com.com/cnwk.1d/sc/34001684-2-60-0.gif
-http://offers-service.cbsinteractive.com/offers/script.sc?offerId=56
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs173.ash2/41658_690120417_4031_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs227.ash2/49220_100000322637435_8052_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs308.ash1/23305_7155422274_2443_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs322.snc4/41385_503089540_3925_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs342.snc4/41388_1826537476_8514_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs352.snc4/41650_100000287781995_3361_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs448.snc4/49297_100000552365817_6557_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs460.snc4/48669_1355983879_1078_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs621.ash1/27346_100000352465097_1963_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs626.ash1/27447_100000954253950_8577_q.jpg
-http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs642.snc3/27358_100000938066510_2882_q.jpg
-http://static.ak.fbcdn.net/connect/xd_proxy.php#cb=f3e59d56fdcf604&origin=http%3A%2F%2Fwww.cnet.com%2Ff226dba425468&relation=parent&transport=postmessage&frame=f22ae78bbc11b68
-http://static.ak.fbcdn.net/rsrc.php/z5R48/hash/ejut8v2y.gif
-http://static.ak.fbcdn.net/rsrc.php/z7/p/r/qTxZss-4EFY.js
-http://static.ak.fbcdn.net/rsrc.php/zC/r/HxuD3VqPAGY.js
-http://static.ak.fbcdn.net/rsrc.php/zH/r/eIpbnVKI9lR.png
-http://static.ak.fbcdn.net/rsrc.php/zI/p/r/wxw0nLn9tMb.js
-http://static.ak.fbcdn.net/rsrc.php/zI/r/ewrjb4eEaq6.ico
-http://static.ak.fbcdn.net/rsrc.php/zK/p/r/HWL11JhzW9w.js
-http://static.ak.fbcdn.net/rsrc.php/zY/r/yFd4zWAl0Az.css
-http://static.ak.fbcdn.net/rsrc.php/zZ/p/r/7A3QMA2zvlH.js
-http://static.ak.fbcdn.net/rsrc.php/zZ/r/oyEaJ71hHm4.css
-http://static.ak.fbcdn.net/rsrc.php/zh/r/Ch71Zv858xU.png
-http://static.ak.fbcdn.net/rsrc.php/zk/r/asHLVuqKmoo.css
-http://static.ak.fbcdn.net/rsrc.php/zl/p/r/4A0A_IDcjJ7.js
-http://static.ak.fbcdn.net/rsrc.php/zo/r/UlIqmHJn-SK.gif
-http://twitter.com/favicon.ico
-http://www.cnet.com/3474-4_1-0.html?nomesh&refresh=1285963100506
-http://www.facebook.com/extern/login_status.php?access_token=false&api_key=16995676698&display=hidden&extern=2&locale=en_US&method=auth.status&next=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%23cb%3Df2fb9abfd91e64a%26origin%3Dhttp%253A%252F%252Fwww.cnet.com%252Ff226dba425468%26relation%3Dopener%26transport%3Dpostmessage%26frame%3Df22ae78bbc11b68%26result%3D%2522xxRESULTTOKENxx%2522&no_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%23cb%3Df7d5594a5dc862%26origin%3Dhttp%253A%252F%252Fwww.cnet.com%252Ff226dba425468%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df22ae78bbc11b68&no_user=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%23cb%3Df3e59d56fdcf604%26origin%3Dhttp%253A%252F%252Fwww.cnet.com%252Ff226dba425468%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df22ae78bbc11b68&ok_session=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%23cb%3Df1589c1246846bc%26origin%3Dhttp%253A%252F%252Fwww.cnet.com%252Ff226dba425468%26relation%3Dparent%26transport%3Dpostmessage%26frame%3Df22ae78bbc11b68&sdk=joey&session_version=3
-http://www.facebook.com/plugins/likebox.php?api_key=16995676698&channel=http%3A%2F%2Fstatic.ak.fbcdn.net%2Fconnect%2Fxd_proxy.php%23cb%3Df1261980aa2603c%26origin%3Dhttp%253A%252F%252Fwww.cnet.com%252Ff226dba425468%26relation%3Dparent.parent%26transport%3Dpostmessage&colorscheme=light&connections=10&header=false&height=255&href=http%3A%2F%2Fwww.facebook.com%2Fcnet&locale=en_US&sdk=joey&show_faces=false&stream=false&width=322
-https://statse.webtrendslive.com/dcsis0ifv10000gg3ag82u4rf_7b1e/dcs.gif?&dcsdat=1285963154138&dcssip=addons.mozilla.org&dcsuri=/en-US/firefox/extensions/&dcsref=https://addons.mozilla.org/en-US/firefox/addon/1865/&WT.co_f=2307c94c618302341791273294629172&WT.vtid=2307c94c618302341791273294629172&WT.vtvs=1285963145010&WT.tz=2&WT.bh=21&WT.ul=en-US&WT.cd=24&WT.sr=1366x768&WT.jo=No&WT.ti=Extensions%20::%20Add-ons%20for%20Firefox&WT.js=Yes&WT.jv=1.8&WT.ct=unknown&WT.bs=1366x391&WT.fv=10.1&WT.slv=Not%20enabled&WT.tv=8.6.2&WT.dl=0&WT.ssl=1&WT.es=addons.mozilla.org/en-US/firefox/extensions/&WT.vt_f_tlh=1285963145
-https://addons.mozilla.org/en-US/firefox/addons/buttons.js/build:37170e5
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/10137/1284766352
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/10868/1281641549
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/10900/1285801267
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/1368/1282976426
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/13990/1281050089
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/1419/1275608178
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/1843/1284003437
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/1865/1282080020
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/201/1284606438
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/2108/1281403223
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/220/1285888225
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/2257/1285176024
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/26/1282861221
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/3006/1280194126
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/3456/1284069729
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/60/1275607908
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/722/1285666032
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/748/1275608164
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/8174/1284910425
-https://addons.mozilla.org/en-US/firefox/images/addon_icon/8879/1281050080
-https://addons.mozilla.org/en-US/jsi18n//build:37170e5
-https://addons.mozilla.org/media//css/common-min.css?build=37170e5
-https://addons.mozilla.org/media//css/zamboni/z-min.css?build=37170e5
-https://addons.mozilla.org/media//img/amo2009/app-icons/firefox.png
-https://addons.mozilla.org/media//img/amo2009/blank.gif
-https://addons.mozilla.org/media//img/amo2009/illustrations/logo-add-ons-half.png
-https://addons.mozilla.org/media//img/favicon.ico
-https://addons.mozilla.org/media//img/zamboni/icons/button-icons.png
-https://addons.mozilla.org/media//img/zamboni/icons/no-14x14.png
-https://addons.mozilla.org/media//js/common-min.js?build=37170e5
-https://addons.mozilla.org/media//js/webtrends/webtrends-v0.1.js
-https://addons.mozilla.org/media/img/amo2009/bg/body.jpg
-https://addons.mozilla.org/media/img/amo2009/bg/border-header-user-options.gif
-https://addons.mozilla.org/media/img/amo2009/bg/button-green.jpg
-https://addons.mozilla.org/media/img/amo2009/bg/footer.png
-https://addons.mozilla.org/media/img/amo2009/bg/header-border.png
-https://addons.mozilla.org/media/img/amo2009/bg/heading-dark-blue.jpg
-https://addons.mozilla.org/media/img/amo2009/bg/listing-footer.gif
-https://addons.mozilla.org/media/img/amo2009/bg/listing-header.gif
-https://addons.mozilla.org/media/img/amo2009/bg/listing-item.png
-https://addons.mozilla.org/media/img/amo2009/icons/arrows.gif
-https://addons.mozilla.org/media/img/amo2009/icons/buttons/breadcrumb.gif
-https://addons.mozilla.org/media/img/amo2009/icons/buttons/go-green.gif
-https://addons.mozilla.org/media/img/amo2009/icons/magnifying-glass.gif
-https://addons.mozilla.org/media/img/amo2009/icons/stars.png
-https://addons.mozilla.org/media/img/amo2009/logo-mozilla.gif
-https://addons.mozilla.org/media/img/amo2009/tab-mozilla.png
diff --git a/mochitest/tests/performance/data/elemhide_selectors_testdata.html b/mochitest/tests/performance/data/elemhide_selectors_testdata.html
deleted file mode 100644
index 337589a..0000000
--- a/mochitest/tests/performance/data/elemhide_selectors_testdata.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<body>
- <script type="application/x-javascript;version=1.7">
- for (let i = 0; i < 100; i++)
- {
- let list = [];
- for (let j = 0; j < 100; j++)
- list.push('<div id="' + i + j + '" class="' + i + j + '"></div>');
- document.writeln(list.join("\n"));
- }
- </script>
-</body>
-</html>
\ No newline at end of file
diff --git a/mochitest/tests/performance/data/filters.txt b/mochitest/tests/performance/data/filters.txt
deleted file mode 100644
index 3d149b8..0000000
--- a/mochitest/tests/performance/data/filters.txt
+++ /dev/null
@@ -1,9736 +0,0 @@
-! Checksum: myezfBBqXCkJssWY+8Xbtw
-! EasyList - https://easylist.adblockplus.org/
-! Last modified: 26 Nov 2010 17:10 UTC
-! Expires: 5 days (update frequency)
-! Licence: https://easylist-downloads.adblockplus.org/COPYING
-!
-! Please report any unblocked adverts or problems
-! in the forums (http://forums.lanik.us/)
-! or via e-mail (easylist.subscription at gmail.com).
-!
-!-----------------General advert blocking filters-----------------!
-! *** easylist_general_block.txt ***
-&ad_keyword=
-&ad_type_
-&adname=
-&adspace=
-&adtype=
-&advertiserid=
-&clientype=*&adid=
-&googleadword=
-&program=revshare&
-+adverts/
--ad-large.
--ad-loading.
--ad-manager/
--ad-util-
--ad1.jpg
--ad2.gif
--adhelper.
--advert-
--banner-ads/
--bin/ad_
--content/adsys/
--contest-ad.
--images/ad-
--inspire-ad.
--leaderboard-ad-
--panel_ad_
--rebels-ads/
--text-ads.
--third-ad.
-.ad.footer.
-.ad.page.
-.ad.premiere.
-.adplacement=
-.adriver.
-.ads.darla.
-.adserv/*
-.adserver.
-.aspx?ad=
-.aspx?zoneid=*&task=
-.au/_ads/
-.au/ads/
-.biz/ad.
-.ca/ads/
-.cc/ads/
-.com/ad-
-.com/ad.
-.com/ad/
-.com/ad1.
-.com/ad2.
-.com/ad2/
-.com/ad?
-.com/ad_
-.com/adlib/
-.com/adops/
-.com/ads-
-.com/ads.
-.com/ads/$image,object,subdocument
-.com/ads?
-.com/ads_
-.com/advt/
-.com/adx/
-.com/gad/
-.com/gads/
-.com/openx/
-.com/ss/ad/
-.html?ad=
-.in/ads/
-.info/ads/
-.jp/ads/
-.ke/ads/
-.net/_ads/
-.net/ad/$~object_subrequest
-.net/ads/
-.net/ads2/
-.net/ads3/
-.net/ads_
-.nz/ads/
-.org/ad/
-.org/ad2_
-.org/ad_
-.org/ads-
-.org/ads/
-.org/gads/
-.ph/ads/
-.php?bannerid=
-.php?zoneid=*&loc=
-.swf?clicktag=
-.to/ad.php|
-.to/ads/
-.tv/ads/
-.uk/ads/
-.us/ads/
-.za/ads/
-/*;cue=pre;$object_subrequest
-/120ad.gif
-/468ad.gif
-/468xads.
-/?addyn|*
-/?advideo/*
-/a2/ads/*
-/aamsz=*/acc_random=
-/aamsz=*/pageid=
-/aamsz=*/position=
-/abm.asp?z=
-/abmw.asp?z=
-/abmw.aspx
-/acc_random=*/aamsz=
-/ad-468-
-/ad-amz.
-/ad-banner-
-/ad-box-
-/ad-cdn.
-/ad-frame.
-/ad-header.
-/ad-hug.
-/ad-iframe-
-/ad-inject/*
-/ad-leaderboard.
-/ad-letter.
-/ad-loader-
-/ad-local.
-/ad-managment/*
-/ad-server/*
-/ad-template/*
-/ad-top-
-/ad-topbanner-
-/ad-vert.
-/ad-vertical-
-/ad.asp?
-/ad.cgi?
-/ad.css?
-/ad.epl?
-/ad.jsp?
-/ad.mason?
-/ad.php?
-/ad/files/*
-/ad/iframe/*
-/ad/img/*
-/ad/script/*
-/ad/side_
-/ad/takeover/*
-/ad1.html
-/ad160.php
-/ad160x600.
-/ad1place.
-/ad1x1home.
-/ad2.aspx
-/ad2.html
-/ad2border.
-/ad300.htm
-/ad300x145.
-/ad350.html
-/ad728.php
-/ad728x15.
-/ad?count=
-/ad_300x250.
-/ad_agency/*
-/ad_area.
-/ad_banner.
-/ad_banner/*
-/ad_banner_
-/ad_bottom.
-/ad_bsb.
-/ad_campaigns/*
-/ad_code.
-/ad_configuration.
-/ad_content.
-/ad_count.
-/ad_creatives.
-/ad_editorials_
-/ad_engine?
-/ad_feed.js?
-/ad_footer.
-/ad_forum_
-/ad_frame.
-/ad_function.
-/ad_gif/*
-/ad_google.
-/ad_header_
-/ad_holder/*
-/ad_horizontal.
-/ad_html/*
-/ad_iframe.
-/ad_iframe_
-/ad_insert.
-/ad_jnaught/*
-/ad_label_
-/ad_leader.
-/ad_left.
-/ad_legend_
-/ad_link.
-/ad_load.
-/ad_manager.
-/ad_mpu.
-/ad_notice.
-/ad_os.php?
-/ad_page_
-/ad_print.
-/ad_rectangle_
-/ad_refresher.
-/ad_reloader_
-/ad_right.
-/ad_rotation.
-/ad_rotator.
-/ad_rotator_
-/ad_script.
-/ad_serv.
-/ad_serve.
-/ad_server.
-/ad_server/*
-/ad_sizes=
-/ad_skin_
-/ad_sky.
-/ad_skyscraper.
-/ad_slideout.
-/ad_space.
-/ad_square.
-/ad_supertile/*
-/ad_tag.
-/ad_tag_
-/ad_tags_
-/ad_tile/*
-/ad_title_
-/ad_top.
-/ad_topgray2.
-/ad_tpl.
-/ad_upload/*
-/ad_vert.
-/ad_vertical.
-/ad_view_
-/adaffiliate_
-/adanim/*
-/adaptvadplayer.
-/adbanner.
-/adbanner/*
-/adbanner_
-/adbanners/*
-/adbar.aspx
-/adbg.jpg
-/adbot_promos/*
-/adbottom.
-/adbox.gif
-/adbox.js
-/adbox.php
-/adboxes/*
-/adbrite.
-/adbureau.
-/adcde.js
-/adcell/*
-/adcentral.
-/adchannel_
-/adclick.
-/adclient.
-/adclient/*
-/adclutter.
-/adcode.
-/adcode/*
-/adcodes/*
-/adcollector.
-/adcomponent/*
-/adconfig.js
-/adconfig.xml?
-/adconfig/*
-/adcontent.$~object_subrequest
-/adcontroller.
-/adcreative.
-/adcycle.
-/adcycle/*
-/addeals/*
-/addelivery/*
-/addyn/3.0/*
-/addyn|*|adtech;
-/adengage1.
-/adengage_
-/adengine/*
-/adexclude/*
-/adf.cgi?
-/adfactory.
-/adfarm.
-/adfetch?
-/adfetcher?
-/adfever_
-/adfile/*
-/adfooter.
-/adframe.
-/adframe/*
-/adframe?
-/adframe_
-/adframebottom.
-/adframemiddle.
-/adframetop.
-/adfshow?
-/adfunction.
-/adfunctions.
-/adgitize-
-/adgraphics/*
-/adguru.
-/adhalfbanner.
-/adhandler.
-/adhandler/*
-/adheader.
-/adheadertxt.
-/adhomepage.
-/adhtml/*
-/adhug_jc.
-/adiframe.
-/adiframe/*
-/adiframe?
-/adiframeanchor.
-/adiframem1.
-/adiframem2.
-/adiframetop.
-/adify_box.
-/adify_leader.
-/adify_sky.
-/adimage.
-/adimages.
-/adimages/*$~subdocument
-/adindex/*
-/adinjector.
-/adinsert.
-/adinterax.
-/adjs.php?
-/adjsmp.
-/adlabel.
-/adlabel_
-/adlayer.
-/adlayer/*
-/adleader.
-/adlink-
-/adlink.
-/adlink_
-/adlinks.
-/adlist_
-/adloader.
-/adm/ad/*
-/adman.js
-/adman/image/*
-/adman/www/*
-/admanagement/*
-/admanagementadvanced.
-/admanager.$~object_subrequest
-/admanager/*$~object_subrequest
-/admanager3.
-/admanagers/*
-/admanagerstatus/*
-/admarket/*
-/admaster.
-/admaster?
-/admedia.
-/admedia/*
-/admega.
-/admentor/*
-/admicro2.
-/admicro_
-/admin/ad_
-/adminibanner2.
-/adnetmedia.
-/adnetwork.
-/adnews.
-/adnext.
-/adng.html
-/adnotice.
-/adonline.
-/adotubeplugin.
-/adp.htm
-/adpage.
-/adpage/*
-/adpartner.
-/adpeeps.
-/adpeeps/*
-/adplayer.
-/adplayer/*
-/adplugin.
-/adpoint.
-/adpool/*
-/adpopup.
-/adproducts/*
-/adproxy.
-/adproxy/*
-/adrelated.
-/adreload?
-/adremote.
-/adrevenue/*
-/adrevolver/*
-/adriver.
-/adriver_
-/adrolays.
-/adroller.
-/adroot/*
-/adrot.js
-/adrotator/*
-/adrotv2.
-/adruptive.
-/ads-banner.
-/ads-common.
-/ads-footer.
-/ads-leader|
-/ads-rectangle.
-/ads-rec|
-/ads-right.
-/ads-service.
-/ads-skyscraper.
-/ads-sky|
-/ads.asp?
-/ads.dll/*
-/ads.gif
-/ads.htm
-/ads.jsp
-/ads.php?
-/ads.pl?
-/ads/2010/*
-/ads/cnvideo/*
-/ads/common/*
-/ads/footer_
-/ads/freewheel/*
-/ads/home/*
-/ads/house/*
-/ads/images/*
-/ads/indexsponsors/*
-/ads/interstitial/*
-/ads/labels/*
-/ads/layer.
-/ads/leaderboard_
-/ads/openx/*
-/ads/preloader/*
-/ads/preroll_
-/ads/promo_
-/ads/rectangle_
-/ads/sponsor_
-/ads/square-
-/ads/third-party/*
-/ads09a/*
-/ads2.html
-/ads2.php
-/ads2_2.
-/ads2_header.
-/ads9.dll
-/ads?id=
-/ads_code.
-/ads_global.
-/ads_google.
-/ads_iframe.
-/ads_openx/*
-/ads_php/*
-/ads_reporting/*
-/ads_yahoo.
-/adsa468.
-/adsa728.
-/adsadview.
-/adsales/*
-/adsatt.
-/adsbanner.
-/adsbannerjs.
-/adscale_
-/adscluster.
-/adscontent.
-/adscontent2.
-/adscript.
-/adscript_
-/adscripts/*
-/adscroll.
-/adsdaqbanner_
-/adsdaqbox_
-/adsdaqsky_
-/adsearch.
-/adsense-
-/adsense.
-/adsense/*
-/adsense23.
-/adsense24.
-/adsense?
-/adsense_
-/adsensegb.
-/adsensegoogle.
-/adsensets.
-/adserv.
-/adserv2.
-/adserve.
-/adserve/*
-/adserver.
-/adserver/*
-/adserver2.
-/adserver2/*
-/adserver?
-/adserver_
-/adserversolutions/*
-/adservices/*
-/adservice|
-/adserving.
-/adsfac.
-/adsfetch.
-/adsfile.
-/adsfolder/*
-/adsframe.
-/adshandler.
-/adsheader.
-/adshow.
-/adshow?
-/adshow_
-/adsiframe/*
-/adsign.
-/adsimage/*
-/adsinclude.
-/adsinsert.
-/adsky.php
-/adskyright.
-/adskyscraper.
-/adslots.
-/adslug-
-/adslug_
-/adsmanagement/*
-/adsmanager/*
-/adsmedia_
-/adsnew.
-/adsonar.
-/adsopenx/*
-/adspace.
-/adspace/*
-/adspaces.
-/adsponsor.
-/adspro/*
-/adsquare.
-/adsremote.
-/adsreporting/*
-/adsrich.
-/adsright.
-/adsrotate.
-/adsrule.
-/adsserv.
-/adssrv.
-/adstemplate/*
-/adstorage.
-/adstracking.
-/adstream.
-/adstream_
-/adstub.
-/adstubs/*
-/adswap.
-/adswap/*
-/adswide.
-/adswidejs.
-/adswrapper.
-/adsx728.
-/adsx_728.
-/adsync/*
-/adsyndication.
-/adsyndication/*
-/adsys/ads.
-/adsystem/*
-/adtag/type/*
-/adtago.
-/adtags.
-/adtags/*
-/adtagtc.
-/adtagtranslator.
-/adtech.
-/adtech/*
-/adtech;
-/adtech_
-/adtext.
-/adtext4.
-/adtext_
-/adtitle.
-/adtology.
-/adtonomy.
-/adtop.do
-/adtop.js
-/adtrack/*
-/adtraff.
-/adtvideo.
-/adtype.
-/adunits/*
-/adv/ads/*
-/adverserve.
-/advert-$~stylesheet
-/advert.$domain=~kp.ru
-/advert/*
-/advert?
-/advert_
-/advertise-
-/advertise.
-/advertise/*
-/advertisehere.
-/advertisement-
-/advertisement.
-/advertisement/*
-/advertisement2.
-/advertisement_
-/advertisementheader.
-/advertisementrotation.
-/advertisements.
-/advertisements/*
-/advertisementview/*
-/advertiser/*
-/advertisers/*
-/advertising.
-/advertising/*$~object,~object_subrequest
-/advertising2.
-/advertising_
-/advertisingcontent/*
-/advertisingmanual.
-/advertisingmodule.
-/advertisings.
-/advertisingwidgets/*
-/advertisment.
-/advertisments/*
-/advertize_
-/advertmedia/*
-/advertorials/*
-/advertphp/*
-/advertpro/*
-/adverts.
-/adverts/*
-/adverts_
-/adview.
-/adview?
-/adviewer.
-/advision.
-/advolatility.
-/advpartnerinit.
-/adwords/*
-/adworks.
-/adworks/*
-/adwrapper/*
-/adwrapperiframe.
-/adxx.php?
-/adzone.
-/adzone_
-/adzones/*
-/aff_frame.
-/affad?q=
-/affads/*
-/affclick/*
-/affilatebanner.
-/affiliate/banners/*
-/affiliate/script.php?
-/affiliate_banners/*
-/affiliate_resources/*
-/affiliatebanner/*
-/affiliatebanners/*
-/affiliateimages/*
-/affiliatelinks.
-/affiliates.*.aspx?
-/affiliates/banner
-/affiliatewiz/*
-/affiliation/*
-/affiliationcash.
-/affilinet/ads/*
-/afimages.
-/afr.php?
-/ajax/ads/*
-/ajrotator/*
-/ajs.php?
-/annonser/*
-/api/ads/*
-/app/ads.js
-/article_ad.
-/as3adplayer.
-/aseadnshow.
-/aspbanner_inc.asp?
-/assets/ads/*
-/audioads/*
-/auditudeadunit.
-/austria_ad.
-/auto_ad_
-/back-ad.
-/ban_m.php?
-/banimpress.
-/banman.asp?
-/banman/*
-/banner-ad-
-/banner-ad/*
-/banner-ads/*
-/banner/ad_
-/banner/affiliate/*
-/banner_468.
-/banner_ad.
-/banner_ad_
-/banner_ads.
-/banner_ads_
-/banner_adv/*
-/banner_advert/*
-/banner_control.php?
-/banner_db.php?
-/banner_file.php?
-/banner_js.*?
-/banner_management/*
-/banner_skyscraper.
-/bannerad.
-/bannerad_
-/bannerads-
-/bannerads/*
-/banneradviva.
-/bannercode.php
-/bannerconduit.swf?
-/bannerexchange/*
-/bannerfarm/*
-/bannerframe.*?
-/bannerframeopenads.
-/bannerframeopenads_
-/bannermanager/*
-/bannermedia/*
-/bannerrotation.
-/bannerrotation/*
-/banners.*&iframe=
-/banners/affiliate/*
-/banners/promo/*
-/banners_rotation.
-/bannerscript/*
-/bannerserver/*
-/bannersyndication.
-/bannerview.*?
-/bannery/*?banner=
-/bar-ad.
-/baselinead.
-/basic/ad/*
-/behaviorads/*
-/beta-ad.
-/bg-ad.jpg|
-/bg/ads/*
-/bg_ads_
-/bi_affiliate.js
-/bigad.p
-/bigboxad.
-/bkgrndads/*
-/blocks/ads/*
-/blogad_
-/blogads.
-/blogads/*
-/blogads3/*
-/blogoas-
-/bmndoubleclickad.
-/bnrsrv.*?
-/bodyads/*
-/boomad.
-/bottom_ad.
-/bottomad.
-/bottomad/*
-/btn_ad_
-/bucketads.
-/butler.php?type=
-/buttonads.
-/buyad.html
-/buyclicks/*
-/buysellads.
-/bw_adsys.
-/bytemark_ad.
-/campus/ads/*
-/cashad.
-/cashad2.
-/central/ads/*
-/cgi-bin/ads/*
-/channelblockads.
-/chinaadclient.
-/chitika-ad?
-/circads.
-/cms/js/ad_
-/cn-fe-ads/*
-/cnnslads.
-/cnwk.1d/ads/*
-/coldseal_ad.
-/commercial_horizontal.
-/commercial_top.
-/commercials/*
-/common/ad/*
-/common/ads/*
-/companion_ads.
-/content/ad_
-/content_ad.
-/content_ad_
-/contentadxxl.
-/contentad|
-/contextad.
-/controller/ads/*
-/corner_ads/*
-/country_ad.
-/cpxads.
-/ctamlive160x160.
-/customad.
-/customadsense.
-/cvs/ads/*
-/cwggoogleadshow.
-/dart_ads/*
-/dartadengine.
-/dartads.
-/dateads.
-/dclk_ads.
-/dclk_ads_
-/dcloadads/*
-/de/ads/*
-/defer_ads.
-/deferads.
-/deliver.nmi?
-/deliverad/*
-/deliverjs.nmi?
-/delivery/ag.php
-/delivery/al.php
-/delivery/apu.php
-/delivery/avw.php
-/descpopup.js
-/direct_ads.
-/directads.
-/display_ads.
-/displayad.
-/displayad?
-/displayads/*
-/dne_ad.
-/dnsads.html?
-/doors/ads/*
-/doubleclick.phpi?
-/doubleclick/iframe.
-/doubleclick_ads.
-/doubleclick_ads/*
-/doubleclickcontainer.
-/doubleclicktag.
-/download/ad.
-/download/ad/*
-/drawad.php?
-/drivingrevenue/*
-/dsg/bnn/*
-/dxd/ads/*
-/dyn_banner.
-/dyn_banners_
-/dynamic/ads/*
-/dynamicad?
-/dynamiccsad?
-/dynamicvideoad?
-/dynanews/ad-
-/dynbanner/flash/*
-/ebay_ads/*
-/emailads/*
-/emediatead.
-/eng/ads/*
-/ext_ads.
-/external/ad.
-/external/ads/*
-/external_ads.
-/eyewondermanagement.
-/eyewondermanagement28.
-/fastclick160.
-/fastclick728.
-/fatads.
-/featuredadshome.
-/file/ad.
-/files/ad/*
-/files/ads/*
-/fimserve.
-/flash/ad_
-/flash/ads/*
-/flashad.
-/flashads.
-/flashads/*
-/floatingads.
-/footad-
-/footer-ad-
-/footer_ad_
-/framead-
-/framead.
-/framead/*
-/framead_
-/frequencyads.
-/frnads.
-/fuseads/*
-/gads.html
-/gads.js
-/gafsads?
-/galleryad.
-/gamead/*
-/gamersad.
-/genericrichmediabannerad/*
-/geo-ads_
-/geo/ads.
-/get-ad.
-/getad.aspx
-/getad.js
-/getad.php?
-/getad.php|
-/getad?n=
-/getadframe.
-/getads/*
-/getadvertimageservlet?
-/getarticleadvertimageservlet?
-/getbanner.cfm?
-/gethalfpagead.
-/getmarketplaceads.
-/getsponslinks.
-/getsponslinksauto.
-/getvdopiaads.
-/getvideoad.
-/gexternalad.
-/gfx/ads/*
-/glam_ads.
-/google-ad?
-/google-ads.
-/google-adsense-
-/google-adsense.
-/google_ad_
-/google_ads.
-/google_ads/*
-/google_ads_
-/google_adsense.
-/google_adsense_
-/google_afc.
-/googlead-
-/googlead.
-/googlead_
-/googleadhtml/*
-/googleadright.
-/googleads-
-/googleads.
-/googleads2.
-/googleads3widetext.
-/googleads_
-/googleadsafs_
-/googleadsense.
-/googleafs.
-/graphics/ad_
-/gt6skyadtop.
-/header_ads_
-/headerads.
-/headvert.
-/hitbar_ad_
-/homepage_ads/*
-/house-ads/*
-/house_ad-
-/house_ad_
-/housead/*
-/houseads.
-/houseads/*
-/houseads?
-/hoverad.
-/html.ng/*
-/htmlads/*
-/httpads/*
-/icon_ad.
-/idevaffiliate/*
-/iframe-ads/*
-/iframe/ad/*
-/iframe_ad.
-/iframe_ad?
-/iframe_ads/*
-/iframe_ads?
-/iframe_chitika_
-/iframead.
-/iframead/*
-/iframead_
-/iframeadsense.
-/iframeadsensewrapper.
-/iframedartad.
-/im-ad/im-rotator.
-/im-ad/im-rotator2.
-/imads.js
-/image/ads/*
-/image_ads/*
-/images/ad-
-/images/ad.
-/images/ad/*
-/images/ad1.
-/images/ad125.
-/images/ad2.
-/images/ad4.
-/images/ad5.
-/images/ad_
-/images/ads-
-/images/ads/*
-/images/ads_
-/images/aff-
-/images/gads_
-/images/sponsored/*
-/images_jtads/*
-/img/ad/*
-/img/ad_
-/img/ads/*
-/img/sponsor/*
-/img/topad_
-/imgs/ads/*
-/inad.js
-/inad.php
-/inc/ads/*
-/include/ads/*
-/include/boxad_
-/include/skyad_
-/included_ads/*
-/includes/ad_
-/includes/ads/*
-/incmpuad.
-/index-ad.
-/index_ads.
-/inline_ad.
-/inline_ad_
-/innerads.
-/insertads.
-/instreamad/*
-/intellitext.js
-/interad.
-/intextads.
-/introduction_ad.
-/invideoad.
-/inx-ad.
-/ipadad.
-/irc_ad_
-/ireel/ad*.jpg
-/ispy/ads/*
-/iwadsense.
-/j/ads.js
-/jivoxadplayer.
-/jlist-affiliates/*
-/js/ads-
-/js/ads/*
-/js/ads_
-/jsadscripts/*
-/jsfiles/ads/*
-/jstextad.
-/keyade.js
-/kredit-ad.
-/label-advertisement.
-/layer-ad.
-/layer-ads.
-/layer/ad.
-/layer/ads.
-/layerad-
-/layerads_
-/layout/ads/*
-/lbl_ad.
-/leader_ad.
-/leftad_
-/linkads.
-/links_sponsored_
-/linkshare/*
-/liveads.
-/loadad.aspx?
-/loadadwiz.
-/local_ads_
-/lotto_ad_
-/lrec_ad.
-/mac-ad?
-/magic-ads/*
-/main/ad_
-/main_ad.
-/main_ad/*
-/mainad.
-/mbn_ad.
-/mcad.php
-/media/ads/*
-/megaad.
-/metaadserver/*
-/mini-ads/*
-/mini_ads.
-/mint/ads/*
-/misc/ad-
-/miva_ads.
-/mnetorfad.js
-/mobile_ad.
-/mobilephonesad/*
-/mod/adman/*
-/mod_ad/*
-/modalad.
-/modules/ad_
-/modules/ads/*
-/mpumessage.
-/msnadimg.
-/msnads/*
-/mstextad?
-/mtvi_ads_
-/mylayer-ad/*
-/mysimpleads/*
-/neoads.
-/new/ad/*
-/newads.
-/newrightcolad.
-/news_ad.
-/newtopmsgad.
-/nextad/*
-/o2contentad.
-/oas-config.
-/oas_ad_
-/oasadframe.
-/oasadfunctionlive.
-/oascentral.$~object_subrequest
-/oasdefault/*
-/oasisi-*.php?
-/oasisi.php?
-/oiopub-direct/*$~stylesheet
-/omb-ad-
-/online/ads/*
-/openads-
-/openads.
-/openads/*
-/openads2/*
-/openx/www/*
-/openx_fl.
-/other/ads/*
-/overlay_ad_
-/ovt_show.asp?
-/page-ads.
-/pagead/ads?
-/pageadimg/*
-/pageads/*
-/pageear.
-/pageear/*
-/pageear_
-/pagepeel-
-/pagepeel.
-/pagepeel/*
-/pagepeel_banner/*
-/pagepeelads.
-/paidlisting/*
-/partnerads/*
-/partnerads_
-/partnerbanner.
-/partnerbanner/*
-/partners/ads/*
-/partnersadbutler/*
-/peel.js
-/peel/?webscr=
-/peel1.js
-/peelad.
-/peelad/*
-/peeljs.php
-/perfads.
-/performancingads/*
-/phpads.
-/phpads/*
-/phpads2/*
-/phpadserver/*
-/phpadsnew/*
-/pictures/ads/*
-/pilot_ad.
-/pitattoad.
-/pix/ad/*
-/pix/ads/*
-/pixelads/*
-/play/ad/*
-/player/ads/*
-/pool.ads.
-/pop_ad.
-/popads.
-/popads/*
-/popunder.
-/position=*/aamsz=
-/post_ads_
-/ppd_ads.
-/predictad.
-/premierebtnad/*
-/premium_ad.
-/premiumads/*
-/previews/ad/*
-/printad.
-/printad/*
-/printads/*
-/processads.
-/promo/ad_
-/promobuttonad.
-/promotions/ads.
-/promotions/ads?
-/protection/ad/*
-/pub/ad/*
-/pub/ads/*
-/public/ad/*
-/public/ad?
-/publicidad.$~object_subrequest
-/publicidad/*
-/qandaads/*
-/quadadvert.
-/questions/ads/*
-/radopenx?
-/radwindowclient.js
-/railad.
-/railads.
-/railsad.
-/random=*/aamsz=
-/randomad.
-/randomad2.
-/rcolads1.
-/rcolads2.
-/rcom-ads.
-/realmedia/ads/*
-/rec_ad1.
-/reclame/*
-/rectangle_ad.
-/refreshads-
-/reklam.
-/reklama.
-/related-ads.
-/relatedads.
-/requestadvertisement.
-/requestmyspacead.
-/resources/ads/*
-/retrad.
-/richmedia.adv?
-/right-ad-
-/right_ads?
-/rightad.
-/rightnavads.
-/rightnavadsanswer.
-/rotads/*
-/rotateads.
-/rotatingpeels.js
-/rsads.js
-/rsads/c
-/rsads/r
-/rsads/u
-/rss/ads/*
-/salesad/*
-/satnetads.
-/satnetgoogleads.
-/sb-relevance.js
-/scanscoutoverlayadrenderer.
-/scaradcontrol.
-/script/oas/*
-/scripts/ad-
-/scripts/ad.
-/scripts/ad/*
-/scripts/ads/*
-/scripts/clickjs.php
-/search/ad/*
-/search/ads?
-/searchad.
-/searchads/*
-/secondads.
-/secondads_
-/serveads.
-/services/ads/*
-/sevenl_ad.
-/share/ads/*
-/shared/ads/*
-/show-ad.
-/show_ad.
-/show_ad_
-/show_ads.js
-/show_ads_
-/showad.
-/showad/*
-/showad_
-/showads.
-/showads/*
-/showadvertising.
-/showflashad.
-/showlayer.
-/showmarketingmaterial.
-/side-ad-
-/side-ads-
-/sidead.
-/sideads/*
-/sideads|
-/sidebar_ad.
-/sidebarad/*
-/sidecol_ad.
-/silver/ads/*
-/site_ads.
-/siteads.
-/siteads/*
-/siteafs.txt?
-/sites/ad_
-/skyad.php
-/skyadjs/*
-/skybar_ad.
-/skyframeopenads.
-/skyframeopenads_
-/skyscraperad.
-/slideadverts/*
-/slideinad.
-/small_ad.
-/smartad.
-/smartads.
-/smartlinks.
-/smb/ads/*
-/socialads.
-/socialads/*
-/someads.
-/spc.php?
-/spcjs.php?
-/special-ads/*
-/special_ads/*
-/specials/htads/*
-/spo_show.asp?
-/sponser.
-/sponsimages/*
-/sponslink_
-/sponsor-ad|
-/sponsor-right.
-/sponsor-top.
-/sponsor_images/*
-/sponsorad.
-/sponsoradds/*
-/sponsorads/*
-/sponsored_ad.
-/sponsored_links_
-/sponsored_text.
-/sponsored_top.
-/sponsoredcontent.
-/sponsoredlinks.
-/sponsoredlinks/*
-/sponsoredlinksiframe.
-/sponsoring/*
-/sponsorpaynetwork.
-/sponsors_box.
-/sponsorship_
-/sponsorstrips/*
-/square-ads/*
-/squaread.
-/srv/ad/*
-/static/ad_
-/static/ads/*
-/stickyad.
-/storage/ads/*
-/story_ad.
-/subad2_
-/superads_
-/swf/ad-
-/swf/ad3-
-/synad2.
-/system/ad/*
-/systemad.
-/systemad_
-/taxonomy-ads.
-/td_ads/*
-/tdlads/*
-/templates/_ads/*
-/templates/ads/*
-/testingad.
-/textad.
-/textad/*
-/textad?
-/textadrotate.
-/textads/*
-/textads_
-/thirdparty/ad/*
-/thirdpartyads/*
-/tii_ads.
-/tikilink?
-/title_ad.
-/tmo/ads/*
-/tmobilead.
-/toigoogleads.
-/toolkitads.
-/tools/ad.
-/top-ad-
-/top_ad.
-/top_ad_
-/top_ads/*
-/top_ads_
-/topad.h
-/topad.php
-/topads.
-/topperad.
-/tracked_ad.
-/tradead_
-/tribalad.
-/tripplead/*
-/ttz_ad.
-/tx_macinabanners/*
-/txt_ad.
-/ukc-ad.
-/unibluead.
-/unity/ad/*
-/update_ads/*
-/upload/ads/*
-/uploads/ads/*
-/us-adcentre.
-/valueclick.
-/vclkads.
-/video/ads/*
-/video_ad.
-/video_ad_
-/videoad.
-/videoadrenderer.
-/videoads.
-/videoads/*
-/videowall-ad.
-/view/banner/*/zone?zid=
-/vtextads.
-/wallpaperads/*
-/webad?a
-/webadimg/*
-/webads.
-/webads_
-/webadverts/*
-/welcome_ad.
-/widget/ads.
-/wipeads/*
-/wp-content/ads/*
-/wp-content/plugins/fasterim-optin/*
-/wp-srv/ad/*
-/wpads/iframe.
-/writelayerad.
-/www/ads/*
-/www/delivery/*
-/xmladparser.
-/yahoo-ads/*
-/yahooads.
-/your-ad.
-/ysmads.
-/zanox.js
-/zanox/banner/*
-/zanox_ad/*
-2010/ads/
-8080/ads/
-;adsense_
-;iframeid=ad_
-=adtech_
-=advert/
-=advertorial&
-?ad_ids=
-?ad_type=
-?ad_width=
-?adarea=
-?adclass=
-?adpage=
-?adpartner=
-?adsize=
-?adslot=
-?adtype=
-?advertising=
-?advtile=
-?advurl=
-?file=ads&
-?getad=&$~object_subrequest
-?goto=ad|
-?view=ad&
-_140x600_
-_160_ad_
-_acorn_ad_
-_ad.php?
-_ad120x120_
-_ad234x90-
-_ad_big.
-_ad_bsb.
-_ad_code.
-_ad_content.
-_ad_controller.
-_ad_count.
-_ad_courier.
-_ad_engine/
-_ad_footer.
-_ad_homepage.
-_ad_iframe.
-_ad_images/
-_ad_label.
-_ad_leaderboard.
-_ad_placeholder-
-_ad_right.
-_ad_skyscraper.
-_ad_square.
-_ad_widesky.
-_adagency/
-_adbanner.
-_adbreak.
-_adcall_
-_adengine_
-_adfunction.
-_adpage=
-_adpartner.
-_adplugin.
-_ads.html
-_ads.php?
-_ads/script.
-_ads1.asp
-_ads?pid=
-_ads_index_
-_ads_reporting.
-_ads_single_
-_adserve/
-_adshare.
-_adshow.
-_adsjs.php?
-_adsys.js
-_adtext_
-_adtitle.
-_advert.
-_advert1.
-_advertise.
-_advertise180.
-_advertisehere.
-_advertisement.
-_advertisement_
-_advertising/
-_advertisment.
-_advertorials/
-_adwrap.
-_afs_ads.
-_argus_ad_
-_assets/ads/
-_background_ad/
-_banner_adv_
-_bannerad.
-_blogads.
-_bottom_ads_
-_box_ads/
-_buttonad.
-_companionad.
-_contest_ad_
-_contest_ads/
-_custom_ad.
-_custom_ad_
-_displaytopads.
-_dynamicads/
-_externalad.
-_fach_ad.
-_fd_adbg1a.
-_fd_adbg2.
-_fd_adbg2a.
-_fd_adtop.
-_feast_ad.
-_gads_bottom.
-_gads_footer.
-_gads_top.
-_headerad.
-_home_adrow-
-_images/ads/
-_inc/adsrc.
-_index_ad.
-_mainad.
-_media/ads/*
-_mmsadbanner/
-_org_ad.
-_overlay_ad.
-_paidadvert_
-_player_ads_
-_psu_ad.
-_request_ad.
-_right_ad.
-_special_ads/
-_stack_ads/
-_temp/ad_
-_top_ad.
-_topad.php
-_tribalfusion.
-_videoad.
-a/adx.js
-couk/ads/
-d/adx.js
-e/adx.js
-m/adbox/
-m/adx.js
-m/topads|
-n/adx.js
-s/adx.js
-t/adx.js
-u/adx.js
-z/adx.js
-|http://a.ads.
-|http://ad-uk.
-|http://ad.$~object_subrequest,domain=~europa.eu|~gogopin.com|~sjsu.edu|~uitm.edu.my|~uni-freiburg.de
-|http://ad0.
-|http://ad1.
-|http://ad2.$domain=~ad2.zophar.net
-|http://ad3.
-|http://ad4.
-|http://ad5.
-|http://ad6.
-|http://ad7.
-|http://adbox.
-|http://adimg.
-|http://adnet.
-|http://ads.$domain=~ahds.ac.uk
-|http://ads0.
-|http://ads1.
-|http://ads18.
-|http://ads2.
-|http://ads3.
-|http://ads4.
-|http://ads5.
-|http://adserv
-|http://adseu.
-|http://adsrv.
-|http://adsvr.
-|http://adsys.
-|http://adtag.
-|http://adver.
-|http://advertiser.
-|http://bwp.*/search
-|http://feeds.*/~a/
-|http://getad.
-|http://jazad.
-|http://openx.
-|http://pubad.
-|http://rss.*/~a/
-|http://synad.
-|http://u-ads.
-|http://wrapper.*/a?
-|https://ads.
-||adserver1.
-!Dimensions
--120x60-
--120x60.
--160x600.
--360x110.
--468_60.
--468x60-
--468x60.
--468x60/
--468x60_
--468x80-
--468x80.
--468x80/
--468x80_
--480x60-
--480x60.
--480x60/
--480x60_
--728x90-
--728x90.
--728x90/
--728x90_
-.468x60-
-.468x60.
-.468x60/
-.468x60_
-.468x80-
-.468x80.
-.468x80/
-.468x80_
-.480x60-
-.480x60.
-.480x60/
-.480x60_
-.728x90-
-.728x90.
-.728x90/
-.728x90_
-.com/160_
-.com/728_
-/125x125_banner.
-/160x600.
-/180x150-
-/180x150_
-/250x250.
-/300x250-
-/300x250.
-/300x250_
-/468-60.
-/468_60.
-/468x60-
-/468x60.
-/468x60/*
-/468x60_
-/468x80-
-/468x80.
-/468x80/*
-/468x80_
-/480x60-
-/480x60.
-/480x60/*
-/480x60_
-/600x160_
-/728_90/*
-/728x79_
-/728x90-
-/728x90.
-/728x90/*
-/728x90_
-/768x90-
-=300x250;
-_120_600
-_120x60.
-_120x600.
-_120x60_
-_160_600_
-_160x600_
-_300_250_
-_300x250-
-_300x250_
-_460x60.
-_468-60.
-_468.gif
-_468.htm
-_468_60.
-_468_60_
-_468x120.
-_468x60-
-_468x60.
-_468x60/
-_468x60_
-_468x80-
-_468x80.
-_468x80/
-_468x80_
-_468x90.
-_480x60-
-_480x60.
-_480x60/
-_480x60_
-_720x90.
-_728.gif
-_728.htm
-_728_90.
-_728_90_
-_728x90-
-_728x90.
-_728x90/
-_728x90_
-_768x90_
-!-----------------General element hiding rules-----------------!
-! *** easylist_general_hide.txt ***
-###A9AdsMiddleBoxTop
-###A9AdsOutOfStockWidgetTop
-###A9AdsServicesWidgetTop
-###ADSLOT_1
-###ADSLOT_2
-###ADSLOT_3
-###ADSLOT_4
-###AD_CONTROL_22
-###ADsmallWrapper
-~digitalhome.ca###Ad1
-###Ad160x600
-###Ad2
-###Ad300x250
-###Ad3Left
-###Ad3Right
-###Ad3TextAd
-###AdBanner_F1
-###AdBar
-###AdBar1
-###AdContainerTop
-###AdContentModule_F
-###AdDetails_GoogleLinksBottom
-###AdDetails_InsureWith
-###AdFrame4
-~ksl.com###AdHeader
-###AdMiddle
-###AdMobileLink
-###AdRectangle
-###AdSenseDiv
-###AdServer
-###AdShowcase_F1
-###AdSky23
-###AdSkyscraper
-###AdSponsor_SF
-###AdSubsectionShowcase_F1
-###AdTargetControl1_iframe
-###AdText
-###AdTop
-###Ad_Block
-###Ad_Center1
-###Ad_Right1
-###Ad_Top
-~cynamite.de###Adbanner
-###Adrectangle
-###Ads
-###AdsContent
-###AdsRight
-###AdsWrap
-###Ads_BA_CAD
-###Ads_BA_CAD2
-###Ads_BA_CAD_box
-###Ads_BA_SKY
-###Ads_CAD
-###Ads_Special
-###AdvertMPU23b
-###AdvertPanel
-~designspotter.com###AdvertiseFrame
-~winload.de###Advertisement
-~ping-timeout.de###Advertisements
-###Advertorial
-###Advertorials
-###BannerAdvert
-###BigBoxAd
-###BodyAd
-###ButtonAd
-###CompanyDetailsNarrowGoogleAdsPresentationControl
-###CompanyDetailsWideGoogleAdsPresentationControl
-###ContentAd
-###ContentAd1
-###ContentAd2
-###ContentAdPlaceHolder1
-###ContentAdPlaceHolder2
-###ContentAdXXL
-###ContentPolepositionAds_Result
-###DivAdEggHeadCafeTopBanner
-###FooterAd
-###FooterAdContainer
-###GoogleAd1
-###GoogleAd2
-###GoogleAd3
-###GoogleAdsPresentationControl
-###GoogleAdsense
-###Google_Adsense_Main
-###HEADERAD
-###HOME_TOP_RIGHT_BOXAD
-###HeaderAdsBlock
-###HeaderAdsBlockFront
-###HeaderBannerAdSpacer
-###HeaderTextAd
-###HeroAd
-###HomeAd1
-###HouseAd
-###ID_Ad_Sky
-###Journal_Ad_125
-###Journal_Ad_300
-###KH-contentAd
-###LeftAd
-###LeftAdF1
-###LeftAdF2
-###LftAd
-###LoungeAdsDiv
-###LowerContentAd
-###MainSponsoredLinks
-###Nightly_adContainer
-###PREFOOTER_LEFT_BOXAD
-###PREFOOTER_RIGHT_BOXAD
-###PageLeaderAd
-###RelevantAds
-###RgtAd1
-###RightAd
-###RightNavTopAdSpot
-###RightSponsoredAd
-###SectionAd300-250
-###SectionSponsorAd
-###SidebarAdContainer
-###SkyAd
-###SpecialAds
-###SponsoredAd
-###SponsoredLinks
-###TOP_ADROW
-###TOP_RIGHT_BOXAD
-~kids.t-online.de###Tadspacehead
-###TopAd
-###TopAdContainer
-###TopAdDiv
-###TopAdPos
-###VM-MPU-adspace
-###VM-footer-adspace
-###VM-header-adspace
-###VM-header-adwrap
-###XEadLeaderboard
-###XEadSkyscraper
-###_ads
-###about_adsbottom
-###ad-120x600-sidebar
-###ad-120x60Div
-###ad-160x600
-###ad-160x600-sidebar
-###ad-250
-###ad-250x300
-###ad-300
-###ad-300x250
-###ad-300x250-sidebar
-###ad-300x250Div
-###ad-728
-###ad-728x90-leaderboard-top
-###ad-article
-###ad-banner
-###ad-banner-1
-###ad-block-125
-###ad-bottom
-###ad-bottom-wrapper
-###ad-boxes
-###ad-bs
-###ad-buttons
-###ad-colB-1
-###ad-column
-~madame.lefigaro.fr###ad-container
-###ad-content
-###ad-contentad
-###ad-footer
-###ad-footprint-160x600
-###ad-front-footer
-###ad-front-sponsoredlinks
-###ad-halfpage
-~ifokus.se###ad-header
-###ad-inner
-###ad-label
-###ad-leaderboard
-###ad-leaderboard-bottom
-###ad-leaderboard-container
-###ad-leaderboard-spot
-###ad-leaderboard-top
-###ad-left
-###ad-list-row
-###ad-lrec
-###ad-medium-rectangle
-###ad-medrec
-###ad-middlethree
-###ad-middletwo
-###ad-module
-###ad-mpu
-###ad-mpu1-spot
-###ad-mpu2
-###ad-mpu2-spot
-###ad-north
-###ad-one
-###ad-placard
-###ad-placeholder
-###ad-rectangle
-###ad-right
-###ad-righttop
-###ad-row
-###ad-side-text
-###ad-sky
-###ad-skyscraper
-###ad-slug-wrapper
-###ad-small-banner
-###ad-space
-###ad-splash
-###ad-spot
-###ad-target
-###ad-target-Leaderbord
-###ad-teaser
-###ad-text
-~gismeteo.com,~gismeteo.ru,~gismeteo.ua###ad-top
-###ad-top-banner
-###ad-top-text-low
-###ad-top-wrap
-###ad-tower
-###ad-trailerboard-spot
-###ad-typ1
-###ad-west
-###ad-wrap
-###ad-wrap-right
-~collegeslackers.com###ad-wrapper
-###ad-wrapper1
-###ad-yahoo-simple
-~tphousing.com,~tvgorge.com###ad1
-###ad1006
-###ad125BL
-###ad125BR
-###ad125TL
-###ad125TR
-###ad125x125
-###ad160x600
-###ad160x600right
-###ad1Sp
-###ad2
-###ad2Sp
-~absoluteradio.co.uk###ad3
-###ad300
-###ad300-250
-###ad300X250
-###ad300_x_250
-###ad300x150
-###ad300x250
-###ad300x250Module
-###ad300x60
-###ad300x600
-###ad300x600_callout
-###ad336
-###ad336x280
-###ad375x85
-###ad4
-###ad468
-###ad468x60
-###ad468x60_top
-###ad526x250
-###ad600
-###ad7
-###ad728
-###ad728Mid
-###ad728Top
-###ad728Wrapper
-~natgeo.tv###ad728x90
-###adBadges
-~campusdish.com###adBanner
-###adBanner120x600
-###adBanner160x600
-###adBanner336x280
-###adBannerTable
-###adBannerTop
-###adBar
-###adBlock125
-###adBlocks
-###adBox
-###adBox350
-###adBox390
-###adCirc300X200
-###adCirc_620_100
-###adComponentWrapper
-~jobs.wa.gov.au,~pricewatch.com###adContainer
-###adContainer_1
-###adContainer_2
-###adContainer_3
-~remixshare.com###adDiv
-###adFiller
-###adFps
-###adFtofrs
-###adGallery
-###adGroup1
-~ksl.com###adHeader
-###adIsland
-###adL
-###adLB
-###adLabel
-###adLayer
-###adLeader
-###adLeaderTop
-###adLeaderboard
-###adMPU
-###adMediumRectangle
-###adMiddle0Frontpage
-###adMiniPremiere
-###adP
-###adPlaceHolderRight
-###adPlacer
-###adRight
-###adSenseModule
-###adSenseWrapper
-###adServer_marginal
-###adSidebar
-###adSidebarSq
-###adSky
-###adSkyscraper
-###adSlider
-###adSpace
-###adSpace3
-###adSpace300_ifrMain
-###adSpace4
-###adSpace5
-###adSpace6
-###adSpace7
-###adSpace_footer
-###adSpace_right
-###adSpace_top
-###adSpacer
-###adSpecial
-###adSpot-Leader
-###adSpot-banner
-###adSpot-island
-###adSpot-mrec1
-###adSpot-sponsoredlinks
-###adSpot-textbox1
-###adSpot-widestrip
-###adSpotAdvertorial
-###adSpotIsland
-###adSpotSponsoredLinks
-###adSquare
-###adStaticA
-###adStrip
-###adSuperAd
-###adSuperPremiere
-###adSuperbanner
-###adTableCell
-###adTag1
-###adTag2
-###adText
-###adText_container
-###adTile
-~ran.de###adTop
-###adTopboxright
-###adTower
-###adUnit
-~bankenverband.de,~thisisleicestershire.co.uk###adWrapper
-###adZoneTop
-###ad_160x160
-###ad_160x600
-###ad_190x90
-###ad_300
-###ad_300_250
-###ad_300_250_1
-###ad_300x250
-###ad_300x250_content_column
-###ad_300x90
-###ad_468_60
-###ad_5
-###ad_728_foot
-###ad_728x90
-###ad_728x90_container
-###ad_940
-###ad_984
-###ad_A
-###ad_B
-###ad_Banner
-###ad_C
-###ad_C2
-###ad_D
-###ad_E
-###ad_F
-###ad_G
-###ad_H
-###ad_I
-###ad_J
-###ad_K
-###ad_L
-###ad_M
-###ad_N
-###ad_O
-###ad_P
-###ad_YieldManager-300x250
-###ad_anchor
-###ad_area
-###ad_banner
-###ad_banner_top
-###ad_bar
-###ad_bellow_post
-###ad_block_1
-###ad_block_2
-###ad_bottom
-###ad_box_colspan
-###ad_branding
-###ad_bs_area
-###ad_center_monster
-###ad_cont
-~academics.de###ad_container
-###ad_container_marginal
-###ad_container_side
-###ad_container_top
-###ad_content_top
-###ad_content_wrap
-###ad_feature
-###ad_firstpost
-###ad_footer
-###ad_front_three
-###ad_fullbanner
-~arablionz.com,~avatar-forums.com,~djluv.in,~egymedicine.net,~mmowned.com###ad_global_below_navbar
-###ad_global_header
-###ad_haha_1
-###ad_haha_4
-###ad_halfpage
-###ad_head
-###ad_header
-###ad_horizontal
-###ad_horseshoe_left
-###ad_horseshoe_right
-###ad_horseshoe_spacer
-###ad_horseshoe_top
-###ad_hotpots
-###ad_in_arti
-###ad_island
-###ad_label
-###ad_large_rectangular
-###ad_lastpost
-###ad_layer2
-~tv3.ie###ad_leader
-###ad_leaderBoard
-###ad_leaderboard
-###ad_leaderboard728x90
-###ad_leaderboard_top
-###ad_left
-###ad_lrec
-###ad_lwr_square
-###ad_main
-###ad_medium_rectangle
-###ad_medium_rectangular
-###ad_mediumrectangle
-###ad_menu_header
-###ad_middle
-###ad_most_pop_234x60_req_wrapper
-###ad_mpu
-###ad_mpu300x250
-###ad_mpuav
-###ad_mrcontent
-###ad_overlay
-###ad_play_300
-###ad_rect
-###ad_rect_body
-###ad_rect_bottom
-###ad_rectangle
-###ad_rectangle_medium
-###ad_related_links_div
-###ad_related_links_div_program
-###ad_replace_div_0
-###ad_replace_div_1
-###ad_report_leaderboard
-###ad_report_rectangle
-###ad_right
-###ad_right_main
-###ad_ros_tower
-###ad_rr_1
-###ad_sec
-###ad_sec_div
-###ad_sgd
-###ad_sidebar
-###ad_sidebar1
-###ad_sidebar2
-###ad_sidebar3
-###ad_skyscraper
-###ad_skyscraper160x600
-###ad_skyscraper_text
-###ad_slot_leaderboard
-###ad_slot_livesky
-###ad_slot_sky_top
-~streetinsider.com###ad_space
-~wretch.cc###ad_square
-###ad_ss
-###ad_table
-###ad_term_bottom_place
-###ad_thread_first_post_content
-###ad_top
-###ad_top_holder
-###ad_tp_banner_1
-###ad_tp_banner_2
-###ad_unit
-###ad_vertical
-###ad_widget
-###ad_window
-~amnestyusa.org,~drownedinsound.com###ad_wrapper
-###adbanner
-###adbig
-###adbnr
-###adboard
-###adbody
-###adbottom
-~kalaydo.de###adbox
-###adbox1
-###adbox2
-###adclear
-###adcode
-###adcode1
-###adcode2
-###adcode3
-###adcode4
-###adcolumnwrapper
-###adcontainer
-###adcontainerRight
-###adcontainsm
-###adcontent
-###adcontrolPushSite
-###add_ciao2
-###addbottomleft
-###addiv-bottom
-###addiv-top
-###adfooter_728x90
-###adframe:not(frameset)
-###adhead
-###adhead_g
-###adheader
-###adhome
-###adiframe1_iframe
-###adiframe2_iframe
-###adiframe3_iframe
-###adimg
-###adition_content_ad
-###adlabel
-###adlabelFooter
-###adlayerad
-###adleaderboard
-###adleft
-###adlinks
-###adlinkws
-###adlrec
-###admid
-###admiddle3center
-###admiddle3left
-###adposition
-###adposition-C
-###adposition-FPMM
-###adposition2
-~contracostatimes.com,~mercurynews.com,~siliconvalley.com###adposition3
-###adposition4
-###adrectangle
-###adrectanglea
-###adrectangleb
-###adrig
-###adright
-###adright2
-###adrighthome
-~2gb-hosting.com,~addoway.com,~bash.org.ru,~block-adblock-plus.com,~dailykos.com,~divxhosting.net,~facebook.com,~harpers.org,~miloyski.com,~radio.de,~tomwans.com,~tonprenom.com,~www.google.com,~zuploads.com,~zuploads.net###ads
-###ads-468
-###ads-area
-###ads-block
-###ads-bot
-###ads-bottom
-###ads-col
-###ads-dell
-###ads-horizontal
-###ads-indextext
-###ads-leaderboard1
-###ads-lrec
-###ads-menu
-###ads-middle
-###ads-prices
-###ads-rhs
-###ads-right
-###ads-top
-###ads-vers7
-###ads-wrapper
-###ads160left
-###ads2
-###ads300
-###ads300Bottom
-###ads300Top
-###ads336x280
-###ads7
-###ads728bottom
-###ads728top
-###ads790
-###adsDisplay
-###adsID
-###ads_160
-###ads_300
-###ads_728
-###ads_banner
-###ads_belowforumlist
-###ads_belownav
-###ads_bottom_inner
-###ads_bottom_outer
-###ads_box
-###ads_button
-###ads_catDiv
-###ads_footer
-###ads_html1
-###ads_html2
-###ads_notice
-###ads_right
-###ads_right_sidebar
-###ads_sidebar_roadblock
-###ads_space
-###ads_top
-###ads_watch_top_square
-###ads_zone27
-###adsbottom
-###adsbox
-###adscolumn
-###adsd_contentad_r1
-###adsd_contentad_r2
-###adsd_contentad_r3
-###adsdiv
-###adsense
-###adsense-2
-###adsense-tag
-###adsense-text
-###adsenseOne
-###adsenseWrap
-~jeeppatriot.com###adsense_inline
-###adsense_leaderboard
-###adsense_overlay
-###adsense_placeholder_2
-###adsenseheader
-###adsensetopplay
-###adsensewidget-3
-###adserv
-###adsimage
-###adsky
-###adskyscraper
-###adslot
-###adsonar
-~metblogs.com,~oreilly.com###adspace
-###adspace-300x250
-###adspace300x250
-###adspaceBox
-###adspaceBox300
-###adspace_header
-###adspot-1
-###adspot-149x170
-###adspot-1x4
-###adspot-2
-###adspot-295x60
-###adspot-2a
-###adspot-2b
-###adspot-300x250-pos-1
-###adspot-300x250-pos-2
-###adspot-468x60-pos-2
-###adspot-a
-###adspot300x250
-###adsright
-###adst
-###adstop
-###adt
-###adtab
-###adtag_right_side
-###adtech_googleslot_03c
-###adtech_takeover
-###adtop
-###adtophp
-###adtxt
-###adv-masthead
-###adv_google_300
-###adv_google_728
-###adv_top_banner_wrapper
-###adver1
-###adver2
-###adver3
-###adver4
-###adver5
-###adver6
-###adver7
-~finn.no,~gcrg.org,~kalaydo.de,~m424.com,~secondamano.it,~sepa.org.uk###advert
-###advert-1
-###advert-120
-###advert-boomer
-###advert-display
-###advert-header
-###advert-leaderboard
-###advert-links-bottom
-###advert-skyscraper
-###advert-top
-###advert1
-###advertBanner
-###advertRight
-###advert_250x250
-###advert_box
-###advert_leaderboard
-###advert_lrec_format
-###advert_mid
-###advert_mpu
-###advert_right_skyscraper
-###advertbox
-###advertbox2
-###advertbox3
-###advertbox4
-###adverthome
-~zlatestranky.cz###advertise
-###advertise-now
-###advertise1
-###advertiseHere
-~ping-timeout.de###advertisement
-###advertisement160x600
-###advertisement728x90
-###advertisementLigatus
-###advertisementPrio2
-###advertiser-container
-###advertiserLinks
-~spoofmail.de,~uscbookstore.com###advertising
-###advertising-banner
-###advertising-caption
-###advertising-container
-###advertising-control
-###advertising-skyscraper
-###advertisingModule160x600
-###advertisingModule728x90
-###advertisment
-###advertismentElementInUniversalbox
-###advertorial
-~markt.de###adverts
-###adverts-top-container
-###adverts-top-left
-###adverts-top-middle
-###adverts-top-right
-###advertsingle
-###advt
-###adwhitepaperwidget
-###adwin_rec
-###adwith
-###adwords-4-container
-~musicstar.de###adwrapper
-###adxBigAd
-###adxMiddle5
-###adxSponLink
-###adxSponLinkA
-###adxtop
-###adzbanner
-###adzerk
-###adzerk1
-###adzoneBANNER
-###affinityBannerAd
-###agi-ad300x250
-###agi-ad300x250overlay
-###agi-sponsored
-###alert_ads
-###anchorAd
-###annoying_ad
-###ap_adframe
-###apiBackgroundAd
-###apiTopAdWrap
-###apmNADiv
-###araHealthSponsorAd
-###article-ad-container
-###article-box-ad
-###articleAdReplacement
-###articleLeftAdColumn
-###articleSideAd
-###article_ad
-###article_box_ad
-###asinglead
-###atlasAdDivGame
-###awds-nt1-ad
-###banner-300x250
-###banner-ad
-###banner-ad-container
-###banner-ads
-###banner250x250
-###banner468x60
-###banner728x90
-###bannerAd
-###bannerAdTop
-###bannerAd_ctr
-###banner_ad
-###banner_ad_footer
-###banner_admicro
-###banner_ads
-###banner_content_ad
-###banner_topad
-~shareapic.net###bannerad
-###bannerad2
-###bbccom_mpu
-###bbccom_storyprintsponsorship
-###bbo_ad1
-###bg-footer-ads
-###bg-footer-ads2
-###bg_YieldManager-300x250
-###bigAd
-###bigBoxAd
-###bigad300outer
-###bigadbox
-###bigadspot
-###billboard_ad
-###block-ad_cube-1
-###block-openads-1
-###block-openads-3
-###block-openads-4
-###block-openads-5
-###block-thewrap_ads_250x300-0
-###block_advert
-###blog-ad
-###blog_ad_content
-###blog_ad_opa
-###blox-big-ad
-###blox-big-ad-bottom
-###blox-big-ad-top
-###blox-halfpage-ad
-###blox-tile-ad
-###blox-tower-ad
-###book-ad
-###botad
-###bott_ad2
-###bott_ad2_300
-###bottom-ad
-###bottom-ad-container
-###bottom-ads
-###bottomAd
-###bottomAdCCBucket
-###bottomAdContainer
-###bottomAdSense
-###bottomAdSenseDiv
-###bottomAds
-###bottomRightAd
-###bottomRightAdSpace
-###bottom_ad
-###bottom_ad_area
-###bottom_ads
-###bottom_banner_ad
-###bottom_overture
-###bottom_sponsor_ads
-###bottom_sponsored_links
-###bottom_text_ad
-###bottomad
-###bottomads
-###bottomadsense
-###bottomadwrapper
-###bottomleaderboardad
-###box-content-ad
-###box-googleadsense-1
-###box-googleadsense-r
-###box1ad
-###boxAd300
-###boxAdContainer
-###box_ad
-###box_advertisment
-###box_mod_googleadsense
-###boxad1
-###boxad2
-###boxad3
-###boxad4
-###boxad5
-###bpAd
-###bps-header-ad-container
-###btr_horiz_ad
-###burn_header_ad
-###button-ads-horizontal
-###button-ads-vertical
-###buttonAdWrapper1
-###buttonAdWrapper2
-###buttonAds
-###buttonAdsContainer
-###button_ad_container
-###button_ad_wrap
-###buttonad
-###buy-sell-ads
-###c4ad-Middle1
-###caAdLarger
-###catad
-###category-ad
-###cellAd
-###channel_ad
-###channel_ads
-###ciHomeRHSAdslot
-###circ_ad
-###cnnRR336ad
-###cnnTopAd
-###col3_advertising
-###colRightAd
-###collapseobj_adsection
-###column4-google-ads
-###commercial_ads
-###common_right_ad_wrapper
-###common_right_lower_ad_wrapper
-###common_right_lower_adspace
-###common_right_lower_player_ad_wrapper
-###common_right_lower_player_adspace
-###common_right_player_ad_wrapper
-###common_right_player_adspace
-###common_right_right_adspace
-###common_top_adspace
-###companion-ad
-###companionAdDiv
-###containerLocalAds
-###containerLocalAdsInner
-###containerMrecAd
-###containerSqAd
-###content-ad-header
-###content-header-ad
-###contentAd
-###contentTopAds2
-~filestage.to,~maximonline.ru###content_ad
-###content_ad_square
-###content_ad_top
-###content_ads_content
-###content_box_300body_sponsoredoffers
-###content_box_adright300_google
-###content_mpu
-###contentad
-###contentad_imtext
-###contentad_right
-###contentads
-###contentinlineAd
-###contextad
-###contextual-ads
-###contextual-ads-block
-###contextualad
-###coverads
-###ctl00_Adspace_Top_Height
-###ctl00_BottomAd
-###ctl00_ContentRightColumn_RightColumn_Ad1_BanManAd
-###ctl00_ContentRightColumn_RightColumn_PremiumAd1_ucBanMan_BanManAd
-###ctl00_LHTowerAd
-###ctl00_LeftHandAd
-###ctl00_MasterHolder_IBanner_adHolder
-###ctl00_TopAd
-###ctl00_TowerAd
-###ctl00_VBanner_adHolder
-###ctl00_abot_bb
-###ctl00_adFooter
-###ctl00_atop_bt
-###ctl00_cphMain_hlAd1
-###ctl00_cphMain_hlAd2
-###ctl00_cphMain_hlAd3
-###ctl00_ctl00_MainPlaceHolder_itvAdSkyscraper
-###ctl00_ctl00_ctl00_Main_Main_PlaceHolderGoogleTopBanner_MPTopBannerAd
-###ctl00_ctl00_ctl00_Main_Main_SideBar_MPSideAd
-###ctl00_dlTilesAds
-###ctl00_m_skinTracker_m_adLBL
-###ctl00_phCrackerMain_ucAffiliateAdvertDisplayMiddle_pnlAffiliateAdvert
-###ctl00_phCrackerMain_ucAffiliateAdvertDisplayRight_pnlAffiliateAdvert
-###ctrlsponsored
-###cubeAd
-###cube_ads
-###cube_ads_inner
-###cubead
-###cubead-2
-###dItemBox_ads
-###dart_160x600
-###dc-display-right-ad-1
-###dcol-sponsored
-###defer-adright
-###detail_page_vid_topads
-~mtanyct.info###divAd
-###divAdBox
-###divMenuAds
-###divWNAdHeader
-###divWrapper_Ad
-###div_ad_leaderboard
-###div_video_ads
-###dlads
-###dni-header-ad
-###dnn_ad_banner
-###download_ads
-###ds-mpu
-###editorsmpu
-###evotopTen_advert
-###ex-ligatus
-###exads
-~discuss.com.hk,~uwants.com###featuread
-###featured-advertisements
-###featuredAdContainer2
-###featuredAds
-###feed_links_ad_container
-###first-300-ad
-###first-adlayer
-###first_ad_unit
-###firstad
-###fl_hdrAd
-###flexiad
-###footer-ad
-###footer-advert
-###footer-adverts
-###footer-sponsored
-###footerAd
-###footerAdDiv
-###footerAds
-###footerAdvertisement
-###footerAdverts
-###footer_ad
-###footer_ad_01
-###footer_ad_block
-###footer_ad_container
-###footer_ad_modules
-~investopedia.com###footer_ads
-###footer_adspace
-###footer_text_ad
-###footerad
-###footerads
-###footeradsbox
-###fr_ad_center
-###frame_admain
-###frnAdSky
-###frnBannerAd
-###frnContentAd
-###from_our_sponsors
-###front_advert
-###front_mpu
-###ft-ad
-###ft-ad-1
-###ft-ad-container
-###ft_mpu
-###fusionad
-###fw-advertisement
-###g_ad
-###g_adsense
-###ga_300x250
-###gad
-###galleries-tower-ad
-###gallery-ad-m0
-###gallery_ads
-###game-info-ad
-###gasense
-###global_header_ad_area
-###gmi-ResourcePageAd
-###gmi-ResourcePageLowerAd
-###goads
-###google-ad
-###google-ad-art
-###google-ad-table-right
-###google-ad-tower
-###google-ads
-###google-ads-bottom
-###google-ads-header
-###google-ads-left-side
-###google-adsense-mpusize
-###googleAd
-###googleAds
-###googleAdsSml
-###googleAdsense
-###googleAdsenseBanner
-###googleAdsenseBannerBlog
-###googleAdwordsModule
-###googleAfcContainer
-###googleSearchAds
-###googleShoppingAdsRight
-###googleShoppingAdsTop
-###googleSubAds
-###google_ad
-###google_ad_container
-###google_ad_inline
-###google_ad_test
-###google_ads
-###google_ads_frame1
-###google_ads_frame1_anchor
-###google_ads_frame2
-###google_ads_frame2_anchor
-###google_ads_frame3
-###google_ads_frame3_anchor
-###google_ads_test
-###google_ads_top
-###google_adsense_home_468x60_1
-###googlead
-###googleadbox
-###googleads
-###googleadsense
-###googlesponsor
-###grid_ad
-###gsyadrectangleload
-###gsyadrightload
-###gsyadtop
-###gsyadtopload
-###gtopadvts
-###half-page-ad
-###halfPageAd
-###halfe-page-ad-box
-###hdtv_ad_ss
-~uwcu.org###head-ad
-###headAd
-###head_advert
-###headad
-###header-ad
-###header-ad-rectangle-container
-###header-ads
-###header-adspace
-###header-advert
-###header-advertisement
-###header-advertising
-###headerAd
-###headerAdBackground
-###headerAdContainer
-###headerAdWrap
-###headerAds
-###headerAdsWrapper
-###headerTopAd
-~cmt.com###header_ad
-###header_ad_728_90
-###header_ad_container
-###header_adcode
-###header_ads
-###header_advertisement_top
-###header_leaderboard_ad_container
-###header_publicidad
-###headerad
-###headeradbox
-###headerads
-###headeradsbox
-###headeradwrap
-###headline_ad
-###headlinesAdBlock
-###hiddenadAC
-###hideads
-###hl-sponsored-results
-###homeTopRightAd
-###home_ad
-###home_bottom_ad
-###home_contentad
-###home_mpu
-###home_spensoredlinks
-###homepage-ad
-###homepageAdsTop
-###homepageFooterAd
-###homepage_right_ad
-###homepage_right_ad_container
-###homepage_top_ads
-###hometop_234x60ad
-###hor_ad
-###horizontal-banner-ad
-###horizontal_ad
-###horizontal_ad_top
-###horizontalads
-###houseAd
-###hp-header-ad
-###hp-right-ad
-###hp-store-ad
-###hpV2_300x250Ad
-###hpV2_googAds
-###icePage_SearchLinks_AdRightDiv
-###icePage_SearchLinks_DownloadToolbarAdRightDiv
-###icePage_SearchResults_ads0_SponsoredLink
-###icePage_SearchResults_ads1_SponsoredLink
-###icePage_SearchResults_ads2_SponsoredLink
-###icePage_SearchResults_ads3_SponsoredLink
-###icePage_SearchResults_ads4_SponsoredLink
-###in_serp_ad
-###inadspace
-###indexad
-###inlinead
-###inlinegoogleads
-###inlist-ad-block
-###inner-advert-row
-###insider_ad_wrapper
-###instoryad
-###int-ad
-###interstitial_ad_wrapper
-###islandAd
-###j_ad
-###ji_medShowAdBox
-###jmp-ad-buttons
-###joead
-###joead2
-###ka_adRightSkyscraperWide
-###landing-adserver
-###largead
-###lateAd
-###layerTLDADSERV
-###lb-sponsor-left
-###lb-sponsor-right
-###leader-board-ad
-###leader-sponsor
-###leaderAd
-###leaderAdContainer
-###leader_board_ad
-###leaderad
-###leaderad_section
-###leaderboard-ad
-###leaderboard-bottom-ad
-###leaderboard_ad
-###left-ad-skin
-###left-lower-adverts
-###left-lower-adverts-container
-###leftAdContainer
-###leftAd_rdr
-###leftAdvert
-###leftSectionAd300-100
-###left_ad
-###left_adspace
-###leftad
-###leftads
-###leftcolAd
-###lg-banner-ad
-###ligatus
-###linkAds
-###linkads
-###live-ad
-###longAdSpace
-###lowerAdvertisementImg
-###lowerads
-###lowerthirdad
-###lowertop-adverts
-###lowertop-adverts-container
-###lpAdPanel
-###lrecad
-###lsadvert-left_menu_1
-###lsadvert-left_menu_2
-###lsadvert-top
-###mBannerAd
-###main-ad
-###main-ad160x600
-###main-ad160x600-img
-###main-ad728x90
-###main-bottom-ad
-###mainAd
-###mainAdUnit
-###mainAdvert
-###main_ad
-###main_rec_ad
-###main_top_ad_container
-###marketing-promo
-###mastAdvert
-###mastad
-###mastercardAd
-###masthead_ad
-###masthead_topad
-###medRecAd
-###media_ad
-###mediumAdvertisement
-###medrectad
-###menuAds
-###mi_story_assets_ad
-###mid-ad300x250
-###mid-table-ad
-###midRightTextAds
-###mid_ad_div
-###mid_ad_title
-###mid_mpu
-###midadd
-###midadspace
-###middle-ad
-###middlead
-###middleads
-###midrect_ad
-###midstrip_ad
-###mini-ad
-###module-google_ads
-###module_ad
-###module_box_ad
-###module_sky_scraper
-###monsterAd
-###moogleAd
-###most_popular_ad
-###motionAd
-###mpu
-###mpu-advert
-###mpuAd
-###mpuDiv
-###mpuSlot
-###mpuWrapper
-###mpuWrapperAd
-###mpu_banner
-###mpu_holder
-###mpu_text_ad
-###mpuad
-###mrecAdContainer
-###ms_ad
-###msad
-###multiLinkAdContainer
-###myads_HeaderButton
-###n_sponsor_ads
-###namecom_ad_hosting_main
-###narrow_ad_unit
-###natadad300x250
-###national_microlink_ads
-###nationalad
-###navi_banner_ad_780
-###nba300Ad
-###nbaMidAds
-###nbaVid300Ad
-###new_topad
-###newads
-###ng_rtcol_ad
-###noresults_ad_container
-###noresultsads
-###northad
-###oanda_ads
-###onespot-ads
-###online_ad
-###p-googleadsense
-###page-header-ad
-###page-top-ad
-###pageAds
-###pageAdsDiv
-###page_content_top_ad
-###pagelet_adbox
-###pagelet_netego_ads
-###pagelet_search_ads2
-###panelAd
-###pb_report_ad
-###pcworldAdBottom
-###pcworldAdTop
-###pinball_ad
-###player-below-advert
-###player_ad
-###player_ads
-###pod-ad-video-page
-###populate_ad_bottom
-###populate_ad_left
-###portlet-advertisement-left
-###portlet-advertisement-right
-###post-promo-ad
-###post5_adbox
-###post_ad
-###premium_ad
-###priceGrabberAd
-###print_ads
-~bipbip.co.il###printads
-###product-adsense
-~flickr.com###promo-ad
-###promoAds
-###ps-vertical-ads
-###pub468x60
-###publicidad
-###pushdown_ad
-###qm-ad-big-box
-###qm-ad-sky
-###qm-dvdad
-###r1SoftAd
-###rail_ad1
-###rail_ad2
-###realEstateAds
-###rectAd
-###rect_ad
-###rectangle-ad
-###rectangle_ad
-###refine-300-ad
-###region-node-advert
-###region-top-ad
-###rh-ad-container
-###rh_tower_ad
-###rhs_ads
-###rhsadvert
-###right-ad
-###right-ad-skin
-###right-ad-title
-###right-ads-3
-###right-box-ad
-###right-featured-ad
-###right-mpu-1-ad-container
-###right-uppder-adverts
-###right-uppder-adverts-container
-###rightAd
-###rightAd300x250
-###rightAdColumn
-###rightAd_rdr
-###rightColAd
-###rightColumnMpuAd
-###rightColumnSkyAd
-###right_ad
-###right_ad_wrapper
-###right_ads
-###right_advertisement
-###right_advertising
-###right_column_ads
-###rightad
-###rightadContainer
-###rightadvertbar-doubleclickads
-###rightbar-ad
-###rightside-ads
-###rightside_ad
-###righttop-adverts
-###righttop-adverts-container
-###rm_ad_text
-###ros_ad
-###rotatingads
-###row2AdContainer
-###rt-ad
-###rt-ad-top
-###rt-ad468
-###rtMod_ad
-###rtmod_ad
-###sAdsBox
-###sb-ad-sq
-###sb_advert
-###sb_sponsors
-###search-google-ads
-###search-sponsored-links
-###search-sponsored-links-top
-###searchAdSenseBox
-###searchAdSenseBoxAd
-###searchAdSkyscraperBox
-###search_ads
-###search_result_ad
-###second-adlayer
-###secondBoxAdContainer
-###secondrowads
-###section-container-ddc_ads
-###section-sponsors
-###section_advertorial_feature
-###servfail-ads
-###sew-ad1
-###shoppingads
-###show-ad
-###showAd
-###showad
-###side-ad
-###side-ad-container
-###sideAd
-###sideAdSub
-###sideBarAd
-###side_ad
-###side_ad_wrapper
-###side_ads_by_google
-###side_sky_ad
-###sidead
-###sideads
-###sidebar-125x125-ads
-###sidebar-125x125-ads-below-index
-###sidebar-ad
-###sidebar-ad-boxes
-###sidebar-ad-space
-###sidebar-ad-wrap
-###sidebar-ad3
-~gaelick.com###sidebar-ads
-###sidebar2ads
-###sidebar_ad
-###sidebar_ad_widget
-~facebook.com,~japantoday.com###sidebar_ads
-###sidebar_ads_180
-###sidebar_sponsoredresult_body
-###sidebarad
-###sideline-ad
-###single-mpu
-###singlead
-###site-leaderboard-ads
-###site_top_ad
-###sitead
-###sky-ad
-###skyAd
-###skyAdContainer
-###skyScrapperAd
-###skyWrapperAds
-###sky_ad
-###sky_advert
-###skyads
-###skyscraper-ad
-###skyscraperAd
-###skyscraperAdContainer
-###skyscraper_ad
-###skyscraper_advert
-###skyscraperad
-###sliderAdHolder
-###slideshow_ad_300x250
-###sm-banner-ad
-###small_ad
-###smallerAd
-###specials_ads
-###speeds_ads
-###speeds_ads_fstitem
-###speedtest_mrec_ad
-###sphereAd
-###splinks
-###sponLinkDiv_1
-###sponlink
-###sponlinks
-###sponsAds
-###sponsLinks
-###spons_left
-###sponseredlinks
-###sponsor-search
-###sponsorAd1
-###sponsorAd2
-###sponsorAdDiv
-###sponsorLinks
-###sponsorTextLink
-###sponsor_banderole
-###sponsor_box
-###sponsor_deals
-###sponsor_panSponsor
-###sponsor_recommendations
-###sponsorbar
-###sponsorbox
-~hollywood.com,~worldsbestbars.com###sponsored
-###sponsored-ads
-###sponsored-features
-###sponsored-links
-###sponsored-resources
-###sponsored1
-###sponsoredBox1
-###sponsoredBox2
-###sponsoredLinks
-###sponsoredList
-###sponsoredResults
-###sponsoredSiteMainline
-###sponsoredSiteSidebar
-###sponsored_ads_v4
-###sponsored_content
-###sponsored_game_row_listing
-###sponsored_links
-###sponsored_v12
-###sponsoredlinks
-###sponsoredlinks_cntr
-###sponsoredresults_top
-###sponsoredwellcontainerbottom
-###sponsoredwellcontainertop
-###sponsoring_bar
-###sponsorlink
-###sponsors
-###sponsors_top_container
-###sponsorshipBadge
-###spotlightAds
-###spotlightad
-###sqAd
-###square-sponsors
-###squareAd
-###squareAdSpace
-###squareAds
-###square_ad
-###start_middle_container_advertisment
-###sticky-ad
-###stickyBottomAd
-###story-ad-a
-###story-ad-b
-###story-leaderboard-ad
-###story-sponsoredlinks
-###storyAd
-###storyAdWrap
-###storyad2
-###subpage-ad-right
-###subpage-ad-top
-###swads
-###synch-ad
-###systemad_background
-###tabAdvertising
-###takeoverad
-###tblAd
-###tbl_googlead
-###tcwAd
-###template_ad_leaderboard
-###tertiary_advertising
-###text-ad
-###text-ads
-###textAd
-###textAds
-###text_ad
-###text_ads
-###text_advert
-###textad
-###textad3
-###the-last-ad-standing
-###thefooterad
-###themis-ads
-###tile-ad
-###tmglBannerAd
-###top-ad
-###top-ad-container
-###top-ad-menu
-###top-ads
-###top-ads-tabs
-###top-advertisement
-###top-banner-ad
-###top-search-ad-wrapper
-###topAd
-###topAd728x90
-###topAdBanner
-###topAdContainer
-###topAdSenseDiv
-###topAdcontainer
-###topAds
-###topAdsContainer
-###topAdvert
-~neowin.net###topBannerAd
-###topNavLeaderboardAdHolder
-###topRightBlockAdSense
-~morningstar.se###top_ad
-###top_ad_area
-###top_ad_game
-###top_ad_wrapper
-###top_ads
-###top_advertise
-###top_advertising
-###top_right_ad
-###top_wide_ad
-~bumpshack.com###topad
-###topad_left
-###topad_right
-###topadblock
-###topaddwide
-###topads
-###topadsense
-###topadspace
-###topadzone
-###topbanner_ad
-###topbar-ad
-###topcustomad
-###topleaderboardad
-###toprightAdvert
-###toprightad
-###topsponsored
-###toptextad
-###towerad
-###ttp_ad_slot1
-###ttp_ad_slot2
-###twogamesAd
-###txt_link_ads
-###undergameAd
-###upperAdvertisementImg
-###upperMpu
-###upperad
-###urban_contentad_1
-###urban_contentad_2
-###urban_contentad_article
-###v_ad
-###vert_ad
-###vert_ad_placeholder
-###vertical_ad
-###vertical_ads
-###videoAd
-###video_cnv_ad
-###video_overlay_ad
-###videoadlogo
-###viewportAds
-###walltopad
-###weblink_ads_container
-###welcomeAdsContainer
-###welcome_ad_mrec
-###welcome_advertisement
-###wf_ContentAd
-###wf_FrontSingleAd
-###wf_SingleAd
-###wf_bottomContentAd
-###wgtAd
-###whatsnews_top_ad
-###whitepaper-ad
-###whoisRightAdContainer
-###wide_ad_unit_top
-###widget_advertisement
-###wrapAdRight
-###wrapAdTop
-###y-ad-units
-###y708-ad-expedia
-###y708-ad-lrec
-###y708-ad-partners
-###y708-ad-ysm
-###y708-advertorial-marketplace
-###yahoo-ads
-###yahoo-sponsors
-###yahooSponsored
-###yahoo_ads
-###yahoo_ads_2010
-###yahooad-tbl
-###yan-sponsored
-###yatadsky
-###ybf-ads
-###yfi_fp_ad_mort
-###yfi_fp_ad_nns
-###yfi_pf_ad_mort
-###ygrp-sponsored-links
-###ymap_adbanner
-###yn-gmy-ad-lrec
-###yreSponsoredLinks
-###ysm_ad_iframe
-###zoneAdserverMrec
-###zoneAdserverSuper
-##.ADBAR
-##.ADPod
-##.AD_ALBUM_ITEMLIST
-##.AD_MOVIE_ITEM
-##.AD_MOVIE_ITEMLIST
-##.AD_MOVIE_ITEMROW
-##.Ad-MPU
-##.Ad1
-##.Ad120x600
-##.Ad160x600
-##.Ad160x600left
-##.Ad160x600right
-##.Ad2
-##.Ad247x90
-##.Ad300x250
-##.Ad300x250L
-##.Ad728x90
-##.AdBorder
-~co-operative.coop##.AdBox
-##.AdBox7
-##.AdContainerBox308
-##.AdHeader
-##.AdHere
-~backpage.com##.AdInfo
-##.AdMedium
-##.AdPlaceHolder
-##.AdRingtone
-##.AdSense
-##.AdSpace
-##.AdTextSmallFont
-~buy.com,~superbikeplanet.com##.AdTitle
-##.AdUnit
-##.AdUnit300
-##.Ad_C
-##.Ad_D_Wrapper
-##.Ad_E_Wrapper
-##.Ad_Right
-~thecoolhunter.net##.Ads
-##.AdsBoxBottom
-##.AdsBoxSection
-##.AdsBoxTop
-##.AdsLinks1
-##.AdsLinks2
-~swanseacity.net,~wrexhamafc.co.uk##.Advert
-##.AdvertMidPage
-##.AdvertiseWithUs
-##.AdvertisementTextTag
-##.ArticleAd
-##.ArticleInlineAd
-##.BannerAd
-##.BigBoxAd
-##.BlockAd
-##.BottomAdContainer
-##.BottomAffiliate
-##.BoxAd
-##.CG_adkit_leaderboard
-##.CG_details_ad_dropzone
-##.CWReviewsProdInfoAd
-##.ComAread
-##.CommentAd
-##.ContentAd
-##.ContentAds
-##.DAWRadvertisement
-##.DeptAd
-##.DisplayAd
-##.FT_Ad
-##.FlatAds
-##.GOOGLE_AD
-##.GoogleAd
-##.GoogleAdSenseBottomModule
-##.GoogleAdSenseRightModule
-##.HPNewAdsBannerDiv
-##.HPRoundedAd
-##.HomeContentAd
-##.IABAdSpace
-##.IndexRightAd
-##.LazyLoadAd
-##.LeftAd
-##.LeftButtonAdSlot
-##.LeftTowerAd
-##.M2Advertisement
-##.MD_adZone
-##.MOS-ad-hack
-##.MPU
-##.MPUHolder
-##.MPUTitleWrapperClass
-##.MREC_ads
-##.MiddleAd
-##.MiddleAdContainer
-##.OpenXad
-##.PU_DoubleClickAdsContent
-##.Post5ad
-##.Post9ad
-##.RBboxAd
-##.RectangleAd
-##.RelatedAds
-##.RightAd1
-##.RightGoogleAFC
-##.RightRailTop300x250Ad
-##.RightSponsoredAdTitle
-##.RightTowerAd
-##.SideAdCol
-##.SidebarAd
-##.SitesGoogleAdsModule
-##.SkyAdContainer
-##.SponsorCFrame
-##.SponsoredAdTitle
-##.SponsoredContent
-##.SponsoredLinks
-##.SponsoredLinksGrayBox
-##.SponsorshipText
-##.SquareAd
-##.StandardAdLeft
-##.StandardAdRight
-##.TextAd
-##.TheEagleGoogleAdSense300x250
-##.TopAd
-##.TopAdContainer
-##.TopAdL
-##.TopAdR
-##.TopBannerAd
-##.UIWashFrame_SidebarAds
-##.UnderAd
-##.VerticalAd
-##.VideoAd
-##.WidgetAdvertiser
-##.a160x600
-##.a728x90
-##.ad-120x600
-##.ad-160
-##.ad-160x600
-##.ad-250
-##.ad-300
-##.ad-300-block
-##.ad-300-blog
-##.ad-300x100
-##.ad-300x250
-##.ad-300x250-right0
-##.ad-350
-##.ad-355x75
-##.ad-600
-##.ad-635x40
-##.ad-728
-##.ad-728x90
-##.ad-728x90-1
-##.ad-728x90_forum
-##.ad-above-header
-##.ad-adlink-bottom
-##.ad-adlink-side
-##.ad-background
-##.ad-banner
-##.ad-bigsize
-##.ad-block
-##.ad-blog2biz
-##.ad-bottom
-##.ad-box
-##.ad-break
-##.ad-btn
-##.ad-btn-heading
-~assetbar.com##.ad-button
-##.ad-cell
-~arbetsformedlingen.se##.ad-container
-##.ad-container-300x250
-##.ad-container-728x90
-##.ad-disclaimer
-##.ad-display
-##.ad-div
-##.ad-enabled
-##.ad-feedback
-##.ad-filler
-##.ad-footer
-##.ad-footer-leaderboard
-##.ad-google
-##.ad-graphic-large
-##.ad-gray
-##.ad-hdr
-##.ad-head
-~dublinairport.com##.ad-holder
-##.ad-homeleaderboard
-##.ad-img
-##.ad-island
-##.ad-label
-##.ad-leaderboard
-##.ad-links
-##.ad-lrec
-##.ad-medium
-##.ad-medium-two
-##.ad-mpu
-##.ad-note
-##.ad-notice
-##.ad-other
-##.ad-permalink
-##.ad-placeholder
-##.ad-postText
-##.ad-poster
-##.ad-priority
-##.ad-rect
-##.ad-rectangle
-##.ad-rectangle-text
-##.ad-related
-##.ad-rh
-##.ad-ri
-##.ad-right
-##.ad-right-header
-##.ad-right-txt
-##.ad-row
-##.ad-section
-~ifokus.se##.ad-sidebar
-##.ad-sidebar-outer
-##.ad-sidebar300
-##.ad-sky
-##.ad-slot
-##.ad-slot-234-60
-##.ad-slot-300-250
-##.ad-slot-728-90
-##.ad-space
-##.ad-space-mpu-box
-##.ad-spot
-##.ad-squares
-##.ad-statement
-##.ad-tabs
-##.ad-text
-##.ad-text-links
-##.ad-tile
-##.ad-title
-##.ad-top
-##.ad-top-left
-##.ad-unit
-##.ad-unit-300
-##.ad-unit-300-wrapper
-##.ad-unit-anchor
-##.ad-vert
-##.ad-vtu
-##.ad-wrap
-##.ad-wrapper
-##.ad-zone-s-q-l
-##.ad.super
-##.ad0
-##.ad1
-##.ad10
-##.ad120
-##.ad120x600
-##.ad125
-##.ad160
-##.ad160x600
-##.ad18
-##.ad19
-##.ad2
-##.ad21
-##.ad250
-##.ad250c
-##.ad3
-##.ad300
-##.ad300250
-##.ad300_250
-##.ad300x100
-##.ad300x250
-##.ad300x250-hp-features
-##.ad300x250Top
-##.ad300x250_container
-##.ad300x250box
-##.ad300x50-right
-##.ad300x600
-##.ad310
-##.ad336x280
-##.ad343x290
-##.ad4
-##.ad400right
-##.ad450
-~itavisen.no##.ad468
-##.ad468_60
-##.ad468x60
-##.ad6
-##.ad620x70
-##.ad626X35
-##.ad7
-##.ad728
-##.ad728_90
-##.ad728x90
-##.ad728x90_container
-##.ad8
-##.ad90x780
-##.adAgate
-##.adArea674x60
-##.adBanner
-##.adBanner300x250
-##.adBanner728x90
-##.adBannerTyp1
-##.adBannerTypSortableList
-##.adBannerTypW300
-##.adBar
-##.adBgBottom
-##.adBgMId
-##.adBgTop
-##.adBlock
-##.adBottomboxright
-~ksl.com##.adBox
-##.adBoxBody
-##.adBoxBorder
-##.adBoxContainer
-##.adBoxContent
-##.adBoxInBignews
-##.adBoxSidebar
-##.adBoxSingle
-##.adCMRight
-##.adColumn
-##.adCont
-##.adContTop
-~mycareer.com.au,~nytimes.com##.adContainer
-##.adContour
-##.adCreative
-~superbikeplanet.com##.adDiv
-~contracostatimes.com,~mercurynews.com,~siliconvalley.com##.adElement
-##.adFender3
-##.adFrame
-##.adFtr
-##.adFullWidthMiddle
-##.adGoogle
-##.adHeader
-##.adHeadline
-~superhry.cz##.adHolder
-##.adHome300x250
-##.adHorisontal
-##.adInNews
-##.adLabel
-##.adLeader
-##.adLeaderForum
-##.adLeaderboard
-##.adLeft
-##.adLoaded
-##.adLocal
-##.adMastheadLeft
-##.adMastheadRight
-##.adMegaBoard
-##.adMkt2Colw
-~outspark.com##.adModule
-##.adMpu
-##.adNewsChannel
-##.adNoOutline
-##.adNotice
-##.adNoticeOut
-##.adObj
-##.adPageBorderL
-##.adPageBorderR
-##.adPanel
-##.adRect
-##.adRight
-##.adSelfServiceAdvertiseLink
-##.adServer
-##.adSkyscraperHolder
-##.adSlot
-##.adSpBelow
-~o2online.de##.adSpace
-##.adSpacer
-##.adSponsor
-##.adSpot
-##.adSpot-searchAd
-##.adSpot-textBox
-##.adSpot-twin
-##.adSpotIsland
-##.adSquare
-~marktplaats.nl##.adSummary
-##.adSuperboard
-##.adSupertower
-##.adTD
-##.adTab
-##.adTag
-~bipbip.co.il##.adText
-##.adTileWrap
-##.adTiler
-~ksl.com,~stadtlist.de,~superbikeplanet.com##.adTitle
-##.adTopboxright
-##.adTout
-##.adTxt
-##.adUnitHorz
-##.adUnitVert
-##.adUnitVert_noImage
-##.adWebBoard
-##.adWidget
-##.adWithTab
-##.adWrap
-##.adWrapper
-##.ad_0
-##.ad_1
-##.ad_120x90
-##.ad_125
-##.ad_130x90
-##.ad_160
-##.ad_160x600
-##.ad_2
-##.ad_200
-##.ad_200x200
-##.ad_250x250
-##.ad_250x250_w
-##.ad_3
-##.ad_300
-##.ad_300_250
-##.ad_300x250
-##.ad_300x250_box_right
-##.ad_336
-##.ad_336x280
-##.ad_350x100
-##.ad_350x250
-##.ad_400x200
-##.ad_468
-##.ad_468x60
-##.ad_600
-##.ad_728
-##.ad_728x90
-##.ad_Left
-~nirmaltv.com##.ad_Right
-##.ad_amazon
-##.ad_banner
-##.ad_banner_border
-##.ad_bg
-##.ad_bigbox
-##.ad_biz
-##.ad_block_338
-##.ad_body
-##.ad_border
-##.ad_botbanner
-##.ad_bottom_leaderboard
-##.ad_box
-##.ad_box2
-##.ad_box_ad
-##.ad_box_div
-##.ad_callout
-##.ad_caption
-##.ad_column
-##.ad_column_hl
-##.ad_contain
-##.ad_container
-~salon.com##.ad_content
-##.ad_content_wide
-##.ad_contents
-##.ad_descriptor
-##.ad_disclaimer
-##.ad_eyebrow
-##.ad_footer
-##.ad_framed
-##.ad_front_promo
-##.ad_head
-~news.yahoo.com,~speurders.nl##.ad_header
-##.ad_hpm
-##.ad_info_block
-##.ad_inline
-##.ad_island
-##.ad_label
-##.ad_launchpad
-##.ad_leader
-##.ad_leaderboard
-##.ad_left
-~leboncoin.fr,~subito.it##.ad_links
-##.ad_linkunit
-##.ad_loc
-##.ad_lrec
-##.ad_main
-##.ad_medrec
-##.ad_medrect
-##.ad_middle
-##.ad_mpu
-##.ad_mr
-##.ad_mrec
-##.ad_mrec_title_article
-##.ad_mrect
-##.ad_news
-##.ad_notice
-##.ad_one
-##.ad_p360
-##.ad_partner
-##.ad_partners
-##.ad_plus
-##.ad_post
-##.ad_power
-##.ad_rectangle
-~didaktik-der-mathematik.de##.ad_right
-##.ad_right_col
-##.ad_row
-##.ad_sidebar
-##.ad_skyscraper
-##.ad_slug
-##.ad_slug_table
-~chinapost.com.tw##.ad_space
-##.ad_space_300_250
-##.ad_sponsor
-##.ad_sponsoredsection
-##.ad_spot_b
-##.ad_spot_c
-##.ad_square_r
-##.ad_square_top
-~bbs.newhua.com,~leboncoin.fr##.ad_text
-##.ad_text_w
-##.ad_title
-##.ad_top
-##.ad_top_leaderboard
-##.ad_topright
-##.ad_tower
-##.ad_unit
-##.ad_unit_rail
-##.ad_url
-##.ad_warning
-##.ad_wid300
-##.ad_wide
-##.ad_wrap
-##.ad_wrapper
-##.ad_wrapper_fixed
-##.ad_wrapper_top
-##.ad_zone
-##.adarea
-##.adarea-long
-##.adbanner
-##.adbannerbox
-##.adbannerright
-##.adbar
-##.adboard
-##.adborder
-##.adbot
-##.adbottom
-##.adbottomright
-~bodybuilding.com,~gametop.com,~lidovky.cz,~nordea.fi##.adbox
-##.adbox-outer
-##.adbox-wrapper
-##.adbox_300x600
-##.adbox_366x280
-##.adbox_468X60
-##.adbox_bottom
-##.adboxclass
-##.adbuttons
-##.adcode
-~yanini.de##.adcol1
-~yanini.de##.adcol2
-##.adcolumn
-##.adcolumn_wrapper
-~subito.it##.adcont
-##.adcopy
-~superbikeplanet.com##.addiv
-##.adfieldbg
-##.adfoot
-##.adfootbox
-~linux.com##.adframe
-##.adhead
-##.adheader
-##.adheader100
-##.adhere
-##.adhered
-##.adhi
-##.adhint
-~northjersey.com,~rabota.by##.adholder
-##.adhoriz
-##.adi
-##.adiframe
-~backpage.com##.adinfo
-##.adinside
-##.adintro
-##.adjlink
-##.adkit
-##.adkit-advert
-##.adkit-lb-footer
-##.adlabel-horz
-##.adlabel-vert
-##.adleft1
-##.adline
-~superbikeplanet.com##.adlink
-##.adlinks
-~bipbip.co.il##.adlist
-##.adlnklst
-##.admarker
-##.admedrec
-##.admessage
-##.admodule
-##.admpu
-##.admpu-small
-##.adnation-banner
-##.adnotice
-##.adops
-##.adp-AdPrefix
-##.adpadding
-##.adpane
-~bipbip.co.il,~quoka.de##.adpic
-##.adprice
-~tomwans.com##.adright
-##.adroot
-##.adrotate_widget
-##.adrow
-##.adrow-post
-##.adrule
-~dailykos.com##.ads
-##.ads-125
-##.ads-728x90-wrap
-##.ads-banner
-##.ads-below-content
-##.ads-categories-bsa
-##.ads-favicon
-##.ads-links-general
-##.ads-mpu
-##.ads-outer
-##.ads-profile
-##.ads-right
-~apple.com##.ads-section
-##.ads-sidebar
-##.ads-sky
-##.ads-stripe
-##.ads-text
-##.ads-widget
-##.ads-widget-partner-gallery
-##.ads2
-##.ads3
-##.ads300
-##.ads468
-##.ads728
-~amusingplanet.com,~antsandelephants.de,~apple.com,~bakeca.it,~chw.net,~cub.com,~inmart.ua,~joinmyband.co.uk,~lets-sell.info,~najauto.pl,~repubblica.it,~tonprenom.com##.ads:not(body)
-##.adsArea
-##.adsBelowHeadingNormal
-##.adsBlock
-##.adsBox
-##.adsCont
-##.adsDiv
-##.adsFull
-##.adsImages
-##.adsMPU
-##.adsRight
-##.adsTextHouse
-##.adsTop
-##.adsTower2
-##.adsTowerWrap
-##.adsWithUs
-##.ads_125_square
-##.ads_180
-##.ads_300
-##.ads_300x250
-##.ads_337x280
-##.ads_728x90
-##.ads_big
-##.ads_big-half
-##.ads_box
-##.ads_brace
-##.ads_catDiv
-##.ads_container
-##.ads_disc_anchor
-##.ads_disc_leader
-##.ads_disc_lwr_square
-##.ads_disc_skyscraper
-##.ads_disc_square
-##.ads_div
-##.ads_header
-##.ads_leaderboard
-##.ads_mpu
-##.ads_outer
-##.ads_rectangle
-##.ads_right
-##.ads_sc_bl_i
-##.ads_sc_tl_i
-##.ads_show_if
-##.ads_side
-##.ads_sidebar
-##.ads_singlepost
-##.ads_spacer
-##.ads_takeover
-##.ads_title
-##.ads_tr
-##.ads_widesky
-##.ads_wrapperads_top
-##.adsblockvert
-##.adsborder
-##.adsbottom
-##.adsbox
-##.adsboxitem
-##.adsbyyahoo
-##.adsc
-##.adscaleAdvert
-##.adsclick
-##.adscontainer
-##.adscreen
-##.adsection_a2
-##.adsection_c2
-~lalsace.fr,~lepays.fr,~tonprenom.com##.adsense
-##.adsense-ad
-##.adsense-category
-##.adsense-category-bottom
-##.adsense-heading
-##.adsense-post
-##.adsense-right
-##.adsense-title
-##.adsense3
-##.adsenseAds
-##.adsenseBlock
-##.adsenseContainer
-##.adsenseGreenBox
-##.adsense_bdc_v2
-##.adsensebig
-##.adsenseblock
-##.adsenseblock_bottom
-##.adsenseblock_top
-##.adsenselr
-##.adsensem_widget
-##.adsensesq
-##.adsenvelope
-##.adset
-##.adsforums
-##.adsghori
-##.adsgvert
-##.adside
-##.adsidebox
-##.adsider
-##.adsingle
-##.adsleft
-##.adslogan
-##.adsmalltext
-##.adsmessage
-##.adspace
-##.adspace-MR
-##.adspace180
-##.adspace_bottom
-##.adspace_buysell
-##.adspace_rotate
-##.adspace_skyscraper
-##.adspacer
-##.adspot
-##.adspot728x90
-##.adstextpad
-##.adstitle
-##.adstop
-##.adstrip
-~rinkworks.com##.adtable
-##.adtag
-##.adtech
-~anzwers.com.au,~bipbip.co.il,~ksl.com,~quoka.de,~u-file.net##.adtext
-##.adtext_gray
-##.adtext_horizontal
-##.adtext_onwhite
-##.adtext_vertical
-##.adtile
-##.adtips
-##.adtips1
-##.adtop
-##.adtravel
-##.adtxt
-##.adunit
-##.adv-mpu
-##.adver
-##.adverTag
-##.adver_cont_below
-~beginyouridea.com,~irr.ru,~jobs.wa.gov.au,~manxtelecom.com,~storegate.co.uk,~storegate.com,~storegate.se,~swanseacity.net,~toonzaki.com,~travelblog.dailymail.co.uk,~tu-chemnitz.de,~wrexhamafc.co.uk,~yourvids.nl##.advert
-##.advert-article-bottom
-##.advert-bannerad
-##.advert-box
-##.advert-head
-~mobifrance.com##.advert-horizontal
-##.advert-iab-300-250
-##.advert-iab-468-60
-##.advert-mpu
-##.advert-skyscraper
-##.advert-text
-##.advert300
-##.advert4
-##.advert5
-##.advert8
-##.advertColumn
-##.advertCont
-##.advertContainer
-##.advertHeadline
-##.advertRight
-##.advertText
-##.advertTitleSky
-##.advert_468x60
-##.advert_box
-##.advert_cont
-##.advert_djad
-##.advert_label
-##.advert_leaderboard
-~browsershots.org##.advert_list
-##.advert_note
-##.advert_top
-##.advertheader-red
-~tonprenom.com##.advertise
-##.advertise-here
-##.advertise-homestrip
-##.advertise-horz
-##.advertise-leaderboard
-##.advertise-top
-##.advertise-vert
-##.advertiseContainer
-##.advertiseText
-##.advertise_ads
-##.advertise_here
-##.advertise_link
-##.advertise_link_sidebar
-~andkon.com,~ping-timeout.de,~wired.com##.advertisement
-##.advertisement-728x90
-##.advertisement-block
-##.advertisement-sidebar
-##.advertisement-sponsor
-##.advertisement-text
-##.advertisement-top
-##.advertisement468
-##.advertisementBox
-##.advertisementColumnGroup
-##.advertisementContainer
-##.advertisementHeader
-##.advertisementLabel
-##.advertisementPanel
-##.advertisement_btm
-##.advertisement_caption
-##.advertisement_g
-##.advertisement_header
-##.advertisement_horizontal
-##.advertisement_top
-~zlinked.com##.advertiser
-##.advertiser-links
-##.advertisespace_div
-~larga.ru,~tonprenom.com,~trove.nla.gov.au##.advertising
-##.advertising-banner
-##.advertising-header
-##.advertising-local-links
-##.advertising2
-##.advertisingTable
-##.advertising_block
-##.advertising_images
-~macwelt.de##.advertisment
-##.advertisment_two
-##.advertize
-##.advertorial
-##.advertorial-2
-##.advertorial-promo-box
-##.adverts
-##.advt
-##.advt-banner-3
-##.advt-block
-##.advt300
-##.advt720
-##.adwordListings
-##.adwordsHeader
-##.adwrap
-~calgaryherald.com,~montrealgazette.com,~vancouversun.com,~windsorstar.com##.adwrapper
-##.adwrapper-lrec
-##.adwrapper948
-##.adzone-footer
-##.adzone-sidebar
-~virginmobile.fr##.affiliate
-##.affiliate-link
-##.affiliate-sidebar
-##.affiliateAdvertText
-##.affinityAdHeader
-##.after_ad
-##.agi-adsaleslinks
-##.alb-content-ad
-##.alt_ad
-##.anchorAd
-##.another_text_ad
-##.answer_ad_content
-##.aolSponsoredLinks
-##.aopsadvert
-##.apiAdMarkerAbove
-##.apiAds
-##.archive-ads
-##.art_ads
-##.article-ads
-##.articleAd
-##.articleAds
-##.articleAdsL
-##.articleEmbeddedAdBox
-##.article_ad
-##.article_adbox
-##.article_mpu_box
-##.articleads
-##.aseadn
-##.aux-ad-widget-2
-##.b-astro-sponsored-links_horizontal
-##.b-astro-sponsored-links_vertical
-##.banner-ad
-##.banner-ads
-##.banner-adverts
-##.banner300x100
-##.banner300x250
-##.banner468
-##.bannerAd
-##.bannerAdWrapper300x250
-##.bannerAdWrapper730x86
-##.bannerRightAd
-##.banner_300x250
-~milenio.com##.banner_728x90
-##.banner_ad
-##.banner_ad_footer
-##.banner_ad_leaderboard
-##.bannerad
-##.barkerAd
-##.base-ad-mpu
-##.base_ad
-##.bg-ad-link
-##.bgnavad
-##.big-ads
-##.bigAd
-##.big_ad
-##.big_ads
-##.bigad
-##.bigad2
-##.bigbox_ad
-##.bigboxad
-##.billboard_ad
-##.blk_advert
-##.block-ad
-##.block-ad300
-##.block-admanager
-##.block-ads-bottom
-##.block-ads-top
-##.block-adsense
-##.block-openadstream
-##.block-openx
-##.block-thirdage-ads
-~kin0.org##.block_ad
-##.block_ad_sb_text
-##.block_ad_sponsored_links
-##.block_ad_sponsored_links-wrapper
-##.blocked-ads
-##.blog-ad-leader-inner
-##.blog-ads-container
-##.blogAd
-##.blogAdvertisement
-##.blogBigAd
-##.blog_ad
-##.blogads
-##.blox3featuredAd
-##.body_ad
-##.body_sponsoredresults_bottom
-##.body_sponsoredresults_middle
-##.body_sponsoredresults_top
-##.bookseller-header-advt
-##.bottomAd
-##.bottomAds
-##.bottom_ad
-~ixbtlabs.com##.bottom_ad_block
-##.bottom_sponsor
-##.bottomad
-##.bottomadvert
-##.bottomrightrailAd
-##.bottomvidad
-##.box-ad
-##.box-ads
-##.box-adsense
-##.boxAd
-##.box_ad
-##.box_ads
-##.box_advertising
-##.box_advertisment_62_border
-##.box_content_ad
-##.box_content_ads
-##.boxad
-##.boxyads
-##.bps-ad-wrapper
-##.bps-advertisement
-##.bps-advertisement-inline-ads
-##.br-ad
-##.bsa_ads
-##.btm_ad
-##.btn-ad
-##.bullet-sponsored-links
-##.bullet-sponsored-links-gray
-##.burstContentAdIndex
-##.buttonAd
-##.buttonAds
-##.buttonadbox
-##.bx_ad
-##.bx_ad_right
-##.cA-adStrap
-##.cColumn-TextAdsBox
-##.care2_adspace
-##.catalog_ads
-##.category-ad
-##.category__big_game_container_body_games_advertising
-##.cb-ad-container
-##.cb_ads
-##.cb_footer_sponsor
-##.cb_navigation_ad
-##.cbstv_ad_label
-##.cbzadvert
-##.cbzadvert_block
-##.cdAdTitle
-##.cdmainlineSearchAdParent
-##.cdsidebarSearchAdParent
-##.centerAd
-##.center_ad
-##.centerad
-##.centered-ad
-##.cinemabotad
-##.clearerad
-##.cm_ads
-##.cms-Advert
-##.cnbc_badge_banner_ad_area
-##.cnbc_banner_ad_area
-##.cnn160AdFooter
-##.cnnAd
-##.cnnMosaic160Container
-##.cnnSearchSponsorBox
-##.cnnStoreAd
-##.cnnStoryElementBoxAd
-##.cnnWCAdBox
-##.cnnWireAdLtgBox
-##.cnn_728adbin
-##.cnn_adcntr300x100
-##.cnn_adcntr728x90
-##.cnn_adspc336cntr
-##.cnn_adtitle
-##.column2-ad
-##.com-ad-server
-##.comment-advertisement
-##.common_advertisement_title
-##.communityAd
-##.conTSponsored
-##.conductor_ad
-##.confirm_ad_left
-##.confirm_ad_right
-##.confirm_leader_ad
-##.consoleAd
-##.container-adwords
-##.containerSqAd
-##.container_serendipity_plugin_google_adsense
-##.content-ad
-~theology.edu##.contentAd
-##.contentAdFoot
-##.contentAdsWrapper
-##.content_ad
-##.content_ad_728
-##.content_adsq
-##.contentad
-##.contentad300x250
-##.contentad_right_col
-##.contentadcontainer
-##.contentadleft
-##.contenttextad
-##.contest_ad
-##.cp_ad
-##.cpmstarHeadline
-##.cpmstarText
-##.create_ad
-##.cs-mpu
-##.cscTextAd
-##.cse_ads
-##.cspAd
-##.ct_ad
-##.cube-ad
-##.cubeAd
-##.cube_ads
-##.currency_ad
-##.custom_ads
-##.darla_ad
-##.dartAdImage
-##.dart_ad
-##.dart_tag
-##.dartadvert
-##.dartiframe
-##.dc-ad
-##.dcAdvertHeader
-##.deckAd
-##.deckads
-##.detail-ads
-##.detailMpu
-##.detail_ad
-##.detail_top_advert
-##.divAd
-##.divad1
-##.divad2
-##.divad3
-##.divads
-##.divider_ad
-##.dmco_advert_iabrighttitle
-##.download_ad
-##.downloadad
-##.dynamic-ads
-##.dynamic_ad
-##.e-ad
-##.ec-ads
-##.ec-ads-remove-if-empty
-##.em-ad
-##.embed-ad
-##.entry-body-ad
-##.entry_sidebar_ads
-##.entryad
-##.ez-clientAd
-##.f_Ads
-##.featuredAds
-##.featuredadvertising
-##.firstpost_advert_container
-##.flagads
-##.flash-advertisement
-##.flash_ad
-##.flash_advert
-##.flashad
-##.flexiad
-##.flipbook_v2_sponsor_ad
-##.floatad
-##.floated_right_ad
-##.floatingAds
-##.fm-badge-ad
-##.footad
-##.footer-ad
-##.footerAd
-##.footerAdModule
-##.footerAdslot
-##.footerTextAd
-##.footer_ad
-##.footer_ads
-##.footer_block_ad
-##.footer_bottomad
-##.footer_line_ad
-##.footer_text_ad
-##.footerad
-##.forumtopad
-##.frn_adbox
-##.frn_cont_adbox
-##.ft-ad
-##.ftdAdBar
-##.ftdContentAd
-##.full_ad_box
-##.fullbannerad
-##.g3rtn-ad-site
-##.gAdRows
-##.gAdSky
-##.gAdvertising
-##.g_ggl_ad
-##.ga-ads
-##.ga-textads-bottom
-##.ga-textads-top
-##.gaTeaserAdsBox
-##.gads
-##.gads_cb
-##.gads_container
-##.gam_ad_slot
-##.gameAd
-##.gamesPage_ad_content
-##.gglAds
-##.global_banner_ad
-##.googad
-##.googads
-##.google-ad
-##.google-ad-container
-##.google-ads
-##.google-ads-boxout
-##.google-ads-slim
-##.google-right-ad
-##.google-sponsored-ads
-##.google-sponsored-link
-##.google468_60
-##.googleAd
-##.googleAd-content
-##.googleAd-list
-##.googleAdBox
-##.googleAdSense
-##.googleAdSenseModule
-##.googleAd_body
-##.googleAds
-##.googleAds_article_page_above_comments
-##.googleAdsense
-##.googleContentAds
-##.googleProfileAd
-##.googleSearchAd_content
-##.googleSearchAd_sidebar
-##.google_ad
-##.google_add_container
-##.google_ads
-##.google_ads_bom_title
-##.google_ads_content
-##.googlead
-##.googleaddiv
-##.googleaddiv2
-##.googleads
-##.googleads_300x250
-##.googleads_title
-##.googley_ads
-##.gpAdBox
-##.gpAds
-##.gradientAd
-##.grey-ad-line
-##.group_ad
-##.gsAd
-##.gsfAd
-##.gt_ad
-##.gt_ad_300x250
-##.gt_ad_728x90
-##.gt_adlabel
-##.gutter-ad-left
-##.gutter-ad-right
-##.h-ad-728x90-bottom
-##.h_Ads
-##.h_ad
-##.half-ad
-##.half_ad_box
-##.hcf-cms-ad
-##.hd_advert
-##.hdr-ads
-~assetbar.com,~burningangel.com##.header-ad
-##.header-advert
-~photobucket.com##.headerAd
-##.headerAds
-##.headerAdvert
-##.header_ad
-~associatedcontent.com##.header_ad_center
-##.header_ad_div
-##.header_advertisment
-##.headerad
-##.hi5-ad
-##.highlightsAd
-##.hm_advertisment
-##.home-ad-links
-##.homeAd
-##.homeAd1
-##.homeAd2
-##.homeAdBoxA
-##.homeAdBoxBetweenBlocks
-##.homeAdBoxInBignews
-##.homeAdSection
-##.homeMediumAdGroup
-##.home_ad_bottom
-##.home_advertisement
-##.home_mrec_ad
-##.homead
-##.homepage-ad
-##.homepage300ad
-##.homepageFlexAdOuter
-##.homepageMPU
-##.homepage_middle_right_ad
-##.hor_ad
-##.horiz_adspace
-##.horizontalAd
-~radaronline.com##.horizontal_ad
-##.horizontal_ads
-##.horizontaltextadbox
-##.horizsponsoredlinks
-##.hortad
-##.houseAd1
-##.houseAdsStyle
-##.housead
-##.hp2-adtag
-##.hp_ad_cont
-##.hp_ad_text
-##.hp_t_ad
-##.hp_w_ad
-##.ic-ads
-##.ico-adv
-##.idMultiAd
-##.image-advertisement
-##.imageads
-##.imgad
-##.in-page-ad
-##.in-story-text-ad
-##.indie-sidead
-##.indy_googleads
-##.inline-ad
-##.inline-mpu
-##.inline-mpu-left
-##.inlineSideAd
-##.inline_ad
-##.inline_ad_title
-##.inlinead
-##.inlineadsense
-##.inlineadtitle
-##.inlist-ad
-##.inlistAd
-##.inner-advt-banner-3
-##.innerAds
-##.innerad
-##.inpostad
-##.insert_advertisement
-##.insertad
-##.insideStoryAd
-##.inteliusAd_image
-##.interest-based-ad
-##.is24-adplace
-##.islandAd
-##.islandAdvert
-##.islandad
-##.jimdoAdDisclaimer
-##.jp-advertisment-promotional
-##.js-advert
-##.kw_advert
-##.kw_advert_pair
-##.l_ad_sub
-##.l_banner.ads_show_if
-##.labelads
-##.largeRectangleAd
-##.lastRowAd
-##.lcontentbox_ad
-##.leaderAdTop
-##.leaderAdvert
-##.leader_ad
-##.leaderboardAd
-##.leaderboardad
-##.leaderboardadtop
-##.left-ad
-##.leftAd
-##.leftAdColumn
-##.leftAds
-##.left_ad_box
-##.left_adlink
-##.left_ads
-##.leftad
-##.leftadtag
-##.leftbar_ad_160_600
-##.leftbarads
-##.leftnavad
-##.lgRecAd
-##.lg_ad
-##.ligatus
-##.linead
-##.link_adslider
-##.link_advertise
-##.live-search-list-ad-container
-##.ljad
-##.log_ads
-##.logoAds
-##.logoad
-##.longAd
-##.lowerAds
-##.m-ad-tvguide-box
-##.m4-adsbygoogle
-##.m_banner_ads
-##.macAd
-##.macad
-##.main-ad
-##.main-tabs-ad-block
-##.main_ad
-##.main_adbox
-##.main_intro_ad
-##.map_media_banner_ad
-##.marginadsthin
-##.marketing-ad
-##.masthead_topad
-##.mdl-ad
-##.media-advert
-##.mediaAd
-##.mediaAdContainer
-##.mediaResult_sponsoredSearch
-##.medium-rectangle-ad
-##.mediumRectangleAdvert
-##.medrect_ad
-##.menuItemBannerAd
-##.messageBoardAd
-##.mf-ad300-container
-##.micro_ad
-##.mid_ad
-##.midad
-##.middleAds
-##.middleads
-##.min_navi_ad
-##.miniad
-##.mobile-sponsoring
-##.mod-ad-lrec
-##.mod-ad-n
-##.mod-adopenx
-##.mod_admodule
-~corrieredicomo.it##.module-ad
-##.module-ad-small
-##.module-ads
-##.moduleAdvertContent
-##.module_ad
-##.module_box_ad
-##.modulegad
-##.moduletable-advert
-##.moduletable-googleads
-##.moduletablesquaread
-~gamespot.com##.mpu
-##.mpu-ad
-##.mpu-advert
-##.mpu-footer
-##.mpu-fp
-##.mpu-title
-##.mpu-top-left
-##.mpu-top-left-banner
-##.mpu-top-right
-##.mpuAd
-##.mpuAdSlot
-##.mpuAdvert
-##.mpuArea
-##.mpuBox
-##.mpuContainer
-##.mpuHolder
-##.mpuTextAd
-##.mpu_ad
-##.mpu_advert
-##.mpu_gold
-##.mpu_holder
-##.mpu_platinum
-##.mpu_text_ad
-##.mpuad
-##.mpuholderportalpage
-##.mrec_advert
-##.ms-ads-link
-##.msfg-shopping-mpu
-##.mwaads
-##.nSponsoredLcContent
-##.nSponsoredLcTopic
-##.nadvt300
-##.narrow_ad_unit
-##.narrow_ads
-##.navAdsBanner
-##.navi_ad300
-##.naviad
-##.nba300Ad
-##.nbaT3Ad160
-##.nbaTVPodAd
-##.nbaTwo130Ads
-##.nbc_ad_carousel_wrp
-##.newTopAdContainer
-##.newad
-##.news_article_ad_google
-##.newsviewAdBoxInNews
-##.nf-adbox
-##.nn-mpu
-##.noAdForLead
-##.normalAds
-##.nrAds
-##.nsAdRow
-##.oas-ad
-##.oas-bottom-ads
-##.offer_sponsoredlinks
-##.oio-banner-zone
-##.oio-link-sidebar
-##.oio-zone-position
-##.on_single_ad_box
-##.onethirdadholder
-##.openads
-##.openadstext_after
-##.openx
-##.openx-ad
-##.osan-ads
-##.other_adv2
-##.outermainadtd1
-##.ovAdPromo
-##.ovAdSky
-##.ovAdartikel
-##.ov_spns
-##.pageGoogleAd
-##.pageGoogleAdFlat
-##.pageLeaderAd
-##.page_content_right_ad
-##.pagead
-##.pagenavindexcontentad
-##.paneladvert
-##.partnersTextLinks
-##.pencil_ad
-##.player_ad_box
-##.player_page_ad_box
-##.plista_inimg_box
-##.pnp_ad
-##.pod-ad-300
-##.podRelatedAdLinksWidget
-##.podSponsoredLink
-##.portalCenterContentAdBottom
-##.portalCenterContentAdMiddle
-##.portalCenterContentAdTop
-##.portalcontentad
-##.post-ad
-##.post_ad
-##.post_ads
-##.post_sponsor_unit
-##.postbit_adbit_register
-##.postbit_adcode
-##.postgroup-ads
-##.postgroup-ads-middle
-##.prebodyads
-##.premium_ad_container
-##.promoAd
-##.promoAds
-##.promo_ad
-##.publication-ad
-##.publicidad
-##.puff-advertorials
-##.qa_ad_left
-##.qm-ad-content
-##.qm-ad-content-news
-##.quigo-ad
-##.qzvAdDiv
-##.r_ad_box
-##.r_ads
-##.rad_container
-##.rect_ad_module
-##.rectad
-##.rectangleAd
-##.rectanglead
-##.redads_cont
-##.regular_728_ad
-##.regularad
-##.relatedAds
-##.related_post_google_ad
-##.remads
-##.resourceImagetAd
-##.result_ad
-##.results_sponsor
-##.results_sponsor_right
-##.reviewMidAdvertAlign
-##.rght300x250
-##.rhads
-##.rhs-ad
-##.rhs-ads-panel
-##.right-ad
-##.right-ad-holder
-##.right-ad2
-##.right-ads
-##.right-ads2
-##.right-sidebar-box-ad
-~theberrics.com##.rightAd
-##.rightColAd
-##.rightRailAd
-##.right_ad
-##.right_ad_box
-##.right_ad_text
-##.right_ad_top
-##.right_ads
-~dailymotion.com,~dailymotion.virgilio.it##.right_ads_column
-##.right_col_ad
-##.right_hand_advert_column
-##.rightad
-##.rightad_1
-##.rightad_2
-##.rightadbox1
-##.rightads
-##.rightadunit
-##.rightcol_boxad
-##.rightcoladvert
-##.rightcoltowerad
-##.rnav_ad
-##.rngtAd
-##.roundingrayboxads
-##.rt_ad1_300x90
-##.rt_ad_300x250
-##.rt_ad_call
-##.savvyad_unit
-##.sb-ad-sq-bg
-##.sbAd
-##.sbAdUnitContainer
-##.sb_adsN
-##.sb_adsNv2
-##.sb_adsW
-##.sb_adsWv2
-##.scanAd
-##.scc_advert
-##.sci-ad-main
-##.sci-ad-sub
-##.search-ad
-##.search-results-ad
-##.search-sponsor
-##.search-sponsored
-##.searchAd
-##.searchSponsoredResultsBox
-##.searchSponsoredResultsList
-##.search_column_results_sponsored
-##.search_results_sponsored_top
-##.section-ad2
-##.section-sponsor
-##.section_mpu_wrapper
-##.section_mpu_wrapper_wrapper
-##.selfServeAds
-##.sepContentAd
-##.serp_sponsored
-##.servsponserLinks
-##.shoppingGoogleAdSense
-##.sidbaread
-##.side-ad
-##.side-ads
-##.sideAd
-##.sideBoxAd
-##.side_ad
-##.side_ad2
-##.side_ad_1
-##.side_ad_2
-##.side_ad_3
-##.sidead
-##.sideads
-##.sideadsbox
-##.sideadvert
-##.sidebar-ad
-##.sidebar-ads
-##.sidebar-text-ad
-##.sidebarAd
-##.sidebarAdUnit
-##.sidebarAdvert
-##.sidebar_ad
-##.sidebar_ad_300_250
-##.sidebar_ads
-##.sidebar_ads_336
-##.sidebar_adsense
-##.sidebar_box_ad
-##.sidebarad
-##.sidebarad_bottom
-##.sidebaradbox
-##.sidebarboxad
-##.sideheadnarrowad
-##.sideheadsponsorsad
-##.singleAd
-##.singleAdsContainer
-##.singlead
-##.sitesponsor
-##.skinAd
-##.skin_ad_638
-##.sky-ad
-##.skyAd
-##.skyAdd
-##.skyAdvert
-##.sky_ad
-##.sky_scraper_ad
-##.skyad
-##.skyscraper-ad
-##.skyscraper_ad
-##.skyscraper_bannerAdHome
-##.slideshow-ad
-##.slpBigSlimAdUnit
-##.slpSquareAdUnit
-##.sm_ad
-##.smallSkyAd1
-##.smallSkyAd2
-##.small_ad
-##.small_ads
-##.smallad-left
-##.smallads
-##.smallsponsorad
-##.smart_ads_bom_title
-##.specialAd175x90
-##.speedyads
-##.sphereAdContainer
-##.spl-ads
-##.spl_ad
-##.spl_ad2
-##.spl_ad_plus
-##.splitAd
-##.sponlinkbox
-##.spons-link
-##.spons_links
-##.sponslink
-##.sponsor-ad
-##.sponsor-bottom
-##.sponsor-link
-##.sponsor-links
-##.sponsor-right
-##.sponsor-services
-##.sponsor-top
-##.sponsorArea
-##.sponsorBox
-##.sponsorPost
-##.sponsorPostWrap
-##.sponsorStrip
-##.sponsorTop
-##.sponsor_ad_area
-##.sponsor_footer
-##.sponsor_horizontal
-##.sponsor_line
-##.sponsor_links
-##.sponsor_logo
-##.sponsor_top
-##.sponsor_units
-##.sponsoradtitle
-##.sponsorbox
-~gamespot.com,~mint.com,~slidetoplay.com,~smh.com.au,~zattoo.com##.sponsored
-##.sponsored-ads
-##.sponsored-chunk
-##.sponsored-editorial
-##.sponsored-features
-##.sponsored-links
-##.sponsored-links-alt-b
-##.sponsored-links-holder
-##.sponsored-links-right
-##.sponsored-post
-##.sponsored-post_ad
-##.sponsored-results
-##.sponsored-right-border
-##.sponsored-text
-##.sponsoredInner
-##.sponsoredLabel
-##.sponsoredLinks
-##.sponsoredLinks2
-##.sponsoredLinksHeader
-##.sponsoredProduct
-##.sponsoredResults
-##.sponsoredSideInner
-##.sponsored_ads
-##.sponsored_box
-##.sponsored_box_search
-##.sponsored_by
-##.sponsored_links
-##.sponsored_links_title_container
-##.sponsored_links_title_container_top
-##.sponsored_links_top
-##.sponsored_results
-##.sponsored_well
-##.sponsoredibbox
-##.sponsoredlink
-##.sponsoredlinks
-##.sponsoredlinkscontainer
-##.sponsoredresults
-~excite.eu##.sponsoredtextlink_container
-##.sponsoredtextlink_container_ovt
-##.sponsorlink
-##.sponsorlink2
-##.sponsors
-##.sponsors-box
-##.sponsorshipbox
-##.spotlightAd
-##.squareAd
-##.square_ad
-##.squared_ad
-##.ss-ad-mpu
-##.start__newest__big_game_container_body_games_advertising
-##.staticAd
-##.stocks-ad-tag
-##.store-ads
-##.story_AD
-##.story_ad_div
-##.subad
-##.subcontent-ad
-##.super-ad
-##.supercommentad_left
-##.supercommentad_right
-##.supp-ads
-##.supportAdItem
-##.surveyad
-##.t10ad
-##.tab_ad
-##.tab_ad_area
-##.tablebordersponsor
-##.tadsanzeige
-##.tadsbanner
-##.tadselement
-##.tallad
-##.tblTopAds
-##.tbl_ad
-##.tbox_ad
-##.td-Adholder
-##.teaser-sponsor
-##.teaserAdContainer
-##.teaser_adtiles
-##.text-ad-links
-##.text-g-advertisement
-##.text-g-group-short-rec-ad
-##.text-g-net-grp-google-ads-article-page
-##.textAd
-##.textAdBox
-##.textAds
-##.text_ad
-##.text_ads
-##.textad
-##.textadContainer
-##.textad_headline
-##.textadbox
-##.textadheadline
-##.textadlink
-~frogueros.com##.textads
-##.textadsfoot
-##.textadtext
-##.textlink-ads
-##.tf_page_ad_search
-##.thisIsAd
-##.thisIsAnAd
-##.ticket-ad
-##.tileAds
-##.tips_advertisement
-##.title-ad
-##.title_adbig
-##.tncms-region-ads
-##.toolad
-##.toolbar-ad
-##.top-ad
-##.top-ad-space
-##.top-ads
-##.top-menu-ads
-##.top-sponsors
-##.topAd
-##.topAdWrap
-~timescall.com##.topAds
-##.topAdvertisement
-##.topBannerAd
-##.topLeaderboardAd
-##.top_Ad
-##.top_ad
-##.top_ad_728
-##.top_ad_728_90
-##.top_ad_disclaimer
-##.top_ad_div
-##.top_ad_post
-##.top_ad_wrapper
-~trailvoy.com##.top_ads
-##.top_advert
-##.top_advertising_lb
-##.top_container_ad
-##.top_sponsor
-~pchome.com.tw##.topad
-##.topad-bar
-##.topadbox
-~earlyamerica.com##.topads
-##.topadspot
-##.topadvertisementsegment
-##.topcontentadvertisement
-##.topic_inad
-##.topstoriesad
-##.toptenAdBoxA
-##.towerAd
-##.towerAdLeft
-##.towerAds
-##.tower_ad
-##.tower_ad_disclaimer
-##.towerad
-##.ts-ad_unit_bigbox
-##.ts-banner_ad
-##.ttlAdsensel
-##.tto-sponsored-element
-##.tucadtext
-##.tvs-mpu
-##.twoColumnAd
-##.twoadcoll
-##.twoadcolr
-##.tx_smartadserver_pi1
-##.txt-ads
-##.txtAds
-##.txt_ads
-##.txtadvertise
-##.type_adscontainer
-##.type_miniad
-##.type_promoads
-##.ukAds
-##.undertimyads
-##.universalboxADVBOX01
-##.universalboxADVBOX03
-##.universalboxADVBOX04a
-##.usenext
-##.vertad
-##.vertical-adsense
-##.videoAd
-##.videoBoxAd
-##.video_ad
-##.view-promo-mpu-right
-##.view_rig_ad
-##.virgin-mpu
-##.wa_adsbottom
-##.wantads
-##.wide-ad
-##.wide-skyscraper-ad
-##.wideAdTable
-##.wide_ad
-##.wide_ad_unit_top
-##.wide_ads
-##.wide_google_ads
-##.widget-ad
-##.widget-ad300x250
-##.widget-entry-ads-160
-##.widgetYahooAds
-##.widget_ad
-##.widget_ad_rotator
-##.widget_island_ad
-##.widget_sdac_bottom_ad_widget
-##.widget_sdac_footer_ads_widget
-##.widget_sdac_skyscraper_ad_widget
-##.wikia-ad
-##.wikia_ad_placeholder
-##.withAds
-##.wnMultiAd
-##.wp125ad
-##.wp125ad_2
-##.wpn_ad_content
-##.wrap-ads
-##.wsSponsoredLinksRight
-##.wsTopSposoredLinks
-##.x03-adunit
-##.x04-adunit
-##.xads-blk2
-##.xads-ojedn
-##.y-ads
-##.y-ads-wide
-##.y7-advertisement
-##.yahoo-sponsored
-##.yahoo-sponsored-links
-##.yahooAds
-##.yahoo_ads
-##.yan-sponsored
-##.ygrp-ad
-##.yrail_ad_wrap
-##.yrail_ads
-##.ysmsponsor
-##.ysponsor
-##.yw-ad
-~marketgid.com,~mgid.com,~theberry.com,~thebrigade.com,~thechive.com,~thethrottle.com##[id^="MarketGid"]
-##a[href^="http://ad-emea.doubleclick.net/"]
-##a[href^="http://ad.doubleclick.net/"]
-##a[href^="http://adserving.liveuniversenetwork.com/"]
-##a[href^="http://galleries.pinballpublishernetwork.com/"]
-##a[href^="http://galleries.securewebsiteaccess.com/"]
-##a[href^="http://install.securewebsiteaccess.com/"]
-##a[href^="http://latestdownloads.net/download.php?"]
-##a[href^="http://secure.signup-page.com/"]
-##a[href^="http://secure.signup-way.com/"]
-##a[href^="http://www.FriendlyDuck.com/AF_"]
-##a[href^="http://www.adbrite.com/mb/commerce/purchase_form.php?"]
-##a[href^="http://www.friendlyduck.com/AF_"]
-##a[href^="http://www.google.com/aclk?"]
-##a[href^="http://www.liutilities.com/aff"]
-##a[href^="http://www.liutilities.com/products/campaigns/adv/"]
-##a[href^="http://www.my-dirty-hobby.com/?sub="]
-##a[href^="http://www.ringtonematcher.com/"]
-!Google
-###mbEnd[cellspacing="0"][cellpadding="0"][style="padding: 0pt;"]
-###mbEnd[cellspacing="0"][style="padding: 0pt; white-space: nowrap;"]
-##div#mclip_container:first-child:last-child
-##div#tads.c
-##table.ra[align="left"][width="30%"]
-##table.ra[align="right"][width="30%"]
-!-----------------Third-party advertisers-----------------!
-! *** easylist_adservers.txt ***
-||10pipsaffiliates.com^$third-party
-||1100i.com^$third-party
-||188server.com^$third-party
-||194.71.107.25^$third-party
-||247realmedia.com^$third-party
-||2mdn.net^$third-party
-||360ads.com^$third-party
-||3rdads.com^$third-party
-||43plc.com^$third-party
-||600z.com^$third-party
-||777seo.com^$third-party
-||7search.com^$third-party
-||aa.voice2page.com^$third-party
-||accuserveadsystem.com^$third-party
-||acf-webmaster.net^$third-party
-||acronym.com^$third-party
-||ad-flow.com^$third-party
-||ad20.net^$third-party
-||ad2games.com^$third-party
-||ad4game.com^$third-party
-||adaction.se^$third-party
-||adaos-ads.net^$third-party
-||adbard.net^$third-party
-||adbasket.net^$third-party
-||adblade.com^$third-party
-||adbrite.com^$third-party
-||adbull.com^$third-party
-||adbureau.net^$third-party
-||adbutler.com^$third-party
-||adcde.com^$third-party
-||adcentriconline.com^$third-party
-||adchap.com^$third-party
-||adclickmedia.com^$third-party
-||adcolo.com^$third-party
-||adcru.com^$third-party
-||addynamo.com^$third-party
-||adecn.com^$third-party
-||adengage.com^$third-party
-||adf01.net^$third-party
-||adfactory88.com^$third-party
-||adfrontiers.com^$third-party
-||adfusion.com^$third-party
-||adgardener.com^$third-party
-||adgear.com^$third-party
-||adgent007.com^$third-party
-||adgine.net^$third-party
-||adgitize.com^$third-party
-||adgroups.com^$third-party
-||adhese.be^$third-party
-||adhese.net^$third-party
-||adhitzads.com^$third-party
-||adhostingsolutions.com^$third-party
-||adicate.com^$third-party
-||adimise.com^$third-party
-||adimpact.com^$third-party
-||adinterax.com^$third-party
-||adireland.com^$third-party
-||adisfy.com^$third-party
-||adisn.com^$third-party
-||adition.com^$third-party
-||adjal.com^$third-party
-||adjug.com^$third-party
-||adjuggler.com^$third-party
-||adjuggler.net^$third-party
-||adk2.com^$third-party
-||adkonekt.com^$third-party
-||adlink.net^$third-party
-||adlisher.com^$third-party
-||admarketplace.net^$third-party
-||admaya.in^$third-party
-||admeld.com^$third-party
-||admeta.com^$third-party
-||admitad.com^$third-party
-||admpads.com^$third-party
-||adnectar.com^$third-party
-||adnet.biz^$third-party
-||adnet.com^$third-party
-||adnet.ru^$third-party
-||adocean.pl^$third-party
-||adoperator.com^$third-party
-||adoptim.com^$third-party
-||adotube.com^$third-party
-||adparlor.com^$third-party
-||adperium.com^$third-party
-||adpinion.com^$third-party
-||adpionier.de^$third-party
-||adpremo.com^$third-party
-||adprs.net^$third-party
-||adquest3d.com^$third-party
-||adreadytractions.com^$third-party
-||adrise.de^$third-party
-||adrocket.com^$third-party
-||adroll.com^$third-party
-||ads-stats.com^$third-party
-||ads2srv.com^$third-party
-||ads4cheap.com^$third-party
-||adscendmedia.com^$third-party
-||adsdk.com^$third-party
-||adsensecamp.com^$third-party
-||adservinginternational.com^$third-party
-||adsfactor.net^$third-party
-||adsfast.com^$third-party
-||adsforindians.com^$third-party
-||adsfuse.com^$third-party
-||adshopping.com^$third-party
-||adshuffle.com^$third-party
-||adsignals.com^$third-party
-||adsmarket.com^$third-party
-||adsmedia.cc^$third-party
-||adsonar.com^$third-party
-||adspeed.com^$third-party
-||adsrevenue.net^$third-party
-||adsupermarket.com^$third-party
-||adswizz.com^$third-party
-||adtaily.com^$third-party
-||adtaily.eu^$third-party
-||adtech.de^$third-party
-||adtechus.com^$third-party
-||adtoll.com^$third-party
-||adtology1.com^$third-party
-||adtology2.com^$third-party
-||adtology3.com^$third-party
-||adtoma.com^$third-party
-||adtotal.pl^$third-party
-||adtrgt.com^$third-party
-||adtrix.com^$third-party
-||adult-adv.com^$third-party
-||adultadworld.com^$third-party
-||adversalservers.com^$third-party
-||adverserve.net^$third-party
-||advertarium.com.ua^$third-party
-||adverticum.net^$third-party
-||advertise.com^$third-party
-||advertiseyourgame.com^$third-party
-||advertising-department.com^$third-party
-||advertising.com^$third-party
-||advertisingiq.com^$third-party
-||advertlets.com^$third-party
-||advertpay.net^$third-party
-||advertserve.com^$third-party
-||advertstatic.com^$third-party
-||advertxi.com^$third-party
-||advg.jp/$third-party
-||advgoogle.com^$third-party
-||adviva.net^$third-party
-||advmaker.ru^$third-party
-||advmd.com^$third-party
-||advpoints.com^$third-party
-||adworldmedia.com^$third-party
-||adxpower.com^$third-party
-||adyoz.com^$third-party
-||adzerk.net^$third-party
-||afcyhf.com^$third-party
-||aff.biz^$third-party
-||affiliate.com^$third-party
-||affiliate.cx^$third-party
-||affiliatefuel.com^$third-party
-||affiliatefuture.com^$third-party
-||affiliatelounge.com^$third-party
-||affiliatemembership.com^$third-party
-||affiliatesensor.com^$third-party
-||affiliproducts.com^$third-party
-||affimo.de^$third-party
-||affinity.com^$third-party
-||afterdownload.com^$third-party
-||afy11.net^$third-party
-||agentcenters.com^$third-party
-||aggregateknowledge.com^$third-party
-||aim4media.com^$third-party
-||aimatch.com^$third-party
-||ajansreklam.net^$third-party
-||alimama.cn^$third-party
-||alphagodaddy.com^$third-party
-||amgdgt.com^$third-party
-||ampxchange.com^$third-party
-||anrdoezrs.net^$third-party
-||apmebf.com^$third-party
-||arcade-advertisement.com^$third-party
-||arcadebannerexchange.net^$third-party
-||arcadebanners.com^$third-party
-||arcadebe.com^$third-party
-||arti-mediagroup.com^$third-party
-||as5000.com^$third-party
-||asklots.com^$third-party
-||assetize.com^$third-party
-||assoc-amazon.co.uk^$third-party
-||assoc-amazon.com^$third-party
-||atdmt.com^$third-party
-||atmalinks.com^$third-party
-||atwola.com^$third-party
-||audienceprofiler.com^$third-party
-||auditude.com^$third-party
-||auspipe.com^$third-party
-||automateyourlist.com^$third-party
-||avads.co.uk^$third-party
-||avantlink.com^$third-party
-||awaps.net^$third-party
-||awin1.com^$third-party
-||awltovhc.com^$third-party
-||axill.com^$third-party
-||azads.com^$third-party
-||azjmp.com^$third-party
-||azoogleads.com^$third-party
-||backbeatmedia.com^$third-party
-||banner-clix.com^$third-party
-||bannerbank.ru^$third-party
-||bannerblasters.com^$third-party
-||bannercde.com^$third-party
-||bannerconnect.com^$third-party
-||bannerconnect.net^$third-party
-||bannerflux.com^$third-party
-||bannerjammers.com^$third-party
-||bannerlot.com^$third-party
-||bannerrage.com^$third-party
-||bannersmania.com^$third-party
-||bannersnack.net^$third-party
-||bannertgt.com^$third-party
-||bbelements.com^$third-party
-||beaconads.com^$third-party
-||begun.ru^$third-party
-||belointeractive.com^$third-party
-||bestcasinopartner.com^$third-party
-||bestdeals.ws^$third-party
-||bestfindsite.com^$third-party
-||bestofferdirect.com^$third-party
-||bet365affiliates.com^$third-party
-||bfast.com^$third-party
-||bidvertiser.com^$third-party
-||biemedia.com^$third-party
-||bin-layer.de^$third-party
-||bin-layer.ru^$third-party
-||bingo4affiliates.com^$third-party
-||binlayer.de^$third-party
-||bittads.com^$third-party
-||blogads.com^$third-party
-||bluestreak.com^$third-party
-||bmanpn.com^$third-party
-||bnetworx.com^$third-party
-||bnr.sys.lv^$third-party
-||boo-box.com^$third-party
-||boylesportsreklame.com^$third-party
-||branchr.com^$third-party
-||bravenetmedianetwork.com^$third-party
-||bridgetrack.com^$third-party
-||btrll.com^$third-party
-||bu520.com^$third-party
-||buildtrafficx.com^$third-party
-||burstnet.com^$third-party
-||buysellads.com^$third-party
-||buzzparadise.com^$third-party
-||c-on-text.com^$third-party
-||c-planet.net^$third-party
-||c8.net.ua^$third-party
-||canoeklix.com^$third-party
-||captainad.com^$third-party
-||casalemedia.com^$third-party
-||cash4members.com^$third-party
-||cbclickbank.com^$third-party
-||cc-dt.com^$third-party
-||cdna.tremormedia.com^$third-party
-||cgecwm.org^$third-party
-||checkm8.com^$third-party
-||checkmystats.com.au^$third-party
-||checkoutfree.com^$third-party
-||chipleader.com^$third-party
-||chitika.net^$third-party
-||cjt1.net^$third-party
-||clash-media.com^$third-party
-||claxonmedia.com^$third-party
-||click4free.info^$third-party
-||clickad.pl^$third-party
-||clickbooth.com^$third-party
-||clickexa.com^$third-party
-||clickexperts.net^$third-party
-||clickfuse.com^$third-party
-||clickintext.net^$third-party
-||clicksor.com^$third-party
-||clicksor.net^$third-party
-||clickthrucash.com^$third-party
-||clixgalore.com^$third-party
-||coadvertise.com^$third-party
-||cogsdigital.com^$third-party
-||collection-day.com^$third-party
-||collective-media.net^$third-party
-||come2play.net^$third-party
-||commission-junction.com^$third-party
-||commissionmonster.com^$third-party
-||comscore.com^$third-party
-||conduit-banners.com^$third-party
-||connectedads.net^$third-party
-||connextra.com^$third-party
-||contenture.com^$third-party
-||contexlink.se^$third-party
-||contextuads.com^$third-party
-||contextweb.com^$third-party
-||cpaclicks.com^$third-party
-||cpalead.com^$third-party
-||cpays.com^$third-party
-||cpmstar.com^$third-party
-||cpuim.com^$third-party
-||cpxinteractive.com^$third-party
-||crispads.com^$third-party
-||crowdgravity.com^$third-party
-||ctasnet.com^$third-party
-||ctm-media.com^$third-party
-||ctrhub.com^$third-party
-||cubics.com^$third-party
-||d.m3.net^$third-party
-||dashboardad.net^$third-party
-||dbbsrv.com^$third-party
-||decisionmark.com^$third-party
-||decisionnews.com^$third-party
-||decknetwork.net^$third-party
-||deepmetrix.com^$third-party
-||defaultimg.com^$third-party
-||deplayer.net^$third-party
-||destinationurl.com^$third-party
-||dexplatform.com^$third-party
-||dgmaustralia.com^$third-party
-||digitrevenue.com^$third-party
-||dinclinx.com^$third-party
-||directorym.com^$third-party
-||directtrack.com^$third-party
-||dl-rms.com^$third-party
-||dollarade.com^$third-party
-||domainsponsor.com^$third-party
-||dotomi.com^$third-party
-||doubleclick.net/ad/sevenload.*.smartclip/video;$object_subrequest
-||doubleclick.net/adx/*.collegehumor/$object_subrequest,third-party
-||doubleclick.net/pfadx/*.mtvi$object_subrequest,third-party
-||doubleclick.net/pfadx/*.sevenload.com_$object_subrequest
-||doubleclick.net/pfadx/*adcat=$object_subrequest,third-party
-||doubleclick.net^$object_subrequest,third-party,domain=addictinggames.com|atom.com|break.com|businessweek.com|cbc.ca|cbs4denver.com|cnbc.com|darkhorizons.com|doubleviking.com|eonline.com|fandango.com|foxbusiness.com|foxnews.com|g4tv.com|joblo.com|kptv.com|mtv.co.uk|mtv.com|mtv.com.au|mtv.com.nz|mtvbase.com|mtvmusic.com|myfoxorlando.com|myfoxphoenix.com|newsweek.com|nick.com|nintendoeverything.com|pandora.com|play.it|ps3news.com|rte.ie|sbsun.com|sevenload.com|shockwave.com|southpark.nl|space.com|spike.com|thedailygreen.com|thedailyshow.com|thewire.com|ustream.tv|washingtonpost.com|wcbstv.com|wired.com|wkbw.com|wsj.com|wwe.com|youtube.com|zoomin.tv
-||doubleclick.net^$~object_subrequest,third-party
-||doubleclick.net^*;sz=$object_subrequest,third-party,domain=1up.com|breitbart.tv|digitaltrends.com|gamesradar.com|gametrailers.com|heavy.com|myfoxny.com|myspace.com|nbc.com|nfl.com|nhl.com|wptv.com
-||dpbolvw.net^$third-party
-||dt00.net^$domain=~goodsbrowser.com|~marketgid.com|~mgid.com|~thechive.com
-||dt07.net^$domain=~marketgid.com|~mgid.com|~thechive.com
-||e-planning.net^$third-party
-||easyhits4u.com^$third-party
-||ebannertraffic.com^$third-party
-||ebayobjects.com.au^$third-party
-||ebayobjects.com^$third-party
-||edge-dl.andomedia.com^$third-party
-||egamingonline.com^$third-party
-||ekmas.com^$third-party
-||emediate.eu^$third-party
-||emediate.se^$third-party
-||engineseeker.com^$third-party
-||ero-advertising.com^$third-party
-||etology.com^$third-party
-||euroclick.com^$third-party
-||euros4click.de^$third-party
-||exelator.com^$third-party
-||exitexplosion.com^$third-party
-||exitjunction.com^$third-party
-||exponential.com^$third-party
-||eyereturn.com^$third-party
-||eyewonder.com^$third-party
-||fairadsnetwork.com^$third-party
-||fairfax.com.au^$~stylesheet,third-party
-||falkag.net^$third-party
-||fastclick.net^$third-party
-||fimserve.com^$third-party
-||findsthat.com^$third-party
-||firstadsolution.com^$third-party
-||firstlightera.com^$third-party
-||fixionmedia.com^$third-party
-||flashtalking.com^$third-party
-||fluxads.com^$third-party
-||fmpub.net^$third-party
-||footerslideupad.com^$third-party
-||forexyard.com^$third-party
-||forrestersurveys.com^$third-party
-||freebannerswap.co.uk^$third-party
-||freelancer.com^$third-party
-||friendlyduck.com^$third-party
-||ftjcfx.com^$third-party
-||funklicks.com^$third-party
-||fusionads.net^$third-party
-||fwmrm.net^$third-party
-||g.doubleclick.net^$third-party
-||gambling-affiliation.com^$third-party
-||game-advertising-online.com^$third-party
-||gameads.com^$third-party
-||gamecetera.com^$third-party
-||gamersbanner.com^$third-party
-||gannett.gcion.com^$third-party
-||gate-ru.com^$third-party
-||geek2us.net^$third-party
-||geo-idm.fr^$third-party
-||geopromos.com^$third-party
-||gestionpub.com^$third-party
-||ggncpm.com^$third-party
-||gimiclub.com^$third-party
-||gklmedia.com^$third-party
-||globaladsales.com^$third-party
-||globaladv.net^$third-party
-||gmads.net^$third-party
-||go2media.org^$third-party
-||googleadservices.com^$third-party
-||grabmyads.com^$third-party
-||gratisnetwork.com^$third-party
-||guardiandigitalcomparison.co.uk^$third-party
-||gumgum.com^$third-party
-||halogennetwork.com^$third-party
-||havamedia.net^$third-party
-||hb-247.com^$third-party
-||hit-now.com^$third-party
-||hits.sys.lv^$third-party
-||hopfeed.com^$third-party
-||hosticanaffiliate.com^$third-party
-||hot-hits.us^$third-party
-||hotptp.com^$third-party
-||httpool.com^$third-party
-||hypemakers.net^$third-party
-||hypervre.com^$third-party
-||ibatom.com^$third-party
-||icdirect.com^$third-party
-||imagesatlantic.com^$third-party
-||imedia.co.il^$third-party
-||imglt.com^$third-party
-||imho.ru/$third-party
-||imiclk.com^$third-party
-||impact-ad.jp^$third-party
-||impresionesweb.com^$third-party
-||indiabanner.com^$third-party
-||indiads.com^$third-party
-||indianbannerexchange.com^$third-party
-||indianlinkexchange.com^$third-party
-||industrybrains.com^$third-party
-||inetinteractive.com^$third-party
-||infinite-ads.com^$third-party
-||influads.com^$third-party
-||infolinks.com^$third-party
-||information-sale.com^$third-party
-||innity.com^$third-party
-||insightexpressai.com^$third-party
-||inskinad.com^$third-party
-||inskinmedia.com^$third-party
-||instantbannercreator.com^$third-party
-||intellibanners.com^$third-party
-||intellitxt.com^$third-party
-||interclick.com^$third-party
-||interpolls.com^$third-party
-||inuvo.com^$third-party
-||investingchannel.com^$third-party
-||ipromote.com^$third-party
-||jangonetwork.com^$third-party
-||jdoqocy.com^$third-party
-||js.cdn.ac^
-||jsfeedadsget.com^$third-party
-||jumboaffiliates.com^$third-party
-||justrelevant.com^$third-party
-||kalooga.com^$third-party
-||kanoodle.com^$third-party
-||kavanga.ru^$third-party
-||kehalim.com^$third-party
-||kerg.net^$third-party
-||ketoo.com^$third-party
-||kitnmedia.com^$third-party
-||klikvip.com^$third-party
-||klipmart.com^$third-party
-||kontera.com^$third-party
-||kqzyfj.com^$third-party
-||lakequincy.com^$third-party
-||lduhtrp.net^$third-party
-||leadacceptor.com^$third-party
-||liftdna.com^$third-party
-||ligatus.com^$third-party
-||lightningcast.net^$~object_subrequest,third-party
-||lingospot.com^$third-party
-||linkbucks.com^$third-party
-||linkbuddies.com^$third-party
-||linkexchange.com^$third-party
-||linkreferral.com^$third-party
-||linkshowoff.com^$third-party
-||linkstorm.net^$third-party
-||linksynergy.com^$third-party
-||linkworth.com^$third-party
-||linkz.net^$third-party
-||liverail.com^$third-party
-||liveuniversenetwork.com^$third-party
-||looksmart.com^$third-party
-||ltassrv.com.s3.amazonaws.com^$third-party
-||ltassrv.com^$third-party
-||lzjl.com^$third-party
-||madisonlogic.com^$third-party
-||markethealth.com^$third-party
-||marketingsolutions.yahoo.com^$third-party
-||marketnetwork.com^$third-party
-||maxserving.com^$third-party
-||mb01.com^$third-party
-||mbn.com.ua^$third-party
-||media6degrees.com^$third-party
-||mediag4.com^$third-party
-||mediagridwork.com^$third-party
-||medialand.ru^$third-party
-||medialation.net^$third-party
-||mediaonenetwork.net^$third-party
-||mediaplex.com^$third-party
-||mediatarget.com^$third-party
-||medleyads.com^$third-party
-||medrx.sensis.com.au^$third-party
-||meetic-partners.com^$third-party
-||megaclick.com^$third-party
-||mercuras.com^$third-party
-||metaffiliation.com^$third-party
-||mezimedia.com^$third-party
-||microsoftaffiliates.net^$third-party
-||milabra.com^$third-party
-||mirago.com^$third-party
-||miva.com^$third-party
-||mixpo.com^$third-party
-||mktseek.com^$third-party
-||money4ads.com^$third-party
-||mookie1.com^$third-party
-||mootermedia.com^$third-party
-||moregamers.com^$third-party
-||moreplayerz.com^$third-party
-||mpression.net^$third-party
-||msads.net^$third-party
-||nabbr.com^$third-party
-||nbjmp.com^$third-party
-||nbstatic.com^$third-party
-||neodatagroup.com^$third-party
-||neoffic.com^$third-party
-||net3media.com^$third-party
-||netavenir.com^$third-party
-||netseer.com^$third-party
-||networldmedia.net^$third-party
-||newsadstream.com^$third-party
-||newtention.net^$third-party
-||nexac.com^$third-party
-||nicheads.com^$third-party
-||nobleppc.com^$third-party
-||northmay.com^$third-party
-||nowlooking.net^$third-party
-||nvero.net^$third-party
-||nyadmcncserve-05y06a.com^$third-party
-||obeus.com^$third-party
-||obibanners.com^$third-party
-||objects.tremormedia.com^$~object_subrequest,third-party
-||objectservers.com^$third-party
-||oclus.com^$third-party
-||offerforge.com^$third-party
-||omg2.com^$third-party
-||omguk.com^$third-party
-||onads.com^$third-party
-||onenetworkdirect.net^$third-party
-||onlineadtracker.co.uk^$third-party
-||opensourceadvertisementnetwork.info^$third-party
-||openx.com^$third-party
-||openx.net^$third-party
-||openx.org^$third-party
-||opinionbar.com^$third-party
-||othersonline.com^$third-party
-||overture.com^$third-party
-||oxado.com^$third-party
-||p-advg.com^$third-party
-||pagead2.googlesyndication.com^$~object_subrequest,third-party
-||pakbanners.com^$third-party
-||paperg.com^$third-party
-||partner.video.syndication.msn.com^$~object_subrequest,third-party
-||partypartners.com^$third-party
-||payperpost.com^$third-party
-||pc-ads.com^$third-party
-||peer39.net^$third-party
-||pepperjamnetwork.com^$third-party
-||perfb.com^$third-party
-||performancingads.com^$third-party
-||pgmediaserve.com^$third-party
-||pgpartner.com^$third-party
-||pheedo.com^$third-party
-||picadmedia.com^$third-party
-||pinballpublishernetwork.com^$third-party
-||pixazza.com^$third-party
-||platinumadvertisement.com^$third-party
-||playertraffic.com^$third-party
-||pmsrvr.com^$third-party
-||pntra.com^$third-party
-||pntrac.com^$third-party
-||pntrs.com^$third-party
-||pointroll.com^$third-party
-||popads.net^$third-party
-||popadscdn.net^$third-party
-||ppclinking.com^$third-party
-||precisionclick.com^$third-party
-||predictad.com^$third-party
-||primaryads.com^$third-party
-||pro-advertising.com^$third-party
-||pro-market.net^$third-party
-||proadsdirect.com^$third-party
-||probannerswap.com^$third-party
-||prod.untd.com^$third-party
-||profitpeelers.com^$third-party
-||projectwonderful.com^$third-party
-||proximic.com^$third-party
-||psclicks.com^$third-party
-||ptp.lolco.net^$third-party
-||pubmatic.com^$third-party
-||pulse360.com^$third-party
-||qksrv.net^$third-party
-||qksz.net^$third-party
-||questionmarket.com^$third-party
-||questus.com^$third-party
-||quisma.com^$third-party
-||radiusmarketing.com^$third-party
-||rapt.com^$third-party
-||rbcdn.com^$third-party
-||realclick.co.kr^$third-party
-||realmedia.com^$third-party
-||reelcentric.com^$third-party
-||reklamz.com^$third-party
-||resultlinks.com^$third-party
-||revenuegiants.com^$third-party
-||revenuemantra.com^$third-party
-||revfusion.net^$third-party
-||revresda.com^$third-party
-||ricead.com^$third-party
-||ringtonematcher.com^$third-party
-||rmxads.com^$third-party
-||roirocket.com^$third-party
-||rotatingad.com^$third-party
-||rovion.com^$third-party
-||ru4.com/$third-party
-||rubiconproject.com^$third-party
-||rwpads.com^$third-party
-||sa.entireweb.com^$third-party
-||safelistextreme.com^$third-party
-||salvador24.com^$third-party
-||saple.net^$third-party
-||sbaffiliates.com^$third-party
-||scanscout.com^$third-party
-||search123.uk.com^$third-party
-||securewebsiteaccess.com^$third-party
-||selsin.net^$third-party
-||sendptp.com^$third-party
-||seriousfiles.com^$third-party
-||servali.net^$third-party
-||sev4ifmxa.com^$third-party
-||sexmoney.com^$third-party
-||shareasale.com^$third-party
-||sharegods.com^$third-party
-||shareresults.com^$third-party
-||shinobi.jp^$third-party
-||simply.com^$third-party
-||sitebrand.com^$third-party
-||siteencore.com^$third-party
-||skimlinks.com^$third-party
-||skimresources.com^$third-party
-||skoovyads.com^$third-party
-||smart.allocine.fr$third-party
-||smart2.allocine.fr^$third-party
-||smartadserver.com^$third-party
-||smarttargetting.co.uk^$third-party
-||smarttargetting.com^$third-party
-||smarttargetting.net^$third-party
-||smpgfx.com^$third-party
-||snap.com^$third-party
-||so-excited.com^$third-party
-||sochr.com^$third-party
-||sociallypublish.com^$third-party
-||socialmedia.com^$third-party
-||socialspark.com^$third-party
-||sociocast.com^$third-party
-||softonicads.com^$third-party
-||sonnerie.net^$third-party
-||sparkstudios.com^$third-party
-||specificclick.net^$third-party
-||specificmedia.com^$third-party
-||speedsuccess.net^$third-party
-||spinbox.freedom.com^$third-party
-||sponsorads.de^$third-party
-||sponsoredtweets.com^$third-party
-||sponsormob.com^$third-party
-||sponsorpalace.com^$third-party
-||sportsyndicator.com^$third-party
-||spotrails.com^$third-party
-||spottt.com^$third-party
-||spotxchange.com^$third-party,domain=~supernovatube.com
-||sproose.com^$third-party
-||srtk.net^$third-party
-||sta-ads.com^$third-party
-||starlayer.com^$third-party
-||statcamp.net^$third-party
-||stocker.bonnint.net^$third-party
-||struq.com^$third-party
-||sublimemedia.net^$third-party
-||supremeadsonline.com^$third-party
-||survey-poll.com^$third-party
-||tacoda.net^$third-party
-||tailsweep.com^$third-party
-||targetnet.com^$third-party
-||targetpoint.com^$third-party
-||targetspot.com^$third-party
-||teracent.net^$third-party
-||testnet.nl^$third-party
-||text-link-ads.com^$third-party
-||theloungenet.com^$third-party
-||thewebgemnetwork.com^$third-party
-||tidaltv.com^$third-party
-||tiser.com^$third-party
-||tkqlhce.com^$third-party
-||topauto10.com^$third-party
-||total-media.net^$third-party
-||tqlkg.com^$third-party
-||tradedoubler.com^$third-party
-||tradepub.com^$third-party
-||tradetracker.net^$third-party
-||trafficbarads.com^$third-party
-||trafficjunky.net^$third-party
-||trafficmasterz.net^$third-party
-||trafficrevenue.net^$third-party
-||trafficsynergy.com^$third-party
-||trafficwave.net^$third-party
-||traveladvertising.com^$third-party
-||travelscream.com^$third-party
-||travidia.com^$third-party
-||triadmedianetwork.com^$third-party
-||tribalfusion.com^$third-party
-||trigami.com^$third-party
-||trker.com^$third-party
-||tvprocessing.com^$third-party
-||twinplan.com^$third-party
-||twittad.com^$third-party
-||tyroo.com^$third-party
-||udmserve.net^$third-party
-||ukbanners.com^$third-party
-||unanimis.co.uk^$third-party
-||unicast.com^$third-party
-||unrulymedia.com^$third-party
-||usbanners.com^$third-party
-||usemax.de^$third-party
-||usenetpassport.com^$third-party
-||usercash.com^$third-party
-||utarget.co.uk^$third-party
-||v.movad.de^*/ad.xml$third-party
-||validclick.com^$third-party
-||valuead.com^$third-party
-||valueclick.com^$third-party
-||valueclickmedia.com^$third-party
-||vcmedia.com^$third-party
-||velmedia.net^$third-party
-||versetime.com^$third-party
-||vianadserver.com^$third-party
-||vibrantmedia.com^$third-party
-||videoegg.com^$third-party
-||videostrip.com^$~object_subrequest,third-party
-||videostrip.com^*/admatcherclient.$object_subrequest,third-party
-||vidpay.com^$third-party
-||viglink.com^$third-party
-||vipquesting.com^$third-party
-||viraladnetwork.net^$third-party
-||visitdetails.com^$third-party
-||vitalads.net^$third-party
-||vpico.com^$third-party
-||vs20060817.com^$third-party
-||vsservers.net^$third-party
-||webads.co.nz^$third-party
-||webgains.com^$third-party
-||webmasterplan.com^$third-party
-||weborama.fr^$third-party
-||webtraffic.ttinet.com^$third-party
-||wgreatdream.com^$third-party
-||widgetbucks.com^$third-party
-||widgets.fccinteractive.com^$third-party
-||wootmedia.net^$third-party
-||worlddatinghere.com^$third-party
-||worthathousandwords.com^$third-party
-||wwbn.com^$third-party
-||wwwadcntr.com^$third-party
-||x4300tiz.com^$third-party
-||xcelltech.com^$third-party
-||xcelsiusadserver.com^$third-party
-||xchangebanners.com^$third-party
-||xgraph.net^$third-party
-||yceml.net^$third-party
-||yesnexus.com^$third-party
-||yieldbuild.com^$third-party
-||yieldmanager.com^$third-party
-||yieldmanager.net^$third-party
-||yldmgrimg.net^$third-party
-||yottacash.com^$third-party
-||yumenetworks.com^$third-party
-||zangocash.com^$third-party
-||zanox.com^$third-party
-||zeads.com^$third-party
-||zedo.com^$third-party
-||zoomdirect.com.au^$third-party
-||zxxds.net^$third-party
-!Mobile
-||admob.com^$third-party
-||adwhirl.com^$third-party
-||adzmob.com^$third-party
-||amobee.com^$third-party
-||mkhoj.com^$third-party
-||mojiva.com^$third-party
-||smaato.net^$third-party
-||waptrick.com^$third-party
-!-----------------Third-party adverts-----------------!
-! *** easylist_thirdparty.txt ***
-||000webhost.com/images/banners/
-||208.43.84.120/trueswordsa3.gif$third-party
-||21nova.com/promodisplay?
-||770.com/banniere.php?
-||a.ucoz.net^
-||ablacrack.com/popup-pvd.js$third-party
-||adn.ebay.com^
-||ads.mp.mydas.mobi^
-||adserver-live.yoc.mobi^
-||adstil.indiatimes.com^
-||adultfriendfinder.com/banners/$third-party
-||adultfriendfinder.com/go/page/js_im_box?$third-party
-||advanced-intelligence.com/banner
-||affil.mupromo.com^
-||affiliate.astraweb.com^
-||affiliates.a2hosting.com^
-||affiliates.bhphotovideo.com^
-||affiliates.bravenet.com^
-||affiliates.generatorsoftware.com^
-||affiliates.hotelclub.com^
-||affiliates.jlist.com^
-||affiliates.justhost.com^
-||affiliates.supergreenhosting.com^
-||affiliation.fotovista.com^
-||affutdmedia.com^$third-party
-||allposters.com^*/banners/
-||allsend.com/public/assets/images/
-||allsolutionsnetwork.com/banners/
-||aolcdn.com/os/music/img/*-skin.jpg
-||apple.com/itunesaffiliates/
-||appwork.org/hoster/banner_$image
-||appwork.org/images/
-||as.devbridge.com^$third-party
-||autoprivileges.net/news/
-||award.sitekeuring.net^
-||aweber.com/banners/
-||b.livesport.eu^
-||b.sell.com^$third-party
-||b92.putniktravel.com^
-||b92s.net/images/banners/
-||babylon.com/trans_box/*&affiliate=
-||banner.1and1.com^
-||banner.3ddownloads.com^
-||banner.telefragged.com^
-||banners.adultfriendfinder.com^$third-party
-||banners.cams.com^
-||banners.friendfinder.com^
-||banners.getiton.com^
-||banners.ixitools.com^
-||banners.penthouse.com^
-||banners.smarttweak.com^
-||banners.virtuagirlhd.com^
-||bc.coupons.com^$third-party
-||bet-at-home.com/oddbanner.aspx?
-||beta.down2crazy.com^$third-party
-||bigcdn.com^*/adttext.swf
-||bijk.com^*/banners/
-||bitshare.com^*/banner/
-||bittorrent.am/serws.php?$third-party
-||blissful-sin.com/affiliates/
-||box.anchorfree.net^
-||bplaced.net/pub/
-||bravenet.com/cserv.php?
-||break.com^*/partnerpublish/
-||btguard.com/images/$third-party
-||bullguard.com^*/banners/
-||buy.com^*/affiliate/
-||buzznet.com^*/showpping-banner-$third-party
-||cas.clickability.com^
-||cash.neweramediaworks.com^
-||cashmakingpowersites.com^*/banners/
-||cashmyvideo.com/images/cashmyvideo_banner.gif
-||cazoz.com/banner.php
-||cbanners.virtuagirlhd.com^$third-party
-||cdn.sweeva.com/images/$third-party
-||challies.com^*/wtsbooks5.png$third-party
-||cimg.in/images/banners/
-||connect.summit.co.uk^
-||counter-strike.com/banners/
-||creatives.inmotionhosting.com^
-||creatives.summitconnect.co.uk^
-||dapatwang.com/images/banner/
-||datakl.com/banner/
-||desi4m.com/desi4m.gif$third-party
-||detroitmedia.com/jfry/
-||dynw.com/banner
-||enticelabs.com/el/
-||entrecard.com/static/banners/
-||eplreplays.com/wl/
-||esport-betting.com^*/betbanner/
-||everestpoker.com^*/?adv=
-||facebook.com/whitepages/wpminiprofile.php?partner_id=$third-party
-||fantaz.com^*/banners/$third-party
-||fapturbo.com/testoid/
-||farmholidays.is/iframeallfarmsearch.aspx?$third-party
-||feedburner.com/~a/
-||filedownloader.net/design/$third-party
-||filesonic.com^*/banners/
-||flipchat.com/index.php?$third-party
-||forms.aweber.com/form/styled_popovers_and_lightboxes.js$third-party
-||fragfestservers.com/bannerb.gif
-||freakshare.net/banner/
-||free-football.tv/images/usd/
-||frogatto.com/images/$third-party
-||frontsight.com^*/banners/
-||fugger.netfirms.com/moa.swf$third-party
-||futuresite.register.com/us?$third-party
-||gamersaloon.com/images/banners/
-||gamestop.com^*/aflbanners/
-||gawkerassets.com/assets/marquee/$object,third-party
-||gfxa.sheetmusicplus.com^$third-party
-||ggmania.com^*.jpg$third-party
-||giganews.com/banners/$third-party
-||glam.com/js/$third-party
-||gogousenet.com^*/promo.cgi
-||googlesyndication.com^*/domainpark.cgi?
-||graboid.com/affiliates/
-||graduateinjapan.com/affiliates/
-||grammar.coursekey.com/inter/$third-party
-||gsniper.com/images/$third-party
-||hostingcatalog.com/banner.php?
-||idg.com.au/ggg/images/*_home.jpg$third-party
-||idownloadunlimited.com/aff-exchange/
-||ifilm.com/website/*_skin_$third-party
-||ign.com/js.ng/
-||image.com.com^*/skin2.jpg$third-party
-||images.youbuy.it/images/$third-party
-||img.mybet.com^$third-party
-||iol.co.za^*/sponsors/
-||iselectmedia.com^*/banners/
-||jimdo.com/s/img/aff/
-||jinx.com/content/banner/$third-party
-||jlist.com/feed.php?affid=$third-party
-||joylandcasino.com/promoredirect?$third-party
-||justcutegirls.com/banners/$third-party
-||kaango.com/fecustomwidgetdisplay?
-||kallout.com^*.php?id=
-||keyword-winner.com/demo/images/
-||krillion.com^*/productoffers.js
-||l.yimg.com^*&partner=*&url=
-||ladbrokes.com^*&aff_id=
-||lastlocation.com/images/banner
-||lego.com^*/affiliate/
-||letters.coursekey.com/lettertemplates_$third-party
-||liutilities.com/partners/affiliate/
-||livejasmin.com^$subdocument,third-party
-||longtailvideo.com/ltas.swf$third-party
-||lowbird.com/random/$third-party
-||marketing.888.com^
-||marketsamurai.com/affiliate/
-||mastiway.com/webimages/$third-party
-||match.com^*/prm/$third-party
-||mazda.com.au/banners/
-||media-toolbar.com^$third-party
-||media.onlineteachers.co.in^$third-party
-||meta4-group.com^*/promotioncorner.js?
-||metaboli.fr^*/adgude_$third-party
-||mfeed.newzfind.com^$third-party
-||missnowmrs.com/images/banners/
-||mto.mediatakeout.com^$third-party
-||my-dirty-hobby.com/getmdhlink.$third-party
-||mydirtyhobby.com/?sub=$third-party
-||mydirtyhobby.com/banner/$third-party
-||mydirtyhobby.com/custom/$third-party
-||mydirtyhobby.com/getmdhlink.$third-party
-||mydirtyhobby.com/gpromo/$third-party
-||mydirtyhobby.com^*.php?*&goto=join$third-party
-||mydirtyhobby.com^*/gpromo/$third-party
-||myfreepaysite.info^*.gif$third-party
-||myfreeresources.com/getimg.php?$third-party
-||myhpf.co.uk/banners/
-||mytrafficstrategy.com/images/$third-party
-||myusenet.net/promo.cgi?
-||netload.in^*?refer_id=
-||nzpages.co.nz^*/banners/
-||nzphoenix.com/nzgamer/$third-party
-||onegameplace.com/iframe.php$third-party
-||oriongadgets.com^*/banners/
-||partner.bargaindomains.com^
-||partner.catchy.com^
-||partner.premiumdomains.com^
-||partners.agoda.com^
-||partners.dogtime.com/network/
-||partycasino.com^*?wm=$third-party
-||partypoker.com/hp_landingpages/$third-party
-||partypoker.com^*?wm=$third-party
-||paytel.co.za/code/ref
-||pcash.imlive.com^$third-party
-||perfectmarket.com/pm/ad-
-||play-asia.com/paos-$third-party
-||pokerstars.com/euro_bnrs/
-||pop6.com/banners/
-||pornturbo.com/tmarket.php
-||ppc-coach.com/jamaffiliates/
-||pricegrabber.com/cb_table.php$third-party
-||pricegrabber.com/mlink.php?$third-party
-||promo.bauermedia.co.uk^
-||promos.fling.com^
-||promote.pair.com^
-||proxies2u.com/images/btn/$third-party
-||proxyroll.com/proxybanner.php
-||pub.betclick.com^
-||pubs.hiddennetwork.com^
-||qiksilver.net^*/banners/
-||radiocentre.ca/randomimages/$third-party
-||radioshack.com^*/promo/
-||rapidjazz.com/banner_rotation/
-||rcm*.amazon.$third-party
-||redvase.bravenet.com^$third-party
-||regnow.com/vendor/
-||robofish.com/cgi-bin/banner.cgi?
-||sayswap.com/banners/
-||searchportal.information.com/?$third-party
-||secondspin.com/twcontent/
-||sfimg.com/images/banners/
-||shaadi.com^*/get-banner.php?
-||shareflare.net/images/$third-party
-||shop-top1000.com/images/
-||shop4tech.com^*/banner/
-||shragle.com^*?ref=
-||singlemuslim.com/affiliates/
-||sitegrip.com^*/swagbucks-
-||skykingscasino.com/promoloaddisplay?
-||slickdeals.meritline.com^
-||smartclip.net/delivery/tag?
-||smilepk.com/bnrsbtns/
-||snapdeal.com^*.php$third-party
-||splashpagemaker.com/images/$third-party
-||stats.sitesuite.org^
-||stockroom.com/banners/
-||storage.to/affiliate/
-||supply.upjers.com^$third-party
-||sweed.to/affiliates/
-||sweeva.com/widget.php?w=$third-party
-||swiftco.net/banner/
-||theatm.info/images/$third-party
-||thebigchair.com.au^$subdocument,third-party
-||themes420.com/bnrsbtns/
-||themis-media.com^*/sponsorships/
-||ticketmaster.com/promotionalcontent/
-||tigerdirect.com^*/affiliate_
-||top5result.com/promo/
-||toptenreviews.com/widgets/af_widget.js$third-party
-||torrentfreebie.com/index.asp?pid=$third-party
-||tosol.co.uk/international.php?$third-party
-||toysrus.com/graphics/promo/
-||travelmail.traveltek.net^$third-party
-||turbotrafficsystem.com^*/banners/
-||twivert.com/external/banner234x60.
-||u-loader.com/image/hotspot_
-||unsereuni.at/resources/img/$third-party
-||valuate.com/banners/
-||veospot.com^*.html
-||videodetective.net/flash/players/plugins/iva_adaptvad.swf
-||videoplaza.com/creatives/
-||visit.homepagle.com^$third-party
-||visitorboost.com/images/$third-party
-||website.ws^*/banners/
-||williamhill.com/promoloaddisplay?
-||williamhillcasino.com/promoredirect?
-||wonderlabs.com/affiliate_pro/banners/
-||ws.amazon.*/widgets/q?$third-party
-||xgaming.com/rotate*.php?$third-party
-||xml.exactseek.com/cgi-bin/js-feed.cgi?$third-party
-||yimg.com^*/quickplay_maxwellhouse.png
-!Preliminary third-party adult section
-||awempire.com/ban/$third-party
-||hotcaracum.com/banner/$third-party
-!Mobile
-||iadc.qwapi.com^
-!-----------------Specific advert blocking filters-----------------!
-! *** easylist_specific_block.txt ***
-||1057theoasis.com/addrotate_content.php?
-||1079thealternative.com/addrotate_content.php?
-||174.143.241.129^$domain=astalavista.com
-||1up.com^*/promos/
-||216.151.186.5^*/serve.php?$domain=sendspace.com
-||4chan.org/support/
-||5min.com^*/banners/
-||77.247.178.36/layer/$domain=movie2k.com
-||84.234.22.104/ads/$domain=tvcatchup.com
-||85.17.254.150^*.php?$domain=wiretarget.com
-||87.230.102.24/ads/
-||87.230.102.24/gads/
-||911tabs.com/img/takeover_app_
-||911tabs.com^*/ringtones_overlay.js
-||963kklz.com/addrotate_content.php?
-||9news.com/promo/
-||a.giantrealm.com^
-||a.thefreedictionary.com^
-||a7.org/info_en/
-||about.com/0g/$subdocument
-||abovetopsecret.com/300_
-||ac2.msn.com^
-||access.njherald.com^
-||acidcow.com/banners.php?
-||activewin.com^*/blaze_static2.gif
-||adelaidecityfc.com.au/oak.swf
-||adf.ly/market.php
-||adpaths.com/_aspx/cpcinclude.aspx?
-||ads.readwriteweb.com^
-||adshare.freedocast.com^
-||adv.letitbit.net^
-||advt.manoramaonline.com^
-||akipress.com/_ban/
-||akipress.org/ban/
-||akipress.org/bimages/
-||allmovieportal.com/dynbanner.php?
-||allthelyrics.com^*/popup.js
-||analytics.mmosite.com^
-||androidpit.com/app-seller/app-seller.swf?xmlpath=$object
-||anime-source.com/banzai/banner.$subdocument
-||animekuro.com/layout/google$subdocument
-||animenewsnetwork.com^*.aframe?
-||aniscartujo.com^*/layer.js
-||anonib.com/zimages/
-||anti-leech.com/al.php?
-||armorgames.com^*/banners/
-||armorgames.com^*/site-skins/
-||armorgames.com^*/siteskin.css
-||artima.com/zcr/
-||asianewsnet.net/banner/
-||astalavista.com/avtng/
-||athena-ads.wikia.com^
-||autosport.com/skinning/
-||avaxhome.ws/banners/
-||azlyrics.com^*_az.js
-||b92.net/images/banners/
-||banner.atomicgamer.com^
-||banner.itweb.co.za^
-||banners-*.jobstreet.com^
-||banners.expressindia.com^
-||banners.friday-ad.co.uk/hpbanneruploads/$image
-||banners.i-comers.com^
-||banners.itweb.co.za^
-||bbc.co.uk^*/bbccom.js?
-||bcdb.com^*/banners.pl?
-||beingpc.com^*/banners/
-||belfasttelegraph.co.uk/editorial/web/survey/recruit-div-img.js
-||bigpoint.com/xml/recommender.swf?
-||bigpond.com/home/skin_
-||bit-tech.net/images/backgrounds/skin/
-||bittorrent.am/banners/
-||blackberryforums.net/banners/
-||blinkx.com/adhocnetwork/
-||blinkx.com/f2/overlays/adhoc
-||blogspider.net/images/promo/
-||bloomberg.com^*/banner.js
-||bnrs.ilm.ee^
-||bollywoodbuzz.in^*/728x70.gif
-||bookingbuddy.com/js/bookingbuddy.strings.php?$domain=smartertravel.com
-||boyplz.com^*/layer.js
-||break.com^*/marketguide-iframe.html
-||brenz.net/img/bannerrss.gif
-||brothersoft.com/softsale/
-||brothersoft.com^*/float.js
-||browsershots.org/static/images/creative/
-||budapesttimes.hu/images/banners/
-||burnsoftware.info*/!
-||businesstimes.com.sg^*/ad
-||bwp.theinsider.com.com^
-||c-sharpcorner.com^*/banners/
-||c21media.net/uploads/flash/*.swf
-||cafimg.com/images/other/
-||candystand.com/banners/
-||carsguide.com.au^*/marketing/
-||cbc.ca/video/bigbox.html
-||cdmediaworld.com*/!
-||cdnlayer.com/howtogeek/geekers/up/netshel125x125.gif
-||celebjihad.com/widget/widget.js$domain=popbytes.com
-||centos.org/donors/
-||chapagain.com.np^*_125x125_
-||chapala.com/wwwboard/webboardtop.htm
-||china.com^*/googlehead.js
-||chinapost.com.tw/ad/
-||ciao.co.uk/load_file.php?
-||classicfeel.co.za^*/banners/
-||click.livedoor.com^
-||clk.about.com^
-||cms.myspacecdn.com^*/splash_assets/
-||codeasily.com^*/codeasily.js
-||codeproject.com^*/adm/
-||coderanch.com/shingles/
-||comm.kino.to^
-||comparestoreprices.co.uk/images/promotions/
-||complexmedianetwork.com^*/takeovers/
-||computerandvideogames.com^*/promos/
-||computerworld.com^*/jobroll/
-||consumerreports.org^*/sx.js
-||countrychannel.tv/telvos_banners/
-||covertarget.com^*_*.php
-||cpuid.com^*/cpuidbanner72x90_2.
-||crazymotion.net/video_*.php?key=
-||crushorflush.com/html/promoframe.html
-||d-addicts.com^*/banner/
-||da.feedsportal.com^$~subdocument
-||dads.new.digg.com^
-||dailyblogtips.com/wp-content/uploads/*.gif
-||dailydeals.sfgate.com/widget/
-||dailymail.co.uk^*/promoboxes/
-||dailymotion.com/images/ie.png
-||dailymotion.com/skin/data/default/partner/$~stylesheet
-||dailymotion.com^*masscast/
-||dailystar.com.lb/bannerin1.htm
-||dailystar.com.lb/bottombanner.htm
-||dailystar.com.lb/centerbanner.htm
-||dailystar.com.lb/googlearticle468.htm
-||dailystar.com.lb/leaderboard.htm
-||dailystar.com.lb/spcovbannerin.htm
-||dailytimes.com.pk/banners/
-||dailywritingtips.com^*/money-making.gif
-||davesite.com^*/aff/
-||dcad.watersoul.com^
-||demonoid.com/cached/ab_
-||demonoid.com/cached/bnr_
-||desiretoinspire.net^*-125x125.
-||desiretoinspire.net^*_125x125.
-||desiretoinspire.net^*/125x125-
-||desiretoinspire.net^*/125x125_
-||desiretoinspire.net^*/mgbanner.gif
-||detnews.com^*/sponsor/
-||develop-online.net/static/banners/
-||dig.abclocal.go.com/preroll/
-||digdug.divxnetworks.com^
-||digitaljournal.com/promo/
-||digitallook.com^*/rbs-logo-ticker.gif
-||digitalreality.co.nz^*/360_hacks_banner.gif
-||digitizor.com/wp-content/digimages/xsoftspyse.png
-||divxme.com/images/play.png
-||divxstage.net/images/download.png
-||dl4all.com/data4.files/dpopupwindow.js
-||domaining.com/banners/
-||dontblockme.modaco.com^$~image
-||dvdvideosoft.com^*/banners/
-||earthlink.net^*/promos/
-||ebayrtm.com/rtm?
-||ebuddy.com/banners/
-||ebuddy.com/textlink.php?
-||ebuddy.com/web_banners/
-||ebuddy.com/web_banners_
-||ecommerce-journal.com/specdata.php?
-||ehow.com/images/brands/
-||ekrit.de/serious-gamer/1.swf
-||ekrit.de/serious-gamer/film1.swf
-||ekrit.de/serious-gamer/images/stories/city-quest.jpg
-||el33tonline.com^*/el33t_bg_
-||electricenergyonline.com^*/bannieres/
-||episodic.com^*/logos/player-
-||espn.vad.go.com^$domain=youtube.com
-||esus.com/images/regiochat_logo.png
-||eurogamer.net/quad.php
-||eva.ucas.com^
-||eweek.com/images/stories/marketing/
-||excite.com/gca_iframe.html?
-||expatexchange.com/banner/
-||expertreviews.co.uk/images/skins/
-||expreview.com/exp2/
-||fallout3nexus.com^*/300x600.php
-||feedsportal.com/creative/
-||ffiles.com/counters.js
-||fgfx.co.uk/banner.js?
-||filebase.to/gfx/*.jpg
-||filebase.to/xtend/
-||filebase.to^*/note.js
-||filefront.com/linkto/
-||filespazz.com/imx/template_r2_c3.jpg
-||filespazz.com^*/copyartwork_side_banner.gif
-||filetarget.com*/!
-||filetarget.com^*_*.php
-||findfiles.com/images/icatchallfree.png
-||findfiles.com/images/knife-dancing-1.gif
-||flixstertomatoes.com^*/jquery.js?
-||flixstertomatoes.com^*/jquery.rt_scrollmultimedia.js
-||flixstertomatoes.com^*/jquery.tooltip.min.js?
-||flv.sales.cbs.com^$object_subrequest,domain=cbsnews.com
-||flyordie.com/games/free/b/
-||fmr.co.za^*/banners/
-||fordforums.com.au/banner.swf
-||forumimg.ipmart.com/swf/ipmart_forum/banner
-||forumw.org/images/uploading.gif
-||foxbusiness.com/html/google_homepage_promo
-||foxnews1280.com^*/clientgraphics/
-||foxradio.com/common/dfpframe.
-||foxradio.com/media/module/billboards/
-||free-tv-video-online.info/300.html
-||free-tv-video-online.info/300s.html
-||freeappaday.com/nimgs/bb/
-||freemediatv.com/images/inmemoryofmichael.jpg
-||freewaremission.com/banners/
-||freeworldgroup.com/banner
-||friday-ad.co.uk/banner.js?
-||fudzilla.com^*/banners/
-||gamecopyworld.com*/!
-||gamemakerblog.com/gma/gatob.php
-||gameplanet.co.nz^*-takeover.jpg
-||gametrailers.com^*/gt6_siteskin_$stylesheet
-||gbrej.com/c/
-||geocities.com/js_source/
-||geocities.yahoo.*/js/sq.
-||getprice.com.au/searchwidget.aspx?$subdocument
-||ghacks.net/skin-
-||glam.com^*/affiliate/
-||goauto.com.au/mellor/mellor.nsf/toy$subdocument
-||goodgearguide.com.au/files/skins/
-||gowilkes.com/cj/
-||gowilkes.com/other/
-||grapevine.is/media/flash/*.swf
-||guitaretab.com^*/ringtones_overlay.js
-||gumtree.com^*/dart_wrapper_
-||gwinnettdailypost.com/1.iframe.asp?
-||hdtvtest.co.uk^*/pricerunner.php
-||helsinkitimes.fi^*/banners/
-||holyfragger.com/images/skins/
-||horizonsunlimited.com/alogos/
-||horriblesubs.net/playasia*.gif
-||horriblesubs.org/playasia*.gif
-||hostsearch.com/creative/
-||hotfrog.com/adblock.ashx?
-||howtogeek.com/go/
-||hulkshare.oncdn.com^*/removeads.
-||hummy.org.uk^*/brotator/
-||i.com.com^*/vendor_bg_
-||i.i.com.com/cnwk.1d/*/tt_post_dl.jpg
-||i.neoseeker.com/d/$subdocument
-||i4u.com/_banner/
-||ibanners.empoweredcomms.com.au^
-||ibtimes.com/banner/
-||ibtimes.com^*/sponsor_
-||icelandreview.com^*/auglysingar/
-||idg.com.au/images/*_promo$image
-||idg.com.au^*_skin.jpg
-||ifilm.com/website/*-skin-
-||iloveim.com/cadv4.jsp?
-||images-amazon.com^*/marqueepushdown/
-||imageshack.us/images/contests/*/lp-bg.jpg
-||imageshack.us/ym.php?
-||img*.i-comers.com^
-||impulsedriven.com/app_images/wallpaper/
-||independent.co.uk/multimedia/archive/$subdocument
-||informationmadness.com^*/banners/
-||informer.com/images/sponsored.gif
-||infoseek.co.jp/isweb/clip.html
-||injpn.net/images/banners/
-||insidehw.com/images/banners/
-||intellicast.com/travel/cheapflightswidget.htm
-||interfacelift.com/inc_new/$subdocument
-||internet.ziffdavis.com^
-||iptools.com/sky.php
-||isitnormal.com/img/iphone_hp_promo_wide.png
-||itpro.co.uk/images/skins/
-||itweb.co.za/banners/
-||itweb.co.za/logos/
-||iwebtool.com^*/bannerview.php
-||jame-world.com^*/adv/
-||japanvisitor.com/banners/
-||jdownloader.org/_media/screenshots/banner.png
-||jdownloader.org^*/smbanner.png
-||jewishtimes-sj.com/rop/
-||jewlicious.com/banners/
-||jewtube.com/banners/
-||johnbridge.com/vbulletin/banner_rotate.js
-||johnbridge.com/vbulletin/images/tyw/cdlogo-john-bridge.jpg
-||johnbridge.com/vbulletin/images/tyw/wedi-shower-systems-solutions.png
-||jollo.com/images/travel.gif
-||jpost.com/images/*/promos/
-||jpost.com/images/2009/newsite/
-||kcye.com/addrotate_content.php?
-||kdwn.com/addrotate_content.php?
-||kephyr.com/spywarescanner/banner1.gif
-||kermit.macnn.com^
-||kestrel.ospreymedialp.com^
-||kewlshare.com/reward.html
-||kino.to/gr/blob/
-||kitco.com^*/banners/*.swf
-||kitz.co.uk/files/jump2/
-||kjul1047.com^*/clientgraphics/
-||klav1230am.com^*/banners/
-||knowfree.net^*/ezm125x125.gif
-||krapps.com^*-banner-
-||krebsonsecurity.com^*banner.swf?
-||kstp.com^*/flexhousepromotions/
-||kxlh.com/images/banner/
-||kyivpost.com^*/adv_
-||kyivpost.com^*/banner/
-||labtimes.org/banner/
-||lastminute.com^*/universal.html?
-||latex-community.org/images/banners/
-||lightningcast.net^*/getplaylist?$third-party,domain=reuters.com
-||linksafe.info^*/mirror.png
-||linksave.in^*/downloadbutton_highspeed.png
-||linuxtopia.org/includes/$subdocument
-||livestream.com^*/overlay/
-||loaded.it/images/ban*.swf
-||loaded.it^*/geld-internet-verdienen.jpg
-||loaded.it^*/iframe_vid.
-||loaded.it^*/my_banner
-||londonstockexchange.com/prices-and-news/*/fx.gif
-||looky.hyves.org^
-||loombo.com^*/remove-ads.
-||loveolgy.com/banners/
-||lowbird.com/lbpu.php
-||lowellsun.com/litebanner/
-||lowyat.net/catfish/
-||lowyat.net^*/images/header/
-||lyricsfreak.com^*/overlay.js
-||macaudailytimes.com.mo/files/banners/
-||macmillandictionary.com/info/frame.html?zone=
-||macobserver.com/js/givetotmo.js
-||macobserver.com^*/deal_brothers/
-||macworld.co.uk^*/textdeals/
-||madskristensen.net/discount2.js
-||mail.google.com/mail/*&view=ad
-||majorgeeks.com/aff/
-||majorgeeks.com/images/mb-hb-2.jpg
-||majorgeeks.com/images/mg120.jpg
-||majorgeeks.com^*/banners/
-||mangafox.com/media/game321/
-||mangaupdates.com/affiliates/
-||mani-admin-plugin.com^*/banners/
-||mccont.com/sda/
-||mccont.com/takeover/
-||mcstatic.com^*/billboard_
-||mcvuk.com/static/banners/
-||medhelp.org/hserver/
-||media.abc.go.com^*/callouts/
-||media.mtvnservices.com/player/scripts/mtvn_player_control.js$domain=spike.com
-||mediafire.com^*/linkto/default-$subdocument
-||mediafire.com^*/remove_ads.gif
-||mediamgr.ugo.com^
-||meetic.com/js/*/site_under_
-||megaupload.com/mc.php?
-||megavideo.com/goviral.php
-||megavideo.com/unruley.php
-||merriam-webster.com^*/accipiter.js
-||mg.co.za/uploads/*.swf?
-||mgnetwork.com/dealtaker/
-||mirror.co.uk^*/gutters/
-||mirror.co.uk^*/m4_gutters/
-||mirror.co.uk^*/m4_partners/
-||mirror.co.uk^*/people_promotions/
-||mmegi.bw^*/banner_
-||mmegi.bw^*/banners_
-||mmorpg.com/images/skins/
-||mochiads.com/srv/
-||movshare.net^*/remove_ads.jpg
-||movstreaming.com/images/edhim.jpg
-||mp3mediaworld.com*/!
-||mp3raid.com/imesh.gif
-||msn.com/?adunitid
-||musicremedy.com/banner/
-||musictarget.com*/!
-||myspace.com^*.adtooltip&
-||mystream.to^*/button_close.png
-||myway.com/gca_iframe.html
-||nationalturk.com^*/banner
-||naukimg.com/banner/
-||nba.com^*/amex_logo
-||nba.com^*/steinersports_
-||nearlygood.com^*/_aff.php?
-||neoseeker.com/a_pane.php
-||nerej.com/c/
-||newport-county.co.uk/images/general_images/blue_square_update_01.gif
-||newport-county.co.uk/images/home_page_images/234x60.gif
-||newport-county.co.uk/images/home_page_images/premier_sport_anmin.gif
-||news-leader.com^*/banner.js
-||news.com.au/news/vodafone/$object
-||news.com.au^*-promo$image
-||news.com.au^*/promos/
-||news10.net^*/just-deals-940x30.jpg
-||newsreview.com/images/adv.gif
-||newsreview.com/images/promo.gif
-||nirsoft.net/banners/
-||nma-fallout.com^*_banner_120x240.jpg
-||ntdtv.com^*/adv/
-||nuts.co.uk/themes/takeovers/$image
-||ny1.com^*/servecontent.aspx?iframe=
-||nyaatorrents.org/images/nw.
-||nyaatorrents.org/images/skyscraper.
-||nymag.com^*/metrony_
-||nypost.com^*/takeovers/
-||nyrej.com/c/
-||objects.tremormedia.com/embed/swf/bcacudeomodule.swf$domain=radaronline.com
-||ocforums.com/adj/
-||oldgames.sk/images/topbar/
-||osdir.com/ml/$subdocument
-||oyetimes.com/join/advertisers.html
-||payplay.fm^*/mastercs.js
-||pbsrc.com/sponsor/
-||pbsrc.com^*/sponsor/
-||pcauthority.com.au^*/skins/
-||pcpro.co.uk/images/*_siteskin
-||pcpro.co.uk/images/skins/
-||pcpro.co.uk^*/pcprositeskin
-||pcpro.co.uk^*skin_wide.
-||pcworld.idg.com.au/files/skins/
-||pettube.com/images/*-partner.
-||phobos.apple.com^$object_subrequest,domain=dailymotion.com
-||photoshopguides.com/banners/
-||photosupload.net/photosupload.js
-||pinknews.co.uk/newweb/
-||pitchero.com^*/toolstation.gif
-||pocketpcaddict.com/forums/images/banners/
-||pons.eu^*/lingeniobanner.swf
-||popbytes.com/img/*-ad.jpg
-||popbytes.com/img/becomeasponsor.gif
-||popbytes.com/img/no-phone-zone.gif
-||popbytes.com/img/sunset-idle-1.gif
-||popbytes.com/img/thinkups-230x115.gif
-||popbytes.com/img/visitmysponsors.gif
-||postcrescent.com^*/promos/
-||postzambia.com/banner_
-||prisonplanet.com^*advert.
-||prisonplanet.com^*banner
-||prisonplanet.com^*sky.
-||project-for-sell.com/_google.php
-||promo.fileforum.com^
-||proxy.org/af.html
-||proxy.org/ah.html
-||ps3news.com/banner/
-||ps3news.com^*.swf
-||ps3news.com^*/200x90.jpg
-||ps3news.com^*/200x90_
-||ps3news.com^*/200x90f.jpg
-||ps3news.com^*/dscartshop.gif
-||ps3news.com^*/global_background_ps3break.jpg
-||ps3news.com^*/lightake.gif
-||ps3news.com^*/mod-chip.png
-||psx-scene.com^*/cyb_banners/
-||psx-scene.com^*/sponsors/
-||qrz.com/pix/*.gif
-||querverweis.net/pu.js
-||quickload.to^*/layer.divx.js
-||quickload.to^*/note.divx.js
-||quickload.to^*/note.js
-||quicksilverscreen.com/img/moviesforfree.jpg
-||rad.msn.com^
-||radiovaticana.org^*/alitalia
-||rapbasement.com/images/stacy-adams-rs.jpg
-||readwriteweb.com^*/clouddownloadvmwarepromo.png
-||readwriteweb.com^*/rwcloudlearnmorebutton.png
-||rejournal.com/images/banners/
-||rejournal.com/users/blinks/
-||rejournal.com^*/images/homepage/
-||retrevo.com^*/pcwframe.jsp?
-||rfu.com/js/jquery.jcarousel.js
-||richmedia.yimg.com^
-||riderfans.com/other/
-||rocktelevision.com^*_banner_
-||sahilonline.org/adv/
-||sameip.org/images/froghost.gif
-||satelliteguys.us/burst_header_iframe.
-||satelliteguys.us/burstbox_iframe.
-||satelliteguys.us/burstsky_iframe.
-||scenereleases.info/wp-content/*.swf
-||scenereleases.info^*/yourprivatevpn.gif
-||sciencedaily.com^*/google-story2-rb.js
-||seatguru.com/deals?
-||seeingwithsound.com/noad.gif
-||sendspace.com/defaults/framer.html?z=
-||sendspace.com^*?zone=
-||sensongs.com/nfls/
-||serialzz.us/ad.js
-||share-links.biz^*/hs.gif
-||sharebeast.com^*/remove_ads.gif
-||sharetera.com/images/icon_download.png
-||sharetera.com/promo.php?
-||shop.com/cc.class/dfp?
-||shopping.stylelist.com/widget?
-||shoppingpartners2.futurenet.com^
-||shops.tgdaily.com^*&widget=
-||shortcuts.search.yahoo.com^*&callback=yahoo.shortcuts.utils.setdittoadcontents&
-||showstreet.com/banner.
-||sify.com^*/gads_
-||sk-gaming.com/image/acersocialw.gif
-||sk-gaming.com/image/pts/
-||sk-gaming.com/www/skdelivery/
-||slyck.com/pics/*304x83_
-||smh.com.au/images/promo/
-||snopes.com^*/casalebox.asp
-||snopes.com^*/tribalbox.asp
-||soccerlens.com/files1/
-||soccerway.com/banners/
-||soccerway.com/buttons/120x90_
-||soccerway.com/media/img/mybet_banner.gif
-||softarchive.net/js/getbanner.php?
-||softcab.com/google.php?
-||softonic.com/specials_leaderboard/
-||soundtracklyrics.net^*_az.js
-||southafricab2b.co.za/banners/
-||space.com/promo/
-||startxchange.com/bnr.php
-||sternfannetwork.com/forum/images/banners/
-||steroid.com/banner/
-||steroid.com/dsoct09.swf
-||stlyrics.com^*_az.js
-||strategypage.com^*_banner
-||stuff.tv/client/skinning/
-||suntimes.com^*/banners/
-||supernovatube.com/spark.html
-||sydneyolympicfc.com/admin/media_manager/media/mm_magic_display/$image
-||techpowerup.com/images/bnnrs/
-||techradar.com^*/img/*_takeover_
-||techsupportforum.com^*/banners/
-||techtree.com^*/jquery.catfish.js
-||teesoft.info/images/uniblue.png
-||telegraphindia.com^*/banners/
-||telegraphindia.com^*/hoabanner.
-||tentonhammer.com^*/takeovers/
-||theaquarian.com^*/banners/
-||thecorrsmisc.com/10feet_banner.gif
-||thecorrsmisc.com/brokenthread.jpg
-||thecorrsmisc.com/msb_banner.jpg
-||thehighstreetweb.com^*/banners/
-||theispguide.com/premiumisp.html
-||theispguide.com/topbanner.asp?
-||themis-media.com/media/global/images/cskins/
-||themis.yahoo.com^
-||thepiratebay.org/img/bar.gif
-||thewb.com/thewb/swf/tmz-adblock/
-||tigerdroppings.com^*&adcode=
-||times-herald.com/pubfiles/
-||titanbet.com/promoloaddisplay?
-||torrentfreak.com^*/wyzo.gif
-||trackitdown.net/skins/*_campaign/
-||tripadvisor.co.uk/adp/
-||tripadvisor.com/adp/
-||tripadvisor.com^*/skyscraper.jpg
-||turbobit.net/js/popunder2.js
-||tweaktown.com/cms/includes/i*.php
-||typicallyspanish.com/banners/
-||ua.badongo.com^
-||ubuntugeek.com/images/dnsstock.png
-||uimserv.net^
-||ultimate-guitar.com^*/takeover/
-||uncoached.com/smallpics/ashley
-||unicast.ign.com^
-||unicast.msn.com^
-||universalhub.com/bban/
-||uploading.com/static/banners/
-||videodownloadtoolbar.com/fancybox/
-||videogamer.com^*/css/skins/$stylesheet
-||videos.com/click?
-||videos.mediaite.com/decor/live/white_alpha_60.
-||videosift.com/bnr.php?
-||videoweed.com^*/remove_ads.png
-||videoweed.com^*/stream_movies_hd_button.png
-||viewdocsonline.com/images/banners/
-||vortez.co.uk^*120x600.swf
-||vortez.co.uk^*skyscraper.jpg
-||w3schools.com/banners/
-||wareseeker.com/banners/
-||webhostingtalk.com/js/hail.js
-||webnewswire.com/images/banner
-||websitehome.co.uk/seoheap/cheap-web-hosting.gif
-||weddingtv.com/src/usefulstuff/*banner
-||werlv.com^*banner
-||weselectmodels.com^*/new_banner.jpg
-||whispersinthecorridors.com/banner2009/
-||wikia.com/__varnish_
-||windowsitpro.com^*/doubleclick/
-||windowsitpro.com^*/googleafc
-||windowsitpro.com^*/roadblock.js
-||wnst.net/img/coupon/
-||wolf-howl.com/wp-content/banners/
-||wollongongfc.com.au/images/banners/
-||worthdownloading.com/images/mirrors/preview_logo.gif
-||wowwiki.com/__varnish_
-||wunderground.com/geo/swfad/
-||www2.sys-con.com^*.cfm
-||xbitlabs.com^*/xbanner.php?
-||xbox-scene.com/crave/logo_on_white_s160.jpg
-||xoops-theme.com/images/banners/
-||yahoo.*/serv?s=
-||yahoo.com/darla/
-||yahoo.com/ysmload.html?
-||yahoo.com^*/eyc-themis?
-||yellowpages.co.za/bms/
-||yfrog.com/images/contests/*/lp-bg.jpg
-||yfrog.com/ym.php?
-||yimg.com/a/1-$~stylesheet
-||yimg.com^*/fairfax/$image
-||yimg.com^*/flash/promotions/
-||yourmovies.com.au^*/side_panels_
-||yourtomtom.com^*/back_adblock.gif
-||ytimg.com^*/new_watch_background$domain=youtube.com
-||ytimg.com^*_banner$domain=youtube.com
-||zam.com/i/promos/*-skin.
-||zambiz.co.zm/banners/
-||zonein.tv/adds.php
-||zonein.tv/adds1.php
-||zonein.tv/addsz.php
-||zophar.net/files/tf_
-||zurrieqfc.com/images/banners/
-!Anti-Adblock
-||illimitux.net/js/abp.js
-||indieclicktv.com/player/swf/*/icmmva%5eplugin.swf$object_subrequest
-!-----------------Specific element hiding rules-----------------!
-! *** easylist_specific_hide.txt ***
-10minutemail.com###shoutouts
-123people.co.uk###l_banner
-1911encyclopedia.org##.google_block_style
-2gb-hosting.com##div.info[align="center"]
-4chan.org###ad
-4megaupload.com##table[width="100%"][cellspacing="0"][cellpadding="0"][border="0"][bgcolor="#d8d8d0"]
-4shared.com##.signupbanner
-4shared.com##center > img[width="13"][height="84"][style="cursor: pointer;"]
-4shared.com##img[alt="Remove Ads"]
-6lyrics.com##.ad
-7tutorials.com##.block-openx
-9news.com##.poster
-9to5mac.com###block-dealmac-0
-9to5mac.com###page-top
-a10.com###gameunderbanner
-abc2news.com##.ad
-abclocal.go.com###bannerTop
-abclocal.go.com##.linksWeLike
-abcnews.go.com##.ad
-abndigital.com###banner468
-abndigital.com###leaderboard_728x90
-about.com###adB
-about.com##.gB
-accuradio.com###rightskyscraper_placeholder
-accuradio.com###top_leaderboard
-accuweather.com###googleContainer
-achieve360points.com###a1
-achieve360points.com###a3
-actiontrip.com###banner300
-adelaidecityfc.com.au##td[width="130"][valign="top"][align="right"]:last-child > table[width="125"][cellspacing="0"][cellpadding="0"][border="0"][align="right"]:first-child:last-child
-adelaideunited.com.au##.promotion_wrapper
-adf.ly###bottom
-adultswim.com###ad
-advocate.com###BottomBanners
-advocate.com###TopBanners
-afl.com.au##div[style="width: 300px; height: 250px;"]
-afro.com###leaderboard
-afterdawn.com###dlSoftwareDesc300x250
-afterdawn.com##.uniblue
-airspacemag.com###top-banners
-ajaxian.com###taeheader
-akeelwap.net##a[href^="http://c.admob.com/"]
-akeelwap.net##a[href^="http://click.buzzcity.net/click.php?"]
-akihabaranews.com###bbTop
-akihabaranews.com###recSidebar
-alarabiya.net###side_banner
-allakhazam.com###bannerMain
-allakhazam.com###towerRt
-allbusiness.com##.search_results
-allexperts.com###sl
-allmovieportal.com##table[width="100%"][height="90"]
-allmusicals.com##img[width="190"]
-allshopsuk.co.uk##table[border="0"][align="center"][width="100%"]
-allthelyrics.com##div[style="padding: 0px 0px 15px;"]
-altavista.com###spons
-altavista.com##a[href*=".overture.com/d/sr/"]
-alternet.org###premium
-alternet.org###premium2_container
-alternet.org##.premium-container
-amazon.co.uk##.bm
-amazon.co.uk##.tigerbox
-amazon.co.uk##iframe[title="Ad"]
-amazon.com##.pa_containerWrapper
-amazon.com##iframe[title="Ad"]
-america.fm###banbo
-ampercent.com###centersidebar
-ampercent.com##.titlebelow
-anandtech.com##.ad
-ancestry.com##.uprPromo
-anchorfree.net##div[style="width: 728px; display: block; height: 90px; margin: 15px 0pt;"]
-androidapps.com##.ad
-androidpit.com##.boxLightLeft[style="width: 620px; text-align: center; font-size: 95%;"]
-anime-planet.com##.medrec
-animea.net##.ad
-animenewsnetwork.com###page-header-banner
-animepaper.net###ifiblockthisthenicheatap
-animetake.com##.top-banner
-anonymouse.org###mouselayer
-ansearch.com.au##.sponsor
-answerology.com##.leaderboard
-answers.com###radLinks
-aol.ca###rA
-aol.co.uk###banner
-aol.co.uk###rA
-aol.co.uk##.sad_cont
-aol.co.uk##.sidebarBanner
-aol.com###rA
-aol.com##.g_slm
-aol.com##.gsl
-aol.com##.sad_cont
-aolnews.com##.fauxArticleIMU
-ap.org##td[width="160"]
-app.com,argusleader.com,battlecreekenquirer.com,baxterbulletin.com,bucyrustelegraphforum.com,burlingtonfreepress.com,centralohio.com,chillicothegazette.com,cincinnati.com,citizen-times.com,clarionledger.com,coloradoan.com,coshoctontribune.com,courier-journal.com,courierpostonline.com,dailyrecord.com,dailyworld.com,delawareonline.com,delmarvanow.com,democratandchronicle.com,desmoinesregister.com,dnj.com,fdlreporter.com,freep.com,greatfallstribune.com,greenbaypressgazette.com,greenvilleonline.com,guampdn.com,hattiesburgamerican.com,hometownlife.com,honoluluadvertiser.com,htrnews.com,indystar.com,jacksonsun.com,jconline.com,lancastereaglegazette.com,lansingstatejournal.com,livingstondaily.com,lohud.com,mansfieldnewsjournal.com,marionstar.com,marshfieldnewsherald.com,montgomeryadvertiser.com,mycentraljersey.com,mydesert.com,newarkadvocate.com,news-leader.com,news-press.com,newsleader.com,pal-item.com,pnj.com,portclintonnewsherald.com,postcrescent.com,poughkeepsiejournal.com,press-citizen.com,pressconnects.com,rgj.com,sctimes.com,sheboyganpress.com,shreveporttimes.com,stargazette.com,statesmanjournal.com,stevenspointjournal.com,tallahassee.com,tennessean.com,theadvertiser.com,thecalifornian.com,thedailyjournal.com,theithacajournal.com,theleafchronicle.com,thenews-messenger.com,thenewsstar.com,thenorthwestern.com,thespectrum.com,thestarpress.com,thetimesherald.com,thetowntalk.com,visaliatimesdelta.com,wausaudailyherald.com,wisconsinrapidstribune.com,zanesvilletimesrecorder.com##.articleflex-container
-app.com,argusleader.com,battlecreekenquirer.com,baxterbulletin.com,bucyrustelegraphforum.com,burlingtonfreepress.com,centralohio.com,chillicothegazette.com,cincinnati.com,citizen-times.com,clarionledger.com,coloradoan.com,coshoctontribune.com,courier-journal.com,courierpostonline.com,dailyrecord.com,dailyworld.com,delawareonline.com,delmarvanow.com,democratandchronicle.com,desmoinesregister.com,dnj.com,fdlreporter.com,freep.com,greatfallstribune.com,greenbaypressgazette.com,greenvilleonline.com,guampdn.com,hattiesburgamerican.com,hometownlife.com,honoluluadvertiser.com,htrnews.com,indystar.com,jacksonsun.com,jconline.com,lancastereaglegazette.com,lansingstatejournal.com,livingstondaily.com,lohud.com,mansfieldnewsjournal.com,marionstar.com,marshfieldnewsherald.com,montgomeryadvertiser.com,mycentraljersey.com,mydesert.com,newarkadvocate.com,news-leader.com,news-press.com,newsleader.com,pal-item.com,pnj.com,portclintonnewsherald.com,postcrescent.com,poughkeepsiejournal.com,press-citizen.com,pressconnects.com,rgj.com,sctimes.com,sheboyganpress.com,shreveporttimes.com,stargazette.com,statesmanjournal.com,stevenspointjournal.com,tallahassee.com,tennessean.com,theadvertiser.com,thecalifornian.com,thedailyjournal.com,theithacajournal.com,theleafchronicle.com,thenews-messenger.com,thenewsstar.com,thenorthwestern.com,thespectrum.com,thestarpress.com,thetimesherald.com,thetowntalk.com,visaliatimesdelta.com,wausaudailyherald.com,wisconsinrapidstribune.com,zanesvilletimesrecorder.com##.leaderboard-container
-app.com,argusleader.com,battlecreekenquirer.com,baxterbulletin.com,bucyrustelegraphforum.com,burlingtonfreepress.com,centralohio.com,chillicothegazette.com,cincinnati.com,citizen-times.com,clarionledger.com,coloradoan.com,coshoctontribune.com,courier-journal.com,courierpostonline.com,dailyrecord.com,dailyworld.com,delawareonline.com,delmarvanow.com,democratandchronicle.com,desmoinesregister.com,dnj.com,fdlreporter.com,freep.com,greatfallstribune.com,greenbaypressgazette.com,greenvilleonline.com,guampdn.com,hattiesburgamerican.com,hometownlife.com,honoluluadvertiser.com,htrnews.com,indystar.com,jacksonsun.com,jconline.com,lancastereaglegazette.com,lansingstatejournal.com,livingstondaily.com,lohud.com,mansfieldnewsjournal.com,marionstar.com,marshfieldnewsherald.com,montgomeryadvertiser.com,mycentraljersey.com,mydesert.com,newarkadvocate.com,news-leader.com,news-press.com,newsleader.com,pal-item.com,pnj.com,portclintonnewsherald.com,postcrescent.com,poughkeepsiejournal.com,press-citizen.com,pressconnects.com,rgj.com,sctimes.com,sheboyganpress.com,shreveporttimes.com,stargazette.com,statesmanjournal.com,stevenspointjournal.com,tallahassee.com,tennessean.com,theadvertiser.com,thecalifornian.com,thedailyjournal.com,theithacajournal.com,theleafchronicle.com,thenews-messenger.com,thenewsstar.com,thenorthwestern.com,thespectrum.com,thestarpress.com,thetimesherald.com,thetowntalk.com,visaliatimesdelta.com,wausaudailyherald.com,wisconsinrapidstribune.com,zanesvilletimesrecorder.com##.leaderboard-container-top
-appleinsider.com###aadbox
-appleinsider.com###ldbd
-appleinsider.com##.bottombox
-appleinsider.com##.leaderboard
-appleinsider.com##.main_box4
-appleinsider.com##div[style="border: 1px solid rgb(221, 221, 221); width: 498px; height: 250px; font-size: 14px;"]
-appleinsider.com##div[style="padding: 10px 0pt; width: auto; height: 60px; margin: 0pt 0pt 0pt 348px;"]
-appleinsider.com##img[width="300"][height="250"]
-appleinsider.com##td[width="150"][valign="top"]
-appleinsider.com##td[width="180"][valign="top"]
-aquariumfish.net##table[width="440"][height="330"]
-aquariumfish.net##td[align="center"][width="100%"][height="100"]
-arabianbusiness.com###banner-container
-arabiclookup.com##td[style="width: 156px; border-style: solid; text-align: center;"]
-arabiclookup.com##td[style="width: 157px; border-style: solid; text-align: left;"]
-armorgames.com###leaderboard
-arnnet.com.au###marketplace
-arnnet.com.au##.careerone_search
-arsenal.com###banner
-arstechnica.com###daehtsam-da
-artima.com###floatingbox
-artima.com###topbanner
-arto.com###BannerInfobox
-asia.cnet.com###sp-box
-asia.cnet.com##.splink
-ask.com###rbox
-ask.com##.spl_unshd
-associatedcontent.com##div[style="width: 300px; height: 250px; position: relative;"]
-associatedcontent.com##div[style="width: 300px; height: 250px;"]
-asylum.co.uk##.sidebarBanner
-asylum.com##.sidebarBanner
-asylum.com##.topBanner
-atom.com###iframe_container300x250
-atomicgamer.com###bannerFeatures
-au.movies.yahoo.com##table.y7mv-wraptable[width="750"][height="112"]
-au.yahoo.com###y708-windowshade
-audioreview.com##.MiddleTableRightColumn
-audioreview.com##script + table[width="539"]
-audioreview.com##table[width="300"][style="border: 1px solid rgb(65, 103, 122); margin-left: 10px;"]
-autoblog.com##.leader
-autoblog.com##.medrect
-autoblog.com##.topleader
-autobloggreen.com##.medrect
-autonews.com##div[style="width: 300px; height: 128px; margin-bottom: 5px; border-top: 2px solid rgb(236, 236, 236); border-bottom: 2px solid rgb(236, 236, 236); padding-top: 3px; font-family: arial,helvetica; font-size: 10px; text-align: center;"]
-autonewseurope.com###header_bottom
-autonewseurope.com##div[style="width: 300px; height: 128px; margin-bottom: 5px; border-top: 2px solid rgb(236, 236, 236); border-bottom: 2px solid rgb(236, 236, 236); padding-top: 3px; font-family: arial,helvetica; font-size: 10px; text-align: center;"]
-autos.yahoo.com##.yatysm-y
-autosport.com##.content[width] td[height="17"][bgcolor="#dcdcdc"]
-autosport.com##td[align="center"][valign="top"][height="266"][bgcolor="#dcdcdc"]
-autotrader.co.uk###placeholderTopLeaderboard
-avantfind.com###right
-avantfind.com##div[style="width: 100%; background-color: rgb(236, 245, 250); height: auto; padding-left: 5px; margin-bottom: 15px;"]
-avaxsearch.com###bottom_block
-avaxsearch.com###top_block
-avsforum.com##td[width="125"][valign="top"][style="padding-left: 15px;"]
-avsforum.com##td[width="193"][valign="top"]
-avsforum.com##td[width="300"][valign="top"][rowspan="3"]
-awfulplasticsurgery.com##a[href="http://www.blogads.com"]
-awfulplasticsurgery.com##a[href^="http://www.freeipadoffer.com/default.aspx?r="]
-azarask.in##.ad
-azstarnet.com##.bannerinstory
-babble.com.au###leaderboard-bottom
-babble.com.au###leaderboard-top
-babble.com.au###medium-rectangle
-babelfish.yahoo.com##.ovt
-babynamegenie.com##.promo
-bangkokpost.com##.boomboxSize1
-bangkokpost.com##.buzzBoombox
-basketball.com##td[width="530"] + td[width="120"]
-battellemedia.com##.sidebar
-bbc.co.uk##.bbccom_display_none
-bbc.com###bbccom_leaderboard
-bdnews24.com###bannerdiv2
-bdnews24.com##.add
-bebo.com##.spon-mod
-bebo.com##table[style="background-color: rgb(247, 246, 246);"]
-belfasttelegraph.co.uk###yahooLinks
-belfasttelegraph.co.uk##.googleThird
-belfasttelegraph.co.uk##table[width="300"][height="250"][cellspacing="0"][cellpadding="0"][border="0"]
-bellinghamherald.com###mastBanner
-bestbuy.com###dart-container-728x90
-betterpropaganda.com##div[style="width: 848px; height: 91px; margin: 0pt; position: relative;"]
-bigblueball.com###text-384255551
-bigdownload.com##.quigo
-bigpond.com###header_banner
-bikeradar.com###shopping_partner_box_fat
-bingo-hunter.com##img[width="250"][height="250"]
-birminghampost.net##.promotop
-bit-tech.net##div[style="width: 728px; height: 90px;"]
-biz.yahoo.com##table[bgcolor="white"][width="100%"]
-bizrate.com###banner_top
-bizrate.com###rectangular
-blackberryforums.com##td[align="left"][width="160"][valign="top"]
-blackberryforums.com.au##td[valign="top"][style="width: 175px;"]
-blackmesasource.com##.ad
-block.opendns.com###acbox
-bloggingbuyouts.com##.topleader
-bloggingstocks.com##.topleader
-blogoscoped.com##.adBlock
-blogoscoped.com##.adBlockBottom
-blogoscoped.com##.adBlockBottomBreak
-blogtv.com##div[style="width: 752px; height: 115px; padding-top: 5px; overflow: hidden;"]
-blogtv.com##div[style="width: 752px; top: 5px; height: 100px; text-align: center; padding-top: 5px;"]
-blogtv.com##div[style="width: 990px; height: 115px; padding-top: 5px; overflow: hidden;"]
-blogtv.com##div[style="width: 990px; top: 5px; height: 100px; text-align: center; padding-top: 5px;"]
-bloomberg.com##.leaderboard
-blurtit.com##.adblock
-boardgamegeek.com###tanga
-boardgamegeek.com##tr > td[width="160"][valign="top"][align="center"][style="padding-left: 10px;"]:last-child
-boingboing.net###cheetos_collapsed
-boingboing.net##.ad
-boingboing.net##div[style="height: 630px; width: 300px;"]
-bollywoodbuzz.in##div[style="height: 250px; width: 300px;"]
-bollywoodbuzz.in##div[style="height: 90px; width: 728px;"]
-books.google.ca###rhswrapper font[size="-1"]
-books.google.co.nz###rhswrapper font[size="-1"]
-books.google.co.uk###rhswrapper font[size="-1"]
-books.google.co.za###rhswrapper font[size="-1"]
-books.google.com###rhswrapper font[size="-1"]
-books.google.com.au###rhswrapper font[size="-1"]
-booookmark.com###sitematches
-boston.com###externalBanner
-bostonherald.com##div[style="position: relative; margin-bottom: 16px; background-color: rgb(233, 233, 233); border-left: 16px solid rgb(23, 23, 23); padding: 20px 12px 20px 20px; clear: both;"]
-brandsoftheworld.com###leaderboardTop
-break.com###infospace-sidebar
-break.com##.ad
-break.com##.breaking_news
-breakingviews.com###floatit
-breitbart.com##.sidebar
-briefmobile.com##td[style="height: 90px; width: 960px; background-color: rgb(255, 255, 255); padding: 10px; vertical-align: middle;"]
-brighouseecho.co.uk###banner01
-brisbaneroar.com.au##.promotion_wrapper
-brisbanetimes.com.au##.ad
-broadbandreports.com##td[width="125"][style="border-right: 1px solid rgb(204, 204, 204);"]
-broadcastnewsroom.com###shopperartbox
-broadcastnewsroom.com##.bfua
-broadcastnewsroom.com##.bottombanner
-brothersoft.com##.sponsor
-btjunkie.org###main > div[height="10"]:first-child + table[width="100%"]
-btjunkie.org###main > div[height="10"]:first-child + table[width="100%"] + .tab_results
-btjunkie.org##th[align="left"][height="100%"]
-buenosairesherald.com###publiTopHeader
-buffalonews.com###bot-main
-buffalonews.com##.leaderboard_top
-builderau.com.au###leaderboard
-bunalti.com##img[width="728"][height="90"]
-business.com###railFls
-business.com###sponsoredwellcontainerbottom
-business.com###sponsoredwellcontainertop
-business.com##.wellFls
-businessdailyafrica.com##.c15r
-businessdictionary.com###topBnr
-businessinsider.com###FM1
-businessinsurance.com##.StoryInsert
-businesstimes.com.sg##td[bgcolor="#333333"]
-businessweek.com###bwMall
-businessweek.com##.ad
-buxtonadvertiser.co.uk###banner01
-buzzfocus.com###eyebrowtop
-buzznet.com###topSection
-c21media.net##table[border="0"][width="130"]
-cafemom.com##div[style="background-color: rgb(255, 255, 255); width: 560px; height: 100px; padding: 0px; margin: 0pt 0pt 5px;"]
-caller.com###content_match_wrapper
-caller.com##.bigbox_wrapper
-campustechnology.com###leaderboard
-candystand.com##.cs_square_banner
-candystand.com##.cs_wide_banner
-canmag.com##td[align="center"][height="278"]
-canoe.ca###commerce
-canoe.ca###subbanner
-cantbeunseen.com###top-leaderboard
-cantbeunseen.com##.leaderboard
-caranddriver.com##.shopping-tools
-carrentals.co.uk##div[style="float: right; width: 220px; height: 220px;"]
-carsguide.com.au##.CG_loancalculator
-cataloguecity.co.uk##.bordered
-catholicnewsagency.com##div[style="background-color: rgb(247, 247, 247); width: 256px; height: 250px;"]
-caymannewsservice.com###content-top
-caymannewsservice.com##[style="width: 175px; height: 200px;"]
-caymannewsservice.com##[style="width: 450px; height: 100px;"]
-caymannewsservice.com##[style="width: 550px; height: 100px;"]
-cboe.com###simplemodal-overlay
-cbs5.com##.cbstv_partners_wrap
-cbsnews.com##.searchSponsoredResultsList
-cbssports.com###leaderboardRow
-cbssports.com##table[cellpadding="0"][width="310"]
-ccfcforum.com##.tablepad
-ccfcforum.com##img[alt="ISS"]
-ccmariners.com.au##.promotion_wrapper
-celebnipslipblog.com###HeaderBanner
-celebuzz.com###bmSuperheader
-cell.com###main_banner
-cgenie.com###ja-banner
-cgenie.com##.cgenie_banner4
-chacha.com##.show-me-the-money
-chairmanlol.com###top-leaderboard
-chairmanlol.com##.leaderboard
-chami.com##.c
-channel3000.com###leaderboard-sticky
-checkoutmyink.com###centerbanner
-checkoutmyink.com###mid
-checkthisvid.com##a[href^="http://links.verotel.com/"]
-chicagobreakingbusiness.com##.ad
-chicagotribune.com###story-body-parent + .rail
-chinadaily.com.cn##table[width="130"][height="130"]
-chinapost.com.tw###winner
-chinasmack.com##.ad
-chinatechnews.com###banner1
-christianitytoday.com##.bgbanner
-christianitytoday.com##.bgshop
-chrome-hacks.net##div[style="width: 600px; height: 250px;"]
-chronicle.northcoastnow.com##table[width="100%"][height="90"][bgcolor="#236aa7"]
-cio.com.au##.careerone_search
-cio.com.au##.careerone_tj_box
-citynews.ca###SuperBannerContainer
-citynews.ca##.Box.BigBox
-citypaper.com###topLeaderboard
-citypaper.com##div[style="display: block; width: 980px; height: 120px;"]
-classifieds.aol.co.uk###dmn_results
-classifieds.aol.co.uk###dmn_results1
-clevelandgasprices.com##div[style="height: 250px; width: 301px; margin-bottom: 10px;"]
-clubwebsite.co.uk##td[width="158"][valign="top"] > start_lspl_exclude > end_lspl_exclude > .boxpadbot[width="100%"][cellspacing="0"][cellpadding="6"][border="0"][style="background-color: rgb(0, 51, 0);"]:last-child
-cnbc.com###cnbc300x250
-cnbc.com##.fL[style="width: 185px; height: 40px; margin: 10px 0pt 0pt 25px; float: none;"]
-cnbc.com##.fL[style="width: 365px; margin-bottom: 20px; margin-top: 0px; padding-top: 0px; padding-left: 25px; padding-bottom: 100px; border-top: 1px solid rgb(204, 204, 204); border-left: 1px solid rgb(204, 204, 204);"]
-cnbc.com##.fL[style="width: 960px; height: 90px; margin: 0pt 0pt 5px;"]
-cnet.com##.ad
-cnet.com##.bidwar
-cnet.com.au##.ad
-cnet.com.au##.explain-promo
-cnmnewsnetwork.com###rightcol
-cnn.com##.cnnSearchSponsorBox
-cnsnews.com###ctl00_leaderboard
-cocoia.com###ad
-codeasily.com##.money
-codinghorror.com##.welovecodinghorror
-coffeegeek.com##img[width="200"][height="250"]
-coffeegeek.com##img[width="200"][height="90"]
-coffeegeek.com##td[align="center"][width="100%"][valign="middle"]
-coldfusion.sys-con.com###header-title
-collegehumor.com##.partner_links
-columbiatribune.com##.ad
-columbiatribune.com##.skyscraper
-com.au##table.fdMember
-comcast.net##.ad
-comedy.com###hat
-comicartfans.com###contentcolumn:last-child > center > table[cellspacing="0"][cellpadding="1"][border="0"]:first-child
-comicgenesis.com###ks_da
-comicsalliance.com##.sidebarBanner
-comicsalliance.com##.topBanner
-comingsoon.net###col2TopPub
-comingsoon.net###upperPub
-commercialappeal.com##.bigbox_wrapper
-complex.com##.ad
-complex.com##div[style="float: left; position: relative; margin: 5px auto; width: 960px; height: 90px; border: 0px solid rgb(0, 0, 0); text-align: center;"]
-computeractive.co.uk##.leaderboard
-computerandvideogames.com###skyslot
-computerweekly.com##.sponsors
-computerworld.com###top_leaderboard_wrapper
-computerworld.com##table[align="center"][width="336"][valign="top"]
-computerworld.com##table[width="342"][height="290"][bgcolor="#bbbbbb"]
-computerworlduk.com###bottomBanner
-computerworlduk.com###topBanner
-computing.co.uk##.leaderboard
-computing.net###top_banner
-computingondemand.com###sub-nav
-cookingforengineers.com##div[style="border: 0px solid rgb(255, 255, 160); width: 160px; height: 600px;"]
-cookingforengineers.com##div[style="border: 0px solid rgb(255, 255, 160); width: 728px; height: 90px; margin: 0pt auto;"]
-cookingforengineers.com##div[style="height: 60px; width: 120px; margin: 0pt 20px 5px;"]
-coolest-gadgets.com##.banner1
-coolest-gadgets.com##.contentbox
-coolest-gadgets.com##.contentboxred
-core77.com###rsDesignDir
-countryliving.com###sub_promo
-cpu-world.com##table[width="760"][style="border: 1px solid rgb(64, 64, 64);"]
-cracked.com##.Ad
-crackserver.com##input[onclick^="window.open('http://www.friendlyduck.com/AF_"]
-crazymotion.net###fadeinbox
-crazymotion.net##[style="margin: 10px auto 0pt; width: 875px;"]
-cricbuzz.com###chrome_home_banner
-cricbuzz.com###tata_phton_home_banner
-cricinfo.com##.ciHomeSponcerLink
-cricinfo.com##.hpSpncrHead
-cricinfo.com##.seatwaveM
-cricinfo.com##.seriesSpncr
-cricvid.info###bannerfloat2
-crikey.com.au###top
-crikey.com.au##.crikey_widget_small_island
-crmbuyer.com##.content-block-slinks
-crmbuyer.com##.content-tab-slinks
-crn.com###channelwebmarketplacewrapper
-crooksandliars.com###block-clam-1
-crooksandliars.com###block-clam-3
-crooksandliars.com###block-clam-7
-crunchgear.com##.ad
-crunchyroll.com##.anime-mrec
-crunchyroll.com##a[href^="http://clk.atdmt.com/"]
-cubeecraft.com###leaderboard
-cultofmac.com###leaderboard
-cultofmac.com###skyBlock
-cyberciti.biz###leaderboard
-cynagames.com##li[style="width: 25%; margin: 0pt; clear: none; padding: 0pt; float: left; display: block;"]
-dailyblogtips.com##img[border="0"]
-dailyblogtips.com##img[style="margin-right: 16px;"]
-dailyblogtips.com##img[width="125"][height="125"]
-dailyfinance.com##div[style="background: url(\"http://o.aolcdn.com/art/ch_pf/advertisement-text\") no-repeat scroll 295px 90px rgb(240, 240, 240); padding-top: 20px; margin: 0pt 0pt 10px; height: 84px;"]
-dailyfreegames.com###banner_886x40
-dailyfreegames.com###topratedgames
-dailyhaha.com###sponheader
-dailymail.co.uk##.classified-list
-dailymotion.com##.dmpi_masscast
-dailymotion.com##.dmpi_subheader
-dailymotion.com##.ie_download
-dailymotion.com##.masscast_box_Middle
-dailystar.co.uk###hugebanner
-dailystar.co.uk##.greyPanelOuter
-dailystar.co.uk##.greyPanelOuterSmall
-dailystar.co.uk##div[style="width: 165px; text-align: center; border: 1px solid rgb(184, 184, 184);"]
-dailystar.co.uk##div[style="width: 300px; height: 250px; background: url(\"http://cdn.images.dailystar-uk.co.uk/img/adverts/mpufail.gif\") repeat scroll 0% 0% transparent;"]
-dancingwhilewhite.com##.add
-daniweb.com###textsponsor
-daparto.de###leaderboard
-daringfireball.net###SidebarTheDeck
-darkhorizons.com###content-island
-dataopedia.com##.container_banner
-deadspin.com###skyscraper
-dealbrothers.com##.specials
-dealmac.com###banner-bottom
-dealnews.com##.banner
-deargirlsaboveme.com##.ad
-deditv.com##.overlayVid
-deletedspam.blogspot.com##.LinkList
-deletedspam.blogspot.com##img[width="125"][height="125"]
-delicious.com###spns
-deliciousdays.com###adlove
-deliciousdays.com###book
-deliciousdays.com###recipeshelf
-demogeek.com##div[style="height: 250px; width: 250px; margin: 10px;"]
-demogeek.com##div[style="height: 280px; width: 336px; margin: 10px;"]
-demonoid.com##.pad9px_right
-denofgeek.com##.skyright
-depositfiles.com###adv_banner_sidebar
-derbyshiretimes.co.uk###banner01
-derbyshiretimes.co.uk##.roundedboxesgoogle
-deseretnews.com##.continue
-desiretoinspire.net##div[style="background: url(\"http://www.centralscotlandjoinery.co.uk/images/csj-125.gif\") repeat scroll 0% 0% transparent; width: 125px; height: 125px; font-family: arial,sans-serif; font-size: 9px; color: rgb(0, 0, 0); position: relative;"]
-desiretoinspire.net##div[style="height: 120px; text-align: center; background-color: rgb(105, 145, 72); width: 300px;"]
-desiretoinspire.net##div[style="height: 150px; text-align: center; background-color: rgb(38, 38, 38); width: 150px;"]
-deskbeauty.com##tr > td[width="100%"][height="95"][align="center"]
-destructoid.com##div[style="overflow: hidden; width: 300px; height: 250px;"]
-detnews.com###sponsor-flyout
-develop-online.net##.newsinsert
-deviantart.com###overhead-you-know-what
-deviantart.com##.ad-blocking-makes-fella-confused
-deviantart.com##.hidoframe
-deviantart.com##.sleekadbubble
-deviantart.com##.subbyCloseX
-deviantart.com##a[href^="http://advertising.deviantart.com/"]
-deviantart.com##div[gmi-name="ad_zone"]
-deviantart.com##div[style="float: right; position: relative; width: 410px; text-align: left;"]
-devx.com##.expwhitebox > table[cellspacing="0"][cellpadding="0"][border="0"][align="center"][style="margin-left: 0pt; margin-bottom: 0pt;"]:last-child
-devx.com##.expwhitebox[style="border: 0px none;"] > table[cellspacing="0"][cellpadding="0"][border="0"][align="right"]:first-child
-devx.com##div[align="center"][style="margin-top: 0px; margin-bottom: 0px; width: 100%;"]
-devx.com##div[style="margin: 20px auto auto;"] > div[align="center"][style="margin-top: 0px; margin-bottom: 0px; width: 100%; padding: 10px;"]
-devx.com##div[style="margin: 20px auto auto;"] > table[align="center"][style="border: 2px solid rgb(255, 102, 0); padding-right: 2px; width: 444px; background-color: rgb(255, 255, 255); text-align: left;"]
-devx.com##table[width="164"][cellspacing="0"][cellpadding="0"][border="0"][style="margin-bottom: 5px;"]:first-child:last-child
-dgvid.com##.overlayVid
-dickens-literature.com##td[width="7%"][valign="top"]
-dictionary.co.uk##table[border="0"][width="570"]
-didyouwatchporn.com###bottomBanner
-didyouwatchporn.com###recos_box
-digitalspy.co.uk##.marketing_puff
-digitizor.com##td[style="width: 348px;"]
-dir.yahoo.com##td[width="215"]
-discogs.com###div-gpt-Discogs_Release_Top_728x90
-discountvouchers.co.uk##a[rel="nofollow"]
-discovery.com##.rectangle
-dishusa.net##div[style="border: 1px dotted rgb(190, 190, 190); background-color: rgb(255, 255, 224); padding: 5px;"]
-dishusa.net##table[style="border: 3px outset rgb(87, 173, 198); font-size: 16px; background-color: rgb(253, 252, 240); margin-bottom: 10px;"]
-disney.go.com###banner
-disney.go.com###superBanner
-disney.go.com##div[style="position: relative; float: right; clear: right; width: 300px; height: 260px; top: 5px; margin: 10px 0px 5px 5px;"]
-divxden.com###divxshowboxt > a[target="_blank"] > img[width="158"]
-divxden.com##.ad
-divxden.com##.header_greenbar
-divxme.com##a[href^="http://www.jdoqocy.com/"]
-divxstage.net##.ad
-diyfail.com###top-leaderboard
-diyfail.com##.leaderboard
-dkszone.net##.liutilities-top
-dl4all.com###deluxePopupWindow-container
-dogpile.com##.paidSearchResult
-dosgamesarchive.com###banner
-dosgamesarchive.com##.rectangle
-dosgamesarchive.com##.skyscraper
-dotsauce.com###leadsponsor
-dotsauce.com##.onetwentyfive
-dotsauce.com##img[width="260"][height="260"]
-downforeveryoneorjustme.com###container > .domain + p + br + center:last-child
-downloadhelper.net##.banner-468x60
-downloadhelper.net##a[href^="/liutilities.php"]
-downloadsquad.com###newjobs-module
-downloadsquad.com###topleader-wrap
-downloadsquad.com##.medrect
-dragcave.net###prefooter
-drive.com.au##.cA-twinPromo
-drugs.com###topbannerWrap
-dt-updates.com##.adv_items
-dt-updates.com##div[style="margin: 20px auto 0pt; text-align: left;"]
-dubbed-scene.com##.adblock
-dubcnn.com##img[border="0"][width="200"]
-dumbassdaily.com##a[href$=".clickbank.net"]
-dumbassdaily.com##a[href^="http://www.badjocks.com"]
-dumblittleman.com##.ad
-dumblittleman.com##.cats_box2
-dv.com##table[width="665"]
-eartheasy.com##td[width="200"][height="4451"][bgcolor="#e1e3de"][rowspan="19"]
-earthweb.com##.footerbanner
-easybib.com##.banner
-ebaumsworld.com###eacs-sidebar
-ebuddy.com###Rectangle
-ebuddy.com###banner_rectangle
-eclipse.org##.ad
-ecommerce-journal.com###runnews
-ecommercetimes.com##.slink-text
-ecommercetimes.com##.slink-title
-economist.com###classified_wrapper
-economist.com###footer-classifieds
-economist.com###leaderboard
-economist.com###top_banner
-ecr.co.za###thebug
-ecr.co.za##.block_120x600
-ectnews.com###welcome-box
-ectnews.com##.content-block-slinks
-ectnews.com##.content-tab-slinks
-edge-online.com###above-header-region
-edn.com###headerwildcard
-edn.com##.sponsorcontent
-edn.com##div[style="font-family: verdana,sans-serif; font-style: normal; font-variant: normal; font-weight: normal; font-size: 10px; line-height: normal; font-size-adjust: none; font-stretch: normal; -x-system-font: none; color: rgb(51, 51, 51); background-color: rgb(160, 186, 200); padding-bottom: 7px;"]
-eeeuser.com###header
-efinancialnews.com##.promo-leaderboard
-egreetings.com##td[style="background-color: rgb(255, 255, 255); vertical-align: top;"]
-ehow.com###jsWhoCanHelp
-ehow.com##.takeoverBanner
-el33tonline.com###AdA
-el33tonline.com###AdB
-el33tonline.com###AdC
-el33tonline.com###AdD
-el33tonline.com###AdE
-el33tonline.com###AdF
-el33tonline.com###AdG
-el33tonline.com###AdH
-el33tonline.com###AdI
-electricenergyonline.com###top_pub
-electricenergyonline.com###tower_pub
-electricenergyonline.com##.sponsor
-electronista.com###footerleft
-electronista.com###footerright
-electronista.com###leaderboard
-electronista.com###supportbod
-elizium.nu##center > ul[style="padding: 0pt; width: 100%; margin: 0pt; list-style: none outside none;"]
-elle.com###ad-block-bottom
-emaillargefile.com##a[href^="http://www.mb01.com/lnk.asp?"]
-emedtv.com###leaderboard
-empireonline.com##table[align="center"][width="950"][height="130"]
-empireonline.com##td.smallgrey[width="300"][height="250"]
-engadget.com##.medrect
-engadget.com##.siteswelike
-england.fm###banbo
-englishforum.ch##td[style="width: 160px; padding-left: 15px;"]
-englishforum.ch##td[width="176"][style="padding-left: 15px;"]
-environmentalgraffiti.com##div[style="width: 300px; height: 250px; overflow: hidden;"]
-eonline.com###franchise
-eonline.com###module_sky_scraper
-epicurious.com###sweepstakes
-epinions.com##td[width="180"][valign="top"]
-eq2flames.com##td[width="120"][style="padding-left: 5px; white-space: normal;"]
-erictric.com###banner300-top-right
-erictric.com###head-banner468
-esecurityplanet.com###gemhover
-esecurityplanet.com###partners
-esecurityplanet.com##.vspace
-esl.eu##.bannerContainer
-esoft.web.id###content-top
-espn.go.com##.mast-container
-espn.go.com##.spons_optIn
-esus.com##a[href="http://www.regiochat.be"]
-etonline.com##.superbanner
-eurogamer.net###skyscraper
-eurogamer.net###tabbaz
-euronews.net###OAS1
-euronews.net###OAS2
-euronews.net##.col-pub-skyscraper
-euronews.net##.google-banner
-europolitics.info##.publicite1
-everyjoe.com##.ad
-eweek.com###Table_01
-eweek.com###hp_special_reports
-eweek.com###syndication
-eweek.com##.hp_link_online_classifieds
-eweek.com##.omniture_module_tracker
-eweek.com##table[width="500"][style="border: 1px solid rgb(204, 204, 204); margin: 5px 10px 5px 20px;"]
-exactseek.com###featured
-exactseek.com##.recommended
-examiner.co.uk##.promotop
-examiner.com##.headerbg
-excelforum.com##.contentLeft
-excelforum.com##div[style="width: 300px; height: 250px; float: left; display: inline; margin-left: 5%;"]
-excelforum.com##div[style="width: 300px; height: 250px; float: right; display: inline; margin-left: 5%;"]
-excite.com##.mexContentBdr
-expedia.com##.wpInner
-expertreviews.co.uk###skin
-expertreviews.co.uk###skyScrapper
-expertreviews.co.uk##.leaderBoard
-expertreviews.co.uk##.leaderLeft
-expertreviews.co.uk##.leaderRight
-experts-exchange.com###compCorpAcc
-experts-exchange.com###compSky
-experts-exchange.com##.ontopBanner
-explainthisimage.com###top-leaderboard
-explainthisimage.com##.leaderboard
-explosm.net##td[height="90"][bgcolor="#000000"][style="border: 3px solid rgb(55, 62, 70);"]
-extremeoverclocking.com##td[height="104"][colspan="2"]
-facebook.com###home_sponsor_nile
-facebook.com##.ego_spo
-facebook.com##.fbEmu
-factoidz.com##div[style="float: left; margin: 0pt 30px 20px 0pt; width: 336px; height: 280px;"]
-fairyshare.com##.google_top
-famousbloggers.net###hot_offer
-famousbloggers.net##.stop_sign
-fanhouse.com##.ad
-fanpix.net###leaderboard
-fanpop.com###rgad
-fanpop.com##div[style="width: 300px; height: 250px; background-color: rgb(0, 0, 0); color: rgb(153, 153, 153);"]
-fansfc.com###worldcupspl_container_left
-fark.com###rightSideRightMenubar
-fasterlouder.com.au##.ad
-faststats.cricbuzz.com##td[style="width: 300px; height: 250px;"]
-fatwallet.com###promoBand
-favicon.co.uk##img[width="190"][height="380"]
-faxo.com###fa_l
-fayobserver.com###bottom-leaderboard
-feedburner.com##a[href^="http://ads.pheedo.com/"]
-feedicons.com###footerboard
-feministing.com###bannerBottom
-feministing.com###bannerLeft
-feministing.com###bannerTop
-ffiles.com###right_col
-file-extensions.org###uniBan
-filedropper.com###sidebar
-filefactory.com###aContainer
-filefront.com##div[style="width: 300px; min-height: 250px;"]
-filehippo.com##.ad
-filestube.com##.nova
-filetrip.net###products
-finalgear.com##.googlebanwide
-finance.yahoo.com###yfi_pf_ysm
-finance.yahoo.com###yfi_ysm
-finance.yahoo.com##.ad
-finance.yahoo.com##.ysm
-financialpost.com###npLeaderboardRow
-findfiles.com##.tvisible[width="468"][cellspacing="0"][cellpadding="0"][bgcolor="#ffffff"][align="center"]
-firewallguide.com##td[width="300"][height="250"]
-flashgot.net##.tla
-flashscore.com##div[style="height: 240px ! important;"]
-flashscore.com##div[style="height: 90px ! important;"]
-flixster.com##div[style="position: relative; height: 270px;"]
-flvz.com###additional_plugins_bar
-flvz.com##a[href^="http://www.flvpro.com/movies/?aff="]
-fontstock.net##.mediaBox
-foodnetwork.ca##.bannerContainer
-foodnetwork.ca##.bboxContainer
-foodnetwork.co.uk###pre-header-banner
-foodnetwork.co.uk##.right_header_row
-foodnetwork.com##.mrec
-fool.com###promoAndLeaderboard
-footylatest.com###leaderboardspace
-forbes.com##.fifthN
-forbes.com##.top_banner
-forbes.com##div[style="width: 125px; height: 125px; padding: 20px 20px 20px 25px; float: left;"]
-forbes.com##div[style="width: 125px; height: 125px; padding: 20px 25px 20px 20px; float: right;"]
-forrst.com##.ad
-forum.notebookreview.com##td[width="400"][height="280"]
-forum.rpg.net##img[border="0"][style="outline: medium none;"]
-forums.battle.net##td[align="center"][width="130"]
-forums.scifi.com###flippingBanner
-forums.vr-zone.com##.perm_announcement
-forums.worldofwarcraft.com##td[align="center"][width="130"]
-forums.worldofwarcraft.com##td[width="130px"][valign="top"][align="center"]:last-child
-forums.wow-europe.com##td[align="center"][width="130"]
-forums.wow-europe.com##td[width="130px"][valign="top"][align="center"]:last-child
-forumserver.twoplustwo.com##td[width="120"][valign="top"][style="padding-left: 10px;"]
-fox.com##.ad
-foxbusiness.com###cb_medrect1_div
-foxnews.com###console300x100
-foxnews.com###marketplace
-foxnews.com##.ad
-foxnews.com##.quigo
-fpsbanana.com##a[href^="http://www.xfactorservers.com/clients/link.php?id="]
-free-tv-video-online.info##a[style="margin-left: auto; font-size: 14px; padding: 3px; margin-right: auto; width: 640px; display: block; text-decoration: none;"]
-freecodesource.com###banner
-freedict.com##.partners
-freeiconsdownload.com###LeftBanner
-freestreamtube.com###ad
-freshmeat.net##.banner-imu
-freshmeat.net##.banner1
-friday-ad.co.uk##.PlateFood
-ft.com###leaderboard
-ft.com##.marketing
-ftv.com###hdr_c
-ftv.com###hdr_r
-fudzilla.com###showcase
-fudzilla.com##.artbannersxtd
-funnyexam.com###top-leaderboard
-funnyexam.com##.leaderboard
-funnyordie.com###header_takeover
-funnytipjars.com###top-leaderboard
-funnytipjars.com##.leaderboard
-fxnetworks.com###adBlock
-gadgetzone.com.au###Leaderboard-placeholder
-gadgetzone.com.au##td[style="width: 300px;"]
-gadling.com##.medrect
-gadling.com##.topleader
-gamebanshee.com##.banner
-gamegrep.com##.leaderboard_unit
-gamepro.com.au##.rhs_300x250
-gamerevolution.com##td[height="100"][style="padding-left: 5px; padding-top: 5px; padding-right: 5px;"]
-gamernode.com##.ad
-gamerstemple.com###banner
-gamerstemple.com###tower1
-gamerstemple.com###tower2
-gamersyde.com##.placeholder-top
-games.com##.ad
-gamesindustry.biz###leader
-gamesindustry.biz###leader-container
-gamesradar.com##.tablets
-gawker.com###skySpacer
-gawker.com###skyscraper
-gbrej.com###bottom_banner
-gearlive.com###google
-gearlive.com##.wellvert
-geek.com##.leaderboard
-geek.com##.picksBox
-geek.com##a[href^="http://www.geek.com/partners?"]
-geek.com##td[width="170"]
-geekologie.com###leaderboard
-generation-nt.com##.innerpub125
-generation-nt.com##.innerpub250
-generation-nt.com##.pub125
-generation-nt.com##.pub2
-generation-nt.com##.pub3
-genesisowners.com##.tborder[width="160"]
-genuineforextrading.com###clickbank
-get-ip.de##div[style="display: block; background: none repeat scroll 0% 0% rgb(238, 238, 238); width: 300px; height: 250px; margin-top: 10px;"]
-get-ip.de##div[style="display: block; background: none repeat scroll 0% 0% rgb(238, 238, 238); width: 300px; height: 250px;"]
-getfoxyproxy.org###ad
-gethuman.com##td[style="width: 200px;"]
-getprice.com.au##li[style="clear: both; padding-left: 0pt; padding-bottom: 0pt; width: 580px;"]
-ghacks.net##.gutterlink
-gigabyteupload.com##input[onclick^="window.location.href='http://www.affbuzzads.com/affiliate/"]
-gigasize.com##.topbanner
-gigwise.com###skyscraper
-giveawayoftheday.com##.before_hot_tags
-givesmehope.com###droitetop
-gizmocrunch.com##div[style="background-color: rgb(235, 242, 247); width: 560px;"]
-gizmodo.com###marquee-frame
-gizmodo.com###skySpacer
-gizmodo.com###skyscraper
-gizmodo.com###spacer160
-gmanews.tv##div[style="width: 250px; height: 280px; border-top: 1px solid rgb(204, 204, 204);"]
-goal.com###marketplaceModule
-goal.com##.betting200x120
-goal.com##.betting364x80
-goauto.com.au###leftnavcontainer + table[width="130"]
-gocurrency.com###gosense
-goldcoastunited.com.au##.promotion_wrapper
-golivewire.com##div[style="height: 292px; margin-left: 10px; background-image: url(http://img.golivewire.com/stickynote-gray.gif); background-repeat: no-repeat; background-position: 0px 3px; padding-left: 26px; padding-top: 26px;"]
-good.is##.ad
-goodhopefm.co.za##.mrec
-goodhousekeeping.com###hpV2_728x90
-google.co.uk##.ts[style="margin: 0pt 0pt 12px; height: 92px;"]
-google.com##.ts[style="margin: 0pt 0pt 12px; height: 92px;"]
-google.com.au##.ts[style="margin: 0pt 0pt 12px; height: 92px;"]
-googletutor.com##div[style="width: 125px; text-align: center;"]
-googlewatch.eweek.com###topBanner
-governmentvideo.com##table[width="665"]
-gpsreview.net###lead
-grapevine.is##.ad
-grapevine.is##div[style="padding: 12px 0pt; text-align: center;"]
-grindtv.com###LREC
-grindtv.com###SKY
-grindtv.com###hLREC
-growingbusiness.co.uk##.siteLeaderBoard
-gtplanet.net###a2
-gtplanet.net###a3
-guardian.co.uk###commercial-partners
-guardian.co.uk##.kelkoo
-guitaretab.com##.ring_link
-guru3d.com##a[href^="http://driveragent.com/?ref="]
-guruji.com###SideBar
-guruji.com##div[style="border: 1px solid rgb(250, 239, 209); margin: 0px 4px; padding: 4px; background-color: rgb(255, 248, 221);"]
-h-online.com##.bcadv
-haaretz.com##.affiliates
-haaretz.com##.buttonBanners
-halifaxcourier.co.uk###banner01
-hardocp.com##.ad
-harpers.org##.topbanner
-hdtvtest.co.uk##.deal
-healthboards.com##td[\!valign="top"]
-healthboards.com##td[align="left"][width="300"]:first-child
-hebdenbridgetimes.co.uk###banner01
-helenair.com##table.bordered[align="center"][width="728"]
-hellmode.com###header
-hellomagazine.com###publi
-help.com###bwp
-helpwithwindows.com###ad
-helpwithwindows.com###desc
-heraldscotland.com###leaderboard
-heraldsun.com.au##.multi-promo
-hi5.com###hi5-common-header-banner
-hi5.com##.hi5-common-header-banner-ad
-highdefdigest.com##table[width="300"][cellspacing="0"][cellpadding="0"]
-hilarious-pictures.com###block-block-1
-hilarious-pictures.com###block-block-12
-hilarious-pictures.com###block-block-8
-hilarious-pictures.com##.horizontal
-hindustantimes.com##.story_lft_wid
-hitfix.com##.googlewide
-hollywood-elsewhere.com##.ad
-hollywoodreporter.com##.ad
-holyfragger.com##.ad
-hotfrog.com##.search-middle-adblock
-hotfroguk.co.uk##.search-middle-adblock
-hotjobs.yahoo.com###sponsorResults
-hotlinkfiles.com###leaderboard
-hotshare.net##.publi_videos1
-howstuffworks.com###MedRectHome
-howstuffworks.com###SponLogo
-howstuffworks.com##.adv
-howstuffworks.com##.ch
-howstuffworks.com##.search-span
-howstuffworks.com##td[width="980"][height="90"]
-howtoforge.com##div[style="margin-top: 10px; font-size: 11px;"]
-howtogeek.com##body > div[style="height: 90px;"]:first-child
-howtogeek.com##div[style="padding-top: 20px; margin-top: 10px; margin-bottom: 10px; min-height: 115px; text-align: center; width: 750px; margin-left: 113px;"]
-howtogeek.com##div[style="padding-top: 20px; margin-top: 210px; margin-bottom: 10px; min-height: 115px; text-align: center; width: 750px; margin-left: -15px;"]
-hplusmagazine.com###bottom
-huffingtonpost.com##.contin_below
-hulkshare.com##div[style="width: 312px; height: 262px; background-color: rgb(255, 240, 225); border: 1px solid rgb(0, 0, 0);"]
-hulkshare.com##div[style="width: 312px; height: 262px; text-align: center; background-color: rgb(255, 240, 225); border: 1px solid rgb(0, 0, 0);"]
-hulkshare.com##div[style="width: 730px; height: 90px; background-color: rgb(255, 240, 225); border: 1px solid rgb(0, 0, 0);"]
-hulkshare.com##div[style="width: 740px; height: 102px; background-color: rgb(255, 240, 225); border: 1px solid rgb(0, 0, 0); padding-top: 5px;"]
-humanevents.com###skyscraperbox
-hvac-talk.com##td[align="center"][valign="top"][style="padding-left: 10px;"]
-i-comers.com###headerfix
-i-programmer.info###iProgrammerAmazoncolum
-i-programmer.info##.bannergroup
-i4u.com###topBanner > div#right
-iafrica.com###c_row1_bannerHolder
-iafrica.com##.article_Banner
-iamdisappoint.com###top-leaderboard
-iamdisappoint.com##.leaderboard
-iberia.com##.bannerGiraffe
-ibtimes.com###DHTMLSuite_modalBox_contentDiv
-ibtimes.com##.modalDialog_contentDiv_shadow
-ibtimes.com##.modalDialog_transparentDivs
-icelandreview.com###ImgArea2
-icenews.is###topbanner
-idg.com.au###skin_bump
-idg.com.au###top_adblock_fix
-ign.com###boards_medrec_relative
-illimitux.net###screens
-illimitux.net##.pub_bot
-illimitux.net##.pub_top
-iloubnan.info###bann
-iloveim.com###closeAdsDiv
-imagebanana.com##.ad
-images.search.yahoo.com###r-n
-imageshack.us###add_frame
-imdb.com###top_rhs_1_wrapper
-imdb.com###top_rhs_wrapper
-imtranslator.net##td[align="right"][valign="bottom"][height="96"]
-inbox.com###r
-inbox.com##.slinks
-indeed.co.uk##.sjl
-independent.co.uk###article > .box
-independent.co.uk###bottom_link
-independent.co.uk###yahooLinks
-independent.co.uk##.commercialpromo
-independent.co.uk##.googleCols
-independent.co.uk##.homepagePartnerList
-independent.co.uk##.spotlight
-indianexpress.com###shopping_deals
-indiatimes.com###jobsbox
-indiatimes.com##.hover2bg
-indiatimes.com##.tpgrynw > .topbrnw:first-child + div
-indiatimes.com##td[valign="top"][height="110"][align="center"]
-indiewire.com###promo_book
-indyposted.com##.ad
-indystar.com##.ad
-info.co.uk##.p
-info.co.uk##.spon
-infoplease.com###gob
-infoplease.com###ssky
-infoplease.com##.tutIP-infoarea
-informationmadness.com###ja-topsl
-informationweek.com###buylink
-informationweek.com##.ad
-informit.com###leaderboard
-infoworld.com##.recRes_head
-inquirer.net###bottom_container
-inquirer.net###leaderboard_frame
-inquirer.net###marketplace_vertical_container
-inquirer.net##.bgadgray10px
-inquirer.net##.fontgraysmall
-inquirer.net##.padtopbot5
-inquirer.net##table[width="780"][height="90"]
-inquisitr.com###topx2
-insanelymac.com##.ad
-instapaper.com###deckpromo
-intelligencer.ca###banZone
-intelligencer.ca##.bnr
-interfacelift.com##.ad
-internet.com###contentmarketplace
-internet.com###mbEnd
-internet.com##.ch
-internetevolution.com##div[style="border: 2px solid rgb(230, 230, 230); margin-top: 30px;"]
-investopedia.com###leader
-investopedia.com##.mainbodyleftcolumntrade
-investopedia.com##div[style="float: left; width: 250px; height: 250px; margin-right: 5px;"]
-io9.com###marquee
-io9.com###marquee-frame
-io9.com###skyscraper
-io9.com##.highlite
-iol.co.za###sp_links
-iol.co.za###weatherbox-bottom
-iol.co.za##.lead_sp_links
-iol.co.za##table[width="120"]
-iomtoday.co.im###banner01
-iphpbb3.com##table[width="728"][height="90"]
-ipmart-forum.com###table1
-irishcentral.com###banner
-irishtimes.com###banner-area
-israelnationalnews.com##.leftColumn
-istockanalyst.com##.rr
-itnews.com.au##div[style="width: 300px; height: 250px;"]
-itnews.com.au##div[style="width: 728px; height: 90px; margin-left: auto; margin-right: auto; padding-bottom: 20px;"]
-itnewsonline.com##table[width="300"][height="250"]
-itnewsonline.com##td[width="120"]
-itp.net##.top_bit
-itpro.co.uk###skyScraper
-itproportal.com###hp-accordion
-itproportal.com##.se_left
-itproportal.com##.se_right
-itproportal.com##.teaser
-itreviews.co.uk###bmmBox
-itweb.co.za###cosponsor
-itweb.co.za###cosponsor-logo
-itweb.co.za###cosponsorTab
-itweb.co.za###highlight-on
-itweb.co.za###sponsor
-itweb.co.za###sponsor-logo
-itweb.co.za###top-banner
-itweb.co.za##.hidden
-itweb.co.za##div[style="width: 300px; height: 266px; overflow: hidden; margin: 0pt;"]
-itworld.com###more_resources
-itworld.com###partner_strip
-iwebtool.com##table[cellspacing="0"][cellpadding="0"][border="1"]
-ixquick.com##td[bgcolor="#f7f9ff"]
-jacarandafm.com###thebug
-jacarandafm.com##.block_120x600
-jakeludington.com###ablock
-jalopnik.com###skyscraper
-jame-world.com###adv_top
-jame-world.com##.adv_right
-jamendo.com###ad
-jamendo.com##.col_extra
-japanator.com##.gutters
-japanator.com##div[style="background-color: rgb(176, 176, 176); width: 320px; height: 260px; padding: 20px 10px 10px;"]
-japanisweird.com###top-leaderboard
-japanisweird.com##.leaderboard
-japannewsreview.com##div[style="width: 955px; height: 90px; margin-bottom: 10px;"]
-japantimes.co.jp###FooterAdBlock
-japantimes.co.jp###HeaderAdsBlockFront
-japantimes.co.jp##.RealEstateAdBlock
-japantimes.co.jp##.SmallBanner
-japantimes.co.jp##.UniversitySearchAdBlock
-japantimes.co.jp##table[height="250"][width="250"]
-japanvisitor.com###sponsor
-jarrowandhebburngazette.com###banner01
-javalobby.org###topLeaderboard
-jayisgames.com##.bfg-feature
-jdownloader.org##a[href^="http://fileserve.com/signup.php?reff="]
-jekoo.com##.boxItem
-jekoo.com##.textCollSpons
-jeuxvideo-flash.com###pub_header
-jewtube.com###adv
-jewtube.com##div[style="display: block; width: 468px; height: 60px; padding: 5px; border: 1px solid rgb(221, 221, 221); text-align: left;"]
-jezebel.com###skyscraper
-joe.ie###topbanner
-johnbridge.com###header_right_cell
-johnbridge.com##td[valign="top"] > table.tborder[width="140"][cellspacing="1"][cellpadding="6"][border="0"]
-joomla.org##div[style="margin: 0pt auto; width: 728px; height: 100px;"]
-joox.net###body-sidebar
-joox.net##img[alt="Download FLV Direct"]
-joystickdivision.com###Page_Header
-joystiq.com###medrect
-joystiq.com###medrectrb
-joystiq.com###topleader-wrap
-joystiq.com##.medrect
-jpost.com###topBanner
-jpost.com##.jp-grid-oppsidepane
-jpost.com##.padtopblubar
-jpost.com##[id="ads.gbox.1"]
-jumptags.com##div[style="background: none repeat scroll 0% 0% rgb(255, 255, 255); padding: 5px; border-bottom: 1px solid rgb(170, 170, 170); height: 95px;"]
-justhungry.com##a[href^="http://affiliates.jlist.com/"]
-justin.tv###iphone_banner
-kaldata.net###header2
-katu.com###mrktplace_tabbed
-katu.com##.callout
-katz.cd###spon
-katzforums.com###aff
-kayak.co.in##[height="330"][width="270"][bgcolor="#fff8dd"]
-kayak.co.uk##[height="330"][width="270"][bgcolor="#fff8dd"]
-kayak.com##[height="330"][width="270"][bgcolor="#fff8dd"]
-keepvid.com##.sponsors
-keepvid.com##.sponsors-s
-kewlshare.com###rollAdRKLA
-kibagames.com##.adv_default_box_container
-kibagames.com##.category_adv_container
-kibagames.com##.dc_color_lightgreen.dc_bg_for_adv
-kibagames.com##.search_adv_container
-kibagames.com##.start_overview_adv_container
-kibagames.com##div[style="border: 0px solid rgb(0, 0, 0); width: 160px; height: 600px;"]
-kibagames.com##div[style="margin-bottom: 10px; border: 1px solid rgb(0, 0, 0); height: 90px;"]
-kids-in-mind.com##td[valign="top"][style="padding-left: 5px; padding-right: 5px;"]
-kidsinmind.com##td[valign="top"][style="padding-left: 5px; padding-right: 5px;"]
-kidzworld.com##div[style="width: 160px; height: 617px; margin: auto;"]
-kidzworld.com##div[style="width: 300px; height: 117px; margin: auto;"]
-kidzworld.com##div[style="width: 300px; height: 267px; margin: auto;"]
-king-mag.com###banner_468
-king-mag.com###leaderboard
-king-mag.com###mediumrec
-king-mag.com###skyscraper
-kino.to###LeftFull
-kino.to###RightFull
-kino.to##.Special
-kioskea.net###topContent
-kissfm961.com##div[style="padding-top: 10px; padding-left: 10px; height: 250px;"]
-kizna-blog.com##a[href$=".clickbank.net"]
-knowfree.net###mta_bar
-knowfree.net##.web_link
-knowfree.net##a[href^="http://kvors.com/click/"]
-knowyourmeme.com##.a160x600
-knowyourmeme.com##.a250x250
-knowyourmeme.com##.a300x250
-knowyourmeme.com##.a728x90
-knoxnews.com###leaderboard
-knoxnews.com##.big_box
-kohit.net##.banner_468
-kohit.net##.top_banner
-kohit.net##div[style="width: 300px; height: 250px; background-color: rgb(0, 0, 0);"]
-kotaku.com###skySpacer
-kotaku.com###skyscraper
-kovideo.net##.h-728
-kovideo.net##.right-def-160
-kovideo.net##.search-728
-krapps.com###header
-krapps.com##a[href^="index.php?adclick="]
-krebsonsecurity.com###sidebar-b
-krebsonsecurity.com###sidebar-box
-krillion.com###sponCol
-ksl.com##div[style="float: left; width: 300px; margin: 5px 0px 13px;"]
-ksl.com##table[style="width: 635px; padding: 0pt; margin: 0pt; background-color: rgb(230, 239, 255);"]
-kstp.com###siteHeaderLeaderboard
-ktvu.com###leaderboard-sticky
-kuklaskorner.com###ultimate
-kval.com###mrktplace_tabbed
-kval.com##.callout
-langmaker.com##table[width="120"]
-lastminute.com###sponsoredFeature
-latimes.com###article-promo
-law.com###leaderboard
-layoutstreet.com##.ad
-lbc.co.uk###topbanner
-learninginfo.org##table[align="left"][width="346"]
-lemondrop.com##.sidebarBanner
-lemondrop.com##.topBanner
-licensing.biz##.newsinsert
-life.com##.ad
-lifehack.org##.offer
-lifehacker.com###skySpacer
-lifehacker.com###skyscraper
-lifespy.com##.SRR
-lightreading.com##div[align="center"][style="height: 114px;"]
-linksave.in###wrap > #menue + #menuelinks
-linksave.in###wrap > #menue:first-child
-linksave.in##.text[align="center"] > table[width="513"][cellspacing="0"][cellpadding="0"][border="0"]:last-child
-linksave.in##a[href^="http://linksave.in/go/unnl/"]
-linksave.in##a[href^="http://linksave.in/go/usene/"]
-linksave.in##a[href^="http://www.endwelt.com/signups/add/"]
-linksave.in##a[href^="http://www.gamesaffiliate.de/"]
-linksave.in##a[href^="http://www.uws-board.com"]
-linux-mag.com##.sponsor-widget
-linuxforums.org###rightColumn
-linuxforums.org##div[style="margin: 2px; float: right; width: 300px; height: 250px;"]
-linuxinsider.com###welcome-box
-linuxinsider.com##.content-block-slinks
-linuxinsider.com##.content-tab-slinks
-linuxquestions.org##div[style="margin: -3px -3px 5px 5px; float: right;"]
-linuxtopia.org###bookcover_sky
-lionsdenu.com###banner300-top-right
-lionsdenu.com###sidebar-bottom-left
-lionsdenu.com###sidebar-bottom-right
-live365.com##.ad
-livejournal.com##.ljad
-liverpooldailypost.co.uk##.promotop
-livestream.com##.ad
-livevss.net###ad
-livevss.tv###floatLayer1
-living.aol.co.uk##.wide.horizontal_promo_HPHT
-lmgtfy.com###sponsor
-lmgtfy.com###sponsor_wrapper
-load.to##.download_right
-loaded.it###apDiv1
-loaded.it###bottomcorner
-loaded.it###ppad1
-loaded.it##img[style="border: 0px none; width: 750px;"]
-local.co.uk###borderTab
-local.yahoo.com##.yls-rs-paid
-londonstockexchange.com##.banner
-londonstockexchange.com##.bannerTop
-loombo.com##.ad
-lotro-lore.com###banner
-lowbird.com##.teaser
-lowyat.net##img[border="1"]
-lowyat.net##tr[style="cursor: pointer;"]
-luxist.com###topleader-wrap
-luxist.com##.medrect
-lyrics007.com##td[bgcolor="#ffcc00"][width="770"][height="110"]
-lyricsfreak.com###ticketcity
-lyricsfreak.com##.ad
-lyricsfreak.com##.ringtone
-lyricsmode.com##div[style="text-align: center; margin-top: 15px; height: 90px;"]
-lyricwiki.org###p-navigation + .portlet
-lyrster.com##.el_results
-m-w.com###google_creative_3
-m-w.com###skyscraper_creative_2
-maannews.net##td[style="border: 1px solid rgb(204, 204, 204); width: 250px; height: 120px;"]
-maannews.net##td[style="border: 1px solid rgb(204, 204, 204); width: 640px; height: 80px;"]
-macdailynews.com###right
-macintouch.com###yellows
-macintouch.com##img[width="125"][height="125"]
-macintouch.com##img[width="468"]
-macleans.ca###leaderboard
-maclife.com###top-banner
-macnewsworld.com##.content-block-slinks
-macnewsworld.com##.content-tab-slinks
-macnn.com###leaderboard
-macnn.com###supportbod
-macobserver.com##.dealsontheweb
-macobserver.com##.specials
-macosxhints.com##div[style="border-bottom: 2px solid rgb(123, 123, 123); padding-bottom: 8px; margin-bottom: 5px;"]
-macrumors.com###googleblock300
-macrumors.com###mr_banner_topad
-macstories.net###ad
-macsurfer.com##.text_top_box
-macsurfer.com##table[width="300"][height="250"]
-macthemes2.net###imagelinks
-macupdate.com###promoSidebar
-macupdate.com##div[style="width: 728px; height: 90px; margin: 0px auto; display: block;"]
-macworld.co.uk###footer
-macworld.co.uk###topBannerSpot
-macworld.com###shopping
-madeformums.com###contentbanner
-magic.co.uk###headerRowOne
-magme.com###top_banner
-mahalo.com##div[id^="ads-section-"]
-mail.google.com##.u5
-mail.live.com###SkyscraperContent
-mail.yahoo.com###MNW
-mail.yahoo.com###MON > div[style="color: rgb(0, 0, 0); font-size: 10px; font-family: Verdana,arial,sans-serif; text-align: center;"]
-mail.yahoo.com###SKY
-mail.yahoo.com###northbanner
-mail.yahoo.com###nwPane
-mail.yahoo.com###slot_LREC
-majorgeeks.com##.Outlines
-majorgeeks.com##a[href^="http://www.pctools.com/registry-mechanic/?ref="]
-majorgeeks.com##a[href^="https://secure.avangate.com/affiliate.php"]
-majorgeeks.com##a[target="1"]
-majorgeeks.com##a[target="top"]
-majorgeeks.com##table[align="right"][width="336"][style="padding-left: 5px;"]
-maketecheasier.com##a[href="http://maketecheasier.com/advertise"]
-makeuseof.com##a[href="http://www.makeuseof.com/advertise/"]
-makeuseof.com##div[style="margin-bottom: 15px; margin-top: 15px; padding: 5px; border: 1px solid rgb(198, 215, 225); background-color: rgb(216, 234, 242);"]
-makezine.com##.ad
-malaysiastory.com##.box2
-maltonmercury.co.uk###banner01
-mangafox.com##a[href^="http://fs.game321.com/"]
-map24.com###cont_m24up
-mapquest.com###offers
-marketingmag.ca###leaderboard_container
-marketingpilgrim.com###ad
-mashable.com##.header-banner
-massively.com###topleader-wrap
-mcvuk.com###leaderboard
-mcvuk.com##.newsinsert
-mediabistro.com##.right-column-boxes-content-partners
-mediacoderhq.com##.gg1
-mediafire.com###catfish_div
-mediafire.com##.download_banner_container
-mediafire.com##.ninesixty_container:last-child td[align="right"][valign="top"]:first-child
-mediafiresearch.net##a[href^="http://mediafiresearch.net/adv1.php"]
-mediaite.com###magnify_widget_rect_handle
-mediaite.com###supertop
-medicineandtechnology.com##div[style="width: 728px; height: 90px; position: relative; margin: 0pt; padding: 0pt; text-align: left;"]
-megafileupload.com##.banner300
-megafileupload.com##.big_banner
-megauploadsearch.net##a[href^="http://megauploadsearch.net/adv.php"]
-megavideo.com##div[style="position: relative; width: 355px; height: 299px; margin-top: 2px;"]
-megavideo.com##div[style="position: relative; width: 359px; height: 420px; margin-left: -3px; margin-top: 1px;"]
-melbourneheartfc.com.au##.promotion_wrapper
-melbournevictory.com.au##.promotion_wrapper
-mercurynews.com###mn_SP_Links
-merriam-webster.com###Dictionary-MW_DICT_728_BOT
-merriam-webster.com###google_creative_3
-metacafe.com###Billboard
-metadivx.com##.ad
-metblogs.com###a_medrect
-metblogs.com###a_widesky
-metro.co.uk##.google-sky
-metro.co.uk##.sky
-metro.us##div[style="width: 300px; height: 250px; float: right;"]
-metrolyrics.com###cee_box
-metrolyrics.com###cee_overlay
-metrolyrics.com###ipod
-metromix.com###leaderboard
-mg.co.za###masthead > table[style="padding-right: 5px;"]:first-child
-mg.co.za###miway-creative
-mg.co.za##.articlecontinues
-mg.co.za##div[style="width: 300px; height: 250px;"]
-mg.co.za##table[border="0"][width="300"]
-miamiherald.com###leaderboard
-michigangasprices.com##div[style="height: 250px; width: 301px; margin-bottom: 10px;"]
-microsoft-watch.com###topBannerContainer
-miloyski.com##a.button[target="_blank"]
-mindspark.com##.desc
-miniclip.com##.block_300x250
-miniclip.com##.letterbox
-minnpost.com##.topleader
-missoulian.com###yahoo-contentmatch
-mlfat4arab.com##img[width="234"][height="60"]
-mmosite.com##.c_gg
-mmosite.com##.mmo_gg
-mmosite.com##.mmo_gg2
-mmosite.com##.mmo_textsponsor
-mobile-ent.biz##.newsinsert
-mobilecrunch.com##.ad
-mobilemoviezone.com##a[href^="http://adsalvo.com/"]
-mobilemoviezone.com##a[href^="http://clk.mobgold.com/"]
-mobilust.net##a[href^="http://nicevid.net/?af="]
-modernhealthcare.com##.mh_topshade_b
-mofunzone.com###ldrbrd_td
-money.co.uk###topBar
-morefailat11.com###top-leaderboard
-morefailat11.com##.leaderboard
-morningstar.com##.LeaderWrap
-morningstar.com##.aadsection_b1
-morningstar.com##.aadsection_b2
-mortgageguide101.com###ppc
-mosnews.com##.right_pop
-motherboard.tv##.banner
-motherboard.tv##.moreFromVice
-motherjones.com##.post-continues
-motherproof.com###leader
-motionempire.com##div[style="width: 728px; margin-top: 3px; margin-bottom: 3px; height: 90px; overflow: hidden; margin-left: 113px;"]
-motorcycle-usa.com##.bannergoogle
-movie2k.com###ball
-movie2k.com##.s2k_ad
-movie2k.com##a[href^="http://www.affbuzzads.com/affiliate/"]
-movie2k.com##a[style="color: rgb(255, 0, 0); font-size: 14px;"]
-moviecritic.com.au###glinks
-moviefone.com###WIAModule
-moviefone.com##.ent_promo_sidetexttitle
-moviefone.com##.mf-banner-container
-movies.yahoo.com###banner
-movies.yahoo.com##.lrec
-moviesfoundonline.com###banner
-moviesmobile.net##a[href*=".amobee.com"]
-moviesmobile.net##a[href*=".mojiva.com"]
-moviesplanet.com##.Banner468X60
-moviesplanet.com##.gb
-movshare.net##.ad
-movstore.com##.overlayVid
-mp3-shared.net##a[href^="http://click.yottacash.com?PID="]
-mp3lyrics.org###bota
-mp3nova.org###msgDiv
-mp3raid.com##td[align="left"]
-mpfour.net##.overlayVid
-msn.com###Sales1
-msn.com###Sales2
-msn.com###Sales3
-msn.com###Sales4
-msn.com###ad
-msn.com##.abs
-msn.com##.ad
-msnbc.msn.com###Dcolumn
-msnbc.msn.com###marketplace
-msnbc.msn.com##.w460
-mstar.com##.MPFBannerWrapper
-mtv.co.uk###mtv-shop
-mtv.com###gft-sponsors
-multiupload.com##div[style="position: relative; width: 701px; height: 281px; background-image: url(\"img/ad_bgr.gif\");"]
-mumbaimirror.com##.bottombanner
-mumbaimirror.com##.topbanner
-music.yahoo.com###YMusicRegion_T3_R2C2_R1
-music.yahoo.com###lrec
-music.yahoo.com###lrecTop
-musicradar.com##.shopping_partners
-musicsonglyrics.com###adv_bg
-musicsonglyrics.com##td[width="300"][valign="top"]
-muskogeephoenix.com##div[style="height: 240px; width: 350px; background-color: rgb(238, 238, 238);"]
-my360.com.au##div[style="height: 250px;"]
-myfoxny.com##.marketplace
-myfoxphoenix.com###leaderboard
-myfoxphoenix.com##.marketplace
-myfoxphoenix.com##.module.horizontal
-myfoxphoenix.com##.vert.expanded
-mygaming.co.za##.banner_300
-mygaming.co.za##.banner_468
-mylifeisaverage.com##.ad
-myoutsourcedbrain.com###HTML2
-myretrotv.com##img[width="875"][height="110"]
-mysearch.com##a.desc > div
-myspace.com###marketing
-myspace.com###medRec
-myspace.com###music_googlelinks
-myspace.com###music_medrec
-myspace.com###tkn_medrec
-myspace.com##.SitesMedRecModule
-myspace.com##.medrecContainer
-mystream.to###adv
-mystream.to###sysbar
-mystream.to##a[href^="out/"]
-myway.com##.desc
-mywebsearch.com##.desc
-narutofan.com###right-spon
-nasdaq.com##div[style="vertical-align: middle; width: 336px; height: 284px;"]
-nation.co.ke##.c15r
-nationalgeographic.com###headerboard
-nationalpost.com##.ad
-naukri.com##.collMTp
-nbc.com###nbc-300
-nbcbayarea.com##.ad
-nbcbayarea.com##.promo
-nbcconnecticut.com###marketingPromo
-nbcsandiego.com###partnerBar
-nbcsandiego.com##.ad
-nbcsports.com###top_90h
-ncrypt.in##a[title="HIGHSPEED Download"]
-ndtv.com##div[style="position: relative; height: 260px; width: 300px;"]
-nearlygood.com###abf
-necn.com###main_117
-necn.com###main_121
-necn.com###main_175
-necn.com###right_generic_117
-necn.com###right_generic_121
-necn.com###right_generic_175
-neopets.com###ban_bottom
-neopets.com##a[style="display: block; margin-left: auto; margin-right: auto; width: 996px; height: 94px;"]
-neowin.net###special-steve
-neowin.net##.sidebar-block-bsa
-neowin.net##.unspecific
-neowin.net##div[style="background: url(\"/images/atlas/aww2.png\") no-repeat scroll center center transparent ! important; height: 250px; width: 300px;"]
-neowin.net##div[style="background:url(/images/atlas/aww2.png) no-repeat center center !important;height:250px;width:300px"]
-nerej.com###bottom_banner
-nerve.com###topBanner
-netchunks.com###af_adblock
-netchunks.com###m_top_adblock
-netchunks.com###sponsorsM
-netmag.co.uk##div[style="margin: 0px auto; padding-right: 0px; float: left; padding-bottom: 0px; width: 320px; padding-top: 0px; height: 290px; background-color: rgb(255, 255, 255);"]
-networkworld.com###lb_container_top
-networkworld.com###promoslot
-networkworld.com##.sponsor
-nevadaappeal.com##.youradhere
-newcastlejets.com.au##.promotion_wrapper
-newgrounds.com##.wide_storepromo
-newgrounds.com##.wide_storepromobot
-news.aol.co.uk###tdiv60
-news.aol.co.uk###tdiv71
-news.aol.co.uk###tdiv74
-news.cnet.com###bottom-leader
-news.com.au##.ad
-news.com.au##.sponsors
-news.yahoo.com###ymh-invitational-recs
-newsarama.com##.marketplace
-newsday.co.zw##.articlecontinues
-newsday.co.zw##div[style="width: 300px; height: 250px;"]
-newsfactor.com##td[style="border-left: 1px solid rgb(192, 192, 192); padding-top: 3px; padding-bottom: 3px;"]
-newsmax.com###noprint1
-newsmax.com##.sponsors_spacer
-newsnet5.com##.ad
-newsnet5.com##.marketplace
-newsniche.com##a[style="font-size: 12px; color: rgb(255, 166, 23);"]
-newsonjapan.com###squarebanner300x250
-newsroomamerica.com###promotional
-newstatesman.com###footerbanner
-newsweek.com##.sponsor
-newsweek.com##.sponsorship
-nfl.com##.adcontainer
-nicknz.co.nz##.lrec
-nicknz.co.nz##.top-banner
-ninemsn.com.au###ad
-ninemsn.com.au###bannerTop
-ninemsn.seek.com.au###msnhd_div3
-nintendolife.com##.the300x250
-nitrome.com###banner_box
-nitrome.com###banner_description
-nitrome.com###banner_shadow
-nitrome.com###skyscraper_box
-nitrome.com###skyscraper_description
-nitrome.com###skyscraper_shadow
-nmap.org##img[height="90"][width="120"]
-nme.com###editorial_sky
-nme.com###skyscraper
-northjersey.com##.detail_boxwrap
-northjersey.com##.detail_pane_text
-notdoppler.com##table[width="312"][height="252"]
-notdoppler.com##td[background="/img/topad_1a.gif"]
-notdoppler.com##td[background="/img/topad_1b.gif"]
-notdoppler.com##td[background="/img/topad_1c.gif"]
-notdoppler.com##td[background="/img/topad_2a.gif"]
-notdoppler.com##td[height="100"][rowspan="3"]
-notdoppler.com##td[style="background-image: url(\"img/main_topshadow-light.gif\"); background-repeat: repeat-x; background-color: rgb(243, 243, 243);"]
-notdoppler.com##td[width="728"][height="90"]
-notebooks.com##.efbleft
-noupe.com##.ad
-novamov.com##.ad
-novamov.com##.top_banner
-nqfury.com.au##.promotion_wrapper
-nullscript.info##div[style="border: 2px solid red; margin: 10px; padding: 10px; text-align: left; height: 80px; background-color: rgb(255, 247, 182);"]
-nwanime.com###iwarn
-nwsource.com###skyscraperwide
-nwsource.com##.adblock
-nwsource.com##.googlemiddle
-ny1.com##.bannerSidebar
-ny1.com##.bannerTop
-nyaatorrents.org###maincont:first-child:last-child > div > a > img
-nyaatorrents.org###maincont:first-child:last-child > div:first-child > div:first-child > a > img
-nyaatorrents.org##a[href^="http://www.nyaatorrents.org/a?"]
-nyaatorrents.org##a[href^="http://www.nyaatorrents.org/b?"]
-nyaatorrents.org##a[href^="http://www.nyaatorrents.org/c?"]
-nydailynews.com###nydn-topbar
-nydailynews.com##.z_sponsor
-nymag.com###partner-feeds
-nymag.com##.google-bottom
-nypost.com##.ad
-nyrej.com###bottom_banner
-nytimes.com##.ad
-nzgamer.com###premierholder
-nzgamer.com##.article_banner_holder
-nzherald.co.nz##.marketPlace
-o2cinemas.com##.links
-objectiface.com###top-leaderboard
-objectiface.com##.leaderboard
-ocregister.com###bannertop2
-ocworkbench.com##.shopwidget1
-offshore-mag.com##.sponsoredBy
-offshore-mag.com##.webcast-promo-box-sponsorname
-oldgames.sk###r_TopBar
-omg-facts.com###droitetop
-omg-facts.com##table[border="0"][width="330px"][height="270px"]
-omg.yahoo.com###omg-lrec
-omgili.com###ad
-oneindia.in##.deal_lists
-oneindia.in##.fotfont
-oneindia.in##td[width="300"][height="250"]
-onjava.com###leaderboard
-online-literature.com##.leader-wrap-bottom
-online-literature.com##.leader-wrap-middle
-online-literature.com##.leader-wrap-top
-onlineathens.com##.story-insert
-onlineathens.com##.yahoo_hoz
-opendiary.com##div[style="width: 300px; height: 250px; border: 1px solid black; margin: 0px; padding: 0px;"]
-opendiary.com##div[style="width: 728px; height: 90px; margin: 0px auto; padding: 0px;"]
-opendrivers.com###google336x280
-orange.co.uk###home_leaderboard
-orange.co.uk###home_mpu
-orange.co.uk###home_partnerlinks
-orange.co.uk###home_shoppinglinks
-orange.co.uk##.spon_sored
-oreillynet.com###leaderboard
-osnews.com##.ad
-ourfamilygenes.ca##div[style="width: 100%; display: block; margin-bottom: 10px; height: 90px;"]
-ovguide.com##.banner-rectangleMedium
-oxygen.com###companion_300x250
-p2pnet.net###sidebar > ul:first-child + table[width="19%"]
-p2pnet.net###sidebar2
-p2pnet.net##td[align="center"][width="100%"] > a[style="border: 0px none ; margin: 0px;"][target="_blank"] > img
-pagead2.googlesyndication.com##html
-passedoutphotos.com###top-leaderboard
-passedoutphotos.com##.leaderboard
-pbs.org###corp-sponsor-sec
-pbs.org###masthead1
-pbs.org###masthead2
-pbs.org##.newshour-support-wrap
-pc-freak.net##div[style="position: absolute; left: 740px; top: 240px; width: 0px;"]
-pcadvisor.co.uk###broadbandchoices_frm
-pcadvisor.co.uk###mastHeadTopLeft
-pcauthority.com.au##.featured-retailers
-pcgamer.com##.ad
-pcmag.com###special_offers_trio
-pcmag.com##.content-links
-pcmag.com##.partners
-pcmag.com##.sp-links
-pcmag.com##.special-offers
-pcmag.com##.spotlight
-pcpro.co.uk###skin
-pcpro.co.uk###skyScrapper
-pcpro.co.uk##.leaderBoard
-pcr-online.biz##.newsinsert
-pcstats.com##table[cellpadding="2"][align="right"][width="300"][style="border: 1px solid ;"]
-pctipsbox.com###daikos-text-4
-pcworld.co.nz###sponsor_div
-pcworld.com###bizPromo
-pcworld.com###ciscoOOSBlog
-pcworld.com###industryWebcasts
-pcworld.com###resourceCenters
-pcworld.com###resourceLinks
-pcworld.com###specialOffers
-pcworld.com##.msReminderBadgeBanner
-pcworld.com##.skyscraper
-pdfmyurl.com##.banner
-pdfzone.com##.Skyscraper_BG
-pdfzone.com##.sponsors_container
-pdfzone.com##div[style="float: left; width: 336px; margin-right: 16px; margin-bottom: 5px;"]
-pedulum.com###header_top
-penny-arcade.com###funding-h
-people.com##.quigo
-perfectlytimedphotos.com###top-leaderboard
-perfectlytimedphotos.com##.leaderboard
-perl.com###leaderboard
-perthglory.com.au##.promotion_wrapper
-pettube.com###ca
-phazeddl.com##a[href^="http://www.mydownloader.net/pr/"]
-phazeddl.com##table#searchResult:first-child
-phazemp3.com##a[href^="http://www.mydownloader.net/pr/"]
-phazemp3.com##table#searchResult:first-child
-phonescoop.com###botlink
-phonescoop.com###promob
-phoronix.com###welcome_screen
-photobucket.com##.bannerContainer
-phpbb.com##a[rel="external affiliate"]
-phpbb.com##a[rel="external sponsor"]
-phpbbhacks.com##div[style="height: 90px;"]
-picapp.com##.ipad_300_250
-picapp.com##.ipad_728_90
-ping.eu##td[height="9"][bgcolor="white"][style="padding: 10px 25px 0px;"]
-pingtest.net##.ad
-pinknews.co.uk##a[href^="http://www.pinknews.co.uk/clicks/"]
-pitchero.com###clubSponsor
-planetxbox360.com###rightCol3gameHome
-planetxbox360.com##div[style="margin: 0px 0pt; padding: 2px; width: 300px; height: 250px;"]
-planetxbox360.com##td#rightCol1[align="right"][valign="top"]
-planetxbox360.com##td[align="center"][height="100"][bgcolor="#3f3f3f"]
-play.tm###lbc
-play.tm###sky
-playkidsgames.com##table[bgcolor="#333333"][width="320"][height="219"]
-playkidsgames.com##table[width="100%"][height="105"]
-plusnetwork.com##.more_links
-plussports.com##.midBanner
-pmptoday.com##div[style="background-color: rgb(255, 255, 255); border: 1px solid rgb(51, 0, 0); font-family: Verdana,Arial,Sans-serif; font-size: 10px; padding: 0px; line-height: 11px; color: rgb(0, 0, 0); width: 728px; height: 90px;"]
-politico.com##.in-story-banner
-politics.co.uk###top-banner
-politifact.com##.pfad
-ponged.com##.adv
-popbytes.com##div[align="left"][style="padding-top: 0px; padding-bottom: 4px; width: 230px; background: none repeat scroll 0% 0% rgb(255, 255, 255);"]
-popbytes.com##div[align="left"][style="width: 230px; background: none repeat scroll 0% 0% rgb(255, 255, 255);"]
-popbytes.com##table[cellspacing="1"][cellpadding="0"][border="0"][bgcolor="#b9e70c"]
-popbytes.com##table[width="229"][cellspacing="0"][cellpadding="0"][border="0"][bgcolor="#000000"]
-popbytes.com##table[width="230"][cellspacing="0"][cellpadding="0"][border="0"][bgcolor="#000000"]
-popbytes.com##table[width="230"][cellspacing="0"][cellpadding="0"][border="0"][bgcolor="#ffffff"]
-popbytes.com##table[width="230"][cellspacing="0"][cellpadding="4"][border="0"][bgcolor="#ffffff"]
-popbytes.com##table[width="230"][cellspacing="5"][cellpadding="3"][style="overflow: hidden; border: 0px solid rgb(204, 204, 204); background-color: rgb(44, 161, 200);"]
-popeater.com##.sidebarBanner
-popularmechanics.com###circ300x100
-popularmechanics.com###circ300x200
-popularmechanics.com###circ620x100
-post-trib.com###zip2save_link_widget
-press-citizen.com##.rightrail-promo
-pressf1.co.nz###sponsor_div
-pri.org###amazonBox180
-pricegrabber.co.uk###spl
-pricegrabber.com##.topBanner
-pricespy.co.nz##.ad
-prisonplanet.com###bottombanners
-prisonplanet.com###efoods
-proaudioreview.com##table[width="665"]
-productreview.com.au##td[width="160"][valign="top"]
-projectw.org##a[href^="http://uploading.com/partners/"]
-ps3news.com###bglink
-ps3news.com###sidebar > div > div > table[cellspacing="5px"]:first-child
-psu.com###ad
-psx-scene.com##tr[valign="top"]:first-child:last-child > td[width="125"][valign="top"][style="padding-left: 5px;"]:last-child
-ptinews.com##.fullstoryadd
-ptinews.com##.fullstorydivright
-publicradio.org###amzContainer
-punjabimob.org##a[href*=".smaato.net"]
-pureoverclock.com###adblock1
-pureoverclock.com###adblock2
-pureoverclock.com###mainbanner
-qj.net###shoppingapi
-qj.net##.square
-quackit.com###rightColumn
-quackit.com##div[style="margin: auto; width: 180px; height: 250px; text-align: center; background: url(\"/pix/ads/ad_zappyhost_search_box_180x250.gif\") no-repeat scroll left top rgb(255, 255, 255);"]
-querverweis.net##.iframe_box
-quickload.to##a[href^="http://www.quickload.to/click.php?id="]
-quicksilverscreen.com##a[href="http://www.tubeplus.com"]
-quizlet.com##.googlewrap
-radaronline.com###videoExternalBanner
-radaronline.com###videoSkyscraper
-rapbasement.com##a[style="display: block; width: 100%; height: 280px; text-indent: -10000px; position: absolute;"]
-rapid8.com##.content:first-child > code:last-child
-rapid8.com##.content:first-child > form[method="post"] > code:last-child
-rapid8.com##a[href^="http://www.crowdGravity.com/AF_"]
-rapidlibrary.com##table[cellspacing="1"][cellpadding="3"][border="0"][width="98%"]
-ratemyprofessors.com##.rmp_leaderboard
-rawstory.com##td[width="101"][align="center"][style][margin="0"]
-readmetro.com##.header
-readwriteweb.com###ad_block
-readwriteweb.com###fm_conversationalist_zone
-readwriteweb.com###rwcloud_promo
-readwriteweb.com###rwwpartners
-readwriteweb.com###vmware-trial
-realitytvobsession.com###glinks
-realworldtech.com##.leaderboard_wrapper
-rebubbled.com##.leaderboard
-receeve.it##.carousel
-redbookmag.com###special_offer_300x100
-reddit.com##.promotedlink
-rediff.com###world_right1
-rediff.com###world_top
-redmondmag.com##.ad
-reference.com###Resource_Center
-reference.com###abvFold
-reference.com###bannerTop
-reference.com###bnrTop
-reference.com###centerbanner_game
-reference.com###rc
-reference.com##.spl_unshd
-reference.com##.spl_unshd_NC
-rejournal.com##img[style="border-width: 0px;"]
-rejournal.com##img[width="200"][height="100"]
-reloadevery.mozdev.org###main-content > #mysidebar
-reminderfox.mozdev.org###promotion3
-restaurants.com##.latad
-retailgazette.co.uk##.ad
-reverso.net##.columnBanner2
-rhylfc.co.uk##.bannergroup
-rinkworks.com##table[style="float: right; border: 1px solid red; width: 250px; padding: 10px; margin: 10px;"]
-rivals.com###thecontainer
-roadfly.com###leaderboardHead
-roadfly.com##.adv
-roadrunner.com##.leaderboard
-robotswithfeelings.com##div[style="height: 250px; width: 300px; background-color: rgb(0, 0, 0);"]
-robotswithfeelings.com##div[style="height: 90px; width: 728px; margin-left: auto; margin-right: auto; background-color: rgb(0, 0, 0);"]
-robtex.com##div[style="width: 728px; height: 90px; margin-left: auto; margin-right: auto;"]
-rockpapershotgun.com##.marketing
-rollcall.com##.ad
-rollingstone.com##.ad
-rotoruadailypost.co.nz##.marketPlace
-rottentomatoes.com###afc_sidebar
-roughlydrafted.com###banner
-roulettereactions.com###top-leaderboard
-roulettereactions.com##.leaderboard
-royalgazette.com##div[style="height: 60px; width: 468px;"]
-rr.com##.leaderboard
-rr.com##.leaderboardTop
-rs-catalog.com##div[onmouseout="this.style.backgroundColor='#fff7b6'"]
-rte.ie###island300x250-inside
-rte.ie###story_island
-rte.ie###tilesHolder
-rte.ie##div[style="background-color: rgb(239, 238, 234); text-align: center; width: 728px; height: 92px; padding-top: 2px;"]
-rubbernews.com##td[width="250"]
-runescape.com###tb
-rushlimbaugh.com###top_leaderboard
-rwonline.com##table[width="665"]
-sacbee.com###leaderboard
-satelliteguys.us##div[style="width: 300px; float: right; height: 250px; margin-left: 10px; margin-right: 10px; margin-bottom: 10px;"]
-satelliteguys.us##td[width="160"][valign="top"][align="left"]
-schlockmercenary.com##td[colspan="3"]
-sci-tech-today.com##td[style="border-left: 1px dashed rgb(192, 192, 192); padding: 5px;"]
-sci-tech-today.com##td[style="border-left: 1px solid rgb(192, 192, 192); padding-top: 3px; padding-bottom: 3px;"]
-scienceblogs.com###leaderboard
-scienceblogs.com##.skyscraper
-sciencedaily.com##.rectangle
-sciencedaily.com##.skyscraper
-sciencedirect.com###leaderboard
-scientificamerican.com##a[href^="/ad-sections/"]
-scientificamerican.com##div[style="height: 275px; margin: 0pt;"]
-scoop.co.nz###top-banner
-scoop.co.nz###top-banner-base
-scoop.co.nz###topHeader
-scotsman.com###banner01
-search.aol.ca##.SLL
-search.aol.ca##.WOL
-search.aol.co.uk##.PMB
-search.aol.co.uk##.SLL
-search.aol.co.uk##.WOL
-search.aol.com##.PMB
-search.aol.com##.SLL
-search.aol.com##.WOL
-search.aol.in##.SLL
-search.cnbc.com###ms_aur
-search.com##.citeurl
-search.com##.dtext
-search.com##a[href^="http://shareware.search.com/click?"]
-search.excite.co.uk###results11_container
-search.excite.co.uk##td[width="170"][valign="top"]
-search.icq.com##.more_sp
-search.icq.com##.more_sp_end
-search.icq.com##.res_sp
-search.netscape.com##.SLL
-search.netscape.com##.SWOL
-search.virginmedia.com##.s-links
-search.winamp.com##.SLL
-search.winamp.com##.SWOL
-search.winamp.com##.WOL
-search.yahoo.com###east
-search.yahoo.com###sec-col
-search.yahoo.com##.bbox
-search.yahoo.com##.overture
-searchalot.com##td[onmouseout="cs()"]
-searchenginejournal.com##.even
-searchenginejournal.com##.odd
-searchenginesuggestions.com###top-leaderboard
-searchenginesuggestions.com##.leaderboard
-seattlepi.com##.wingadblock
-secretmaryo.org##div[style="width: 728px; height: 90px; margin-left: 6px;"]
-securityfocus.com##td[width="160"][bgcolor="#eaeaea"]
-securityweek.com###banner
-seekfind.org##table[width="150"]
-sensis.com.au##.pfpRightParent
-sensis.com.au##.pfplist
-serialnumber.in##div[style^="display: block; position: absolute;"]
-serialnumber.in##div[style^="display: block; text-align: center; line-height: normal; visibility: visible; position: absolute;"]
-sevenload.com###superbaannerContainer
-sevenload.com###yahoo-container
-sfgate.com##.kaango
-sfgate.com##.z-sponsored-block
-sfx.co.uk###banner
-share-links.biz###advice
-share-links.biz###inf_outer
-share-links.biz###infoC
-share-links.biz##.m10.center
-share-links.biz##.w160.dark.center
-shine.yahoo.com###ylf-ysm-side
-shinyshiny.tv##.leaderboard
-shitbrix.com###top-leaderboard
-shitbrix.com##.leaderboard
-shopcrazy.com.ph###topleaderboard
-shopping.com###featListingSection
-shopping.findtarget.com##div[style="background: none repeat scroll 0% 0% rgb(255, 255, 255); padding: 0pt 0.4em 0.1em 0pt; margin: 0.3em 0pt;"]
-shopping.net##table[border="1"][width="580"]
-shopping.yahoo.com##.shmod-ysm
-sify.com##div[style="width: 250px; height: 250px;"]
-siliconchip.com.au##td[align="RIGHT"][width="50%"][valign="BOTTOM"]
-siliconrepublic.com###leaderboard
-siliconvalley.com##.blogBox
-siliconvalley.com##.lnbbgcolor
-silverlight.net##.banner_header
-simplyassist.co.uk##.std_BottomLine
-simplyhired.com##.featured
-siteadvisor.com##.midPageSmallOuterDiv
-sitepoint.com##.industrybrains
-siteseer.ca###banZone
-sixbillionsecrets.com###droitetop
-sk-gaming.com###pts
-sk-gaming.com###ptsf
-skins.be##.shortBioShadowB.w240
-skyrock.com###pub_up
-slashfood.com##.quigo
-slate.com##.bizbox_promo
-slideshare.net##.medRecBottom2
-sloughobserver.co.uk###buttons-mpu-box
-slyck.com##div[style="width: 295px; border: 1px solid rgb(221, 221, 221); text-align: center; background: none repeat scroll 0% 0% rgb(255, 255, 255); padding: 5px; font: 12px verdana;"]
-smarter.com##.favboxmiddlesearch
-smarter.com##.favwrapper
-smash247.com###RT1
-smashingmagazine.com###commentsponsortarget
-smashingmagazine.com###mediumrectangletarget
-smashingmagazine.com###sidebaradtarget
-smashingmagazine.com###sponsorlisttarget
-smashingmagazine.com##.ed
-smh.com.au##.ad
-snapfiles.com###bannerbar
-snapfiles.com###borderbar
-snapfiles.com###prodmsg
-snow.co.nz###content-footer-wrap
-snow.co.nz###header-banner
-snowtv.co.nz###header-banner
-soccer365.com##.whiteContentBdr350
-soccerphile.com###midbanners
-soccerphile.com###topbanners
-socialmarker.com###ad
-soft32.com##a[href="http://p.ly/regbooster"]
-softonic.com##.topbanner
-softonic.com##.topbanner_program
-softpedia.com##.logotable[align="right"] > a[target="_blank"]
-softpedia.com##.pagehead_op2
-softpedia.com##img[width="600"][height="90"]
-softpedia.com##td[align="right"][style="padding-bottom: 5px; padding-left: 22px; padding-right: 17px;"]
-solarmovie.com###l_35061
-someecards.com###shop
-someecards.com###some-ads
-someecards.com###some-more-ads
-someecards.com###store
-somethingawful.com##.oma_pal
-songlyrics.com##.content-bottom-banner
-songs.pk##img[width="120"][height="60"]
-songs.pk##table[width="149"][height="478"]
-songs.pk##td[width="100%"][height="20"]
-space.com###expandedBanner
-space.com##table[width="321"][height="285"][bgcolor="#000000"]
-space.com##td[colspan="2"]:first-child > table[width="968"]:first-child
-sparesomelol.com###top-leaderboard
-sparesomelol.com##.leaderboard
-spectator.org##.ad
-spectrum.ieee.org###whtpprs
-speedtest.net##.ad
-spikedhumor.com###ctl00_CraveBanners
-spikedhumor.com##.ad
-spoiledphotos.com###top-leaderboard
-spoiledphotos.com##.leaderboard
-spokesman.com##.ad
-squidoo.com###header_banner
-stagevu.com##.ad
-start64.com##td[height="92"][colspan="2"]
-startpage.com###inlinetable
-startribune.com###bottomLeaderboard
-startribune.com###topLeaderboard
-staticice.com.au##table[rules="none"][style="border: 1px solid rgb(135, 185, 245);"]
-staticice.com.au##td[align="center"][valign="middle"][height="80"]
-sternfannetwork.com##[align="center"] > .tborder[width="728"][cellspacing="1"][cellpadding="0"][border="0"][align="center"]
-stickam.com###f_BottomBanner
-stickam.com###h_TopBanner
-stopdroplol.com###top-leaderboard
-stopdroplol.com##.leaderboard
-storagereview.com##td[width="410"]:first-child + td[align="right"]
-stormfront.org##img[border="0"][rel="nofollow"]
-stormfront.org##table[width="863"]
-streamingmedia.com##.sponlinkbox
-stripes.com##.ad
-stumblehere.com##td[width="270"][height="110"]
-stv.tv###collapsedBanner
-stv.tv###expandedBanner
-stv.tv###google
-stylelist.com###cod-promo
-stylelist.com##.fromsponsor
-stylelist.com##.partnerPromo
-stylelist.com##div[style="position: relative; border: 1px solid rgb(191, 191, 191); background: none repeat scroll 0% 0% white; width: 424px; display: block;"]
-sunderlandecho.com###banner01
-sunshinecoastdaily.com.au###localOffers
-supernovatube.com##a[href^="http://preview.licenseacquisition.org/"]
-superpages.com##.sponsreulst
-swamppolitics.com###leaderboard
-switched.com###topleader-wrap
-switched.com##.medrect
-swns.com##.story_mpu
-sydneyfc.com##.promotion_wrapper
-sydneyolympicfc.com###horiz_image_rotation
-sys-con.com###elementDiv
-sys-con.com##td[width="180"][valign="top"][rowspan="3"]
-talkingpointsmemo.com##.seventwentyeight
-talkxbox.com###features-sub
-tarot.com###leaderboardOuter
-tattoofailure.com###top-leaderboard
-tattoofailure.com##.leaderboard
-tcmagazine.com###bannerfulltext
-tcmagazine.com###topbanner
-tcmagazine.info###bannerfulltext
-tcmagazine.info###topbanner
-tcpalm.com##.bigbox_wrapper
-teamliquid.net##div[style="width: 472px; height: 64px; overflow: hidden; padding: 0px; margin: 0px;"]
-tech-recipes.com###first-300-ad
-tech-recipes.com###leaderboard
-tech21century.com##div[style="width: 730px; height: 90px; display: block; margin: 5px auto 15px;"]
-techcrunch.com###post_unit_medrec
-techcrunch.com##.ad
-techcrunchit.com##.ad
-techdigest.tv##.leaderboard
-techdirt.com##.ad
-techguy.org##div[style="height: 100px; width: 100%; text-align: center;"]
-techhamlet.com###text-32
-technewsworld.com##.content-block-slinks
-technewsworld.com##.content-tab-slinks
-technologyreview.com##div[style="padding-bottom: 8px;"]
-technologyreview.com##div[style="text-align: center; background: url(\"/images/divider_horiz.gif\") repeat-x scroll left bottom transparent; padding: 10px;"]
-technologyreview.com##p[style="clear: both; text-align: center; background: url(\"/images/divider_horiz.gif\") repeat-x scroll left bottom transparent; font-size: 11px; padding: 0pt; margin: 0pt;"]
-technorati.com###ad
-technorati.com##.ad
-techrepublic.com.com###medusa
-techrepublic.com.com###ppeHotspot
-techrepublic.com.com###spotlight
-techrepublic.com.com###wpPromo
-techrepublic.com.com##.essentialTopics
-techrepublic.com.com##.hotspot
-techwatch.co.uk##table[width="250"][height="300"]
-techweb.com###h_banner
-tectonic.co.za##.tdad125
-teenhut.net##td[align="left"][width="160"][valign="top"]
-teesoft.info###footer-800
-teesoft.info###uniblue
-telecompaper.com##.side_banner
-telegramcommunications.com###leftBanner
-telegramcommunications.com###rightBanner
-telegraph.co.uk###gafsslot1
-telegraph.co.uk###gafsslot2
-telegraph.co.uk##.comPuff
-telegraph.co.uk##a[href^="http://www.telegraph.co.uk/sponsored/"]
-telegraphindia.com##.Caption
-televisionbroadcast.com##table[width="665"]
-tesco.com###dartLeftSkipper
-tesco.com###dartRightSkipper
-tesco.com##.dart
-tf2maps.net##a[href="http://forums.tf2maps.net/payments.php"]
-tf2maps.net##form[name="search"] + div + fieldset
-tf2maps.net##form[name="search"] + div + fieldset + br + br + fieldset
-tfportal.net###snt_wrapper
-tgdaily.com###right-banner
-thatvideogameblog.com##table[width="310"][height="260"]
-thatvideosite.com##div[style="padding-bottom: 15px; height: 250px;"]
-the217.com###textpromo
-theaa.com###unanimis1
-theage.com.au##.ad
-thebizzare.com##.adblock
-thecelebritycafe.com##table[width="135"][height="240"]
-thecourier.co.uk###sidebarMiddleCol
-theeagle.com##.SectionRightRail300x600Box
-theeastafrican.co.ke##.c15r
-thefashionspot.com###roadblock
-thefreedictionary.com###Ov
-thefreedictionary.com##.Ov
-thefrisky.com##.partner-link-boxes-container
-thegameslist.com##.leader
-thegauntlet.ca##div[style="width: 170px; height: 620px; background: url(\"/advertisers/your-ad-here-160x600.gif\") repeat scroll 0% 0% rgb(204, 204, 204); vertical-align: top; text-align: center;"]
-thegauntlet.ca##div[style="width: 190px; height: 110px; background: url(\"/advertisers/your-ad-here-180x90.gif\") repeat scroll 0% 0% rgb(204, 204, 204); vertical-align: top; text-align: center;"]
-thegauntlet.ca##div[style="width: 190px; height: 170px; background: url(\"/advertisers/your-ad-here-180x150.gif\") repeat scroll 0% 0% rgb(204, 204, 204); vertical-align: top; text-align: center;"]
-thegauntlet.ca##div[style="width: 738px; height: 110px; background: url(\"/advertisers/your-ad-here-728x90.gif\") repeat scroll 0% 0% rgb(204, 204, 204); vertical-align: top; text-align: center;"]
-theglobeandmail.com##.ad
-thegrumpiest.com##td[align="left"][width="135px"]
-thegrumpiest.com##td[align="left"][width="135px"] + td#table1
-thehill.com###topbanner
-thehill.com##.banner
-thehill.com##.lbanner
-thehill.com##.vbanner
-thelocalweb.net##.verdana9green
-themaineedge.com##td[height="80"][style="background-color: rgb(0, 0, 0);"]
-themaineedge.com##td[width="180"][style="background-color: rgb(51, 95, 155); text-align: center;"]
-themesbase.com##div[style="width: 486px; height: 60px; margin: 0pt auto; line-height: 60px; text-align: center;"]
-themoscowtimes.com##.adv_block
-themoscowtimes.com##.top_banner
-thenation.com##.ad
-thenation.com##.modalContainer
-thenation.com##.modalOverlay
-thenextweb.com##.promo
-thenextweb.com##.promotion_frame
-theonion.com##.ad
-thepittsburghchannel.com##.MS
-thepspblog.com###featured
-thepspblog.com###mta_bar
-theregister.co.uk###jobs-promo
-theregister.co.uk###msdn-promo
-theregister.co.uk##.papers-promo
-theregister.co.uk##.wptl
-thesaurus.com###abvFold
-thesaurus.com##.spl_unshd
-theserverside.com###leaderboard
-thesixthaxis.com##.map-header-mainblock
-thesixthaxis.com##.map-main-right-takeover
-thesixtyone.com##div[style="width: 968px; text-align: center; margin-top: 12px; clear: both; float: left;"]
-thesmokinggun.com###skyscraper
-thestandard.com###leaderboard_banner
-thestates.fm###banbo
-thestreet.com###brokerage
-thestreet.com###textLinks
-thestreet.com###textLinksContainer
-thesun.co.uk###takeoverleft
-thesun.co.uk###takeoverright
-thesun.co.uk##.float-right.padding-left-10.width-300.padding-bottom-10.padding-top-10
-thesun.co.uk##.srch_cont
-thesuperficial.com###leaderboard
-thetandd.com##.yahoo_content_match
-thevarguy.com###middlebannerwrapper
-thevarguy.com##.squarebanner160x160
-thinkpads.com###sponsorbar
-thisisbath.co.uk###mast-head
-thisisbristol.co.uk###mast-head
-thisisleicestershire.co.uk###mast-head
-thisisleicestershire.co.uk##.banner-extButton
-thisismoney.co.uk###Sky
-thisisplymouth.co.uk##.leaderboard
-threatpost.com###partners
-tidbits.com###top_banner
-tigerdirect.ca##div[style="width: 936px; clear: both; margin-top: 2px; height: 90px;"]
-tigerdroppings.com##td[height="95"][bgcolor="#dedede"]
-time.com##.sep
-timeanddate.com##fieldset[style="float: right; width: 180px;"]
-timeout.com##.MD_textLinks01
-timeoutdubai.com###tleaderb
-timesdispatch.com###dealoftheday
-timesnewsline.com##div[style="border: 1px solid rgb(227, 227, 227); background: none repeat scroll 0% 0% rgb(255, 248, 221); padding: 5px; width: 95%;"]
-timesnewsline.com##table[width="300"][height="250"][align="left"]
-timesofindia.indiatimes.com##div[style="float: left; padding-left: 5px;"]
-timesofindia.indiatimes.com##div[style="height: 100px;"]
-timesonline.co.uk##.bg-f0eff5.padding-left-right-9.padding-top-6.link-width.word-wrap
-timesonline.co.uk##.bg-f0eff5.padding-left-right-9.padding-top-6.padding-bottom-7.word-wrap
-timesonline.co.uk##.classifieds-long-container
-tinypic.com##.ad
-tinypic.com##.medrec
-tips.net###googlebig
-titantv.com##.leaderboard
-tmz.com###leaderboard
-tmz.com###skyscraper
-tnt.tv###right300x250
-todaystmj4.com###leaderboard1
-todaytechnews.com##.advText
-tomsgames.com###pub_header
-tomsgames.it###pub_header
-tomsguide.com##.sideOffers
-tomwans.com##a.big_button[target="_blank"]
-toofab.com###leaderboard
-top4download.com##div[style="float: left; width: 620px; height: 250px; clear: both;"]
-top4download.com##div[style="width: 450px; height: 205px; clear: both;"]
-topgear.com###skyscraper
-topix.com###freecredit
-topix.com###krillion_container
-topsocial.info##a[href^="http://click.search123.uk.com/"]
-toptechnews.com##.regtext[style="border: 1px solid rgb(192, 192, 192); padding: 5px;"]
-toptechnews.com##table[width="370"][cellpadding="10"][style="border: 1px solid rgb(204, 204, 204); border-collapse: collapse;"]
-toptechnews.com##table[width="990"][cellpadding="5"]
-toptenreviews.com##.google_add_container
-toptut.com##.af-form
-torontosun.com###buttonRow
-torrent-finder.com##.cont_lb
-torrents.to##.da-top
-torrentz.com##div[style="width: 1000px; margin: 0pt auto;"]
-totalfark.com###rightSideRightMenubar
-totalfilm.com###mpu_container
-totalfilm.com###skyscraper_container
-tothepc.com##.sidebsa
-toynews-online.biz##.newsinsert
-travel.yahoo.com##.spon
-travel.yahoo.com##.tgl-block
-treatmentforbruises.net##.fltlft
-treatmentforbruises.net##.fltrt
-treehugger.com##.google-indiv-box2
-treehugger.com##.leaderboard
-tripadvisor.ca##.commerce
-tripadvisor.co.uk##.commerce
-tripadvisor.com##.commerce
-tripadvisor.ie##.commerce
-tripadvisor.in##.commerce
-trovit.co.uk##.wrapper_trovit_ppc
-trucknetuk.com###page-body > div[style="margin: 0pt auto; text-align: center;"]
-trucknetuk.com##table[width="100%"][bgcolor="#cecbce"] > tbody > tr > #sidebarright[valign="top"]:last-child
-trucknetuk.com##table[width="620"][cellspacing="3"][bgcolor="#ffffff"][align="center"][style="border: thin solid black;"]
-trueslant.com##.bot_banner
-trustedreviews.com###bottom-sky
-trustedreviews.com###top-sky
-trutv.com##.banner
-tsviewer.com###layer
-tuaw.com##.medrect
-tuaw.com##.topleader
-tucows.com##.w952.h85
-tucsoncitizen.com##.bigbox_container
-tucsoncitizen.com##.leaderboard_container_top
-tucsoncitizen.com##.skyscraper_container
-tutsplus.com###AdobeBanner
-tutsplus.com##.leader_board
-tutzone.net###bigBox
-tv.yahoo.com##.spons
-tvgolo.com##.inner2
-tvgolo.com##.title-box4
-tvgolo.com##.title-box5
-tvguide.co.uk##table[width="160"][height="620"]
-tvsquad.com###tvsquad_topBanner
-tvsquad.com##.banner
-tvtechnology.com##table[width="665"]
-twcenter.net##div[style="width: 728px; height: 90px; margin: 1em auto 0pt;"]
-twilightwap.com##.ahblock2
-twitter.com##.promoted-account
-twitter.com##.promoted-trend
-twitter.com##.promoted-tweet
-twitter.com##li[data*="advertiser_id"]
-u-file.net##.spottt_tb
-ucas.com##a[href^="http://eva.ucas.com/s/redirect.php?ad="]
-ucoz.com##[id^="adBar"]
-ucoz.org##[id^="adBar"]
-ugotfile.com##a[href="https://www.astrill.com/"]
-ugotfile.com##a[href^="http://ugotfile.com/affiliate?"]
-ukclimbing.com##img[width="250"][height="350"]
-ultimate-guitar.com##.pca
-ultimate-guitar.com##.pca2
-ultimate-guitar.com##td[align="center"][width="160"]
-ultimate-guitar.com##td[style="height: 110px; vertical-align: middle; text-align: center;"]
-ultimate-guitar.com##td[width="100%"][valign="middle"][height="110"]
-ultimate-rihanna.com###ad
-unblock-proxy-server.com###ablc
-uncoached.com###sidebar300X250
-united-ddl.com##table[width="435"][bgcolor="#575e57"]
-unknown-horizons.org###akct
-unrealitymag.com###header
-unrealitymag.com###sidebar300X250
-upfordown.com##div[style="float: left; width: 100%; padding: 0px 0px 10px; text-align: center; position: static;"]
-uploaded.to##div[style="background-repeat: no-repeat; width: 728px; height: 90px; margin-left: 0px;"]
-uploading.com##div[style="background: rgb(246, 246, 246) none repeat scroll 0% 0%; width: 35%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous; height: 254px;"]
-uploading.com##div[style="margin: -2px auto 19px; display: block; position: relative;"]
-uploadville.com##a[href^="http://www.flvpro.com/movies/?aff="]
-uploadville.com##a[href^="http://www.gygan.com/affiliate/"]
-urbandictionary.com###dfp_define_rectangle
-urbandictionary.com###dfp_homepage_medium_rectangle
-urbandictionary.com###dfp_skyscraper
-urbandictionary.com###rollup
-urbandictionary.com##.zazzle_links
-url.org###resspons1
-url.org###resspons2
-urlesque.com##.sidebarBanner
-urlesque.com##.topBanner
-usatoday.com###expandedBanner
-usatoday.com###footerSponsorOne
-usatoday.com###footerSponsorTwo
-usatoday.com##.ad
-usautoparts.net##td[height="111"][align="center"][valign="top"]
-userscripts.org##.sponsor
-userstyles.org##.ad
-usnews.com##.ad
-usniff.com###bottom
-usniff.com##.top-usniff-torrents
-v3.co.uk###superSky
-v3.co.uk##.ad
-v3.co.uk##.hpu
-v3.co.uk##.leaderboard
-v8x.com.au##td[align="RIGHT"][width="50%"][valign="BOTTOM"]
-variety.com###googlesearch
-variety.com###w300x250
-variety.com##.sponsor
-veehd.com##.isad
-venturebeat.com###leader
-venturebeat.com##div[style="height: 300px; text-align: center;"]
-verizon.net##.sponsor
-vg247.com###leader
-vg247.com###rightbar > #halfpage
-vidbox.net##.overlayVid
-vidbux.com##a[href="http://www.vidbux.com/ccount/click.php?id=4"]
-video.foxnews.com###cb_medrect1_div
-video2mp3.net###ad
-videogamer.com##.skinClick
-videogamer.com##.widesky
-videography.com##table[width="665"]
-videohelp.com###leaderboard
-videohelp.com##.stylenormal[width="24%"][valign="top"][align="left"]
-videohelp.com##td[valign="top"][height="200"][style="background-color: rgb(255, 255, 255);"]
-videojug.com##.forceMPUSize
-videoweed.com##.ad
-videoweed.com##div[style="width: 460px; height: 60px; border: 1px solid rgb(204, 204, 204); margin: 0px auto 10px;"]
-videoweed.com##div[style^="width: 160px; height: 600px; border: 1px solid rgb(204, 204, 204); float:"]
-vidreel.com##.overlayVid
-vidxden.com###divxshowboxt > a[target="_blank"] > img[width="158"]
-vidxden.com##.ad
-vidxden.com##.header_greenbar
-vimeo.com##.ad
-vioku.com##.ad
-virginmedia.com##.s-links
-virtualnights.com###head-banner
-virus.gr###block-block-19
-viz.com##div[style^="position: absolute; width: 742px; height: 90px;"]
-vladtv.com###banner-bottom
-w2c.in##[href^="http://c.admob.com/"]
-w3schools.com##a[rel="nofollow"]
-w3schools.com##div[style="width: 890px; height: 94px; position: relative; margin: 0px; padding: 0px; overflow: hidden;"]
-walesonline.co.uk##.promobottom
-walesonline.co.uk##.promotop
-walletpop.com###attic
-walletpop.com##.medrect
-walletpop.com##.sponsWidget
-walyou.com##.ad
-warez-files.com##.premium_results
-warezchick.com##div.top > p:last-child
-warezchick.com##img[border="0"]
-wareznova.com##img[width="298"][height="53"]
-wareznova.com##img[width="468"]
-wareznova.com##input[value="Download from DLP"]
-wareznova.com##input[value="Start Premium Downloader"]
-washingtonexaminer.com###header_top
-washingtonpost.com###textlinkWrapper
-washingtonscene.thehill.com##.top
-wasterecyclingnews.com##.bigbanner
-watoday.com.au##.ad
-wattpad.com##div[style="width: 100%; height: 90px; text-align: center;"]
-weather.ninemsn.com.au###msnhd_div3
-weatherbug.com##.wXcds1
-weatherbug.com##.wXcds2
-webdesignerwall.com##.ad
-webdesignstuff.com###headbanner
-webopedia.com##.bstext
-webpronews.com##.articleleftcol
-webresourcesdepot.com##.Banners
-webresourcesdepot.com##img[width="452px"][height="60px"]
-webworldindex.com##table[bgcolor="#ceddf0"]
-weddingmuseum.com##a[href^="http://click.linksynergy.com/"]
-weeklyworldnews.com##.top-banner
-wefindads.co.uk##div.posts-holder[style="margin-top: 10px;"]
-wefollow.com##.ad
-wenn.com###topbanner
-weselectmodels.com##div[style="width: 728px; height: 90px; background-color: black; text-align: center;"]
-westlothianhp.co.uk###banner01
-westsussextoday.co.uk###banner01
-wftv.com###leaderboard-sticky
-whatismyip.com##.gotomypc
-whatismyip.com##span[style="margin: 2px; float: left; width: 301px; height: 251px;"]
-wheels.ca##div[style="color: rgb(153, 153, 153); font-size: 9px; clear: both; border-top: 1px solid rgb(238, 238, 238); padding-top: 15px;"]
-wheels.ca##div[style="float: left; width: 237px; height: 90px; margin-right: 5px;"]
-wheels.ca##div[style="float: left; width: 728px; height: 90px; z-index: 200000;"]
-whistlestopper.com##td[align="left"][width="160"][valign="top"]
-widescreengamingforum.com###banner-content
-wikia.com###HOME_LEFT_SKYSCRAPER_1
-wikia.com###HOME_TOP_LEADERBOARD
-wikia.com###LEFT_SKYSCRAPER_1
-wikia.com###LEFT_SKYSCRAPER_2
-wikia.com###TOP_LEADERBOARD
-winamp.com###subheader
-wincustomize.com##.wc_home_tour_loggedout
-windows7download.com##div[style="width: 336px; height: 280px;"]
-windows7download.com##div[style="width: 680px; height: 280px; clear: both;"]
-windowsbbs.com##span[style="margin: 2px; float: left; width: 337px; height: 281px;"]
-windowsitpro.com###dnn_pentonRoadblock_pnlRoadblock
-windowsxlive.net##div[style="width: 160px; height: 600px; margin-left: 12px; margin-top: 16px;"]
-windowsxlive.net##div[style="width: 336px; height: 380px; float: right; margin: 8px;"]
-winsupersite.com###footerLinks > table[width="100%"]:first-child
-winsupersite.com##td[style="border-top: 1px none rgb(224, 224, 224); color: rgb(0, 0, 0); font-weight: normal; font-style: normal; font-family: sans-serif; font-size: 8pt; padding-right: 3px; padding-bottom: 3px; padding-top: 3px; text-align: left;"]
-wired.co.uk##.banner-top
-wired.co.uk##.banner1
-wired.com###featured
-wirelessforums.org##td[width="160"][valign="top"]
-wisegeek.com##[action="/the-best-schools-for-you.htm"]
-wishtv.com###leaderboard
-wlfi.com###leaderboard
-wordreference.com##.bannertop
-workforce.com##td[width="970"][height="110"]
-worksopguardian.co.uk###banner01
-worldmag.com##div[style="padding: 8px 0px; text-align: center;"]
-worldmag.com##div[style="text-align: center; padding: 8px 0px; clear: both;"]
-worthdownloading.com##tr:first-child:last-child > td:first-child:last-child > .small_titleGrey[align="center"]:first-child
-worthingherald.co.uk###banner01
-worthplaying.com##.ad
-wow.com###topleader-wrap
-wow.com##.medrect
-wowwiki.com###HOME_LEFT_SKYSCRAPER_1
-wowwiki.com###HOME_TOP_LEADERBOARD
-wowwiki.com###LEFT_SKYSCRAPER_1
-wowwiki.com###TOP_LEADERBOARD
-wpbt2.org##.home_banners
-wphostingdiscount.com##.ad
-wptv.com##.module.horizontal
-wsj.com##.spn_links_box
-wwl.com###BannerXGroup
-wwtdd.com###showpping
-wwtdd.com##.post_insert
-wwtdd.com##.s728x90
-www.google.co.in##table[cellpadding="0"][width="100%"][style^="border: 1px solid"]
-www.google.com##table[cellpadding="0"][width="100%"][style^="border: 1px solid"]
-wxyz.com##.ad
-wypr.org###leaderboard
-xbox360rally.com###topbanner
-xe.com###HomePage_Slot1
-xe.com###HomePage_Slot2
-xe.com###HomePage_Slot3
-xe.com###UCCInputPage_Slot1
-xe.com###UCCInputPage_Slot2
-xe.com###UCCInputPage_Slot3
-xe.com###leaderB
-xe.com##.wa_leaderboard
-xfm.co.uk###commercial
-xml.com###leaderboard
-xml.com##.recommended_div2
-xml.com##.secondary[width="153"][bgcolor="#efefef"]
-xtremesystems.org##embed[width="728"]
-xtremesystems.org##img[width="728"]
-xtshare.com##.overlayVid
-xxlmag.com###medium-rec
-yahoo.com###ad
-yahoo.com###marketplace
-yahoo.com###mw-ysm-cm
-yahoo.com###y_provider_promo
-yahoo.com###ygmapromo
-yahoo.com###ylf-ysm
-yahoo.com###yn-gmy-promo-answers
-yahoo.com###yn-gmy-promo-groups
-yahoo.com##.fpad
-yahoo.com##.marketplace
-yahoo.com##.y708-commpartners
-yahoo.com##.yschspns
-yahoo.com##.ysptblbdr3[cellspacing="0"][cellpadding="1"][width="100%"]
-yatsoba.com##.sponsors
-yauba.com###sidebar > .block_result:first-child
-yauba.com##.resultscontent:first-child
-yesasia.com##.advHr
-yfrog.com##.promo-area
-yodawgpics.com###top-leaderboard
-yodawgpics.com##.leaderboard
-yoimaletyoufinish.com###top-leaderboard
-yoimaletyoufinish.com##.leaderboard
-yorkshireeveningpost.co.uk###banner01
-yorkshirepost.co.uk###banner01
-yourmindblown.com##div[style="float: right; width: 300px; height: 600px; padding: 10px 0px;"]
-yourmindblown.com##div[style="width: 300px; min-height: 250px; padding: 10px 0px; background: none repeat scroll 0% 0% rgb(255, 255, 255);"]
-yourtomtom.com##.bot
-yourtomtom.com##div[style="height: 600px; padding: 6px 0pt; border: 1px solid rgb(180, 195, 154); background: none repeat scroll 0% 0% rgb(249, 252, 241); margin: 0pt;"]
-youtube.com###feedmodule-PRO
-youtube.com###homepage-chrome-side-promo
-youtube.com###search-pva
-youtube.com###watch-branded-actions
-youtube.com###watch-buy-urls
-youtube.com##.promoted-videos
-youtube.com##.watch-extra-info-column
-youtube.com##.watch-extra-info-right
-ytmnd.com###please_dont_block_me
-ytmnd.com##td[colspan="5"]
-yummy.ph###headerLeaderBoard
-yummy.ph##.bannerBox
-zalaa.com##.left_iframe
-zalaa.com##.overlayVid
-zalaa.com##a[href^="http://www.graboid.com/affiliates/"]
-zambiz.co.zm##td[width="130"][height="667"]
-zambiz.co.zm##td[width="158"][height="667"]
-zath.co.uk##.ad
-zdnet.co.uk##.sponsor
-zdnet.com###pplayLinks
-zdnet.com##.dirListSuperSpons
-zdnet.com##.hotspot
-zdnet.com##.promoBox
-zedomax.com##.entry > div[style="width: 100%; height: 280px;"]
-zedomax.com##.entry > div[style="width: 336px; height: 280px;"]
-zeenews.com##.ban-720-container
-zippyshare.com##.center_reklamy
-zomganime.com##a[href="http://fs.game321.com/?utm_source=zomganime&utm_medium=skin_banner&utm_term=free&utm_campaign=fs_zomg_skin"]
-zomganime.com##div[style="background-color: rgb(153, 153, 153); width: 300px; height: 250px; overflow: hidden; margin: 0pt auto;"]
-zomganime.com##div[style="background-color: rgb(239, 239, 239); width: 728px; height: 90px; overflow: hidden;"]
-zomganime.com##marquee[width="160"]
-zone.msn.com##.SuperBannerTVMain
-zonelyrics.net###panelRng
-zoozle.org###search_right
-zoozle.org###search_topline
-zoozle.org##a[onclick^="downloadFile('download_big', null,"]
-zoozle.org##a[onclick^="downloadFile('download_related', null,"]
-zuploads.com###buttoncontainer
-zuploads.com##.hispeed
-zuploads.net###buttoncontainer
-zuula.com##.sponsor
-zxxo.net##a[href^="http://www.linkbucks.com/referral/"]
-!-----------------Whitelists-----------------!
-! *** easylist_whitelist.txt ***
-@@&adname=$script,domain=sankakucomplex.com
-@@||2mdn.net/*/dartshell*.swf
-@@||2mdn.net/*_ecw_$image,domain=wwe.com
-@@||2mdn.net/crossdomain.xml$object_subrequest
-@@||2mdn.net/instream/ads_sdk_config.xml$object_subrequest,domain=globaltv.com|youtube.com
-@@||2mdn.net/instream/adsapi_$object_subrequest,domain=globaltv.com|youtube.com
-@@||2mdn.net/viewad/817-grey.gif$object_subrequest,domain=imdb.com
-@@||a.ads2.msads.net^*.swf$domain=msnbc.msn.com
-@@||a.giantrealm.com/assets/vau/grplayer*.swf
-@@||abc.vad.go.com/dynamicvideoad?$object_subrequest
-@@||ad.103092804.com/st?ad_type=$subdocument,domain=wizard.mediacoderhq.com
-@@||ad.doubleclick.net/adx/nbcu.nbc/rewind$object_subrequest
-@@||ad.doubleclick.net/adx/vid.age/$object_subrequest
-@@||ad.doubleclick.net/pfadx/nbcu.nbc/rewind$object_subrequest
-@@||ad.zanox.com/ppc/$subdocument,domain=wisedock.at|wisedock.co.uk|wisedock.com|wisedock.de|wisedock.eu
-@@||ad3.liverail.com^$object_subrequest,domain=breitbart.tv|seesaw.com
-@@||adhostingsolutions.com/crossdomain.xml$object_subrequest,domain=novafm.com.au
-@@||adjuggler.com^$script,domain=videodetective.com
-@@||adm.fwmrm.net^*/admanager.swf?
-@@||admin.brightcove.com/viewer/*/advertisingmodule.swf$domain=guardian.co.uk|slate.com
-@@||adnet.twitvid.com/crossdomain.xml$object_subrequest
-@@||ads.ad4game.com/www/delivery/ajs.php?zoneid=*&loc=/armorgames.com/play/$script
-@@||ads.adap.tv/control?$object_subrequest
-@@||ads.adap.tv/crossdomain.xml$object_subrequest
-@@||ads.adap.tv/redir/client/adplayer.swf$domain=xxlmag.com
-@@||ads.adultswim.com/js.ng/site=toonswim&toonswim_pos=600x400_ctr&toonswim_rollup=games$script
-@@||ads.belointeractive.com/realmedia/ads/adstream_mjx.ads/www.kgw.com/video/$script
-@@||ads.cnn.com/js.ng/*&cnn_intl_subsection=download$script
-@@||ads.cricbuzz.com/adserver/units/microsites/faststats.leaderboard.customcode.php$subdocument
-@@||ads.forbes.com/realmedia/ads/*@videopreroll$script
-@@||ads.fox.com/fox/black_2sec_600.flv
-@@||ads.foxnews.com/api/*-slideshow-data.js?
-@@||ads.foxnews.com/js/ad.js
-@@||ads.foxnews.com/js/omtr_code.js
-@@||ads.hulu.com^*.flv
-@@||ads.hulu.com^*.swf
-@@||ads.id-t.com/crossdomain.xml$domain=sensation.com
-@@||ads.id-t.com/ep/custom/sensation/flashbanner.php?zone=$domain=sensation.com
-@@||ads.id-t.com/images/$domain=sensation.com
-@@||ads.jetpackdigital.com.s3.amazonaws.com^$image,domain=vibe.com
-@@||ads.jetpackdigital.com/jquery.tools.min.js?$domain=vibe.com
-@@||ads.jetpackdigital.com^*/_uploads/$image,domain=vibe.com
-@@||ads.monster.com/html.ng/$background,image,subdocument,domain=monster.com
-@@||ads.morningstar.com/realmedia/ads/adstream_lx.ads/www.morningstar.com/video/$object_subrequest
-@@||ads.revsci.net/adserver/ako?$script,domain=foxbusiness.com|foxnews.com
-@@||ads.trutv.com/crossdomain.xml$object_subrequest
-@@||ads.trutv.com/html.ng/tile=*&site=trutv&tru_tv_pos=preroll&$object_subrequest
-@@||ads.yimg.com/ev/eu/any/$object
-@@||ads.yimg.com/ev/eu/any/vint/videointerstitial*.js
-@@||ads.yimg.com^*/any/yahoologo$image
-@@||ads.yimg.com^*/search/b/syc_logo_2.gif
-@@||ads.yimg.com^*videoadmodule*.swf
-@@||ads1.msn.com/ads/pronws/$image,domain=live.com
-@@||ads1.msn.com/library/dap.js$domain=msnbc.msn.com|wowarmory.com
-@@||adserver.bigwigmedia.com/ingamead3.swf
-@@||adserver.tvcatchup.com/crossdomain.xml$object_subrequest
-@@||adserver.tvcatchup.com/|$object_subrequest
-@@||adserver.yahoo.com/a?*&l=head&$script,domain=yahoo.com
-@@||adserver.yahoo.com/a?*=headr$script,domain=mail.yahoo.com
-@@||adswizz.com/www/components/$object_subrequest,domain=motogp.com
-@@||adswizz.com/www/delivery/swfindex.php?reqtype=adssetup&$object_subrequest,domain=motogp.com
-@@||adtech.de/crossdomain.xml$object_subrequest,domain=deluxetelevision.com|gigwise.com|nelonen.fi|radiorock.fi|tv2.dk
-@@||app.promo.tubemogul.com/feed/placement.html?id=$script,domain=comedy.com
-@@||apple.com^*/ads/$object,xmlhttprequest
-@@||apple.com^*/video-ad.html
-@@||applevideo.edgesuite.net/admedia/*.flv
-@@||ar.atwola.com/file/adswrapper.js$script,domain=gasprices.mapquest.com
-@@||as.webmd.com/html.ng/transactionid=$object_subrequest
-@@||as.webmd.com/html.ng/transactionid=*&frame=$subdocument
-@@||assets.idiomag.com/flash/adverts/yume_$object_subrequest
-@@||atdmt.com^*/direct*01$domain=sprint.com
-@@||att.com/images/*/admanager/
-@@||auctiva.com/listings/checkcustomitemspecifics.aspx?*&adtype=$script
-@@||autotrader.co.nz/data/adverts/$image
-@@||avclub.com/ads/av-video-ad/$xmlhttprequest
-@@||b.photobucket.com^$object_subrequest
-@@||bing.com/images/async?q=$xmlhttprequest
-@@||bing.net/images/thumbnail.aspx?q=$image
-@@||bitgravity.com/revision3/swf/player/admanager.swf?$object_subrequest,domain=area5.tv
-@@||break.com/ads/preroll/$object_subrequest,domain=videosift.com
-@@||brothersoft.com/gads/coop_show_download.php?soft_id=$script
-@@||burotime.*/xml_*/reklam.xml$object_subrequest
-@@||campusfood.com/css/ad.css?
-@@||candystand.com/assets/images/ads/$image
-@@||cbs.com/sitecommon/includes/cacheable/combine.php?*/adfunctions.
-@@||cdn.last.fm/adserver/video/
-@@||cdn.last.fm/adserver/video/adroll/*/adroll.swf$domain=last.fm
-@@||cdn.springboard.gorillanation.com/storage/lightbox_code/static/companion_ads.js$domain=comingsoon.net|gamerevolution.com
-@@||channel4.com/media/scripts/oasconfig/siteads.js
-@@||chibis.adotube.com/appruntime/player/$object,object_subrequest
-@@||chloe.videogamer.com/data/*/videos/adverts/$object_subrequest
-@@||cisco.com/html.ng/site=cdc&concept=products$script
-@@||clustrmaps.com/images/clustrmaps-back-soon.jpg$third-party
-@@||cms.myspacecdn.com/cms/js/ad_wrapper*.js
-@@||cnet.com/ads/common/adclient/*.swf
-@@||creative.ak.fbcdn.net/ads3/creative/$image,domain=facebook.com
-@@||cubeecraft.com/openx/www/
-@@||dart.clearchannel.com/html.ng/$object_subrequest,domain=kissfm961.com|radio1045.com
-@@||deviantart.com/global/difi/?*&ad_frame=$subdocument
-@@||direct.fairfax.com.au/hserver/*/site=vid.*/adtype=embedded/$script
-@@||discovery.com/components/consolidate-static/?files=*/adsense-
-@@||disneyphotopass.com/adimages/
-@@||doubleclick.net/ad/*smartclip$script,domain=last.fm
-@@||doubleclick.net/adi/amzn.*;ri=digital-music-track;$subdocument
-@@||doubleclick.net/adi/dhd/homepage;sz=728x90;*;pos=top;$subdocument,domain=deadline.com
-@@||doubleclick.net/adj/*smartclip$script,domain=last.fm
-@@||doubleclick.net/adj/imdb2.consumer.video/*;sz=320x240,$script
-@@||doubleclick.net/adj/nbcu.nbc/videoplayer-$script
-@@||doubleclick.net/adj/pong.all/*;dcopt=ist;$script
-@@||doubleclick.net/pfadx/channel.video.crn/;*;cue=pre;$object_subrequest
-@@||doubleclick.net/pfadx/slate.v.video/*;cue=pre;$object_subrequest
-@@||doubleclick.net/pfadx/umg.*;sz=10x$script
-@@||doubleclick.net/pfadx/vid.age/tv/*;sz=$script
-@@||doubleclick.net/pfadx/vid.smh/tv/*;sz=$script
-@@||doubleclick.net^*/adj/wwe.shows/ecw_ecwreplay;*;sz=624x325;$script
-@@||doubleclick.net^*/listen/*;sz=$script,domain=last.fm
-@@||doubleclick.net^*/ndm.tcm/video;$script,domain=player.video.news.com.au
-@@||doubleclick.net^*/videoplayer*=worldnow$subdocument,domain=ktiv.com|wflx.com
-@@||dstw.adgear.com/crossdomain.xml$domain=hot899.com|nj1015.com|streamtheworld.com
-@@||dstw.adgear.com/impressions/int/as=*.json?ag_r=$object_subrequest,domain=hot899.com|nj1015.com|streamtheworld.com
-@@||dyncdn.buzznet.com/catfiles/?f=dojo/*.googleadservices.$script
-@@||ebayrtm.com/rtm?rtmcmd&a=json&cb=parent.$script
-@@||edgar.pro-g.co.uk/data/*/videos/adverts/$object_subrequest
-@@||edmontonjournal.com/js/adsync/adsynclibrary.js
-@@||emediate.eu/crossdomain.xml$domain=tv3play.se
-@@||emediate.eu/eas?cu_key=*;ty=playlist;$object_subrequest,domain=tv3play.se
-@@||emediate.se/crossdomain.xml$domain=tv3play.se
-@@||emediate.se/eas?eascu_keys=$object_subrequest,domain=tv3play.se
-@@||emediate.se/eas_tag.1.0.js$domain=tv3play.se
-@@||espn.go.com^*/espn360/banner?$subdocument
-@@||eyewonder.com^$object,script,domain=last.fm
-@@||eyewonder.com^*/video/$object_subrequest,domain=last.fm
-@@||fdimages.fairfax.com.au^*/ffxutils.js$domain=thevine.com.au
-@@||feeds.videogamer.com^*/videoad.xml?$object_subrequest
-@@||fifa.com/flash/videoplayer/libs/advert_$object_subrequest
-@@||fokzine.net/templates/*/forum_min.js?*/advertisers
-@@||fwmrm.net/ad/p/1?$object_subrequest
-@@||fwmrm.net/crossdomain.xml$object_subrequest
-@@||gannett.gcion.com/addyn/3.0/*/adtech;alias=pluck_signin$script
-@@||garrysmod.org/ads/$background,image,script,stylesheet
-@@||go.com/dynamicvideoad?$object_subrequest,domain=disney.go.com
-@@||google.*/complete/search?$script
-@@||google.com/uds/?file=ads&$script,domain=guardian.co.uk
-@@||google.com/uds/api/ads/$script,domain=guardian.co.uk
-@@||gpacanada.com/img/sponsors/
-@@||gr.burstnet.com/crossdomain.xml$object_subrequest,domain=filefront.com
-@@||gstatic.com/images?q=$image
-@@||guim.co.uk^*/styles/wide/google-ads.css
-@@||gws.ign.com/ws/search?*&google_adpage=$script
-@@||hp.com/ad-landing/
-@@||huffingtonpost.com/images/v/etp_advert.png
-@@||i.cdn.turner.com^*/adserviceadapter.swf
-@@||i.real.com/ads/*.swf?clicktag=$domain=rollingstone.com
-@@||identity-us.com/ads/ads.html
-@@||ign.com/js.ng/size=headermainad&site=teamxbox$script,domain=teamxbox.com
-@@||ikea.com/ms/img/ads/
-@@||images.apple.com^*/images/ads_
-@@||img.thedailywtf.com/images/ads/
-@@||img.timeinc.net/shared/static/js/tii_ads.js$domain=time.com
-@@||img.weather.weatherbug.com^*/stickers/$background,image,stylesheet
-@@||imgag.com/product/full/el/adaptvadplayer.swf$domain=egreetings.com
-@@||imwx.com/js/adstwo/adcontroller.js$domain=weather.com
-@@||itv.com^*.adserver.js
-@@||itweb.co.za/banners/en-cdt*.gif
-@@||jdn.monster.com/render/adservercontinuation.aspx?$subdocument,domain=monster.com
-@@||jobs.wa.gov.au/images/advertimages/
-@@||js.revsci.net/gateway/gw.js?$domain=foxbusiness.com|foxnews.com
-@@||ksl.com/resources/classifieds/graphics/ad_
-@@||last.fm/ads.php?zone=*listen$subdocument
-@@||lightningcast.net/servlets/getplaylist?*&responsetype=asx&$object
-@@||live365.com/mini/blank300x250.html
-@@||live365.com/scripts/liveads.js
-@@||liverail.com/crossdomain.xml$object_subrequest
-@@||liverail.com/swf/*/plugins/flowplayer/
-@@||loaded.it/images/advertise/divx/playeroverlay.png
-@@||loaded.it/images/advertise/flash/flash_player.png$object_subrequest
-@@||ltassrv.com/crossdomain.xml$object_subrequest,domain=animecrazy.net|gamepro.com
-@@||ltassrv.com/yume.swf$domain=animecrazy.net|gamepro.com
-@@||ltassrv.com/yume/yume_$object_subrequest,domain=animecrazy.net|gamepro.com
-@@||mads.cbs.com/mac-ad?$object_subrequest
-@@||mads.com.com/ads/common/faith/*.xml$object_subrequest
-@@||manoramaonline.com/advt/cricbuzz/
-@@||marines.com/videos/commercials/$object_subrequest
-@@||maxmind.com/app/geoip.js$domain=incgamers.com
-@@||media.abc.com/streaming/ads/preroll_$object_subrequest,domain=abc.go.com
-@@||media.monster.com/ads/$background,image,domain=monster.com
-@@||media.newjobs.com/ads/$background,image,object,domain=monster.com
-@@||media.salemwebnetwork.com/js/admanager/swfobject.js$domain=christianity.com
-@@||media.scanscout.com/ads/ss_ads3.swf$domain=failblog.org|icanhascheezburger.com|rr.com
-@@||media.washingtonpost.com/wp-srv/ad/ad_v2.js
-@@||media.washingtonpost.com/wp-srv/ad/tiffany_manager.js
-@@||medrx.sensis.com.au/images/sensis/afl/util.js$domain=afl.com.au
-@@||meduniwien.ac.at/homepage/uploads/tx_macinabanners/$image
-@@||mercurial.selenic.com/images/sponsors/
-@@||mircscripts.org/advertisements.js
-@@||mlb.mlb.com/scripts/dc_ads.js
-@@||monster.com/services/bannerad.asmx/getadsrc$xmlhttprequest,domain=monster.com
-@@||mozilla.com/img/tignish/plugincheck/*/728_90/loading.png$domain=mozilla.com
-@@||msads.net/*.swf|$domain=msnbc.msn.com
-@@||msads.net/crossdomain.xml$object_subrequest,domain=msnbc.msn.com
-@@||msads.net^*.flv|$domain=msnbc.msn.com
-@@||mscommodin.webege.com/images/inicio/sponsors/$image
-@@||mxtabs.net/ads/interstitial$subdocument
-@@||newgrounds.com/ads/ad_medals.gif
-@@||newsarama.com/common/js/advertisements.js
-@@||newsweek.com/ads/adscripts/prod/*_$script
-@@||nick.com/js/ads.jsp
-@@||o.aolcdn.com/ads/adswrapper.js$domain=photos.tmz.com
-@@||oas.absoluteradio.co.uk/realmedia/ads/$object_subrequest
-@@||oas.bigflix.com/realmedia/ads/$object_subrequest
-@@||oas.five.tv/realmedia/ads/adstream_sx.ads/demand.five.tv/$object_subrequest
-@@||oascentral.feedroom.com/realmedia/ads/adstream_sx.ads/$script,domain=businessweek.com|economist.com|feedroom.com|stanford.edu
-@@||oascentral.surfline.com/realmedia/ads/adstream_sx.ads/www.surfline.com/articles$object_subrequest
-@@||objects.tremormedia.com/embed/js/$domain=bostonherald.com|deluxetelevision.com
-@@||objects.tremormedia.com/embed/swf/acudeoplayer.swf$domain=bostonherald.com|deluxetelevision.com
-@@||objects.tremormedia.com/embed/swf/admanager*.swf
-@@||objects.tremormedia.com/embed/xml/*.xml?r=$object_subrequest,domain=mydamnchannel.com
-@@||omgili.com/ads.search?
-@@||omnikool.discovery.com/realmedia/ads/adstream_mjx.ads/dsc.discovery.com/$script
-@@||onionstatic.com^*/videoads.js
-@@||pagead2.googlesyndication.com/pagead/*/show_ads_impl.js$domain=gameserver.n4cer.de|omegadrivers.net|upfordown.com
-@@||pagead2.googlesyndication.com/pagead/ads?client=$subdocument,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||pagead2.googlesyndication.com/pagead/expansion_embed.js$domain=artificialvision.com|gameserver.n4cer.de|gpxplus.net|metamodal.com|myspace.com|seeingwithsound.com|upfordown.com
-@@||pagead2.googlesyndication.com/pagead/scache/show_invideo_ads.js$domain=sciencedaily.com
-@@||pagead2.googlesyndication.com/pagead/show_ads.js$domain=articlewagon.com|artificialvision.com|gameserver.n4cer.de|gpxplus.net|metamodal.com|myspace.com|omegadrivers.net|seeingwithsound.com|spreadlink.us|upfordown.com|warp2search.net
-@@||pagead2.googlesyndication.com/pagead/static?format=in_video_ads&$elemhide,subdocument
-@@||partner.googleadservices.com/gampad/google_ads.js$domain=avclub.com
-@@||partner.googleadservices.com/gampad/google_service.js$domain=avclub.com
-@@||partners.thefilter.com/crossdomain.xml$object_subrequest,domain=dailymotion.com|dailymotion.virgilio.it
-@@||partners.thefilter.com/dailymotionservice/$image,object_subrequest,script,domain=dailymotion.com|dailymotion.virgilio.it
-@@||pix04.revsci.net^*/pcx.js?$script,domain=foxbusiness.com|foxnews.com
-@@||player.grabnetworks.com^*/vox_300x250_inline.xml$domain=mavrixonline.com
-@@||pressdisplay.com/advertising/showimage.aspx?
-@@||promo2.tubemogul.com/adtags/slim_no_iframe.js$domain=comedy.com
-@@||promo2.tubemogul.com/flash/youtube.swf$domain=comedy.com
-@@||promo2.tubemogul.com/lib/tubemoguldisplaylib.js$domain=comedy.com
-@@||quit.org.au/images/images/ad/
-@@||redir.adap.tv/redir/client/adplayer.swf$domain=cracked.com|egreetings.com|ehow.com|imgag.com|videosift.com|xxlmag.com
-@@||redir.adap.tv/redir/client/static/as3adplayer.swf$domain=king5.com|kptv.com|mavrixonline.com|newsinc.com|stickam.com|videosift.com|wkbw.com
-@@||redir.adap.tv/redir/javascript/adaptvadplayer.js$object_subrequest,domain=imgag.com
-@@||redir.adap.tv/redir/plugins/*/adotubeplugin.swf?$domain=stickam.com
-@@||rosauers.com/locations/ads.html
-@@||rotate.infowars.com/www/delivery/fl.js
-@@||rotate.infowars.com/www/delivery/spcjs.php
-@@||sam.itv.com/xtserver/acc_random=*.video.preroll/seg=$object_subrequest
-@@||sankakucomplex.com^$script
-@@||sankakustatic.com^$script
-@@||scorecardresearch.com/beacon.js$domain=deviantart.com
-@@||search.excite.co.uk/minify.php?files*/css/feed/adsearch.css
-@@||seesaw.com/cp/c4/realmedia/ads/adstream_sx.ads/$xmlhttprequest
-@@||serve.vdopia.com/adserver/ad*.php$object_subrequest,script,xmlhttprequest
-@@||server.cpmstar.com/adviewas3.swf?contentspotid=$object_subrequest,domain=armorgames.com|freewebarcade.com|gamesforwork.com
-@@||server.cpmstar.com/view.aspx?poolid=$domain=newgrounds.com
-@@||sfx-images.mozilla.org^$image,domain=spreadfirefox.com
-@@||shackvideo.com/playlist_xml.x?
-@@||sharehoster.com/design/advertise/premium_*_divx.png
-@@||smartadserver.com/call/pubj/*/affiliate_id$script,domain=deezer.com
-@@||smartadserver.com/def/def/showdef.asp$domain=deezer.com
-@@||smartclip.net/delivery/tag?sid=$script,domain=last.fm
-@@||sonicstate.com/video/hd/hdconfig-geo.cfm?*/www/delivery/$object_subrequest
-@@||southparkstudios.com/layout/common/js/reporting/mtvi_ads_reporting.js
-@@||southparkstudios.com/layout/common/js/reporting/mtvi_ads_reporting_config.js
-@@||spotrails.com/crossdomain.xml$object_subrequest
-@@||spotrails.com^*/flowplayeradplayerplugin.swf
-@@||spotxchange.com/flash/adplayer.swf$domain=boxlive.tv
-@@||spotxchange.com/media/videos/flash/ad_player/$domain=boxlive.tv
-@@||startxchange.com/textad.php?$xmlhttprequest
-@@||static.2mdn.net^*.xml$object_subrequest,domain=photoradar.com|youtube.com
-@@||static.ak.fbcdn.net^*/ads/$script
-@@||static.linkbucks.com^$script,stylesheet,domain=zxxo.net
-@@||static.scanscout.com/ads/are3.swf$domain=failblog.org|icanhascheezburger.com
-@@||streaming.gmgradio.com/adverts/*.mp3$object_subrequest
-@@||superfundo.org/advertisement.js
-@@||telegraphcouk.skimlinks.com/api/telegraph.skimlinks.js
-@@||thefrisky.com/js/adspaces.min.js
-@@||thekraftgroup.com/ad.cfc?*&key=prerollvideo.*,midrollvideo.$object_subrequest,domain=patriots.com
-@@||thekraftgroup.com/crossdomain.xml$object_subrequest,domain=patriots.com
-@@||thenewsroom.com^*/advertisement.xml$object_subrequest
-@@||theonion.com/ads/video-ad/$object_subrequest,xmlhttprequest
-@@||theonion.com^*/videoads.js
-@@||thestreet.com/js/ads/adplacer.js
-@@||timeinc.net/people/static/i/advertising/getpeopleeverywhere-*$background,domain=people.com|peoplestylewatch.com
-@@||timeinc.net^*/tii_ads.js$domain=ew.com
-@@||trutv.com/includes/banners/de/video/*.ad|$object_subrequest
-@@||turner.com^*/advertisement/cnnmoney_sponsors.gif$domain=money.cnn.com
-@@||tvgorge.com^*/adplayer.swf
-@@||tvnz.co.nz/stylesheets/tvnz/lib/js/advertisement.js
-@@||twitvid.com/mediaplayer_*.swf?
-@@||ultrabrown.com/images/adheader.jpg
-@@||upload.wikimedia.org/wikipedia/
-@@||utarget.co.uk/crossdomain.xml$object_subrequest,domain=tvcatchup.com
-@@||vancouversun.com/js/adsync/adsynclibrary.js
-@@||video-cdn.abcnews.com/ad_$object_subrequest
-@@||video.nbcuni.com/outlet/extensions/inext_ad_engine/ad_engine_extension.swf
-@@||videoads.washingtonpost.com^$object_subrequest,domain=slatev.com
-@@||vidtech.cbsinteractive.com/plugins/*_adplugin.swf
-@@||vindicoasset.edgesuite.net/repository/campaigncreative/*/instreamad/$domain=shackvideo.com
-@@||vortex.accuweather.com/adc2004/pub/ads/js/ads-2006_vod.js
-@@||vox-static.liverail.com/swf/*/admanager.swf
-@@||vtstage.cbsinteractive.com/plugins/*_adplugin.swf
-@@||we7.com/api/streaming/advert-info?*&playsource=$object_subrequest
-@@||weather.com/common/a2/oasadframe.html?position=pagespon
-@@||weather.com/common/a2/oasadframe.html?position=pointspon
-@@||widget.slide.com^*/ads/*/preroll.swf
-@@||wikimedia.org^$elemhide
-@@||wikipedia.org^$elemhide
-@@||wrapper.teamxbox.com/a?size=headermainad&altlocdir=teamxbox$script
-@@||www.google.*/search?$subdocument
-@@||yallwire.com/pl_ads.php?$object_subrequest
-@@||yimg.com^*&yat/js/ads_
-@@||yimg.com^*/java/promotions/js/ad_eo_1.1.js
-@@||zedo.com/*.swf$domain=rajshri.com
-@@||zedo.com/*.xml$object_subrequest,domain=rajshri.com
-@@||zedo.com//$object_subrequest,domain=rajshri.com
-!Anti-Adblock
-@@/_468.gif$domain=seeingwithsound.com
-@@/_728.gif$domain=seeingwithsound.com
-@@/_728_90.$image,domain=seeingwithsound.com
-@@/_728x90.$image,domain=seeingwithsound.com
-@@_728by90.$image,domain=seeingwithsound.com
-@@||195.241.77.82^$image,domain=seeingwithsound.com
-@@||212.115.192.168^$image,domain=seeingwithsound.com
-@@||216.97.231.225^$domain=seeingwithsound.com
-@@||84.243.214.232^$image,domain=seeingwithsound.com
-@@||akihabaranews.com/images/ad/
-@@||artificialvision.com^$elemhide,image,script
-@@||arto.com/includes/js/adtech.de/script.axd/adframe.js?
-@@||avforums.com/forums/adframe.js
-@@||cinshare.com/js/embed.js?*=http://adserving.cpxinteractive.com/?
-@@||content.ytmnd.com/assets/js/a/adx.js
-@@||dailykos.com/ads/adblocker.blogads.css
-@@||dropbox.com^$image,script,domain=seeingwithsound.com
-@@||eq2flames.com/adframe.js
-@@||funkyfun.altervista.org/adsense.js$domain=livevss.net
-@@||gdataonline.com/exp/textad.js
-@@||googlepages.com^$image,script,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||gpxplus.net^$elemhide
-@@||hackers.co.id/adframe/adframe.js
-@@||hardforum.com^*/adframe.js
-@@||home.tiscali.nl^$domain=seeingwithsound.com
-@@||livevss.net/adsense.js
-@@||lunarpages.com^$image,script,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||macobserver.com/js/adlink.js
-@@||metamodal.com^$elemhide,image,script
-@@||multi-load.com/peel.js$domain=multi-load.com
-@@||multiup.org/advertisement.js
-@@||ninjaraider.com/ads/$script
-@@||ninjaraider.com/adsense/$script
-@@||novamov.com/ads.js?*&ad_url=/adbanner
-@@||nwanime.com^$script
-@@||onlinevideoconverter.com/scripts/advertisement.js
-@@||pagead2.googlesyndication.com/pagead/render_ads.js$domain=seeingwithsound.com
-@@||photobucket.com^$image,domain=seeingwithsound.com
-@@||ratebeer.com/javascript/advertisement.js
-@@||seeingwithsound.cn^$image,script,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||seeingwithsound.com^$elemhide,image,script
-@@||sharejunky.com/adserver/$script
-@@||showme-myip.com^*/advertisement.js
-@@||sites.google.com/site/$image,script,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||sportsm8.com/adsense.js
-@@||spreadlink.us/advertisement.js
-@@||succesfactoren.nl^$image,domain=seeingwithsound.com
-@@||teknogods.com/advert.js
-@@||theteacherscorner.net/adlayer/$script
-@@||tpmrpg.net/adframe.js
-@@||visualprosthesis.com^$image,script,domain=artificialvision.com|metamodal.com|seeingwithsound.com
-@@||zshare.net/ads.js?*&ad_url=/adbanner
-!Non-English
-@@||24ur.com/adserver/adall.php?*&video_on_page=1
-@@||ads.globo.com/crossdomain.xml$object_subrequest
-@@||ads.globo.com/realmedia/ads/adstream_jx.ads/$object_subrequest,domain=globo.com
-@@||adser.localport.it/banman.asp?zoneid=71$subdocument
-@@||adtech.de/?adrawdata/3.0/*;|$object_subrequest,domain=nelonen.fi|radiorock.fi|tv2.dk
-@@||adtech.panthercustomer.com^*.flv$domain=tv3.ie
-@@||afterdark-nfs.com/ad/$background,image,script,stylesheet
-@@||aka-cdn-ns.adtech.de^*.flv$domain=tv3.ie
-@@||alimama.cn/taobaocdn/css/s8.css$domain=taobao.com
-@@||amarillas.cl/advertise.do?$xmlhttprequest
-@@||amarillas.cl/js/advertise/$script
-@@||autoscout24.*/all.js.aspx?m=css&*=/stylesheets/adbanner.css
-@@||banneradmin.rai.it/js.ng/sezione_rai=barramenu$script
-@@||bnrs.ilm.ee/www/delivery/fl.js
-@@||cpalead.com/mygateway.php?pub=$script,domain=serialnumber.in|spotifyripping.com|stumblehere.com|videodownloadx.com|yourpcmovies.net
-@@||e-planning.net/eb/*?*fvp=2&$object_subrequest,domain=clarin.com|emol.com
-@@||ebayrtm.com/rtm?$script,domain=annonces.ebay.fr|ebay.it
-@@||fokzine.net/templates/$script,domain=fok.nl
-@@||forolockerz.com/advertisement.js
-@@||fotojorgen.no/images/*/webadverts/
-@@||fusion.adtoma.com/*.flv$domain=expressen.se
-@@||hry.cz/ad/adcode.js
-@@||img.deniksport.cz/css/reklama.css?
-@@||mail.bg/mail/index/getads/$xmlhttprequest
-@@||nextmedia.com/admedia/$object_subrequest
-@@||ninjaraider.com^*/adsense.js
-@@||openx.motomedia.nl/live/www/delivery/$script
-@@||openx.zomoto.nl/live/www/delivery/fl.js
-@@||openx.zomoto.nl/live/www/delivery/spcjs.php?id=
-@@||pagead2.googlesyndication.com/pagead/*/show_ads_impl.js$domain=fok.nl
-@@||pagead2.googlesyndication.com/pagead/abglogo/abg-da-100c-000000.png$domain=janno.dk|nielco.dk
-@@||pagead2.googlesyndication.com/pagead/show_ads.js$domain=fok.nl
-@@||ping.indieclicktv.com/www/delivery/ajs.php?zoneid=$object_subrequest,domain=penny-arcade.com
-@@||ring.bg/adserver/adall.php?*&video_on_page=1
-@@||static.mobile.eu^*/resources/images/ads/superteaser_$image,domain=automobile.fr|automobile.it|mobile.eu|mobile.ro
-@@||style.seznam.cz/ad/im.js
-@@||uol.com.br/html.ng/*&affiliate=$object_subrequest
-@@||video1.milanofinanza.it/movie/movie/adserver_$object,object_subrequest
-@@||videos.lanacion.com.ar^*/xml/publicidad/$object
-@@||virpl.ru^*_advert.php$xmlhttprequest,domain=virpl.ru
diff --git a/mochitest/tests/performance/data/testpages.jar b/mochitest/tests/performance/data/testpages.jar
deleted file mode 100644
index 2d3f73a..0000000
Binary files a/mochitest/tests/performance/data/testpages.jar and /dev/null differ
diff --git a/mochitest/tests/performance/elemhide_selectors.html b/mochitest/tests/performance/elemhide_selectors.html
deleted file mode 100644
index 8aecb44..0000000
--- a/mochitest/tests/performance/elemhide_selectors.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Element hiding performance measurements</title>
-
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
-</head>
-<body>
- <p id="progress">Please wait while performance measurement is in progress... <span id="current"></span></p>
-
- <iframe id="frame" onload="runNextTest();" style="visibility: hidden;height: 0px;"></iframe>
-
- <pre id="result"></pre>
-
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
- preparePrefs();
-
- let selectors = ['#foo', '.foo', '*#foo', '*.foo', '[id="foo"]', '*[id="foo"]', '[class~="foo"]', '*[class~="foo"]', '[id^="foo"]', '[id*="foo"]', '[id$="foo"]'];
- let currentSelector = -1;
- let count = 1000;
- let startTime;
- let results = [];
-
- window.addEventListener("load", runNextTest, false);
-
- function runNextTest()
- {
- if (currentSelector >= 0)
- {
- if (!(count in results))
- results[count] = [];
-
- results[count].push(Date.now() - startTime);
- }
-
- if (count >= 1000)
- {
- currentSelector++;
- if (currentSelector >= selectors.length)
- {
- let resultText = "# rule_count " + selectors.join(" ") + "\n";
- for (let i = 0; i < results.length; i++)
- if (i in results)
- resultText += i + " " + results[i].join(" ") + "\n";
-
- document.getElementById("result").textContent = resultText;
- document.getElementById("progress").style.display = "none";
- }
- else
- document.getElementById("current").textContent = "Processing selector " + (currentSelector + 1) + " out of " + selectors.length;
-
- count = 0;
- ElemHide.clear();
- }
- else
- {
- let max = count + 50;
- for (; count < max; count++)
- ElemHide.add(Filter.fromText("mochikit##" + selectors[currentSelector].replace("foo", "foo" + count)));
- }
- ElemHide.apply();
-
- startTime = Date.now();
- document.getElementById("frame").contentWindow.location.href = "data/elemhide_selectors_testdata.html";
- }
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/filter_fromText.html b/mochitest/tests/performance/filter_fromText.html
deleted file mode 100644
index 9a59f57..0000000
--- a/mochitest/tests/performance/filter_fromText.html
+++ /dev/null
@@ -1,67 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter initialization performance measurements</title>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
-</head>
-<body>
- <p>
- Filters to be used:<br>
- <textarea id="filters" style="width: 100%; height: 300px;"></textarea><br>
- <button id="startButton" onclick="start();">Click to start test</button>
- </p>
-
- <p id="progress" style="display: none;">Please wait while performance measurement is in progress... <span id="current"></span></p>
-
- <pre id="result"></pre>
-
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- let filters = null;
-
- window.onload = function()
- {
- let r = new XMLHttpRequest();
- r.open("GET", "data/filters.txt", false);
- r.overrideMimeType("text/plain");
- r.send(null);
- document.getElementById("filters").value = r.responseText;
- }
-
- function start()
- {
- document.getElementById("filters").disabled = true;
- document.getElementById("startButton").disabled = true;
- filters = document.getElementById("filters").value.replace(/^[\r\n]+/, "")
- .replace(/[\r\n]+$/, "")
- .split(/[\r\n]+/);
- document.getElementById("result").textContent = "";
- document.getElementById("progress").style.display = "";
-
- runTests(runTest, cleanup, finalize);
- }
-
- function runTest()
- {
- for each (let text in filters)
- Filter.fromText(text);
- }
-
- function cleanup()
- {
- // Clear cache
- Filter.knownFilters = {__proto__: null};
- }
-
- function finalize()
- {
- document.getElementById("progress").style.display = "none";
- document.getElementById("filters").disabled = false;
- document.getElementById("startButton").disabled = false;
- filters = null;
- }
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/matcher_init.html b/mochitest/tests/performance/matcher_init.html
deleted file mode 100644
index 4ad761f..0000000
--- a/mochitest/tests/performance/matcher_init.html
+++ /dev/null
@@ -1,71 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Matcher initialization performance measurements</title>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
-</head>
-<body>
- <p>
- Filters to be used:<br>
- <textarea id="filters" style="width: 100%; height: 300px;"></textarea><br>
- <button id="startButton" onclick="start();">Click to start test</button>
- </p>
-
- <p id="progress" style="display: none;">Please wait while performance measurement is in progress... <span id="current"></span></p>
-
- <pre id="result"></pre>
-
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- let filters = null;
-
- window.onload = function()
- {
- let r = new XMLHttpRequest();
- r.open("GET", "data/filters.txt", false);
- r.overrideMimeType("text/plain");
- r.send(null);
- document.getElementById("filters").value = r.responseText;
- }
-
- function start()
- {
- document.getElementById("filters").disabled = true;
- document.getElementById("startButton").disabled = true;
- filters = document.getElementById("filters").value.replace(/^[\r\n]+/, "")
- .replace(/[\r\n]+$/, "")
- .split(/[\r\n]+/)
- .map(function(text) Filter.fromText(text))
- .filter(function(filter) filter instanceof RegExpFilter);
- document.getElementById("filters").value = filters.map(function(filter) filter.text)
- .join("\n");
- document.getElementById("result").textContent = "";
- document.getElementById("progress").style.display = "";
-
- runTests(runTest, cleanup, finalize);
- }
-
- function runTest()
- {
- // Add everything to the same matcher, don't bother separating whitelist and blacklist
- let matcher = new CombinedMatcher();
- for each (let filter in filters)
- matcher.add(filter);
- }
-
- function cleanup()
- {
- }
-
- function finalize()
- {
- document.getElementById("progress").style.display = "none";
- document.getElementById("filters").disabled = false;
- document.getElementById("startButton").disabled = false;
- filters = null;
- }
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/matching.html b/mochitest/tests/performance/matching.html
deleted file mode 100644
index 1f6ea6b..0000000
--- a/mochitest/tests/performance/matching.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter matching performance measurements</title>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
-</head>
-<body>
- <p>
- Filters to be used:<br>
- <textarea id="filters" style="width: 100%; height: 150px;"></textarea><br>
-
- Addresses to check:<br>
- <textarea id="addresses" style="width: 100%; height: 150px;"></textarea><br>
- <button id="startButton" onclick="start();">Click to start test</button>
- </p>
-
- <p id="progress" style="display: none;">Please wait while performance measurement is in progress... <span id="current"></span></p>
-
- <pre id="result"></pre>
-
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- let filters = null;
- let addresses = null;
-
- window.onload = function()
- {
- let r = new XMLHttpRequest();
- r.open("GET", "data/filters.txt", false);
- r.overrideMimeType("text/plain");
- r.send(null);
- document.getElementById("filters").value = r.responseText;
-
- r = new XMLHttpRequest();
- r.open("GET", "data/addresses.txt", false);
- r.overrideMimeType("text/plain");
- r.send(null);
- document.getElementById("addresses").value = r.responseText;
- }
-
- function start()
- {
- document.getElementById("filters").disabled = true;
- document.getElementById("addresses").disabled = true;
- document.getElementById("startButton").disabled = true;
- filters = document.getElementById("filters").value.replace(/^[\r\n]+/, "")
- .replace(/[\r\n]+$/, "")
- .split(/[\r\n]+/)
- .map(function(text) Filter.fromText(text))
- .filter(function(filter) filter instanceof RegExpFilter);
- document.getElementById("filters").value = filters.map(function(filter) filter.text)
- .join("\n");
- addresses = document.getElementById("addresses").value.replace(/^[\r\n]+/, "")
- .replace(/[\r\n]+$/, "")
- .split(/[\r\n]+/);
- document.getElementById("result").textContent = "";
- document.getElementById("progress").style.display = "";
-
- defaultMatcher.clear();
- for each (let filter in filters)
- defaultMatcher.add(filter);
-
- runTests(runTest, cleanup, finalize);
- }
-
- function runTest()
- {
- for each (let address in addresses)
- defaultMatcher.matchesAny(address, "IMAGE", null, false);
- }
-
- function cleanup()
- {
- // Add and remove a dummy filter to clear matcher's cache
- let dummy = Filter.fromText("foobar");
- defaultMatcher.add(dummy);
- defaultMatcher.remove(dummy);
- }
-
- function finalize()
- {
- document.getElementById("progress").style.display = "none";
- document.getElementById("filters").disabled = false;
- document.getElementById("addresses").disabled = false;
- document.getElementById("startButton").disabled = false;
- filters = null;
- addresses = null;
- }
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/memory_use1.html b/mochitest/tests/performance/memory_use1.html
deleted file mode 100644
index f21f6d5..0000000
--- a/mochitest/tests/performance/memory_use1.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Memory use while an image with the same address is being created continuously</title>
- <script type="application/x-javascript;version=1.7" src="../../httpd.js"></script>
-</head>
-<body>
- <p>This page will continuously create new images with the same address and throw them away. Adblock Plus should let garbage collection do its job and the browser's memory use shouldn't increase while this page is open.</p>
-
- <iframe id="frame" style="visibility: visible;"></iframe>
-
- <script type="application/x-javascript;version=1.7">
- function start()
- {
- window.addEventListener("unload", stop, false);
- server.start(1234);
-
- setInterval(function()
- {
- window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils)
- .garbageCollect();
- }, 100);
-
- server.registerPathHandler("/test", function(metadata, response)
- {
- response.setStatusLine("1.1", "200", "OK");
- response.setHeader("Content-Type", "text/html");
-
- let body = "<script>setInterval(function() { new Image().src = 'test.png'; }, 0);</" + "script>";
- response.bodyOutputStream.write(body, body.length);
- });
-
- document.getElementById("frame").src = "http://127.0.0.1:1234/test";
- }
-
- function stop()
- {
- server.stop();
- }
-
- let server = new nsHttpServer();
- window.addEventListener("load", start, false);
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/memory_use2.html b/mochitest/tests/performance/memory_use2.html
deleted file mode 100644
index 2a90678..0000000
--- a/mochitest/tests/performance/memory_use2.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Memory use while images with different addresses are being created continuously</title>
- <script type="application/x-javascript;version=1.7" src="../../httpd.js"></script>
-</head>
-<body>
- <p>This page will continuously create new images with different addresses and throw them away. This will make the memory use grow but it should reach a stable point after a few minutes where a certain limit is no longer exceeded. Also, old entries should disappear from the list of blockable items after a minute.</p>
-
- <iframe id="frame" style="visibility: visible;"></iframe>
-
- <script type="application/x-javascript;version=1.7">
- function start()
- {
- window.addEventListener("unload", stop, false);
- server.start(1234);
-
- setInterval(function()
- {
- window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindowUtils)
- .garbageCollect();
- }, 100);
-
- server.registerPathHandler("/test", function(metadata, response)
- {
- response.setStatusLine("1.1", "200", "OK");
- response.setHeader("Content-Type", "text/html");
-
- let body = "<script>var i = 0; setInterval(function() { new Image().src = 'test' + (++i) + '.png'; }, 0);</" + "script>";
- response.bodyOutputStream.write(body, body.length);
- });
-
- document.getElementById("frame").src = "http://127.0.0.1:1234/test";
- }
-
- function stop()
- {
- server.stop();
- }
-
- let server = new nsHttpServer();
- window.addEventListener("load", start, false);
- </script>
-</body>
-</html>
diff --git a/mochitest/tests/performance/page_load_overhead.html b/mochitest/tests/performance/page_load_overhead.html
deleted file mode 100644
index 5475311..0000000
--- a/mochitest/tests/performance/page_load_overhead.html
+++ /dev/null
@@ -1,133 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Page load overhead measurement (no filters)</title>
- <script type="application/x-javascript;version=1.7" src="../../httpd.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
-</head>
-<body>
- <p>
- <input type="checkbox" id="enableABP" checked="checked" onclick="if (!this.disabled) document.getElementById('filters').disabled = !this.checked;">
- <label for="enableABP">Enable Adblock Plus processing</label><br>
- Filters to be used:<br>
- <textarea id="filters" style="width: 100%; height: 300px;"></textarea><br>
- <button id="startButton" onclick="start();">Click to start test</button>
- </p>
-
- <p id="progress" style="display: none;">Please wait while performance measurement is in progress... <span id="current"></span></p>
-
- <pre id="result"></pre>
-
- <script type="application/x-javascript;version=1.7">
- Cu.import(baseURL.spec + "Utils.jsm");
- Cu.import(baseURL.spec + "ContentPolicy.jsm");
- var PolicyPrivate = Cu.import(baseURL.spec + "ContentPolicy.jsm", null).PolicyPrivate;
-
- prepareFilterComponents();
-
- let thread = Utils.threadManager.currentThread;
- let server = new nsHttpServer();
- server.registerContentType("jar", "application/java-archive");
-
- {
- // Register data directory as server root
- let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
- let dataURL = Utils.ioService.newURI("data/", null, chromeRegistry.convertChromeURL(Utils.makeURI(location.href)));
- server.registerDirectory("/", dataURL.QueryInterface(Ci.nsIFileURL).file);
- }
-
- window.addEventListener("unload", function()
- {
- Policy.startup();
- server.stop();
- }, false);
-
- let urls = [];
- for (let i = 1; i <= 5; i++)
- urls.push("jar:http://127.0.0.1:1234/testpages.jar!/testpage" + i + ".html");
- urls.push("about:blank");
-
- window.onload = function()
- {
- let r = new XMLHttpRequest();
- r.open("GET", "data/filters.txt", false);
- r.overrideMimeType("text/plain");
- r.send(null);
- document.getElementById("filters").value = r.responseText;
- }
-
- function start()
- {
- document.getElementById("enableABP").disabled = true;
- document.getElementById("filters").disabled = true;
- document.getElementById("startButton").disabled = true;
- document.getElementById("result").textContent = "";
- document.getElementById("progress").style.display = "";
-
- if (document.getElementById("enableABP").checked)
- {
- let filters = document.getElementById("filters").value.replace(/^[\r\n]+/, "")
- .replace(/[\r\n]+$/, "")
- .split(/[\r\n]+/)
- .map(function(text) Filter.fromText(text));
- for each (let filter in filters)
- {
- if (filter instanceof RegExpFilter)
- defaultMatcher.add(filter);
- else if (filter instanceof ElemHideFilter)
- ElemHide.add(filter);
- }
- ElemHide.apply();
- }
- else
- {
- for each (let category in PolicyPrivate.xpcom_categories)
- Utils.categoryManager.deleteCategoryEntry(category, PolicyPrivate.classDescription, false);
- }
-
- server.start(1234);
-
- runTests(runTest, null, finalize);
- }
-
- function runTest()
- {
- let frame = document.getElementById("frame");
-
- let loaded;
- let eventListener = function() {loaded = true;};
- frame.addEventListener("load", eventListener, false);
-
- for each (let url in urls)
- {
- loaded = false;
- frame.src = url;
- while (!loaded)
- thread.processNextEvent(true);
- }
-
- frame.removeEventListener("load", eventListener, false);
- }
-
- function finalize()
- {
- defaultMatcher.clear();
- ElemHide.clear();
-
- server.stop();
-
- for each (let category in PolicyPrivate.xpcom_categories)
- Utils.categoryManager.addCategoryEntry(category, PolicyPrivate.classDescription, PolicyPrivate.contractID, false, true);
-
- document.getElementById("progress").style.display = "none";
- document.getElementById("enableABP").disabled = false;
- document.getElementById("filters").disabled = !document.getElementById("enableABP").checked;
- document.getElementById("startButton").disabled = false;
- }
- </script>
-
- <iframe id="frame" src="about:blank" style="visibility: hidden"></iframe>
-
-</body>
-</html>
diff --git a/mochitest/tests/test_domainRestrictions.html b/mochitest/tests/test_domainRestrictions.html
deleted file mode 100644
index c1e3955..0000000
--- a/mochitest/tests/test_domainRestrictions.html
+++ /dev/null
@@ -1,116 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Tests for domain-restricted filters</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <meta http-equiv="Content-Type" value="text/html; charset=utf-8"/>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- function testActive(text, domain, expectedActive, expectedOnlyDomain)
- {
- let filter = Filter.fromText(text);
- is(filter.isActiveOnDomain(domain), expectedActive, text + " active on " + domain);
- is(filter.isActiveOnlyOnDomain(domain), expectedOnlyDomain, text + " only active on " + domain);
- }
-
- testActive("foo", null, true, false);
- testActive("foo", "com", true, false);
- testActive("foo", "example.com", true, false);
- testActive("foo", "foo.example.com", true, false);
- testActive("foo", "mple.com", true, false);
-
- testActive("#foo", null, true, false);
- testActive("#foo", "com", true, false);
- testActive("#foo", "example.com", true, false);
- testActive("#foo", "foo.example.com", true, false);
- testActive("#foo", "mple.com", true, false);
-
- testActive("foo$domain=example.com", null, false, false);
- testActive("foo$domain=example.com", "com", false, true);
- testActive("foo$domain=example.com", "example.com", true, true);
- testActive("foo$domain=example.com", "foo.example.com", true, false);
- testActive("foo$domain=example.com", "mple.com", false, false);
-
- testActive("example.com#foo", null, false, false);
- testActive("example.com#foo", "com", false, true);
- testActive("example.com#foo", "example.com", true, true);
- testActive("example.com#foo", "foo.example.com", true, false);
- testActive("example.com#foo", "mple.com", false, false);
-
- testActive("foo$domain=example.com|foo.example.com", null, false, false);
- testActive("foo$domain=example.com|foo.example.com", "com", false, true);
- testActive("foo$domain=example.com|foo.example.com", "example.com", true, true);
- testActive("foo$domain=example.com|foo.example.com", "foo.example.com", true, false);
- testActive("foo$domain=example.com|foo.example.com", "mple.com", false, false);
-
- testActive("example.com,foo.example.com#foo", null, false, false);
- testActive("example.com,foo.example.com#foo", "com", false, true);
- testActive("example.com,foo.example.com#foo", "example.com", true, true);
- testActive("example.com,foo.example.com#foo", "foo.example.com", true, false);
- testActive("example.com,foo.example.com#foo", "mple.com", false, false);
-
- testActive("foo$domain=~foo.example.com", null, true, false);
- testActive("foo$domain=~foo.example.com", "com", true, false);
- testActive("foo$domain=~foo.example.com", "example.com", true, false);
- testActive("foo$domain=~foo.example.com", "foo.example.com", false, false);
- testActive("foo$domain=~foo.example.com", "mple.com", true, false);
-
- testActive("~foo.example.com#foo", null, true, false);
- testActive("~foo.example.com#foo", "com", true, false);
- testActive("~foo.example.com#foo", "example.com", true, false);
- testActive("~foo.example.com#foo", "foo.example.com", false, false);
- testActive("~foo.example.com#foo", "mple.com", true, false);
-
- testActive("foo$domain=example.com|~foo.example.com", null, false, false);
- testActive("foo$domain=example.com|~foo.example.com", "com", false, true);
- testActive("foo$domain=example.com|~foo.example.com", "example.com", true, true);
- testActive("foo$domain=example.com|~foo.example.com", "foo.example.com", false, false);
- testActive("foo$domain=example.com|~foo.example.com", "mple.com", false, false);
-
- testActive("example.com,~foo.example.com#foo", null, false, false);
- testActive("example.com,~foo.example.com#foo", "com", false, true);
- testActive("example.com,~foo.example.com#foo", "example.com", true, true);
- testActive("example.com,~foo.example.com#foo", "foo.example.com", false, false);
- testActive("example.com,~foo.example.com#foo", "mple.com", false, false);
-
- testActive("foo$domain=example.com|~com", null, false, false);
- testActive("foo$domain=example.com|~com", "com", false, true);
- testActive("foo$domain=example.com|~com", "example.com", true, true);
- testActive("foo$domain=example.com|~com", "foo.example.com", true, false);
- testActive("foo$domain=example.com|~com", "mple.com", false, false);
-
- testActive("example.com,~com#foo", null, false, false);
- testActive("example.com,~com#foo", "com", false, true);
- testActive("example.com,~com#foo", "example.com", true, true);
- testActive("example.com,~com#foo", "foo.example.com", true, false);
- testActive("example.com,~com#foo", "mple.com", false, false);
-
- testActive("foo$domain=nnnnnnn.nnn", null, false, false);
- testActive("foo$domain=nnnnnnn.nnn", "com", false, false);
- testActive("foo$domain=nnnnnnn.nnn", "example.com", false, false);
- testActive("foo$domain=nnnnnnn.nnn", "foo.example.com", false, false);
- testActive("foo$domain=nnnnnnn.nnn", "mple.com", false, false);
-
- testActive("nnnnnnn.nnn#foo", null, false, false);
- testActive("nnnnnnn.nnn#foo", "com", false, false);
- testActive("nnnnnnn.nnn#foo", "example.com", false, false);
- testActive("nnnnnnn.nnn#foo", "foo.example.com", false, false);
- testActive("nnnnnnn.nnn#foo", "mple.com", false, false);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_elemhide.html b/mochitest/tests/test_elemhide.html
deleted file mode 100644
index b21f3da..0000000
--- a/mochitest/tests/test_elemhide.html
+++ /dev/null
@@ -1,157 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Element hiding tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="../httpd.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="visibility: hidden;">
- <iframe id="frame" onload="runNextTest()"></iframe>
- </div>
-
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
- preparePrefs();
-
- let tests = [
- [[], "visible visible"],
- [["#div(test1)"], "hidden visible"],
- [["localhost#div(test1)"], "hidden visible"],
- [["localhost#div(test1)", "foo,foo2#p(test2)"], "hidden visible"],
- [["localhost,foo#div(test1)", "foo,localhost#p(test2)"], "hidden hidden"],
- [["localhost#div(test1)", "localhost#p(test2)"], "hidden hidden"],
- [["foo#div(test1)", "foo#p(test2)"], "visible visible"],
-
- [["localhost#div(testClass)"], "hidden visible"],
- [["localhost#p(testClass)"], "visible hidden"],
- [["localhost#*(testClass)"], "hidden hidden"],
- [["localhost#div(testClass)", "localhost#p(test2)"], "hidden hidden"],
- [["localhost#p(testClass)", "localhost#p(test2)"], "visible hidden"],
- [["localhost#p(testClass)(test2)"], "visible visible"], // this filter is invalid, must be ignored
-
- [["localhost#*(id^=test)"], "hidden hidden"],
- [["localhost#p(id^=test)"], "visible hidden"],
- [["localhost#*(id$=2)"], "visible hidden"],
- [["localhost#p(id$=2)"], "visible hidden"],
- [["localhost#div(id$=2)"], "visible visible"],
-
- [["localhost#*(test1)(id^=test)"], "hidden visible"],
- [["localhost#*(testClass)(id^=test)"], "hidden hidden"],
- [["localhost#p(testClass)(id^=test)"], "visible hidden"],
- [["localhost#*(test1)(id$=2)"], "visible visible"],
- [["localhost#*(testClass)(id$=2)"], "visible hidden"],
- [["localhost#p(testClass)(id$=2)"], "visible hidden"],
-
- [["localhost#*(test1)(id^=test)(id$=2)"], "visible visible"],
- [["localhost#*(test1)(id^=test)(id$=1)"], "hidden visible"],
- [["localhost#p(test1)(id^=test)(id$=1)"], "visible visible"],
- [["localhost#div(test1)(id^=test)(id$=1)"], "hidden visible"],
- [["localhost#*(id^=test)(id$=2)"], "visible hidden"],
- [["localhost#*(id^=test)(id$=1)"], "hidden visible"],
- [["localhost#p(id^=test)(id$=1)"], "visible visible"],
- [["localhost#div(id^=test)(id$=1)"], "hidden visible"],
-
- [["localhost##div#test1"], "hidden visible"],
- [["localhost##p.testClass"], "visible hidden"],
- [["localhost##div#test1, p.testClass"], "hidden hidden"],
- [["localhost##div#test1", "localhost##p.testClass"], "hidden hidden"],
- [["localhost##.testClass"], "hidden hidden"],
-
- [["~localhost##div#test1"], "visible visible"],
- [["foo,~localhost##div#test1"], "visible visible"],
- [["localhost,~foo##div#test1"], "hidden visible"],
- ];
- let currentTest = -1;
- let currentRun = -1;
-
- function runNextTest()
- {
- if (currentRun < 0)
- return;
-
- if (currentTest >= tests.length - 1)
- {
- if (++currentRun <= 5)
- {
- currentTest = -1;
- runNextTest();
- }
- else
- SimpleTest.finish();
- return;
- }
-
- currentTest++;
- ElemHide.clear();
- defaultMatcher.clear();
-
- let [filters, expected] = tests[currentTest];
- for each (let filter in filters)
- ElemHide.add(Filter.fromText(filter));
- ElemHide.apply();
- if (currentRun == 2)
- defaultMatcher.add(Filter.fromText("@@|chrome://mochikit/$document"));
- else if (currentRun == 3)
- defaultMatcher.add(Filter.fromText("@@|chrome://mochikit/$~document"));
- else if (currentRun == 4)
- defaultMatcher.add(Filter.fromText("@@|chrome://mochikit/$elemhide"));
- else if (currentRun == 5)
- defaultMatcher.add(Filter.fromText("@@||localhost^$elemhide"));
-
- // Reset the loaded document
- let body = document.getElementById("frame").contentDocument.body;
- body.innerHTML = body.innerHTML;
-
- if (currentRun == 2 || currentRun == 5)
- expected = "visible visible"; // Second and fifth runs are whitelisted, nothing should be hidden
-
- body.offsetHeight; // force reflow
- setTimeout(function()
- {
- let doc = document.getElementById("frame").contentDocument;
- let result = (doc.getElementById("test1").offsetHeight > 0 ? "visible" : "hidden") + " " + (doc.getElementById("test2").offsetHeight > 0 ? "visible" : "hidden");
- is(result, expected, "Run " + currentRun + "\n" + filters.join("\n"));
- runNextTest();
- }, 0);
- }
-
- function start()
- {
- window.addEventListener("unload", stop, false);
- server.start(1234);
-
- server.registerPathHandler("/test", function(metadata, response)
- {
- let body = '<div id="test1" class="testClass">foo</div><p id="test2" class="testClass">bar</p>';
- response.setStatusLine("1.1", "200", "OK");
- response.setHeader("Content-Type", "text/html");
- response.bodyOutputStream.write(body, body.length);
- });
-
- currentRun = 1;
-
- let frame = document.getElementById("frame");
- frame.contentWindow.location.href = "http://localhost:1234/test";
- }
-
- function stop()
- {
- server.stop();
- }
-
- let server = new nsHttpServer();
- SimpleTest.waitForExplicitFinish();
- addLoadEvent(start);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_filterClasses.html b/mochitest/tests/test_filterClasses.html
deleted file mode 100644
index e29145f..0000000
--- a/mochitest/tests/test_filterClasses.html
+++ /dev/null
@@ -1,248 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter classes tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- Cu.import(baseURL.spec + "Utils.jsm");
- prepareFilterComponents();
-
- function serializeFilter(filter)
- {
- // Filter serialization only writes out essential properties, need to do a full serialization here
- let result = [];
- result.push("text=" + filter.text);
- if (filter instanceof InvalidFilter)
- {
- result.push("type=invalid");
- if (filter.reason)
- result.push("hasReason");
- }
- else if (filter instanceof CommentFilter)
- {
- result.push("type=comment");
- }
- else if (filter instanceof ActiveFilter)
- {
- result.push("disabled=" + filter.disabled);
- result.push("lastHit=" + filter.lastHit);
- result.push("hitCount=" + filter.hitCount);
-
- let domains = [];
- if (filter.includeDomains)
- {
- for (let domain in filter.includeDomains)
- domains.push(domain);
- }
- if (filter.excludeDomains)
- {
- for (let domain in filter.excludeDomains)
- domains.push("~" + domain);
- }
- result.push("domains=" + domains.sort().join("|"));
-
- if (filter instanceof RegExpFilter)
- {
- result.push("regexp=" + filter.regexp.source);
- result.push("contentType=" + filter.contentType);
- result.push("matchCase=" + filter.matchCase);
-
- result.push("thirdParty=" + filter.thirdParty);
- if (filter instanceof BlockingFilter)
- {
- result.push("type=filterlist");
- result.push("collapse=" + filter.collapse);
- }
- else if (filter instanceof WhitelistFilter)
- {
- result.push("type=whitelist");
- }
- }
- else if (filter instanceof ElemHideFilter)
- {
- result.push("type=elemhide");
- result.push("selectorDomain=" + (filter.selectorDomain || ""));
- result.push("selector=" + filter.selector);
- }
- }
- return result;
- }
-
- function addDefaults(expected)
- {
- let type = null;
- let hasProperty = {};
- for each (let entry in expected)
- {
- if (/^type=(.*)/.test(entry))
- type = RegExp.$1;
- else if (/^(\w+)/.test(entry))
- hasProperty[RegExp.$1] = true;
- }
-
- function addProperty(prop, value)
- {
- if (!(prop in hasProperty))
- expected.push(prop + "=" + value);
- }
-
- if (type == "whitelist" || type == "filterlist" || type == "elemhide")
- {
- addProperty("disabled", "false");
- addProperty("lastHit", "0");
- addProperty("hitCount", "0");
- }
- if (type == "whitelist" || type == "filterlist")
- {
- addProperty("contentType", 0x7FFFFFFF & ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFilter.typeMap.DONOTTRACK));
- addProperty("matchCase", "false");
- addProperty("thirdParty", "null");
- addProperty("domains", "");
- }
- if (type == "filterlist")
- {
- addProperty("collapse", "null");
- }
- if (type == "elemhide")
- {
- addProperty("selectorDomain", "");
- addProperty("domains", "");
- }
- }
-
- function compareFilter(text, expected, postInit)
- {
- addDefaults(expected);
-
- let filter = Filter.fromText(text);
- if (postInit)
- postInit(filter)
- let result = serializeFilter(filter);
- is(result.sort().join("\n"), expected.sort().join("\n"), text);
-
- // Test round-trip
- let filter2;
- let buffer = [];
- filter.serialize(buffer);
- if (buffer.length)
- {
- let map = {__proto__: null};
- for each (let line in buffer.slice(1))
- {
- if (/(.*?)=(.*)/.test(line))
- map[RegExp.$1] = RegExp.$2;
- }
- filter2 = Filter.fromObject(map);
- }
- else
- {
- filter2 = Filter.fromText(filter.text);
- }
-
- is(serializeFilter(filter).join("\n"), serializeFilter(filter2).join("\n"), text + " deserialization");
- }
-
- is(typeof Filter, "function", "typeof Filter");
- is(typeof InvalidFilter, "function", "typeof InvalidFilter");
- is(typeof CommentFilter, "function", "typeof CommentFilter");
- is(typeof ActiveFilter, "function", "typeof ActiveFilter");
- is(typeof RegExpFilter, "function", "typeof RegExpFilter");
- is(typeof BlockingFilter, "function", "typeof BlockingFilter");
- is(typeof WhitelistFilter, "function", "typeof WhitelistFilter");
- is(typeof ElemHideFilter, "function", "typeof ElemHideFilter");
-
- compareFilter("!asdf", ["type=comment", "text=!asdf"]);
- compareFilter("!foo#bar", ["type=comment", "text=!foo#bar"]);
- compareFilter("!foo##bar", ["type=comment", "text=!foo##bar"]);
- compareFilter("/??/", ["type=invalid", "text=/??/", "hasReason"]);
-
- compareFilter("#dd(asd)(ddd)", ["type=invalid", "text=#dd(asd)(ddd)", "hasReason"]);
- {
- let result = Filter.fromText("#dd(asd)(ddd)").reason;
- is(result, Utils.getString("filter_elemhide_duplicate_id"), "#dd(asd)(ddd).reason");
- }
-
- compareFilter("#*", ["type=invalid", "text=#*", "hasReason"]);
- {
- let result = Filter.fromText("#*").reason;
- is(result, Utils.getString("filter_elemhide_nocriteria"), "#*.reason");
- }
-
- compareFilter("blabla", ["type=filterlist", "text=blabla", "regexp=blabla"]);
- compareFilter("blabla_default", ["type=filterlist", "text=blabla_default", "regexp=blabla_default"], function(filter)
- {
- filter.disabled = false;
- filter.hitCount = 0;
- filter.lastHit = 0;
- });
- compareFilter("blabla_non_default", ["type=filterlist", "text=blabla_non_default", "regexp=blabla_non_default", "disabled=true", "hitCount=12", "lastHit=20"], function(filter)
- {
- filter.disabled = true;
- filter.hitCount = 12;
- filter.lastHit = 20;
- });
-
- let t = RegExpFilter.typeMap;
- let allTypes = 0x7FFFFFFF;
-
- compareFilter("/ddd|f?a[s]d/", ["type=filterlist", "text=/ddd|f?a[s]d/", "regexp=ddd|f?a[s]d"]);
- compareFilter("*asdf*d**dd*", ["type=filterlist", "text=*asdf*d**dd*", "regexp=asdf.*d.*dd"]);
- compareFilter("|*asd|f*d**dd*|", ["type=filterlist", "text=|*asd|f*d**dd*|", "regexp=^.*asd\\|f.*d.*dd.*$"]);
- compareFilter("dd[]{}$%<>&()d", ["type=filterlist", "text=dd[]{}$%<>&()d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\)d"]);
-
- compareFilter("@@/ddd|f?a[s]d/", ["type=whitelist", "text=@@/ddd|f?a[s]d/", "regexp=ddd|f?a[s]d", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT))]);
- compareFilter("@@*asdf*d**dd*", ["type=whitelist", "text=@@*asdf*d**dd*", "regexp=asdf.*d.*dd", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT))]);
- compareFilter("@@|*asd|f*d**dd*|", ["type=whitelist", "text=@@|*asd|f*d**dd*|", "regexp=^.*asd\\|f.*d.*dd.*$", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT))]);
- compareFilter("@@dd[]{}$%<>&()d", ["type=whitelist", "text=@@dd[]{}$%<>&()d", "regexp=dd\\[\\]\\{\\}\\$\\%\\<\\>\\&\\(\\)d", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT))]);
-
- compareFilter("bla$match-case,script,other,third-party,domain=foo.com", ["type=filterlist", "text=bla$match-case,script,other,third-party,domain=foo.com", "regexp=bla", "matchCase=true", "contentType=" + (t.SCRIPT | t.OTHER), "thirdParty=true", "domains=FOO.COM"]);
- compareFilter("bla$~match-case,~script,~other,~third-party,domain=~bar.com", ["type=filterlist", "text=bla$~match-case,~script,~other,~third-party,domain=~bar.com", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.SCRIPT | t.OTHER)), "thirdParty=false", "domains=~BAR.COM"]);
- compareFilter("@@bla$match-case,script,other,third-party,domain=foo.com|bar.com|~bar.foo.com|~foo.bar.com", ["type=whitelist", "text=@@bla$match-case,script,other,third-party,domain=foo.com|bar.com|~bar.foo.com|~foo.bar.com", "regexp=bla", "matchCase=true", "contentType=" + (t.SCRIPT | t.OTHER), "thirdParty=true", "domains=BAR.COM|FOO.COM|~BAR.FOO.COM|~FOO.BAR.COM"]);
-
- // background and image should be the same for backwards compatibility
- compareFilter("bla$image", ["type=filterlist", "text=bla$image", "regexp=bla", "contentType=" + (t.IMAGE)]);
- compareFilter("bla$background", ["type=filterlist", "text=bla$background", "regexp=bla", "contentType=" + (t.IMAGE)]);
- compareFilter("bla$~image", ["type=filterlist", "text=bla$~image", "regexp=bla", "contentType=" + (allTypes & ~(t.IMAGE | t.ELEMHIDE | t.DONOTTRACK))]);
- compareFilter("bla$~background", ["type=filterlist", "text=bla$~background", "regexp=bla", "contentType=" + (allTypes & ~(t.IMAGE | t.ELEMHIDE | t.DONOTTRACK))]);
-
- compareFilter("@@bla$~script,~other", ["type=whitelist", "text=@@bla$~script,~other", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@http://bla$~script,~other", ["type=whitelist", "text=@@http://bla$~script,~other", "regexp=http\\:\\/\\/bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.SCRIPT | t.OTHER))]);
- compareFilter("@@|ftp://bla$~script,~other", ["type=whitelist", "text=@@|ftp://bla$~script,~other", "regexp=^ftp\\:\\/\\/bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$~script,~other,document", ["type=whitelist", "text=@@bla$~script,~other,document", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$~script,~other,~document", ["type=whitelist", "text=@@bla$~script,~other,~document", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$document", ["type=whitelist", "text=@@bla$document", "regexp=bla", "contentType=" + t.DOCUMENT]);
- compareFilter("@@bla$~script,~other,elemhide", ["type=whitelist", "text=@@bla$~script,~other,elemhide", "regexp=bla", "contentType=" + (allTypes & ~(t.DONOTTRACK | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$~script,~other,~elemhide", ["type=whitelist", "text=@@bla$~script,~other,~elemhide", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$elemhide", ["type=whitelist", "text=@@bla$elemhide", "regexp=bla", "contentType=" + t.ELEMHIDE]);
- compareFilter("@@bla$~script,~other,donottrack", ["type=whitelist", "text=@@bla$~script,~other,donottrack", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$~script,~other,~donottrack", ["type=whitelist", "text=@@bla$~script,~other,~donottrack", "regexp=bla", "contentType=" + (allTypes & ~(t.ELEMHIDE | t.DONOTTRACK | t.DOCUMENT | t.SCRIPT | t.OTHER))]);
- compareFilter("@@bla$donottrack", ["type=whitelist", "text=@@bla$donottrack", "regexp=bla", "contentType=" + t.DONOTTRACK]);
-
- compareFilter("#ddd", ["type=elemhide", "text=#ddd", "selector=ddd"]);
- compareFilter("#ddd(fff)", ["type=elemhide", "text=#ddd(fff)", "selector=ddd.fff,ddd#fff"]);
- compareFilter("#ddd(foo=bar)(foo2^=bar2)(foo3*=bar3)(foo4$=bar4)", ["type=elemhide", "text=#ddd(foo=bar)(foo2^=bar2)(foo3*=bar3)(foo4$=bar4)", 'selector=ddd[foo="bar"][foo2^="bar2"][foo3*="bar3"][foo4$="bar4"]']);
- compareFilter("#ddd(fff)(foo=bar)", ["type=elemhide", "text=#ddd(fff)(foo=bar)", 'selector=ddd.fff[foo="bar"],ddd#fff[foo="bar"]']);
- compareFilter("#*(fff)", ["type=elemhide", "text=#*(fff)", "selector=.fff,#fff"]);
- compareFilter("#*(foo=bar)", ["type=elemhide", "text=#*(foo=bar)", 'selector=[foo="bar"]']);
- compareFilter("##body > div:first-child", ["type=elemhide", "text=##body > div:first-child", "selector=body > div:first-child"]);
- compareFilter("foo#ddd", ["type=elemhide", "text=foo#ddd", "selectorDomain=foo", "selector=ddd", "domains=FOO"]);
- compareFilter("foo,bar#ddd", ["type=elemhide", "text=foo,bar#ddd", "selectorDomain=foo,bar", "selector=ddd", "domains=BAR|FOO"]);
- compareFilter("foo,~bar#ddd", ["type=elemhide", "text=foo,~bar#ddd", "selectorDomain=foo", "selector=ddd", "domains=FOO|~BAR"]);
- compareFilter("foo,~baz,bar#ddd", ["type=elemhide", "text=foo,~baz,bar#ddd", "selectorDomain=foo,bar", "selector=ddd", "domains=BAR|FOO|~BAZ"]);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_filterListener.html b/mochitest/tests/test_filterListener.html
deleted file mode 100644
index 7a2e07e..0000000
--- a/mochitest/tests/test_filterListener.html
+++ /dev/null
@@ -1,202 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter listeners tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents(true);
- preparePrefs();
-
- FilterStorage.addSubscription(Subscription.fromURL("~fl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~wl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~il~"));
- FilterStorage.addSubscription(Subscription.fromURL("~eh~"));
-
- function checkKnownFilters(text, expected)
- {
- let result = {};
- for each (let type in ["blacklist", "whitelist"])
- {
- let matcher = defaultMatcher[type]
- let filters = [];
- for (let keyword in matcher.filterByKeyword)
- {
- let entry = matcher.filterByKeyword[keyword];
- let list = (typeof entry == "string" ? [Filter.fromText(entry)] : entry.map(function(text) Filter.fromText(text)));
- for each (let filter in list)
- {
- if (matcher.getKeywordForFilter(filter) != keyword)
- is(matcher.getKeywordForFilter(filter), keyword, "Keyword of filter " + filter.text);
- filters.push(filter);
- }
- }
- result[type] = filters;
- }
- result.elemhide = [];
- for (let key in ElemHideGlobal.filterByKey)
- result.elemhide.push(Filter.fromText(ElemHideGlobal.filterByKey[key]));
-
- function canonize(obj)
- {
- let result = [];
- for (let key in obj)
- {
- if (obj[key].length)
- result.push({key : key, value: obj[key].map(function(filter) {return filter.text;}).sort()});
- }
- result.sort(function(a, b)
- {
- if (a.key < b.key)
- return -1;
- else if (a.key > b.key)
- return 1;
- else
- return 0;
- });
- return result.map(function(entry) {return entry.key + ":\n" + entry.value.join("\n")}).join("\n");
- }
-
- is(canonize(result), canonize(expected), text);
- }
-
- let filter1 = Filter.fromText("filter1");
- let filter2 = Filter.fromText("@@filter2");
- let filter3 = Filter.fromText("#filter3");
- let filter4 = Filter.fromText("!filter4");
-
- FilterStorage.addFilter(filter1);
- checkKnownFilters("add filter1", {blacklist: [filter1]});
- FilterStorage.addFilter(filter2);
- checkKnownFilters("add filter2", {blacklist: [filter1], whitelist: [filter2]});
- FilterStorage.addFilter(filter3);
- checkKnownFilters("add filter3", {blacklist: [filter1], whitelist: [filter2], elemhide: [filter3]});
- FilterStorage.addFilter(filter4);
- checkKnownFilters("add filter4", {blacklist: [filter1], whitelist: [filter2], elemhide: [filter3]});
-
- FilterStorage.removeFilter(filter1);
- checkKnownFilters("remove filter1", {whitelist: [filter2], elemhide: [filter3]});
- filter2.disabled = true;
- FilterStorage.triggerObservers("filters disable", [filter2]);
- checkKnownFilters("disable filter2", {elemhide: [filter3]});
- FilterStorage.removeFilter(filter2);
- checkKnownFilters("remove filter2", {elemhide: [filter3]});
- FilterStorage.removeFilter(filter4);
- checkKnownFilters("remove filter4", {elemhide: [filter3]});
-
- filter2.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter2]);
- checkKnownFilters("enable filter2 while not in list", {elemhide: [filter3]});
- filter2.disabled = true;
- FilterStorage.triggerObservers("filters disable", [filter2]);
- checkKnownFilters("disable filter2 while not in list", {elemhide: [filter3]});
-
- let subscription = Subscription.fromURL("http://test1/");
- subscription.filters = [filter1, filter2, filter3, filter4];
-
- FilterStorage.addSubscription(subscription);
- checkKnownFilters("add subscription with filter1, filter2, filter3, filter4", {blacklist: [filter1], elemhide: [filter3]});
- filter2.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter2]);
- checkKnownFilters("enable filter2", {blacklist: [filter1], whitelist: [filter2], elemhide: [filter3]});
- FilterStorage.updateSubscriptionFilters(subscription, [filter4]);
- checkKnownFilters("change subscription filters to filter4", {elemhide: [filter3]});
- FilterStorage.removeFilter(filter3);
- checkKnownFilters("remove filter3", {});
- FilterStorage.updateSubscriptionFilters(subscription, [filter1, filter2]);
- checkKnownFilters("change subscription filters to filter1, filter2", {blacklist: [filter1], whitelist: [filter2]});
- FilterStorage.addFilter(filter1);
- checkKnownFilters("add filter1", {blacklist: [filter1], whitelist: [filter2]});
-
- filter1.disabled = true;
- FilterStorage.triggerObservers("filters disable", [filter1]);
- checkKnownFilters("disable filter1", {whitelist: [filter2]});
- filter2.disabled = true;
- FilterStorage.triggerObservers("filters disable", [filter2]);
- checkKnownFilters("disable filter2", {});
- filter1.disabled = false;
- filter2.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter1, filter2]);
- checkKnownFilters("enable filter1, filter2", {blacklist: [filter1], whitelist: [filter2]});
-
- subscription.disabled = true;
- FilterStorage.triggerObservers("subscriptions disable", [subscription]);
- checkKnownFilters("disable subscription", {blacklist: [filter1]});
- FilterStorage.removeSubscription(subscription);
- checkKnownFilters("remove subscription", {blacklist: [filter1]});
- FilterStorage.addSubscription(subscription);
- checkKnownFilters("add subscription", {blacklist: [filter1]});
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- checkKnownFilters("enable subscription", {blacklist: [filter1], whitelist: [filter2]});
-
- subscription.disabled = true;
- FilterStorage.triggerObservers("subscriptions disable", [subscription]);
- checkKnownFilters("disable subscription", {blacklist: [filter1]});
- FilterStorage.addFilter(filter2);
- checkKnownFilters("add filter2", {blacklist: [filter1], whitelist: [filter2]});
- FilterStorage.removeFilter(filter2);
- checkKnownFilters("remove filter2", {blacklist: [filter1]});
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- checkKnownFilters("enable subscription", {blacklist: [filter1], whitelist: [filter2]});
-
- let subscription2 = Subscription.fromURL("~fl~");
- subscription2.disabled = true;
- FilterStorage.triggerObservers("subscriptions disable", [subscription2]);
- checkKnownFilters("disable blocking filters", {blacklist: [filter1], whitelist: [filter2]});
- FilterStorage.removeSubscription(subscription);
- checkKnownFilters("remove subscription", {});
- subscription2.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription2]);
- checkKnownFilters("enable blocking filters", {blacklist: [filter1]});
-
- let subscription3 = Subscription.fromURL("~wl~");
- subscription3.disabled = true;
- FilterStorage.triggerObservers("subscriptions disable", [subscription3]);
- checkKnownFilters("disable exception rules", {blacklist: [filter1]});
- FilterStorage.addFilter(filter2);
- checkKnownFilters("add filter2", {blacklist: [filter1]});
- subscription3.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription3]);
- checkKnownFilters("enable exception rules", {blacklist: [filter1], whitelist: [filter2]});
-
- let subscription4 = Subscription.fromURL("http://test/");
- let filter5 = Filter.fromText("filter5");
- let filter6 = Filter.fromText("@@filter6");
- let filter7 = Filter.fromText("!filter7");
- FilterStorage.updateSubscriptionFilters(subscription4, [filter5, filter6, filter7]);
- checkKnownFilters("update subscription not in the list yet", {blacklist: [filter1], whitelist: [filter2]});
-
- FilterStorage.addSubscription(subscription4);
- checkKnownFilters("add subscription to the list", {blacklist: [filter1, filter5], whitelist: [filter2, filter6]});
-
- FilterStorage.updateSubscriptionFilters(subscription4, [filter5, filter2, filter7]);
- checkKnownFilters("update subscription while in the list", {blacklist: [filter1, filter5], whitelist: [filter2]});
-
- subscription3.disabled = true;
- FilterStorage.triggerObservers("subscriptions disable", [subscription3]);
- checkKnownFilters("disable exception rules", {blacklist: [filter1, filter5], whitelist: [filter2]});
-
- FilterStorage.removeSubscription(subscription4);
- checkKnownFilters("remove subscription from the list", {blacklist: [filter1]});
-
- subscription3.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription3]);
- checkKnownFilters("enable exception rules", {blacklist: [filter1], whitelist: [filter2]});
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_filterStorage.html b/mochitest/tests/test_filterStorage.html
deleted file mode 100644
index 409c67f..0000000
--- a/mochitest/tests/test_filterStorage.html
+++ /dev/null
@@ -1,324 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter storage tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- //TODO: increaseHitCount, resetHitCounts
-
- prepareFilterComponents();
-
- function compareObservers(test, list)
- {
- let result = FilterStorageGlobal.observers.map(function(observer) {return observer.name}).join("\n");
- let expected = list.map(function(observer) {return observer.name}).join("\n");
- is(result, expected, test);
- }
-
- function compareSubscriptionList(test, list)
- {
- let result = FilterStorage.subscriptions.map(function(subscription) {return subscription.url}).join("\n");
- let expected = list.map(function(subscription) {return subscription.url}).join("\n");
- is(result, expected, test);
- }
-
- function compareFiltersList(test, list)
- {
- let result = FilterStorage.subscriptions.map(function(subscription) {return subscription.filters.map(function(filter) {return filter.text}).join("\n") + "\n"}).join("\n");
- let expected = list.map(function(filters) {return filters.join("\n") + "\n"}).join("\n");
- is(result, expected, test);
- }
-
- function compareFilterSubscriptions(test, filter, list)
- {
- let result = filter.subscriptions.map(function(subscription) {return subscription.url}).join("\n");
- let expected = list.map(function(subscription) {return subscription.url}).join("\n");
- is(result, expected, test);
- }
-
- testSubscriptions();
- testFilterSubscriptionRelationship();
-
- FilterStorage.addSubscription(Subscription.fromURL("~fl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~wl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~il~"));
- FilterStorage.addSubscription(Subscription.fromURL("~eh~"));
-
- testFilters();
- testDisabledSubscriptions();
-
- function testSubscriptions()
- {
- let observed1 = "";
- let observed2 = "";
- let observed3 = "";
- let observer1 = function subscription_observer1(action, subscriptions) { observed1 += action + " " + subscriptions.map(function(subscription) {return subscription.url;}).join(" ") + "\n"; }
- let observer2 = function subscription_observer2(action, subscriptions) { observed2 += action + " " + subscriptions.map(function(subscription) {return subscription.url;}).join(" ") + "\n"; }
- let observer3 = function subscription_observer3(action, subscriptions) { observed3 += action + " " + subscriptions.map(function(subscription) {return subscription.url;}).join(" ") + "\n"; }
-
- let subscription1 = Subscription.fromURL("http://test1/");
- let subscription2 = Subscription.fromURL("http://test2/");
- let subscription3 = Subscription.fromURL("http://test3/");
-
- compareSubscriptionList("No subscriptions", []);
- compareObservers("No observers", []);
-
- FilterStorage.addSubscription(subscription1);
- compareSubscriptionList("add(test1)", [subscription1]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1)", [observer1]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1) again", [observer1]);
-
- FilterStorage.addSubscription(subscription1);
- compareSubscriptionList("add(test1) again", [subscription1]);
-
- FilterStorage.removeSubscription(subscription2);
- compareSubscriptionList("remove(test2)", [subscription1]);
-
- FilterStorage.addObserver(observer2);
- compareObservers("addObserver(observer2)", [observer1, observer2]);
-
- FilterStorage.removeObserver(observer1);
- compareObservers("removeObserver(observer1)", [observer2]);
-
- FilterStorage.addSubscription(subscription2, true);
- compareSubscriptionList("add(test2) silent", [subscription1, subscription2]);
-
- FilterStorage.addSubscription(subscription3);
- compareSubscriptionList("add(test3)", [subscription1, subscription2, subscription3]);
-
- FilterStorage.addObserver(observer3);
- compareObservers("addObserver(observer3)", [observer2, observer3]);
-
- FilterStorage.removeSubscription(subscription1, true);
- compareSubscriptionList("remove(test1) silent", [subscription2, subscription3]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1)", [observer2, observer3, observer1]);
-
- FilterStorage.removeObserver(observer3);
- compareObservers("removeObserver(observer3)", [observer2, observer1]);
-
- FilterStorage.removeSubscription(subscription1);
- compareSubscriptionList("remove(test1) again", [subscription2, subscription3]);
-
- FilterStorage.addSubscription(subscription1);
- compareSubscriptionList("add(test1)", [subscription2, subscription3, subscription1]);
-
- FilterStorage.removeSubscription(subscription3);
- compareSubscriptionList("remove(test3)", [subscription2, subscription1]);
-
- FilterStorage.removeSubscription(subscription3);
- compareSubscriptionList("remove(test3) again", [subscription2, subscription1]);
-
- is(observed1, "subscriptions add http://test1/\nsubscriptions remove http://test3/\n", "observed1");
- is(observed2, "subscriptions add http://test3/\nsubscriptions add http://test1/\nsubscriptions remove http://test3/\n", "observed2");
- is(observed3, "", "observed3");
-
- FilterStorage.removeSubscription(subscription1);
- FilterStorage.removeSubscription(subscription2);
- FilterStorage.removeSubscription(subscription3);
- FilterStorage.removeObserver(observer1);
- FilterStorage.removeObserver(observer2);
- FilterStorage.removeObserver(observer3);
- }
-
- function testFilters()
- {
- let observed1 = "";
- let observed2 = "";
- let observed3 = "";
- let observer1 = function filter_observer1(action, filters) { observed1 += action + " " + filters.map(function(filter) {return filter.text;}).join(" ") + "\n"; }
- let observer2 = function filter_observer2(action, filters) { observed2 += action + " " + filters.map(function(filter) {return filter.text;}).join(" ") + "\n"; }
- let observer3 = function filter_observer3(action, filters) { observed3 += action + " " + filters.map(function(filter) {return filter.text;}).join(" ") + "\n"; }
-
- compareFiltersList("No filters", [[],[],[],[]]);
- compareObservers("No observers", []);
-
- FilterStorage.addFilter(Filter.fromText("foo"));
- compareFiltersList("add(foo)", [["foo"],[],[],[]]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1)", [observer1]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1) again", [observer1]);
-
- FilterStorage.addFilter(Filter.fromText("bar"));
- compareFiltersList("add(bar)", [["foo", "bar"],[],[],[]]);
-
- FilterStorage.removeFilter(Filter.fromText("foobar"));
- compareFiltersList("remove(foobar)", [["foo", "bar"],[],[],[]]);
-
- FilterStorage.addObserver(observer2);
- compareObservers("addObserver(observer2)", [observer1, observer2]);
-
- FilterStorage.removeObserver(observer1);
- compareObservers("removeObserver(observer1)", [observer2]);
-
- FilterStorage.addFilter(Filter.fromText("@@ddd"));
- compareFiltersList("add(@@ddd)", [["foo", "bar"],["@@ddd"],[],[]]);
-
- FilterStorage.addFilter(Filter.fromText("!foobar"));
- compareFiltersList("add(!foobar)", [["foo", "bar", "!foobar"],["@@ddd"],[],[]]);
-
- FilterStorage.addObserver(observer3);
- compareObservers("addObserver(observer3)", [observer2, observer3]);
-
- FilterStorage.removeFilter(Filter.fromText("bar"));
- compareFiltersList("remove(bar)", [["foo", "!foobar"],["@@ddd"],[],[]]);
-
- FilterStorage.removeFilter(Filter.fromText("@@ddd"));
- compareFiltersList("remove(@@ddd)", [["foo", "!foobar"],[],[],[]]);
-
- FilterStorage.addObserver(observer1);
- compareObservers("addObserver(observer1)", [observer2, observer3, observer1]);
-
- FilterStorage.removeObserver(observer3);
- compareObservers("removeObserver(observer3)", [observer2, observer1]);
-
- FilterStorage.addFilter(Filter.fromText("foo#bar"));
- compareFiltersList("add(foo#bar)", [["foo", "!foobar"],[],[],["foo#bar"]]);
-
- FilterStorage.addFilter(Filter.fromText("/??/"));
- compareFiltersList("add(/??/)", [["foo", "!foobar"],[],["/??/"],["foo#bar"]]);
-
- FilterStorage.addFilter(Filter.fromText("@@asdf"));
- compareFiltersList("add(@asdf/)", [["foo", "!foobar"],["@@asdf"],["/??/"],["foo#bar"]]);
-
- is(observed1, "filters add bar\nfilters add foo#bar\nfilters add /??/\nfilters add @@asdf\n", "observed1");
- is(observed2, "filters add @@ddd\nfilters add !foobar\nfilters remove bar\nfilters remove @@ddd\nfilters add foo#bar\nfilters add /??/\nfilters add @@asdf\n", "observed2");
- is(observed3, "filters remove bar\nfilters remove @@ddd\n", "observed3");
-
- FilterStorage.removeObserver(observer1);
- FilterStorage.removeObserver(observer2);
- FilterStorage.removeObserver(observer3);
-
- // Tests for adding filters before a particular filter
-
- FilterStorage.addFilter(Filter.fromText("test1"), Filter.fromText("!foobar"));
- compareFiltersList("add(test1) before !foobar", [["foo", "test1", "!foobar"],["@@asdf"],["/??/"],["foo#bar"]]);
-
- FilterStorage.addFilter(Filter.fromText("test2"), Filter.fromText("foo"));
- compareFiltersList("add(test2) before foo", [["test2", "foo", "test1", "!foobar"],["@@asdf"],["/??/"],["foo#bar"]]);
-
- FilterStorage.addFilter(Filter.fromText("test3"), Filter.fromText("@@asdf"));
- compareFiltersList("add(test3) before @@asdf", [["test2", "foo", "test1", "!foobar", "test3"],["@@asdf"],["/??/"],["foo#bar"]]);
-
- FilterStorage.addFilter(Filter.fromText("@@test4"), Filter.fromText("@@asdf"));
- compareFiltersList("add(@@test5) before @@asdf", [["test2", "foo", "test1", "!foobar", "test3"],["@@test4", "@@asdf"],["/??/"],["foo#bar"]]);
- }
-
- function testFilterSubscriptionRelationship()
- {
- let filter1 = Filter.fromText("filter1");
- let filter2 = Filter.fromText("filter2");
- let filter3 = Filter.fromText("filter3");
-
- let subscription1 = Subscription.fromURL("http://test1/");
- subscription1.filters = [filter1, filter2];
-
- let subscription2 = Subscription.fromURL("http://test2/");
- subscription2.filters = [filter2, filter3];
-
- let subscription3 = Subscription.fromURL("http://test3/");
- subscription3.filters = [filter1, filter2, filter3];
-
- compareFilterSubscriptions("Initial filter1 subscriptions", filter1, []);
- compareFilterSubscriptions("Initial filter2 subscriptions", filter2, []);
- compareFilterSubscriptions("Initial filter3 subscriptions", filter3, []);
-
- FilterStorage.addSubscription(subscription1);
-
- compareFilterSubscriptions("filter1 subscriptions after adding http://test1/", filter1, [subscription1]);
- compareFilterSubscriptions("filter2 subscriptions after adding http://test1/", filter2, [subscription1]);
- compareFilterSubscriptions("filter3 subscriptions after adding http://test1/", filter3, []);
-
- FilterStorage.addSubscription(subscription2);
-
- compareFilterSubscriptions("filter1 subscriptions after adding http://test2/", filter1, [subscription1]);
- compareFilterSubscriptions("filter2 subscriptions after adding http://test2/", filter2, [subscription1, subscription2]);
- compareFilterSubscriptions("filter3 subscriptions after adding http://test2/", filter3, [subscription2]);
-
- FilterStorage.removeSubscription(subscription1);
-
- compareFilterSubscriptions("filter1 subscriptions after removing http://test1/", filter1, []);
- compareFilterSubscriptions("filter2 subscriptions after removing http://test1/", filter2, [subscription2]);
- compareFilterSubscriptions("filter3 subscriptions after removing http://test1/", filter3, [subscription2]);
-
- FilterStorage.updateSubscriptionFilters(subscription3, [filter3]);
-
- compareFilterSubscriptions("filter1 subscriptions after updating http://test3/ filters", filter1, []);
- compareFilterSubscriptions("filter2 subscriptions after updating http://test3/ filters", filter2, [subscription2]);
- compareFilterSubscriptions("filter3 subscriptions after updating http://test3/ filters", filter3, [subscription2]);
-
- FilterStorage.addSubscription(subscription3);
-
- compareFilterSubscriptions("filter1 subscriptions after adding http://test3/", filter1, []);
- compareFilterSubscriptions("filter2 subscriptions after adding http://test3/", filter2, [subscription2]);
- compareFilterSubscriptions("filter3 subscriptions after adding http://test3/", filter3, [subscription2, subscription3]);
-
- FilterStorage.updateSubscriptionFilters(subscription3, [filter1, filter2]);
-
- compareFilterSubscriptions("filter1 subscriptions after updating http://test3/ filters", filter1, [subscription3]);
- compareFilterSubscriptions("filter2 subscriptions after updating http://test3/ filters", filter2, [subscription2, subscription3]);
- compareFilterSubscriptions("filter3 subscriptions after updating http://test3/ filters", filter3, [subscription2]);
-
- FilterStorage.removeSubscription(subscription3);
-
- compareFilterSubscriptions("filter1 subscriptions after removing http://test3/", filter1, []);
- compareFilterSubscriptions("filter2 subscriptions after removing http://test3/", filter2, [subscription2]);
- compareFilterSubscriptions("filter3 subscriptions after removing http://test3/", filter3, [subscription2]);
-
- FilterStorage.removeSubscription(subscription1);
- FilterStorage.removeSubscription(subscription2);
- FilterStorage.removeSubscription(subscription3);
- }
-
- function testDisabledSubscriptions()
- {
- let subscription = Subscription.fromURL("~fl~");
- FilterStorage.updateSubscriptionFilters(subscription, []);
- subscription.disabled = true;
-
- let filter1 = Filter.fromText("filter1");
- let filter2 = Filter.fromText("filter2");
-
- FilterStorage.addFilter(filter1);
- is(subscription.disabled, true, "Subscription still disabled after adding one filter");
- FilterStorage.addFilter(filter2);
- is(subscription.disabled, true, "Subscription still disabled after adding two filters");
-
- FilterStorage.removeFilter(filter1);
- is(subscription.disabled, true, "Subscription still disabled after removing one filter");
- FilterStorage.removeFilter(filter2);
- is(subscription.disabled, false, "Subscription no longer disabled after removing all filters");
-
- subscription.disabled = true;
- FilterStorage.updateSubscriptionFilters(subscription, [filter1]);
- is(subscription.disabled, true, "Subscription still disabled after replacing filters by one filter");
- FilterStorage.updateSubscriptionFilters(subscription, [filter1, filter2]);
- is(subscription.disabled, true, "Subscription still disabled after replacing filters by two filters");
- FilterStorage.updateSubscriptionFilters(subscription, []);
- is(subscription.disabled, false, "Subscription no longer disabled after replacing filters by an empty list");
- }
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_filterStorage_readwrite.html b/mochitest/tests/test_filterStorage_readwrite.html
deleted file mode 100644
index d18365b..0000000
--- a/mochitest/tests/test_filterStorage_readwrite.html
+++ /dev/null
@@ -1,4783 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter storage read/write tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <meta http-equiv="Content-Type" value="text/html; charset=utf-8"/>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
- <div id="filterData">
-# Adblock Plus preferences
-
-[Filter]
-text=@@not/banner/
-lastHit=12345
-hitCount=445
-
-[Filter]
-text=[Filter]
-disabled=true
-
-[Subscription]
-url=~il~
-
-[Subscription filters]
-! This is my own filters
-
-[Subscription]
-url=~wl~
-
-[Subscription filters]
-@@not/banner/
-
-[Subscription]
-url=~fl~
-
-[Subscription filters]
-\[Filter]
-foo$collapse
-bar$~collapse,match-case
-abc$domain=foo.com|~bar.foo.com
-*/banner/*
-
-[Subscription]
-url=~eh~
-
-[Subscription filters]
-foo.com#bar
-
-[Subscription]
-url=http://easylist.adblockplus.org/easylist+easyelement+abp_tracking.txt
-title=EasyList + EasyElement + EasyPrivacy
-lastDownload=1225437961
-downloadStatus=synchronize_ok
-lastModified=Fri, 31 Oct 2008 02:13:31 GMT
-expires=1225869961
-requiredVersion=0.7.5
-alternativeLocations=http://example.com/easylist+easyelement+abp_tracking.txt;q=0.5
-
-[Subscription filters]
-! NOTE: This file is a combination of multiple subscriptions
-!
-! *** Fetched from: http://easylist.adblockplus.org/adblock_rick752.txt ***
-!
-!
-! Rick752's EASYLIST (global English ad-blocking subscription)
-! -add the optional EasyElement & EasyPrivacy subscriptions.
-! | Last Modified: 30oct2008 | http://easylist.adblockplus.org |
-!Expires after 5 days
-!
--adspace
-&adspace=
-=viewAdJs
-&affiliate=$subdocument
-&ClientType=*&AdID=
-&google_adpage=
-&partner$subdocument
-?adtype=
-?affiliate
-?getad=&$~other,~object-subrequest
-?showbanner=
-_ad.aspx
-_adbrite
-_adfunction
-_ads/$image
-_ads.php?
-_adspace
-_banner_ad
-_bannerid*random
-_companionad.
-_files/*htm|$subdocument
-_videoad.$other,object-subrequest
-adaffiliate
-AdIFrame$match-case
-admentor
-ADTECH;cookie=
-ads.sv.publicus.$script
-adsfac.net
-affiliatebrand.
-audienceprofiler.
-aurora-*marketing.co
-banner-ad
-bannerad
-BannerMangement
-banners&id=
-blog.tmcnet.*/overlib.js
-brandcentral.
-Click*Advertiser
-clicktag=*/ad
-content.search
-adserving.cpxinteractive
-cubics.com/
-dbbsrv.com
-dgmaustralia.
-download-door.search.com/search
-dynamicad.
-earthlink*/promos
-eas.blocket.
-engine.awaps.net/
-exitexplosion.*/exit.js
-expedia_ad.
-faireagle.com
-favinfo.com/ad.
-gamesbanner.net/
-geocities.com/js_source/
-google.com*/promo_
-hera.hardocp.
-imageshack*tagworld
-interclick.
-js.worthathousandwords.
-js2.yimg.*_popup_
-kanoodle
-link_ads
-mediacorpsingapore
-medrx.sensis.com.au/content/
-nebuad.com
-netspiderads
-network.ninemsn.*/share/
-nbjmp.com/
-openbanner$match-case
-page.grabclick.
-phpadsnew$~other,~object-subrequest
-popinads.
-popunder$script
-popup_ad.
-precisionclick.
-pro-market.
-promopop
-ptnrcontent
-publicidad
-quigo.com
-rad.live.com/ADSAdClient
-richmedia.*yimg.
-space.com/*interstitial_space.js
-sponslink
-sponsor.gif
-sponsorads
-sponsoredlink$~stylesheet
-sponsored_links
-sponsors*banner
-storefronts$~stylesheet
-sys-con.com/common/$script
-targetpoint.com
-textlink-ads.$~image
-themis.yahoo.
-vs20060817.com/
-worsethanfailure.*/Tizes/$object
-www.cb.cl/*banner
-www.ad.tomshardware.*=banner
-xcelsiusadserver.
-yceml.net
-.1100i.com/
-.188server.
-.2mdn.net/
-.360ads.
-.43plc.com
-.about.com/0/$subdocument
-.accuserveadsystem.
-.acronym.com/
-.ad.tomshardware.com/$script
-.ad-flow.
-.ad20.net/
-.ad4cash.
-.adaction.
-.adbard.net/ab
-.adbrite.com/mb/
-.adbureau.
-.adbutler.
-.adcentriconline.
-.adchap.
-.adecn.com/
-.adengage.
-.adf01.net/
-.adfusion.
-.adgardener.
-.adgine.
-.adgroups.
-.adhese.
-.adicate.
-.adition.com/
-.adinterax.
-.adireland.
-.adjuggler.
-.admarketplace.
-.adnet.biz
-.adlink.net
-.adnet.ru
-.adocean.
-.adoperator.
-.adpark.
-.adpinion.
-.adsdk.com/
-.adserver.*?
-.adservinginternational.
-.adsforindians.
-.adshopping.
-.adshuffle.
-.adsmarket.
-.adsonar.
-.adspeed.
-.adtext.
-.adtmedia.
-.adtology3.
-.adtrgt.
-.adultadworld.
-.adultfriendfinder.com/banners/
-.adverserve.
-.advertarium.
-.adverticum.net/
-.advertising.
-.advertlets.
-.advertserve.
-.adviva.
-.adxpower.
-.afcyhf.
-.affiliate.
-.affiliatefuel.
-.affiliatefuture.
-.affiliatesensor.
-.affilimatch.
-.aim4media.
-.akamai.*sponsor
-.alphagodaddy.
-.anrdoezrs.
-.arcadebanners.
-.as5000.
-.ase.cc/
-.assoc-amazon.
-.atdmt.com/
-.atwola.
-.auspipe.
-.awin1.com
-.awltovhc.
-.axill.com/
-.azads.com/
-.azjmp.com/
-.azoogleads.
-.bannerbank.ru/
-.bannerconnect.
-.bannersmania.
-.bbc.co.uk/*/vs.js
-.begun.ru/
-.belointeractive.
-.bestofferdirect.
-.bidvertiser.
-.bimedia.net/video/$object
-.blogads.
-.bluestreak.
-.bravenetmedianetwork.
-.bravenet.*/rover/
-.bridgetrack.
-.btrll.com/*
-.burstnet.
-.c8.net.ua/
-.casalemedia.
-.cc-dt.com/
-.centralmediaserver.$~image
-.cgecwm.org/
-.checkm8.
-.checkmystats.
-.chitika.
-.ciao.co.uk/load_file.php?
-.cjt1.net
-.clash-media.
-.claxonmedia.
-.clickad.
-.clickbooth
-.clickexperts.
-.clickintext.$~script
-.clickthrucash.
-.clixgalore.
-.cogsdigital.
-.commission-junction.
-.commissionmonster.
-.com/sideads|
-.com/topads|
-.connextra.
-.contextuads.
-.contextweb.
-.cpaclicks
-.cpays.com/
-.cpmstar.
-.cpuim.com/
-.crashextads.
-.crispads.
-.crwdcntrl.net/cc.js
-.decisionmark.
-.decisionnews.
-.deepmetrix.
-.directorym.
-.dl-rms.com/
-.domainsponsor.
-.doubleclick.
-.dpbolvw.
-.main.ebayrtm.com/rtm?RtmCmd&a=inline&$script
-.ebaystatic./adserver
-.edge.ru4.
-.emediate.
-.etology.
-.euroclick.
-.exponential.
-.eyereturn.
-.eyewonder.
-.fairfax.$~stylesheet
-.falkag.
-.fastclick.
-.feedburner.com/~a/
-.filefront.*/fnOverlay.js
-.fimserve.
-.firstadsolution.
-.fixionmedia.
-.flux.com/*?
-.fmpub.net/
-.forrestersurveys.
-.fluxads.
-.flyordie.com/games/free/b/*--?p=
-.friendlyduck.
-.ftjcfx.
-.funklicks.
-.g.akamai.*/ads.
-.game-advertising-online.
-.gamecetera.
-.gamersbanner.
-.geopromos.
-.gestionpub.
-.gklmedia.
-.go.com/*ads.js
-.googleadservices.
-.grabmyads.
-.gumgum.*/ggv2.js
-.henwo.com/$script
-.hit-now.
-.hosticanaffiliate.
-.httpool.
-.hypemakers.
-.hypervre.$script
-.ibatom.*/syndication/
-.ic-live.
-.icdirect.
-.idg.com.au/images/*_promo$image
-.imagesatlantic.
-.imedia.co.il/
-.infinite-ads.
-.imglt.com/
-.impresionesweb.
-.imrworldwide.
-.indiads.
-.industrybrains.
-.inetinteractive.
-.infocious.
-.intellitxt.
-.interpolls.
-.ivwbox.
-.jdoqocy.
-.jumboaffiliates.
-.jydesign.
-.ketoo.com/
-.klipmart.
-.kontera.
-.kqzyfj.
-.leadacceptor.
-.lduhtrp.
-.lightningcast.$~other,~object-subrequest
-.linkads.*?
-.linkexchange.
-.linkworth.
-.litres.ru/static/banner/
-.ltassrv.
-.maxserving.
-.mb01.com/
-.mbn.com.ua/
-.mediagridwork.com/mx.js
-.medialand.ru/
-.mediaonenetwork.
-.mediaplex.
-.mediatarget.
-.mediavantage.
-.megaclick.com/
-.mercuras.
-.metaffiliation.
-.microsoftaffiliates.*.aspx?
-.mirago.com/
-.miva.com/
-.mochiads.com/srv/$other,object-subrequest
-.mootermedia.
-.msn.com/?adunitid
-.myway.com/gca_iframe.
-.neoseeker.com/*_pc.html
-.net3media.
-.netavenir.
-.newanglemedia.com/clients/
-.newsadstream.
-.ngads.com/
-.northmay.
-.ng/*&affiliate=
-.nwsource.*/adv.gif
-.nyadmcncserve-
-.obibanners.
-.onenetworkdirect.
-.openx.org/a*.php
-.overture.
-.oxado.com/
-.pc-ads.com/
-.peelawayads.com/affads/
-.perfb.com
-.pgpartner.
-.pheedo.
-.php?bannerid
-.php?adclass
-.platinumadvertisement.
-.playertraffic.
-.pointroll.
-.predictad.
-.pricegrabber.$subdocument
-.pricespy.co.nz/adds/
-.primaryads.
-.pro-advertising.
-.probannerswap.
-.profitpeelers.$script
-.projectwonderful.
-.proximic.com/js/widget.js
-.pulse360.
-.qksrv.net/
-.qksz.net/
-.questionmarket.
-.revresda.
-.revsci.
-.rmxads.
-.rottentomatoes.*size=*x*&dechannel
-.rovion.*?AffID=
-.rwpads.
-.scanscout.
-.sevenload.com/*/endscreen.swf
-.shareasale.
-.shareresults.
-.smartadserver.
-.smarttargetting.
-.snap.com/$script
-.snopes.com/*/*ad$subdocument
-.socialmedia.com/
-.sonnerie.
-.space.com/promo/
-.sparkstudios.
-.specificclick.
-.specificmedia.
-.speedsuccess.net/
-.sponsorpalace.
-.spotplex.*widget
-.srtk.net/
-.sta-ads.
-.survey-poll.
-.swf?clickTag=
-.tacoda.
-.targetnet.
-.thebigchair.com.au/egnonline/
-.tiser.com
-.tkqlhce.
-.torrentspy.*staticframe
-.total-media.net/
-.tqlkg.com
-.tradedoubler.
-.trafficmasterz.
-.trafic.
-.tribalfusion.
-.trigami.
-.typepad.com/sponsors/
-.tyroo.com
-.uimserv.net/
-.unicast.
-.universalhub.com/bban/
-.utarget.
-.valuead.
-.valueclick.
-.vibrantmedia.
-.videosift.com/bnr.php?
-.visitorglobe.*record
-.vpico.com/
-.webads.co.nz
-.webmasterplan.
-.widgetbucks.
-.worlddatinghere.
-.xchangebanners.
-.y.megaclick.
-.yimg.com/a/1-$~stylesheet
-.yimg.com/adv/
-.yimg.com/*/fairfax/$image
-.zanox.com/
-.zangocash.*/detectenvironment
-.zeads.com/
-.zedo.com/
-.zoomdirect.com.au/
-/63.225.61.
-/64.73.24.44
-/207.67.9.41/*
-/213.239.222.7/ad/*
-/217.15.94.117
-/468x60/*$script
-/.adserv/*
-/a.clearlightdigital.
-/a.collective-media.net/*
-/a.kerg.net/*
-/a.lakequincy.
-/ab.vcmedia.
-/abmw.aspx
-/ad/*promo
-/ad/code$script
-/ad/view/*
-/ad.asp?
-/ad.aspx?
-/ad2.aspx?
-/ad.php?
-/ad/frame
-/ad/mercury$object
-/ad/serve
-/ad/sponsors/*
-/ad_*.gif
-/ad_$subdocument
-/ad_functions
-/ad_insert.
-/ad_refresher.
-/ad_wrapper
-/ad-frame.
-/ad2games.
-/adbanner
-/adbrite$subdocument
-/adbrite.
-/adclick
-/adcode.js
-/adconfig/*
-/adconfig.xml?$image
-/adcontent.$~other,~object-subrequest
-/adcycle/*
-/adf.cgi?
-/adfetch?
-/adframe.
-/adframe_
-/adfshow?
-/adgraphics/*
-/adheader
-/adhoc/js/swfobject.js
-/AdIFrame.
-/adimages/*
-/adfunction
-/adimage.
-/adinsert.
-/adjs.php?
-/adjsmp.php?
-/adlabel
-/adlinks.js
-/adman/www/*
-/admanagement/*
-/ad_manager.js
-/admanager$script
-/admatch-syndication.
-/admedia.
-/adnetwork.
-/adpage.
-/adpeeps/*
-/adpeeps.php
-/Adplayer/*
-/adproducts/*
-/adRelated.
-/adsreporting/*
-/adrevolver/*
-/adroot/*
-/adrotator
-/ads/*$~stylesheet
-/ads.htm
-/ads.php?
-/ads_iframe.
-/ads_reporting/*
-/ads_v2.js
-/ads_yahoo.
-/ads*.php$subdocument
-/Ads-Leader
-/Ads-Rec
-/Ads-Sky
-/ads2.php?
-/ads2/*
-/ADSAdClient31.dll?GetAd?$other,object-subrequest
-/adscript
-/adsense_$script
-/adsense.
-/adserv*/delivery/*
-/AdServer/*?
-/Adserver?
-/adServer.*?
-/adsfolder/*
-/adshow?
-/AdsIframe/*
-/adsimage/*
-/AdsInclude.js
-/AdsManager/*
-/adsmanagement/*?
-/adspace$subdocument
-/adspro/*
-/adsonar.
-/adSwap.js
-/adsyndication.
-/adtags/*
-/ADTECH;
-/adtext.
-/adtext_
-/adtraff.
-/adtype.php?
-/advert_
-/advert/ms
-/adverti
-/advertpro/*
-/adverts_
-/adverts/*
-/adview.
-/AdWorks/*
-/adwrapper/*
-/AdWrapperIframe.
-/adxx.php?
-/affiliate_$image
-/affiliate*/ad/*
-/AffiliateBanners/*
-/affiliates.babylon.
-/AffiliateWiz/*
-/afr.php?
-/ah.pricegrabber.com/cb_table.php
-/aj.600z.
-/ajrotator/*
-/ajs.php?
-/anchor.captainad.
-/annonser/*
-/au.video.yahoo.com/ads?
-/autoPromo
-/banimpress.
-/banman.asp?$subdocument
-/banman/*$subdocument,script
-/banman.isoftmarketing.
-/banmanpro/*&ad
-/banner/Ad
-/banner_db.php?
-/banner_ads.
-/Banner_Management/*
-/banner.php?*http
-/banner_file.php?
-/bannermedia/*
-/banners?*&
-/banners/*$script,object
-/banners/banners.jsp?
-/banners.adultfriendfinder
-/banner*ClickTag=
-/banners.empoweredcomms.
-/banners/*.gif$~background
-/bannery/*?banner=
-/bbccom.js?
-/bbc.com/script/1/config.js
-/bin-layer.
-/blogad_
-/blogads
-/bmp/banman.asp?
-/bnrsrv.*?
-/bs.yandex.ru
-/cas.clickability.com/*
-/clickserv
-/cm8adam
-/cm8space_call$script
-/cms/Profile_Display/*
-/cnnSLads.js
-/cnwk.*widgets.js
-/commercials/splash
-/content.yieldmanager.
-/ContextAd.
-/csDynamic$match-case
-/ctxtlink/*
-/d.m3.net/*
-/da.feedsportal.com/r/*
-/data.resultlinks.
-/de*.myspace.$subdocument
-/delivery.3rdads.
-/descPopup.js
-/destacados/*$subdocument
-/direct_ads.
-/directads.
-/dontblockthis/*
-/DisplayAds$match-case
-/DNSads.html?
-/dsg/bnn/*
-/DynamicAd?
-/DynamicVideoAd?*&
-/dynBanner/flash/*
-/eBayISAPI.dll?EKServer&
-/ecustomeropinions.com/popup/*
-/ekmas.com
-/ERALinks/*$subdocument
-/export_feeds.php?*&banner
-/external/ad.js
-/eyoob.com/elayer/*
-/fairadsnetwork.
-/flashAds.
-/flashbanner/*$match-case
-/flipmedia
-/forms.aweber.
-/freetrafficbar.
-/fuseads/*
-/gamecast/ads
-/gamersad.
-/gampad/google_service.js|
-/get.lingospot.
-/getad.php?
-/get_ad.php?
-/getbanner.cfm?$subdocument
-/google_ads/*
-/google-adsense$subdocument
-/googleAd.js
-/googleframe.
-/hits.europuls.
-/hits4pay.
-/hotjobs_module.js
-/houseads/*
-/html.ng/*$subdocument
-/httpads/*
-/iframe_ad.
-/iframead.
-/iframed_*sessionid=
-/images/ad/*
-/images/promo/player
-/index_files/*.htm|
-/IndianRailways/*$match-case
-/intext.js
-/invideoad.
-/itunesaffiliate
-/job_ticker.
-/js/interstitial_space.js
-/js/ysc_csc_
-/js.ng/site=
-/kermit.macnn.
-/kestrel.ospreymedialp.
-/l.yimg.com/a/a/1-/flash/promotions/*/0*
-/l.yimg.com/a/a/1-/java/promotions/*.swf
-/launch/testdrive.gif
-/layerads_
-/layer-ads.
-/LinkExchange/*
-/linkreplacer.js
-/linkshare/*
-/logos/adLogo
-/lw/ysc_csc_$script
-/marketing*partner$image
-/mac-ad?
-/magic-ads/*
-/media.funpic.*/layer.
-/mediamgr.ugo.
-/medrx.sensis.com.au/*
-/miva_ads.
-/MNetOrfad.js
-/mod_ad/*
-/nascar/*/defector.js
-/nascar/*/promos/*$script,object
-/network.sportsyndicator.
-/network.triadmedianetwork.
-/oas_logic.
-/oasc03.$other,object-subrequest
-/oascentral.
-/oasisi.php?
-/oasisi-*.php?
-/openads/*?
-/openads2/*
-/outsidebanners/*
-/overture/*$subdocument
-/overture_
-/ox.bit-tech.net/delivery/*
-/pagead/*&videoad_start_delay=1
-/pagead/imgad?
-/pageear/*
-/pagepeel$script
-/partner*rotate
-/partner.sbaffiliates.
-/partner.video.syndication.msn.com/*$~other,~object-subrequest
-/partners/*$script
-/partnership/*affiliate
-/peel.js|
-/peelad/*$script
-/perfads.js?
-/phpads/*
-/phpads2/*
-/phpadserver/*
-/pilot_ad.
-/play/ad/*$other,object-subrequest
-/podimages/*$match-case
-/popupjs.
-/promos/*banner.gif
-/promos.fling.
-/printads/*
-/public/ad?
-/publisher.shopzilla.$subdocument
-/r.mail.ru$object
-/rad.*?GetSAd=
-/RequestAdvertisement.
-/rhs_promo_
-/rok.com.com/*
-/rotateAds.
-/rotating_banner
-/rotating.php$subdocument
-/rotation/*.php?
-/rtq.careerbuilder.
-/s3.buysellads.
-/s7121.vsservers.
-/scripts.snowball.com/clinkscontent/*
-/shared/promos/*
-/show.asp?*_sky$subdocument
-/show_ad_
-/show_afs_ads.js
-/show_deals.js
-/show_i.php?
-/showad.$subdocument
-/showads.
-/showbanner.php?
-/ShowFlashAd.
-/skyad.php
-/slideInAd.js
-/small_ad.
-/socialads.js
-/softsale/*$subdocument
-/Splash/Page_Header/*
-/spinbox.freedom.
-/sponsImages/*
-/sponsorad.
-/sponsored$subdocument
-/sponsored.gif
-/support.biemedia.
-/surveyCookie.js
-/svgn.com/*
-/textad?
-/textAd.js
-/tii_ads.js
-/tikilink?
-/tizes/a.aspx?
-/trusearch.net/affblock/*
-/ttz_ad.js
-/userbanners/*
-/valueclick.
-/vendshow/*
-/video.ap.org/*/ad_js.
-/videoad.$match-case
-/videoads.$match-case
-/videoads/*$match-case
-/w1.buysub.$~image
-/webadImg/*
-/webads_
-/whiteglove.jsp?
-/widget.blogrush.com/show.js
-/ws.amazon.*/widgets/q?
-/www/delivery/*.php
-/ygames_e/embed/src/embedPlayer.js
-/ysmads.html
-//wrapper.3dgamers.
-http://171.66.124.80/
-http://196.41.0.207/
-http://72.32.71.244
-http://a.ads.
-http://ad*.emidiate.
-http://abm.hothardware.
-http://ad-uk.
-http://ad.
-http://ad0.
-http://ad1.
-http://ad2.
-http://adbureau.
-http://adclient
-http://adcreative.
-http://adfarm.
-http://adimg.
-http://adimages.
-http://adinterax.
-http://adnet.
-http://adq.
-http://adremote.
-http://adonline.
-http://ads.
-http://ads1.
-http://ads2.
-http://ads3.
-http://ads4.
-http://ads5.
-http://adsatt.
-http://adsearch.
-http://adserv
-http://adsnew.
-http://adsremote.
-http://adstream.*.cgi
-http://adsvr.
-http://adsys.
-http://adt.
-http://adtags.
-http://adtology
-http://adv.
-http://advert.
-http://adverts.
-http://advision.*/getad
-http://adworks.
-http://adx.
-http://affiliates.*.aspx?
-http://afimages.
-http://almobty.com/
-http://altfarm.
-http://avpa.
-http://banner.
-http://banners*&Random=
-http://banners.*http
-http://biz28.
-|http://body.imho.ru/
-http://bwp.$subdocument
-http://cbanners.
-http://cdn.nvero.
-http://circads.
-http://common.*/slider.js
-http://dclk.*.ng/
-http://feeds.*/~a/
-http://fdads.sv.
-http://ffxcam.
-http://getad.
-http://images.*/banners/
-http://jazad.
-http://lads.*-gutter-
-http://mads.
-http://marketing.*http
-http://ng3.ads.
-http://oas-central.
-http://pagead2.$~other,~object-subrequest
-http://partner.$subdocument
-http://promo.
-http://promo2.
-http://rcm*.amazon.
-http://reklama.
-http://richmedia2.
-http://rss.*/~a/
-http://servedbyadbutler.
-http://smartad.
-http://stocker.bonnint.
-http://synad
-http://ttsrc.aroq.
-http://unicast.ign.*.swf?
-http://video.flashtalking.
-http://wrapper.*/a?
-http://*/partners.$subdocument
-!
-! MALICIOUS:
-http://*.cn/*/w.js
-/virusscanner2009.com/*
-antivirusxp2008
-antivirus2009-freescan.
-/googlescanners-360.com/*
-/0scanner.com/*
-0scanner.com#body
-http://www.*.ru/script.js
-/your-windows-scanner.
-your-windows-scanner.com#body
-/onlineprivatescan.com/*
-/scanner-center.com/*
-/antvirushelp.com/*
-antvirushelp.com#body
-/professionalpcscan.com/*
-/google-analistyc.
-/online-antivirus.net/*
-online-antivirus.net#body
-/online-scan.net/*
-!
-! WHITELISTS
-@@1800flowers.com/*/banners/
-@@/a.abc.com/fsp/ads/*.swf$other,object-subrequest
-@@.adbrite.gif|
-@@/admatch-syndication.mochila.com/viewer/*?$script
-@@/ads.hulu.com*.flv
-@@ads.ign.com/fod/*.html
-@@ads.ign.com/*masthead
-@@/ads.imeem.com/*$other,object-subrequest
-@@/ads/video/*.flv$other,object-subrequest
-@@/ads1.msn.com/ads/*.jpg$other,object-subrequest
-@@ads1.msn.com/library/dap.js
-@@/adserver.yahoo.com/a*LREC$script
-@@.adserver.yahoo.com/*=HEAD&
-@@.amarillas.cl*/Adverti
-@@*/autoplayer/*$object
-@@.battletech-mercenaries.com/banners/
-@@.bbc.co.uk/*/banners/*logo
-@@.belointeractive.com/*/ads/*@*?|$script
-@@.bnet.com/advertising/images/
-@@.brightcove.com*/viewer/
-@@.cbc.ca/*/promos/
-@@.cbsnews.com/*video;
-@@cdn.fastclick.net/fastclick.net/video/
-@@.cnet*.com/Ads/*/faith_v2.swf
-@@/cnn_adspaces.js|
-@@cosmos.bcst.yahoo.com/scp_v3/detectomatic/
-@@.crutchfield.com*/banners/
-@@despair.com/banners/
-@@.doubleclick.net/*sect=player;
-@@.doubleclick.net/pfadx/nbcu.*/video$other,object-subrequest
-@@doubleclick.net/pfadx/sw.nol/
-@@.doubleclick.net/*/DartShell$other,object-subrequest
-@@doubleclick.net/*/videogallery/$other,object-subrequest
-@@.doubleclick.net/crossdomain.xml$other,object-subrequest
-@@.doubleclick.net/pfadx/*omniturePlayer
-@@.doubleclick.net/ad/st.news/*;tile=0;$other,object-subrequest
-@@.doubleclick.net/pfadx/*;vidID=$other,object-subrequest
-@@.doubleclick.net/pfadx/video.*preroll$other,object-subrequest
-@@.doubleclick.net/adj/playergen.
-@@.doubleclick.net*/videos.$other,object-subrequest
-@@.doubleclick.net/pfadx/*.nol/$other,object-subrequest
-@@.doubleclick.net/adx/*.video/$other,object-subrequest
-@@/emoltv.emol.com/player.swf?
-@@/espn360/banner?$subdocument
-@@gcirm.gannettvideo.com/*Video$script
-@@.gov/*
-@@.flux.com/-/Content.ashx?$other,object-subrequest
-@@flyordie.com/*&affiliate
-@@.forbes.com*/video
-@@fox*.com*video$object
-@@.fox.com/fod/$subdocument
-@@.freeonlinegames.com/advertising/hosted_loader.swf?
-@@.gametrailers.*player$image
-@@/getPlaylist$script
-@@.gtcc.edu/docs/*/banners/
-@@images.neopets.com/items/ad_$image
-@@.imeem.com/*/video_player.swf?$other,object-subrequest
-@@int1.fp.sandpiper.net/$other,object-subrequest
-@@judo.salon.com/$script
-@@.js.yimg.com/combo?*/carousel_*/sponsored_links
-@@js2.yimg.com/us.yimg.com/a/1-/java/promotions/js/ad_eo_1.1.js
-@@.lightningcast.com/*:general&$script,object
-@@.liveuniversenetwork.com/zones.php?
-@@/ll.static.abc.go.com/streaming/move/*
-@@/mediacenter/*.flv|
-@@meevee.com/ads/adIframe.aspx?
-@@microsoft.com/*/banners/$image
-@@.mlb.com/shared/*/video/$other,object-subrequest
-@@.mlb/homepage$other,object-subrequest
-@@/mp3toys_files/*
-@@/n*ad.doubleclick.net/pfadx/com.ytpwatch.$other,object-subrequest
-@@NBC*preroll.$other,object-subrequest
-@@/nbcu.nbc/*$other,object-subrequest
-@@.nbl.com.au/*/0*-image.
-@@.newsarama.com/*/hbx.js
-@@newsimg.bbc.co.uk/media/*promo
-@@.newsweek.com/players/v2/*
-@@nissanusa.com/
-@@/NissanLiveSets_$script
-@@nytimes.com/ads/mm
-@@/o.aolcdn.com/ads/adsWrapper.js|
-@@/oascentral.feedroom.com*&
-@@/openad.tf1.fr/*/mediacenter/*
-@@//partner.de/$subdocument
-@@/podimages/*_tab.
-@@.popsci.com/sites/all/modules/omniture/
-@@rad.live.com/*&DPJS
-@@/RealMedia/ads/adstream_mjx.ads/*?*type=video
-@@/resources-p*.imeem.com/*
-@@/reviews.cnet.com/Ads/common/adclient/*.swf
-@@.sears.com/data/
-@@/service.tremormedia.com*/video@$subdocument
-@@/smh.com.au/images/ads/*.jpg
-@@.space.com/flashvideo/
-@@.spike.com/*spike-functions.js?
-@@/static.ak.fbcdn.net/*/ads/*$script
-@@.stream.aol.com$other,object-subrequest
-@@.telstra.com.au/banners/*
-@@Table_files/$subdocument
-@@.thenewsroom.com//$other,object-subrequest
-@@/TVads.ie/Ads/*
-@@.usps.com/
-@@vidavee.net*video$subdocument
-@@/video/player$~image
-@@/video.eurosport.
-@@/video/shareplayer.swf?videoID=
-@@video.on.nytimes.com/
-@@video.wwe.com$object
-@@videos.theonion.$other,object-subrequest
-@@/widget.slide.com/*/preroll.swf
-@@yahoo.com/a?*headr
-@@.videogamer.*/videoad.xml?
-@@http://*.abc.go.com/fep/player?src=
-@@http://ads.biggerboat.com/$script
-@@http://ads1.msn.com*=video$object
-@@http://*.cbs.com/video/video.php?
-@@|http://gasprices.mapquest.com/
-@@|http://*.kidswb.com/video
-@@http://media*video*.flv|
-@@http://media.*.flv|
-@@http://*.mlb.com/media/player/
-@@|http://*.mtvmusic.com/video/?id=
-@@http://www.nbc.com/*/video/episodes.
-@@|http://oascentral.*Top*?|$script
-@@|http://oascentral.discovery.com/*
-@@|http://www.people.com/people/*/photos
-@@http://www.tv.com/video/
-@@http://promo.ebay.*?GetCrossPromos
-@@|http://promo.verizon.com/
-@@http://video.*.flv
-@@http://*videodetective.com/
-@@|http://*.wikimedia.org/wikipedia/
-!
-!
-! *** Fetched from: http://easylist.adblockplus.org/easylist-element_rick752.txt ***
-!
-!
-! Rick752's EASYELEMENT (optional English element-hiding subscription)
-! | Last Modified: 30oct2008 | http://easylist.adblockplus.org |
-!Expires after 5 days
-!
-##body > div+ div#outerslice
-##body > div + div#outerslice + div.topleader
-#*(class*=_advert_)
-#*(id*=_advertisement)
-#*(id*=_spons_)
-#div(class=ad)
-#*(id^=ad)(id$=300x250)
-#*(class^=ad)(class*=300x250)
-#*(id^=ad)(id*=728x90)
-#*(id^=ad)(id$=banner)
-#*(class^=ad)(class*=eaderboard)
-#*(id^=ad)(id*=kyscraper)
-#*(class^=ad-)(class*=kyscraper)
-#*(id*=ad300x250)
-#*(class*=ad300x250)
-#*(id*=Ad300x250)
-#*(class*=Ad300x250)
-#*(ad-island)
-#div(id^=ad-)(class=md)
-#*(id^=ad-leader)
-#*(id^=ad-splash)
-#*(class=ad_banner)
-#div(id^=ad_)(id*=728)
-#*(ad_Banner)
-#*(ad_bar)
-#*(ad_bg)
-#*(id^=ad_center)
-#div(id=ad_content)
-#*(id^=ad_footer)
-#*(id=ad_iframe)
-#*(id^=ad_leader)
-#*(id^=ad_rectangle)
-#*(id=ad_right)
-#*(class=^ad_side)
-#*(ad_sponsor)
-#*(id^=ad_tile)
-#*(class^=ad_unit)
-#div(class^=ad_wrapper)
-#div(id=ad1)
-#*(class^=ad120x)
-#div(id=ad2)
-#*(adarea)
-#*(AdBanner)
-#*(class^=adbanner)
-#*(class^=adBanner)
-#*(id^=adBanner)
-#*(adBar)
-#div(id$=Adbar)
-#*(id^=adBoard)
-#*(class^=adbottom)
-#*(adBox)
-#*(adbox)
-#*(AdCol)
-#*(class^=adcolumn)
-#td(id=AdContainer)
-#*(addiv)
-#*(class=^adhead)
-#*(adHead)
-#*(adHeadline)
-#*(Ad2Header)
-#*(adHolder)
-#*(id^=adLeader)
-#*(class^=adlink)
-#*(id^=adlink)
-#*(id*=_adlink)
-#*(id^=adMarket)
-#*(id=admid)
-#*(id^=admiddle)
-#*(admpu)
-#*(adpad)
-#*(AdPlaceHolder)
-#*(id^=AdPlaceholder-)
-#*(adrectangle)
-#*(id^=adRight)
-#*(class^=adRight)
-#*(class^=AdRight)
-#*(adRow)
-#td(class=ads)
-#*(ads-footer)
-#*(id^=ads.)
-#*(id^=ads-top)
-#*(adsBar)
-#*(adsBox)
-#*(class^=adsbox)
-#*(id*=AdsContainer)
-#*(ads_self)
-#div(class^=adsense)
-#div(class^=adSlug)
-#*(id*=AdsMiddle)
-#*(id^=adMini)
-#*(adsquare)
-#*(adspace)
-#*(adSpace)
-#*(id^=adspace)(id*=header)
-#*(adSpot)
-#*(class^=adSpot)
-#*(id^=adspot-)
-#*(adStrip)
-#div(id^=adTag)
-#*(class^=adText)
-#*(class=adtext)
-#*(id=adtext)
-#*(class=adtitle)
-#*(class^=ad top_)
-#*(id=adtop)
-#*(id^=AdTop)
-#*(id^=advert)(id*=column)
-#*(class^=advert-)
-#*(class^=advertContainer)
-#img(alt^=advertise)
-#div(id^=advertisement)
-#div(class*=advertisement)
-#*(advertisingColumn)
-#*(advertisment)
-#*(id^=advertRight)
-#*(class^=adverts-)
-#*(class^=advright)
-#*(adwords)
-#*(adwrapper)
-#*(adxLeaderboard)
-#*(articleAd)
-#*(id*=ArticleAd)
-#*(articleAds)
-#*(class^=articleExtras)
-#*(id^=banAd)
-#*(class*=banner_ad)
-#*(class*=bannerAd)
-#*(class*=BannerAd)
-#*(id*=_bannerAd)
-#*(id*=BannerAd)
-#*(class*=bannerholder)
-#*(id^=bigBanner)
-#*(class*=BigAd)
-#*(class=bigaddiv)
-#*(billboard_ad)
-#*(blog_ad)
-#*(class*=blogAdvertisement)
-#*(id^=bnrAd)
-#div(id*=boombox)
-#*(bottomAdvertise)
-#*(box_ad)
-#*(id^=boxad)
-#*(boxyads)
-#*(boxAd)
-#*(id$=cellAd)
-#*(channel_ad)
-#*(columnad)
-#*(companionAd)
-#*(id*=consoleAd)
-#*(id*=containerAd)
-#*(id*=containerSqAd)
-#*(contentad)
-#*(id$=ContextualAds)
-#*(dart_ad)
-#*(ds-mpu)
-#*(id*=FloaterAd)
-#*(footer_ads)
-#*(genericadtext)
-#*(globalad)
-#*(id*=google_ad)
-#*(name*=google_ads_)
-#*(id*=GOOGLE_ADS)
-#*(class^=googlead)
-#*(name*=GoogleAd)
-#*(id*=GoogleAd)
-#*(id=googleAfcContainer)
-#div(class^=google468)
-##div#header + div.leader
-#div(id^=headerad)
-#*(id$=headerAd)
-#*(header_ad)
-#*(id$=header-ad)
-#*(header-ads)
-#*(horizontalAd)
-#*(inlinead)
-#*(id=inner_ad)
-#*(inpostad)
-#div(id=interruptor)
-#*(id=islandad)
-#*(leaderad)
-#*(div^=leftads)
-#*(mainad)
-#*(id=MainAds)
-#*(id^=mediumAdvert)
-#*(menuads)
-#*(microsoft_ad)
-#*(misc-ad)
-#*(class$=module ad)
-#*(class=mpu)
-#*(id=mpu)
-#*(mpuAd)
-#*(id*=MpuAd)
-#div(id*=ninemsn)
-#*(id*=OasContainer)
-#*(otherads)
-#*(PanelAd)
-#*(panelTextAd)
-#*(partner_links)
-#div(id^=promo300)
-#*(id=promotext)
-#div(quigo)
-#*(class^=rail-ad)
-#*(id^=right_ad_)
-#*(id^=rightad)
-#*(class^=rightad)
-#*(rightAdvert)
-#*(side-ad)
-#*(class^=skyscraper)
-#*(id^=skyscraper)
-#div(id*=skyscraper)(style*=width: 160px;)
-#div(id=smallAd)
-#*(small_banner)
-#div(servedAd)
-#*(spnsr)
-#*(id*=sponLink)
-#*(spons_links)
-#*(id*=sponsered)
-#div(sponsor)
-#*(id*=sponsor_ads)
-#*(id*=sponsor_block)
-#*(id^=sponsorads)
-#*(sponsorBar)
-#*(SponsorBg)
-#*(id*=sponsored)
-#div(class^=sponsored)
-#p(class=sponsored)
-#*(class^=Sponsored)
-#*(class*=sponsored-links)
-#*(class$=SponsoredGrid)
-#*(id*=SponsoredList)
-#*(id$=sponsors)
-#*(class$=sponsors)
-#*(sponsorbox)
-#*(sponsorLinks)
-#*(spot-ads)
-#*(id=squareAd)
-#*(storyad)
-#*(id^=SWF_AD)
-#*(id*=tableAds)
-#*(textad)
-#div(class^=textad)
-#*(class$=TextAd)
-#*(class^=text-ad-)
-#*(id*=textads)
-#*(textlinkads)
-#*(id=textlinkWrapper)
-#*(top-ad)
-#*(id$=top_ad)
-#*(id$=TopAd)
-#*(id=topad)
-#*(id*=topAd)(id*=x90)
-#*(topAdArea)
-#*(topadblock)
-#*(class=topadbox)
-#*(id^=topAdContainer)
-#*(topAdGroup)
-#*(id^=topadvert)
-#*(id=topadouter)
-#*(topads)
-#*(id^=towerad)
-#*(upperad)
-#div(id^=WctlDartHtml)
-#*(class^=wideAd)
-#div(id^=wrapper_wnsz)
-1001webgames.com,1001spill.no,1001spel.se#*(class^=advert)
-1911encyclopedia.org#div(class^=google_)
-2cpu.com##td\[width="155"]:last-child
-2cpu.com#td(id=right-ad)
-2cpu.com#iframe(src*=2cpu/)(src*=side)
-43things.com#div(ads)
-about.com#div(id^=adL)
-about.com#div(adB)
-about.com#div(id=s3)
-allmalaysia.info#tr(height=105)
-allmusic.com,infoweek.ca,fark.com,hotlinkfiles.com,informit.com,knoxnews.com,pcmag.com,swamppolitics.com,theglobeandmail.com,tucsoncitizen.com,vnunet.com,xml.com#*(leaderboard)
-allmusic.com#div(id^=ad)
-altavista.com#div(spons)
-anandtech.com##div.adcontainer+div.HeaderSurround
-anandtech.com#div(boxfooter)
-anandtech.com#div(topmarq)
-anonymouse.org#div(mouselayer)
-answers.com#div(class=leaderBoardDiv)
-answers.com#*(class=msnadbox)
-aol.com#div(rA)
-aol.com#div(admodule)
-aol.com#div(id=outerTwrAd)
-aol.com#div(id=ad)
-aol.com#div(id=dmn_results)
-aol.com#div(rgtAd)
-appleinsider.com#td(width=180)
-appleinsider.com#td(width=150)(valign=top)
-appleinsider.com#table(aadbox)
-archiv.to#div(style*=top: 13px; left: 10px; height: 500px;)
-arstechnica.com#div(class^=Ad)
-arstechnica.com#div(id=Banner)
-artofproblemsolving.com#div(class=aopsadvert)
-ask.com#div(class$=_ad)
-ask.com#div(class=spl_shd_plus)
-askville.amazon.com#div(class^=ad_)
-atom.com#div(id^=iframe_container)
-au.news.yahoo.com#div(class=rec)
-au.news.yahoo.com#div(id=mrec)
-au.movies.yahoo.com,au.blogs.yahoo.com#table(class$=mv-wraptable)(width=750)(height=112)
-au.yahoo.com#div(id^=partner-)
-au.yahoo.com#div(id*=-ad-)
-au.yahoo.com#div(id*=-advertorial-)
-audioreview.com#div(id=_ctl10_HotDeals)
-autotrader.com#*(class$=_advertisement)
-battleon.com##td\[width="180"]:last-child
-bbc.co.uk#div(id^=bbccom_)
-bit-tech.net##div\[style*="width: 925px; height: 115px"]
-bjorn3d.com#div(class*=_bigad_)
-blackberryforums.com#td(width=160)(align=left)
-bloggingstocks.com#div(id=topleader)
-bubblebox.com#div(class=wide ondertop)
-bubblebox.com#A(class=img_link)
-businessweek.com#div(AllAds)
-buddytv.com#div(class*=_ad)
-buy.ebay.com.au#div(id=rtm_div_309)
-buy.ebay.com.au#div(id=rtm_div_310)
-calgarysun.com#div(subbanner)
-canmag.com#div(popinbox)
-canmag.com#td(style*=advertborder)
-canmag.com#div(sidebar-straight)
-capitalnews9.com,news10now.com,news14.com#div(style$=height: 90px; width: 22px;)
-capitalnews9.com,news10now.com,news14.com#div(style^=width: 160px; float: right;)
-thecelebritycafe.com#td(height=250)(bgcolor=#ffffff)(colspan=3)
-thecelebritycafe.com#table(width=135)(height=240)
-cardomain.com#div(class=ad community)
-chaos-laboratory.com#table(width=450)(height=380)
-chron.com#div(class$=TopAd)
-chron.com#td(class=noPrint)(width=300)
-comedycentral.com#div(id^=ad_)
-computerworld.com#table(height=290)(bordercolor=#bbbbbb)
-computerworld.com#div(class=imu module)
-cnet.com#div(asl_margin)
-cnet.com#div(rb_pft_ad)
-cnet.com,download.com,news.com#div(rb_pro2_div)
-cnet.com,download.com,news.com#div(id=topMPU)
-cnet.com#div(class=ads)
-cnet.com#*(adpremier)
-cnet.com#div(id$=_ad_ss)
-cnet.com#div(class^=dh_vend)
-cnet.com#div(class*=_prem_shell)
-cnet.com#div(id=sidedoor)
-cnettv.com#div(logoBoxParent)
-cnn.com#div(class$=AdBox)
-cnn.com#table(id^=cnn)(id$=ad)
-cnn.com#div(class=cnnStoryElementBox)
-cnn.com##div.cnnPad9Top > div#cnn_cb336
-consumerist.com#div(class*=ad-pad)
-computerandvideogames.com#div(class=ads_mpu)
-computerworld.com#div(class*=ad-space)
-computerworld.com#div(class=subcolumncomponent)
-computerworlduk.com#div(id=topBanner)
-crn.com#div(adcolumnwrapper)
-custompc.co.uk#div(class=mpuBox)
-dailymail.co.uk#div(id^=mpu_)
-dallasnews.com#div(secondarycontainer)
-databasejournal.com#table(width=125)(align=right)(cellspacing=3)
-timeanddate.com#fieldset(style=float: right; width: 180px;)
-delicious.com#div(id=spns)
-detnews.com#p(adAlert)
-deviantart.com#div(id^=ad-)
-deviantart.com#div(id^=adso-)
-deviantart.com#div(class^=sleekadbubble)
-devshed.com#div(id=resultright)
-devx.com#table(style*=width: 444px)
-digg.com#div(class*=_ad)
-digitalspy.co.uk##div.box300 + table\[height="250"]\[width="300"]
-digitalspy.co.uk#table(style=width: 300px; height: 250px;)
-digitalspy.co.uk##div\[\;]
-dir.yahoo.com#td(width=215)
-dir.yahoo.com#div(ads)
-discovery.com#embed(id=splashFO)
-disney.go.com#div(id=BANNERDIV)
-domaintools.com#*(g-keywords)
-domaintools.com#div(bannerContainer)
-download.com#div(id^=launchpad-)
-download.com#div(class$=-ad)
-download.com#div(id=contentAux)
-downloadsquad.com#*(topleader)
-dragonfable.com##td.tdclear\[width="125"]:last-child
-drugs.com#div(id=topbanner)
-ebaumsworld.com#div(id=eacs-sidebar)
-ebaumsworld.com#iframe(id=mediumrect)(width=300)
-ebay.co.uk#div(id=rtm_html_274)
-ecommercetimes.com#div(class*=slink)
-economist.com#*(id*=banner)
-economist.com#div(class*=banner)
-edmunds.com#table(class*=spotlightArea)
-eetimes.com##div\[style="border: 1px solid rgb(204, 0, 0); padding: 0px;"]
-eetimes.com#table(width=131)(bgcolor=#ffffff)
-elitistjerks.com#div(easylist)
-embedded.com##table\[width="975"]:first-child
-embedded.com#div(id=cc_container)(style=width: 336px;)
-empireonline.com#td(width$=0)(bgcolor=#000000)
-eweek.com#div(id^=hp_ad_)
-eweek.com#table(module_bg)
-eweek.com#table(width^=4)(height^=2)(id=Table_01)
-excite.com#tr(mexContentBdr)
-facebook.com#div(class*=_ad_)
-facebook.com#*(adcolumn)
-facebook.com#div(id=sidebar_ads)
-fanpop.com#div(style^=width: 300px; height: 250px; background-color:)
-fark.com#td(tbcj)
-fark.com#div(rightAd)
-fark.com#div(topAd)
-fark.com#div(rightSideRightMenubar)
-firstcoastnews.com#*(gtv_caption)
-firstcoastnews.com#span(gtv_source)
-flickr.com#td(AdColumn)
-flickr.com#div(id=AdBlock)
-foodnetwork.com#div(id=gutter_area)
-forbes.com#*(fifthN)
-forbes.com#span(smallgreytxt)
-forbes.com#div(id=dynamicAdWinDiv)
-forestryforum.com#td(width=145)
-forums.audioreview.com#td(bgcolor=#ffffff)
-forums.gametrailers.com##td\[bgcolor="#a5abb9"]:first-child > div\[align="center"]:first-child
-forums.motortrend.com#div(id$=_ncLinksYMMColumn)
-forums.mozillazine.org#*(class*=gas)
-forums.scifi.com#table(bgcolor=#3a3163)
-fox.com#td(colspan=6)
-fox.com#div(id$=Ad)
-fox.com#div(class*=-module-)(class$=ad)
-foxnews.com#div(class=root)(id=feat)
-foxnews.com#div(hide1)
-foxnews.com#div(id*=PromoBox)
-foxnews.com#div(id^=sponsor_)
-foxnews.com#div(bannertwins)
-foxnews.com#div(id=corrSpon)
-foxnews.com#*(marketplace)
-foxsports.com#div(id^=ad300x250)
-foxsports.com#table(class=big7)(height=41)
-foxsports.com#table(width=294)(height=400)(bgcolor=#fffff0)
-foxsports.com#div(class=dMSNME_1)
-foxsports.com##*.hdrContainer > table\[width="980"]
-foxsports.com##table\[width="770"]:first-child
-foxsports.com##*#commentsDiv > *:first-child + DIV\[style="height: 330px; position: relative;"]
-freeservers.com#div(id*=aws)
-freeworldgroup.com#iframe(src*=banner)
-fudzilla.com#div(id=showcase)
-g4tv.com#div(class=mid_ad)
-gadgetzone.com.au#td(style=width: 300px;)
-gadgetzone.com.au#div(id=HeroAd)
-gadgetzone.com.au#div(id=Leaderboard-placeholder)
-games.yahoo.com#div(id^=ad-)
-gamespot.com#div(class=cb pb10)
-gametrailers.com#IMG(height=98)(width=200)(src=/images/spacer.gif)
-gamevee.com#div(style*=width: 728px; height: 100px;)
-gamevee.com#div(style*=width: 300px; height: 270px;)
-geocities.yahoo.com#table(height=90)(bgcolor=#ffffff)(width=750)
-gethuman.com#td(width=158)(bgcolor=#00468c)
-getprice.com.au#*(id*=AdAware)
-gettherhythm.com,actionext.com#img(width=336)(height=280)
-gizmodo.com.au#div(class=medium_rectangle_container)
-gpsreview.net#tr(id=lead)
-gpsreview.net#div(style$=width: 450px; height: 450px;)
-golivewire.com##div\[style*="height: 292px;"]\[style*="/stickynote"]
-golivewire.com#img(width=132)(height=83)
-goodgearguide.com.au#div(class^=marketplace_)
-google.com,google.ca,google.co.uk#div(ads)
-google.com,google.ca,google.co.uk,google.com.ar,google.com.au,google.com.es,google.be,google.nl#div(id^=tpa)
-google.com#div(spl)
-google.com,google.ca,google.co.uk,google.com.ar,google.com.es,google.com.au,google.be,google.nl#table(width=25%)(align=right)
-google.com#table(class=lads)
-google.com#*(class^=promo)
-google.com,google.com.au,google.co.il#div(id=tads)
-google.com##table\[style="border: 1px solid rgb(0, 102, 102);"]
-google.com,google.com.au,google.co.uk,google.ca#table(id=mbEnd)(width=30%)
-google.com#table(class=ra)(align=right)(width=30%)
-googletutor.com##div\[style="width: 125px; text-align: center;"]:last-child
-guardian.co.uk#div(spacedesc_mpu_div)
-guidelive.com#td(id^=biright)
-hardocp.com#div(class^=thead)
-health.discovery.com#embed(id=maincontentFO)
-health.yahoo.com#div(id=yh-ysm)
-health.yahoo.com#div(yh-ovt2a)
-health.yahoo.com#div(class$=ysmcm)
-helpwithwindows.com#div(id=desc)
-helpwithwindows.com#span(id=ad)
-hexus.net#div(id=cColAd)
-hotmail.com#td(width=300)(style^=padding-top)
-huffingtonpost.com#div(class^=ad_block)
-hummy.org.uk##div#userlinksguest + p\[align="center"]
-hvac-talk.com#td(style=padding-left: 10px;)
-hwt.dk#div(class*=-banner)
-icalshare.com#div(style*=adsense)
-icerocket.com#table(advertising)
-ign.com#div(class=medRec)
-ign.com#div(id$=_ad)
-idg.com.au#div(class^=marketplace_)
-idg.com.au#div(class*=tjobbox)
-idg.com.au#div(id=c1_jsbox)
-idg.com.au#div(class^=careerone)
-idg.com.au#div(class=black_box)
-idg.com.au#div(id=ebay_search_box)
-idg.com.au#img(src*=/C1_)
-imageshack.us##table\[class="table_decoration"]\[width="760"]\[bordercolor="#cccccc"]>tbody>tr>td:first-child
-imageshack.us#div(id=doneaddiv)
-imdb.com#div(id$=adrhs)
-imdb.com#div(class$=-ad-container)
-imdb.com#div(id^=swf_)(style*=position: absolute;)
-imdb.com#div(id^=swf_)(align=right)
-imdb.com#*(id=^swf_)(id*=_728x90)
-imdb.com#div(id^=swf_rectangle)
-imdb.com##div.aux-content-widget-3\[style="padding-top: 6px;"] + div.aux-content-widget-3
-imdb.com##layer div\[id$="supertab"]
-imdb.com##body >div#wrapper > div\[align="center"]
-imdb.com#div(class=imdb_lb)
-imeem.com#div(id^=PanelImeemAd)
-imtranslator.net#iframe(id=topbanner)
-infoworld.com#td(width=240)
-internetautoguide.com#table(class=TableClass)
-inthenews.co.uk#div(id$=YahooAds)
-itbusiness.ca#table(id=Table1)
-itnewsonline.com#td(width=120)
-itnewsonline.com#*(id^=rmi)
-itnewsonline.com#table(width=300)(height=250)
-itworld.com#table(width=100%)(bgcolor=#e9e9e9)(style^=border: 1px solid silver;)
-jango.com#div(class^=ad bigblock)
-javaworld.com#div(techwords)
-kayak.com#div(id=nrAds)
-kerneltrap.org#div(id^=block-block-)(id$=4)
-kick2kick.net#div(class=ads)
-knoxnews.com#div(class=big_box)
-latimes.com#div(id*=ad_wrapper)
-latimes.com#div(adheader)
-latimes.com#div(quigoheader)
-lifespy.com#div(class=SRR)
-linuxinsider.com#p(class=story-cip)
-linuxvirgins.com#*(sidebar-b)
-live.com#div(id*=RadAd)
-live.com#div(id=AdContainer)
-live.com#div(id$=AdPart)
-livejournal.com#div(class^=ljad)
-lowbird.com#div(class=teaser)
-lyrics007.com#td(width=770)(height=110)
-lyrics007.com##br + div\[align="center"]
-lyrics007.com#div(id=jangoWrapper)
-macdailynews.com#div(adbox)
-macnn.com#div(id=supportbod)
-macworld.co.uk#DIV(id=topBannerSpot)
-madison.com#td(bgcolor=#e5e5e5)(width=175)(height=615)
-madison.com#div(ldrbrd_cntnr)
-madison.com#div(mrktng_ad_wrp)
-mail.google.com#div(class^=rh)
-mail.google.com##*.XoqCub > \[style="width: 189px;"]
-mail.google.com#div(style^=width: 189px;)(class^=yx)
-mail.google.com#div(class=slwyWc)
-mail.google.com#SPAN(class=iFOJMb)
-mail.live.com#div(class=ToolsCustomerCommunication)
-mail.yahoo.com#table(height=250)(background$=full_background_2.jpg)
-mail.yahoo.com#div(nwad)
-mail.yahoo.com#table(width=425)(height=580)(bgcolor=#ffffff)
-mail.yahoo.com#div(id=swads)
-mail.yahoo.com#div(id=northbanner)
-mail.yahoo.com#div(id=H2_div)(style^=display)
-mapper.acme.com#div(id=ad)
-mapquest.com#div(id=top-header-container)
-marketingpilgrim.com#div(id=adblock)
-mediafire.com#iframe(id=iframe_linkto2)
-megagames.com#table(width^=7)(height=92)
-megaupload.com#div(id=filetag)
-mercurynews.com#div(adElement)
-mercurynews.com#div(articleEmbeddedAdBox)
-metacafe.com#div(id=mediumRectangle)
-metacafe.com#DIV(class=MedRect)
-microsoft-watch.com#div(topBannerContainer)
-mofunzone.com#td(id=ldrbrd_td)
-money.cnn.com#div(id=MagOFIE)
-mortgageguide101.com#div(id=ppc)
-mousebreaker.com#div(id^=x)
-mousebreaker.com#div(class^=skyslot)
-msn.com#div(id=lgad)
-msn.com,msn.ca#div(id^=ads_)
-msn.com#div(shoppinglayout)
-msn.com#div(class*=textSmallGrey)
-msn.com#div(id^=ad-front)
-msn.com#div(class=dapad)
-msnbc.msn.com#div(id=Dcolumn)
-mtv.com#div(thirdColumnAd)
-myspace.com##table\[width="800"] > tbody > tr > td > div\[style="height: 90px;"]
-myspace.com#div(id$=_leaderboardDiv)(style=height: 90px;)
-myspace.com#div(id*=_adspecial)
-myspace.com#div(id=cmsContent)
-myspace.com#div(id=ad-wrap)
-myspace.com#div(id=marketing)(style^=width: 960px)
-myspace.com#div(class=srchfieldLayer)
-myway.com#a(id^=rs)
-nascar.com#div(id=cnnStore)
-nba.com#table(width=938)
-nbc.com#div(b-companion-ad)
-neopets.com#div(id^=ban)
-neowin.net#div(id=content-main-square)
-neowin.net#div(id=header-banner)
-neowin.net#div(id=sidebar-skyscraper)
-neowin.net#div(id=content-leaderboard)
-nervepop.com#div(id=topBanner)
-netmag.co.uk#div(id^=ad_space)
-netmag.co.uk#div(style*=width: 320px; padding-top: 0px; height: 290px;)
-networkworld.com#div(id^=lb_container)
-news.com.au#div(ad-network)
-news.com.au#div(id=special-promotion)
-news8austin.com##td\[width="180"]:last-child
-newscientist.com,newscientisttech.com,newscientistspace.com#div(id*=mpu)
-newsfactor.com#td(background$=-ad.gif)
-newsmax.com#td(noprint1)
-ninemsn.com.au#div(id=ad)
-notebookreview.com#div(id=topBanner)
-nwsource.com#div(adv-masthead)
-nysun.com#div(class=ad-300-250)
-nytimes.com#ul(advertisementThumbnails)
-observer.com#p(advertisement)
-opendns.com#div(id$=-ads)
-pantagraph.com##body > div.omniture + * + table\[width="1000"]
-pantagraph.com#*(id^=dropinbox)
-payments.ebay.com.au#div(class=pcontent)
-penny-arcade.com#div(id=adhoriz)
-people.com#div(id=adTop)
-pcmag.com#*(class^=AdModule)
-pcmag.com#table(class=PremPart_Container)
-pcmag.com##td\[valign="top"]\[_base_target="_top"]:last-child
-pcmag.com#td(class^=mrktcell)
-pcmag.com#div(class^=spotlight)
-pcmag.com#div(class=storybox)
-pcworld.com#div(class^=adMkt2Col)
-pcworld.com#div(class*=Ad)
-pcworld.com#div(class=areaBanner)
-pcworld.co.nz,pressf1.co.nz##td\[width="180"]\[align="center"]:last-child
-pcworld.com#div(id=topAd)
-pcworld.co.nz,pressf1.co.nz#div(style=width: 160px; float: left;)
-people.com#div(class$=adTout)
-phonescoop.com#td(width=750)(height=125)
-pistonheads.com#td(class=mpu)
-playkidsgames.com#table(width=320)(height=219)
-playkidsgames.com#table(height=105)
-popphoto.com#table(width=990)(height=110)
-popphoto.com#table(width=300)(bgcolor=#dddddd)
-popsci.com#div(id=header_row1)
-portableapps.com#div(id=block-block-4)
-prefixmag.com#div(id^=banner-)
-propeller.com#div(id^=mn)
-ps3fanboy.com#div(class=medrect)
-pspfanboy.com#div(class=topleader)
-ratemyprofessors.com#div(withAds)
-ratemyprofessors.com#div(rmp_leaderboard)
-realclearpolitics.com#div(id^=ad-)
-realclearpolitics.com#div(id$=-ads)
-realclearpolitics.com#div(id$=-ad)
-realclearpolitics.com#div(right-wide-skyscraper)
-reference.com#div(class^=banner ad)
-reference.com#*(spl_unshd)
-reference.com#*(bannerTop)
-restaurants.com#table(width=760)(height=95)(border=0)
-reuters.com#div(class^=adButton)
-rollingstone.com#div(ad)
-rollyo.com#div(style=margin: 0pt; font-size: 100%; padding-bottom: 10px;)
-rollyo.com#div(style=margin: 0pt 0px 0px; font-size: 100%; padding-bottom: 10px;)
-rottentomatoes.com#td(height=100)(align=center)
-rottentomatoes.com#div(header_leaderboard_ad_container)
-runescape.com#div(id=tb)
-sbsun.com#div(articleEmbeddedAdBox)
-sci-tech-today.com##table\[width="980"]:first-child + TABLE + TABLE\[width="980"]
-sci-tech-today.com#TD(width=346)(bgcolor=#eeeeee)
-sciencemag.org#td(id=SideColumnCell)
-search.live.com#div(class^=sb_ads)
-search.netscape.com#div(SLL)
-search.yahoo.com#div(class=yschbbox)
-search.yahoo.com#div(class=bbox)
-search.yahoo.com#div(id=east)
-sensis.com.au#div(class^=pfp)
-sevenload.com#div(id=superbaanner)
-sevenload.com#div(id=skyyscraperContainer)
-sevenload.com#div(class=textAd)
-sfgate.com#div(sfg_ads001)
-sfgate.com#div(class^=ad top)
-shopping.com#div(class^=lvl2Box)
-shopping.yahoo.com#div(class=ovt)
-siliconchip.com.au,v8x.com.au##table\[style*="background: rgb(227, 235, 243) none repeat scroll 0% 0%; width: 310px;"]
-sitepoint.com#div(featuredproduct)
-slashdot.org#div(id^=fad)
-slashfilm.com#td(style*=300adback)
-slate.com#hr
-sltrib.com#td(class=preHeaderRegion)
-sltrib.com#div(class*=AdBox)
-sourceforge.net#div(id^=fad)
-sportsline.com#td(class^=cshoptxt)
-space.com##table\[width="968"]:first-child
-space.com#table(height=285)(bgcolor=#000000)(width=321)
-spikedhumor.com#p(class=ad)
-spinner.com#div(class$=_aol)
-sportsillustrated.cnn.com#td(width=180)(id=cnnRightCol)
-sportsline.com#table(class=banner_bg)(width=985)
-sportsline.com#table(width=310)(align=left)
-sportsline.com#td(width=160)(align=center)
-staticice.com.au#td(height=80)(align=center)
-staticice.com.au##table\[rules="none"]\[style="border: 1px solid rgb(135, 185, 245);"]
-stylusstudio.com#div(id=popwin)
-superpages.com#div(ads)
-superpages.com#td(relatedppc_text)
-sys-con.com#table(width^=9)(height=95)(align=center)
-tampabay.com#div(adtag)
-teagames.com#div(id^=TopBanner)
-tech.co.uk#div(id*=TopAd)
-technewsworld.com#div(class$=-slinks)
-technorati.com#div(id=banner)
-techrepublic.com.com#div(class=hotspot)
-techrepublic.com.com#div(class=advert)
-techspot.com#table(background^=/images/deg-wide)
-techtree.com#div(id=fixme)(style=height: 60px; width: 102%;)
-techweb.com#div(id=h_banner)
-tectonic.co.za#*(id=bannerad)
-tek-tips.com#div(id=dropin)
-theglobeandmail.com#div(bigbox)
-thefreedictionary.com#div(Ov)
-themaineedge.com##td\[height="80"]:first-child
-themorningnews.org#div(class=deckAd)
-theonion.com#div(id=partner_feeds)
-thephoenix.com#div(GrayBackground)
-thephoenix.com#td(class^=bnb)
-thestar.com#div(headerAdContainer)
-thestar.com#div(rightNoPad)
-thestar.com#div(bigAd)
-thisisleicestershire.co.uk#div(id=columeRight)
-thisismoney.co.uk#div(id=Banner)
-timesonline.co.uk#div(id$=top-ad)
-tomshardware.com,tomsguide.com#*(class^=shopping)
-topix.com#div(id$=_ad)
-toptechnews.com#table(width=990)(cellpadding=5)
-torrentz.com#div(style$=width: 728px; height: 90px;)
-torontosun.com#table(width=160)(cellpadding=0)
-trustedreviews.com#div(id$=-sky)
-tucows.com#div(class^=w952)
-tvguide.com#div(class=ccTopAdContainer)
-tvguide.com#div(id=adRotator)
-tvguide.com#div(id=ad_270)
-tvguide.com#div(class^=ad-728)
-tvtechnology.com,proaudioreview.com,rwonline.com#td(class=business)
-tvtechnology.com,proaudioreview.com,rwonline.com#table(width=72%)(bordercolor=#006699)
-ugo.com#*(wrapper_banner)
-ugo.com#div(style*=width: 728px; height: 110px)
-upi.com#div(style=float: left; width: 794px;)
-upi.com#div(style=text-align: center; height: 250px;)
-usatoday.com#div(class^=relatedLinks)
-usatoday.com#table(width=940)(height=126)
-usatoday.com#div(njMarketplace)
-usatoday.com#table(id=rightRail)(width=250)
-usnews.com#div(class=ad-gray)
-videojug.com#*(id^=ad300x)
-vimeo.com#div(class=atlas ad)
-virtualdr.com#div(id=flex)
-vnunet.com#h2(advertisement)
-vnunet.com#div(specialAd175x90)
-washingtonpost.com#div(class=flex-ad)
-washingtontimes.com#div(twt-wrapper-bottom)
-washingtontimes.com#*(id*=-ad)
-washingtontimes.com#*(class*=-ad)
-washingtonwatch.com##*#container > div#right
-weatherbug.com#div(id^=wXcds)
-webpronews.com#div(class=topad)
-wdvl.com##body div:first-child, td\[bgcolor="#e6e6e6"] img, td\[bgcolor="#e6e6e6"] p:first-child, td\[bgcolor="#e6e6e6"] div:first-child
-whistlestopper.com#td(width=160)(align=left)
-winamp.com#div(id=subheader)
-windowsbbs.com#span(style=margin: 2px; float: left; width: 337px; height: 281px;)
-windowsnetworking.com#div(id^=ads)
-winehq.org#td(width=468)
-wordreference.com#td(bannertop)
-wsj.com#div(adl)
-wsj.com#div(boldGreyNine)
-wsj.com#div(style=width: 300px; height: 250px;)
-wunderground.com#*(class^=leftad)
-wunderground.com#div(bottomAds)
-wunderground.com#td(class=taC)(style=width: 50%; padding-bottom: 10px;)
-wunderground.com##div\[style*="/statefarm_bg.gif)"]
-wwe.com#div(id^=wrapAd)
-www.google.com##table\[bgcolor="#ffffff"]\[align="right"]\[style=""]
-windowsitpro.com##table\[width="973"]:not(\[bgcolor])
-x17online.com#div(id=alpha)
-xanga.com#ul(search-ad)
-xanga.com#div(module-ad)
-xml.com#td(class=secondary)
-xml.com#div(id=colored-bar-ad)
-yahoo.com#div(LREC)
-yahoo.com#div(class=md)(id^=marketplace)
-yahoo.com#div(class=yschhd)
-yahoo.com#*(class^=ad_slug_)
-yahoo.com#*(class*=_ad_)
-yahoo.com#div(yschspns)
-yahoo.com#*(id=yschsec)
-yahoo.com#div(id$=-ads)
-yahoo.com#*(spons)
-yahoo.com#div(class^=yad-)
-yahoo.com#div(class^=rhs-)
-yahoo.com#span(id^=yfs_ad_)
-youtube.com#div(id^=ad_creative)
-youtube.com#div(id^=search-pva)
-youtube.com#div(id=watch-channel-brand-div)
-yell.com#div(id=banners)
-zdnet.com#div(macad)
-zdnet.com#div(class=hotspot)
-zdnet.com#div(id^=powerP)
-zdnet.com##div.window:last-child
-zdnet.com.au#div(id=promo-power-centre)
-zdnetasia.com#div(ad-mpu)
-!
-!
-! *** Fetched from: http://easylist.adblockplus.org/abp-tracking-filter.txt ***
-!
-!
-! Rick752's EASYPRIVACY Tracking Filter (optional tracking blocker)
-! | Last Modified: 30oct2008 | http://easylist.adblockplus.org |
-!Expires after 5 days
-!
-:8081/log/*?
-?*&*mozilla$image
-?*=*org.mozilla$image,script
-?*&*www*%$image
-?*&CPTarget$image
-?*counterpixel
-?*=tracker
-?wtype=activity&
-&browserversion=$image
-&mode=track$subdocument
-&refer*/pixel.gif
-_beacon.txt?
-_count.js
-_count.php?
-_counter|
-_counter.js
-_track.php?
--statserver.
-_webtrekk
-_webtrends/
-addcontrol.net
-ATAtracker
-backupinfo.auctiva.com/Default.aspx?query=
-btn.clickability.com/
-c2.gostats.
-ct.360i.com/
-coremetrics
-count&AdID=
-directtrack.
-extreme-dm.com
-geo.yahoo.com/serv?s=
-getclicky.com/$script
-google*referer
-hit.stat
-hitcounter
-hitslink
-inet-tracker.de
-infotech.*log
-insightxe.
-linkCount?
-livestat.
-log*.hit-parade.
-log/ct.gif?
-nedstatbasic.
-pclick.internal.yahoo.com/$image
-ping.nnselect.
-quantserve.
-services.cnetchannel.
-sitecatalyst$script
-statistik-gallup.
-stats/track
-tracker.js?
-tracking.js|
-TrackingCode
-TrackingLog
-trk.sodoit.
-wallcannrewards.com/*/index.php?
-WebAnalytics.js
-webstats4u.
-www.google.com/logos/Logo_
-.2o7.net/
-.247realmedia.
-.3dstats.
-.51yes.com/
-.addfreestats.
-.adsensedetective.
-.axf8.net/
-.amung.us/
-.bbc.co.uk/*/o.gif
-.bc.yahoo.com/b?P=
-.betarget.
-.bizographics.
-.blizzardcheck.
-.bluecounter.de/
-.blvdstatus.com/js/
-.bronto.
-.burstbeacon.
-.chart.dk/
-.christmalicious.
-.clearspring.com/t/
-.clickaider.
-.clickalyzer.
-.clickclick.
-.clickdensity.
-.clicktale.net
-.clicktracks.
-.clickzs.com/*.php?
-.cnzz.com/stat.
-.com/b.gif$image
-.com/c.gif?*&
-.com/stats.*?*&
-.compteur.cc/
-.count.brat-online.ro/
-.counterlevel.de/
-.counterstation.de/*.php?
-.countomat.
-.cqcounter.
-.crowdscience.com
-.de/Log.*?*&
-.de/stati,*.gif
-.dlrowehtfodne.
-.dmtracker.
-.eloqua.
-.eresmas.
-.esomniture.
-.estat.com/
-.etracker.
-.etrafficcounter.
-.everesttech.
-.evisitanalyst.
-.extreme-dm.
-.ezytrack.
-.facebook.com/beacon/
-.flashadengine.
-.flashgamestats.
-.free-counter.
-.free-counters.
-.fusestats.
-.gcion.com
-.gemius.
-.gif?Log=
-.gif?referrer=
-.gigya.com$~object
-.globetrackr.com/dynimg/
-.google.*?*http*&$image
-.google-analytics.
-.google.com/coop/cse/
-.halstats.com*.php?
-.histats.
-.hitbox.
-.hitfarm.
-.hitmatic.
-.hittail.
-.hittracker.
-.host-tracker.
-.hotlog.
-.html.ivw|
-.ilogbox.
-.imdb.com/rd/?q=$image
-.infocollect.
-.instadia.
-.intelli-direct.
-.ipcount.
-.iperceptions.com%2
-.ipstats.
-.js?Log=
-.jstracker.
-.komtrack.
-.landingpg.
-.linkconnector.
-.lookery.
-.ipcounter.
-.masterstats.
-.metriweb.be
-.microcounter.de/
-.midkotatraffic.
-.mmismm.
-.mochibot.$other,object-subrequest
-.mstracker.net
-.myaffiliateprogram.
-.myspace.com/tracking/
-.mystats.
-.nametec.de/cp/
-.net-filter.
-.netflame.cc
-.netmining.
-.netratings.
-.nextstat.
-.nuggad.
-.offermatica.
-.oewabox.
-.onestat.
-.opentracker.
-.optimost.
-.ourstats.de/
-.paypal.*/pixel.gif
-.pickzor.
-.pikzor.
-.ppctracking.
-.ranking-hits.de
-.rapidstats.
-.reeferss.
-.regieci.
-.reinvigorate.net/
-.research-int.
-.richrelevance.
-.ritecounter.
-.rtfn.net/
-.s2d6.com/
-.sageanalyst.
-.schoolyeargo.
-.searchfeed.
-.sedotracker.
-.serving-sys.
-.sexcounter.
-.sextracker.
-.shinystat.
-.shortcuts.*yahoo.com$script
-.shortnews.de/iframes/view_news.cfm?id=
-.sitemeter.
-.sitestat.
-.sitetracker.
-.snowball.com*/pixy
-.sptag.com
-.spiegel.de/*/pixel.gif
-.spylog.
-.statcounter.
-.stats.de/
-.stats4free.
-.superstats.
-.sys.lv/*?
-.tamedia.
-.technorati.com/z/*.gif?
-.thecounter.com/
-.tinycounter.
-.tns-counter.
-.tophits4u.
-.traceworks.
-.track.decideinteractive.
-.traffic4u.
-.trafficmaxx.de/*thx.php
-.trafficmaxx.de/*traxx.js
-.trafficzap.
-.trafiq.
-.trackalyzer.
-.trakzor.
-.truehits.in.th/
-.urlself.
-.useronline.de/
-.users.51.la/
-.vizu.com/
-.web-stat.
-.webiqonline.
-.webmeter.ws/spider.php?
-.weborama.fr/
-.webstat.
-.webstats.
-.webtrendslive.
-.wemfbox.
-.woopra.
-.wundercounter.
-.wunderloop.net/
-.wws.*?*&pageName
-.wysistat.
-.x-stat.de/
-.xiti.com/
-.yahoo.com/serv?*&
-.yimg.com/*/pxl.gif
-.zaehler.tv/*?
-/_CPiX/*/pixel.gif
-/__utm.js
-/__utm.min.js
-/__utm_external.js
-/1dot.php?
-/1pix.gif?
-/1x1pixel.gif
-/a.ligatus.de/*
-/aads.myspacecdn.
-/acestats.net/*
-/adcookie
-/adcount.
-/adjs_zrt.
-/adlogger
-/adstat.
-/adstats.
-/adtrack.
-/adtracker/*
-/akamai/pixy.gif
-/analytics.php
-/analytics/tracking
-/analytics/wt.js
-/analyse.gif?
-/app.insightgrit.
-/apagopixel.js
-/astrack.js
-/astracker/*
-/axroi/script.php?
-/beacon/*?
-/beacon/v2/*
-/beacon.js
-/beaconservice
-/blank.gif?*&
-/blogtotal_stats
-/botd.gif?*http
-/brbtpixel/*$object
-/c.bigmir.net/?$image
-/c3.gostats.
-/cache.izearanks.
-/canwest_s_code.js
-/carnivore.ncom.dk/*
-/cbtracker.
-/cetrk.com/pages/*
-/cgi-bin*/CP/*
-/cgi-bin/*.gif?*&
-/cgi-bin/ivw/*
-/cgi-bin/vdz/*$image
-/cgicounter.
-/chkpt.zdnet.
-/claimdot.gif
-/click_track/*
-/clickcount
-/clickheat.js
-/clickLogger?
-/clicktrack/*
-/clicktracker.
-/clientstats/*
-/clixdom.js
-/cmdatatagutils.js
-/collect.m-pathy.
-/collector.js
-/content.adtegrity
-/content.cpxinteractive.com/rmtag3.js
-/cookie.crumb
-/count/id:
-/count.asp?
-/count.cgi?
-/Count.exe?
-/count.fcgi?*&
-/count.gif
-/count.js?
-/count_js.
-/count.php?
-/count.pl
-/count1.altastat.
-/count2.php?
-/counter*.php?
-/counter?
-/counter.
-/counter/*$subdocument
-/counter/*?
-/countercollector/*
-/countergif
-/countpage.*?
-/countr.js
-/cpx.php?*&$image
-/crazyegg.com/pages/*
-/creative.myspace.*AdID
-/cts.channelintelligence.
-/cycounter?
-/dcs.gif?
-/dcs_tag.js
-/detrack.js
-/dm_client_aol.js
-/dot.asp?
-/dot.gif?
-/dtjdel.php?n=
-/dw-eu.com.com/js/dw.js
-/eapBeacon.swf?
-/eluminate.js
-/emos2.js
-/ethnio.
-/fastcounter.
-/fastwebcounter.
-/feedjit.com/serve/?
-/fixstats.php
-/flagcounter.com/count/*
-/Flex*Promotions
-/flvcounter.
-/geo_track.*?
-/geoloc*.geovisite.
-/geov2.js|
-/hbx*.js|$~other,~object-subrequest
-/hits.e.cl/*
-/i.rottentomatoes.com/i.gif?
-/image.php?*&refer
-/img.msgtag.com/*
-/img/null.gif
-/indextools.js
-/ivw.php?
-/ivw/CP/*?
-/ivw/d5.php?
-/ivw/pixel.gif
-/ivw/SP/*?
-/ivw-bin/ivw/*
-/ivwscript.
-/jdc3.0nv.de/*
-/joomla-visites.js
-/js/behave.js
-/js/hitbox
-/js/stats/*?
-/js/urchin
-/jsstatus?*&
-/lib1.libstat.
-/link.decideinteractive.
-/linkcount
-/linktrack.
-/livestats_
-/loadcount.
-/log.go.com
-/log.js?
-/log.php?
-/log.stattooz.
-/log_agent.
-/Logger?
-/logging?
-/logging.js
-/loglib.js
-/mapstats.
-/mint/?js
-/mint/?record
-/mochibot.$other,object-subrequest
-/moviecount.php?*&
-/mtvi_report
-/mystat.
-/mystats.asp?
-/nb.myspace.com/isf.gif
-/neocounter2/*
-/nettracker/*
-/nielsen_v*.js
-/nowtrack.
-/ntpagetag.
-/omnidiggthis
-/omniture/*$script
-/omniture*_code
-/omniture/*?path=
-/omniunih.js
-/on3.php?
-/onedot.php?*&
-/onepixel.gif
-/optimized-by.rubiconproject.
-/p.reuters.*?$image
-/pagedot.gif?
-/pagetracker.
-/phpmyvisites.js
-/pistats/*
-/pix.gif?
-/pixel.apago.
-/pixel.gif?*&
-/powercounter.
-/ptrack2.php?
-/pi_counter/*
-/pic.gif?*http
-/piwik.js
-/pixl.gif
-/play/count/*
-/pmetrics.performancing.
-/pmsrvr.
-/pphlogger.
-/pub.mybloglog.com/comm2.php?
-/record.*?
-/RecordClick.
-/recordhit.*?
-/rms.admeta.
-/roia.biz/*
-/SellathonCounterService.asmx/*
-/sett.i12.de/*
-/site_specific_code.js
-/site-tracker.
-/sitestat.js
-/site_stats/*
-/sky_cross_promo/*
-/sniff.visistat.
-/spacehits.
-/spacer.gif?
-/ssl.kieden.com/sfga.js
-/stat*/counter/*
-/stat.4u.
-/stat/pixel.
-/stathound.
-/statistic?
-/statistics?*&$image
-/statistik_*?*&
-/statpixel.
-/stats/?
-/stats/log.
-/stats-bin/*.cgi
-/stats_insight.
-/stats.cgi$image
-/stats.js
-/stats.html?*&
-/stats.php
-/stats?*referrer=
-/statserver/*
-/StatsRecorder.php
-/STTracking.
-/t.aspx?*|T|*$image
-/ta.cfm?*&
-/Tacoda_
-/tmv11.js
-/toi.2cnt.net/*
-/top100-images.rambler.ru/*
-/topcnt?
-/trace.aspx?
-/track*/count.js
-/track/*-none.gif
-/track.cgi
-/track.gif?
-/track.i12.de/*
-/track.js
-/track.php?
-/trackclick.js
-/tracker/*?*http
-/tracker.js
-/tracker.php
-/tracker_gif*?
-/tracker?
-/Tracking/*?
-/Tracking~
-/tracking.gif?
-/tracking.js?
-/tracking.php
-/trackingScript
-/trackit.js
-/traffic.*?*&
-/traffic/?
-/traffk.
-/trans_pixel.asp
-/trk.enecto.
-/trk.newtention.
-/up.nytimes.
-/upixel.js
-/urchin00
-/urchin.js
-/vclick.adbrite.com/*
-/viewCounter?
-/video_log.php
-/videotracking.js
-/visit.gif?
-/visitcount.js
-/webBug.js
-/webcounter.
-/webstats/*
-/webtraxs.
-/webtrekk
-/webtrends$script
-/wtid.js
-/x4.xclicks.net/*
-/xgemius.js
-/yieldmanager.php
-/ymlowmedrec.php
-/ystat.do?
-/wholinked.com/tracker
-/zaehlergif.
-/zaehlpixel.
-http://103bees.
-http://4stats.
-http://a.*/hg?*&
-http://adlog.
-http://ad-track
-http://analytics.
-http://beacon.
-http://bigstats.net/
-http://click.*?
-http://count.
-http://counters.
-http://countus$script
-http://dw*.com.com/*?$~subdocument
-http://feedproxy.google.com/~r/$image
-http://fimserve.
-http://i.*/images/1.gif
-http://ivw.$image
-http://log.*?
-http://logger.$other,object-subrequest
-http://ltrack.
-http://mint.*?
-http://pr.blogflux.
-http://rsi.msnbc.msn.
-http://stat*.cybermonitor.
-http://statistics.
-http://stat.*/cgi-bin/
-http://stats.
-http://stats2.
-http://track.*?$~stylesheet
-http://track1.
-http://track2.
-http://track3.
-http://tracker.*?
-http*://tracking.
-http://s.stats.
-http://tr.*/CP/
-http://urchin
-http://utm.
-http://video-stats.
-http://visit.*?*&*http
-http://was.navlink.
-http://wz*/i/i.gif?*&
-@@/88.80.205.215/?*&*www*%$image
-@@/_thumb.php?*&$image
-@@/addons.mozilla.org/*/stats.js
-@@.atomfilms.com/a/js/
-@@.bigpond.com/*/omniture/s_code.js
-@@.canon.com*/webtrends
-@@/coiserv.php?href=$image
-@@content.mqcdn.com/*/omniunih.js
-@@.f1-online.fi/*/stats.js
-@@.googlehosted.com/base_media?q=$image
-@@.gravatar.com/avatar
-@@.heavy.com/*/tracking.js
-@@.hibm.org/arm/lib/exe/fetch.php?$image
-@@/i.livescience.com/common/js/hbx.js
-@@images.pronto.com/thumb
-@@/img.timeinc.net/tii/omniture/h/common.js
-@@/indystar.ur.gcion.com/Scripts/UA/*
-@@.ireport.com/*/swfplayer/omniture_tracking.js
-@@.linksys.com/*/hbx/
-@@.logitech.com/javascript/webtrends.js
-@@.mail.live.com*/GetAttachment.aspx
-@@/msn.foxsports.com/fe/js/hbx.js|
-@@muenster.markt.de/js/indextools.js
-@@.mlb.com/*/bam.tracking.js
-@@.nvidia.com/*/hbx.js
-@@.pandora.com/detail/track.js
-@@/player.movenetworks.com/pub/*ing.js
-@@.rtl.de/*/tcount.php?modul=$other,object-subrequest
-@@.saturn.de/frontend/webtrends/$script
-@@.seek.com.au/omniture/
-@@.sitestat.com/ing-diba/$subdocument
-@@static.ak.fbcdn.net/*/feedtracking.js
-@@stats.nypost.
-@@/stats.surfaid.ihost.com*_economi.js
-@@stats.washingtonpost.com/*
-@@stats.wikimedia.org/
-@@.thestar.com/omniture*/s_code.js
-@@.thumbalizr.com/api/?url=
-@@.truelocal.com.au/js/hbx/hbx.js
-@@.tickets.com/*?*http*&$image
-@@.tvguide.com/script/webtrends.js
-@@.video.aol.com/publish/players/*OmniCall$subdocument
-@@.vmixcore.com/widgets/video_list_player.php?*/omniture/
-@@.websnapr.com/?*&*www*%$image
-@@|http://desktop.google.
-@@|http://earth.google.*/download-
-@@|http://*.friendster.com/photos/*#
-@@|http://www.krone.tv/*/kmwebtv/
-@@|http://www.google.com/talk/
-@@|http://www.sirius.com/
-!
-
-[Subscription]
-url=http://chewey.de/mozilla/data/adblock.txt
-title=Cédrics Liste (Deutschland)
-lastDownload=1225437969
-downloadStatus=synchronize_ok
-lastModified=Wed, 29 Oct 2008 21:03:44 GMT
-expires=1225697169
-requiredVersion=0.7.1
-
-[Subscription filters]
-! 2008-10-29 -- expires: 3 days
-! Kommentare (vor allem false positives) bitte an adblock at mengemail.de oder per http://chewey.de/mozilla/kontakt.html
-! Please send comments (especially false positive reports) to adblock at mengemail.de or use http://chewey.de/mozilla/contact_en.html
-@@/^http:\/\/\w{2,3}\.wikipedia\.org\//
-@@|http://upload.wikimedia.org/
-@@phpmyadmin
-@@klack.de/JS*.js|
-@@id=googlepreview
-@@yahoo.com/a?*headr
-@@|http://www.clipfish.de/videoplayer.swf?
-@@video.on.nytimes.com/
-@@://pcw-tv.download.pcwelt.de/
-@@://www.atomfilms.com/a/autoplayer$object
-@@://www.drei.at/
-@@://broadband.nba.com/*/embed-ads.js
-@@://ad.doubleclick.net*/DartShellPlayer
-@@://www.rtl.de/media/ads/
-@@.yahoo.com/*playlist
-/\[-\/\._\(&=]ad_?(action|butler|brite|bottom|codes?\d*|function|ima?ge?s?|_?id(?!=&)|js(?!\.php)|\.php|box_?|farm|x\.js|-(?!aware).*|l(ink|og|ayer))\[-\/\._\)&=\|\?](?!s(ea)?rch)/$~stylesheet
-/\[-\/\._\(&=]ad_?(man|mentor|module|mosaic|pops?|parse|revolver|s(dk|end|erv(er)|ize|tome|onar|cripts?)|s|s?remote|type|-?f(low|rame|etch))\[-\/\._\)&=]/$~stylesheet
-/\[-\/\._\(&=\?]ad(vert.*|view|type|_?string|code|case|cli(ck|ent)s?)\[-\/\._\)\?=](?!etr)/$~stylesheet
-/\W(atwola|dimaso|dvlabs|eproof|falkag|ientry|revsci|tacoda)\./
-moneymakers.de/script.php?
-.ebayrtm.com/clk?RtmClk&
-anzeigenlieferant.de/c/
-web.de/*logoutcenter/
-.banner-networx.de/
-widget.proximic.com/
-.industrybrains.com/
-.banner.t-online.de/
-.adpeel.ch/mypeel/
-geo.yahoo.com/ser
-context*.kanoodle
-/bannerdealer/link.
-.reinvigorate.net/
-.targetpoint.com/
-googlesyndication
-delivery/ajs.php?
-.webmasterplan.
-.wunderloop.net
-dataWERBE.asp
-/getBanner.php
-/unddu_iframe/?
-doubleclick.net/
-.mediaplex.com
-taz.de/taz/anz/
-mm.chitika.net/
-.infospace.com
-&showad=true
-.checkm8.com/
-.interclick.com/
-addcontrol.net
-.cpvfeed.com/
-.infolinks.com/
-.sonnerie.net/
-http://banner.
-/ad_functions.
-trafficlayer.de
-assoc-amazon
-yourlayer.de/
-/adsense.php
-adbureau.net
-_adfunctions.
-&ad_url=http
-.azionare.de/
-ligatus.de/?id
-*/banner_*/
-bs*.gmx.net
-.nuggad.net
-.mpnrs.com/
-.azjmp.com/
-*/werbung/*
-anzeige.png
-/bannerfarm
-*/pagedot/*
-/adResize.js
-/adrotate.js
-/binlayer.de
-.ad2net.de/
-.mb01.com/
-adclick.asp?
-chunnel.de/
-anzeige.jpg
-_sponsor.js
-google_ads
-/adSwap.js
-mirando.de
-/popunder.
-/overture_
-&adCode=
-dl-rms.com
-sponsorad
-/adstream
-/pagepeel
-googleads
-.espotting
-banner.js|
-?adiframe
-.adcell.de
-/rich.asp?
-kmadserv
-.adpinion.
-/ad2.html
-fptd1.net
-/adwords
-/linkcount
-/adjs.php
-/adfetch?
-.2mdn.net
-/localads.
-systix.de
-/adframe
-/adwiz.js
-/imgad1.
-/imgad2.
-/imgad3.
-/adsales
-dat/bgf/
-/adctrl_
-//fdads.
-intellitxt
-.yieldmanager.
-themis.geocities.yahoo.
-imagesrv.adition.com
-ovm-einsundeins.
-.quality-channel.
-.trafficmasterz.
-ds.serving-sys.
-mediavantage.
-quarterserver.
-.adserverplus.
-sublimemedia.
-tradedoubler.
-vibrantmedia.
-imrworldwide.
-.mediaplazza.
-ebayobjects.
-.adshopping.
-hypemakers.
-promo.bahn.
-casalemedia.
-gfx.klipmart.
-.advertising.
-.euros4click.
-adgardener.
-bannerview.
-/countpage.
-maxserving.
-eyewonder.
-tribalfusion.
-maxserver.
-bidvertiser.
-directorym.
-rightmedia.
-bluestreak.
-contentad.
-http://ad2.
-http://ad1.
-contextad.
-.webgains.
-_adspaces
-.adtegrity.
-.mochiads.
-storyAds_
-.overture.
-banner_id
-.euroclick.
-http://ad.
-popularix.
-scanalert.
-burstnet.
-.adscale.
-pixelbox.
-kinghost.
-hoverad.
-.adtech.
-kontera.
-affiliate.
-//adwiz.
-adfloat.
-linkbox.
-clickthru
-iframead
-activead
-onlinead
-://www.ad.
-/banner$script
-popunder$script
-adition.com$script
-?clickTAG=$object
-&clickTAG=$object
-_promo.swf$object
-/index2.php|$script
-/passul.t-online.de$subdocument
-www.toolbar.de/$subdocument
-/adredirect.php?
-/oas_logic.js
-/lookatme.js
-/83.246.71.
-/jsadplace.
-/bin-layer.de
-/adtology.com
-/peel.js
-/ad/code-
-.emediate.eu/
-.axill.com/
-/webads_
-/adcycle
-.tfag.de/
--adpool.
-rad.msn.com
-/woshop_
-/adtags_
-.contaxe.com/
-.pricegrabber.com/$script
-traffalo.com
-.com/ads/
-.atdmt.com/
-.imdb.com/media/*.swf
-/heisebanner.
-.captainad.
-/wodas.wetteronline.de
-.fimserve.com/
-.layer4u.
-.triplead.de/
-/ad_wrapper
-/adthome.
-/adtmobile.
-metrics.feedroom.com/
-.smartadserver.
-.wai.de/emailads
-/oss.informaction.com
-/content.pulse360.com
-/adscale
-.blogads.com/
-#*(ad1)
-#*(ad2)
-#*(ad3)
-#*(ad01)
-#*(ad02)
-#*(ad03)
-#*(cellAd)
-#*(allAds)
-#*(adbar)
-#*(AdBox)
-#*(admpu)
-#*(adtext)
-#*(mpuad)
-#*(flashad)
-#*(adhoriz)
-#*(adArea)
-#*(inlinead)
-#*(AdBlock)
-#*(textads)
-#*(Ad_Top)
-#*(storyad)
-#*(storyAd)
-#*(inline-ad)
-#*(articlead)
-#*(ads_title)
-#*(overture)
-#*(articleAd)
-#*(werbung)
-#*(googeins)
-#*(Ad_Right)
-#*(bigBoxAd)
-#*(adbottom)
-#*(AdColumn)
-#*(contentad)
-#*(Ad_Middle)
-#*(tdWerbung)
-#*(sponsorBox)
-#*(adContainer)
-#*(AdContainer)
-#*(ad_rectangle)
-#*(topBannerAd)
-#*(industrybrains)
-#*(sponsoredlinks)
-#*(leaderboardAd)
-#*(sponsored_iframe)
-#*(feedburnerAdBlock)
-#*(SponsoredLinksBox)
-#*(id^=adx)
-#*(id^=ad_leader)
-#*(id^=AdSponsor)
-#*(class^=AD_)
-#*(class^=AdTop)
-#*(class^=ad_slug)
-#*(class^=adSpot-)
-#*(class^=adbottom)
-#*(class*=hiddenad)
-#*(class*=googlead)
-#*(class*=-ad-space)
-#*(class*=ContextualLinks)
-#*(id*=bigAd)
-#*(id*=contextualLinks)
-#a(advert)
-#span(ad)
-#p(anzeige)
-#td(Adcol)
-#td(topAd1)
-#div(ovt)
-#div(adR)
-#div(mpu)
-#div(quigo)
-#div(adDiv)
-#div(ad-rail)
-#div(adtest)
-#div(bwbox)
-#div(advdiv)
-#div(adspot)
-#div(adsTop)
-#div(ad-links)
-#div(hotspot)
-#div(top-ads)
-#div(sideAds)
-#div(mpubox)
-#div(sky_anz)
-#div(singleAd)
-#div(adspace)
-#div(mpuSpot)
-#div(ads_mpu)
-#div(ad-space)
-#div(admarker)
-#div(adheader)
-#div(adbanner)
-#div(ad-fullsize)
-#div(adpartner)
-#div(contentad)
-#div(articlempu)
-#div(header_ad)
-#div(cubeadbox)
-#div(adCreative)
-#div(sidebar_ad)
-#div(content_ad)
-#div(adv-header)
-#div(spOffersDiv)
-#div(pAdSolution)
-#div(Adrectangle)
-#div(TopAdCenter)
-#div(featuredLinks)
-#div(ad_fullbanner)
-#div(sponsoredLinks)
-#div(class*=bottomads)
-#div(class*=advertisement)
-#table(adlinks)
-#table(yahooBox)
-#div(id^=ad3)
-#div(id^=ad-3)
-#dvi(id^=ad_3)
-#div(id^=adv_)
-#div(id^=adpos)
-#div(id^=adical_)
-#*(id^=kanoodle)
-#div(id^=adscale)
-#div(id^=mainAd)
-#div(id^=rtm_div)
-#div(id^=advert3)
-#div(id^=sponsor)
-#div(id^=admiddle)
-#div(id^=AdBroker)
-#div(id^=sponsor_)
-#div(id^=GoogleAds)
-#div(id^=divHeadAd)
-#div(id^=AdShowcase)
-#div(id$=_ad)
-#div(id$=_ads)
-#div(id$=_topad)
-#div(id$=0adBox)
-#div(id$=RightAd)
-#div(id$=_adlinks)
-#div(id$=_mpu_div)
-#div(id$=-sponsored)
-#div(id$=sponsoredoffers)
-#div(id$=right_ad)
-#div(id*=TopAd)
-#div(id*=_ads_)
-#div(id*=_adright)
-#div(id*=ArticleAd)
-#div(id*=googlead)
-#div(class=islandad)
-#div(class=Ad Panel)
-#div(class=AdSense)
-#div(class=ysmSponsored)
-#div(class$=-adarea)
-#div(class$=ysponsor)
-#div(class$=RightColAd)
-#div(class$=_contentad)
-#div(class^=adMkt)
-#div(class^=werbe)
-#div(class^=boxAd)
-#div(class^=adTitle)
-#div(class^=pod ad)
-#div(class^=advXert)
-#div(class^=anzeige_)
-#div(class^=hiddenAd)
-#div(class^=BannerAd)
-#div(class^=sponsors_)
-#div(class^=advertCont)
-#div(class^=showcaseAd)
-#div(class^=sponsoredLinks)
-#div(id=bannercont)
-#div(name=promotion)
-#iframe(id^=ad2)
-#iframe(google_ads_frame)
-#div(style*=/img/layout/overture/)
-#object(FLASH_AD)
-#table(id^=werbung_)
-#table(class^=ad_top)
-##*\[id="ads"]:not(\[class="xs"])
-taz.de#div(class^=werb)
-web.de#iframe(id=promo)
-sourceforge.net#div(adbatch)
-sourceforge.net#div(id^=fad)
-heise.de#div(sales)
-heise.de#*(skyscraper)
-heise.de#*(heiseadvert)
-heise.de#div(class*=bcadv)
-heise.de#*(contentbanner)
-heise.de#div(id^=jobsuche)
-heise.de#*(class*=kasten_markt)
-heise.de##table\[cellpadding="3"]\[border="0"]\[align="center"], table\[width="200"]\[cellpadding="3"]\[border="0"]\[align="right"], table\[class="druck"]\[align="center"]
-heise.de##td\[width="1"]\[valign="top"]\[rowspan="2"], td\[valign="bottom"]\[colspan="2"]\[class="rightcontent_2"], div\[class="leaderboard"]
-sueddeutsche.de#p(class=bannerAnzeige)
-sueddeutsche.de##tr\[class="bgeff8ff"], table\[bgcolor="#f2f2f2"], div\[class="BannerBug"], div\[class="bannerMediumRectangle"]
-zeit.de#*(ad)
-zeit.de#*(main_related)
-zeit.de#div(class^=adcloud_)
-zeit.de##div\[class="marktplatz"], div\[class="yahoo_ad"], div\[class="anzeige"]
-spiegel.de#*(spCommercialNav)
-spiegel.de#div(class=spPartnerBar)
-exalead.de#div(class^=c236)
-mail.google.com#div(class=rh)
-mail.google.com#div(class^=yx)
-google.de,google.com,google.fr,google.pl,google.at,google.ch,google.it,google.co.uk#table(width=230)(id=t)
-google.de,google.com,google.fr,google.pl,google.at,google.ch,google.it,google.co.uk#table(width=25%)
-google.de,google.com,google.fr,google.pl,google.at,google.ch,google.it,google.co.uk#table(id=mbEnd)
-google.de,google.com,google.fr,google.pl,google.at,google.ch,google.it,google.co.uk#*(tads)
-google.de,google.com,google.fr,google.pl,google.at,google.ch,google.it,google.co.uk#*(id^=tpa)
-map24.com##td\[id="m24s"], iframe\[id="m24up"], div\[id="cont_m24up"]
-dict.leo.org##td\[class="cT"]\[width="15%"], td\[width="80%"]\[valign="middle"]\[align="right"], td\[width="10"], td\[valign="middle"]\[style*="text-align: center"]
-dict.leo.org###filter
-dict.leo.org#*(sidebar)
-dict.leo.org#*(standard_banner)
-golem.de##td > h5\[class="rightcolhead"] + div
-golem.de##table\[style="background-color: rgb(221, 244, 254);"]
-golem.de##table\[width="480"]\[cellspacing="0"]\[style="clear: right;"], table\[width="740"]\[height="90"], table\[width="772"]\[height="90"], table\[width="792"]\[height="90"], div\[style*="width: 234px;"], div\[style="margin-top: 10px; margin-bottom: 10px;"]
-imdb.com#div(id^=lea_)
-imdb.com#div(tn15adrhs)
-imdb.com#div(nb15supertab)
-creativeproxy.web.de##div\[id="mainWrapper"], div\[id="header-banner-intern-s"]
-cnn.com#div(class$=AdBox)
-n-tv.de##td.hl:first-child
-n-tv.de##div#mainnavi > *:not(\[class="navi"]):not(\[id="searchform"])
-n-tv.de#div(class^=dms_ad_)
-n-tv.de#table(bannerhead)
-n-tv.de#div(upphcontent)
-n-tv.de#div(ubottom)
-n-tv.de#div(wallsky)
-n-tv.de#div(skypos)
-n-tv.de#div(ulayer)
-yahoo.com#div(id^=lrec_)
-yahoo.com#div(id$=ypn-ads)
-focus.de#div(id*=_ligatus_)
-ask.com#div(gsl)
-ask.com#div(class$=spl_shd)
-about.com#div(bb34)
-derstandard.at#td(class=ins_obj)
-chip.de#div(resizetableBANNER)
-exalead.de#div(class=c325 c357)
-exalead.de#div(class=c325 c41)
-www.t-online.de#div(tsrwh)
-bildblog.de#div(anzeige)
-studivz.net#a(href*=doubleclick.net/)
-studivz.net#div(class=yahoo_leftnav)
-studivz.net##span\[style="color: rgb(69, 69, 69); font-size: 10px;"], span\[style="color: rgb(153, 153, 153); font-size: 9px;"]
-groups.google.com#DIV(class=rnimc)
-wetter.com#div(id$=_BOX_PARENT)
-youtube.com#DIV(id=search-pva)
-bbc.co.uk#DIV(id^=bbccom_)
-search.live.com#DIV(class$=_adsW)
-search.live.com#DIV(class$=_adsN)
-heise.de#DIV(class=online-markt)
-#DIV(class=boxad)
-#DIV(id^=adSpot)
-
-[Subscription]
-url=http://maltekraus.de/Firefox/adblock_site-specific-elemhiding.txt
-title=Filter von Dr.Evil (Deutschland)
-lastDownload=1225437974
-downloadStatus=synchronize_ok
-lastModified=Thu, 30 Oct 2008 12:41:14 GMT
-expires=1225956375
-requiredVersion=0.7.1
-
-[Subscription filters]
-! Filterliste von Dr. Evil & MonztA (mit Hilfe der Foren-Nutzer auf firefox-browser.de)
-! Zuletzt geändert: Thu, 30 Oct 2008 13:41:14 +0100 wird alle 6 Tage aktualisiert (expires after 6 days).
-! Kommentare (verbleibende Werbung, fälschlicherweise blockierte Inhalte, Danksagungen ;-), ...)
-! bitte per Mail an adblockfilters at mozdev.org oder auf http://www.firefox-browser.de/forum/viewtopic.php?t=58194 an uns richten
-! Filterliste ohne allgemeine Element-Hiding-Filter
-&ClientType=*&AdID=
-&ad_url=
-&affiliate=$~stylesheet,~subdocument
-&playlistvideoad=$other,object-subrequest
-*&clicktag=*/partner/*$object
-*&popup=y&*
-*&program=revshare&*
-*-adverti*
-*-skyscraper.gif|
-*.biz/ads/*
-*.com/adserv*
-*.ebayrtm.com/*$script
-*.html.ivw|
-*.i12.de/_script/log.js
-*.nbjmp.com
-*.swf?clickTag=*/partner/*
-*.us/ads/*
-*.yourlayer.de/*
-*/.adserv/$match-case
-*/Tacoda_
-*/TopAdsJS.
-*/ad-head*
-*/ad-script
-*/ad-sys/*
-*/ad.channel/*
-*/ad.serve*
-*/ad/frame*
-*/ad/js.php
-*/ad2.htm
-*/adClutter.js
-*/adRelated.
-*/ad_function*$~stylesheet
-*/ad_head*
-*/ad_iframe
-*/ad_insert*
-*/ad_left
-*/ad_parse*
-*/ad_right*
-*/ad_top_*
-*/ad_wrap
-*/adcache/*
-*/adcentric/*
-*/adclient
-*/adcodes/*
-*/adcookie
-*/adcount.
-*/adctrl_*$~object
-*/adcycle.
-*/adcycle/*
-*/adfiles/*
-*/adiframe
-*/adjump/*
-*/adlink/*
-*/adlinks.js
-*/adlogger
-*/adpimp.js
-*/adplosive
-*/adredirect.php?
-*/adremote.
-*/adrevolver/*
-*/adrot.js
-*/adrotat*
-*/ads/side*
-*/ads_banner
-*/adsales/*
-*/adsend/*
-*/adserv.
-*/adserv/*
-*/adsnew/*
-*/adsource/*
-*/adsrv_js*
-*/adstream_
-*/adsystem/*
-*/adtext.
-*/adtrack/*
-*/advert.
-*/advert_
-*/adview?*
-*/adwiz.js
-*/adwords
-*/adworks
-*/adwrapper/*
-*/aff_iframe$subdocument
-*/afr.php?$match-case
-*/amazonads.
-*/banner.js|$script
-*/banner.php3?*banner=*
-*/banner/skyscraper*
-*/banner_ad.*
-*/banner_ads/*
-*/banner_display.php*
-*/banner_sky.
-*/bannerad_*
-*/bannerads/*
-*/bannerclick/*
-*/bannerscript_*$script
-*/blogads
-*/bottomad.
-*/bserver/AAMALL/*
-*/bservers/AAMALL/*
-*/buyclicks/*
-*/c_overture/$match-case
-*/center/ad_*
-*/cetrk.com/*
-*/clickheat/*$script
-*/clicklayer.
-*/countercollector/
-*/etracker.js
-*/expand_banner.js
-*/fastclick
-*/frnads.js|
-*/fuseads/*
-*/get_ad.php
-*/gfx/ads/*
-*/googleAd.js
-*/googlesky.php*
-*/graphics/_ad/
-*/hbx_cookies.js
-*/hitbox/$script
-*/hphdas2/*$script,subdocument
-*/ifr_ads.
-*/iframeAd.
-*/imageads.
-*/imageads/*
-*/images/ad.gif|
-*/images/ads/*
-*/img/ads/*
-*/img/adv/*
-*/inajs.php$match-case
-*/index_ads.
-*/interstial_ad.js
-*/invideoad.
-*/itunesaffiliate
-*/js/ads.js
-*/js/ads/*
-*/js/hbx_*
-*/js/hitbox*
-*/jsadplace
-*/layerads_
-*/layerbody.php
-*/layerhead.js|
-*/lookatme.js
-*/maxiad/*
-*/media/presentings/*
-*/mediaAd.
-*/mediamgr
-*/openads-
-*/openads.
-*/openads/*
-*/overture/*
-*/overture_*
-*/pagead/$match-case,~other,~object-subrequest
-*/pagead/*&videoad_start_delay=1
-*/pagead/imgad?
-*/pagepeel*$object,script,object-subrequest
-*/paidlisting_*
-*/partner-ad/*
-*/partner/*&clickTag=*
-*/peel.js
-*/peelads/*
-*/phpads/*
-*/pics/ads/*
-*/realmedia/ads/
-*/rmtag3.js
-*/servlet/view/banner/*$script
-*/shopBanner/*
-*/showads.
-*/sidead2.
-*/skyscraper$script,object,subdocument
-*/sponsorad.
-*/sponsoredlinks/*
-*/ssbanners/*
-*/stickyAd.js
-*/topad.htm
-*/tradedoubler/*
-*/video_ads/*
-*/videoad/*
-*/webads_*
-*/webtrekk
-*/werbebanner/*
-*/werbemittel/banner_
-*/wipeads/*
-*/xkoop/presentings/*$~background
-*/yieldmanager.php
-*/ysmads.html
-*=write_layer_neu&*$script
-*_adcenterconversion.js
-*_adfunction*
-*_ads/skyscraper*
-*_adspace*
-*_adverti*$~other,~object-subrequest
-*_js/ad.js
-*_skyscraper.gif|
-*_skyscraper.swf|
-*_top_ad.*
-*_werbe_layer*
-*_werbelayer*
-*_werbung*
-*ads/adx.js|
-*assets/ads/*
-*content/ads/*
-*hosting_ads/*
-*iframe/ad_*
-*promo/flash/468x60*
-*script/Ads.
-*script/ad.js
-*script/ads/*
-*script/ads_*
-*script/adx.js
-*scripts/ads/*
-*server/adx.js|
-*yahoo.com/eu/ads/*
--120_600_
--120x600.
--468-60-
--468_60_
--468x60.
--728x90-
--728x90.
--ads.com/
--ads.net/
--adservice.com
--adserving
--advert.
--tracker.de/
-.120x600.
-.128b.com
-.247realmedia.
-.2mdn.net/
-.2o7.net
-.ad-balancer.
-.ad-flow.com/
-.ad-pay.de/
-.ad20.net/
-.ad2net.de/
-.adaction.
-.adbard.net
-.adbrite.com/
-.adbureau.net/
-.adcell.de
-.adcentriconline.com/
-.adcocktail.com
-.addfreestats.com/
-.adecn.com/
-.adengage.com
-.adfusion.com/
-.adgardener.com/
-.adhese.be
-.adicate.
-.adinterax.com/
-.adition.com/
-.adjuggler.com/
-.adjustment.de/
-.adklick.de
-.adland.
-.adlink.net/
-.adnet.com
-.adnet.ru
-.adocean.
-.adpark.$match-case
-.adpeel.
-.adpinion.com
-.adrevolver.
-.adrom.de/
-.ads.pack.js
-.adscale.de
-.adserve
-.adsmarket.com
-.adsonar.com/
-.adspirit.
-.adspread.net
-.adsrevenue.net/
-.adtech.de/
-.adtegrity.net/
-.adtology3.com/
-.adtrgt.com
-.adultadworld.com/
-.adverti
-.advolution.de
-.adzones.com/
-.afcyhf.com/
-.affilitec.com
-.allsponsor.de/
-.anrdoezrs.net/
-.assoc-amazon.
-.atdmt.com/
-.ath.cx/?WM=
-.atwola.com/
-.awltovhc.com/
-.axpio.com/
-.azads.com
-.azjmp.com/
-.bannerbank.ru
-.belboon.de
-.betarget.de/
-.bidvertiser.com/
-.blogads.com/
-.bluestreak.com
-.buysellads.com
-.captainad.com
-.cc/ads/
-.centralmediaserver.$~image
-.checkm8.com/
-.checkmystats.
-.chitika.net/
-.chunnel.de/tracking.php?$image
-.clickability.com/
-.clickad.
-.clickaider.com
-.clickbank.
-.clickdensity.com/
-.clicktale.net
-.clixgalore.com/
-.collective-media.net
-.com/ad.js
-.com/ad/
-.com/ads-*
-.com/ads.*
-.com/ads/
-.com/ads2/
-.com/adx.js|
-.com/de/ad/
-.connexpromotions.de
-.connextra.com/
-.contentlayer.de
-.contextweb.com/
-.coremetrics.com/
-.countercash.de
-.counterstation.de/
-.countomat.com/
-.cpmstar.com/
-.cpuim.com
-.cpvfeed.com
-.cpxinteractive.com/
-.cybermonitor.com/
-.d-stat.com/
-.de.vu/adv/*
-.de/_ads/$object,image
-.de/ads/$~object
-.de/adx.js|
-.de/js.ng/
-.de/peel/$script
-.decdna.net/
-.die-staemme.de/ad_
-.directorym.com/
-.dl-rms.com
-.dotomi.com
-.doubleclick.
-.dpbolvw.net/
-.drevil.to/
-.ebayobjects.com/
-.elite-layer.de
-.emediate.
-.estat.com/
-.etology.com/
-.etracker.
-.eu/ads/*
-.euroclick.com/
-.everesttech.
-.exoclick.com/
-.exponential.com
-.extreme-dm.com/
-.eyewonder.com/
-.falkag.$match-case
-.fickads.net
-.filefront.com/*/fnOverlay.js
-.fimserve.
-.firstadsolution.com/
-.firstload.de/affiliate/
-.firstload.de/banner_
-.fixionmedia.net/
-.fmpub.net
-.forced-boom.de
-.forced-layer.de/
-.friendlyduck.com
-.ftjcfx.com/
-.funklicks.
-.gamecetera.com/
-.gamecopyworld.com/*!_*.php
-.gestionpub.com
-.gigya.com$~object
-.google-analytics.com/
-.herold.at/FS/orgimg/*.swf?
-.histats.com
-.hitbox.com/
-.hittail.com
-.hypemakers.
-.iconadserver.com/
-.imageshack.us/img/imgad$image
-.imglt.com/
-.imrworldwide.com/
-.in/layer/
-.indextools.com/
-.industrybrains.
-.info/adx.js
-.infolinks.com
-.intelli-direct.
-.intensifier.de/
-.ivwbox.de/
-.iwsolutions.eu
-.jdoqocy.com/
-.jstracker.
-.kilu.net/extra/a1/
-.klipmart.com/
-.komtrack.com/
-.kontera.
-.kqzyfj.com/
-.layer-change.de/
-.lea.lycos.de/
-.ligatus.de/
-.linksynergy.com
-.m-pathy.com
-.map24.com/banner/$object
-.map24.com/campaign/surfats.php?adId=*&adLang=
-.mediaonenetwork.
-.mediascale.de
-.megaclick.com
-.megavideo.com/mr_videoad.php?
-.mercuras.com/
-.metaffiliation.com/
-.mirago.com
-.msads.net/
-.mspaceads.com/
-.nedstatbasic.net/
-.net/?WM=
-.net/ad?
-.net/ads/
-.net/ads?
-.net/adsrv/
-.net3media.com
-.netflame.cc
-.nextstat.com
-.nuggad.net/
-.nyadmcncserve-
-.oewabox.
-.offermatica.com/
-.onad-marketing.de
-.onenetworkdirect.net/
-.onestat.com/
-.openx.org
-.org/ads/
-.overture.com/
-.partnercash.com
-.partnercash.de/
-.paypopup.com/
-.pheedo.
-.photobucket.com/*/aamsz=*
-.popdowncash.de/
-.popularix.com/
-.powerwinning.com
-.predictad.com
-.prepaid-usenet.de
-.pricegrabber.$subdocument
-.primaryads.com
-.privatschlampen.net/pa.php?*&
-.proximic.com
-.qksz.net
-.qualigo.de/doks/search/source/std/*.js
-.questionmarket.com/
-.rapidstats.de/
-.reinvigorate.net
-.repage.de/script5.php?u=*$script
-.revsci.net/
-.rmbclick.com
-.rmxads.com/
-.rubiconproject.com
-.sageanalyst.net
-.scanscout.
-.serving-sys.com/
-.sexcounter.com/
-.sitemeter.com/
-.sitestat.com/
-.smartadserver.com/
-.smarttargetting.com/
-.specificclick.
-.spinbox.net/
-.sponsorads.de/
-.spss.vita-b.de/$script
-.spylog.com
-.stat24.
-.stats.de/
-.stats24.net/
-.stats4free.de/
-.superclix.de/
-.supercomm.de/
-.swf?clickTAG=http*/click.
-.t-online.de/addyn/*
-.tacoda.net/
-.targetnet.com/
-.targetpoint.com/
-.tfag.de/
-.tk/*.ban?fldpromonr=*&fldbannernr=
-.tkqlhce.com/
-.to/?WM=
-.to/ads.js
-.to/ads/
-.to/res/gr/|$script
-.to/res/|$script
-.total-media.net
-.tradedoubler.com/
-.tradetracker.
-.trafficcenter.de/
-.trafficmaxx.de/thx.php
-.triadmedianetwork.com
-.triplead.de
-.tripple.at/triadshow.
-.twinplan.com
-.uimserv.net/
-.uk/adx.js|
-.unicast.com
-.utarget.co.uk/
-.valuead.com
-.valueclick.com
-.valueclickmedia.com
-.vibrantmedia.com/
-.web.de/banner/banner.htm?$subdocument
-.webads.
-.webmasterplan.
-.webstats.
-.webstats4u.com/
-.webtrekk.net
-.webtrends.com/
-.webtrendslive.
-.wemfbox.
-.widgetbucks.com
-.wunderloop.net
-.xclicks.net
-.xhit.com/
-.xiti.com/
-.yieldmanager.
-.yimg.com/a/eu/any/*300x250*.swf
-.yimg.com/adv/*
-.zangocash.com
-.zanox-affiliate.de/
-.zanox.com/
-.zeads.com
-.zedo.com/
-.zeusfiles.com/promo/
-.zshare.net/cpx/
-/120x60.
-/120x600_
-/468_60_
-/468x60.
-/468x60/*
-/468x60_
-/486x60_
-/600x100
-/728_90_
-/728x90/*
-/92.241.169.251/*/|$script
-/Adtracker
-/Common/Ad/*
-/RealMedia/*$match-case
-/ShowFlashAd.
-/WriteLayerAd.js
-/ad-frame
-/ad-graphics/*
-/ad-serv
-/ad.aspx
-/ad.cgi?
-/ad.html$subdocument
-/ad.php?
-/ad/code$script
-/ad/init.php
-/ad/serv
-/ad1.html
-/ad2.aspx
-/adFunction
-/ad_120x
-/ad_728x
-/ad_anzeige
-/ad_bottom
-/ad_click.cgi
-/ad_frame
-/ad_manager
-/ad_refresher.js
-/ad_string.js?
-/ad_top.
-/ad_werbebanner$subdocument
-/adabovescroll.
-/adbanner
-/adbelowscroll.
-/adbrite
-/adcadbanner.jpg|
-/adclick
-/adcloud.
-/adcode.
-/adconfig.xml?
-/adcube.
-/adfetch?
-/adframe
-/adgenerator
-/adhelper
-/adimage.
-/adjs.php$match-case
-/adjsd.php$match-case
-/adlayer
-/adlink.
-/adlog.php?
-/admanagement/*
-/admaster
-/admentor
-/adoverlay
-/adpopup.php
-/adproxy/promo
-/adroot/*
-/ads-iframe
-/ads.htm
-/ads.js?
-/ads.php
-/ads.pl?
-/ads/*swf?clicktag=
-/ads/banner
-/ads/burst_$subdocument
-/ads/click
-/ads/common
-/ads/firstload
-/ads/script
-/ads/show
-/ads/sky
-/ads2.js
-/ads2.php
-/ads?client=
-/ads_iframe
-/ads_reporting/*
-/ads_yahoo.
-/adsadview.php?
-/adscript_
-/adsense$subdocument,script
-/adsense.
-/adserve
-/adsfolder/*
-/adsframe/*
-/adsonar.
-/adspace
-/adsserv
-/adstats
-/adsyndication.
-/adsystem$subdocument
-/adtags.
-/adtarget
-/adtech_
-/adtechtag.
-/adtype.php
-/advert/*
-/adverti
-/adverts
-/adview.
-/adxx.php?
-/affiframe$subdocument
-/affiliate/script.php
-/ajs.php?
-/altad.html
-/altadadbrite$subdocument
-/archiv.to/res/?*&$other,object-subrequest
-/banner.php?
-/banner/*_zanox
-/banner/adx.js|
-/banner_fullsize*.gif
-/banner_objekte/*
-/bannerad.
-/bannerclicks/*
-/bannerrotation
-/banners.php?
-/banners?*$third-party
-/bannerwerbung
-/beamme.php
-/bilder/ads/*
-/browsertraps/*
-/cashads.
-/clickbanner.
-/clickheat.js|
-/clickserve
-/cnwk.1d/Ads/*
-/cpxads/*
-/dataWERBE.asp
-/dateads.php
-/dcs.gif?
-/defaults/hbx.js
-/deliver*&ads=
-/delivery.engine/*?
-/delivery/*.php$script,image,object
-/doubleclick/*
-/dyn_banner*.php?
-/dynbanner*.php?
-/external/ads/*
-/externalAd.
-/firstload-pu.js
-/framead-
-/framead_
-/getAd2.php
-/getLinkedAd.php
-/getad.php
-/getmdhlink
-/google/ads/*
-/google_ad.
-/google_ads/*
-/graf.is-a-geek.org/*
-/hbx/hbx.js
-/hitbox/hbx.js
-/iframe_ad.
-/iframead_$subdocument
-/iframes/ebaypromo$subdocument
-/imgad.png|
-/in.php/*id=$subdocument
-/in.php?*id=$subdocument
-/inads.php
-/includes/hbx.js
-/js/ad.js
-/js/ads_
-/js/hbx.js
-/jslogger.php?
-/lalalala.ath.cx/*
-/layer.php
-/layerad-
-/layr.php$script
-/linkcount
-/loadBanner.
-/miva_ads.
-/mnbanner.html?
-/mr_tb_ad.php
-/oasisi-*.php?
-/onlinecounter.
-/openbanner.html
-/openx/www/*
-/pagedot.gif?
-/pagedot/pixel.gif?
-/pageear.js
-/pagepeel.js|
-/partner*x600_*
-/partner-teaser/*
-/partner/*160x80*
-/partner_promo/*
-/php/adx.js|
-/phpads.
-/phpads2/*
-/piwik.js
-/powerlayer_
-/pp/jcorner.js|
-/pricerunner.html
-/promo/layer
-/quadbanner.htm$match-case
-/rectangle.$subdocument
-/right-ad-
-/rotating_banner
-/scripts/ad_
-/scripts/hbx.js
-/shopad.gif|
-/showAd/*
-/show_ad_
-/show_ads
-/show_afs_ads.js
-/showad.
-/showadvert
-/showban.asp?
-/showlayer.$script
-/sidead.
-/sideads/*
-/sitestat.js
-/skyad1.
-/skyscraper.gif
-/skyscraper/*.gif
-/skyscraper_
-/smartad.js|
-/smartserve/ad?
-/sponser.
-/sponsor/*
-/sponsorads.
-/sponsoredLinks.php
-/sponsored_link
-/stats/hbx$script
-/systemad.js
-/testingad.php
-/textad.
-/textads.
-/tikilink?
-/toplist$subdocument
-/valueclick
-/vclkAds.html?
-/werbeframe$subdocument
-/werbung$~stylesheet
-/ws.amazon.com/widgets/q?$object
-/www/dist/*.php?
-/www/firstload/*
-4stats.de/
-://195.138.63.52/$match-case
-://195.138.63.53/$match-case
-://195.138.63.54/$match-case
-://195.157.98.219/$match-case
-://195.90.247.132/$match-case
-://212.123.106.149/$match-case
-://212.204.49.83/$match-case
-://62.146.108.145/$match-case
-://62.27.51.163/$match-case
-://64.158.223.128/$match-case
-://81.171.77.190/
-://adserv
-=468x60&
-=728x90;
-=VIEWAD&
-=textad&
-?*=adiframe
-?affiliate=
-ATAtracker
-AdClient$match-case
-ArtikelAd.
-ContentAd.
-Iframe_Ads
-SponsLink
-_100x150.
-_120_600_
-_120x600.
-_120x600_
-_468_200.
-_468_60_
-_468x60.
-_468x60_
-_728_80.
-_728x90.
-_728x90_
-_SkyscraperBanner
-_ad_promo
-_adbrite$subdocument
-_adntv.js
-_adplib.js
-_ads.php
-_ads/script
-_ads_reporting
-_banner_adv.
-_displayTopAds.js|
-_htmlads_
-_img/ad_
-_php_a-d_s_n-e_w/
-adbutler.de
-adcode.ws/
-affiliwelt.net
-anuncigo.gamigo.de/
-banner-sponsor.info
-banner/*.swf?ClickTag=http
-banner468x
-banner_ad_
-banner_click.php
-banner_id=
-banner_werb
-bannerid=
-banners.affilimatch.de/
-banners/468
-banners/adv
-bin-layer.
-blogadswap.com
-boylesportsreklame.com
-buxflow.com
-casalemedia.com/
-clickhype.com
-contentad*.swf?CLICKTAG=$object
-countyou.de/
-dbasixx.com/amat$subdocument
-ddl-music.org/javascript/lightwindow.js
-exchangecash.de/
-extads.web.de/
-extremetracking.com
-fairadsnetwork.com
-fastclick.net
-firstload.de/index.php?*&$subdocument
-frame/ads.js
-gacela.eu
-getclicky.com
-googleads
-header_ad.
-http://ad.
-http://ad1.
-http://ad2.
-http://ad2games.com
-http://adisfy.com
-http://adnet.
-http://ads*.omc.net
-http://ads.
-http://ads1.
-http://ads2.
-http://ads5.
-http://adsfac.net/
-http://adstat.
-http://adstorage.
-http://adsys.
-http://adx.
-http://banner.
-http://bigstats.net/
-http://binlayer.com
-http://cashad2.
-http://click.ilove.de/
-http://dw-eu.com.com/
-http://dw.com.com/
-http://ekmas.com/
-http://fimserve.
-http://gavzad.
-http://heisebanner.geizhals.at
-http://imageshack.us/ymlead2.php
-http://maltekraus.blogdns.com
-http://media.alphaload.com
-http://mystat.
-http://nbjmp.com/
-http://oss.informaction.com/ap/
-http://partner.download-sofort.com
-http://promo.
-http://promos.
-http://pub.lookery.com/
-http://public.cicero-media.de
-http://publisher.shopzilla.com/$subdocument
-http://reduxads.
-http://sel.ads.
-http://survey.novatris.com$script
-http://track*.mybloglog.com/
-http://uff5.to
-http://vas.ppro.de/
-http://www.ad-z.de
-http://www.adplosive.com
-http://www.adsforindians.com
-http://www.adwaves.de
-http://www.axill.com
-http://www.banner-rotation.com
-http://www.contaxe.com
-http://www.euro4ads.de
-http://www.lduhtrp.net
-http://www.logr.de
-http://www.openadnetwork.com
-http://www.paidsolution.de
-http://www.peelawayads.com
-http://www.ritecounter.com
-http://www.sedotracker.com/
-http://www.sunnysales.biz
-http://www.uff5.to
-http://www.viewsponsor.com
-http://yourlayer.de
-includes/ad_
-includes/ads/
-intellitxt.com/
-interclick.
-interwebads.de
-kanoodle$match-case
-kingads.net
-kino.to/*/|$script
-kmadserv
-layer-ad$match-case
-linktarget.com
-locationads.
-lygo.com/
-mactechnews.de/images/adv/
-match.net/scripts/mnads$script
-mediavantage.de
-mirando.de
-moviestream.to/*/|$script
-multistats.de
-network.ninemsn.com.au/share/*
-onadadserver.de
-openadlayer
-oxado.com
-phpadsnew
-pmsrvr.com
-popinads.com
-popunder
-popup_ad
-promo_728.
-publicidad
-quantserve.com/
-richmedia.*yimg.
-script/hbx.js
-searchfeed.com
-static/ads/*
-statisfy.net
-swf/ads/*
-taz.de/taz/anz/gifs/*
-trafficlayer.de/
-tribalfusion.com/
-weborama.com
-weborama.fr
-xbitlabs.com/images/banners/*
-|http://*mediaplex.com/
-|http://103bees.com/bees/
-|http://213.239.222.7/$script
-|http://78.46.43.182/$script
-|http://78.46.44.246/$script
-|http://78.46.46.67/$script
-|http://78.46.52.163/$script
-|http://a.ads.
-|http://a.dimaso.net/?*
-|http://ad-track.de/
-|http://adfarm
-|http://adfire.de/
-|http://adi.sz-online.de/
-|http://adical2.de/c/ad/
-|http://adimg.
-|http://adiowideo.
-|http://adlog.
-|http://adonline.
-|http://adsatt.
-|http://adseu.
-|http://adson.
-|http://adsvr.
-|http://adsxposed.
-|http://adtech.
-|http://adtology
-|http://adv.
-|http://advision.
-|http://adx1.
-|http://affiliate.
-|http://affiliates.
-|http://analyze.*/$script
-|http://anzeigenlieferant.de/c/ad/*
-|http://asn.contextad.de/
-|http://avicash.com/
-|http://banners.*
-|http://bas.schottenland.de
-|http://bilder.guenstiger.de/banner/*
-|http://billabong2.wetter.com/
-|http://binlayer.de/*
-|http://blue.ingame.de
-|http://bwp.$subdocument
-|http://cbanners.
-|http://clicktracker.
-|http://content.ipro.com/
-|http://content.pulse360.com/
-|http://counter.
-|http://cp.intl.match.com/deu/msn/msnde/*$subdocument
-|http://da.feedsportal.com/*/a2.img$image
-|http://data.resultlinks.com/*
-|http://de.ads.
-|http://extads.
-|http://falk.speedera.net/
-|http://fc.webmasterpro.de/
-|http://geizhals.at/b/ad/
-|http://green.ingame.de/*
-|http://iframe.adultfriendfinder.com/promo/
-|http://images.anandtech.com/banners/*
-|http://images.lokalisten.de/lokiimg/kunden/
-|http://img.mybet.com/*?campaign=*
-|http://ivw.
-|http://layer.
-|http://localads.
-|http://mads.
-|http://media.funpic.
-|http://now.eloqua.com
-|http://nwl.gameforge.de/
-|http://partner.gonamic.de/
-|http://pics.firstload.de/
-|http://prom.ecato.net
-|http://promo2.
-|http://rbx.com.com/mac-ad?
-|http://rcm*.amazon.
-|http://searchmarketing.yahoo.
-|http://servedby.
-|http://shop.gamedemos.de/|$subdocument
-|http://sitestat
-|http://spy.
-|http://static.planet49.com/$subdocument
-|http://track.
-|http://tracking.
-|http://traffic.livevideo.com/
-|http://trafficcdn.liveuniversenetwork.com/*
-|http://us.geocities.com
-|http://wodas.wetteronline.de/
-|http://wrapper.*/a?
-|http://www.20min.ch/skyscraper/*
-|http://www.20min.ch/skywin/$object,subdocument
-|http://www.3dstats.com/
-|http://www.ad.
-|http://www.adcross.de
-|http://www.adshopping.com
-|http://www.adtiger.de/
-|http://www.adversalservers.com/
-|http://www.affilicrawler.de/
-|http://www.affilitrade.de/
-|http://www.bannerstatistik.com
-|http://www.bestofferdirect.com/banner/*
-|http://www.bnetworx.com/
-|http://www.burstnet.com/
-|http://www.cash4members.com/
-|http://www.code-server.biz/
-|http://www.contextmatters.de
-|http://www.countercentral.com/
-|http://www.counti.de/
-|http://www.cpaclicks.com
-|http://www.euros4click.de/
-|http://www.fastpromotion.de/
-|http://www.financeads.net
-|http://www.finestresults.com
-|http://www.gigacash.de/
-|http://www.gmx.net/sid*/images/*.gif
-|http://www.go-clicks.de/
-|http://www.hittracker.org/
-|http://www.instadia.net/
-|http://www.kartenhaus.de/banner/*
-|http://www.klickads.de/
-|http://www.linkads.de/
-|http://www.ltassrv.com/
-|http://www.lynxtrack.com/
-|http://www.mb01.com/
-|http://www.midasmedia.eu/
-|http://www.money-layer.com
-|http://www.moneymakers.de
-|http://www.mydirtyhobby.com/hsa/$script
-|http://www.myfreepaysite.com/*
-|http://www.netdebit-counter.de
-|http://www.netzwerk-werbung.de
-|http://www.ox007.com/
-|http://www.pearl.de/sp/microsites/$subdocument
-|http://www.powertracker.de
-|http://www.ppctracking.net/
-|http://www.projectwonderful.com/*
-|http://www.save.tv/STVAF/
-|http://www.scash.de/*
-|http://www.schlauli.de
-|http://www.speedtracker.de/
-|http://www.sponsor4cash.de/
-|http://www.sz-online.de/_tools/coop/$image
-|http://www.teltarif.de/ad/*
-|http://www.totaltracker.com/
-|http://www.tqlkg.com/
-|http://www.ttzmedia.com
-|http://www.view4cash.de/
-|http://www.w3counter.com/
-|http://www.wai.de/
-|http://www.webcounters.de/
-|http://www.webhits.de/
-|http://www.welt.de/*/bigbox_*
-|http://www.welt.de/multimedia/archive/*346x*$object,image
-|http://www.yourtracking.net/
-|https://freemailng*.web.de/unddu_iframe/*$subdocument
-|https://img.web.de/v/logoutlounge/*$subdocument,image
-@@.adserver.yahoo.com/*=HEAD&
-@@.brightcove.com*/viewer/
-@@.doubleclick.net/*/DartShell$other,object-subrequest
-@@.doubleclick.net/*sect=player;
-@@.doubleclick.net/adj/playergen.
-@@.doubleclick.net/adx/www.nntv.de/$other,object-subrequest
-@@.doubleclick.net/crossdomain.xml$other,object-subrequest
-@@.doubleclick.net/pfadx/*;vidID=$other,object-subrequest
-@@.doubleclick.net/pfadx/video.*preroll$other,object-subrequest
-@@.imeem.com/*/video_player.swf?$other,object-subrequest
-@@.js.yimg.com/combo?*/carousel_*/sponsored_links
-@@.linksys.com/*/hbx/
-@@.sitestat.com/ing-diba/
-@@/ads.imeem.com/*$other,object-subrequest
-@@://res.europcar.com/$subdocument
-@@http://oascentral.feedroom.com
-@@http://oascentral.gameinvasion.net
-@@rad.live.com/*&DPJS
-@@yahoo.com/a?*headr
-@@|http://*.google.*/download-
-@@|http://*.tfag.de/*/videoplayer
-@@|http://ad.eurosport.com/RealMedia/ads/adstream_mjx.ads/video.eurosport.
-@@|http://ad.stadtplandienst.de/spd/adframe.php$subdocument
-@@|http://ads1.msn.com/library/dap.js
-@@|http://adserver.71i.de/global_js/globalV6.js|$match-case
-@@|http://austria1.adverserve.net/RealMedia/ads/adstream_mjx.ads/sat1at/*?content_type=video
-@@|http://derstandard.at/MetaAdServer/werbung.asp
-@@|http://desktop.google.*
-@@|http://promo.ebay.de/$subdocument
-@@|http://video*.tape.tv/play/werbung/*$other,object-subrequest
-@@|http://www.drei.at/*ads
-@@|http://www.google.com/talk/
-@@|http://www.krone.tv/*/kmwebtv/
-@@|http://www.n-tv.de/s/player/NTV_Player_
-3dcenter.org#DIV(id^=add_)
-92.241.169.251##div#PlayerContent > center > img\[usemap="#Map"]
-angesagter.de#A(href^=out.php?bid=)
-anonymouse.org#DIV(id=mouselayer)
-ask.com#DIV(class=gsl)
-autobild.de#DIV(class^=adspace-)
-beisammen.de##td.mainpage > table\[cellspacing="0"]\[cellpadding="0"]\[border="0"]:first-child + table
-bildblog.de#DIV(class=anzeige)
-bildblog.de#DIV(class=reklam)
-bildblog.de#DIV(class=wb_contentad)
-billiger.de#DIV(id=fullbanner)
-blog.de#DIV(id=bottomBanner)
-books.google.de#DIV(id=bottom_ad)
-branchen-info.net,staedte-info.net,brd-info.net#DIV(id^=Layer)
-chip.de#IFRAME(id=brandbox)
-chip.de#div(bullet-partner)
-chip.de#div(class=bullet-sponsored-links)
-chip.de#div(form-teaser)
-chip.de,xonio.com#div(id=resizetableBANNER)
-computerbase.de#IMG(id=powered_by_lycos)
-computerbase.de#table(topbanner)
-computerwoche.de#DIV(class=HeadLeaderBoard)
-computerwoche.de#div(id^=banner)
-creativeproxy.uimserv.net#DIV(id=logoutLounge)
-dailymotion.com#DIV(class*=masscast)
-dasoertliche.de#TABLE(class=hl)
-de.ask.com#DIV(class^=gsp)
-derstandard.at#DIV(id=mztBox)
-deviantart.com#DIV(id=adso-magnifico)
-deviantart.com#DIV(id^=ad-)
-deviantart.com#div(class^=sleekadbubble)
-dict.leo.org#TD(class=sidebar)
-dict.leo.org#TD(class=standard_banner)
-digg.com#DIV(id*=_ad)
-digital-world.de#DIV(class=hiddenAdDiv)
-digital-world.de#DIV(id=sky)
-directupload.net#TABLE(width=100%)(align=center)(style=height: 101px;)
-domaintools.com#*(g-keywords)
-download.com#DIV(class$=-ad)
-download.com#DIV(class=ad)
-download.com#DIV(class=ad-mpu)
-download.com#DIV(id=rec-downloads)
-download.com#DIV(id^=launchpad-ads-)
-dslteam.de#TABLE(class=anzeige)
-ebay.de#*(topBannerAd)
-elixic.de#div(style*=/ad-rahmen-)
-elixic.de#td(name=top-banner)
-erweiterungen.de#div(class=abaAds)
-eurogamer.de#DIV(class=mpuAd)
-evendi.de#DIV(id=buttonAds)
-evendi.de#div(id=mastercardAd)
-evo-cars.de#div(class=xaded)
-facebook.com#DIV(class$=_SidebarAds)
-facebook.com#DIV(class*=sponsor)
-faz.net#DIV(class=AdBox)
-faz.net#DIV(id^=BoxAngebotVerlag)
-fcbayern.t-com.de#DIV(class=skyscraper)
-fifaboards.de#DIV(class=superbanner)
-filmstarts.de#DIV(id=lycos)
-finance.yahoo.com#TABLE(id=hdrads)
-finanztreff.de#DIV(class=admarker)
-finanztreff.de#DIV(class=adpartner)
-finanztreff.de#DIV(id=adSpacer)
-flickr.com#*(class^=ad_slug)
-freeware.de#DIV(id=popup_layer)
-gamepro.de#DIV(id=RightTeaserBanner)
-gamestar.de#A(href*=.eyewonder.com)
-gamestar.de#A(href^=http://ad.doubleclick.net/)
-gamestar.de#DIV(class=wide_ads)
-gametrailers.com#div(id^=ad_)
-geizhals.at##td.s\[width="100%"] + td\[width="305"]
-geizhals.at#TABLE(bgcolor=#999999)
-gmx.net#*(shopping)
-gmx.net#DIV(class=adv singlecontent)
-gmx.net#DIV(id=adv)
-gmx.net#DIV(id=nav-sub-bin)
-google.at,google.ch,google.de,google.auth-o-mat.com#TABLE(id=mbEnd)(width=30%)
-google.com#DIV(id^=tba)
-google.com#TABLE(class=ra)(bgcolor=#ffffff)(align=right)(width=30%)
-google.com,google.de,google.at,google.ch,google.nl,google.auth-o-mat.com#DIV(id=tads)
-google.com,google.de,google.at,google.ch,google.nl,google.auth-o-mat.com#TABLE(id$=-ads)
-google.com,google.de,google.at,google.ch,google.nl,google.auth-o-mat.com#TABLE(id=mbEnd)(class=ra)(bgcolor=#ffffff)(align=right)
-google.com,google.de,google.at,google.ch,google.nl,google.auth-o-mat.com#table(width=25%)(align=right)
-google.de,google.at,google.ch,google.com,google.nl,google.auth-o-mat.com#DIV(id^=tpa)
-guenstiger.de#DIV(id=popup)
-guenstiger.de#div(id=mastercardLayer)
-guenstiger.de#table(width=920)(height=62)(bgcolor=#ffffff)
-guide.opendns.com#DIV(id=dnsstuffad)
-heise.de#*(adbottom)
-heise.de#*(leaderboard)
-heise.de#*(skyscraper)
-heise.de#DIV(class$=adv ISI_IGNORE)
-heise.de#DIV(class=ISI_IGNORE)
-heise.de#DIV(class=adbottom_itmarkt)
-heise.de#DIV(class=heiseadvert)
-heise.de#div(contentbanner)
-heise.de#h4(kasten_markt_titel)
-heise.de#table(kasten_markt)
-herold.at#*(class*=sponsor)
-herold.at#DIV(class=zpage)
-herold.at#DIV(id=bpAd)
-herold.at#DIV(id=downloadBox)
-herold.at#DIV(id=fsb)
-herold.at#DIV(id=loveat)
-herold.at#div(class=rBoard)
-horizont.net#DIV(id=adlayerdiv)
-imageshack.us#DIV(id$=addiv)
-imageshack.us#table(table_decoration)(width=300)
-imdb.com#*(id=top_ad_wrapper)
-imdb.com#A(href*=?promotion_code=)
-imdb.com#DIV(id$=adrhs)
-imdb.com#DIV(id=swf_728x90)
-imdb.com#DIV(id=tn15shopbox)
-imdb.com#DIV(id^=lea_)
-imeem.com#DIV(id^=PanelImeemAd)
-ingame.de#div(id=adlayer)
-kicker.de#DIV(class=ad-promo)
-kino.to##div#PlayerContent > center > img\[usemap="#Map"]
-kino.to##div#PlayerContent > center > img\[width="579"]\[height="120"]
-kino.to#*(href*=.firstload.de)
-kino.to#DIV(style=display: block; width: 780px; top: 10px; left: 10px; height: 410px; margin-left: 27%;)
-klicktel.de#DIV(id$=_adtable)
-krone.at#TABLE(class=teaser_bg)(height=100%)
-kwick.de#DIV(id^=ad-)
-last.fm,lastfm.de#DIV(id=footer_ads)
-leo.org##TD\[width="55%"]\[valign="middle"]\[style="background-color: rgb(255, 255, 238); text-align: center;"]
-leo.org#TD(width=15%)(valign=top)(style=font-size: 100%; padding-top: 2px;)
-linksave.in#DIV(id=ad)
-live.com#*(class=adRow)
-live.com#DIV(id$=AdPart)
-live.com#DIV(id=AdContainer)
-lokalisten.de#DIV(class=skyScraper)
-lycos.de#DIV(class=overture)
-lycos.de#DIV(id=ad_wide_bigtop)
-lycos.de#DIV(id=globalwidebanner)
-lyrics.de#div(id=genlayer)
-mactechnews.de#DIV(class^=Advertisement)
-mail.google.com##*.XoqCub > \[style="width: 189px;"]
-mail.google.com##*.XoqCub > \[style="width: 225px;"]
-mail.google.com#div(class^=rh)
-mail.live.com#DIV(class=ToolsCustomerCommunication)
-mail.live.com#DIV(id=RadAd_Banner)
-mail.live.com#div(id*=RadAd)
-mail.yahoo.com#*(id=welcomeAdsContainer)
-mail.yahoo.com#div(nwad)
-map24.com#*(id=cont_m24up)
-map24.com#DIV(id=MAP24_NAVSHOP)
-maps.google.de#DIV(class=ads noprint)
-maps.google.de,maps.google.com#DIV(id=mclip)
-maps.live.de#*(id^=search_sponsorsRepeater_)
-motor-talk.de#DIV(class*=commercialbox)
-motor-talk.de#DIV(id=topbanner)
-moviestream.to##div#PlayerContent > center > img\[usemap="#Map"]
-msn.com#DIV(class$=radads)
-msn.com#DIV(class=genericadtext)
-msn.com#DIV(id=lgad)
-msn.de#DIV(class$=radads)
-mtv.de#DIV(class=contentAd)
-mtv.de#DIV(id$=_adv)
-munich-airport.de#*(class^=superbanner_)
-my.msn.com#DIV(id=dapDiv)
-myspace.com#DIV(id=ad-wrap)
-myspace.com#DIV(id=channel_ad)
-myvideo.de#*(id^=skyscraper)
-myvideo.de#DIV(id=BANNER_full1)
-myvideo.de#TD(class=body mya)
-n-tv.de#A(href=http://ntv.experteer.de/)
-n-tv.de#A(href^=http://ntv.parship.de/?source=)
-n-tv.de#DIV(class=banner_top)
-n-tv.de#DIV(class=pl_anzeige)
-n-tv.de#DIV(id=skypos)
-n-tv.de#DIV(id=top5)
-n-tv.de#DIV(id=ubottom)
-n-tv.de#DIV(id=ulayer)
-n-tv.de#DIV(id=wallsky)
-n-tv.de#SPAN(class=kleinTxt)
-n-tv.de#TABLE(class=tblinks)
-n-tv.de#TABLE(id=bannerhead)
-n24.de#DIV(class=marginal_ad)
-n24.de#DIV(class^=ad_)
-neowin.net#DIV(class=menuads)
-netzeitung.de#DIV(class$=_ad)
-nzz.ch#div(class=advXertXoriXals)
-ogame.de,ogame.org#div(id=combox_container)
-onvista.de#*(LAYER_AD_CONTAINER)
-onvista.de#DIV(id=MEGASIZE_BANNER)
-onvista.de#TD(id=bottom_line)(class=footer_br)
-opendns.com#DIV(id$=-ads)
-opendns.com#DIV(id=noresultsads)
-otrforum.com##DIV\[id=""]\[style^="display: block; left:"]
-pc-magazin.de#TD(class=micrLink)
-pcgames.de#*(class$=_werbung)
-pcgames.de#A(href*=http://ad.doubleclick.net/)
-pcgames.de#TABLE(class=ga_metaboli_bg)
-pcgames.de#TD(class=sqoops_maincontainer)
-pcgames.de#table(style*=/external/gfx/firstpage/blau_)
-pcgames.de#table(style*=/external/gfx/firstpage/orange_)
-pcgameshardware.de#TABLE(background^=/external/gfx/defaults/metaboli/blau_)
-pcgameshardware.de#TABLE(background^=/external/gfx/defaults/metaboli/orange_)
-pcgameshardware.de#TD(class$=skyscraper)
-pcgameshardware.de#table(style*=/external/gfx/firstpage/blau_)
-pcmasters.de#DIV(class=top-banner)
-pcworld.com#DIV(class=adMkt2Colg)
-pcworld.com#DIV(class=areaBanner)
-pcworld.com#DIV(class=printHide)
-pcworld.com#DIV(class^=adMkt2Col)
-pcworld.com#DIV(class^=buttonad)
-pcworld.com#DIV(class^=towerAd)
-photobucket.com#*(advPanelContainer)
-photobucket.com#*(cellAd)
-photobucket.com#*(id*=Promo)
-photobucket.com#DIV(id=containerSqAd)
-pi-news.net#DIV(class=r_ads)
-pspfreak.de#DIV(id=popup)
-pspfreak.de#DIV(id=umlaufnone)
-quotenmeter.de#*(id^=ad_)
-reuters.com#DIV(class=ad125)
-reuters.com#DIV(class^=adButton)
-reuters.com#DIV(id$=_SpecialOffersSection)
-reuters.com#DIV(id^=dms_hd_IDS_)
-reuters.com#TABLE(class=articleSkyAd)
-search.live.com#DIV(class^=sb_ads)
-search.msn.de##DIV#header > DIV.headerTopFake:first-child
-search.yahoo.com#DIV(class=bbox)
-search.yahoo.com#DIV(id=east)
-search.yahoo.com#DIV(id=sec-col)
-serienjunkies.org#DIV(id=topbar)
-sevenload.com#DIV(class=textAd)
-sevenload.com#DIV(id=contentAadContainer)
-sevenload.com#DIV(id=skyyscraperContainer)
-sevenload.com#DIV(id=superbaannerContainer)
-shareware.de#DIV(id=popup_layer)
-shortnews.de#a(href^=/goto.cfm?t=)
-skins.be#DIV(class=shortBioShadowB w240)
-skins.be#DIV(id=walltopad)
-skins.be#div(class^=h_ad)
-softonic.de#DIV(class=topbanner)
-softonic.de#DIV(class^=ad_)
-softonic.de#DIV(id^=ad_)
-sourceforge.net#DIV(id^=fad)
-sourceforge.net#div(adbatch)
-speedreport.de#DIV(class=box_s)
-spiegel.de#A(href*=.placement24.com)
-spielegeier.de#DIV(id=dropin)(class=box)
-spieletipps.de#DIV(class^=stiYsm)
-spieletipps.de#DIV(id$=_layerad)
-spieletipps.de#DIV(id=spOverture)
-sport1.de#DIV(class=fullbanner)
-sport1.de#DIV(id=skyfallback)
-sport1.de#div(class=TrendBoxHome)
-sportal.de#DIV(id^=banner)
-sportal.de#TD(class=anzeige)
-stadtplan.net#DIV(class$=werbung)
-stadtplandienst.de#*(src^=http://ad.stadtplandienst.de/)
-stupidedia.org#DIV(id=buch)
-suche.lycos.de#DIV(class=bottomkiti)
-suchen.de#DIV(id^=ppcmapmove)
-suchen.de#OL(id^=localResultPpc)
-sueddeutsche.de#DIV(class=bannerMediumRectangle)
-t-online.de#DIV(id$=_anz)
-t-online.de#DIV(id=tsrwh)
-tagesspiegel.de#*(class^=anzeige_)
-tarifecheck.de#div(skycont)
-taz.de#*(class^=anzeige)
-tchibo.de#div(id^=layer)
-teccentral.de#SPAN(class=anzeige_b)
-tecchannel.de#DIV(id=partnerzone)
-tecchannel.de#DIV(id=ticker)
-theinquirer.de#DIV(class^=pubind)
-theinquirer.net,theinquirer.de#DIV(id=mpuAd)
-tinypic.com#DIV(class$= ad)
-tomshardware.com#A(href*=.smartadserver.com)
-tutorials.de#DIV(class=postbit_adcode)
-tweakpc.de#*(class=anzeige)
-tweakpc.de#IMG(src^=/i/anzeige_v)
-unixboard.de##*\[style="border-style: none solid; border-color: -moz-use-text-color rgb(226, 225, 234); border-width: 0px 1px;"] + * *
-veoh.com#DIV(id=adTop)
-vimeo.com#DIV(class=atlas ad)
-web.de##TABLE\[bgcolor="#ffffff"]\[width="100%"]\[style="border: 1px solid rgb(136, 136, 136); text-align: left;"]
-web.de#DIV(id^=adv-)
-web.de#TABLE(cellspacing=1)(cellpadding=0)(border=0)(bgcolor=#888888)(width=100%)(style=margin-top: 10px;)
-web.de#div(id=advMovein)
-webhosting.de#DIV(id=header-banner)
-welt.de#DIV(class=ad)
-welt.de#DIV(class=videoCompanionBanner)
-welt.de#DIV(class^=searchAnzeige)
-wer-kennt-wen.de#div(id=ads)
-wetter.com#DIV(class^=box blue)
-wetter.com#DIV(id*=BOX)(class*=blue)
-wetter.com#DIV(id=smallteaser)
-winboard.org##TD\[width="130"]\[valign="top"]\[align="center"]:last-child
-winfuture.de#DIV(id=ad)
-winload.de#DIV(id=topBanner)
-woerterbuch.info#TD(class=ov)(valign=top)(bgcolor=#f1f1f1)(align=left)(colspan=2)
-woerterbuch.info#TD(class=standard)(valign=top)(bgcolor=#e5e5e5)(align=right)(colspan=2)
-www.google.com,www.google.de,www.google.at,www.google.ch,www.google.nl##table\[bgcolor="#ffffff"]\[align="right"]\[style=""]
-www.planet-liebe.de##TR.portalmenu + TR + TR + TR + TR
-xonio.com#DIV(class=bullet-extern border3)
-yahoo.com#*(ad)
-yahoo.com#*(class^=ad_slug_)
-yahoo.com#*(class^=overture)
-yahoo.com#*(id$=lrec_ad)
-yahoo.com#*(id*=sponsored)
-yahoo.com#*(nwPane)
-yahoo.com#DIV(class=lrec)
-yahoo.com#DIV(class=ov_frame)
-yahoo.com#DIV(class=rec)
-yahoo.com#DIV(class=spons)
-yahoo.com#DIV(class=yschbbox)
-yahoo.com#DIV(class^=yad)
-yahoo.com#DIV(id$=-sponlink)
-yahoo.com#DIV(id=adlrec)
-yahoo.com#DIV(id=lrec)
-yahoo.com#DIV(id=marketplace)
-yahoo.com#DIV(id=mrec)
-yahoo.com#DIV(id=northad)
-yahoo.com#DIV(id=promo)
-yahoo.com#DIV(id=southad)
-yahoo.com#DIV(id=yschsec)
-yahoo.com#DIV(id=ytrAd)
-yahoo.com#DIV(id^=ad-)
-yahoo.com#DIV(id^=adunit)
-yahoo.com#DIV(id^=advert_)
-yahoo.com#DIV(id^=lrec_)
-yahoo.com#DIV(id^=overture)
-yahoo.com#SPAN(id^=yfs_ad_)
-yahoo.com#TABLE(cellspacing=5)(cellpadding=0)(border=0)(align=left)
-yahoo.com#TD(ygrp-ad)
-yahoo.com#div(id=advertising)
-yahoo.com#div(id=eyebrow)
-yahoo.com#div(id=smallbiz)
-yahoo.com#div(id^=swads)
-yahoo.com#div(northbanner)
-yahoo.net#DIV(id=adlrec)
-yahoo.net#DIV(id^=overture)
-yopi.de#DIV(class^=ad_)
-youtube.com#DIV(id=search-pva)
-youtube.com#DIV(id=watch-channel-brand-div)
-youtube.com#DIV(id^=ad_creative_)
-zdnet.de#DIV(id*=_promo)
-zeit.de#DIV(adfooter)
-zeit.de#DIV(class$=_ad)
-zeit.de#DIV(class$=_ads)
- </div>
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- function readFile(file)
- {
- let fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Components.interfaces.nsIFileInputStream);
- fileStream.init(file, 0x01, 0444, 0);
-
- let stream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
- .createInstance(Components.interfaces.nsIConverterInputStream);
- stream.init(fileStream, "UTF-8", 16384, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
- let result = "";
- let data = {};
- while (stream.readString(0xFFFFFF, data))
- result += data.value;
-
- stream.close();
-
- return result;
- }
-
- function canonize(data)
- {
- let curSection = null;
- let sections = [];
- for each (let line in (data + "\n[end]").split(/[\r\n]+/))
- {
- if (/^\[.*\]$/.test(line))
- {
- if (curSection)
- sections.push(curSection);
-
- curSection = {header: line, data: []};
- }
- else if (curSection && /\S/.test(line))
- curSection.data.push(line);
- }
- for each (let section in sections)
- {
- section.key = section.header + " " + section.data[0];
- section.data.sort();
- }
- sections.sort(function(a, b)
- {
- if (a.key < b.key)
- return -1;
- else if (a.key > b.key)
- return 1;
- else
- return 0;
- });
- return sections.map(function(section) {
- return [section.header].concat(section.data).join("\n");
- }).join("\n");
- }
-
- Cu.import(baseURL.spec + "Utils.jsm");
- prepareFilterComponents();
- preparePrefs();
-
- Prefs.patternsbackups = 0;
- Prefs.patternsbackupinterval = 24;
-
- if (/[?&]profiler/i.test(location.href))
- document.getElementById("display").innerHTML = '<p><a href="?">Run this test without profiler</a></p>';
- else
- document.getElementById("display").innerHTML = '<p><a href="?profiler">Run this test with profiler</a></p>';
-
- let testData = "";
- for (let child = document.getElementById("filterData").firstChild; child; child = child.nextSibling)
- testData += child.nodeValue;
- testData = testData.replace(/\s+$/, "");
-
- // Make sure not to trigger fallback code on format version changes
- testData = "version=" + FilterStorageGlobal.formatVersion + "\n" + testData;
-
- let tempFile = Utils.dirService.get("TmpD", Components.interfaces.nsIFile);
- tempFile.append("temp_patterns.ini");
- tempFile.createUnique(tempFile.NORMAL_FILE_TYPE, 0666);
-
- {
- let fileStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Components.interfaces.nsIFileOutputStream);
- fileStream.init(tempFile, 0x02 | 0x08 | 0x20, 0644, 0);
-
- let stream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
- .createInstance(Components.interfaces.nsIConverterOutputStream);
- stream.init(fileStream, "UTF-8", 16384, Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- stream.writeString(testData);
- stream.close();
- }
-
- FilterStorage.__defineGetter__("sourceFile", function() tempFile.clone());
-
- {
- let startTime = Date.now();
- FilterStorage.loadFromDisk();
- let endTime = Date.now();
- ok(true, "Time to load filters: " + (endTime - startTime) + "ms");
- }
-
- {
- let startTime = Date.now();
- FilterStorage.saveToDisk();
- let endTime = Date.now();
- ok(true, "Time to save filters: " + (endTime - startTime) + "ms");
- }
-
- is(canonize(readFile(tempFile)), canonize(testData), "Read/write result");
-
- Cu.import(baseURL.spec + "Public.jsm");
- AdblockPlus.updateExternalSubscription("~external~external subscription ID", "External subscription", ["foo", "bar"]);
-
- let externalSubscriptions = FilterStorage.subscriptions.filter(function (subscription) subscription instanceof ExternalSubscription);
- is(externalSubscriptions.length, 1, "updateExternalSubscription added an external subscription to the list");
- if (externalSubscriptions.length == 1)
- {
- is(externalSubscriptions[0].url, "~external~external subscription ID", "ID of external subscription was set correctly");
- is(externalSubscriptions[0].filters.length, 2, "External subscription has two filters");
- }
- FilterStorage.saveToDisk();
- is(canonize(readFile(tempFile)), canonize(testData), "External subscription wasn't saved to disk");
-
- for each (let subscription in FilterStorage.subscriptions.filter(function (subscription) {return !(subscription instanceof SpecialSubscription)}))
- {
- FilterStorage.removeSubscription(subscription);
- }
- let backupFile1 = tempFile.clone();
- backupFile1.leafName = backupFile1.leafName.replace(/\.ini$/, "-backup1.ini");
-
- FilterStorage.saveToDisk();
- ok(!backupFile1.exists(), "Backup not created with patternsbackups = 0");
-
- Prefs.patternsbackups = 2;
- FilterStorage.saveToDisk();
- ok(backupFile1.exists(), "Backup created with patternsbackups = 2");
-
- backupFile1.lastModifiedTime -= 10000;
- let oldModifiedTime = backupFile1.lastModifiedTime;
- FilterStorage.saveToDisk();
- backupFile1 = backupFile1.clone(); // File parameters are cached, clone to prevent this
- is(backupFile1.lastModifiedTime, oldModifiedTime, "Backup not overwritten if it is only 10 seconds old");
-
- backupFile1.lastModifiedTime -= 40*60*60*1000;
- oldModifiedTime = backupFile1.lastModifiedTime;
- FilterStorage.saveToDisk();
- backupFile1 = backupFile1.clone(); // File parameters are cached, clone to prevent this
- isnot(backupFile1.lastModifiedTime, oldModifiedTime, "Backup overwritten if it is 40 hours old");
-
- let backupFile2 = backupFile1.clone();
- backupFile2.leafName = backupFile2.leafName.replace(/-backup1\.ini$/, "-backup2.ini");
- ok(backupFile2.exists(), "Second backup created when first backup is overwritten");
-
- backupFile1.lastModifiedTime -= 20000;
- oldModifiedTime = backupFile2.lastModifiedTime;
- FilterStorage.saveToDisk();
- backupFile2 = backupFile2.clone(); // File parameters are cached, clone to prevent this
- is(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup not overwritten if first one is only 20 seconds old");
-
- backupFile1.lastModifiedTime -= 25*60*60*1000;
- oldModifiedTime = backupFile2.lastModifiedTime;
- FilterStorage.saveToDisk();
- backupFile2 = backupFile2.clone(); // File parameters are cached, clone to prevent this
- isnot(backupFile2.lastModifiedTime, oldModifiedTime, "Second backup overwritten if first one is 25 hours old");
-
- let backupFile3 = backupFile2.clone();
- backupFile3.leafName = backupFile3.leafName.replace(/-backup2\.ini$/, "-backup3.ini");
- ok(!backupFile3.exists(), "Third backup not created with patternsbackups = 2");
-
- try
- {
- tempFile.remove(false);
- } catch (e) {}
- try
- {
- backupFile1.remove(false);
- } catch (e) {}
- try
- {
- backupFile2.remove(false);
- } catch (e) {}
- try
- {
- backupFile3.remove(false);
- } catch (e) {}
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_matcher.html b/mochitest/tests/test_matcher.html
deleted file mode 100644
index 03fb626..0000000
--- a/mochitest/tests/test_matcher.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Filter matcher tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- function compareKeywords(text, expected)
- {
- for each (let filter in [Filter.fromText(text), Filter.fromText("@@" + text)])
- {
- let result = [];
- for each (let dummy in expected)
- {
- keyword = matcher.findKeyword(filter);
- result.push(keyword);
- if (keyword)
- {
- let dummyFilter = Filter.fromText('^' + keyword + '^');
- dummyFilter.filterCount = Infinity;
- matcher.add(dummyFilter);
- }
- }
-
- is(result.join(", "), expected.join(", "), "Keyword candidates for " + filter.text);
- matcher.clear();
- }
- }
- function checkMatch(filters, location, contentType, docDomain, thirdParty, expected)
- {
- for each (let filter in filters)
- matcher.add(Filter.fromText(filter));
-
- let result = matcher.matchesAny(location, contentType, docDomain, thirdParty);
- if (result)
- result = result.text;
-
- is(result, expected, "match(" + location + ", " + contentType + ", " + docDomain + ", " + (thirdParty ? "third-party" : "first-party") + ") with:\n" + filters.join("\n"));
- matcher.clear();
-
- for (let i = 0; i < 2; i++)
- {
- for each (let filter in filters)
- combinedMatcher.add(Filter.fromText(filter));
-
- let result = combinedMatcher.matchesAny(location, contentType, docDomain, thirdParty);
- if (result)
- result = result.text;
-
- is(result, expected, "combinedMatch(" + location + ", " + contentType + ", " + docDomain + ", " + (thirdParty ? "third-party" : "first-party") + ") with:\n" + filters.join("\n"));
-
- // For next run: add whitelisting filters
- filters = filters.map(function(text) "@@" + text);
- if (expected)
- expected = "@@" + expected;
- }
- combinedMatcher.clear();
- }
- function cacheCheck(location, contentType, docDomain, thirdParty, expected)
- {
- let result = matcher.matchesAny(location, contentType, docDomain, thirdParty);
- if (result)
- result = result.text;
-
- is(result, expected, "match(" + location + ", " + contentType + ", " + docDomain + ", " + (thirdParty ? "third-party" : "first-party") + ") with static filters");
- }
-
- is(typeof Matcher, "function", "typeof Matcher");
- is(typeof CombinedMatcher, "function", "typeof CombinedMatcher");
- is(typeof defaultMatcher, "object", "typeof defaultMatcher");
- ok(defaultMatcher instanceof CombinedMatcher, "defaultMatcher is a CombinedMatcher instance");
-
- let matcher = new Matcher();
- let combinedMatcher = new CombinedMatcher();
-
- compareKeywords("*", []);
- compareKeywords("asdf", []);
- compareKeywords("/asdf/", []);
- compareKeywords("/asdf1234", []);
- compareKeywords("/asdf/1234", ["asdf"]);
- compareKeywords("/asdf/1234^", ["asdf", "1234"]);
- compareKeywords("/asdf/123456^", ["123456", "asdf"]);
- compareKeywords("^asdf^1234^56as^", ["asdf", "1234", "56as"]);
- compareKeywords("*asdf/1234^", ["1234"]);
- compareKeywords("|asdf,1234*", ["asdf"]);
- compareKeywords("||domain.example^", ["example", "domain"]);
- compareKeywords("&asdf=1234|", ["asdf", "1234"]);
- compareKeywords("^foo%2Ebar^", ["foo%2ebar"]);
- compareKeywords("^aSdF^1234", ["asdf"]);
- compareKeywords("_asdf_1234_", ["asdf", "1234"]);
- compareKeywords("+asdf-1234=", ["asdf", "1234"]);
- compareKeywords("/123^ad2&ad&", ["123", "ad2"]);
- compareKeywords("/123^ad2&ad$script,domain=example.com", ["123", "ad2"]);
- compareKeywords("^foobar^$donottrack", ["foobar"]);
- compareKeywords("*$donottrack", ["donottrack"]);
-
- checkMatch([], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["abc"], "http://abc/def", "IMAGE", null, false, "abc");
- checkMatch(["abc", "ddd"], "http://abc/def", "IMAGE", null, false, "abc");
- checkMatch(["ddd", "abc"], "http://abc/def", "IMAGE", null, false, "abc");
- checkMatch(["ddd", "abd"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["abc", "://abc/d"], "http://abc/def", "IMAGE", null, false, "://abc/d");
- checkMatch(["://abc/d", "abc"], "http://abc/def", "IMAGE", null, false, "://abc/d");
- checkMatch(["|http://"], "http://abc/def", "IMAGE", null, false, "|http://");
- checkMatch(["|http://abc"], "http://abc/def", "IMAGE", null, false, "|http://abc");
- checkMatch(["|abc"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["|/abc/def"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["/def|"], "http://abc/def", "IMAGE", null, false, "/def|");
- checkMatch(["/abc/def|"], "http://abc/def", "IMAGE", null, false, "/abc/def|");
- checkMatch(["/abc/|"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["http://abc/|"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["|http://abc/def|"], "http://abc/def", "IMAGE", null, false, "|http://abc/def|");
- checkMatch(["|/abc/def|"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["|http://abc/|"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["|/abc/|"], "http://abc/def", "IMAGE", null, false, null);
- checkMatch(["||example.com/abc"], "http://example.com/abc/def", "IMAGE", null, false, "||example.com/abc");
- checkMatch(["||com/abc/def"], "http://example.com/abc/def", "IMAGE", null, false, "||com/abc/def");
- checkMatch(["||com/abc"], "http://example.com/abc/def", "IMAGE", null, false, "||com/abc");
- checkMatch(["||mple.com/abc"], "http://example.com/abc/def", "IMAGE", null, false, null);
- checkMatch(["||.com/abc/def"], "http://example.com/abc/def", "IMAGE", null, false, null);
- checkMatch(["||http://example.com/"], "http://example.com/abc/def", "IMAGE", null, false, null);
- checkMatch(["||example.com/abc/def|"], "http://example.com/abc/def", "IMAGE", null, false, "||example.com/abc/def|");
- checkMatch(["||com/abc/def|"], "http://example.com/abc/def", "IMAGE", null, false, "||com/abc/def|");
- checkMatch(["||example.com/abc|"], "http://example.com/abc/def", "IMAGE", null, false, null);
- checkMatch(["abc", "://abc/d", "asdf1234"], "http://abc/def", "IMAGE", null, false, "://abc/d");
- checkMatch(["foo*://abc/d", "foo*//abc/de", "://abc/de", "asdf1234"], "http://abc/def", "IMAGE", null, false, "://abc/de");
- checkMatch(["abc$third-party", "abc$~third-party", "ddd"], "http://abc/def", "IMAGE", null, false, "abc$~third-party");
- checkMatch(["abc$third-party", "abc$~third-party", "ddd"], "http://abc/def", "IMAGE", null, true, "abc$third-party");
- checkMatch(["//abc/def$third-party", "//abc/def$~third-party", "//abc_def"], "http://abc/def", "IMAGE", null, false, "//abc/def$~third-party");
- checkMatch(["//abc/def$third-party", "//abc/def$~third-party", "//abc_def"], "http://abc/def", "IMAGE", null, true, "//abc/def$third-party");
- checkMatch(["abc$third-party", "abc$~third-party", "//abc/def"], "http://abc/def", "IMAGE", null, true, "//abc/def");
- checkMatch(["//abc/def", "abc$third-party", "abc$~third-party"], "http://abc/def", "IMAGE", null, true, "//abc/def");
- checkMatch(["abc$third-party", "abc$~third-party", "//abc/def$third-party"], "http://abc/def", "IMAGE", null, true, "//abc/def$third-party");
- checkMatch(["abc$third-party", "abc$~third-party", "//abc/def$third-party"], "http://abc/def", "IMAGE", null, false, "abc$~third-party");
- checkMatch(["abc$third-party", "abc$~third-party", "//abc/def$~third-party"], "http://abc/def", "IMAGE", null, true, "abc$third-party");
- checkMatch(["abc$image", "abc$script", "abc$~image"], "http://abc/def", "IMAGE", null, false, "abc$image");
- checkMatch(["abc$image", "abc$script", "abc$~script"], "http://abc/def", "SCRIPT", null, false, "abc$script");
- checkMatch(["abc$image", "abc$script", "abc$~image"], "http://abc/def", "OTHER", null, false, "abc$~image");
- checkMatch(["//abc/def$image", "//abc/def$script", "//abc/def$~image"], "http://abc/def", "IMAGE", null, false, "//abc/def$image");
- checkMatch(["//abc/def$image", "//abc/def$script", "//abc/def$~script"], "http://abc/def", "SCRIPT", null, false, "//abc/def$script");
- checkMatch(["//abc/def$image", "//abc/def$script", "//abc/def$~image"], "http://abc/def", "OTHER", null, false, "//abc/def$~image");
- checkMatch(["abc$image", "abc$~image", "//abc/def"], "http://abc/def", "IMAGE", null, false, "//abc/def");
- checkMatch(["//abc/def", "abc$image", "abc$~image"], "http://abc/def", "IMAGE", null, false, "//abc/def");
- checkMatch(["abc$image", "abc$~image", "//abc/def$image"], "http://abc/def", "IMAGE", null, false, "//abc/def$image");
- checkMatch(["abc$image", "abc$~image", "//abc/def$script"], "http://abc/def", "IMAGE", null, false, "abc$image");
- checkMatch(["abc$domain=foo.com", "abc$domain=bar.com", "abc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "foo.com", false, "abc$domain=foo.com");
- checkMatch(["abc$domain=foo.com", "abc$domain=bar.com", "abc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "bar.com", false, "abc$domain=bar.com");
- checkMatch(["abc$domain=foo.com", "abc$domain=bar.com", "abc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "baz.com", false, "abc$domain=~foo.com|~bar.com");
- checkMatch(["abc$domain=foo.com", "cba$domain=bar.com", "ccc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "foo.com", false, "abc$domain=foo.com");
- checkMatch(["abc$domain=foo.com", "cba$domain=bar.com", "ccc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "bar.com", false, null);
- checkMatch(["abc$domain=foo.com", "cba$domain=bar.com", "ccc$domain=~foo.com|~bar.com"], "http://abc/def", "IMAGE", "baz.com", false, null);
- checkMatch(["abc$domain=foo.com", "cba$domain=bar.com", "ccc$domain=~foo.com|~bar.com"], "http://ccc/def", "IMAGE", "baz.com", false, "ccc$domain=~foo.com|~bar.com");
- checkMatch(["*$image"], "http://ccc/def", "DONOTTRACK", "example.com", false, null);
- checkMatch(["*$donottrack"], "http://ccc/def", "DONOTTRACK", "example.com", false, "*$donottrack");
- checkMatch(["*$donottrack"], "http://ccc/def", "DONOTTRACK", "example.com", false, "*$donottrack");
- checkMatch(["*$donottrack"], "http://ccc/def", "IMAGE", "example.com", false, null);
- checkMatch(["*$donottrack,third-party"], "http://ccc/def", "DONOTTRACK", "example.com", true, "*$donottrack,third-party");
- checkMatch(["*$donottrack,third-party"], "http://ccc/def", "DONOTTRACK", "example.com", false, null);
-
- // Testing whether result cache messes up results
- matcher = new CombinedMatcher();
- matcher.add(Filter.fromText("abc$image"));
- matcher.add(Filter.fromText("abc$script"));
- matcher.add(Filter.fromText("abc$~image,~script,~document"));
- matcher.add(Filter.fromText("cba$third-party"));
- matcher.add(Filter.fromText("cba$~third-party,~script"));
- matcher.add(Filter.fromText("http://def$image"));
- matcher.add(Filter.fromText("http://def$script"));
- matcher.add(Filter.fromText("http://def$~image,~script,~document"));
- matcher.add(Filter.fromText("http://fed$third-party"));
- matcher.add(Filter.fromText("http://fed$~third-party,~script"));
- cacheCheck("http://abc", "IMAGE", null, false, "abc$image");
- cacheCheck("http://abc", "SCRIPT", null, false, "abc$script");
- cacheCheck("http://abc", "OTHER", null, false, "abc$~image,~script,~document");
- cacheCheck("http://cba", "IMAGE", null, false, "cba$~third-party,~script");
- cacheCheck("http://cba", "IMAGE", null, true, "cba$third-party");
- cacheCheck("http://def", "IMAGE", null, false, "http://def$image");
- cacheCheck("http://def", "SCRIPT", null, false, "http://def$script");
- cacheCheck("http://def", "OTHER", null, false, "http://def$~image,~script,~document");
- cacheCheck("http://fed", "IMAGE", null, false, "http://fed$~third-party,~script");
- cacheCheck("http://fed", "IMAGE", null, true, "http://fed$third-party");
- cacheCheck("http://abc_cba", "DOCUMENT", null, false, "cba$~third-party,~script");
- cacheCheck("http://abc_cba", "DOCUMENT", null, true, "cba$third-party");
- cacheCheck("http://abc_cba", "SCRIPT", null, false, "abc$script");
- cacheCheck("http://def?http://fed", "DOCUMENT", null, false, "http://fed$~third-party,~script");
- cacheCheck("http://def?http://fed", "DOCUMENT", null, true, "http://fed$third-party");
- cacheCheck("http://def?http://fed", "SCRIPT", null, false, "http://def$script");
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_policy.html b/mochitest/tests/test_policy.html
deleted file mode 100644
index 6d87e47..0000000
--- a/mochitest/tests/test_policy.html
+++ /dev/null
@@ -1,355 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Content policy tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="../httpd.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="visibility: hidden;">
- <iframe id="frame" onload="doRunTest()"></iframe>
- </div>
-
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- Cu.import(baseURL.spec + "RequestNotifier.jsm");
- prepareFilterComponents();
- preparePrefs();
-
- let tests = [
- [
- '<img src="test.gif">',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<img src="http://localhost:1234/test.gif">',
- "http://localhost:1234/test.gif", "image", "127.0.0.1", true
- ],
- [
- '<input type="image" src="test.gif">',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<iframe src="data:text/html,%3Cinput%20type%3D%22image%22%20src%3D%22http%3A%2F%2F127.0.0.1:1234%2Ftest.gif%22%3E"></iframe>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<iframe src="data:text/html,%3Ciframe%20src%3D%22data%3Atext%2Fhtml%2C%253Cinput%2520type%253D%2522image%2522%2520src%253D%2522http%253A%252F%252F127.0.0.1%3A1234%252Ftest.gif%2522%253E%22%3E%3C%2Fiframe%3E"></iframe>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<iframe src="about:blank"></iframe><script>window.addEventListener("DOMContentLoaded", function() {frames[0].document.body.innerHTML = \'<input type="image" src="test.gif">\';}, false);<' + '/script>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<div style="background-image: url(test.gif)"></div>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<div style="cursor: url(test.gif), pointer"></div>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- <ol>
- <li style="list-style-image: url(test.gif)">foo</li>
- </ol>,
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<style>div:before { content: url(test.gif); }</style><div>foo</div>',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<embed type="image/gif" src="test.gif"></embed>',
- "http://127.0.0.1:1234/test.gif", "object", "127.0.0.1", false
- ],
- [
- '<object type="image/gif" data="test.gif"></object>',
- "http://127.0.0.1:1234/test.gif", "object", "127.0.0.1", false
- ],
- [
- <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <image src="test.gif"/>
- </window>,
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <image style="list-style-image: url(test.gif)"/>
- </window>,
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <image xlink:href="test.gif"/>
- </svg>,
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <filter>
- <feImage xlink:href="test.gif"/>
- </filter>
- </svg>,
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<' + 'script src="test.js"><' + '/script>',
- "http://127.0.0.1:1234/test.js", "script", "127.0.0.1", false
- ],
- [
- <svg xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <script src="test.js"/>
- </svg>,
- "http://127.0.0.1:1234/test.js", "script", "127.0.0.1", false
- ],
- [
- <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
- <script xlink:href="test.js"/>
- </svg>,
- "http://127.0.0.1:1234/test.js", "script", "127.0.0.1", false
- ],
- [
- '<link rel="stylesheet" type="text/css" href="test.css">',
- "http://127.0.0.1:1234/test.css", "stylesheet", "127.0.0.1", false
- ],
- [
- '<?xml-stylesheet href="test.css" type="text/css"?><window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>',
- "http://127.0.0.1:1234/test.css", "stylesheet", "127.0.0.1", false
- ],
- [
- '<img src="redirect.gif">',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- [
- '<img src="redirect2.gif">',
- "http://127.0.0.1:1234/test.gif", "image", "127.0.0.1", false
- ],
- ];
-
- if (window.navigator.mimeTypes["application/x-shockwave-flash"] && window.navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin)
- {
- tests.push([
- '<embed type="application/x-shockwave-flash" src="test.swf"></embed>',
- "http://127.0.0.1:1234/test.swf", "object", "127.0.0.1", false
- ],
- [
- '<object type="application/x-shockwave-flash" data="test.swf"></object>',
- "http://127.0.0.1:1234/test.swf", "object", "127.0.0.1", false
- ]);
- }
-
- if (window.navigator.mimeTypes["application/x-java-applet"] && window.navigator.mimeTypes["application/x-java-applet"].enabledPlugin)
- {
- // Note: this could use some improvement but Gecko will fail badly with more complicated tests (bug 364400)
- // Note: <applet> is not on the list because it shows some weird async behavior (data is loaded after page load in some strange way)
- tests.push([
- '<embed type="application/x-java-applet" code="test.class" src="test.class"></embed>',
- "http://127.0.0.1:1234/test.class", "object", "127.0.0.1", false
- ],
- [
- '<object type="application/x-java-applet" data="test.class"></object>',
- "http://127.0.0.1:1234/test.class", "object", "127.0.0.1", false
- ]);
- }
-
- if (compareGeckoVersion("1.9.1b3") >= 0)
- {
- tests.push([
- '<style type="text/css">@font-face { font-family: Test; src: url("test.otf"); } html { font-family: Test; }</style>',
- "http://127.0.0.1:1234/test.otf", "font", "127.0.0.1", false
- ]);
- }
-
- if (compareGeckoVersion("1.9.1") >= 0)
- {
- tests.push([
- '<script>var xmlDoc = document.implementation.createDocument(null, "root", null);xmlDoc.async = false;xmlDoc.load("test.xml")</' + 'script>',
- "http://127.0.0.1:1234/test.xml", "xmlhttprequest", "127.0.0.1", false
- ]);
- }
-
- if (compareGeckoVersion("2.0a") >= 0)
- {
- // Remote XUL has been disabled in Gecko 2.0, don't test it any more
- tests = tests.filter(function(test)
- {
- let body = test[0];
- if (body instanceof XML)
- body = body.toXMLString();
- return (body.indexOf("there.is.only.xul") < 0);
- });
- }
-
- // TODO: '<' + 'script>new Worker("test.js");<' + '/script>'
- // Web workers need special treatment, no way to ensure that web worker loads before the page is loaded.
-
- let currentTest = 0;
- let currentStage = 0;
-
- let requestNotifier = null;
- let policyHits = [];
- let serverHit = false;
- let stageDescriptions = {
- 1: "running without filters",
- 2: "running with filter %S",
- 3: "running with filter %S and site exception",
- 4: "running with filter %S and exception not applicable to sites",
- 5: "running with filter %S and exception only applicable for frame",
- };
-
- function onPolicyHit(wnd, node, item, scanComplete)
- {
- if (wnd != top ||
- item.location == "http://127.0.0.1:1234/test" ||
- item.location == "http://127.0.0.1:1234/redirect.gif" ||
- item.location == "http://127.0.0.1:1234/redirect2.gif")
- {
- return;
- }
-
- if (policyHits.length > 0)
- {
- // Ignore duplicate policy calls (possible due to prefetching)
- let [prevWnd, prevNode, prevItem] = policyHits[policyHits.length - 1];
- if (prevWnd == wnd && prevItem.location == item.location && prevItem.type == item.type && prevItem.docDomain == item.docDomain)
- policyHits.pop();
- }
- policyHits.push([wnd, node, item]);
- }
-
- function runNextTest()
- {
- currentStage++;
- if (currentStage > 5)
- {
- currentTest++;
- currentStage = 1;
- }
- if (currentTest >= tests.length)
- {
- SimpleTest.finish();
- return;
- }
-
- let [body, expectedURL, expectedType, expectedDomain, expectedThirdParty] = tests[currentTest];
-
- defaultMatcher.clear();
-
- if (currentStage > 1)
- defaultMatcher.add(Filter.fromText(expectedURL));
- if (currentStage == 3)
- defaultMatcher.add(Filter.fromText("@@|chrome://mochikit/$document"));
- if (currentStage == 4)
- defaultMatcher.add(Filter.fromText("@@|chrome://mochikit/$~document"));
- if (currentStage == 5)
- defaultMatcher.add(Filter.fromText("@@|http://127.0.0.1:1234/test|"));
-
- serverHit = false;
- server.registerPathHandler("/redirect.gif", function(metadata, response)
- {
- response.setStatusLine("1.1", "302", "Moved Temporarily");
- response.setHeader("Location", "http://127.0.0.1:1234/test.gif");
- });
- server.registerPathHandler("/redirect2.gif", function(metadata, response)
- {
- response.setStatusLine("1.1", "302", "Moved Temporarily");
- response.setHeader("Location", "http://127.0.0.1:1234/redirect.gif");
- });
- server.registerPathHandler(expectedURL.replace(/http:\/\/[^\/]+/, ""), function(metadata, response)
- {
- serverHit = true;
- response.setStatusLine("1.1", "404", "Not Found");
- });
-
- policyHits = [];
- document.getElementById("frame").contentWindow.location.href = "http://127.0.0.1:1234/test";
- }
-
- function doRunTest()
- {
- if (currentStage == 0)
- return;
-
- let [body, expectedURL, expectedType, expectedDomain, expectedThirdParty] = tests[currentTest];
-
- let expectedStatus = "allowed";
- if (currentStage == 3)
- is(policyHits.length, 0, "Number of policy hits for " + body + " with site whitelisting");
- else
- {
- let stageDescription = stageDescriptions[currentStage];
- if (stageDescription.indexOf("%S") >= 0)
- stageDescription = stageDescription.replace("%S", expectedURL);
-
- is(policyHits.length, 1, "Number of policy hits for " + body + " (" + stageDescription + ")");
- if (policyHits.length == 1)
- {
- let [wnd, node, item] = policyHits[0];
-
- is(item.location, expectedURL, "Checking request URL");
-
- expectedStatus = (currentStage == 1 ? "allowed" : "blocked");
- let actualStatus = (item.filter ? "blocked" : "allowed");
-
- is(actualStatus, expectedStatus, "Checking whether request was blocked (" + stageDescription + ")");
- is (item.typeDescr.toLowerCase(), expectedType, "Checking whether request type was determined correctly (" + stageDescription + ")");
- is (item.thirdParty, expectedThirdParty, "Checking whether third-party flag was set correctly (" + stageDescription + ")");
- is (item.docDomain, expectedDomain, "Checking whether document domain was set correctly (" + stageDescription + ")");
- }
- }
-
- server.registerPathHandler(expectedURL.replace(/http:\/\/[^\/]+/, ""), null);
- is(serverHit, expectedStatus == "allowed", "Checking whether request was received by server");
-
- runNextTest();
- }
-
- function start()
- {
- requestNotifier = new RequestNotifier(null, onPolicyHit);
-
- window.addEventListener("unload", stop, false);
- server.start(1234);
-
- server.registerPathHandler("/test", function(metadata, response)
- {
- let body = tests[currentTest][0];
- if (body instanceof XML)
- body = body.toXMLString();
- response.setStatusLine("1.1", "200", "OK");
-
- let contentType = "text/html";
- if (body.indexOf("there.is.only.xul") >= 0)
- contentType = "application/vnd.mozilla.xul+xml";
- else if (body.indexOf("2000/svg") >= 0)
- contentType = "image/svg+xml";
- response.setHeader("Content-Type", contentType);
-
- response.bodyOutputStream.write(body, body.length);
- });
-
- runNextTest();
- }
-
- function stop()
- {
- requestNotifier.shutdown();
-
- server.stop();
- }
-
- let server = new nsHttpServer();
- SimpleTest.waitForExplicitFinish();
- addLoadEvent(start);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_regexpFilters_matching.html b/mochitest/tests/test_regexpFilters_matching.html
deleted file mode 100644
index c3be406..0000000
--- a/mochitest/tests/test_regexpFilters_matching.html
+++ /dev/null
@@ -1,288 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Regexp filter matching tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <meta http-equiv="Content-Type" value="text/html; charset=utf-8"/>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- function testMatch(text, location, contentType, docDomain, thirdParty, expected)
- {
- function testMatch_internal(text, location, contentType, docDomain, thirdParty, expected)
- {
- let filter = Filter.fromText(text);
- let result = filter.matches(location, contentType, docDomain, thirdParty);
- is(!!result, expected, '"' + text + '".matches(' + location + ", " + contentType + ", " + docDomain + ", " + (thirdParty ? "third-party" : "first-party") + ")");
- }
- testMatch_internal(text, location, contentType, docDomain, thirdParty, expected);
- if (!/^@@/.test(text))
- testMatch_internal("@@" + text, location, contentType, docDomain, thirdParty, expected);
- }
-
- testMatch("abc", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc", "http://ABC/adf", "IMAGE", null, false, true);
- testMatch("abc", "http://abd/adf", "IMAGE", null, false, false);
- testMatch("|abc", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("|http://abc", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc|", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc/adf|", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("||example.com/foo", "http://example.com/foo/bar", "IMAGE", null, false, true);
- testMatch("||com/foo", "http://example.com/foo/bar", "IMAGE", null, false, true);
- testMatch("||mple.com/foo", "http://example.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||/example.com/foo", "http://example.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||example.com/foo/bar|", "http://example.com/foo/bar", "IMAGE", null, false, true);
- testMatch("||example.com/foo", "http://foo.com/http://example.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||example.com/foo|", "http://example.com/foo/bar", "IMAGE", null, false, false);
- testMatch("abc^d", "http://abc/def", "IMAGE", null, false, true);
- testMatch("abc^e", "http://abc/def", "IMAGE", null, false, false);
- testMatch("def^", "http://abc/def", "IMAGE", null, false, true);
- testMatch("http://abc/d^f", "http://abc/def", "IMAGE", null, false, false);
- testMatch("http://abc/def^", "http://abc/def", "IMAGE", null, false, true);
- testMatch("^foo=bar^", "http://abc/?foo=bar", "IMAGE", null, false, true);
- testMatch("^foo=bar^", "http://abc/?a=b&foo=bar", "IMAGE", null, false, true);
- testMatch("^foo=bar^", "http://abc/?foo=bar&a=b", "IMAGE", null, false, true);
- testMatch("^foo=bar^", "http://abc/?notfoo=bar", "IMAGE", null, false, false);
- testMatch("^foo=bar^", "http://abc/?foo=barnot", "IMAGE", null, false, false);
- testMatch("^foo=bar^", "http://abc/?foo=bar%2Enot", "IMAGE", null, false, false);
- testMatch("||example.com^", "http://example.com/foo/bar", "IMAGE", null, false, true);
- testMatch("||example.com^", "http://example.company.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||example.com^", "http://example.com:1234/foo/bar", "IMAGE", null, false, true);
- testMatch("||example.com^", "http://example.com.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||example.com^", "http://example.com-company.com/foo/bar", "IMAGE", null, false, false);
- testMatch("||example.com^foo", "http://example.com/foo/bar", "IMAGE", null, false, true);
- testMatch("||пÑимеÑ.ÑÑ^", "http://пÑимеÑ.ÑÑ/foo/bar", "IMAGE", null, false, true);
- testMatch("||пÑимеÑ.ÑÑ^", "http://пÑимеÑ.ÑÑководиÑелÑ.ÑÑ/foo/bar", "IMAGE", null, false, false);
- testMatch("||пÑимеÑ.ÑÑ^", "http://пÑимеÑ.ÑÑ:1234/foo/bar", "IMAGE", null, false, true);
- testMatch("||пÑимеÑ.ÑÑ^", "http://пÑимеÑ.ÑÑ.ÑÑ/foo/bar", "IMAGE", null, false, false);
- testMatch("||пÑимеÑ.ÑÑ^", "http://пÑимеÑ.ÑÑ-ководиÑелÑ.ÑÑ/foo/bar", "IMAGE", null, false, false);
- testMatch("||пÑимеÑ.ÑÑ^foo", "http://пÑимеÑ.ÑÑ/foo/bar", "IMAGE", null, false, true);
- testMatch("abc*d", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc*d", "http://abcd/af", "IMAGE", null, false, true);
- testMatch("abc*d", "http://abc/d/af", "IMAGE", null, false, true);
- testMatch("abc*d", "http://dabc/af", "IMAGE", null, false, false);
- testMatch("*abc", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc*", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("|*abc", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc*|", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc***d", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$image", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$other", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$other", "http://abc/adf", "OTHER", null, false, true);
- testMatch("abc$~other", "http://abc/adf", "OTHER", null, false, false);
- testMatch("abc$script", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$script", "http://abc/adf", "SCRIPT", null, false, true);
- testMatch("abc$~script", "http://abc/adf", "SCRIPT", null, false, false);
- testMatch("abc$stylesheet", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$stylesheet", "http://abc/adf", "STYLESHEET", null, false, true);
- testMatch("abc$~stylesheet", "http://abc/adf", "STYLESHEET", null, false, false);
- testMatch("abc$object", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$object", "http://abc/adf", "OBJECT", null, false, true);
- testMatch("abc$~object", "http://abc/adf", "OBJECT", null, false, false);
- testMatch("abc$document", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$document", "http://abc/adf", "DOCUMENT", null, false, true);
- testMatch("abc$~document", "http://abc/adf", "DOCUMENT", null, false, false);
- testMatch("abc$subdocument", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$subdocument", "http://abc/adf", "SUBDOCUMENT", null, false, true);
- testMatch("abc$~subdocument", "http://abc/adf", "SUBDOCUMENT", null, false, false);
- testMatch("abc$background", "http://abc/adf", "OBJECT", null, false, false);
- testMatch("abc$background", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~background", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$xbl", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$xbl", "http://abc/adf", "XBL", null, false, true);
- testMatch("abc$~xbl", "http://abc/adf", "XBL", null, false, false);
- testMatch("abc$ping", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$ping", "http://abc/adf", "PING", null, false, true);
- testMatch("abc$~ping", "http://abc/adf", "PING", null, false, false);
- testMatch("abc$xmlhttprequest", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$xmlhttprequest", "http://abc/adf", "XMLHTTPREQUEST", null, false, true);
- testMatch("abc$~xmlhttprequest", "http://abc/adf", "XMLHTTPREQUEST", null, false, false);
- testMatch("abc$object-subrequest", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$object-subrequest", "http://abc/adf", "OBJECT_SUBREQUEST", null, false, true);
- testMatch("abc$~object-subrequest", "http://abc/adf", "OBJECT_SUBREQUEST", null, false, false);
- testMatch("abc$dtd", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$dtd", "http://abc/adf", "DTD", null, false, true);
- testMatch("abc$~dtd", "http://abc/adf", "DTD", null, false, false);
-
- if (compareGeckoVersion("1.9.1b3") >= 0)
- {
- testMatch("abc$media", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$media", "http://abc/adf", "MEDIA", null, false, true);
- testMatch("abc$~media", "http://abc/adf", "MEDIA", null, false, false);
-
- testMatch("abc$font", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$font", "http://abc/adf", "FONT", null, false, true);
- testMatch("abc$~font", "http://abc/adf", "FONT", null, false, false);
- }
-
- testMatch("abc$image,script", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~image", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$~script", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~image,~script", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$~script,~image", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$~document,~script,~other", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~image,image", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$image,~image", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$~image,image", "http://abc/adf", "SCRIPT", null, false, true);
- testMatch("abc$image,~image", "http://abc/adf", "SCRIPT", null, false, false);
- testMatch("abc$match-case", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$match-case", "http://ABC/adf", "IMAGE", null, false, false);
- testMatch("abc$~match-case", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~match-case", "http://ABC/adf", "IMAGE", null, false, true);
- testMatch("abc$match-case,image", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$match-case,script", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$match-case,image", "http://ABC/adf", "IMAGE", null, false, false);
- testMatch("abc$match-case,script", "http://ABC/adf", "IMAGE", null, false, false);
- testMatch("abc$third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$third-party", "http://abc/adf", "IMAGE", null, true, true);
- testMatch("abd$third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abd$third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("abc$image,third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$image,third-party", "http://abc/adf", "IMAGE", null, true, true);
- testMatch("abc$~image,third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abc$~image,third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("abc$~third-party", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$~third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("abd$~third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("abd$~third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("abc$image,~third-party", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("abc$image,~third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("abc$~image,~third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/abc/", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/abc/", "http://abcd/adf", "IMAGE", null, false, true);
- testMatch("*/abc/", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("*/abc/", "http://abcd/adf", "IMAGE", null, false, false);
- testMatch("/a\\wc/", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/a\\wc/", "http://a1c/adf", "IMAGE", null, false, true);
- testMatch("/a\\wc/", "http://a_c/adf", "IMAGE", null, false, true);
- testMatch("/a\\wc/", "http://a%c/adf", "IMAGE", null, false, false);
- testMatch("/abc/$image", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/abc/$image", "http://aBc/adf", "IMAGE", null, false, true);
- testMatch("/abc/$script", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/abc/$~image", "http://abcd/adf", "IMAGE", null, false, false);
- testMatch("/ab{2}c/$image", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/ab{2}c/$script", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/ab{2}c/$~image", "http://abcd/adf", "IMAGE", null, false, false);
- testMatch("/abc/$third-party", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/abc/$third-party", "http://abc/adf", "IMAGE", null, true, true);
- testMatch("/abc/$~third-party", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/abc/$~third-party", "http://abc/adf", "IMAGE", null, true, false);
- testMatch("/abc/$match-case", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/abc/$match-case", "http://aBc/adf", "IMAGE", null, true, false);
- testMatch("/ab{2}c/$match-case", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/ab{2}c/$match-case", "http://aBc/adf", "IMAGE", null, true, false);
- testMatch("/abc/$~match-case", "http://abc/adf", "IMAGE", null, false, true);
- testMatch("/abc/$~match-case", "http://aBc/adf", "IMAGE", null, true, true);
- testMatch("/ab{2}c/$~match-case", "http://abc/adf", "IMAGE", null, false, false);
- testMatch("/ab{2}c/$~match-case", "http://aBc/adf", "IMAGE", null, true, false);
-
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "foo.com.", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "www.foo.com", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "www.foo.com.", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "Foo.com", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, true);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", "www.baz.com", true, false);
- testMatch("abc$domain=foo.com", "http://abc/def", "IMAGE", null, true, false);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "foo.com.", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "www.foo.com", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "www.foo.com.", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "Foo.com", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, true);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", "www.baz.com", true, false);
- testMatch("abc$domain=foo.com|bar.com", "http://abc/def", "IMAGE", null, true, false);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "foo.com.", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "www.foo.com", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "www.foo.com.", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "Foo.com", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, true);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", "www.baz.com", true, false);
- testMatch("abc$domain=bar.com|foo.com", "http://abc/def", "IMAGE", null, true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "foo.com.", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "www.foo.com", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "www.foo.com.", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "Foo.com", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, false);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", "www.baz.com", true, true);
- testMatch("abc$domain=~foo.com", "http://abc/def", "IMAGE", null, true, true);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "foo.com.", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "www.foo.com", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "www.foo.com.", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "Foo.com", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, false);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", "www.baz.com", true, true);
- testMatch("abc$domain=~foo.com|~bar.com", "http://abc/def", "IMAGE", null, true, true);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "foo.com.", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "www.foo.com", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "www.foo.com.", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "Foo.com", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "abc.def.foo.com", true, false);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", "www.baz.com", true, true);
- testMatch("abc$domain=~bar.com|~foo.com", "http://abc/def", "IMAGE", null, true, true);
- testMatch("abc$domain=foo.com|~bar.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=foo.com|~bar.com", "http://abc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$domain=foo.com|~bar.com", "http://abc/def", "IMAGE", "baz.com", true, false);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "www.foo.com", true, true);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "bar.foo.com", true, false);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "www.bar.foo.com", true, false);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "baz.com", true, false);
- testMatch("abc$domain=foo.com|~bar.foo.com", "http://abc/def", "IMAGE", "www.baz.com", true, false);
- testMatch("abc$domain=com|~foo.com", "http://abc/def", "IMAGE", "bar.com", true, true);
- testMatch("abc$domain=com|~foo.com", "http://abc/def", "IMAGE", "bar.net", true, false);
- testMatch("abc$domain=com|~foo.com", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=com|~foo.com", "http://abc/def", "IMAGE", "foo.net", true, false);
- testMatch("abc$domain=com|~foo.com", "http://abc/def", "IMAGE", "com", true, true);
- testMatch("abc$domain=foo.com", "http://ccc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=foo.com", "http://ccc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$image,domain=foo.com", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$image,domain=foo.com", "http://abc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$image,domain=foo.com", "http://abc/def", "OBJECT", "foo.com", true, false);
- testMatch("abc$image,domain=foo.com", "http://abc/def", "OBJECT", "bar.com", true, false);
- testMatch("abc$~image,domain=foo.com", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$~image,domain=foo.com", "http://abc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$~image,domain=foo.com", "http://abc/def", "OBJECT", "foo.com", true, true);
- testMatch("abc$~image,domain=foo.com", "http://abc/def", "OBJECT", "bar.com", true, false);
- testMatch("abc$domain=foo.com,image", "http://abc/def", "IMAGE", "foo.com", true, true);
- testMatch("abc$domain=foo.com,image", "http://abc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$domain=foo.com,image", "http://abc/def", "OBJECT", "foo.com", true, false);
- testMatch("abc$domain=foo.com,image", "http://abc/def", "OBJECT", "bar.com", true, false);
- testMatch("abc$domain=foo.com,~image", "http://abc/def", "IMAGE", "foo.com", true, false);
- testMatch("abc$domain=foo.com,~image", "http://abc/def", "IMAGE", "bar.com", true, false);
- testMatch("abc$domain=foo.com,~image", "http://abc/def", "OBJECT", "foo.com", true, true);
- testMatch("abc$domain=foo.com,~image", "http://abc/def", "OBJECT", "bar.com", true, false);
-
- testMatch("@@test", "http://test/", "DOCUMENT", null, false, false);
- testMatch("@@http://test*", "http://test/", "DOCUMENT", null, false, true);
- testMatch("@@ftp://test*", "ftp://test/", "DOCUMENT", null, false, true);
- testMatch("@@test$document", "http://test/", "DOCUMENT", null, false, true);
- testMatch("@@test$document,image", "http://test/", "DOCUMENT", null, false, true);
- testMatch("@@test$~image", "http://test/", "DOCUMENT", null, false, false);
- testMatch("@@test$~image,document", "http://test/", "DOCUMENT", null, false, true);
- testMatch("@@test$document,~image", "http://test/", "DOCUMENT", null, false, true);
- testMatch("@@test$document,domain=foo.com", "http://test/", "DOCUMENT", "foo.com", false, true);
- testMatch("@@test$document,domain=foo.com", "http://test/", "DOCUMENT", "bar.com", false, false);
- testMatch("@@test$document,domain=~foo.com", "http://test/", "DOCUMENT", "foo.com", false, false);
- testMatch("@@test$document,domain=~foo.com", "http://test/", "DOCUMENT", "bar.com", false, true);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_requestList.html b/mochitest/tests/test_requestList.html
deleted file mode 100644
index 51ba7e5..0000000
--- a/mochitest/tests/test_requestList.html
+++ /dev/null
@@ -1,251 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Tests for request data</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="../httpd.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
- <iframe id="frame" onload="doRunTest()"></iframe>
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- Cu.import(baseURL.spec + "RequestNotifier.jsm");
- Cu.import(baseURL.spec + "ContentPolicy.jsm");
- prepareFilterComponents();
- preparePrefs();
-
- let currentTest = -1;
-
- let tests = [
- ["about:blank", runBlankChecks],
- ["http://127.0.0.1:1234/test1", runTest1Checks],
- ["http://127.0.0.1:1234/test2", runTest2Checks]
- ];
-
- function start()
- {
- window.addEventListener("unload", stop, false);
- server.start(1234);
-
- server.registerPathHandler("/test1", function(metadata, response)
- {
- response.setStatusLine("1.1", "200", "OK");
- response.setHeader("Content-Type", "text/html");
-
- let body = "<img id='image' src='test.png'>";
- response.bodyOutputStream.write(body, body.length);
- });
-
- server.registerPathHandler("/test2", function(metadata, response)
- {
- response.setStatusLine("1.1", "200", "OK");
- response.setHeader("Content-Type", "text/html");
-
- let body = "<script id='script' src='test.js'><" + "/script>";
- response.bodyOutputStream.write(body, body.length);
- });
-
- runNextTest();
- }
-
- function runNextTest()
- {
- currentTest++;
- if (currentTest >= tests.length)
- {
- SimpleTest.finish();
- return;
- }
-
- let [url, testFunction] = tests[currentTest];
- $("frame").src = url;
- }
-
- function doRunTest()
- {
- if (currentTest < 0)
- return;
-
- let [url, testFunction] = tests[currentTest];
-
- let wndScanComplete = false;
- let wndData = [];
- let requestNotifier1 = new RequestNotifier(window, function(wnd, node, entry, scanComplete)
- {
- if (scanComplete)
- {
- wndScanComplete = true;
- requestNotifier1.shutdown();
- }
- else if (entry)
- wndData.push({wnd: wnd, node: node, entry: entry});
-
- checkScanDone();
- });
-
- let frameScanComplete = false;
- let frameData = [];
- let requestNotifier2 = new RequestNotifier(window.frames[0], function(wnd, node, entry, scanComplete)
- {
- if (scanComplete)
- {
- frameScanComplete = true;
- requestNotifier2.shutdown();
- }
- else if (entry)
- frameData.push({wnd: wnd, node: node, entry: entry});
-
- checkScanDone();
- });
-
- function checkScanDone()
- {
- if (wndScanComplete && frameScanComplete)
- {
- // Fold duplicate entries
- for each (let list in [wndData, frameData])
- {
- let keys = {};
- for (let i = 0; i < list.length; i++)
- {
- let key = " " + list[i].entry.location + " " + list[i].entry.type + " " + list[i].entry.docDomain;
- if (key in keys)
- {
- list.splice(keys[key], 1);
- i--;
- }
- keys[key] = i;
- }
- }
-
- testFunction(wndData, frameData);
- runNextTest();
- }
- }
- }
-
- function runBlankChecks(wndData, frameData)
- {
- is(wndData.length, 0, "No data associated with the window that didn't load anything");
- is(frameData.length, 0, "No data associated with an empty frame");
- is(RequestNotifier.getDataForNode($("frame"), true), null, "No data associated with an empty frame node");
- }
-
- function runTest1Checks(wndData, frameData)
- {
- ok(RequestNotifier.getDataForNode($("frame"), true), "Frame node has data associated with it");
- let frameNodeData = RequestNotifier.getDataForNode($("frame"), true)[1];
-
- ok(RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("image"), true), "Image node inside the frame has data associated with it");
- let imageNodeData = RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("image"), true)[1];
-
- is(wndData.length, 2, "Number of entries in the window data");
- if (wndData.length > 0)
- {
- is(wndData[0].node, $("frame"), "First entry in the window data should be the frame");
- is(wndData[0].entry.toSource(), frameNodeData.toSource(), "Data received for the frame should be identical to the result of getDataForNode");
- }
- if (wndData.length > 1)
- {
- is(wndData[1].node, $("frame").contentDocument.getElementById("image"), "Second entry in the window data should be the image");
- is(wndData[1].entry.toSource(), imageNodeData.toSource(), "Data received for the image should be identical to the result of getDataForNode");
- }
-
- is(frameData.length, 1, "Number of entries in the frame data");
- if (frameData.length > 0)
- {
- is(frameData[0].node, $("frame").contentDocument.getElementById("image"), "Only entry in the frame data should be the image");
- is(frameData[0].entry.toSource(), imageNodeData.toSource(), "Data received for the image should be identical to the result of getDataForNode");
- }
-
- is(frameNodeData.type, Policy.type.SUBDOCUMENT, "Frame node data: type property");
- is(frameNodeData.typeDescr, "SUBDOCUMENT", "Frame node data: typeDescr property");
- is(frameNodeData.docDomain, "mochikit", "Frame node data: docDomain property");
- is(frameNodeData.thirdParty, true, "Frame node data: thirdParty property");
- is(frameNodeData.location, "http://127.0.0.1:1234/test1", "Frame node data: location property");
- is(frameNodeData.filter, null, "Frame node data: filter property");
-
- is(imageNodeData.type, Policy.type.IMAGE, "Image node data: type property");
- is(imageNodeData.typeDescr, "IMAGE", "Image node data: typeDescr property");
- is(imageNodeData.docDomain, "127.0.0.1", "Image node data: docDomain property");
- is(imageNodeData.thirdParty, false, "Image node data: thirdParty property");
- is(imageNodeData.location, "http://127.0.0.1:1234/test.png", "Image node data: location property");
- is(imageNodeData.filter, null, "Image node data: filter property");
-
- top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).garbageCollect();
- ok(RequestNotifier.getDataForNode($("frame"), true), "Frame node still has data associated with it after garbage collection");
- ok(RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("image"), true), "Image node still has data associated with it after garbage collection");
- }
-
- function runTest2Checks(wndData, frameData)
- {
- ok(RequestNotifier.getDataForNode($("frame"), true), "Frame node has data associated with it");
- let frameNodeData = RequestNotifier.getDataForNode($("frame"), true)[1];
-
- ok(RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("script"), true), "Script node inside the frame has data associated with it");
- let scriptNodeData = RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("script"), true)[1];
-
- is(wndData.length, 3, "Number of entries in the window data");
- if (wndData.length > 0)
- {
- is(wndData[0].node, $("frame"), "Second entry in the window data should be the frame (new location)");
- is(wndData[0].entry.toSource(), frameNodeData.toSource(), "Data received for the frame should be identical to the result of getDataForNode");
- }
- if (wndData.length > 1)
- {
- is(wndData[1].node, $("frame"), "First entry in the window data should be the frame (old location)");
- isnot(wndData[1].entry.toSource(), frameNodeData.toSource(), "Data received for the frame should not be identical to the result of getDataForNode");
- }
- if (wndData.length > 2)
- {
- is(wndData[2].node, $("frame").contentDocument.getElementById("script"), "Third entry in the window data should be the script");
- is(wndData[2].entry.toSource(), scriptNodeData.toSource(), "Data received for the script should be identical to the result of getDataForNode");
- }
-
- is(frameData.length, 1, "Number of entries in the frame data");
- if (frameData.length > 0)
- {
- is(frameData[0].node, $("frame").contentDocument.getElementById("script"), "Only entry in the frame data should be the script");
- is(frameData[0].entry.toSource(), scriptNodeData.toSource(), "Data received for the script should be identical to the result of getDataForNode");
- }
-
- is(frameNodeData.type, Policy.type.SUBDOCUMENT, "Frame node data: type property");
- is(frameNodeData.typeDescr, "SUBDOCUMENT", "Frame node data: typeDescr property");
- is(frameNodeData.docDomain, "mochikit", "Frame node data: docDomain property");
- is(frameNodeData.thirdParty, true, "Frame node data: thirdParty property");
- is(frameNodeData.location, "http://127.0.0.1:1234/test2", "Frame node data: location property");
- is(frameNodeData.filter, null, "Frame node data: filter property");
-
- is(scriptNodeData.type, Policy.type.SCRIPT, "Script node data: type property");
- is(scriptNodeData.typeDescr, "SCRIPT", "Script node data: typeDescr property");
- is(scriptNodeData.docDomain, "127.0.0.1", "Script node data: docDomain property");
- is(scriptNodeData.thirdParty, false, "Script node data: thirdParty property");
- is(scriptNodeData.location, "http://127.0.0.1:1234/test.js", "Script node data: location property");
- is(scriptNodeData.filter, null, "Script node data: filter property");
-
- top.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils).garbageCollect();
- ok(RequestNotifier.getDataForNode($("frame"), true), "Frame node still has data associated with it after garbage collection");
- ok(RequestNotifier.getDataForNode($("frame").contentDocument.getElementById("script"), true), "Script node still has data associated with it after garbage collection");
- }
-
- function stop()
- {
- server.stop();
- }
-
- let server = new nsHttpServer();
- SimpleTest.waitForExplicitFinish();
- addLoadEvent(start);
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_subscriptionClasses.html b/mochitest/tests/test_subscriptionClasses.html
deleted file mode 100644
index d2d58df..0000000
--- a/mochitest/tests/test_subscriptionClasses.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Subscription classes tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents();
-
- function compareSubscription(url, expected, postInit)
- {
- expected.push("[Subscription]")
- let subscription;
- if (/^external (.+)/.test(url))
- subscription = new ExternalSubscription(RegExp.$1);
- else
- subscription = Subscription.fromURL(url);
- if (postInit)
- postInit(subscription)
- let result = [];
- subscription.serialize(result);
- is(result.sort().join("\n"), expected.sort().join("\n"), url);
-
- let map = {__proto__: null};
- for each (let line in result.slice(1))
- {
- if (/(.*?)=(.*)/.test(line))
- map[RegExp.$1] = RegExp.$2;
- }
- let subscription2 = Subscription.fromObject(map);
- is(subscription.toString(), subscription2.toString(), url + " deserialization");
- }
-
- is(typeof Subscription, "function", "typeof Subscription");
- is(typeof SpecialSubscription, "function", "typeof SpecialSubscription");
- is(typeof RegularSubscription, "function", "typeof RegularSubscription");
- is(typeof ExternalSubscription, "function", "typeof ExternalSubscription");
- is(typeof DownloadableSubscription, "function", "typeof DownloadableSubscription");
-
- compareSubscription("~il~", ["url=~il~"]);
- compareSubscription("http://test/default", ["url=http://test/default", "title=http://test/default"]);
- compareSubscription("http://test/default_titled", ["url=http://test/default_titled", "title=test"], function(subscription)
- {
- subscription.title = "test";
- });
- compareSubscription("http://test/non_default", ["url=http://test/non_default", "title=test", "nextURL=http://test2/", "autoDownload=false",
- "disabled=true", "lastSuccess=8", "lastDownload=12", "lastCheck=16", "softExpiration=18", "expires=20", "downloadStatus=foo", "lastModified=bar",
- "errors=3", "requiredVersion=0.6", "alternativeLocations=http://foo/;q=0.5,http://bar/;q=2"], function(subscription)
- {
- subscription.title = "test";
- subscription.nextURL = "http://test2/";
- subscription.autoDownload = false;
- subscription.disabled = true;
- subscription.lastSuccess = 8;
- subscription.lastDownload = 12;
- subscription.lastCheck = 16;
- subscription.softExpiration = 18;
- subscription.expires = 20;
- subscription.downloadStatus = "foo";
- subscription.lastModified = "bar";
- subscription.errors = 3;
- subscription.requiredVersion = "0.6";
- subscription.alternativeLocations = "http://foo/;q=0.5,http://bar/;q=2";
- });
- compareSubscription("~fl~", ["url=~fl~", "disabled=true"], function(subscription)
- {
- subscription.disabled = true;
- });
- compareSubscription("external foo_default", ["url=foo_default", "title=foo_default", "external=true"]);
- compareSubscription("external foo_non_default", ["url=foo_non_default", "title=foo", "disabled=true", "external=true", "lastDownload=12"], function(subscription)
- {
- subscription.title = "foo";
- subscription.disabled = true;
- subscription.lastDownload = 12;
- });
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/test_synchronizer.html b/mochitest/tests/test_synchronizer.html
deleted file mode 100644
index 51c9684..0000000
--- a/mochitest/tests/test_synchronizer.html
+++ /dev/null
@@ -1,855 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>Subscription synchronizer tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="../httpd.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
-
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- Cu.import(baseURL.spec + "Utils.jsm");
- let SynchronizerGlobal = Cu.import(baseURL.spec + "Synchronizer.jsm");
- prepareFilterComponents();
- preparePrefs();
-
- let currentTime = 20000 * 24 * 60 * 60 * 1000;
- let startTime = 0;
- let scheduledTasks = [];
-
- let oldRandom = SynchronizerGlobal.Math.random;
- let oldNow = SynchronizerGlobal.Date.now;
- SynchronizerGlobal.Date.now = function()
- {
- return currentTime;
- };
- Date.now = SynchronizerGlobal.Date.now; // Override for httpd Date header
-
- let outstandingRequests = 0;
-
- function runScheduledTasks(maxHours, noExecution)
- {
- startTime = currentTime;
- let maxTime = maxHours * 60 * 60 * 1000;
- let endTime = currentTime + maxTime;
- while (true)
- {
- let nextTask = null;
- for each (let task in scheduledTasks)
- {
- if (!nextTask || nextTask.nextExecution > task.nextExecution)
- nextTask = task;
- }
- if (!nextTask || nextTask.nextExecution > endTime)
- break;
-
- currentTime = nextTask.nextExecution;
- if (!noExecution)
- nextTask.handler();
-
- // Let all asynchronous actions finish
- let thread = Utils.threadManager.currentThread;
- let loopStartTime = Date.now();
-
- while (outstandingRequests > 0 || thread.hasPendingEvents())
- {
- thread.processNextEvent(true);
-
- if (Date.now() - loopStartTime > 5000)
- {
- ok(false, "Synchronizer stuck downloading subscriptions");
- return;
- }
- }
-
- if (nextTask.type == Components.interfaces.nsITimer.TYPE_ONE_SHOT)
- scheduledTasks = scheduledTasks.filter(function(task) task != nextTask);
- else
- nextTask.nextExecution = currentTime + nextTask.delay;
- }
-
- currentTime = endTime;
- }
-
- Prefs.synchronizationinterval = 24;
- Prefs.subscriptions_fallbackerrors = 7;
- Prefs.subscriptions_fallbackurl = "http://127.0.0.1:1234/fallback?%SUBSCRIPTION%&%URL%&%CHANNELSTATUS%&%RESPONSESTATUS%";
-
- {
- let timer = {__proto__: SynchronizerGlobal.timer};
- let callback = timer.callback;
- timer.handler = function() { callback.notify(timer); };
- timer.nextExecution = currentTime + timer.delay;
-
- scheduledTasks.push(timer);
-
- SynchronizerGlobal.timer.cancel();
- SynchronizerGlobal.timer = timer;
- }
-
- // Track requests initiated by Synchronizer object by hooking its
- // XMLHttpRequest constructor.
- let oldXMLHttp = SynchronizerGlobal.XMLHttpRequest;
- SynchronizerGlobal.XMLHttpRequest = function()
- {
- let inner = new oldXMLHttp();
-
- return {
- __proto__: inner,
- send: function()
- {
- outstandingRequests++;
- function finished()
- {
- outstandingRequests--;
- }
- inner.addEventListener("load", finished, false);
- inner.addEventListener("error", finished, false);
-
- inner.send.apply(inner, arguments);
- }
- }
- }
-
- // Make sure to restore everything when this document unloads
- window.addEventListener("unload", function()
- {
- SynchronizerGlobal.Date.now = oldNow;
- SynchronizerGlobal.XMLHttpRequest = oldXMLHttp;
- SynchronizerGlobal.Math.random = oldRandom;
- Synchronizer.startup();
- }, false);
-
- let server = new nsHttpServer();
-
- let requests = [];
-
- let subscription1 = Subscription.fromURL("http://127.0.0.1:1234/subscription1");
- let subscription2 = Subscription.fromURL("http://127.0.0.1:1234/subscription2");
- let subscription3 = Subscription.fromURL("http://127.0.0.1:1234/subscription3");
-
- let subscriptionStatus = [200, "OK"];
- let subscriptionExtraHeaders = null;
- let subscriptionBody = "[Adblock]\nfoo\nbar";
- function getSubscription(metadata, response)
- {
- requests.push((currentTime - startTime) / 3600000 + ": " + metadata.method + " " + metadata.path);
-
- response.setStatusLine("1.1", subscriptionStatus[0], subscriptionStatus[1]);
- // Return wrong MIME type, client should be able to handle it
- response.setHeader("Content-Type", "text/xml");
-
- if (subscriptionExtraHeaders)
- {
- for each (let [header, value] in subscriptionExtraHeaders(metadata))
- response.setHeader(header, value);
- }
-
- response.bodyOutputStream.write(subscriptionBody, subscriptionBody.length);
- }
-
- let redirectPermanent = null;
- let redirectURL = null;
- let redirectExtraHeaders = null;
- function redirectHandler(metadata, response)
- {
- response.setStatusLine("1.1", redirectPermanent ? 301 : 302, redirectPermanent ? "Moved Permanently" : "Moved Temporarily");
- response.setHeader("Location", redirectURL);
-
- if (redirectExtraHeaders)
- {
- for each (let [header, value] in redirectExtraHeaders(metadata))
- response.setHeader(header, value);
- }
- }
- function commentRedirectHandler(metadata, response)
- {
- getSubscription(metadata, response);
-
- if (redirectExtraHeaders)
- {
- for each (let [header, value] in redirectExtraHeaders(metadata))
- response.setHeader(header, value);
- }
-
- var comment = "\n! Redirect: " + redirectURL;
- response.bodyOutputStream.write(comment, comment.length);
- }
-
- var fallbackResult = "";
- function fallbackHandler(metadata, response)
- {
- requests.push((currentTime - startTime) / 3600000 + ": " + metadata.method + " " + metadata.path + " " + decodeURIComponent(metadata.queryString));
-
- response.setStatusLine("1.1", 200, "OK");
- // Return wrong MIME type, client should be able to handle it
- response.setHeader("Content-Type", "application/x-foo-bar");
-
- if (subscriptionExtraHeaders)
- {
- for each (let [header, value] in subscriptionExtraHeaders())
- response.setHeader(header, value);
- }
-
- response.bodyOutputStream.write(fallbackResult, fallbackResult.length);
- }
-
- function compareRequests(test, expected)
- {
- is(requests.join("\n"), expected.join("\n"), test);
- requests = [];
- }
-
- function compareFilters(test, expected, expectedStatus, expectedVersion)
- {
- let result = subscription1.filters.map(function(filter) filter.text).join("\n");
- is(result, expected, test);
- is(subscription1.downloadStatus, expectedStatus, "Subscription status after previous test");
- is(subscription1.requiredVersion, expectedVersion, "Required version after previous test");
- requests = [];
- }
-
- function resetSubscriptions()
- {
- FilterStorage.removeSubscription(subscription1);
- FilterStorage.removeSubscription(subscription2);
- FilterStorage.removeSubscription(subscription3);
- FilterStorage.addSubscription(subscription1);
- FilterStorage.addSubscription(subscription2);
- subscription2.autoDownload = false;
- }
-
- function compareSubscriptions(test, expectedSubscriptions)
- {
- let result = FilterStorage.subscriptions.map(function(subscription) subscription.url).join("\n");
- let expected = expectedSubscriptions.map(function(subscription) subscription.url).join("\n");
- is(result, expected, test);
- requests = [];
- resetSubscriptions();
- }
-
- function runTests()
- {
- is(typeof Synchronizer, "object", "typeof Synchronizer");
-
- server.registerPathHandler("/subscription1", getSubscription);
- server.registerPathHandler("/subscription2", getSubscription);
- server.registerPathHandler("/subscription3", getSubscription);
- server.registerPathHandler("/fallback", fallbackHandler);
-
- FilterStorage.addSubscription(subscription1);
-
- subscription2.autoDownload = false;
- FilterStorage.addSubscription(subscription2);
-
- //
- // General subscription download testing
- //
-
- SynchronizerGlobal.Math.random = function() 0.5;
-
- runScheduledTasks(50);
- compareRequests("Downloads of one subscription (50 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1"
- ]);
-
- subscription2.autoDownload = true;
- runScheduledTasks(70);
- compareRequests("Downloads with second subscription switched on (48 hours)", [
- "0.1: GET /subscription2",
- "22.1: GET /subscription1",
- "24.1: GET /subscription2",
- "46.1: GET /subscription1",
- "48.1: GET /subscription2"
- ]);
- subscription2.autoDownload = false;
-
- //
- // Header variations testing
- //
-
- subscriptionBody = "[Adblock]\nfoo\n!bar\n\n\n@@bas\n#bam";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription", "foo\n!bar\n@@bas\n#bam", "synchronize_ok", null);
-
- subscriptionBody = "[Adblock Plus]\nfoo2\n!bar2\n@@bas2\n#bam2";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription with [Adblock Plus] header", "foo2\n!bar2\n@@bas2\n#bam2", "synchronize_ok", null);
-
- subscriptionBody = "[Adblock Plus 0.0.1]\nfoo3\n!bar3\n@@bas3\n#bam3";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription with [Adblock Plus 0.0.1] header", "foo3\n!bar3\n@@bas3\n#bam3", "synchronize_ok", "0.0.1");
-
- subscriptionBody = "(something)[Adblock]\nfoo4\n!bar4\n@@bas4\n#bam4";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription with (something)[Adblock] header", "foo4\n!bar4\n@@bas4\n#bam4", "synchronize_ok", null);
-
- subscriptionBody = "[Foo]\nthis should not be accepted";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription with [Foo] header", "foo4\n!bar4\n@@bas4\n#bam4", "synchronize_invalid_data", null);
-
- subscriptionBody = "[Adblock Plus 99.9]\nsome_new_syntax";
- runScheduledTasks(24);
- compareFilters("Filters of downloaded subscription with [Adblock Plus 99.9] header", "some_new_syntax", "synchronize_ok", "99.9");
-
- //
- // Expiration testing
- //
-
- // Expiration time too small - should be changed into 24 hours
- subscriptionBody = "[Adblock]\n! Expires after 1 hour\nfoo";
- runScheduledTasks(36);
- compareRequests("Expiration comment with less than default update interval (25 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1"
- ]);
-
- subscriptionBody = "[Adblock]\n! Expires after 26 hours\nfoo";
- runScheduledTasks(48);
- compareRequests("Downloads with 'Expires after 26 hours' comment (48 hours)", [
- "12.1: GET /subscription1",
- "38.1: GET /subscription1"
- ]);
-
- subscriptionBody = "[Adblock]\n! Expires: 2 days\nfoo";
- runScheduledTasks(70);
- compareRequests("Downloads with 'Expires: 2 days' comment (70 hours)", [
- "16.1: GET /subscription1",
- "64.1: GET /subscription1"
- ]);
-
- subscriptionBody = "[Adblock]\nfoo";
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 30 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(80);
- compareRequests("Downloads with 'Expires: +30h' HTTP header (80 hours)", [
- "42.1: GET /subscription1",
- "72.1: GET /subscription1"
- ]);
-
- // Expiration time too small, should be changed into 24 hours
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 20 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(48);
- compareRequests("Expiration header with less than default update interval (48 hours)", [
- "22.1: GET /subscription1",
- "46.1: GET /subscription1"
- ]);
-
- // Expiration time too large, should be changed into 14 days
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 504 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(692);
- compareRequests("Expiration header more than two weeks in future (692 hours)", [
- "22.1: GET /subscription1",
- "358.1: GET /subscription1"
- ]);
-
- // Soft expiration interval should be randomized - random returning 0 means factor 0.8
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 35 * 60 * 60 * 1000).toGMTString()]];
- SynchronizerGlobal.Math.random = function() 0;
- runScheduledTasks(56);
- compareRequests("Soft expiration should be multiplied with 0.8 if Math.random() returns 0 (48 hours)", [
- "2.1: GET /subscription1",
- "30.1: GET /subscription1"
- ]);
-
- // Soft expiration interval should be randomized - random returning 0.9 means factor 1.16
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 35 * 60 * 60 * 1000).toGMTString()]];
- SynchronizerGlobal.Math.random = function() 0.9;
- runScheduledTasks(82);
- compareRequests("Soft expiration should be multiplied with 1.16 if Math.random() returns 0.9 (82 hours)", [
- "2.1: GET /subscription1",
- "43.1: GET /subscription1"
- ]);
- SynchronizerGlobal.Math.random = function() 0.5;
-
- // Soft expiration interval should increase if the user is off-line more than a day
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 35 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(4);
- requests = [];
- runScheduledTasks(26, true); // Skip the next 26 hours
- runScheduledTasks(104);
- compareRequests("Soft expiration interval should increase if user is offline for more than a day (104 hours)", [
- "34.1: GET /subscription1",
- "69.1: GET /subscription1"
- ]);
-
- // Soft expiration interval should *not* increase if the user was off-line for a short period
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 35 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(2);
- requests = [];
- runScheduledTasks(10, true); // Skip the next 10 hours
- runScheduledTasks(93);
- compareRequests("Soft expiration interval should not increase if user is offline for a few hours (93 hours)", [
- "23.1: GET /subscription1",
- "58.1: GET /subscription1"
- ]);
-
- // Hard expiration interval: if the user was away too long the download should happen immediately
- subscriptionExtraHeaders = function() [["Expires", new Date(currentTime + 35 * 60 * 60 * 1000).toGMTString()]];
- runScheduledTasks(4);
- requests = [];
- runScheduledTasks(80, true); // Skip the next 80 hours, more than twice the expiration time
- runScheduledTasks(70);
- compareRequests("Download should happen immediately if hard expiration interval is hit (70 hours)", [
- "0.1: GET /subscription1",
- "35.1: GET /subscription1"
- ]);
-
- subscriptionExtraHeaders = null;
-
- //
- // Redirect testing
- //
-
- server.registerPathHandler("/subscription1", commentRedirectHandler);
-
- redirectURL = subscription2.url;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after comment redirect to /subscription2", [subscription2]);
-
- redirectURL = subscription2.url.replace("subscription2", "invalid_url");
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after redirect to /invalid_url", [subscription1, subscription2]);
-
- server.registerPathHandler("/subscription1", redirectHandler);
-
- redirectURL = subscription2.url;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription2", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription2", [subscription2]);
-
- redirectURL = subscription3.url;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription3", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription3", [subscription2, subscription3]);
-
- redirectURL = subscription2.url.replace("subscription2", "invalid_url");
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /invalid_url", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /invalid_url", [subscription1, subscription2]);
-
- server.registerPathHandler("/subscription3", redirectHandler);
-
- server.registerPathHandler("/subscription1", function redirectHandler(metadata, response)
- {
- response.setStatusLine("1.1", 302, "Moved Temporarily");
- response.setHeader("Location", subscription3.url);
- });
-
- redirectURL = subscription2.url;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription3 followed by temporary redirect to /subscription2", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription3 followed by permanent redirect to /subscription2", [subscription1, subscription2]);
-
- redirectURL = subscription2.url.replace("subscription2", "invalid_url");;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription3 followed by temporary redirect to /invalid_url", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after temporary redirect to /subscription3 followed by permanent redirect to /invalid_url", [subscription1, subscription2]);
-
- server.registerPathHandler("/subscription1", function redirectHandler(metadata, response)
- {
- response.setStatusLine("1.1", 301, "Moved Permanently");
- response.setHeader("Location", subscription3.url);
- });
-
- redirectURL = subscription2.url;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription3 followed by temporary redirect to /subscription2", [subscription2, subscription3]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription3 followed by permanent redirect to /subscription2", [subscription2]);
-
- redirectURL = subscription2.url.replace("subscription2", "invalid_url");;
- redirectPermanent = false;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription3 followed by temporary redirect to /invalid_url", [subscription1, subscription2]);
-
- redirectPermanent = true;
- runScheduledTasks(48);
- compareSubscriptions("Subscriptions after permanent redirect to /subscription3 followed by permanent redirect to /invalid_url", [subscription1, subscription2]);
-
- server.registerPathHandler("/subscription1", getSubscription);
- server.registerPathHandler("/subscription3", getSubscription);
-
- //
- // Behavior on errors
- //
-
- runScheduledTasks(48); // reset error counters
- requests = [];
-
- subscriptionStatus = [404, "Not Found"];
- runScheduledTasks(72);
- compareRequests("Requests after 404 error (72 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1"
- ]);
-
- subscriptionStatus = [200, "OK"];
- subscriptionBody = "Not a valid subscription";
- runScheduledTasks(72);
- compareRequests("Requests for invalid subscription (72 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1"
- ]);
-
- server.registerPathHandler("/subscription1", function(metadata, response)
- {
- getSubscription(metadata, response);
- response.setStatusLine("1.1", "404", "Not found");
- });
- subscriptionBody = "[Adblock]\nfoo\nbar";
- runScheduledTasks(216);
- compareRequests("Requests with fallback calls (216 hours)", [
- "0.1: GET /subscription1",
- "0.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "144.1: GET /subscription1",
- "168.1: GET /subscription1",
- "168.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "192.1: GET /subscription1"
- ]);
-
- fallbackResult = "410 Gone";
- runScheduledTasks(216);
- compareRequests("Requests with fallback returning 410 Gone (216 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "120.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- ]);
- subscription1.autoDownload = true;
-
- fallbackResult = "301 " + subscription2.url;
- runScheduledTasks(216);
- compareRequests("Requests with fallback redirecting to /subscription2 (216 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "144.1: GET /subscription1",
- "144.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "168.1: GET /subscription2",
- "192.1: GET /subscription2"
- ]);
- compareSubscriptions("Subscriptions after test above", [subscription2]);
- subscription1.autoDownload = true;
-
- fallbackResult = "301 " + subscription3.url;
- runScheduledTasks(216);
- compareRequests("Requests with fallback redirecting to /subscription3 (216 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "144.1: GET /subscription1",
- "144.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "168.1: GET /subscription3",
- "192.1: GET /subscription3"
- ]);
- compareSubscriptions("Subscriptions after test above", [subscription2, subscription3]);
- subscription1.autoDownload = true;
-
- fallbackResult = "301 " + subscription2.url.replace("subscription2", "invalid_url");
- runScheduledTasks(384);
- compareRequests("Requests with fallback redirecting to /invalid_url (384 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "144.1: GET /subscription1",
- "144.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "192.1: GET /subscription1",
- "216.1: GET /subscription1",
- "240.1: GET /subscription1",
- "264.1: GET /subscription1",
- "288.1: GET /subscription1",
- "312.1: GET /subscription1",
- "312.1: GET /fallback " + subscription1.url + "&" + subscription1.url + "&0&404",
- "360.1: GET /subscription1"
- ]);
- compareSubscriptions("Subscriptions after test above", [subscription1, subscription2]);
- subscription1.autoDownload = true;
-
- server.registerPathHandler("/subscription1", getSubscription);
- fallbackResult = "";
-
- //
- // Checksum verification
- //
-
- subscriptionBody = "[Adblock]\n! Checksum: e/JCmqXny6Fn24b7JHsq/A\nfoo\nbar\n";
-
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "Subscription download with correct checksum succeeded");
-
- subscriptionBody = subscriptionBody.replace(/Checksum: /, "$&wrong");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_checksum_mismatch", "Subscription download with wrong checksum failed");
- subscriptionBody = subscriptionBody.replace(/wrong/, "");
-
- subscriptionBody = subscriptionBody.replace(/\n/g, "\n\n");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "Empty lines are ignored for checksum validation");
- subscriptionBody = subscriptionBody.replace(/\n\n/g, "\n");
-
- subscriptionBody = subscriptionBody.replace(/\n/g, "\n \n");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_checksum_mismatch", "Lines with spaces are not ignored for checksum validation");
- subscriptionBody = subscriptionBody.replace(/\n \n/g, "\n");
-
- subscriptionBody = subscriptionBody.replace(/(Checksum[^\r\n]*)/, "extra1 $& extra2");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "Extra content in checksum line is ignored");
- subscriptionBody = subscriptionBody.replace(/extra1 /, "").replace(/ extra2/, "");
-
- subscriptionBody = subscriptionBody.replace(/\n/g, "\r\n");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "LF symbols are ignored for checksum validation");
- subscriptionBody = subscriptionBody.replace(/\r\n/g, "\n");
-
- subscriptionBody = subscriptionBody.replace(/\n/g, "\r");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "CR symbols are relevant for checksum validation");
- subscriptionBody = subscriptionBody.replace(/\r/g, "\n");
-
- subscriptionBody = subscriptionBody.replace(/(Checksum[^\r\n]*)/, "$&extra");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_checksum_mismatch", "Extra symbols in the checksum are interpreted as part of the checksum");
- subscriptionBody = subscriptionBody.replace(/extra/, "");
-
- subscriptionBody = subscriptionBody.replace(/(Checksum[^\r\n]*)/, "$&===");
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "= symbols after checksum are ignored");
- subscriptionBody = subscriptionBody.replace(/===/, "");
-
- requests = [];
- subscriptionBody = subscriptionBody.replace(/Checksum: /, "$&wrong");
- runScheduledTasks(216);
- compareRequests("Requests with checksum failures shouldn't trigger fallback URL (27 hours)", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- "72.1: GET /subscription1",
- "96.1: GET /subscription1",
- "120.1: GET /subscription1",
- "144.1: GET /subscription1",
- "168.1: GET /subscription1",
- "192.1: GET /subscription1",
- ]);
- subscriptionBody = subscriptionBody.replace(/wrong/, "");
-
- //
- // Alternative download locations
- //
-
- subscriptionBody = "[Adblock]\nfoo\nbar\n";
- let alternativeLocations = subscription2.url + ";q=0.5," + subscription3.url + ";q=2";
- subscriptionExtraHeaders = function() [["X-Alternative-Locations", alternativeLocations]];
-
- runScheduledTasks(48);
- is(subscription1.downloadStatus, "synchronize_ok", "= symbols after checksum are ignored");
- is(subscription1.alternativeLocations, alternativeLocations, "Alternative locations header processed on download");
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0;
- runScheduledTasks(72);
- compareRequests("Base URL should be chosen if Math.random() returns 0", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- ]);
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0.28;
- runScheduledTasks(72);
- compareRequests("Base URL should be chosen if Math.random() returns 0.28", [
- "0.1: GET /subscription1",
- "24.1: GET /subscription1",
- "48.1: GET /subscription1",
- ]);
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0.29;
- runScheduledTasks(72);
- compareRequests("First alternative should be chosen if Math.random() returns 0.29", [
- "0.1: GET /subscription2",
- "24.1: GET /subscription2",
- "48.1: GET /subscription2",
- ]);
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0.42;
- runScheduledTasks(72);
- compareRequests("First alternative should be chosen if Math.random() returns 0.42", [
- "0.1: GET /subscription2",
- "24.1: GET /subscription2",
- "48.1: GET /subscription2",
- ]);
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0.43;
- runScheduledTasks(72);
- compareRequests("Second alternative should be chosen if Math.random() returns 0.43", [
- "0.1: GET /subscription3",
- "24.1: GET /subscription3",
- "48.1: GET /subscription3",
- ]);
-
- requests = [];
- SynchronizerGlobal.Math.random = function() 0.99; // Note: side-effect is increasing soft expiration interval to 29 hours
- runScheduledTasks(87);
- compareRequests("Second alternative should be chosen if Math.random() returns 0.99", [
- "0.1: GET /subscription3",
- "29.1: GET /subscription3",
- "58.1: GET /subscription3",
- ]);
-
- subscriptionStatus = [404, "Not Found"];
- SynchronizerGlobal.Math.random = function() 0;
- runScheduledTasks(24);
- is(subscription1.alternativeLocations, alternativeLocations, "Alternative locations shouldn't be reset on download failure for base URL");
-
- SynchronizerGlobal.Math.random = function() 0.99;
- runScheduledTasks(24);
- is(subscription1.alternativeLocations, null, "Alternative locations should be reset on download failure for alternative URL");
-
- requests = [];
- subscriptionStatus = [200, "OK"];
- SynchronizerGlobal.Math.random = function() 0.99; // Note: side-effect is increasing soft expiration interval to 29 hours
- runScheduledTasks(87);
- compareRequests("Alternative locations should be used again once the base URL returns a new list", [
- "0.1: GET /subscription1",
- "29.1: GET /subscription3",
- "58.1: GET /subscription3",
- ]);
-
- server.registerPathHandler("/subscription1", commentRedirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0;
- runScheduledTasks(24);
- is(subscription1.nextURL, subscription2.url, "Redirect comment accepted from base URL");
- subscription1.nextURL = null;
- server.registerPathHandler("/subscription1", getSubscription);
-
- server.registerPathHandler("/subscription3", commentRedirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0.99;
- runScheduledTasks(29);
- is(subscription1.nextURL, null, "Redirect comment ignored from alternative URL");
-
- server.registerPathHandler("/subscription3", redirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0.99;
- redirectPermanent = true;
- runScheduledTasks(29);
- compareSubscriptions("Subscriptions after redirect from alternative URL", [subscription1, subscription2]);
- server.registerPathHandler("/subscription3", getSubscription);
-
- server.registerPathHandler("/subscription1", redirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0;
- redirectPermanent = true;
- runScheduledTasks(24);
- compareSubscriptions("Subscriptions after redirect from base URL", [subscription2]);
- server.registerPathHandler("/subscription1", getSubscription);
-
- subscriptionExtraHeaders = redirectExtraHeaders =
- function(metadata) [["X-Alternative-Locations", metadata.path == "/subscription1" ? subscription2.url : subscription1.url]];
- server.registerPathHandler("/subscription1", redirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0;
- redirectPermanent = false;
- runScheduledTasks(24);
- is(subscription1.alternativeLocations, subscription2.url, "Alternative locations not taken over from redirect target on temporary redirect");
- resetSubscriptions();
- server.registerPathHandler("/subscription1", getSubscription);
-
- server.registerPathHandler("/subscription1", redirectHandler);
- redirectURL = subscription2.url;
- SynchronizerGlobal.Math.random = function() 0;
- redirectPermanent = true;
- runScheduledTasks(24);
- is(subscription1.alternativeLocations, subscription1.url, "Alternative locations taken over from redirect target on permanent redirect");
- resetSubscriptions();
- server.registerPathHandler("/subscription1", getSubscription);
-
- subscriptionExtraHeaders = null;
- redirectExtraHeaders = null;
-
- // @TODO: If-Modified-Since
- }
-
- SimpleTest.waitForExplicitFinish();
- addLoadEvent(function()
- {
- try
- {
- server.start(1234);
- runTests();
- }
- catch (e)
- {
- ok(false, e);
- throw e;
- }
- finally
- {
- server.stop();
- SimpleTest.finish();
- }
- });
- </script>
- </pre>
-</body>
-</html>
diff --git a/mochitest/tests/ui/common.js b/mochitest/tests/ui/common.js
deleted file mode 100644
index 9e00199..0000000
--- a/mochitest/tests/ui/common.js
+++ /dev/null
@@ -1,19 +0,0 @@
-var geckoVersion = Components.classes["@mozilla.org/xre/app-info;1"]
- .getService(Components.interfaces.nsIXULAppInfo)
- .platformVersion;
-function compareGeckoVersion(version)
-{
- return Components.classes["@mozilla.org/xpcom/version-comparator;1"]
- .createInstance(Components.interfaces.nsIVersionComparator)
- .compare(geckoVersion, version);
-}
-
-function getBrowserWindow()
-{
- return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIWebNavigation)
- .QueryInterface(Components.interfaces.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
- .getInterface(Components.interfaces.nsIDOMWindow);
-}
diff --git a/mochitest/tests/ui/test_icon_status.html b/mochitest/tests/ui/test_icon_status.html
deleted file mode 100644
index f6652a3..0000000
--- a/mochitest/tests/ui/test_icon_status.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <title>ABP icon status tests</title>
-
- <link rel="stylesheet" type="text/css" href="/content/tests/SimpleTest/test.css" />
-
- <script type="text/javascript" src="/content/MochiKit/MochiKit.js"></script>
- <script type="text/javascript" src="/content/tests/SimpleTest/SimpleTest.js"></script>
-
- <script type="application/x-javascript;version=1.7" src="../common.js"></script>
- <script type="application/x-javascript;version=1.7" src="common.js"></script>
-</head>
-<body>
- <p id="display"></p>
- <div id="content" style="display: none">
-
- </div>
-
- <pre id="test">
- <script type="application/x-javascript;version=1.7">
- prepareFilterComponents(true);
- preparePrefs();
-
- FilterStorage.addSubscription(Subscription.fromURL("~fl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~wl~"));
- FilterStorage.addSubscription(Subscription.fromURL("~il~"));
- FilterStorage.addSubscription(Subscription.fromURL("~eh~"));
-
- let tests = [
- createToolbarTest(testEnabled),
- createToolbarTest(testDisabled),
- createToolbarTest(testWhitelisted),
- createStatusbarTest(testEnabled),
- createStatusbarTest(testDisabled),
- createStatusbarTest(testWhitelisted)
- ];
- let currentTest = -1;
-
- function testEnabled(element)
- {
- if (!Prefs.enabled)
- Prefs.enabled = true;
- setTimeout(function()
- {
- is(element.getAttribute("abpstate"), "active", "Checking icon state when Adblock Plus is enabled");
- runNextTest();
- }, 0);
- }
-
- function testDisabled(element)
- {
- if (Prefs.enabled)
- Prefs.enabled = false;
- setTimeout(function()
- {
- is(element.getAttribute("abpstate"), "disabled", "Checking icon state when Adblock Plus is disabled");
- runNextTest();
- }, 0);
- }
-
- function testWhitelisted(element)
- {
- FilterStorage.addFilter(Filter.fromText("@@|chrome://mochikit/$document"));
- if (!Prefs.enabled)
- Prefs.enabled = true;
- setTimeout(function()
- {
- is(element.getAttribute("abpstate"), "whitelisted", "Checking icon state with site whitelisting");
- FilterStorage.removeFilter(Filter.fromText("@@|chrome://mochikit/$document"));
- runNextTest();
- }, 0);
- }
-
- function createToolbarTest(testFunction)
- {
- return function()
- {
- let icon = getBrowserWindow().document.getElementById("abp-toolbarbutton");
- if (icon)
- testFunction(icon, function() { Prefs.showintoolbar = oldShowInToolbar; });
- else
- ok(false, "Toolbar icon not found in browser");
- };
- }
-
- function createStatusbarTest(testFunction)
- {
- return function()
- {
- let icon = getBrowserWindow().document.getElementById("abp-status");
- if (icon)
- testFunction(icon);
- else
- ok(false, "Status bar icon not found in browser");
- };
- }
-
- function runNextTest()
- {
- currentTest++;
- if (currentTest >= tests.length)
- SimpleTest.finish();
- else
- tests[currentTest]();
- }
-
- function start()
- {
- Prefs.enabled = true;
- Prefs.showintoolbar = false;
- Prefs.showinstatusbar = false;
- setTimeout(function()
- {
- Prefs.showintoolbar = true;
- Prefs.showinstatusbar = true;
-
- setTimeout(runNextTest, 0);
- }, 0);
- }
-
- SimpleTest.waitForExplicitFinish();
- addLoadEvent(start);
- </script>
- </pre>
-</body>
-</html>
diff --git a/modules/AppIntegration.jsm b/modules/AppIntegration.jsm
index 9247dba..df36b09 100644
--- a/modules/AppIntegration.jsm
+++ b/modules/AppIntegration.jsm
@@ -37,7 +37,7 @@ const Cu = Components.utils;
let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
Cu.import(baseURL.spec + "Utils.jsm");
Cu.import(baseURL.spec + "Prefs.jsm");
Cu.import(baseURL.spec + "ContentPolicy.jsm");
@@ -48,7 +48,7 @@ Cu.import(baseURL.spec + "RequestNotifier.jsm");
Cu.import(baseURL.spec + "Sync.jsm");
if (Utils.isFennec)
- Cu.import(baseURL.spec + "AppIntegrationFennec.jsm");
+ Cu.import(baseURL.spec + "AppIntegrationFennec.jsm");
/**
* Wrappers for tracked application windows.
@@ -71,16 +71,16 @@ let hotkeys = null;
*/
function init()
{
- // Process preferences
- reloadPrefs();
-
- // Listen for pref and filters changes
- Prefs.addListener(function(name)
- {
- if (name == "enabled" || name == "showintoolbar" || name == "showinstatusbar" || name == "defaulttoolbaraction" || name == "defaultstatusbaraction")
- reloadPrefs();
- });
- FilterStorage.addObserver(reloadPrefs);
+ // Process preferences
+ reloadPrefs();
+
+ // Listen for pref and filters changes
+ Prefs.addListener(function(name)
+ {
+ if (name == "enabled" || name == "showintoolbar" || name == "showinstatusbar" || name == "defaulttoolbaraction" || name == "defaultstatusbaraction")
+ reloadPrefs();
+ });
+ FilterStorage.addObserver(reloadPrefs);
}
/**
@@ -89,107 +89,107 @@ function init()
*/
var AppIntegration =
{
- /**
- * Adds an application window to the tracked list.
- */
- addWindow: function(/**Window*/ window)
- {
- let hooks = window.document.getElementById("abp-hooks");
- if (!hooks)
- return;
-
- TimeLine.enter("Entered AppIntegration.addWindow()")
- // Execute first-run actions
- if (!("lastVersion" in Prefs))
- {
- Prefs.lastVersion = Prefs.currentVersion;
-
- // Show subscriptions dialog if the user doesn't have any subscriptions yet
- if (Prefs.currentVersion != Utils.addonVersion)
- {
- Prefs.currentVersion = Utils.addonVersion;
-
- if ("nsISessionStore" in Ci)
- {
- // Have to wait for session to be restored
- let observer =
- {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
- observe: function(subject, topic, data)
- {
- observerService.removeObserver(observer, "sessionstore-windows-restored");
- timer.cancel();
- timer = null;
- showSubscriptions();
- }
- };
-
- let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- observerService.addObserver(observer, "sessionstore-windows-restored", false);
-
- // Just in case, don't wait more than a second
- let timer = Cc['@mozilla.org/timer;1'].createInstance(Ci.nsITimer);
- timer.init(observer, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
- }
- else
- Utils.runAsync(showSubscriptions);
- }
- }
- TimeLine.log("App-wide first-run actions done")
-
- let wrapper = new WindowWrapper(window, hooks);
- wrappers.push(wrapper);
- TimeLine.leave("AppIntegration.addWindow() done")
- },
-
- /**
- * Retrieves the wrapper object corresponding to a particular application window.
- */
- getWrapperForWindow: function(/**Window*/ wnd) /**WindowWrapper*/
- {
- for each (let wrapper in wrappers)
- if (wrapper.window == wnd)
- return wrapper;
-
- return null;
- },
-
- /**
- * Toggles the value of a boolean preference.
- */
- togglePref: function(/**String*/ pref)
- {
- Prefs[pref] = !Prefs[pref];
- },
-
- /**
- * Toggles the pref for the Adblock Plus sync engine.
- */
- toggleSync: function()
- {
- let syncEngine = Sync.getEngine();
- syncEngine.enabled = !syncEngine.enabled;
- },
-
- /**
- * If the given filter is already in user's list, removes it from the list. Otherwise adds it.
- */
- toggleFilter: function(/**Filter*/ filter)
- {
- if (filter.subscriptions.length)
- {
- if (filter.disabled || filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription)))
- {
- filter.disabled = !filter.disabled;
- FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter]);
- }
- else
- FilterStorage.removeFilter(filter);
- }
- else
- FilterStorage.addFilter(filter);
- FilterStorage.saveToDisk();
- }
+ /**
+ * Adds an application window to the tracked list.
+ */
+ addWindow: function(/**Window*/ window)
+ {
+ let hooks = window.document.getElementById("abp-hooks");
+ if (!hooks)
+ return;
+
+
+ // Execute first-run actions
+ if (!("lastVersion" in Prefs))
+ {
+ Prefs.lastVersion = Prefs.currentVersion;
+
+ // Show subscriptions dialog if the user doesn't have any subscriptions yet
+ if (Prefs.currentVersion != Utils.addonVersion)
+ {
+ Prefs.currentVersion = Utils.addonVersion;
+
+ if ("nsISessionStore" in Ci)
+ {
+ // Have to wait for session to be restored
+ let observer =
+ {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
+ observe: function(subject, topic, data)
+ {
+ observerService.removeObserver(observer, "sessionstore-windows-restored");
+ timer.cancel();
+ timer = null;
+ showSubscriptions();
+ }
+ };
+
+ let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ observerService.addObserver(observer, "sessionstore-windows-restored", false);
+
+ // Just in case, don't wait more than a second
+ let timer = Cc['@mozilla.org/timer;1'].createInstance(Ci.nsITimer);
+ timer.init(observer, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
+ }
+ else
+ Utils.runAsync(showSubscriptions);
+ }
+ }
+
+
+ let wrapper = new WindowWrapper(window, hooks);
+ wrappers.push(wrapper);
+
+ },
+
+ /**
+ * Retrieves the wrapper object corresponding to a particular application window.
+ */
+ getWrapperForWindow: function(/**Window*/ wnd) /**WindowWrapper*/
+ {
+ for each (let wrapper in wrappers)
+ if (wrapper.window == wnd)
+ return wrapper;
+
+ return null;
+ },
+
+ /**
+ * Toggles the value of a boolean preference.
+ */
+ togglePref: function(/**String*/ pref)
+ {
+ Prefs[pref] = !Prefs[pref];
+ },
+
+ /**
+ * Toggles the pref for the Adblock Plus sync engine.
+ */
+ toggleSync: function()
+ {
+ let syncEngine = Sync.getEngine();
+ syncEngine.enabled = !syncEngine.enabled;
+ },
+
+ /**
+ * If the given filter is already in user's list, removes it from the list. Otherwise adds it.
+ */
+ toggleFilter: function(/**Filter*/ filter)
+ {
+ if (filter.subscriptions.length)
+ {
+ if (filter.disabled || filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription)))
+ {
+ filter.disabled = !filter.disabled;
+ FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter]);
+ }
+ else
+ FilterStorage.removeFilter(filter);
+ }
+ else
+ FilterStorage.addFilter(filter);
+ FilterStorage.saveToDisk();
+ }
};
/**
@@ -197,11 +197,11 @@ var AppIntegration =
*/
function removeWindow()
{
- let wnd = this;
+ let wnd = this;
- for (let i = 0; i < wrappers.length; i++)
- if (wrappers[i].window == wnd)
- wrappers.splice(i--, 1);
+ for (let i = 0; i < wrappers.length; i++)
+ if (wrappers[i].window == wnd)
+ wrappers.splice(i--, 1);
}
/**
@@ -210,1110 +210,1110 @@ function removeWindow()
*/
function WindowWrapper(window, hooks)
{
- TimeLine.enter("Entered WindowWrapper constructor")
- this.window = window;
-
- this.initializeHooks(hooks);
- TimeLine.log("Hooks element initialized")
-
- if (!Utils.isFennec)
- {
- this.fixupMenus();
- TimeLine.log("Context menu copying done")
-
- this.configureKeys();
- TimeLine.log("Shortcut keys configured")
-
- this.initContextMenu();
- TimeLine.log("Context menu initialized")
-
- let browser = this.getBrowser();
- if (browser && browser.currentURI)
- {
- this.updateState();
- }
- else
- {
- // Update state asynchronously, the Thunderbird window won't be initialized yet for non-default window layouts
- Utils.runAsync(this.updateState, this);
- }
- TimeLine.log("Icon state updated")
-
- // Some people actually switch off browser.frames.enabled and are surprised
- // that things stop working...
- window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .allowSubframes = true;
- }
- this.registerEventListeners(!Utils.isFennec);
- TimeLine.log("Added event listeners")
-
- this.executeFirstRunActions();
- TimeLine.log("Window-specific first-run actions done")
-
- // Custom initialization for Fennec
- if (Utils.isFennec)
- AppIntegrationFennec.initWindow(this);
-
- TimeLine.leave("WindowWrapper constructor done")
+
+ this.window = window;
+
+ this.initializeHooks(hooks);
+
+
+ if (!Utils.isFennec)
+ {
+ this.fixupMenus();
+
+
+ this.configureKeys();
+
+
+ this.initContextMenu();
+
+
+ let browser = this.getBrowser();
+ if (browser && browser.currentURI)
+ {
+ this.updateState();
+ }
+ else
+ {
+ // Update state asynchronously, the Thunderbird window won't be initialized yet for non-default window layouts
+ Utils.runAsync(this.updateState, this);
+ }
+
+
+ // Some people actually switch off browser.frames.enabled and are surprised
+ // that things stop working...
+ window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .allowSubframes = true;
+ }
+ this.registerEventListeners(!Utils.isFennec);
+
+
+ this.executeFirstRunActions();
+
+
+ // Custom initialization for Fennec
+ if (Utils.isFennec)
+ AppIntegrationFennec.initWindow(this);
+
+
}
WindowWrapper.prototype =
{
- /**
- * Application window this object belongs to.
- * @type Window
- */
- window: null,
-
- /**
- * Current state as displayed for this window.
- * @type String
- */
- state: null,
-
- /**
- * Methods that can be defined at attributes of the hooks element.
- * @type Array of String
- */
- customMethods: ["getBrowser", "addTab", "getContextMenu", "getToolbox", "getDefaultToolbar", "toolbarInsertBefore", "unhideToolbar"],
-
- /**
- * Progress listener used to watch for location changes, if any.
- * @type nsIProgressListener
- */
- progressListener: null,
-
- /**
- * Filter corresponding with "disable on site" menu item (set in fillPopup()).
- * @type Filter
- */
- siteWhitelist: null,
- /**
- * Filter corresponding with "disable on site" menu item (set in fillPopup()).
- * @type Filter
- */
- pageWhitelist: null,
-
- /**
- * Data associated with the node currently under mouse pointer (set in updateContextMenu()).
- * @type RequestEntry
- */
- nodeData: null,
- /**
- * The document node that nodeData belongs to.
- */
- currentNode: null,
- /**
- * Data associated with the background image currently under mouse pointer (set in updateContextMenu()).
- * @type RequestEntry
- */
- backgroundData: null,
- /**
- * Data associated with the frame currently under mouse pointer (set in updateContextMenu()).
- * @type RequestEntry
- */
- frameData: null,
- /**
- * The frame that frameData belongs to.
- */
- currentFrame: null,
-
- /**
- * Window of the detached list of blockable items (might be null or closed).
- * @type Window
- */
- detachedSidebar: null,
-
- /**
- * Binds a function to the object, ensuring that "this" pointer is always set
- * correctly.
- */
- _bindMethod: function(/**Function*/ method) /**Function*/
- {
- let me = this;
- return function() method.apply(me, arguments);
- },
-
- /**
- * Retrieves an element by its ID.
- */
- E: function(/**String*/ id)
- {
- let doc = this.window.document;
- this.E = function(id) doc.getElementById(id);
- return this.E(id);
- },
-
- /**
- * Initializes abp-hooks element, converts any function attributes to actual
- * functions.
- */
- initializeHooks: function(hooks)
- {
- for each (let hook in this.customMethods)
- {
- let handler = hooks.getAttribute(hook);
- this[hook] = hooks[hook] = (handler ? this._bindMethod(new Function(handler)) : null);
- }
- },
-
- /**
- * Makes a copy of the ABP icon's context menu for the toolbar button.
- */
- fixupMenus: function()
- {
- function fixId(node)
- {
- if (node.nodeType == node.ELEMENT_NODE)
- {
- if (node.hasAttribute("id"))
- node.setAttribute("id", node.getAttribute("id").replace(/abp-status/, "abp-toolbar"));
-
- for (let i = 0, len = node.childNodes.length; i < len; i++)
- fixId(node.childNodes[i]);
- }
- return node;
- }
-
- let menuSource = this.E("abp-status-popup");
- let paletteButton = this.getPaletteButton();
- let toolbarButton = this.E("abp-toolbarbutton");
- if (toolbarButton)
- toolbarButton.appendChild(fixId(menuSource.cloneNode(true)));
- if (paletteButton && paletteButton != toolbarButton)
- paletteButton.appendChild(fixId(menuSource.cloneNode(true)));
- },
-
- /**
- * Attaches event listeners to a window represented by hooks element
- */
- registerEventListeners: function(/**Boolean*/ addProgressListener)
- {
- // Palette button elements aren't reachable by ID, create a lookup table
- let paletteButtonIDs = {};
- let paletteButton = this.getPaletteButton();
- if (paletteButton)
- {
- function getElementIds(element)
- {
- if (element.hasAttribute("id"))
- paletteButtonIDs[element.getAttribute("id")] = element;
-
- for (let child = element.firstChild; child; child = child.nextSibling)
- if (child.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- getElementIds(child);
- }
- getElementIds(paletteButton);
- }
-
- // Go on and register listeners
- this.window.addEventListener("unload", removeWindow, false);
- for each (let [id, event, handler] in this.eventHandlers)
- {
- handler = this._bindMethod(handler);
-
- let element = this.E(id);
- if (element)
- element.addEventListener(event, handler, false);
-
- if (id in paletteButtonIDs)
- paletteButtonIDs[id].addEventListener(event, handler, false);
- }
-
- let browser = this.getBrowser();
- browser.addEventListener("click", this._bindMethod(this.handleLinkClick), true);
-
- // Register progress listener as well if requested
- if (addProgressListener)
- {
- let dummy = function() {};
- this.progressListener =
- {
- onLocationChange: this._bindMethod(this.updateState),
- onProgressChange: dummy,
- onSecurityChange: dummy,
- onStateChange: dummy,
- onStatusChange: dummy,
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference])
- };
- browser.addProgressListener(this.progressListener);
- }
- },
-
- /**
- * Retrieves the current location of the browser (might return null on failure).
- */
- getCurrentLocation: function() /**nsIURI*/
- {
- if ("currentHeaderData" in this.window && "content-base" in this.window.currentHeaderData)
- {
- // Thunderbird blog entry
- return Utils.unwrapURL(this.window.currentHeaderData["content-base"].headerValue);
- }
- else if ("currentHeaderData" in this.window && "from" in this.window.currentHeaderData)
- {
- // Thunderbird mail/newsgroup entry
- try
- {
- let headerParser = Cc["@mozilla.org/messenger/headerparser;1"].getService(Ci.nsIMsgHeaderParser);
- let emailAddress = headerParser.extractHeaderAddressMailboxes(this.window.currentHeaderData.from.headerValue);
- return Utils.makeURI("mailto:" + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, "%20"));
- }
- catch(e)
- {
- return null;
- }
- }
- else
- {
- // Regular browser
- return Utils.unwrapURL(this.getBrowser().currentURI.clone());
- }
- },
-
- /**
- * Executes window-specific first-run actions if necessary.
- */
- executeFirstRunActions: function()
- {
- // Only execute first-run actions for this window once
- if ("doneFirstRunActions " + this.window.location.href in Prefs)
- return;
- Prefs["doneFirstRunActions " + this.window.location.href] = true;
-
- // Check version we previously executed first-run actions for;
- let hooks = this.E("abp-hooks");
- let lastVersion = hooks.getAttribute("currentVersion") || "0.0";
- if (lastVersion != Prefs.currentVersion)
- {
- hooks.setAttribute("currentVersion", Prefs.currentVersion);
- this.window.document.persist("abp-hooks", "currentVersion");
-
- let needInstall = (Utils.versionComparator.compare(lastVersion, "0.0") <= 0);
- if (!needInstall)
- {
- // Before version 1.1 we didn't add toolbar icon in SeaMonkey, do it now
- needInstall = Utils.appID == "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}" &&
- Utils.versionComparator.compare(lastVersion, "1.1") < 0;
- }
-
- // Add ABP icon to toolbar if necessary
- if (needInstall)
- Utils.runAsync(this.installToolbarIcon, this);
- }
- },
-
- /**
- * Finds the toolbar button in the toolbar palette.
- */
- getPaletteButton: function()
- {
- let toolbox = (this.getToolbox ? this.getToolbox() : null);
- if (!toolbox || !("palette" in toolbox) || !toolbox.palette)
- return null;
-
- for (var child = toolbox.palette.firstChild; child; child = child.nextSibling)
- if (child.id == "abp-toolbarbutton")
- return child;
-
- return null;
- },
-
- /**
- * Updates displayed state for an application window.
- */
- updateState: function()
- {
- let state = (Prefs.enabled ? "active" : "disabled");
-
- if (state == "active")
- {
- let location = this.getCurrentLocation();
- if (location && Policy.isWhitelisted(location.spec))
- state = "whitelisted";
- }
- this.state = state;
-
- function updateElement(element)
- {
- if (!element)
- return;
-
- if (element.tagName == "statusbarpanel")
- element.hidden = !Prefs.showinstatusbar;
- else
- {
- element.hidden = !Prefs.showintoolbar;
- if (element.hasAttribute("context") && Prefs.defaulttoolbaraction == 0)
- element.setAttribute("type", "menu");
- else
- element.setAttribute("type", "menu-button");
- }
-
- // HACKHACK: Show status bar icon instead of toolbar icon if the application doesn't have a toolbar icon
- if (element.hidden && element.tagName == "statusbarpanel" && !this.getDefaultToolbar)
- element.hidden = !Prefs.showintoolbar;
-
- element.setAttribute("abpstate", state);
- };
-
- let status = this.E("abp-status");
- if (status)
- {
- updateElement.call(this, status);
- if (Prefs.defaultstatusbaraction == 0)
- status.setAttribute("popup", status.getAttribute("context"));
- else
- status.removeAttribute("popup");
- }
-
- let button = this.E("abp-toolbarbutton");
- if (button)
- updateElement.call(this, button);
-
- updateElement.call(this, this.getPaletteButton());
- },
-
- /**
- * Sets up hotkeys for the window.
- */
- configureKeys: function()
- {
- if (!hotkeys)
- {
- hotkeys = {__proto__: null};
-
- let validModifiers =
- {
- accel: 1,
- shift: 2,
- ctrl: 4,
- control: 4,
- alt: 8,
- meta: 16,
- __proto__: null
- };
-
- try
- {
- let accelKey = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).getIntPref("ui.key.accelKey");
- if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_CONTROL)
- validModifiers.ctrl = validModifiers.control = validModifiers.accel;
- else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_ALT)
- validModifiers.alt = validModifiers.accel;
- else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_META)
- validModifiers.meta = validModifiers.accel;
- }
- catch(e)
- {
- Cu.reportError(e);
- }
-
- // Find which hotkeys are already taken, convert them to canonical form
- let existing = {};
- let keys = this.window.document.getElementsByTagName("key");
- for (let i = 0; i < keys.length; i++)
- {
- let key = keys[i];
- let keyChar = key.getAttribute("key");
- let keyCode = key.getAttribute("keycode");
- if (!keyChar && !keyCode)
- continue;
-
- let modifiers = 0;
- let keyModifiers = key.getAttribute("modifiers");
- if (keyModifiers)
- {
- for each (let modifier in keyModifiers.match(/\w+/g))
- {
- modifier = modifier.toLowerCase();
- if (modifier in validModifiers)
- modifiers |= validModifiers[modifier]
- }
-
- let canonical = modifiers + " " + (keyChar || keyCode).toUpperCase();
- existing[canonical] = true;
- }
- }
-
- // Find available keys for our prefs
- for (let pref in Prefs)
- {
- if (/_key$/.test(pref) && typeof Prefs[pref] == "string")
- {
- try
- {
- let id = RegExp.leftContext;
- let result = this.findAvailableKey(id, Prefs[pref], validModifiers, existing);
- if (result)
- hotkeys[id] = result;
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- }
- }
- }
-
- // Add elements for all configured hotkeys
- for (let id in hotkeys)
- {
- let [keychar, keycode, modifierString] = hotkeys[id];
-
- let element = this.window.document.createElement("key");
- element.setAttribute("id", "abp-key-" + id);
- element.setAttribute("command", "abp-command-" + id);
- if (keychar)
- element.setAttribute("key", keychar);
- else
- element.setAttribute("keycode", keycode);
- element.setAttribute("modifiers", modifierString);
-
- this.E("abp-keyset").appendChild(element);
- }
- },
-
- /**
- * Finds an available hotkey for a value defined in preferences.
- */
- findAvailableKey: function(/**String*/ id, /**String*/ value, /**Object*/ validModifiers, /**Object*/ existing) /**Array*/
- {
- let command = this.E("abp-command-" + id);
- if (!command)
- return;
-
- for each (let variant in value.split(/\s*,\s*/))
- {
- if (!variant)
- continue;
-
- let modifiers = 0;
- let keychar = null;
- let keycode = null;
- for each (let part in variant.split(/\s+/))
- {
- if (part.toLowerCase() in validModifiers)
- modifiers |= validModifiers[part.toLowerCase()];
- else if (part.length == 1)
- keychar = part.toUpperCase();
- else if ("DOM_VK_" + part.toUpperCase() in Ci.nsIDOMKeyEvent)
- keycode = "VK_" + part.toUpperCase();
- }
-
- if (!keychar && !keycode)
- continue;
-
- let canonical = modifiers + " " + (keychar || keycode);
- if (canonical in existing)
- continue;
-
- let modifierString = "";
- for each (let modifier in ["accel", "shift", "control", "alt", "meta"])
- {
- if (modifiers & validModifiers[modifier])
- {
- modifierString += modifier + " ";
- modifiers &= ~validModifiers[modifier];
- }
- }
- return [keychar, keycode, modifierString];
- }
- return null;
- },
-
- /**
- * Initializes window's context menu.
- */
- initContextMenu: function()
- {
- let contextMenu = this.getContextMenu();
- if (contextMenu)
- {
- contextMenu.addEventListener("popupshowing", this._bindMethod(this.updateContextMenu), false);
-
- // Make sure our context menu items are at the bottom
- contextMenu.appendChild(this.E("abp-removeWhitelist-menuitem"));
- contextMenu.appendChild(this.E("abp-frame-menuitem"));
- contextMenu.appendChild(this.E("abp-object-menuitem"));
- contextMenu.appendChild(this.E("abp-media-menuitem"));
- contextMenu.appendChild(this.E("abp-image-menuitem"));
- }
- },
-
- /**
- * Makes sure the toolbar button is displayed.
- */
- installToolbarIcon: function()
- {
- let tb = this.E("abp-toolbarbutton");
- if (tb && tb.parentNode.localName != "toolbarpalette")
- return;
-
- let toolbar = (this.getDefaultToolbar ? this.getDefaultToolbar() : null);
- if (!toolbar || typeof toolbar.insertItem != "function")
- return;
-
- let insertBefore = (this.toolbarInsertBefore ? this.toolbarInsertBefore() : null);
- if (insertBefore && insertBefore.parentNode != toolbar)
- insertBefore = null;
-
- toolbar.insertItem("abp-toolbarbutton", insertBefore, null, false);
-
- toolbar.setAttribute("currentset", toolbar.currentSet);
- this.window.document.persist(toolbar.id, "currentset");
-
- if (this.unhideToolbar && this.unhideToolbar())
- {
- toolbar.setAttribute("collapsed", "false");
- this.window.document.persist(toolbar.id, "collapsed");
- }
- },
-
- /**
- * Handles browser clicks to intercept clicks on abp: links. This can be
- * called either with an event object or with the link target (if it is the
- * former then link target will be retrieved from event target).
- */
- handleLinkClick: function (/**Event*/ event, /**String*/ linkTarget)
- {
- if (event)
- {
- // Ignore right-clicks
- if (event.button == 2)
- return;
-
- // Search the link associated with the click
- let link = event.target;
- while (link && !(link instanceof Ci.nsIDOMHTMLAnchorElement))
- link = link.parentNode;
-
- if (!link || link.protocol != "abp:")
- return;
-
- // This is our link - make sure the browser doesn't handle it
- event.preventDefault();
- event.stopPropagation();
-
- linkTarget = link.href;
- }
-
- if (!/^abp:\/*subscribe\/*\?(.*)/i.test(linkTarget)) /**/
- return;
-
- // Decode URL parameters
- let title = null;
- let url = null;
- let mainSubscriptionTitle = null;
- let mainSubscriptionURL = null;
- for each (let param in RegExp.$1.split('&'))
- {
- let parts = param.split("=", 2);
- if (parts.length != 2 || !/\S/.test(parts[1]))
- continue;
- switch (parts[0])
- {
- case "title":
- title = decodeURIComponent(parts[1]);
- break;
- case "location":
- url = decodeURIComponent(parts[1]);
- break;
- case "requiresTitle":
- mainSubscriptionTitle = decodeURIComponent(parts[1]);
- break;
- case "requiresLocation":
- mainSubscriptionURL = decodeURIComponent(parts[1]);
- break;
- }
- }
- if (!url)
- return;
-
- // Default title to the URL
- if (!title)
- title = url;
-
- // Main subscription needs both title and URL
- if (mainSubscriptionTitle && !mainSubscriptionURL)
- mainSubscriptionTitle = null;
- if (mainSubscriptionURL && !mainSubscriptionTitle)
- mainSubscriptionURL = null;
-
- // Trim spaces in title and URL
- title = title.replace(/^\s+/, "").replace(/\s+$/, "");
- url = url.replace(/^\s+/, "").replace(/\s+$/, "");
- if (mainSubscriptionURL)
- {
- mainSubscriptionTitle = mainSubscriptionTitle.replace(/^\s+/, "").replace(/\s+$/, "");
- mainSubscriptionURL = mainSubscriptionURL.replace(/^\s+/, "").replace(/\s+$/, "");
- }
-
- // Verify that the URL is valid
- url = Utils.makeURI(url);
- if (!url || (url.scheme != "http" && url.scheme != "https" && url.scheme != "ftp"))
- return;
- url = url.spec;
-
- if (mainSubscriptionURL)
- {
- mainSubscriptionURL = Utils.makeURI(mainSubscriptionURL);
- if (!mainSubscriptionURL || (mainSubscriptionURL.scheme != "http" && mainSubscriptionURL.scheme != "https" && mainSubscriptionURL.scheme != "ftp"))
- mainSubscriptionURL = mainSubscriptionTitle = null;
- else
- mainSubscriptionURL = mainSubscriptionURL.spec;
- }
-
- // Open dialog
- if (!Utils.isFennec)
- {
- let subscription = {url: url, title: title, disabled: false, external: false, autoDownload: true,
- mainSubscriptionTitle: mainSubscriptionTitle, mainSubscriptionURL: mainSubscriptionURL};
- this.window.openDialog("chrome://adblockplus/content/ui/subscriptionSelection.xul", "_blank",
- "chrome,centerscreen,resizable,dialog=no", subscription, null);
- }
- else
- {
- // Special handling for Fennec
- AppIntegrationFennec.openFennecSubscriptionDialog(this, url, title);
- }
- },
-
- /**
- * Updates state of the icon tooltip.
- */
- fillTooltip: function(/**Event*/ event)
- {
- let node = this.window.document.tooltipNode;
- if (!node || !node.hasAttribute("tooltip"))
- {
- event.preventDefault();
- return;
- }
-
- let type = (node.id == "abp-toolbarbutton" ? "toolbar" : "statusbar");
- let action = parseInt(Prefs["default" + type + "action"]);
- if (isNaN(action))
- action = -1;
-
- let actionDescr = this.E("abp-tooltip-action");
- actionDescr.hidden = (action < 0 || action > 3);
- if (!actionDescr.hidden)
- actionDescr.setAttribute("value", Utils.getString("action" + action + "_tooltip"));
-
- let statusDescr = this.E("abp-tooltip-status");
- let statusStr = Utils.getString(this.state + "_tooltip");
- if (this.state == "active")
- {
- let [activeSubscriptions, activeFilters] = FilterStorage.subscriptions.reduce(function([subscriptions, filters], current)
- {
- if (current instanceof SpecialSubscription)
- return [subscriptions, filters + current.filters.filter(function(filter) !filter.disabled).length];
- else if (!current.disabled)
- return [subscriptions + 1, filters];
- else
- return [subscriptions, filters]
- }, [0, 0]);
-
- statusStr = statusStr.replace(/\?1\?/, activeSubscriptions).replace(/\?2\?/, activeFilters);
- }
- statusDescr.setAttribute("value", statusStr);
-
- let activeFilters = [];
- this.E("abp-tooltip-blocked-label").hidden = (this.state != "active");
- this.E("abp-tooltip-blocked").hidden = (this.state != "active");
- if (this.state == "active")
- {
- let stats = RequestNotifier.getWindowStatistics(this.getBrowser().contentWindow);
-
- let blockedStr = Utils.getString("blocked_count_tooltip");
- blockedStr = blockedStr.replace(/\?1\?/, stats ? stats.blocked : 0).replace(/\?2\?/, stats ? stats.items : 0);
-
- if (stats && stats.whitelisted + stats.hidden)
- {
- blockedStr += " " + Utils.getString("blocked_count_addendum");
- blockedStr = blockedStr.replace(/\?1\?/, stats.whitelisted).replace(/\?2\?/, stats.hidden);
- }
-
- this.E("abp-tooltip-blocked").setAttribute("value", blockedStr);
-
- if (stats)
- {
- let filterSort = function(a, b)
- {
- return stats.filters[b] - stats.filters[a];
- };
- for (let filter in stats.filters)
- activeFilters.push(filter);
- activeFilters = activeFilters.sort(filterSort);
- }
-
- if (activeFilters.length > 0)
- {
- let filtersContainer = this.E("abp-tooltip-filters");
- while (filtersContainer.firstChild)
- filtersContainer.removeChild(filtersContainer.firstChild);
-
- for (let i = 0; i < activeFilters.length && i < 3; i++)
- {
- let descr = filtersContainer.ownerDocument.createElement("description");
- descr.setAttribute("value", activeFilters[i] + " (" + stats.filters[activeFilters[i]] + ")");
- filtersContainer.appendChild(descr);
- }
- }
- }
-
- this.E("abp-tooltip-filters-label").hidden = (activeFilters.length == 0);
- this.E("abp-tooltip-filters").hidden = (activeFilters.length == 0);
- this.E("abp-tooltip-more-filters").hidden = (activeFilters.length <= 3);
- },
-
- /**
- * Updates state of the icon context menu.
- */
- fillPopup: function(/**Event*/ event)
- {
- let popup = event.target;
-
- // Submenu being opened - ignore
- if (!/^(abp-(?:toolbar|status)-)popup$/.test(popup.getAttribute("id")))
- return;
- let prefix = RegExp.$1;
-
- let sidebarOpen = this.isSidebarOpen();
- this.E(prefix + "opensidebar").hidden = sidebarOpen;
- this.E(prefix + "closesidebar").hidden = !sidebarOpen;
-
- let whitelistItemSite = this.E(prefix + "whitelistsite");
- let whitelistItemPage = this.E(prefix + "whitelistpage");
- whitelistItemSite.hidden = whitelistItemPage.hidden = true;
-
- let location = this.getCurrentLocation();
- if (location && Policy.isBlockableScheme(location))
- {
- let host = null;
- try
- {
- host = location.host.replace(/^www\./, "");
- } catch (e) {}
-
- if (host)
- {
- let ending = "|";
- if (location instanceof Ci.nsIURL && location.ref)
- location.ref = "";
- if (location instanceof Ci.nsIURL && location.query)
- {
- location.query = "";
- ending = "?";
- }
-
- this.siteWhitelist = Filter.fromText("@@||" + host + "^$document");
- whitelistItemSite.setAttribute("checked", this.siteWhitelist.subscriptions.length && !this.siteWhitelist.disabled);
- whitelistItemSite.setAttribute("label", whitelistItemSite.getAttribute("labeltempl").replace(/\?1\?/, host));
- whitelistItemSite.hidden = false;
-
- this.pageWhitelist = Filter.fromText("@@|" + location.spec + ending + "$document");
- whitelistItemPage.setAttribute("checked", this.pageWhitelist.subscriptions.length && !this.pageWhitelist.disabled);
- whitelistItemPage.hidden = false;
- }
- else
- {
- this.siteWhitelist = Filter.fromText("@@|" + location.spec + "|");
- whitelistItemSite.setAttribute("checked", this.siteWhitelist.subscriptions.length && !this.siteWhitelist.disabled);
- whitelistItemSite.setAttribute("label", whitelistItemSite.getAttribute("labeltempl").replace(/\?1\?/, location.spec.replace(/^mailto:/, "")));
- whitelistItemSite.hidden = false;
- }
- }
-
- this.E("abp-command-sendReport").setAttribute("disabled", !location || !Policy.isBlockableScheme(location) || location.scheme == "mailto");
-
- this.E(prefix + "disabled").setAttribute("checked", !Prefs.enabled);
- this.E(prefix + "frameobjects").setAttribute("checked", Prefs.frameobjects);
- this.E(prefix + "slowcollapse").setAttribute("checked", !Prefs.fastcollapse);
- this.E(prefix + "showintoolbar").setAttribute("checked", Prefs.showintoolbar);
- this.E(prefix + "showinstatusbar").setAttribute("checked", Prefs.showinstatusbar);
-
- let syncEngine = Sync.getEngine();
- this.E(prefix + "sync").hidden = !syncEngine;
- this.E(prefix + "sync").setAttribute("checked", syncEngine && syncEngine.enabled);
-
- let defAction = (prefix == "abp-toolbar-" || this.window.document.popupNode.id == "abp-toolbarbutton" ?
- Prefs.defaulttoolbaraction :
- Prefs.defaultstatusbaraction);
- this.E(prefix + "opensidebar").setAttribute("default", defAction == 1);
- this.E(prefix + "closesidebar").setAttribute("default", defAction == 1);
- this.E(prefix + "settings").setAttribute("default", defAction == 2);
- this.E(prefix + "disabled").setAttribute("default", defAction == 3);
-
- // Only show "Recommend" button to Facebook users, we don't want to advertise Facebook
- this.E(prefix + "recommendbutton").hidden = true;
- if (!this.E("abp-hooks").hasAttribute("forceHideRecommend"))
- {
- let cookieManager = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
- if ("getCookiesFromHost" in cookieManager)
- {
- let enumerator = cookieManager.getCookiesFromHost("facebook.com");
- while (enumerator.hasMoreElements())
- {
- let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
- if (cookie.name == "lu")
- {
- this.E(prefix + "recommendbutton").hidden = false;
- break;
- }
- }
- }
- }
- },
-
- /**
- * Opens report wizard for the current page.
- */
- openReportDialog: function()
- {
- let wnd = Utils.windowMediator.getMostRecentWindow("abp:sendReport");
- if (wnd)
- wnd.focus();
- else
- this.window.openDialog("chrome://adblockplus/content/ui/sendReport.xul", "_blank", "chrome,centerscreen,resizable=no", this.window.content, this.getCurrentLocation());
- },
-
- /**
- * Opens Facebook's recommend page.
- */
- recommend: function()
- {
- this.window.open("http://www.facebook.com/share.php?u=http%3A%2F%2Fadblockplus.org%2F&t=Adblock%20Plus", "_blank", "width=550,height=350");
- },
-
- /**
- * Hide recommend button and persist this choice.
- */
- recommendHide: function(event)
- {
- let hooks = this.E("abp-hooks");
- hooks.setAttribute("forceHideRecommend", "true");
- this.window.document.persist(hooks.id, "forceHideRecommend");
-
- for each (let button in [this.E("abp-status-recommendbutton"), this.E("abp-toolbar-recommendbutton")])
- if (button)
- button.hidden = true;
- },
-
- /**
- * Tests whether blockable items list is currently open.
- */
- isSidebarOpen: function() /**Boolean*/
- {
- if (this.detachedSidebar && !this.detachedSidebar.closed)
- return true;
-
- let sidebar = this.E("abp-sidebar");
- return (sidebar ? !sidebar.hidden : false);
- },
-
- /**
- * Toggles open/closed state of the blockable items list.
- */
- toggleSidebar: function()
- {
- if (this.detachedSidebar && !this.detachedSidebar.closed)
- {
- this.detachedSidebar.close();
- this.detachedSidebar = null;
- }
- else
- {
- let sidebar = this.E("abp-sidebar");
- if (sidebar && (!Prefs.detachsidebar || !sidebar.hidden))
- {
- this.E("abp-sidebar-splitter").hidden = !sidebar.hidden;
- this.E("abp-sidebar-browser").setAttribute("src", sidebar.hidden ? "chrome://adblockplus/content/ui/sidebar.xul" : "about:blank");
- sidebar.hidden = !sidebar.hidden;
- if (sidebar.hidden)
- this.getBrowser().contentWindow.focus();
- }
- else
- this.detachedSidebar = this.window.openDialog("chrome://adblockplus/content/ui/sidebarDetached.xul", "_blank", "chrome,resizable,dependent,dialog=no");
- }
-
- let menuItem = this.E("abp-blockableitems");
- if (menuItem)
- menuItem.setAttribute("checked", this.isSidebarOpen());
- },
-
- /**
- * Removes/disables the exception rule applying for the current page.
- */
- removeWhitelist: function()
- {
- let location = this.getCurrentLocation();
- let filter = null;
- if (location)
- filter = Policy.isWhitelisted(location.spec);
- if (filter && filter.subscriptions.length && !filter.disabled)
- {
- AppIntegration.toggleFilter(filter);
- return true;
- }
- return false;
- },
-
- /**
- * Handles command events on toolbar icon.
- */
- handleToolbarCommand: function(event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- if (Prefs.defaulttoolbaraction == 0)
- event.target.open = true;
- else
- this.executeAction(Prefs.defaulttoolbaraction);
- },
-
- /**
- * Handles click events on toolbar icon.
- */
- handleToolbarClick: function(/**Event*/ event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- if (event.button == 1)
- this.executeAction(3);
- },
-
- /**
- * Handles click events on status bar icon.
- */
- handleStatusClick: function(/**Event*/ event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- if (event.button == 0)
- this.executeAction(Prefs.defaultstatusbaraction);
- else if (event.button == 1)
- this.executeAction(3);
- },
-
- // Executes default action for statusbar/toolbar by its number
- executeAction: function (action)
- {
- if (action == 1)
- this.toggleSidebar();
- else if (action == 2)
- Utils.openSettingsDialog();
- else if (action == 3)
- {
- // If there is a whitelisting rule for current page - remove it (reenable).
- // Otherwise flip "enabled" pref.
- if (!this.removeWhitelist())
- AppIntegration.togglePref("enabled");
- }
- },
-
- /**
- * Updates context menu, in particularly controls the visibility of context
- * menu items like "Block image".
- */
- updateContextMenu: function(event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- let contextMenu = this.getContextMenu();
- let target = this.window.document.popupNode;
- if (target instanceof Ci.nsIDOMHTMLMapElement || target instanceof Ci.nsIDOMHTMLAreaElement)
- {
- // HTML image maps will usually receive events when the mouse pointer is
- // over a different element, get the real event target.
- let rect = target.getClientRects()[0];
- target = target.ownerDocument.elementFromPoint(Math.max(rect.left, 0), Math.max(rect.top, 0));
- }
-
- let nodeType = null;
- this.nodeData = null;
- this.currentNode = null;
- this.backgroundData = null;
- this.frameData = null;
- this.currentFrame = null;
- if (target)
- {
- // Lookup the node in our stored data
- let data = RequestNotifier.getDataForNode(target);
- if (data && !data[1].filter)
- {
- [this.currentNode, this.nodeData] = data;
- nodeType = this.nodeData.typeDescr;
- }
-
- let wnd = Utils.getWindow(target);
-
- if (wnd.frameElement)
- {
- let data = RequestNotifier.getDataForNode(wnd.frameElement, true);
- if (data && !data[1].filter)
- [this.currentFrame, this.frameData] = data;
- }
-
- if (nodeType != "IMAGE")
- {
- // Look for a background image
- let imageNode = target;
- while (imageNode)
- {
- if (imageNode.nodeType == imageNode.ELEMENT_NODE)
- {
- let style = wnd.getComputedStyle(imageNode, "");
- let bgImage = extractImageURL(style, "background-image") || extractImageURL(style, "list-style-image");
- if (bgImage)
- {
- let data = RequestNotifier.getDataForNode(wnd.document, true, Policy.type.IMAGE, bgImage);
- if (data && !data[1].filter)
- {
- this.backgroundData = data[1];
- break;
- }
- }
- }
-
- imageNode = imageNode.parentNode;
- }
- }
-
- // Hide "Block Images from ..." if hideimagemanager pref is true and the image manager isn't already blocking something
- let imgManagerContext = this.E("context-blockimage");
- if (imgManagerContext && shouldHideImageManager())
- {
- // Don't use "hidden" attribute - it might be overridden by the default popupshowing handler
- imgManagerContext.collapsed = true;
- }
- }
-
- this.E("abp-image-menuitem").hidden = (nodeType != "IMAGE" && this.backgroundData == null);
- this.E("abp-object-menuitem").hidden = (nodeType != "OBJECT");
- this.E("abp-media-menuitem").hidden = (nodeType != "MEDIA");
- this.E("abp-frame-menuitem").hidden = (this.frameData == null);
-
- let location = this.getCurrentLocation();
- this.E("abp-removeWhitelist-menuitem").hidden = (!location || !Policy.isWhitelisted(location.spec));
- },
-
- /**
- * Brings up the filter composer dialog to block an item.
- */
- blockItem: function(/**Node*/ node, /**RequestEntry*/ item)
- {
- if (!item)
- return;
-
- this.window.openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", [node], item);
- }
+ /**
+ * Application window this object belongs to.
+ * @type Window
+ */
+ window: null,
+
+ /**
+ * Current state as displayed for this window.
+ * @type String
+ */
+ state: null,
+
+ /**
+ * Methods that can be defined at attributes of the hooks element.
+ * @type Array of String
+ */
+ customMethods: ["getBrowser", "addTab", "getContextMenu", "getToolbox", "getDefaultToolbar", "toolbarInsertBefore", "unhideToolbar"],
+
+ /**
+ * Progress listener used to watch for location changes, if any.
+ * @type nsIProgressListener
+ */
+ progressListener: null,
+
+ /**
+ * Filter corresponding with "disable on site" menu item (set in fillPopup()).
+ * @type Filter
+ */
+ siteWhitelist: null,
+ /**
+ * Filter corresponding with "disable on site" menu item (set in fillPopup()).
+ * @type Filter
+ */
+ pageWhitelist: null,
+
+ /**
+ * Data associated with the node currently under mouse pointer (set in updateContextMenu()).
+ * @type RequestEntry
+ */
+ nodeData: null,
+ /**
+ * The document node that nodeData belongs to.
+ */
+ currentNode: null,
+ /**
+ * Data associated with the background image currently under mouse pointer (set in updateContextMenu()).
+ * @type RequestEntry
+ */
+ backgroundData: null,
+ /**
+ * Data associated with the frame currently under mouse pointer (set in updateContextMenu()).
+ * @type RequestEntry
+ */
+ frameData: null,
+ /**
+ * The frame that frameData belongs to.
+ */
+ currentFrame: null,
+
+ /**
+ * Window of the detached list of blockable items (might be null or closed).
+ * @type Window
+ */
+ detachedSidebar: null,
+
+ /**
+ * Binds a function to the object, ensuring that "this" pointer is always set
+ * correctly.
+ */
+ _bindMethod: function(/**Function*/ method) /**Function*/
+ {
+ let me = this;
+ return function() method.apply(me, arguments);
+ },
+
+ /**
+ * Retrieves an element by its ID.
+ */
+ E: function(/**String*/ id)
+ {
+ let doc = this.window.document;
+ this.E = function(id) doc.getElementById(id);
+ return this.E(id);
+ },
+
+ /**
+ * Initializes abp-hooks element, converts any function attributes to actual
+ * functions.
+ */
+ initializeHooks: function(hooks)
+ {
+ for each (let hook in this.customMethods)
+ {
+ let handler = hooks.getAttribute(hook);
+ this[hook] = hooks[hook] = (handler ? this._bindMethod(new Function(handler)) : null);
+ }
+ },
+
+ /**
+ * Makes a copy of the ABP icon's context menu for the toolbar button.
+ */
+ fixupMenus: function()
+ {
+ function fixId(node)
+ {
+ if (node.nodeType == node.ELEMENT_NODE)
+ {
+ if (node.hasAttribute("id"))
+ node.setAttribute("id", node.getAttribute("id").replace(/abp-status/, "abp-toolbar"));
+
+ for (let i = 0, len = node.childNodes.length; i < len; i++)
+ fixId(node.childNodes[i]);
+ }
+ return node;
+ }
+
+ let menuSource = this.E("abp-status-popup");
+ let paletteButton = this.getPaletteButton();
+ let toolbarButton = this.E("abp-toolbarbutton");
+ if (toolbarButton)
+ toolbarButton.appendChild(fixId(menuSource.cloneNode(true)));
+ if (paletteButton && paletteButton != toolbarButton)
+ paletteButton.appendChild(fixId(menuSource.cloneNode(true)));
+ },
+
+ /**
+ * Attaches event listeners to a window represented by hooks element
+ */
+ registerEventListeners: function(/**Boolean*/ addProgressListener)
+ {
+ // Palette button elements aren't reachable by ID, create a lookup table
+ let paletteButtonIDs = {};
+ let paletteButton = this.getPaletteButton();
+ if (paletteButton)
+ {
+ function getElementIds(element)
+ {
+ if (element.hasAttribute("id"))
+ paletteButtonIDs[element.getAttribute("id")] = element;
+
+ for (let child = element.firstChild; child; child = child.nextSibling)
+ if (child.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
+ getElementIds(child);
+ }
+ getElementIds(paletteButton);
+ }
+
+ // Go on and register listeners
+ this.window.addEventListener("unload", removeWindow, false);
+ for each (let [id, event, handler] in this.eventHandlers)
+ {
+ handler = this._bindMethod(handler);
+
+ let element = this.E(id);
+ if (element)
+ element.addEventListener(event, handler, false);
+
+ if (id in paletteButtonIDs)
+ paletteButtonIDs[id].addEventListener(event, handler, false);
+ }
+
+ let browser = this.getBrowser();
+ browser.addEventListener("click", this._bindMethod(this.handleLinkClick), true);
+
+ // Register progress listener as well if requested
+ if (addProgressListener)
+ {
+ let dummy = function() {};
+ this.progressListener =
+ {
+ onLocationChange: this._bindMethod(this.updateState),
+ onProgressChange: dummy,
+ onSecurityChange: dummy,
+ onStateChange: dummy,
+ onStatusChange: dummy,
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, Ci.nsISupportsWeakReference])
+ };
+ browser.addProgressListener(this.progressListener);
+ }
+ },
+
+ /**
+ * Retrieves the current location of the browser (might return null on failure).
+ */
+ getCurrentLocation: function() /**nsIURI*/
+ {
+ if ("currentHeaderData" in this.window && "content-base" in this.window.currentHeaderData)
+ {
+ // Thunderbird blog entry
+ return Utils.unwrapURL(this.window.currentHeaderData["content-base"].headerValue);
+ }
+ else if ("currentHeaderData" in this.window && "from" in this.window.currentHeaderData)
+ {
+ // Thunderbird mail/newsgroup entry
+ try
+ {
+ let headerParser = Cc["@mozilla.org/messenger/headerparser;1"].getService(Ci.nsIMsgHeaderParser);
+ let emailAddress = headerParser.extractHeaderAddressMailboxes(this.window.currentHeaderData.from.headerValue);
+ return Utils.makeURI("mailto:" + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, "%20"));
+ }
+ catch(e)
+ {
+ return null;
+ }
+ }
+ else
+ {
+ // Regular browser
+ return Utils.unwrapURL(this.getBrowser().currentURI.clone());
+ }
+ },
+
+ /**
+ * Executes window-specific first-run actions if necessary.
+ */
+ executeFirstRunActions: function()
+ {
+ // Only execute first-run actions for this window once
+ if ("doneFirstRunActions " + this.window.location.href in Prefs)
+ return;
+ Prefs["doneFirstRunActions " + this.window.location.href] = true;
+
+ // Check version we previously executed first-run actions for;
+ let hooks = this.E("abp-hooks");
+ let lastVersion = hooks.getAttribute("currentVersion") || "0.0";
+ if (lastVersion != Prefs.currentVersion)
+ {
+ hooks.setAttribute("currentVersion", Prefs.currentVersion);
+ this.window.document.persist("abp-hooks", "currentVersion");
+
+ let needInstall = (Utils.versionComparator.compare(lastVersion, "0.0") <= 0);
+ if (!needInstall)
+ {
+ // Before version 1.1 we didn't add toolbar icon in SeaMonkey, do it now
+ needInstall = Utils.appID == "{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}" &&
+ Utils.versionComparator.compare(lastVersion, "1.1") < 0;
+ }
+
+ // Add ABP icon to toolbar if necessary
+ if (needInstall)
+ Utils.runAsync(this.installToolbarIcon, this);
+ }
+ },
+
+ /**
+ * Finds the toolbar button in the toolbar palette.
+ */
+ getPaletteButton: function()
+ {
+ let toolbox = (this.getToolbox ? this.getToolbox() : null);
+ if (!toolbox || !("palette" in toolbox) || !toolbox.palette)
+ return null;
+
+ for (var child = toolbox.palette.firstChild; child; child = child.nextSibling)
+ if (child.id == "abp-toolbarbutton")
+ return child;
+
+ return null;
+ },
+
+ /**
+ * Updates displayed state for an application window.
+ */
+ updateState: function()
+ {
+ let state = (Prefs.enabled ? "active" : "disabled");
+
+ if (state == "active")
+ {
+ let location = this.getCurrentLocation();
+ if (location && Policy.isWhitelisted(location.spec))
+ state = "whitelisted";
+ }
+ this.state = state;
+
+ function updateElement(element)
+ {
+ if (!element)
+ return;
+
+ if (element.tagName == "statusbarpanel")
+ element.hidden = !Prefs.showinstatusbar;
+ else
+ {
+ element.hidden = !Prefs.showintoolbar;
+ if (element.hasAttribute("context") && Prefs.defaulttoolbaraction == 0)
+ element.setAttribute("type", "menu");
+ else
+ element.setAttribute("type", "menu-button");
+ }
+
+ // HACKHACK: Show status bar icon instead of toolbar icon if the application doesn't have a toolbar icon
+ if (element.hidden && element.tagName == "statusbarpanel" && !this.getDefaultToolbar)
+ element.hidden = !Prefs.showintoolbar;
+
+ element.setAttribute("abpstate", state);
+ };
+
+ let status = this.E("abp-status");
+ if (status)
+ {
+ updateElement.call(this, status);
+ if (Prefs.defaultstatusbaraction == 0)
+ status.setAttribute("popup", status.getAttribute("context"));
+ else
+ status.removeAttribute("popup");
+ }
+
+ let button = this.E("abp-toolbarbutton");
+ if (button)
+ updateElement.call(this, button);
+
+ updateElement.call(this, this.getPaletteButton());
+ },
+
+ /**
+ * Sets up hotkeys for the window.
+ */
+ configureKeys: function()
+ {
+ if (!hotkeys)
+ {
+ hotkeys = {__proto__: null};
+
+ let validModifiers =
+ {
+ accel: 1,
+ shift: 2,
+ ctrl: 4,
+ control: 4,
+ alt: 8,
+ meta: 16,
+ __proto__: null
+ };
+
+ try
+ {
+ let accelKey = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).getIntPref("ui.key.accelKey");
+ if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_CONTROL)
+ validModifiers.ctrl = validModifiers.control = validModifiers.accel;
+ else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_ALT)
+ validModifiers.alt = validModifiers.accel;
+ else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_META)
+ validModifiers.meta = validModifiers.accel;
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+ }
+
+ // Find which hotkeys are already taken, convert them to canonical form
+ let existing = {};
+ let keys = this.window.document.getElementsByTagName("key");
+ for (let i = 0; i < keys.length; i++)
+ {
+ let key = keys[i];
+ let keyChar = key.getAttribute("key");
+ let keyCode = key.getAttribute("keycode");
+ if (!keyChar && !keyCode)
+ continue;
+
+ let modifiers = 0;
+ let keyModifiers = key.getAttribute("modifiers");
+ if (keyModifiers)
+ {
+ for each (let modifier in keyModifiers.match(/\w+/g))
+ {
+ modifier = modifier.toLowerCase();
+ if (modifier in validModifiers)
+ modifiers |= validModifiers[modifier]
+ }
+
+ let canonical = modifiers + " " + (keyChar || keyCode).toUpperCase();
+ existing[canonical] = true;
+ }
+ }
+
+ // Find available keys for our prefs
+ for (let pref in Prefs)
+ {
+ if (/_key$/.test(pref) && typeof Prefs[pref] == "string")
+ {
+ try
+ {
+ let id = RegExp.leftContext;
+ let result = this.findAvailableKey(id, Prefs[pref], validModifiers, existing);
+ if (result)
+ hotkeys[id] = result;
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ }
+ }
+ }
+
+ // Add elements for all configured hotkeys
+ for (let id in hotkeys)
+ {
+ let [keychar, keycode, modifierString] = hotkeys[id];
+
+ let element = this.window.document.createElement("key");
+ element.setAttribute("id", "abp-key-" + id);
+ element.setAttribute("command", "abp-command-" + id);
+ if (keychar)
+ element.setAttribute("key", keychar);
+ else
+ element.setAttribute("keycode", keycode);
+ element.setAttribute("modifiers", modifierString);
+
+ this.E("abp-keyset").appendChild(element);
+ }
+ },
+
+ /**
+ * Finds an available hotkey for a value defined in preferences.
+ */
+ findAvailableKey: function(/**String*/ id, /**String*/ value, /**Object*/ validModifiers, /**Object*/ existing) /**Array*/
+ {
+ let command = this.E("abp-command-" + id);
+ if (!command)
+ return;
+
+ for each (let variant in value.split(/\s*,\s*/))
+ {
+ if (!variant)
+ continue;
+
+ let modifiers = 0;
+ let keychar = null;
+ let keycode = null;
+ for each (let part in variant.split(/\s+/))
+ {
+ if (part.toLowerCase() in validModifiers)
+ modifiers |= validModifiers[part.toLowerCase()];
+ else if (part.length == 1)
+ keychar = part.toUpperCase();
+ else if ("DOM_VK_" + part.toUpperCase() in Ci.nsIDOMKeyEvent)
+ keycode = "VK_" + part.toUpperCase();
+ }
+
+ if (!keychar && !keycode)
+ continue;
+
+ let canonical = modifiers + " " + (keychar || keycode);
+ if (canonical in existing)
+ continue;
+
+ let modifierString = "";
+ for each (let modifier in ["accel", "shift", "control", "alt", "meta"])
+ {
+ if (modifiers & validModifiers[modifier])
+ {
+ modifierString += modifier + " ";
+ modifiers &= ~validModifiers[modifier];
+ }
+ }
+ return [keychar, keycode, modifierString];
+ }
+ return null;
+ },
+
+ /**
+ * Initializes window's context menu.
+ */
+ initContextMenu: function()
+ {
+ let contextMenu = this.getContextMenu();
+ if (contextMenu)
+ {
+ contextMenu.addEventListener("popupshowing", this._bindMethod(this.updateContextMenu), false);
+
+ // Make sure our context menu items are at the bottom
+ contextMenu.appendChild(this.E("abp-removeWhitelist-menuitem"));
+ contextMenu.appendChild(this.E("abp-frame-menuitem"));
+ contextMenu.appendChild(this.E("abp-object-menuitem"));
+ contextMenu.appendChild(this.E("abp-media-menuitem"));
+ contextMenu.appendChild(this.E("abp-image-menuitem"));
+ }
+ },
+
+ /**
+ * Makes sure the toolbar button is displayed.
+ */
+ installToolbarIcon: function()
+ {
+ let tb = this.E("abp-toolbarbutton");
+ if (tb && tb.parentNode.localName != "toolbarpalette")
+ return;
+
+ let toolbar = (this.getDefaultToolbar ? this.getDefaultToolbar() : null);
+ if (!toolbar || typeof toolbar.insertItem != "function")
+ return;
+
+ let insertBefore = (this.toolbarInsertBefore ? this.toolbarInsertBefore() : null);
+ if (insertBefore && insertBefore.parentNode != toolbar)
+ insertBefore = null;
+
+ toolbar.insertItem("abp-toolbarbutton", insertBefore, null, false);
+
+ toolbar.setAttribute("currentset", toolbar.currentSet);
+ this.window.document.persist(toolbar.id, "currentset");
+
+ if (this.unhideToolbar && this.unhideToolbar())
+ {
+ toolbar.setAttribute("collapsed", "false");
+ this.window.document.persist(toolbar.id, "collapsed");
+ }
+ },
+
+ /**
+ * Handles browser clicks to intercept clicks on abp: links. This can be
+ * called either with an event object or with the link target (if it is the
+ * former then link target will be retrieved from event target).
+ */
+ handleLinkClick: function (/**Event*/ event, /**String*/ linkTarget)
+ {
+ if (event)
+ {
+ // Ignore right-clicks
+ if (event.button == 2)
+ return;
+
+ // Search the link associated with the click
+ let link = event.target;
+ while (link && !(link instanceof Ci.nsIDOMHTMLAnchorElement))
+ link = link.parentNode;
+
+ if (!link || link.protocol != "abp:")
+ return;
+
+ // This is our link - make sure the browser doesn't handle it
+ event.preventDefault();
+ event.stopPropagation();
+
+ linkTarget = link.href;
+ }
+
+ if (!/^abp:\/*subscribe\/*\?(.*)/i.test(linkTarget)) /**/
+ return;
+
+ // Decode URL parameters
+ let title = null;
+ let url = null;
+ let mainSubscriptionTitle = null;
+ let mainSubscriptionURL = null;
+ for each (let param in RegExp.$1.split('&'))
+ {
+ let parts = param.split("=", 2);
+ if (parts.length != 2 || !/\S/.test(parts[1]))
+ continue;
+ switch (parts[0])
+ {
+ case "title":
+ title = decodeURIComponent(parts[1]);
+ break;
+ case "location":
+ url = decodeURIComponent(parts[1]);
+ break;
+ case "requiresTitle":
+ mainSubscriptionTitle = decodeURIComponent(parts[1]);
+ break;
+ case "requiresLocation":
+ mainSubscriptionURL = decodeURIComponent(parts[1]);
+ break;
+ }
+ }
+ if (!url)
+ return;
+
+ // Default title to the URL
+ if (!title)
+ title = url;
+
+ // Main subscription needs both title and URL
+ if (mainSubscriptionTitle && !mainSubscriptionURL)
+ mainSubscriptionTitle = null;
+ if (mainSubscriptionURL && !mainSubscriptionTitle)
+ mainSubscriptionURL = null;
+
+ // Trim spaces in title and URL
+ title = title.replace(/^\s+/, "").replace(/\s+$/, "");
+ url = url.replace(/^\s+/, "").replace(/\s+$/, "");
+ if (mainSubscriptionURL)
+ {
+ mainSubscriptionTitle = mainSubscriptionTitle.replace(/^\s+/, "").replace(/\s+$/, "");
+ mainSubscriptionURL = mainSubscriptionURL.replace(/^\s+/, "").replace(/\s+$/, "");
+ }
+
+ // Verify that the URL is valid
+ url = Utils.makeURI(url);
+ if (!url || (url.scheme != "http" && url.scheme != "https" && url.scheme != "ftp"))
+ return;
+ url = url.spec;
+
+ if (mainSubscriptionURL)
+ {
+ mainSubscriptionURL = Utils.makeURI(mainSubscriptionURL);
+ if (!mainSubscriptionURL || (mainSubscriptionURL.scheme != "http" && mainSubscriptionURL.scheme != "https" && mainSubscriptionURL.scheme != "ftp"))
+ mainSubscriptionURL = mainSubscriptionTitle = null;
+ else
+ mainSubscriptionURL = mainSubscriptionURL.spec;
+ }
+
+ // Open dialog
+ if (!Utils.isFennec)
+ {
+ let subscription = {url: url, title: title, disabled: false, external: false, autoDownload: true,
+ mainSubscriptionTitle: mainSubscriptionTitle, mainSubscriptionURL: mainSubscriptionURL};
+ this.window.openDialog("chrome://adblockplus/content/ui/subscriptionSelection.xul", "_blank",
+ "chrome,centerscreen,resizable,dialog=no", subscription, null);
+ }
+ else
+ {
+ // Special handling for Fennec
+ AppIntegrationFennec.openFennecSubscriptionDialog(this, url, title);
+ }
+ },
+
+ /**
+ * Updates state of the icon tooltip.
+ */
+ fillTooltip: function(/**Event*/ event)
+ {
+ let node = this.window.document.tooltipNode;
+ if (!node || !node.hasAttribute("tooltip"))
+ {
+ event.preventDefault();
+ return;
+ }
+
+ let type = (node.id == "abp-toolbarbutton" ? "toolbar" : "statusbar");
+ let action = parseInt(Prefs["default" + type + "action"]);
+ if (isNaN(action))
+ action = -1;
+
+ let actionDescr = this.E("abp-tooltip-action");
+ actionDescr.hidden = (action < 0 || action > 3);
+ if (!actionDescr.hidden)
+ actionDescr.setAttribute("value", Utils.getString("action" + action + "_tooltip"));
+
+ let statusDescr = this.E("abp-tooltip-status");
+ let statusStr = Utils.getString(this.state + "_tooltip");
+ if (this.state == "active")
+ {
+ let [activeSubscriptions, activeFilters] = FilterStorage.subscriptions.reduce(function([subscriptions, filters], current)
+ {
+ if (current instanceof SpecialSubscription)
+ return [subscriptions, filters + current.filters.filter(function(filter) !filter.disabled).length];
+ else if (!current.disabled)
+ return [subscriptions + 1, filters];
+ else
+ return [subscriptions, filters]
+ }, [0, 0]);
+
+ statusStr = statusStr.replace(/\?1\?/, activeSubscriptions).replace(/\?2\?/, activeFilters);
+ }
+ statusDescr.setAttribute("value", statusStr);
+
+ let activeFilters = [];
+ this.E("abp-tooltip-blocked-label").hidden = (this.state != "active");
+ this.E("abp-tooltip-blocked").hidden = (this.state != "active");
+ if (this.state == "active")
+ {
+ let stats = RequestNotifier.getWindowStatistics(this.getBrowser().contentWindow);
+
+ let blockedStr = Utils.getString("blocked_count_tooltip");
+ blockedStr = blockedStr.replace(/\?1\?/, stats ? stats.blocked : 0).replace(/\?2\?/, stats ? stats.items : 0);
+
+ if (stats && stats.whitelisted + stats.hidden)
+ {
+ blockedStr += " " + Utils.getString("blocked_count_addendum");
+ blockedStr = blockedStr.replace(/\?1\?/, stats.whitelisted).replace(/\?2\?/, stats.hidden);
+ }
+
+ this.E("abp-tooltip-blocked").setAttribute("value", blockedStr);
+
+ if (stats)
+ {
+ let filterSort = function(a, b)
+ {
+ return stats.filters[b] - stats.filters[a];
+ };
+ for (let filter in stats.filters)
+ activeFilters.push(filter);
+ activeFilters = activeFilters.sort(filterSort);
+ }
+
+ if (activeFilters.length > 0)
+ {
+ let filtersContainer = this.E("abp-tooltip-filters");
+ while (filtersContainer.firstChild)
+ filtersContainer.removeChild(filtersContainer.firstChild);
+
+ for (let i = 0; i < activeFilters.length && i < 3; i++)
+ {
+ let descr = filtersContainer.ownerDocument.createElement("description");
+ descr.setAttribute("value", activeFilters[i] + " (" + stats.filters[activeFilters[i]] + ")");
+ filtersContainer.appendChild(descr);
+ }
+ }
+ }
+
+ this.E("abp-tooltip-filters-label").hidden = (activeFilters.length == 0);
+ this.E("abp-tooltip-filters").hidden = (activeFilters.length == 0);
+ this.E("abp-tooltip-more-filters").hidden = (activeFilters.length <= 3);
+ },
+
+ /**
+ * Updates state of the icon context menu.
+ */
+ fillPopup: function(/**Event*/ event)
+ {
+ let popup = event.target;
+
+ // Submenu being opened - ignore
+ if (!/^(abp-(?:toolbar|status)-)popup$/.test(popup.getAttribute("id")))
+ return;
+ let prefix = RegExp.$1;
+
+ let sidebarOpen = this.isSidebarOpen();
+ this.E(prefix + "opensidebar").hidden = sidebarOpen;
+ this.E(prefix + "closesidebar").hidden = !sidebarOpen;
+
+ let whitelistItemSite = this.E(prefix + "whitelistsite");
+ let whitelistItemPage = this.E(prefix + "whitelistpage");
+ whitelistItemSite.hidden = whitelistItemPage.hidden = true;
+
+ let location = this.getCurrentLocation();
+ if (location && Policy.isBlockableScheme(location))
+ {
+ let host = null;
+ try
+ {
+ host = location.host.replace(/^www\./, "");
+ } catch (e) {}
+
+ if (host)
+ {
+ let ending = "|";
+ if (location instanceof Ci.nsIURL && location.ref)
+ location.ref = "";
+ if (location instanceof Ci.nsIURL && location.query)
+ {
+ location.query = "";
+ ending = "?";
+ }
+
+ this.siteWhitelist = Filter.fromText("@@||" + host + "^$document");
+ whitelistItemSite.setAttribute("checked", this.siteWhitelist.subscriptions.length && !this.siteWhitelist.disabled);
+ whitelistItemSite.setAttribute("label", whitelistItemSite.getAttribute("labeltempl").replace(/\?1\?/, host));
+ whitelistItemSite.hidden = false;
+
+ this.pageWhitelist = Filter.fromText("@@|" + location.spec + ending + "$document");
+ whitelistItemPage.setAttribute("checked", this.pageWhitelist.subscriptions.length && !this.pageWhitelist.disabled);
+ whitelistItemPage.hidden = false;
+ }
+ else
+ {
+ this.siteWhitelist = Filter.fromText("@@|" + location.spec + "|");
+ whitelistItemSite.setAttribute("checked", this.siteWhitelist.subscriptions.length && !this.siteWhitelist.disabled);
+ whitelistItemSite.setAttribute("label", whitelistItemSite.getAttribute("labeltempl").replace(/\?1\?/, location.spec.replace(/^mailto:/, "")));
+ whitelistItemSite.hidden = false;
+ }
+ }
+
+ this.E("abp-command-sendReport").setAttribute("disabled", !location || !Policy.isBlockableScheme(location) || location.scheme == "mailto");
+
+ this.E(prefix + "disabled").setAttribute("checked", !Prefs.enabled);
+ this.E(prefix + "frameobjects").setAttribute("checked", Prefs.frameobjects);
+ this.E(prefix + "slowcollapse").setAttribute("checked", !Prefs.fastcollapse);
+ this.E(prefix + "showintoolbar").setAttribute("checked", Prefs.showintoolbar);
+ this.E(prefix + "showinstatusbar").setAttribute("checked", Prefs.showinstatusbar);
+
+ let syncEngine = Sync.getEngine();
+ this.E(prefix + "sync").hidden = !syncEngine;
+ this.E(prefix + "sync").setAttribute("checked", syncEngine && syncEngine.enabled);
+
+ let defAction = (prefix == "abp-toolbar-" || this.window.document.popupNode.id == "abp-toolbarbutton" ?
+ Prefs.defaulttoolbaraction :
+ Prefs.defaultstatusbaraction);
+ this.E(prefix + "opensidebar").setAttribute("default", defAction == 1);
+ this.E(prefix + "closesidebar").setAttribute("default", defAction == 1);
+ this.E(prefix + "settings").setAttribute("default", defAction == 2);
+ this.E(prefix + "disabled").setAttribute("default", defAction == 3);
+
+ // Only show "Recommend" button to Facebook users, we don't want to advertise Facebook
+ this.E(prefix + "recommendbutton").hidden = true;
+ if (!this.E("abp-hooks").hasAttribute("forceHideRecommend"))
+ {
+ let cookieManager = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
+ if ("getCookiesFromHost" in cookieManager)
+ {
+ let enumerator = cookieManager.getCookiesFromHost("facebook.com");
+ while (enumerator.hasMoreElements())
+ {
+ let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
+ if (cookie.name == "lu")
+ {
+ this.E(prefix + "recommendbutton").hidden = false;
+ break;
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Opens report wizard for the current page.
+ */
+ openReportDialog: function()
+ {
+ let wnd = Utils.windowMediator.getMostRecentWindow("abp:sendReport");
+ if (wnd)
+ wnd.focus();
+ else
+ this.window.openDialog("chrome://adblockplus/content/ui/sendReport.xul", "_blank", "chrome,centerscreen,resizable=no", this.window.content, this.getCurrentLocation());
+ },
+
+ /**
+ * Opens Facebook's recommend page.
+ */
+ recommend: function()
+ {
+ this.window.open("http://www.facebook.com/share.php?u=http%3A%2F%2Fadblockplus.org%2F&t=Adblock%20Plus", "_blank", "width=550,height=350");
+ },
+
+ /**
+ * Hide recommend button and persist this choice.
+ */
+ recommendHide: function(event)
+ {
+ let hooks = this.E("abp-hooks");
+ hooks.setAttribute("forceHideRecommend", "true");
+ this.window.document.persist(hooks.id, "forceHideRecommend");
+
+ for each (let button in [this.E("abp-status-recommendbutton"), this.E("abp-toolbar-recommendbutton")])
+ if (button)
+ button.hidden = true;
+ },
+
+ /**
+ * Tests whether blockable items list is currently open.
+ */
+ isSidebarOpen: function() /**Boolean*/
+ {
+ if (this.detachedSidebar && !this.detachedSidebar.closed)
+ return true;
+
+ let sidebar = this.E("abp-sidebar");
+ return (sidebar ? !sidebar.hidden : false);
+ },
+
+ /**
+ * Toggles open/closed state of the blockable items list.
+ */
+ toggleSidebar: function()
+ {
+ if (this.detachedSidebar && !this.detachedSidebar.closed)
+ {
+ this.detachedSidebar.close();
+ this.detachedSidebar = null;
+ }
+ else
+ {
+ let sidebar = this.E("abp-sidebar");
+ if (sidebar && (!Prefs.detachsidebar || !sidebar.hidden))
+ {
+ this.E("abp-sidebar-splitter").hidden = !sidebar.hidden;
+ this.E("abp-sidebar-browser").setAttribute("src", sidebar.hidden ? "chrome://adblockplus/content/ui/sidebar.xul" : "about:blank");
+ sidebar.hidden = !sidebar.hidden;
+ if (sidebar.hidden)
+ this.getBrowser().contentWindow.focus();
+ }
+ else
+ this.detachedSidebar = this.window.openDialog("chrome://adblockplus/content/ui/sidebarDetached.xul", "_blank", "chrome,resizable,dependent,dialog=no");
+ }
+
+ let menuItem = this.E("abp-blockableitems");
+ if (menuItem)
+ menuItem.setAttribute("checked", this.isSidebarOpen());
+ },
+
+ /**
+ * Removes/disables the exception rule applying for the current page.
+ */
+ removeWhitelist: function()
+ {
+ let location = this.getCurrentLocation();
+ let filter = null;
+ if (location)
+ filter = Policy.isWhitelisted(location.spec);
+ if (filter && filter.subscriptions.length && !filter.disabled)
+ {
+ AppIntegration.toggleFilter(filter);
+ return true;
+ }
+ return false;
+ },
+
+ /**
+ * Handles command events on toolbar icon.
+ */
+ handleToolbarCommand: function(event)
+ {
+ if (event.eventPhase != event.AT_TARGET)
+ return;
+
+ if (Prefs.defaulttoolbaraction == 0)
+ event.target.open = true;
+ else
+ this.executeAction(Prefs.defaulttoolbaraction);
+ },
+
+ /**
+ * Handles click events on toolbar icon.
+ */
+ handleToolbarClick: function(/**Event*/ event)
+ {
+ if (event.eventPhase != event.AT_TARGET)
+ return;
+
+ if (event.button == 1)
+ this.executeAction(3);
+ },
+
+ /**
+ * Handles click events on status bar icon.
+ */
+ handleStatusClick: function(/**Event*/ event)
+ {
+ if (event.eventPhase != event.AT_TARGET)
+ return;
+
+ if (event.button == 0)
+ this.executeAction(Prefs.defaultstatusbaraction);
+ else if (event.button == 1)
+ this.executeAction(3);
+ },
+
+ // Executes default action for statusbar/toolbar by its number
+ executeAction: function (action)
+ {
+ if (action == 1)
+ this.toggleSidebar();
+ else if (action == 2)
+ Utils.openSettingsDialog();
+ else if (action == 3)
+ {
+ // If there is a whitelisting rule for current page - remove it (reenable).
+ // Otherwise flip "enabled" pref.
+ if (!this.removeWhitelist())
+ AppIntegration.togglePref("enabled");
+ }
+ },
+
+ /**
+ * Updates context menu, in particularly controls the visibility of context
+ * menu items like "Block image".
+ */
+ updateContextMenu: function(event)
+ {
+ if (event.eventPhase != event.AT_TARGET)
+ return;
+
+ let contextMenu = this.getContextMenu();
+ let target = this.window.document.popupNode;
+ if (target instanceof Ci.nsIDOMHTMLMapElement || target instanceof Ci.nsIDOMHTMLAreaElement)
+ {
+ // HTML image maps will usually receive events when the mouse pointer is
+ // over a different element, get the real event target.
+ let rect = target.getClientRects()[0];
+ target = target.ownerDocument.elementFromPoint(Math.max(rect.left, 0), Math.max(rect.top, 0));
+ }
+
+ let nodeType = null;
+ this.nodeData = null;
+ this.currentNode = null;
+ this.backgroundData = null;
+ this.frameData = null;
+ this.currentFrame = null;
+ if (target)
+ {
+ // Lookup the node in our stored data
+ let data = RequestNotifier.getDataForNode(target);
+ if (data && !data[1].filter)
+ {
+ [this.currentNode, this.nodeData] = data;
+ nodeType = this.nodeData.typeDescr;
+ }
+
+ let wnd = Utils.getWindow(target);
+
+ if (wnd.frameElement)
+ {
+ let data = RequestNotifier.getDataForNode(wnd.frameElement, true);
+ if (data && !data[1].filter)
+ [this.currentFrame, this.frameData] = data;
+ }
+
+ if (nodeType != "IMAGE")
+ {
+ // Look for a background image
+ let imageNode = target;
+ while (imageNode)
+ {
+ if (imageNode.nodeType == imageNode.ELEMENT_NODE)
+ {
+ let style = wnd.getComputedStyle(imageNode, "");
+ let bgImage = extractImageURL(style, "background-image") || extractImageURL(style, "list-style-image");
+ if (bgImage)
+ {
+ let data = RequestNotifier.getDataForNode(wnd.document, true, Policy.type.IMAGE, bgImage);
+ if (data && !data[1].filter)
+ {
+ this.backgroundData = data[1];
+ break;
+ }
+ }
+ }
+
+ imageNode = imageNode.parentNode;
+ }
+ }
+
+ // Hide "Block Images from ..." if hideimagemanager pref is true and the image manager isn't already blocking something
+ let imgManagerContext = this.E("context-blockimage");
+ if (imgManagerContext && shouldHideImageManager())
+ {
+ // Don't use "hidden" attribute - it might be overridden by the default popupshowing handler
+ imgManagerContext.collapsed = true;
+ }
+ }
+
+ this.E("abp-image-menuitem").hidden = (nodeType != "IMAGE" && this.backgroundData == null);
+ this.E("abp-object-menuitem").hidden = (nodeType != "OBJECT");
+ this.E("abp-media-menuitem").hidden = (nodeType != "MEDIA");
+ this.E("abp-frame-menuitem").hidden = (this.frameData == null);
+
+ let location = this.getCurrentLocation();
+ this.E("abp-removeWhitelist-menuitem").hidden = (!location || !Policy.isWhitelisted(location.spec));
+ },
+
+ /**
+ * Brings up the filter composer dialog to block an item.
+ */
+ blockItem: function(/**Node*/ node, /**RequestEntry*/ item)
+ {
+ if (!item)
+ return;
+
+ this.window.openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", [node], item);
+ }
};
/**
@@ -1322,30 +1322,30 @@ WindowWrapper.prototype =
* @type Array
*/
WindowWrapper.prototype.eventHandlers = [
- ["abp-tooltip", "popupshowing", WindowWrapper.prototype.fillTooltip],
- ["abp-status-popup", "popupshowing", WindowWrapper.prototype.fillPopup],
- ["abp-toolbar-popup", "popupshowing", WindowWrapper.prototype.fillPopup],
- ["abp-command-sendReport", "command", WindowWrapper.prototype.openReportDialog],
- ["abp-command-settings", "command", function() {Utils.openSettingsDialog();}],
- ["abp-command-sidebar", "command", WindowWrapper.prototype.toggleSidebar],
- ["abp-command-togglesitewhitelist", "command", function() { AppIntegration.toggleFilter(this.siteWhitelist); }],
- ["abp-command-togglepagewhitelist", "command", function() { AppIntegration.toggleFilter(this.pageWhitelist); }],
- ["abp-command-toggleobjtabs", "command", function() { AppIntegration.togglePref("frameobjects"); }],
- ["abp-command-togglecollapse", "command", function() { AppIntegration.togglePref("fastcollapse"); }],
- ["abp-command-togglesync", "command", AppIntegration.toggleSync],
- ["abp-command-toggleshowintoolbar", "command", function() { AppIntegration.togglePref("showintoolbar"); }],
- ["abp-command-toggleshowinstatusbar", "command", function() { AppIntegration.togglePref("showinstatusbar"); }],
- ["abp-command-enable", "command", function() { AppIntegration.togglePref("enabled"); }],
- ["abp-command-recommend", "command", WindowWrapper.prototype.recommend],
- ["abp-command-recommend-hide", "command", WindowWrapper.prototype.recommendHide],
- ["abp-toolbarbutton", "command", WindowWrapper.prototype.handleToolbarCommand],
- ["abp-toolbarbutton", "click", WindowWrapper.prototype.handleToolbarClick],
- ["abp-status", "click", WindowWrapper.prototype.handleStatusClick],
- ["abp-image-menuitem", "command", function() { this.backgroundData ? this.blockItem(null, this.backgroundData) : this.blockItem(this.currentNode, this.nodeData); }],
- ["abp-object-menuitem", "command", function() { this.blockItem(this.currentNode, this.nodeData); }],
- ["abp-media-menuitem", "command", function() { this.blockItem(this.currentNode, this.nodeData); }],
- ["abp-frame-menuitem", "command", function() { this.blockItem(this.currentFrame, this.frameData); }],
- ["abp-removeWhitelist-menuitem", "command", WindowWrapper.prototype.removeWhitelist]
+ ["abp-tooltip", "popupshowing", WindowWrapper.prototype.fillTooltip],
+ ["abp-status-popup", "popupshowing", WindowWrapper.prototype.fillPopup],
+ ["abp-toolbar-popup", "popupshowing", WindowWrapper.prototype.fillPopup],
+ ["abp-command-sendReport", "command", WindowWrapper.prototype.openReportDialog],
+ ["abp-command-settings", "command", function() {Utils.openSettingsDialog();}],
+ ["abp-command-sidebar", "command", WindowWrapper.prototype.toggleSidebar],
+ ["abp-command-togglesitewhitelist", "command", function() { AppIntegration.toggleFilter(this.siteWhitelist); }],
+ ["abp-command-togglepagewhitelist", "command", function() { AppIntegration.toggleFilter(this.pageWhitelist); }],
+ ["abp-command-toggleobjtabs", "command", function() { AppIntegration.togglePref("frameobjects"); }],
+ ["abp-command-togglecollapse", "command", function() { AppIntegration.togglePref("fastcollapse"); }],
+ ["abp-command-togglesync", "command", AppIntegration.toggleSync],
+ ["abp-command-toggleshowintoolbar", "command", function() { AppIntegration.togglePref("showintoolbar"); }],
+ ["abp-command-toggleshowinstatusbar", "command", function() { AppIntegration.togglePref("showinstatusbar"); }],
+ ["abp-command-enable", "command", function() { AppIntegration.togglePref("enabled"); }],
+ ["abp-command-recommend", "command", WindowWrapper.prototype.recommend],
+ ["abp-command-recommend-hide", "command", WindowWrapper.prototype.recommendHide],
+ ["abp-toolbarbutton", "command", WindowWrapper.prototype.handleToolbarCommand],
+ ["abp-toolbarbutton", "click", WindowWrapper.prototype.handleToolbarClick],
+ ["abp-status", "click", WindowWrapper.prototype.handleStatusClick],
+ ["abp-image-menuitem", "command", function() { this.backgroundData ? this.blockItem(null, this.backgroundData) : this.blockItem(this.currentNode, this.nodeData); }],
+ ["abp-object-menuitem", "command", function() { this.blockItem(this.currentNode, this.nodeData); }],
+ ["abp-media-menuitem", "command", function() { this.blockItem(this.currentNode, this.nodeData); }],
+ ["abp-frame-menuitem", "command", function() { this.blockItem(this.currentFrame, this.frameData); }],
+ ["abp-removeWhitelist-menuitem", "command", WindowWrapper.prototype.removeWhitelist]
];
/**
@@ -1354,16 +1354,16 @@ WindowWrapper.prototype.eventHandlers = [
*/
function reloadPrefs()
{
- if (currentlyShowingInToolbar != Prefs.showintoolbar)
- {
- currentlyShowingInToolbar = Prefs.showintoolbar;
- if (Prefs.showintoolbar)
- for each (let wrapper in wrappers)
- wrapper.installToolbarIcon();
- }
-
- for each (let wrapper in wrappers)
- wrapper.updateState();
+ if (currentlyShowingInToolbar != Prefs.showintoolbar)
+ {
+ currentlyShowingInToolbar = Prefs.showintoolbar;
+ if (Prefs.showintoolbar)
+ for each (let wrapper in wrappers)
+ wrapper.installToolbarIcon();
+ }
+
+ for each (let wrapper in wrappers)
+ wrapper.updateState();
}
/**
@@ -1372,31 +1372,31 @@ function reloadPrefs()
*/
function shouldHideImageManager()
{
- let result = false;
- if (Prefs.hideimagemanager && "@mozilla.org/permissionmanager;1" in Cc)
- {
- try
- {
- result = true;
- let enumerator = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager).enumerator;
- while (enumerator.hasMoreElements())
- {
- let item = enumerator.getNext().QueryInterface(Ci.nsIPermission);
- if (item.type == "image" && item.capability == Ci.nsIPermissionManager.DENY_ACTION)
- {
- result = false;
- break;
- }
- }
- }
- catch(e)
- {
- result = false;
- }
- }
-
- shouldHideImageManager = function() result;
- return result;
+ let result = false;
+ if (Prefs.hideimagemanager && "@mozilla.org/permissionmanager;1" in Cc)
+ {
+ try
+ {
+ result = true;
+ let enumerator = Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager).enumerator;
+ while (enumerator.hasMoreElements())
+ {
+ let item = enumerator.getNext().QueryInterface(Ci.nsIPermission);
+ if (item.type == "image" && item.capability == Ci.nsIPermissionManager.DENY_ACTION)
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+ catch(e)
+ {
+ result = false;
+ }
+ }
+
+ shouldHideImageManager = function() result;
+ return result;
}
/**
@@ -1405,28 +1405,28 @@ function shouldHideImageManager()
*/
function showSubscriptions()
{
- let wrapper = (wrappers.length ? wrappers[0] : null);
-
- // Don't annoy the user if he has a subscription already
- let hasSubscriptions = FilterStorage.subscriptions.some(function(subscription) subscription instanceof DownloadableSubscription);
- if (hasSubscriptions)
- return;
-
- // Only show the list if this is the first run or the user has no filters
- let hasFilters = FilterStorage.subscriptions.some(function(subscription) subscription.filters.length);
- if (hasFilters && Utils.versionComparator.compare(Prefs.lastVersion, "0.0") > 0)
- return;
-
- if (wrapper && wrapper.addTab)
- {
- wrapper.addTab("chrome://adblockplus/content/ui/subscriptionSelection.xul");
- }
- else
- {
- Utils.windowWatcher.openWindow(wrapper ? wrapper.window : null,
- "chrome://adblockplus/content/ui/subscriptionSelection.xul",
- "_blank", "chrome,centerscreen,resizable,dialog=no", null);
- }
+ let wrapper = (wrappers.length ? wrappers[0] : null);
+
+ // Don't annoy the user if he has a subscription already
+ let hasSubscriptions = FilterStorage.subscriptions.some(function(subscription) subscription instanceof DownloadableSubscription);
+ if (hasSubscriptions)
+ return;
+
+ // Only show the list if this is the first run or the user has no filters
+ let hasFilters = FilterStorage.subscriptions.some(function(subscription) subscription.filters.length);
+ if (hasFilters && Utils.versionComparator.compare(Prefs.lastVersion, "0.0") > 0)
+ return;
+
+ if (wrapper && wrapper.addTab)
+ {
+ wrapper.addTab("chrome://adblockplus/content/ui/subscriptionSelection.xul");
+ }
+ else
+ {
+ Utils.windowWatcher.openWindow(wrapper ? wrapper.window : null,
+ "chrome://adblockplus/content/ui/subscriptionSelection.xul",
+ "_blank", "chrome,centerscreen,resizable,dialog=no", null);
+ }
}
/**
@@ -1434,13 +1434,13 @@ function showSubscriptions()
*/
function extractImageURL(/**CSSStyleDeclaration*/ computedStyle, /**String*/ property)
{
- let value = computedStyle.getPropertyCSSValue(property);
- if (value instanceof Ci.nsIDOMCSSValueList && value.length >= 1)
- value = value[0];
- if (value instanceof Ci.nsIDOMCSSPrimitiveValue && value.primitiveType == Ci.nsIDOMCSSPrimitiveValue.CSS_URI)
- return Utils.unwrapURL(value.getStringValue()).spec;
+ let value = computedStyle.getPropertyCSSValue(property);
+ if (value instanceof Ci.nsIDOMCSSValueList && value.length >= 1)
+ value = value[0];
+ if (value instanceof Ci.nsIDOMCSSPrimitiveValue && value.primitiveType == Ci.nsIDOMCSSPrimitiveValue.CSS_URI)
+ return Utils.unwrapURL(value.getStringValue()).spec;
- return null;
+ return null;
}
init();
diff --git a/modules/AppIntegrationFennec.jsm b/modules/AppIntegrationFennec.jsm
index 8c879c2..d6b6161 100644
--- a/modules/AppIntegrationFennec.jsm
+++ b/modules/AppIntegrationFennec.jsm
@@ -56,15 +56,15 @@ let PolicyPrivate = Cu.import(baseURL.spec + "ContentPolicy.jsm", null).PolicyPr
*/
function FakeWindow(/**String*/ location, /**FakeNode*/ document, /**FakeWindow*/ top)
{
- this._location = location;
- this._top = top;
- this.document = document;
+ this._location = location;
+ this._top = top;
+ this.document = document;
}
FakeWindow.prototype =
{
- get location() this,
- get href() this._location,
- get top() this._top || this
+ get location() this,
+ get href() this._location,
+ get top() this._top || this
}
/**
@@ -74,14 +74,14 @@ FakeWindow.prototype =
*/
function FakeNode(/**String*/ wndLocation, /**String*/ topLocation)
{
- let topWnd = new FakeWindow(topLocation, this, null);
- this.defaultView = new FakeWindow(wndLocation, this, topWnd);
+ let topWnd = new FakeWindow(topLocation, this, null);
+ this.defaultView = new FakeWindow(wndLocation, this, topWnd);
}
FakeNode.prototype =
{
- get ownerDocument() this,
- getUserData: function() {return null},
- setUserData: function() {}
+ get ownerDocument() this,
+ getUserData: function() {return null},
+ setUserData: function() {}
}
let needPostProcess = false;
@@ -93,75 +93,75 @@ let needPostProcess = false;
*/
function postProcessReplacement(node)
{
- needPostProcess = true;
+ needPostProcess = true;
}
try
{
- Utils.parentMessageManager.addMessageListener("AdblockPlus:Policy:shouldLoad", function(message)
- {
- // Replace Utils.schedulePostProcess() to learn whether our node is scheduled for post-processing
- let oldPostProcess = Utils.schedulePostProcess;
- needPostProcess = false;
- Utils.schedulePostProcess = postProcessReplacement;
-
- try
- {
- let data = message.json;
- let fakeNode = new FakeNode(data.wndLocation, data.topLocation);
- let result = PolicyPrivate.shouldLoad(data.contentType, data.contentLocation, null, fakeNode);
- return {value: result, postProcess: needPostProcess};
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- finally
- {
- Utils.schedulePostProcess = oldPostProcess;
- }
- });
-
- Utils.parentMessageManager.addMessageListener("AdblockPlus:ElemHide:styleURL", function(message)
- {
- return ElemHide.styleURL;
- });
-
- Utils.parentMessageManager.addMessageListener("AdblockPlus:ElemHide:checkHit", function(message)
- {
- try
- {
- let data = message.json;
- let filter = ElemHide.getFilterByKey(data.key);
- if (!filter)
- return false;
-
- let fakeNode = new FakeNode(data.wndLocation, data.topLocation);
- return !Policy.processNode(fakeNode.defaultView, fakeNode, Policy.type.ELEMHIDE, filter);
- }
- catch (e)
- {
- Cu.reportError(e);
- }
-
- return ElemHide.styleURL;
- });
-
- // Trigger update in child processes if elemhide stylesheet or matcher data change
- FilterStorage.addObserver(function(action)
- {
- if (action == "elemhideupdate")
- Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:ElemHide:updateStyleURL", ElemHide.styleURL);
- else if (/^(filters|subscriptions) (add|remove|enable|disable|update)$/.test(action))
- Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:Matcher:clearCache");
- });
-
- // Trigger update in child processes if enable or fastcollapse preferences change
- Prefs.addListener(function(name)
- {
- if (name == "enabled" || name == "fastcollapse")
- Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:Matcher:clearCache");
- });
+ Utils.parentMessageManager.addMessageListener("AdblockPlus:Policy:shouldLoad", function(message)
+ {
+ // Replace Utils.schedulePostProcess() to learn whether our node is scheduled for post-processing
+ let oldPostProcess = Utils.schedulePostProcess;
+ needPostProcess = false;
+ Utils.schedulePostProcess = postProcessReplacement;
+
+ try
+ {
+ let data = message.json;
+ let fakeNode = new FakeNode(data.wndLocation, data.topLocation);
+ let result = PolicyPrivate.shouldLoad(data.contentType, data.contentLocation, null, fakeNode);
+ return {value: result, postProcess: needPostProcess};
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ finally
+ {
+ Utils.schedulePostProcess = oldPostProcess;
+ }
+ });
+
+ Utils.parentMessageManager.addMessageListener("AdblockPlus:ElemHide:styleURL", function(message)
+ {
+ return ElemHide.styleURL;
+ });
+
+ Utils.parentMessageManager.addMessageListener("AdblockPlus:ElemHide:checkHit", function(message)
+ {
+ try
+ {
+ let data = message.json;
+ let filter = ElemHide.getFilterByKey(data.key);
+ if (!filter)
+ return false;
+
+ let fakeNode = new FakeNode(data.wndLocation, data.topLocation);
+ return !Policy.processNode(fakeNode.defaultView, fakeNode, Policy.type.ELEMHIDE, filter);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+
+ return ElemHide.styleURL;
+ });
+
+ // Trigger update in child processes if elemhide stylesheet or matcher data change
+ FilterStorage.addObserver(function(action)
+ {
+ if (action == "elemhideupdate")
+ Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:ElemHide:updateStyleURL", ElemHide.styleURL);
+ else if (/^(filters|subscriptions) (add|remove|enable|disable|update)$/.test(action))
+ Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:Matcher:clearCache");
+ });
+
+ // Trigger update in child processes if enable or fastcollapse preferences change
+ Prefs.addListener(function(name)
+ {
+ if (name == "enabled" || name == "fastcollapse")
+ Utils.parentMessageManager.sendAsyncMessage("AdblockPlus:Matcher:clearCache");
+ });
} catch(e) {} // Ignore errors if we are not running in a multi-process setup
@@ -171,240 +171,240 @@ try
*/
var AppIntegrationFennec =
{
- initWindow: function(wrapper)
- {
- if ("messageManager" in wrapper.window)
- {
- // Multi-process setup - we need to inject our content script into all tabs
- let browsers = wrapper.window.Browser.browsers;
- for (let i = 0; i < browsers.length; i++)
- browsers[i].messageManager.loadFrameScript("chrome://adblockplus/content/fennecContent.js", true);
- wrapper.E("tabs").addEventListener("TabOpen", function(event)
- {
- let tab = wrapper.window.Browser.getTabFromChrome(event.originalTarget);
- tab.browser.messageManager.loadFrameScript("chrome://adblockplus/content/fennecContent.js", true);
- }, false);
-
- // Get notified about abp: link clicks for this window
- wrapper.window.messageManager.addMessageListener("AdblockPlus:LinkClick", function(message)
- {
- wrapper.handleLinkClick(null, message.json);
- });
- }
-
- if (typeof wrapper.window.IdentityHandler == "function" && typeof wrapper.window.IdentityHandler.prototype.show == "function")
- {
- // HACK: Hook IdentityHandler.show() to init our UI
- let oldShow = wrapper.window.IdentityHandler.prototype.show;
- wrapper.window.IdentityHandler.prototype.show = function()
- {
- try
- {
- updateFennecStatusUI(wrapper);
- }
- finally
- {
- oldShow.apply(this, arguments);
- }
- }
- }
-
- wrapper.E("addons-list").addEventListener("AddonOptionsLoad", function(event)
- {
- onCreateOptions(wrapper, event)
- }, false);
- },
-
- openFennecSubscriptionDialog: function(/**WindowWrapper*/ wrapper, /**String*/ url, /**String*/ title)
- {
- wrapper.window.importDialog(null, "chrome://adblockplus/content/ui/fennecSubscription.xul");
-
- // Copied from Fennec's PromptService.js
- // add a width style to prevent a element to grow larger
- // than the screen width
- function sizeElement(id, percent)
- {
- let elem = wrapper.E(id);
- let screenW = wrapper.E("main-window").getBoundingClientRect().width;
- elem.style.width = screenW * percent / 100 + "px"
- }
-
- // size the height of the scrollable message. this assumes the given element
- // is a child of a scrollbox
- function sizeScrollableMsg(id, percent)
- {
- let screenH = wrapper.E("main-window").getBoundingClientRect().height;
- let maxHeight = screenH * percent / 100;
-
- let elem = wrapper.E(id);
- let style = wrapper.window.getComputedStyle(elem, null);
- let height = Math.ceil(elem.getBoundingClientRect().height) +
- parseInt(style.marginTop) +
- parseInt(style.marginBottom);
-
- if (height > maxHeight)
- height = maxHeight;
- elem.parentNode.style.height = height + "px";
- }
-
- sizeElement("abp-subscription-title", 50);
- wrapper.E("abp-subscription-title").textContent = title;
-
- sizeElement("abp-subscription-url", 50);
- wrapper.E("abp-subscription-url").textContent = url;
- sizeScrollableMsg("abp-subscription-url", 50);
-
- wrapper.E("abp-subscription-cmd-ok").addEventListener("command", function()
- {
- setSubscription(url, title);
- wrapper.E("abpEditSubscription").close();
- }, false);
-
- wrapper.E("abp-subscription-btn-ok").focus();
- }
+ initWindow: function(wrapper)
+ {
+ if ("messageManager" in wrapper.window)
+ {
+ // Multi-process setup - we need to inject our content script into all tabs
+ let browsers = wrapper.window.Browser.browsers;
+ for (let i = 0; i < browsers.length; i++)
+ browsers[i].messageManager.loadFrameScript("chrome://adblockplus/content/fennecContent.js", true);
+ wrapper.E("tabs").addEventListener("TabOpen", function(event)
+ {
+ let tab = wrapper.window.Browser.getTabFromChrome(event.originalTarget);
+ tab.browser.messageManager.loadFrameScript("chrome://adblockplus/content/fennecContent.js", true);
+ }, false);
+
+ // Get notified about abp: link clicks for this window
+ wrapper.window.messageManager.addMessageListener("AdblockPlus:LinkClick", function(message)
+ {
+ wrapper.handleLinkClick(null, message.json);
+ });
+ }
+
+ if (typeof wrapper.window.IdentityHandler == "function" && typeof wrapper.window.IdentityHandler.prototype.show == "function")
+ {
+ // HACK: Hook IdentityHandler.show() to init our UI
+ let oldShow = wrapper.window.IdentityHandler.prototype.show;
+ wrapper.window.IdentityHandler.prototype.show = function()
+ {
+ try
+ {
+ updateFennecStatusUI(wrapper);
+ }
+ finally
+ {
+ oldShow.apply(this, arguments);
+ }
+ }
+ }
+
+ wrapper.E("addons-list").addEventListener("AddonOptionsLoad", function(event)
+ {
+ onCreateOptions(wrapper, event)
+ }, false);
+ },
+
+ openFennecSubscriptionDialog: function(/**WindowWrapper*/ wrapper, /**String*/ url, /**String*/ title)
+ {
+ wrapper.window.importDialog(null, "chrome://adblockplus/content/ui/fennecSubscription.xul");
+
+ // Copied from Fennec's PromptService.js
+ // add a width style to prevent a element to grow larger
+ // than the screen width
+ function sizeElement(id, percent)
+ {
+ let elem = wrapper.E(id);
+ let screenW = wrapper.E("main-window").getBoundingClientRect().width;
+ elem.style.width = screenW * percent / 100 + "px"
+ }
+
+ // size the height of the scrollable message. this assumes the given element
+ // is a child of a scrollbox
+ function sizeScrollableMsg(id, percent)
+ {
+ let screenH = wrapper.E("main-window").getBoundingClientRect().height;
+ let maxHeight = screenH * percent / 100;
+
+ let elem = wrapper.E(id);
+ let style = wrapper.window.getComputedStyle(elem, null);
+ let height = Math.ceil(elem.getBoundingClientRect().height) +
+ parseInt(style.marginTop) +
+ parseInt(style.marginBottom);
+
+ if (height > maxHeight)
+ height = maxHeight;
+ elem.parentNode.style.height = height + "px";
+ }
+
+ sizeElement("abp-subscription-title", 50);
+ wrapper.E("abp-subscription-title").textContent = title;
+
+ sizeElement("abp-subscription-url", 50);
+ wrapper.E("abp-subscription-url").textContent = url;
+ sizeScrollableMsg("abp-subscription-url", 50);
+
+ wrapper.E("abp-subscription-cmd-ok").addEventListener("command", function()
+ {
+ setSubscription(url, title);
+ wrapper.E("abpEditSubscription").close();
+ }, false);
+
+ wrapper.E("abp-subscription-btn-ok").focus();
+ }
};
function onCreateOptions(wrapper, event)
{
- if (event.originalTarget.getAttribute("addonID") != "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}")
- return;
-
- wrapper.E("adblockplus-subscription-list").addEventListener("command", function(event)
- {
- let menu = event.target;
- if (menu.value)
- setSubscription(menu.value, menu.label);
- }, false);
-
- let syncSetting = wrapper.E("adblockplus-sync");
- let syncEngine = Sync.getEngine();
- syncSetting.hidden = !syncEngine;
- syncSetting.value = syncEngine.enabled;
- wrapper.E("adblockplus-sync").addEventListener("command", AppIntegration.toggleSync, false);
-
- let updateFunction = function(action, items)
- {
- if (/^subscriptions\b/.test(action))
- updateSubscriptionList(wrapper);
- }
- updateFunction("subscriptions");
- FilterStorage.addObserver(updateFunction);
-
- wrapper.window.addEventListener("unload", function()
- {
- FilterStorage.removeObserver(updateFunction);
- }, false);
+ if (event.originalTarget.getAttribute("addonID") != "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}")
+ return;
+
+ wrapper.E("adblockplus-subscription-list").addEventListener("command", function(event)
+ {
+ let menu = event.target;
+ if (menu.value)
+ setSubscription(menu.value, menu.label);
+ }, false);
+
+ let syncSetting = wrapper.E("adblockplus-sync");
+ let syncEngine = Sync.getEngine();
+ syncSetting.hidden = !syncEngine;
+ syncSetting.value = syncEngine.enabled;
+ wrapper.E("adblockplus-sync").addEventListener("command", AppIntegration.toggleSync, false);
+
+ let updateFunction = function(action, items)
+ {
+ if (/^subscriptions\b/.test(action))
+ updateSubscriptionList(wrapper);
+ }
+ updateFunction("subscriptions");
+ FilterStorage.addObserver(updateFunction);
+
+ wrapper.window.addEventListener("unload", function()
+ {
+ FilterStorage.removeObserver(updateFunction);
+ }, false);
}
function updateSubscriptionList(wrapper)
{
- let currentSubscription = FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription);
- currentSubscription = (currentSubscription.length ? currentSubscription[0] : null);
-
- let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIJSXMLHttpRequest);
- xhr.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml", false);
- xhr.send(null);
- if (!xhr.responseXML)
- return;
-
- let menu = wrapper.E("adblockplus-subscription-list");
- menu.removeAllItems();
-
- let subscriptions = xhr.responseXML.documentElement.getElementsByTagName("subscription");
- for (let i = 0; i < subscriptions.length; i++)
- {
- let item = subscriptions[i];
- let url = item.getAttribute("url");
- if (!url)
- continue;
-
- menu.appendItem(item.getAttribute("title"), url, null);
- if (currentSubscription && url == currentSubscription.url)
- menu.selectedIndex = menu.itemCount - 1;
- }
-
- if (currentSubscription && menu.selectedIndex < 0)
- {
- menu.appendItem(currentSubscription.title, currentSubscription.url, null);
- menu.selectedIndex = menu.itemCount - 1;
- }
+ let currentSubscription = FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription);
+ currentSubscription = (currentSubscription.length ? currentSubscription[0] : null);
+
+ let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIJSXMLHttpRequest);
+ xhr.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml", false);
+ xhr.send(null);
+ if (!xhr.responseXML)
+ return;
+
+ let menu = wrapper.E("adblockplus-subscription-list");
+ menu.removeAllItems();
+
+ let subscriptions = xhr.responseXML.documentElement.getElementsByTagName("subscription");
+ for (let i = 0; i < subscriptions.length; i++)
+ {
+ let item = subscriptions[i];
+ let url = item.getAttribute("url");
+ if (!url)
+ continue;
+
+ menu.appendItem(item.getAttribute("title"), url, null);
+ if (currentSubscription && url == currentSubscription.url)
+ menu.selectedIndex = menu.itemCount - 1;
+ }
+
+ if (currentSubscription && menu.selectedIndex < 0)
+ {
+ menu.appendItem(currentSubscription.title, currentSubscription.url, null);
+ menu.selectedIndex = menu.itemCount - 1;
+ }
}
-
+
function setSubscription(url, title)
{
- let currentSubscription = FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription);
- currentSubscription = (currentSubscription.length ? currentSubscription[0] : null);
- if (currentSubscription && currentSubscription.url == url)
- return;
+ let currentSubscription = FilterStorage.subscriptions.filter(function(subscription) subscription instanceof DownloadableSubscription);
+ currentSubscription = (currentSubscription.length ? currentSubscription[0] : null);
+ if (currentSubscription && currentSubscription.url == url)
+ return;
- // We only allow one subscription, remove existing one before adding
- if (currentSubscription)
- FilterStorage.removeSubscription(currentSubscription);
+ // We only allow one subscription, remove existing one before adding
+ if (currentSubscription)
+ FilterStorage.removeSubscription(currentSubscription);
- currentSubscription = Subscription.fromURL(url);
- currentSubscription.title = title;
+ currentSubscription = Subscription.fromURL(url);
+ currentSubscription.title = title;
- FilterStorage.addSubscription(currentSubscription);
- Synchronizer.execute(currentSubscription, false);
- FilterStorage.saveToDisk();
+ FilterStorage.addSubscription(currentSubscription);
+ Synchronizer.execute(currentSubscription, false);
+ FilterStorage.saveToDisk();
}
function updateFennecStatusUI(wrapper)
{
- let siteInfo = wrapper.E("abp-site-info");
- siteInfo.addEventListener("click", toggleFennecWhitelist, false);
-
- let status = "disabled";
- let host = null;
- if (Prefs.enabled)
- {
- status = "enabled";
- let location = wrapper.getCurrentLocation();
- if (location instanceof Ci.nsIURL && Policy.isBlockableScheme(location))
- {
- try
- {
- host = location.host.replace(/^www\./, "");
- } catch (e) {}
- }
-
- if (host && Policy.isWhitelisted(location.spec))
- status = "disabled_site";
- else if (host)
- status = "enabled_site";
- }
-
- let statusText = Utils.getString("fennec_status_" + status);
- if (host)
- statusText = statusText.replace(/\?1\?/g, host);
-
- siteInfo.setAttribute("title", statusText);
- siteInfo.setAttribute("abpstate", status);
+ let siteInfo = wrapper.E("abp-site-info");
+ siteInfo.addEventListener("click", toggleFennecWhitelist, false);
+
+ let status = "disabled";
+ let host = null;
+ if (Prefs.enabled)
+ {
+ status = "enabled";
+ let location = wrapper.getCurrentLocation();
+ if (location instanceof Ci.nsIURL && Policy.isBlockableScheme(location))
+ {
+ try
+ {
+ host = location.host.replace(/^www\./, "");
+ } catch (e) {}
+ }
+
+ if (host && Policy.isWhitelisted(location.spec))
+ status = "disabled_site";
+ else if (host)
+ status = "enabled_site";
+ }
+
+ let statusText = Utils.getString("fennec_status_" + status);
+ if (host)
+ statusText = statusText.replace(/\?1\?/g, host);
+
+ siteInfo.setAttribute("title", statusText);
+ siteInfo.setAttribute("abpstate", status);
}
function toggleFennecWhitelist(event)
{
- if (!Prefs.enabled)
- return;
-
- let wrapper = AppIntegration.getWrapperForWindow(event.target.ownerDocument.defaultView);
- let location = wrapper.getCurrentLocation();
- let host = null;
- if (location instanceof Ci.nsIURL && Policy.isBlockableScheme(location))
- {
- try
- {
- host = location.host.replace(/^www\./, "");
- } catch (e) {}
- }
-
- if (!host)
- return;
-
- if (Policy.isWhitelisted(location.spec))
- wrapper.removeWhitelist();
- else
- AppIntegration.toggleFilter(Filter.fromText("@@||" + host + "^$document"));
-
- updateFennecStatusUI(wrapper);
+ if (!Prefs.enabled)
+ return;
+
+ let wrapper = AppIntegration.getWrapperForWindow(event.target.ownerDocument.defaultView);
+ let location = wrapper.getCurrentLocation();
+ let host = null;
+ if (location instanceof Ci.nsIURL && Policy.isBlockableScheme(location))
+ {
+ try
+ {
+ host = location.host.replace(/^www\./, "");
+ } catch (e) {}
+ }
+
+ if (!host)
+ return;
+
+ if (Policy.isWhitelisted(location.spec))
+ wrapper.removeWhitelist();
+ else
+ AppIntegration.toggleFilter(Filter.fromText("@@||" + host + "^$document"));
+
+ updateFennecStatusUI(wrapper);
}
diff --git a/modules/Bootstrap.jsm b/modules/Bootstrap.jsm
index 5c0e77f..48dd110 100644
--- a/modules/Bootstrap.jsm
+++ b/modules/Bootstrap.jsm
@@ -43,26 +43,26 @@ baseURL.fileName = "";
try
{
- // Gecko 2.0 and higher - chrome URLs can be loaded directly
- Cu.import(baseURL.spec + "Utils.jsm");
- Cu.import(baseURL.spec + "TimeLine.jsm");
+ // Gecko 2.0 and higher - chrome URLs can be loaded directly
+ Cu.import(baseURL.spec + "Utils.jsm");
+
}
catch (e)
{
- // Gecko 1.9.x - have to convert chrome URLs to file URLs first
- let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
- publicURL = chromeRegistry.convertChromeURL(publicURL);
- baseURL = chromeRegistry.convertChromeURL(baseURL);
- Cu.import(baseURL.spec + "Utils.jsm");
- Cu.import(baseURL.spec + "TimeLine.jsm");
- chromeSupported = false;
+ // Gecko 1.9.x - have to convert chrome URLs to file URLs first
+ let chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);
+ publicURL = chromeRegistry.convertChromeURL(publicURL);
+ baseURL = chromeRegistry.convertChromeURL(baseURL);
+ Cu.import(baseURL.spec + "Utils.jsm");
+
+ chromeSupported = false;
}
if (publicURL instanceof Ci.nsIMutable)
- publicURL.mutable = false;
+ publicURL.mutable = false;
if (baseURL instanceof Ci.nsIMutable)
- baseURL.mutable = false;
-
+ baseURL.mutable = false;
+
const cidPublic = Components.ID("5e447bce-1dd2-11b2-b151-ec21c2b6a135");
const contractIDPublic = "@adblockplus.org/abp/public;1";
@@ -70,29 +70,30 @@ const cidPrivate = Components.ID("2f1e0288-1dd2-11b2-bbfe-d7b8a982508e");
const contractIDPrivate = "@adblockplus.org/abp/private;1";
let factoryPublic = {
- createInstance: function(outer, iid)
- {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return publicURL.QueryInterface(iid);
- }
+ createInstance: function(outer, iid)
+ {
+ if (outer)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return publicURL.QueryInterface(iid);
+ }
};
let factoryPrivate = {
- createInstance: function(outer, iid)
- {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return baseURL.QueryInterface(iid);
- }
+ createInstance: function(outer, iid)
+ {
+ if (outer)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return baseURL.QueryInterface(iid);
+ }
};
let defaultModules = [
- baseURL.spec + "Prefs.jsm",
- baseURL.spec + "FilterListener.jsm",
- baseURL.spec + "ContentPolicy.jsm",
- baseURL.spec + "Synchronizer.jsm",
- baseURL.spec + "Sync.jsm"
+ baseURL.spec + "Prefs.jsm",
+ baseURL.spec + "FilterListener.jsm",
+ baseURL.spec + "ContentPolicy.jsm",
+ baseURL.spec + "Synchronizer.jsm",
+ baseURL.spec + "Survey.jsm",
+ baseURL.spec + "Sync.jsm"
];
let loadedModules = {__proto__: null};
@@ -105,127 +106,127 @@ let initialized = false;
*/
var Bootstrap =
{
- /**
- * Initializes add-on, loads and initializes all modules.
- */
- startup: function()
- {
- if (initialized)
- return;
- initialized = true;
-
- TimeLine.enter("Entered Bootstrap.startup()");
-
- // Register component to allow retrieving private and public URL
-
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.registerFactory(cidPublic, "Adblock Plus public module URL", contractIDPublic, factoryPublic);
- registrar.registerFactory(cidPrivate, "Adblock Plus private module URL", contractIDPrivate, factoryPrivate);
-
- TimeLine.log("done registering URL components");
-
- // Load and initialize modules
-
- TimeLine.log("started initializing default modules");
-
- for each (let url in defaultModules)
- Bootstrap.loadModule(url);
-
- TimeLine.log("initializing additional modules");
-
- let categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
- let enumerator = categoryManager.enumerateCategory("adblock-plus-module-location");
- while (enumerator.hasMoreElements())
- {
- let uri = enumerator.getNext().QueryInterface(Ci.nsISupportsCString).data;
- Bootstrap.loadModule(uri);
- }
-
- let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- observerService.addObserver(BootstrapPrivate, "xpcom-category-entry-added", true);
- observerService.addObserver(BootstrapPrivate, "xpcom-category-entry-removed", true);
-
- TimeLine.leave("Bootstrap.startup() done");
- },
-
- /**
- * Shuts down add-on.
- */
- shutdown: function()
- {
- if (!initialized)
- return;
-
- TimeLine.enter("Entered Bootstrap.shutdown()");
-
- // Shut down modules
- for (let url in loadedModules)
- Bootstrap.shutdownModule(url);
-
- TimeLine.leave("Bootstrap.shutdown() done");
- },
-
- /**
- * Loads and initializes a module.
- */
- loadModule: function(/**String*/ url)
- {
- if (url in loadedModules)
- return;
-
- let module = {};
- try
- {
- Cu.import(url, module);
- }
- catch (e)
- {
- Cu.reportError("Adblock Plus: Failed to load module " + url + ": " + e);
- return;
- }
-
- for each (let obj in module)
- {
- if ("startup" in obj)
- {
- try
- {
- obj.startup();
- loadedModules[url] = obj;
- }
- catch (e)
- {
- Cu.reportError("Adblock Plus: Calling method startup() for module " + url + " failed: " + e);
- }
- return;
- }
- }
-
- Cu.reportError("Adblock Plus: No exported object with startup() method found for module " + url);
- },
-
- /**
- * Shuts down a module.
- */
- shutdownModule: function(/**String*/ url)
- {
- if (!(url in loadedModules))
- return;
-
- let obj = loadedModules[url];
- if ("shutdown" in obj)
- {
- try
- {
- obj.shutdown();
- }
- catch (e)
- {
- Cu.reportError("Adblock Plus: Calling method shutdown() for module " + url + " failed: " + e);
- }
- return;
- }
- }
+ /**
+ * Initializes add-on, loads and initializes all modules.
+ */
+ startup: function()
+ {
+ if (initialized)
+ return;
+ initialized = true;
+
+
+
+ // Register component to allow retrieving private and public URL
+
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(cidPublic, "Adblock Plus public module URL", contractIDPublic, factoryPublic);
+ registrar.registerFactory(cidPrivate, "Adblock Plus private module URL", contractIDPrivate, factoryPrivate);
+
+
+
+ // Load and initialize modules
+
+
+
+ for each (let url in defaultModules)
+ Bootstrap.loadModule(url);
+
+
+
+ let categoryManager = Cc["@mozilla.org/categorymanager;1"].getService(Ci.nsICategoryManager);
+ let enumerator = categoryManager.enumerateCategory("adblock-plus-module-location");
+ while (enumerator.hasMoreElements())
+ {
+ let uri = enumerator.getNext().QueryInterface(Ci.nsISupportsCString).data;
+ Bootstrap.loadModule(uri);
+ }
+
+ let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ observerService.addObserver(BootstrapPrivate, "xpcom-category-entry-added", true);
+ observerService.addObserver(BootstrapPrivate, "xpcom-category-entry-removed", true);
+
+
+ },
+
+ /**
+ * Shuts down add-on.
+ */
+ shutdown: function()
+ {
+ if (!initialized)
+ return;
+
+
+
+ // Shut down modules
+ for (let url in loadedModules)
+ Bootstrap.shutdownModule(url);
+
+
+ },
+
+ /**
+ * Loads and initializes a module.
+ */
+ loadModule: function(/**String*/ url)
+ {
+ if (url in loadedModules)
+ return;
+
+ let module = {};
+ try
+ {
+ Cu.import(url, module);
+ }
+ catch (e)
+ {
+ Cu.reportError("Adblock Plus: Failed to load module " + url + ": " + e);
+ return;
+ }
+
+ for each (let obj in module)
+ {
+ if ("startup" in obj)
+ {
+ try
+ {
+ obj.startup();
+ loadedModules[url] = obj;
+ }
+ catch (e)
+ {
+ Cu.reportError("Adblock Plus: Calling method startup() for module " + url + " failed: " + e);
+ }
+ return;
+ }
+ }
+
+ Cu.reportError("Adblock Plus: No exported object with startup() method found for module " + url);
+ },
+
+ /**
+ * Shuts down a module.
+ */
+ shutdownModule: function(/**String*/ url)
+ {
+ if (!(url in loadedModules))
+ return;
+
+ let obj = loadedModules[url];
+ if ("shutdown" in obj)
+ {
+ try
+ {
+ obj.shutdown();
+ }
+ catch (e)
+ {
+ Cu.reportError("Adblock Plus: Calling method shutdown() for module " + url + " failed: " + e);
+ }
+ return;
+ }
+ }
};
/**
@@ -234,21 +235,21 @@ var Bootstrap =
*/
var BootstrapPrivate =
{
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
-
- observe: function(subject, topic, data)
- {
- if (data != "adblock-plus-module-location")
- return;
-
- switch (topic)
- {
- case "xpcom-category-entry-added":
- Bootstrap.loadModule(subject.QueryInterface(Ci.nsISupportsCString).data);
- break;
- case "xpcom-category-entry-removed":
- Bootstrap.unloadModule(subject.QueryInterface(Ci.nsISupportsCString).data, true);
- break;
- }
- }
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
+
+ observe: function(subject, topic, data)
+ {
+ if (data != "adblock-plus-module-location")
+ return;
+
+ switch (topic)
+ {
+ case "xpcom-category-entry-added":
+ Bootstrap.loadModule(subject.QueryInterface(Ci.nsISupportsCString).data);
+ break;
+ case "xpcom-category-entry-removed":
+ Bootstrap.unloadModule(subject.QueryInterface(Ci.nsISupportsCString).data, true);
+ break;
+ }
+ }
};
diff --git a/modules/ContentPolicy.jsm b/modules/ContentPolicy.jsm
index 7c6a959..b07b8c5 100644
--- a/modules/ContentPolicy.jsm
+++ b/modules/ContentPolicy.jsm
@@ -36,7 +36,7 @@ const Cu = Components.utils;
let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
Cu.import(baseURL.spec + "Utils.jsm");
Cu.import(baseURL.spec + "Prefs.jsm");
Cu.import(baseURL.spec + "FilterStorage.jsm");
@@ -63,256 +63,256 @@ const nonVisualTypes = ["SCRIPT", "STYLESHEET", "XBL", "PING", "XMLHTTPREQUEST",
*/
var Policy =
{
- /**
- * Map of content type identifiers by their name.
- * @type Object
- */
- type: {},
-
- /**
- * Map of content type names by their identifiers (reverse of type map).
- * @type Object
- */
- typeDescr: {},
-
- /**
- * Map of localized content type names by their identifiers.
- * @type Object
- */
- localizedDescr: {},
-
- /**
- * Lists the non-visual content types.
- * @type Object
- */
- nonVisual: {},
-
- /**
- * Map containing all schemes that should be ignored by content policy.
- * @type Object
- */
- whitelistSchemes: {},
-
- /**
- * Called on module startup.
- */
- startup: function()
- {
- TimeLine.enter("Entered ContentPolicy.startup()");
-
- // type constant by type description and type description by type constant
- var iface = Ci.nsIContentPolicy;
- for each (let typeName in contentTypes)
- {
- if ("TYPE_" + typeName in iface)
- {
- let id = iface["TYPE_" + typeName];
- Policy.type[typeName] = id;
- Policy.typeDescr[id] = typeName;
- Policy.localizedDescr[id] = Utils.getString("type_label_" + typeName.toLowerCase());
- }
- }
-
- Policy.type.ELEMHIDE = 0xFFFD;
- Policy.typeDescr[0xFFFD] = "ELEMHIDE";
- Policy.localizedDescr[0xFFFD] = Utils.getString("type_label_elemhide");
-
- for each (let type in nonVisualTypes)
- Policy.nonVisual[Policy.type[type]] = true;
-
- // whitelisted URL schemes
- for each (var scheme in Prefs.whitelistschemes.toLowerCase().split(" "))
- Policy.whitelistSchemes[scheme] = true;
-
- TimeLine.log("done initializing types");
-
- // Generate class identifier used to collapse node and register corresponding
- // stylesheet.
- TimeLine.log("registering global stylesheet");
-
- let offset = "a".charCodeAt(0);
- Utils.collapsedClass = "";
- for (let i = 0; i < 20; i++)
- Utils.collapsedClass += String.fromCharCode(offset + Math.random() * 26);
-
- let collapseStyle = Utils.makeURI("data:text/css," +
- encodeURIComponent("." + Utils.collapsedClass +
- "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarbazdummy) !important;}"));
- Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
- TimeLine.log("done registering stylesheet");
-
- // Register our content policy
- TimeLine.log("registering component");
-
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- try
- {
- registrar.registerFactory(PolicyPrivate.classID, PolicyPrivate.classDescription, PolicyPrivate.contractID, PolicyPrivate);
- }
- catch (e)
- {
- // Don't stop on errors - the factory might already be registered
- Cu.reportError(e);
- }
-
- let catMan = Utils.categoryManager;
- for each (let category in PolicyPrivate.xpcom_categories)
- catMan.addCategoryEntry(category, PolicyPrivate.classDescription, PolicyPrivate.contractID, false, true);
-
- Utils.observerService.addObserver(PolicyPrivate, "http-on-modify-request", true);
-
- TimeLine.leave("ContentPolicy.startup() done");
- },
-
- shutdown: function()
- {
- PolicyPrivate.previousRequest = null;
- },
-
- /**
- * Checks whether a node should be blocked, hides it if necessary
- * @param wnd {nsIDOMWindow}
- * @param node {nsIDOMElement}
- * @param contentType {String}
- * @param location {nsIURI}
- * @param collapse {Boolean} true to force hiding of the node
- * @return {Boolean} false if the node should be blocked
- */
- processNode: function(wnd, node, contentType, location, collapse)
- {
- let topWnd = wnd.top;
- if (!topWnd || !topWnd.location || !topWnd.location.href)
- return true;
-
- let match = null;
- if (!match && Prefs.enabled)
- {
- match = Policy.isWindowWhitelisted(topWnd);
- if (match)
- {
- FilterStorage.increaseHitCount(match);
- return true;
- }
- }
-
- // Data loaded by plugins should be attached to the document
- if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDOMElement)
- node = node.ownerDocument;
-
- // Fix type for objects misrepresented as frames or images
- if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjectElement || node instanceof Ci.nsIDOMHTMLEmbedElement))
- contentType = Policy.type.OBJECT;
-
- let locationText = location.spec;
- let originWindow = Utils.getOriginWindow(wnd);
- let wndLocation = originWindow.location.href;
- let docDomain = getHostname(wndLocation);
- if (!match && contentType == Policy.type.ELEMHIDE)
- {
- match = defaultMatcher.matchesAny(wndLocation, "ELEMHIDE", docDomain, false);
- if (match && match instanceof WhitelistFilter)
- {
- FilterStorage.increaseHitCount(match);
-
- RequestNotifier.addNodeData(wnd.document, topWnd, contentType, docDomain, false, wndLocation, match);
- return true;
- }
-
- match = location;
- locationText = match.text.replace(/^.*?#/, '#');
- location = locationText;
-
- if (!match.isActiveOnDomain(docDomain))
- return true;
- }
-
- let thirdParty = (contentType == Policy.type.ELEMHIDE ? false : isThirdParty(location, docDomain));
-
- if (!match && Prefs.enabled)
- {
- match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty);
- if (match instanceof BlockingFilter && node.ownerDocument && !(contentType in Policy.nonVisual))
- {
- let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fastcollapse);
- if (collapse || prefCollapse)
- Utils.schedulePostProcess(node);
- }
-
- // Track mouse events for objects
- if (!match && contentType == Policy.type.OBJECT)
- {
- node.addEventListener("mouseover", objectMouseEventHander, true);
- node.addEventListener("mouseout", objectMouseEventHander, true);
- }
- }
-
- // Store node data
- RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty, locationText, match);
- if (match)
- FilterStorage.increaseHitCount(match);
-
- return !match || match instanceof WhitelistFilter;
- },
-
- /**
- * Checks whether the location's scheme is blockable.
- * @param location {nsIURI}
- * @return {Boolean}
- */
- isBlockableScheme: function(location)
- {
- return !(location.scheme in Policy.whitelistSchemes);
- },
-
- /**
- * Checks whether a page is whitelisted.
- * @param url {String}
- * @return {Filter} filter that matched the URL or null if not whitelisted
- */
- isWhitelisted: function(url)
- {
- // Do not allow whitelisting about:. We get a check for about: during
- // startup, it should be dealt with fast - without checking filters which
- // might load patterns.ini.
- if (/^(moz-safe-)?about:/.test(url))
- return null;
-
- // Ignore fragment identifier
- let index = url.indexOf("#");
- if (index >= 0)
- url = url.substring(0, index);
-
- let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(url), false);
- return (result instanceof WhitelistFilter ? result : null);
- },
-
- /**
- * Checks whether the page loaded in a window is whitelisted.
- * @param wnd {nsIDOMWindow}
- * @return {Filter} matching exception rule or null if not whitelisted
- */
- isWindowWhitelisted: function(wnd)
- {
- let location = getWindowLocation(wnd);
- if (!location)
- return null;
-
- return Policy.isWhitelisted(location);
- },
-
-
- /**
- * Asynchronously re-checks filters for given nodes.
- */
- refilterNodes: function(/**Node[]*/ nodes, /**RequestEntry*/ entry)
- {
- // Ignore nodes that have been blocked already
- if (entry.filter && !(entry.filter instanceof WhitelistFilter))
- return;
-
- for each (let node in nodes)
- Utils.runAsync(refilterNode, this, node, entry);
- }
+ /**
+ * Map of content type identifiers by their name.
+ * @type Object
+ */
+ type: {},
+
+ /**
+ * Map of content type names by their identifiers (reverse of type map).
+ * @type Object
+ */
+ typeDescr: {},
+
+ /**
+ * Map of localized content type names by their identifiers.
+ * @type Object
+ */
+ localizedDescr: {},
+
+ /**
+ * Lists the non-visual content types.
+ * @type Object
+ */
+ nonVisual: {},
+
+ /**
+ * Map containing all schemes that should be ignored by content policy.
+ * @type Object
+ */
+ whitelistSchemes: {},
+
+ /**
+ * Called on module startup.
+ */
+ startup: function()
+ {
+
+
+ // type constant by type description and type description by type constant
+ var iface = Ci.nsIContentPolicy;
+ for each (let typeName in contentTypes)
+ {
+ if ("TYPE_" + typeName in iface)
+ {
+ let id = iface["TYPE_" + typeName];
+ Policy.type[typeName] = id;
+ Policy.typeDescr[id] = typeName;
+ Policy.localizedDescr[id] = Utils.getString("type_label_" + typeName.toLowerCase());
+ }
+ }
+
+ Policy.type.ELEMHIDE = 0xFFFD;
+ Policy.typeDescr[0xFFFD] = "ELEMHIDE";
+ Policy.localizedDescr[0xFFFD] = Utils.getString("type_label_elemhide");
+
+ for each (let type in nonVisualTypes)
+ Policy.nonVisual[Policy.type[type]] = true;
+
+ // whitelisted URL schemes
+ for each (var scheme in Prefs.whitelistschemes.toLowerCase().split(" "))
+ Policy.whitelistSchemes[scheme] = true;
+
+
+
+ // Generate class identifier used to collapse node and register corresponding
+ // stylesheet.
+
+
+ let offset = "a".charCodeAt(0);
+ Utils.collapsedClass = "";
+ for (let i = 0; i < 20; i++)
+ Utils.collapsedClass += String.fromCharCode(offset + Math.random() * 26);
+
+ let collapseStyle = Utils.makeURI("data:text/css," +
+ encodeURIComponent("." + Utils.collapsedClass +
+ "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarbazdummy) !important;}"));
+ Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
+
+
+ // Register our content policy
+
+
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ try
+ {
+ registrar.registerFactory(PolicyPrivate.classID, PolicyPrivate.classDescription, PolicyPrivate.contractID, PolicyPrivate);
+ }
+ catch (e)
+ {
+ // Don't stop on errors - the factory might already be registered
+ Cu.reportError(e);
+ }
+
+ let catMan = Utils.categoryManager;
+ for each (let category in PolicyPrivate.xpcom_categories)
+ catMan.addCategoryEntry(category, PolicyPrivate.classDescription, PolicyPrivate.contractID, false, true);
+
+ Utils.observerService.addObserver(PolicyPrivate, "http-on-modify-request", true);
+
+
+ },
+
+ shutdown: function()
+ {
+ PolicyPrivate.previousRequest = null;
+ },
+
+ /**
+ * Checks whether a node should be blocked, hides it if necessary
+ * @param wnd {nsIDOMWindow}
+ * @param node {nsIDOMElement}
+ * @param contentType {String}
+ * @param location {nsIURI}
+ * @param collapse {Boolean} true to force hiding of the node
+ * @return {Boolean} false if the node should be blocked
+ */
+ processNode: function(wnd, node, contentType, location, collapse)
+ {
+ let topWnd = wnd.top;
+ if (!topWnd || !topWnd.location || !topWnd.location.href)
+ return true;
+
+ let match = null;
+ if (!match && Prefs.enabled)
+ {
+ match = Policy.isWindowWhitelisted(topWnd);
+ if (match)
+ {
+ FilterStorage.increaseHitCount(match);
+ return true;
+ }
+ }
+
+ // Data loaded by plugins should be attached to the document
+ if (contentType == Policy.type.OBJECT_SUBREQUEST && node instanceof Ci.nsIDOMElement)
+ node = node.ownerDocument;
+
+ // Fix type for objects misrepresented as frames or images
+ if (contentType != Policy.type.OBJECT && (node instanceof Ci.nsIDOMHTMLObjectElement || node instanceof Ci.nsIDOMHTMLEmbedElement))
+ contentType = Policy.type.OBJECT;
+
+ let locationText = location.spec;
+ let originWindow = Utils.getOriginWindow(wnd);
+ let wndLocation = originWindow.location.href;
+ let docDomain = getHostname(wndLocation);
+ if (!match && contentType == Policy.type.ELEMHIDE)
+ {
+ match = defaultMatcher.matchesAny(wndLocation, "ELEMHIDE", docDomain, false);
+ if (match && match instanceof WhitelistFilter)
+ {
+ FilterStorage.increaseHitCount(match);
+
+ RequestNotifier.addNodeData(wnd.document, topWnd, contentType, docDomain, false, wndLocation, match);
+ return true;
+ }
+
+ match = location;
+ locationText = match.text.replace(/^.*?#/, '#');
+ location = locationText;
+
+ if (!match.isActiveOnDomain(docDomain))
+ return true;
+ }
+
+ let thirdParty = (contentType == Policy.type.ELEMHIDE ? false : isThirdParty(location, docDomain));
+
+ if (!match && Prefs.enabled)
+ {
+ match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty);
+ if (match instanceof BlockingFilter && node.ownerDocument && !(contentType in Policy.nonVisual))
+ {
+ let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fastcollapse);
+ if (collapse || prefCollapse)
+ Utils.schedulePostProcess(node);
+ }
+
+ // Track mouse events for objects
+ if (!match && contentType == Policy.type.OBJECT)
+ {
+ node.addEventListener("mouseover", objectMouseEventHander, true);
+ node.addEventListener("mouseout", objectMouseEventHander, true);
+ }
+ }
+
+ // Store node data
+ RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty, locationText, match);
+ if (match)
+ FilterStorage.increaseHitCount(match);
+
+ return !match || match instanceof WhitelistFilter;
+ },
+
+ /**
+ * Checks whether the location's scheme is blockable.
+ * @param location {nsIURI}
+ * @return {Boolean}
+ */
+ isBlockableScheme: function(location)
+ {
+ return !(location.scheme in Policy.whitelistSchemes);
+ },
+
+ /**
+ * Checks whether a page is whitelisted.
+ * @param url {String}
+ * @return {Filter} filter that matched the URL or null if not whitelisted
+ */
+ isWhitelisted: function(url)
+ {
+ // Do not allow whitelisting about:. We get a check for about: during
+ // startup, it should be dealt with fast - without checking filters which
+ // might load patterns.ini.
+ if (/^(moz-safe-)?about:/.test(url))
+ return null;
+
+ // Ignore fragment identifier
+ let index = url.indexOf("#");
+ if (index >= 0)
+ url = url.substring(0, index);
+
+ let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(url), false);
+ return (result instanceof WhitelistFilter ? result : null);
+ },
+
+ /**
+ * Checks whether the page loaded in a window is whitelisted.
+ * @param wnd {nsIDOMWindow}
+ * @return {Filter} matching exception rule or null if not whitelisted
+ */
+ isWindowWhitelisted: function(wnd)
+ {
+ let location = getWindowLocation(wnd);
+ if (!location)
+ return null;
+
+ return Policy.isWhitelisted(location);
+ },
+
+
+ /**
+ * Asynchronously re-checks filters for given nodes.
+ */
+ refilterNodes: function(/**Node[]*/ nodes, /**RequestEntry*/ entry)
+ {
+ // Ignore nodes that have been blocked already
+ if (entry.filter && !(entry.filter instanceof WhitelistFilter))
+ return;
+
+ for each (let node in nodes)
+ Utils.runAsync(refilterNode, this, node, entry);
+ }
};
/**
@@ -321,166 +321,166 @@ var Policy =
*/
var PolicyPrivate =
{
- classDescription: "Adblock Plus content policy",
- classID: Components.ID("cfeaabe6-1dd1-11b2-a0c6-cb5c268894c9"),
- contractID: "@adblockplus.org/abp/policy;1",
- xpcom_categories: ["content-policy", "net-channel-event-sinks"],
-
- //
- // nsISupports interface implementation
- //
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
- Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),
-
- //
- // nsIContentPolicy interface implementation
- //
-
- shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
- {
- // Ignore requests without context and top-level documents
- if (!node || contentType == Policy.type.DOCUMENT)
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Ignore standalone objects
- if (contentType == Policy.type.OBJECT && node.ownerDocument && !/^text\/|[+\/]xml$/.test(node.ownerDocument.contentType))
- return Ci.nsIContentPolicy.ACCEPT;
-
- let wnd = Utils.getWindow(node);
- if (!wnd)
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Ignore whitelisted schemes
- let location = Utils.unwrapURL(contentLocation);
- if (!Policy.isBlockableScheme(location))
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Interpret unknown types as "other"
- if (!(contentType in Policy.typeDescr))
- contentType = Policy.type.OTHER;
-
- let result = Policy.processNode(wnd, node, contentType, location, false);
- if (result)
- {
- // We didn't block this request so we will probably see it again in
- // http-on-modify-request. Keep it so that we can associate it with the
- // channel there - will be needed in case of redirect.
- PolicyPrivate.previousRequest = [node, contentType, location];
- }
- return (result ? Ci.nsIContentPolicy.ACCEPT : Ci.nsIContentPolicy.REJECT_REQUEST);
- },
-
- shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra)
- {
- return Ci.nsIContentPolicy.ACCEPT;
- },
-
- //
- // nsIObserver interface implementation
- //
- observe: function(subject, topic, data)
- {
- if (topic != "http-on-modify-request" || !(subject instanceof Ci.nsIHttpChannel))
- return;
-
- if (Prefs.enabled)
- {
- let match = defaultMatcher.matchesAny(subject.URI.spec, "DONOTTRACK", null, false);
- if (match && match instanceof BlockingFilter)
- {
- FilterStorage.increaseHitCount(match);
- subject.setRequestHeader("DNT", "1", false);
-
- // Bug 23845 - Some routers are broken and cannot handle DNT header
- // following Connection header. Make sure Connection header is last.
- try
- {
- let connection = subject.getRequestHeader("Connection");
- subject.setRequestHeader("Connection", null, false);
- subject.setRequestHeader("Connection", connection, false);
- } catch(e) {}
- }
- }
-
- if (PolicyPrivate.previousRequest && subject.URI == PolicyPrivate.previousRequest[2] &&
- subject instanceof Ci.nsIWritablePropertyBag)
- {
- // We just handled a content policy call for this request - associate
- // the data with the channel so that we can find it in case of a redirect.
- subject.setProperty("abpRequestData", PolicyPrivate.previousRequest);
- PolicyPrivate.previousRequest = null;
-
- // Add our listener to remove the data again once the request is done
- if (subject instanceof Ci.nsITraceableChannel)
- new TraceableChannelCleanup(subject);
- }
- },
-
- //
- // nsIChannelEventSink interface implementation
- //
-
- // Old (Gecko 1.9.x) version
- onChannelRedirect: function(oldChannel, newChannel, flags)
- {
- try
- {
- // Try to retrieve previously stored request data from the channel
- let requestData;
- if (oldChannel instanceof Ci.nsIWritablePropertyBag)
- {
- try
- {
- requestData = oldChannel.getProperty("abpRequestData");
- }
- catch(e)
- {
- // No data attached, ignore this redirect
- return;
- }
- }
-
- let newLocation = null;
- try
- {
- newLocation = newChannel.URI;
- } catch(e2) {}
- if (!newLocation)
- return;
-
- // HACK: NS_BINDING_ABORTED would be proper error code to throw but this will show up in error console (bug 287107)
- if (!Policy.processNode(Utils.getWindow(requestData[0]), requestData[0], requestData[1], newLocation, false))
- throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
- else
- return;
- }
- catch (e if (e != Cr.NS_BASE_STREAM_WOULD_BLOCK))
- {
- // We shouldn't throw exceptions here - this will prevent the redirect.
- Cu.reportError(e);
- }
- },
-
- // New (Gecko 2.0) version
- asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
- {
- this.onChannelRedirect(oldChannel, newChannel, flags);
-
- // If onChannelRedirect didn't throw an exception indicate success
- callback.onRedirectVerifyCallback(Cr.NS_OK);
- },
-
- //
- // nsIFactory interface implementation
- //
-
- createInstance: function(outer, iid)
- {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return this.QueryInterface(iid);
- }
+ classDescription: "Adblock Plus content policy",
+ classID: Components.ID("cfeaabe6-1dd1-11b2-a0c6-cb5c268894c9"),
+ contractID: "@adblockplus.org/abp/policy;1",
+ xpcom_categories: ["content-policy", "net-channel-event-sinks"],
+
+ //
+ // nsISupports interface implementation
+ //
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
+ Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),
+
+ //
+ // nsIContentPolicy interface implementation
+ //
+
+ shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
+ {
+ // Ignore requests without context and top-level documents
+ if (!node || contentType == Policy.type.DOCUMENT)
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ // Ignore standalone objects
+ if (contentType == Policy.type.OBJECT && node.ownerDocument && !/^text\/|[+\/]xml$/.test(node.ownerDocument.contentType))
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ let wnd = Utils.getWindow(node);
+ if (!wnd)
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ // Ignore whitelisted schemes
+ let location = Utils.unwrapURL(contentLocation);
+ if (!Policy.isBlockableScheme(location))
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ // Interpret unknown types as "other"
+ if (!(contentType in Policy.typeDescr))
+ contentType = Policy.type.OTHER;
+
+ let result = Policy.processNode(wnd, node, contentType, location, false);
+ if (result)
+ {
+ // We didn't block this request so we will probably see it again in
+ // http-on-modify-request. Keep it so that we can associate it with the
+ // channel there - will be needed in case of redirect.
+ PolicyPrivate.previousRequest = [node, contentType, location];
+ }
+ return (result ? Ci.nsIContentPolicy.ACCEPT : Ci.nsIContentPolicy.REJECT_REQUEST);
+ },
+
+ shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra)
+ {
+ return Ci.nsIContentPolicy.ACCEPT;
+ },
+
+ //
+ // nsIObserver interface implementation
+ //
+ observe: function(subject, topic, data)
+ {
+ if (topic != "http-on-modify-request" || !(subject instanceof Ci.nsIHttpChannel))
+ return;
+
+ if (Prefs.enabled)
+ {
+ let match = defaultMatcher.matchesAny(subject.URI.spec, "DONOTTRACK", null, false);
+ if (match && match instanceof BlockingFilter)
+ {
+ FilterStorage.increaseHitCount(match);
+ subject.setRequestHeader("DNT", "1", false);
+
+ // Bug 23845 - Some routers are broken and cannot handle DNT header
+ // following Connection header. Make sure Connection header is last.
+ try
+ {
+ let connection = subject.getRequestHeader("Connection");
+ subject.setRequestHeader("Connection", null, false);
+ subject.setRequestHeader("Connection", connection, false);
+ } catch(e) {}
+ }
+ }
+
+ if (PolicyPrivate.previousRequest && subject.URI == PolicyPrivate.previousRequest[2] &&
+ subject instanceof Ci.nsIWritablePropertyBag)
+ {
+ // We just handled a content policy call for this request - associate
+ // the data with the channel so that we can find it in case of a redirect.
+ subject.setProperty("abpRequestData", PolicyPrivate.previousRequest);
+ PolicyPrivate.previousRequest = null;
+
+ // Add our listener to remove the data again once the request is done
+ if (subject instanceof Ci.nsITraceableChannel)
+ new TraceableChannelCleanup(subject);
+ }
+ },
+
+ //
+ // nsIChannelEventSink interface implementation
+ //
+
+ // Old (Gecko 1.9.x) version
+ onChannelRedirect: function(oldChannel, newChannel, flags)
+ {
+ try
+ {
+ // Try to retrieve previously stored request data from the channel
+ let requestData;
+ if (oldChannel instanceof Ci.nsIWritablePropertyBag)
+ {
+ try
+ {
+ requestData = oldChannel.getProperty("abpRequestData");
+ }
+ catch(e)
+ {
+ // No data attached, ignore this redirect
+ return;
+ }
+ }
+
+ let newLocation = null;
+ try
+ {
+ newLocation = newChannel.URI;
+ } catch(e2) {}
+ if (!newLocation)
+ return;
+
+ // HACK: NS_BINDING_ABORTED would be proper error code to throw but this will show up in error console (bug 287107)
+ if (!Policy.processNode(Utils.getWindow(requestData[0]), requestData[0], requestData[1], newLocation, false))
+ throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
+ else
+ return;
+ }
+ catch (e if (e != Cr.NS_BASE_STREAM_WOULD_BLOCK))
+ {
+ // We shouldn't throw exceptions here - this will prevent the redirect.
+ Cu.reportError(e);
+ }
+ },
+
+ // New (Gecko 2.0) version
+ asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
+ {
+ this.onChannelRedirect(oldChannel, newChannel, flags);
+
+ // If onChannelRedirect didn't throw an exception indicate success
+ callback.onRedirectVerifyCallback(Cr.NS_OK);
+ },
+
+ //
+ // nsIFactory interface implementation
+ //
+
+ createInstance: function(outer, iid)
+ {
+ if (outer)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(iid);
+ }
};
/**
@@ -488,14 +488,14 @@ var PolicyPrivate =
*/
function getHostname(/**String*/ url) /**String*/
{
- try
- {
- return Utils.unwrapURL(url).host;
- }
- catch(e)
- {
- return null;
- }
+ try
+ {
+ return Utils.unwrapURL(url).host;
+ }
+ catch(e)
+ {
+ return null;
+ }
}
/**
@@ -505,41 +505,41 @@ function getHostname(/**String*/ url) /**String*/
*/
function getWindowLocation(wnd)
{
- if ("name" in wnd && wnd.name == "messagepane")
- {
- // Thunderbird branch
- try
- {
- let mailWnd = wnd.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
-
- // Typically we get a wrapped mail window here, need to unwrap
- try
- {
- mailWnd = mailWnd.wrappedJSObject;
- } catch(e) {}
-
- if ("currentHeaderData" in mailWnd && "content-base" in mailWnd.currentHeaderData)
- {
- return mailWnd.currentHeaderData["content-base"].headerValue;
- }
- else if ("currentHeaderData" in mailWnd && "from" in mailWnd.currentHeaderData)
- {
- let emailAddress = Utils.headerParser.extractHeaderAddressMailboxes(mailWnd.currentHeaderData.from.headerValue);
- if (emailAddress)
- return 'mailto:' + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, '%20');
- }
- } catch(e) {}
- }
- else
- {
- // Firefox branch
- return wnd.location.href;
- }
+ if ("name" in wnd && wnd.name == "messagepane")
+ {
+ // Thunderbird branch
+ try
+ {
+ let mailWnd = wnd.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow);
+
+ // Typically we get a wrapped mail window here, need to unwrap
+ try
+ {
+ mailWnd = mailWnd.wrappedJSObject;
+ } catch(e) {}
+
+ if ("currentHeaderData" in mailWnd && "content-base" in mailWnd.currentHeaderData)
+ {
+ return mailWnd.currentHeaderData["content-base"].headerValue;
+ }
+ else if ("currentHeaderData" in mailWnd && "from" in mailWnd.currentHeaderData)
+ {
+ let emailAddress = Utils.headerParser.extractHeaderAddressMailboxes(mailWnd.currentHeaderData.from.headerValue);
+ if (emailAddress)
+ return 'mailto:' + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, '%20');
+ }
+ } catch(e) {}
+ }
+ else
+ {
+ // Firefox branch
+ return wnd.location.href;
+ }
}
/**
@@ -547,23 +547,23 @@ function getWindowLocation(wnd)
*/
function isThirdParty(/**nsIURI*/location, /**String*/ docDomain) /**Boolean*/
{
- if (!location || !docDomain)
- return true;
-
- try
- {
- return Utils.effectiveTLD.getBaseDomain(location) != Utils.effectiveTLD.getBaseDomainFromHost(docDomain);
- }
- catch (e)
- {
- // EffectiveTLDService throws on IP addresses, just compare the host name
- let host = "";
- try
- {
- host = location.host;
- } catch (e) {}
- return host != docDomain;
- }
+ if (!location || !docDomain)
+ return true;
+
+ try
+ {
+ return Utils.effectiveTLD.getBaseDomain(location) != Utils.effectiveTLD.getBaseDomainFromHost(docDomain);
+ }
+ catch (e)
+ {
+ // EffectiveTLDService throws on IP addresses, just compare the host name
+ let host = "";
+ try
+ {
+ host = location.host;
+ } catch (e) {}
+ return host != docDomain;
+ }
}
/**
@@ -571,14 +571,14 @@ function isThirdParty(/**nsIURI*/location, /**String*/ docDomain) /**Boolean*/
*/
function refilterNode(/**Node*/ node, /**RequestEntry*/ entry)
{
- let wnd = Utils.getWindow(node);
- if (!wnd || wnd.closed)
- return;
-
- if (entry.type == Policy.type.OBJECT)
- {
- node.removeEventListener("mouseover", objectMouseEventHander, true);
- node.removeEventListener("mouseout", objectMouseEventHander, true);
- }
- Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true);
+ let wnd = Utils.getWindow(node);
+ if (!wnd || wnd.closed)
+ return;
+
+ if (entry.type == Policy.type.OBJECT)
+ {
+ node.removeEventListener("mouseover", objectMouseEventHander, true);
+ node.removeEventListener("mouseout", objectMouseEventHander, true);
+ }
+ Policy.processNode(wnd, node, entry.type, Utils.makeURI(entry.location), true);
}
diff --git a/modules/ContentPolicyRemote.jsm b/modules/ContentPolicyRemote.jsm
index 227fc37..84b86ce 100644
--- a/modules/ContentPolicyRemote.jsm
+++ b/modules/ContentPolicyRemote.jsm
@@ -43,190 +43,190 @@ Cu.import("chrome://adblockplus-modules/content/Utils.jsm");
*/
var PolicyRemote =
{
- classDescription: "Adblock Plus content policy",
- classID: Components.ID("094560a0-4fed-11e0-b8af-0800200c9a66"),
- contractID: "@adblockplus.org/abp/policy-remote;1",
- xpcom_categories: ["content-policy", "net-channel-event-sinks"],
-
- cache: new Cache(512),
-
- startup: function()
- {
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- try
- {
- registrar.registerFactory(PolicyRemote.classID, PolicyRemote.classDescription, PolicyRemote.contractID, PolicyRemote);
- }
- catch (e)
- {
- // Don't stop on errors - the factory might already be registered
- Cu.reportError(e);
- }
-
- let catMan = Utils.categoryManager;
- for each (let category in PolicyRemote.xpcom_categories)
- catMan.addCategoryEntry(category, PolicyRemote.classDescription, PolicyRemote.contractID, false, true);
-
- Utils.observerService.addObserver(PolicyRemote, "http-on-modify-request", true);
-
- // Generate class identifier used to collapse node and register corresponding
- // stylesheet.
- let offset = "a".charCodeAt(0);
- Utils.collapsedClass = "";
- for (let i = 0; i < 20; i++)
- Utils.collapsedClass += String.fromCharCode(offset + Math.random() * 26);
-
- let collapseStyle = Utils.makeURI("data:text/css," +
- encodeURIComponent("." + Utils.collapsedClass +
- "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarbazdummy) !important;}"));
- Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
-
- // Get notified if we need to invalidate our matching cache
- Utils.childMessageManager.addMessageListener("AdblockPlus:Matcher:clearCache", function(message)
- {
- PolicyRemote.cache.clear();
- });
- },
-
- //
- // nsISupports interface implementation
- //
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
- Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),
-
- //
- // nsIContentPolicy interface implementation
- //
-
- shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
- {
- // Ignore requests without context and top-level documents
- if (!node || contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT)
- return Ci.nsIContentPolicy.ACCEPT;
-
- let wnd = Utils.getWindow(node);
- if (!wnd)
- return Ci.nsIContentPolicy.ACCEPT;
-
- wnd = Utils.getOriginWindow(wnd);
-
- let wndLocation = wnd.location.href;
- let topLocation = wnd.top.location.href;
- let key = contentType + " " + contentLocation.spec + " " + wndLocation + " " + topLocation;
- if (!(key in this.cache.data))
- {
- this.cache.add(key, Utils.childMessageManager.sendSyncMessage("AdblockPlus:Policy:shouldLoad", {
- contentType: contentType,
- contentLocation: contentLocation.spec,
- wndLocation: wnd.location.href,
- topLocation: wnd.top.location.href})[0]);
- }
-
- let result = this.cache.data[key];
- if (result.value == Ci.nsIContentPolicy.ACCEPT)
- {
- // We didn't block this request so we will probably see it again in
- // http-on-modify-request. Keep it so that we can associate it with the
- // channel there - will be needed in case of redirect.
- PolicyRemote.previousRequest = [node, contentType, Utils.unwrapURL(contentLocation)];
- }
- else if (result.postProcess)
- Utils.schedulePostProcess(node);
- return result.value;
- },
-
- shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra)
- {
- return Ci.nsIContentPolicy.ACCEPT;
- },
-
- //
- // nsIObserver interface implementation
- //
- observe: function(subject, topic, data)
- {
- if (topic != "http-on-modify-request" || !(subject instanceof Ci.nsIHttpChannel))
- return;
-
- // TODO: Do-not-track header
-
- if (PolicyRemote.previousRequest && subject.URI == PolicyRemote.previousRequest[2] &&
- subject instanceof Ci.nsIWritablePropertyBag)
- {
- // We just handled a content policy call for this request - associate
- // the data with the channel so that we can find it in case of a redirect.
- subject.setProperty("abpRequestData", PolicyRemote.previousRequest);
- PolicyRemote.previousRequest = null;
-
- // Add our listener to remove the data again once the request is done
- if (subject instanceof Ci.nsITraceableChannel)
- new TraceableChannelCleanup(subject);
- }
- },
-
- //
- // nsIChannelEventSink interface implementation
- //
-
- onChannelRedirect: function(oldChannel, newChannel, flags)
- {
- try
- {
- // Try to retrieve previously stored request data from the channel
- let requestData;
- if (oldChannel instanceof Ci.nsIWritablePropertyBag)
- {
- try
- {
- requestData = oldChannel.getProperty("abpRequestData");
- }
- catch(e)
- {
- // No data attached, ignore this redirect
- return;
- }
- }
-
- let newLocation = null;
- try
- {
- newLocation = newChannel.URI;
- } catch(e2) {}
- if (!newLocation)
- return;
-
- // HACK: NS_BINDING_ABORTED would be proper error code to throw but this will show up in error console (bug 287107)
- if (PolicyRemote.shouldLoad(requestData[1], newLocation, null, requestData[0]) != Ci.nsIContentPolicy.ACCEPT)
- throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
- else
- return;
- }
- catch (e if (e != Cr.NS_BASE_STREAM_WOULD_BLOCK))
- {
- // We shouldn't throw exceptions here - this will prevent the redirect.
- Cu.reportError(e);
- }
- },
-
- asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
- {
- this.onChannelRedirect(oldChannel, newChannel, flags);
-
- // If onChannelRedirect didn't throw an exception indicate success
- callback.onRedirectVerifyCallback(Cr.NS_OK);
- },
-
- //
- // nsIFactory interface implementation
- //
-
- createInstance: function(outer, iid)
- {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return this.QueryInterface(iid);
- }
+ classDescription: "Adblock Plus content policy",
+ classID: Components.ID("094560a0-4fed-11e0-b8af-0800200c9a66"),
+ contractID: "@adblockplus.org/abp/policy-remote;1",
+ xpcom_categories: ["content-policy", "net-channel-event-sinks"],
+
+ cache: new Cache(512),
+
+ startup: function()
+ {
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ try
+ {
+ registrar.registerFactory(PolicyRemote.classID, PolicyRemote.classDescription, PolicyRemote.contractID, PolicyRemote);
+ }
+ catch (e)
+ {
+ // Don't stop on errors - the factory might already be registered
+ Cu.reportError(e);
+ }
+
+ let catMan = Utils.categoryManager;
+ for each (let category in PolicyRemote.xpcom_categories)
+ catMan.addCategoryEntry(category, PolicyRemote.classDescription, PolicyRemote.contractID, false, true);
+
+ Utils.observerService.addObserver(PolicyRemote, "http-on-modify-request", true);
+
+ // Generate class identifier used to collapse node and register corresponding
+ // stylesheet.
+ let offset = "a".charCodeAt(0);
+ Utils.collapsedClass = "";
+ for (let i = 0; i < 20; i++)
+ Utils.collapsedClass += String.fromCharCode(offset + Math.random() * 26);
+
+ let collapseStyle = Utils.makeURI("data:text/css," +
+ encodeURIComponent("." + Utils.collapsedClass +
+ "{-moz-binding: url(chrome://global/content/bindings/general.xml#foobarbazdummy) !important;}"));
+ Utils.styleService.loadAndRegisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET);
+
+ // Get notified if we need to invalidate our matching cache
+ Utils.childMessageManager.addMessageListener("AdblockPlus:Matcher:clearCache", function(message)
+ {
+ PolicyRemote.cache.clear();
+ });
+ },
+
+ //
+ // nsISupports interface implementation
+ //
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
+ Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),
+
+ //
+ // nsIContentPolicy interface implementation
+ //
+
+ shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
+ {
+ // Ignore requests without context and top-level documents
+ if (!node || contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT)
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ let wnd = Utils.getWindow(node);
+ if (!wnd)
+ return Ci.nsIContentPolicy.ACCEPT;
+
+ wnd = Utils.getOriginWindow(wnd);
+
+ let wndLocation = wnd.location.href;
+ let topLocation = wnd.top.location.href;
+ let key = contentType + " " + contentLocation.spec + " " + wndLocation + " " + topLocation;
+ if (!(key in this.cache.data))
+ {
+ this.cache.add(key, Utils.childMessageManager.sendSyncMessage("AdblockPlus:Policy:shouldLoad", {
+ contentType: contentType,
+ contentLocation: contentLocation.spec,
+ wndLocation: wnd.location.href,
+ topLocation: wnd.top.location.href})[0]);
+ }
+
+ let result = this.cache.data[key];
+ if (result.value == Ci.nsIContentPolicy.ACCEPT)
+ {
+ // We didn't block this request so we will probably see it again in
+ // http-on-modify-request. Keep it so that we can associate it with the
+ // channel there - will be needed in case of redirect.
+ PolicyRemote.previousRequest = [node, contentType, Utils.unwrapURL(contentLocation)];
+ }
+ else if (result.postProcess)
+ Utils.schedulePostProcess(node);
+ return result.value;
+ },
+
+ shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra)
+ {
+ return Ci.nsIContentPolicy.ACCEPT;
+ },
+
+ //
+ // nsIObserver interface implementation
+ //
+ observe: function(subject, topic, data)
+ {
+ if (topic != "http-on-modify-request" || !(subject instanceof Ci.nsIHttpChannel))
+ return;
+
+ // TODO: Do-not-track header
+
+ if (PolicyRemote.previousRequest && subject.URI == PolicyRemote.previousRequest[2] &&
+ subject instanceof Ci.nsIWritablePropertyBag)
+ {
+ // We just handled a content policy call for this request - associate
+ // the data with the channel so that we can find it in case of a redirect.
+ subject.setProperty("abpRequestData", PolicyRemote.previousRequest);
+ PolicyRemote.previousRequest = null;
+
+ // Add our listener to remove the data again once the request is done
+ if (subject instanceof Ci.nsITraceableChannel)
+ new TraceableChannelCleanup(subject);
+ }
+ },
+
+ //
+ // nsIChannelEventSink interface implementation
+ //
+
+ onChannelRedirect: function(oldChannel, newChannel, flags)
+ {
+ try
+ {
+ // Try to retrieve previously stored request data from the channel
+ let requestData;
+ if (oldChannel instanceof Ci.nsIWritablePropertyBag)
+ {
+ try
+ {
+ requestData = oldChannel.getProperty("abpRequestData");
+ }
+ catch(e)
+ {
+ // No data attached, ignore this redirect
+ return;
+ }
+ }
+
+ let newLocation = null;
+ try
+ {
+ newLocation = newChannel.URI;
+ } catch(e2) {}
+ if (!newLocation)
+ return;
+
+ // HACK: NS_BINDING_ABORTED would be proper error code to throw but this will show up in error console (bug 287107)
+ if (PolicyRemote.shouldLoad(requestData[1], newLocation, null, requestData[0]) != Ci.nsIContentPolicy.ACCEPT)
+ throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
+ else
+ return;
+ }
+ catch (e if (e != Cr.NS_BASE_STREAM_WOULD_BLOCK))
+ {
+ // We shouldn't throw exceptions here - this will prevent the redirect.
+ Cu.reportError(e);
+ }
+ },
+
+ asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
+ {
+ this.onChannelRedirect(oldChannel, newChannel, flags);
+
+ // If onChannelRedirect didn't throw an exception indicate success
+ callback.onRedirectVerifyCallback(Cr.NS_OK);
+ },
+
+ //
+ // nsIFactory interface implementation
+ //
+
+ createInstance: function(outer, iid)
+ {
+ if (outer)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+ return this.QueryInterface(iid);
+ }
};
PolicyRemote.startup();
diff --git a/modules/ElemHide.jsm b/modules/ElemHide.jsm
index c257eb4..1871931 100644
--- a/modules/ElemHide.jsm
+++ b/modules/ElemHide.jsm
@@ -41,7 +41,7 @@ Cu.import(baseURL.spec + "Prefs.jsm");
Cu.import(baseURL.spec + "ContentPolicy.jsm");
Cu.import(baseURL.spec + "FilterStorage.jsm");
Cu.import(baseURL.spec + "FilterClasses.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
/**
* Lookup table, filters by their associated key
@@ -61,305 +61,311 @@ let styleURL = null;
*/
var ElemHide =
{
- /**
- * Indicates whether filters have been added or removed since the last apply() call.
- * @type Boolean
- */
- isDirty: false,
-
- /**
- * Inidicates whether the element hiding stylesheet is currently applied.
- * @type Boolean
- */
- applied: false,
-
- /**
- * Lookup table, keys of the filters by filter text
- * @type Object
- */
- keyByFilter: {__proto__: null},
-
- /**
- * Called on module startup.
- */
- init: function()
- {
- TimeLine.enter("Entered ElemHide.init()");
- Prefs.addListener(function(name)
- {
- if (name == "enabled")
- ElemHide.apply();
- });
-
- TimeLine.log("done adding prefs listener");
-
- let styleFile = Utils.resolveFilePath(Prefs.data_directory);
- styleFile.append("elemhide.css");
- styleURL = Utils.ioService.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL);
- TimeLine.log("done determining stylesheet URL");
-
- TimeLine.log("registering component");
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.registerFactory(ElemHidePrivate.classID, ElemHidePrivate.classDescription,
- "@mozilla.org/network/protocol/about;1?what=" + ElemHidePrivate.aboutPrefix, ElemHidePrivate);
-
- TimeLine.leave("ElemHide.init() done");
- },
-
- /**
- * Removes all known filters
- */
- clear: function()
- {
- filterByKey = {__proto__: null};
- ElemHide.keyByFilter = {__proto__: null};
- ElemHide.isDirty = false;
- ElemHide.unapply();
- },
-
- /**
- * Add a new element hiding filter
- * @param {ElemHideFilter} filter
- */
- add: function(filter)
- {
- if (filter.text in ElemHide.keyByFilter)
- return;
-
- let key;
- do {
- key = Math.random().toFixed(15).substr(5);
- } while (key in filterByKey);
-
- filterByKey[key] = filter.text;
- ElemHide.keyByFilter[filter.text] = key;
- ElemHide.isDirty = true;
- },
-
- /**
- * Removes an element hiding filter
- * @param {ElemHideFilter} filter
- */
- remove: function(filter)
- {
- if (!(filter.text in ElemHide.keyByFilter))
- return;
-
- let key = ElemHide.keyByFilter[filter.text];
- delete filterByKey[key];
- delete ElemHide.keyByFilter[filter.text];
- ElemHide.isDirty = true;
- },
-
- /**
- * Generates stylesheet URL and applies it globally
- */
- apply: function()
- {
- TimeLine.enter("Entered ElemHide.apply()");
-
- if (ElemHide.applied)
- ElemHide.unapply();
- TimeLine.log("ElemHide.unapply() finished");
-
- try
- {
- // Return immediately if disabled
- if (!Prefs.enabled)
- {
- TimeLine.leave("ElemHide.apply() done (disabled)");
- return;
- }
-
- // CSS file doesn't need to be rewritten if nothing changed (e.g. we
- // were disabled and reenabled)
- if (ElemHide.isDirty)
- {
- ElemHide.isDirty = false;
-
- // Grouping selectors by domains
- TimeLine.log("start grouping selectors");
- let domains = {__proto__: null};
- let hasFilters = false;
- for (let key in filterByKey)
- {
- let filter = Filter.knownFilters[filterByKey[key]];
- let domain = filter.selectorDomain || "";
-
- let list;
- if (domain in domains)
- list = domains[domain];
- else
- {
- list = {__proto__: null};
- domains[domain] = list;
- }
- list[filter.selector] = key;
- hasFilters = true;
- }
- TimeLine.log("done grouping selectors");
-
- if (!hasFilters)
- {
- TimeLine.leave("ElemHide.apply() done (no filters)");
- return;
- }
-
- // Writing out domains list
- TimeLine.log("start writing CSS data");
-
- try {
- // Make sure the file's parent directory exists
- styleURL.file.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
- } catch (e) {}
-
- let stream;
- try
- {
- stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
- stream.init(styleURL.file, 0x02 | 0x08 | 0x20, 0644, 0);
- }
- catch (e)
- {
- Cu.reportError(e);
- TimeLine.leave("ElemHide.apply() done (error opening file)");
- return;
- }
-
- let buf = [];
- let maxBufLen = 1024;
- function escapeChar(match)
- {
- return "\\" + match.charCodeAt(0).toString(16) + " ";
- }
- function writeString(str, forceWrite)
- {
- buf.push(str);
- if (buf.length >= maxBufLen || forceWrite)
- {
- let output = buf.join("").replace(/[^\x01-\x7F]/g, escapeChar);
- stream.write(output, output.length);
- buf.splice(0, buf.length);
- }
- }
-
- let cssTemplate = "-moz-binding: url(about:" + ElemHidePrivate.aboutPrefix + "?%ID%#dummy) !important;";
- for (let domain in domains)
- {
- let rules = [];
- let list = domains[domain];
-
- if (domain)
- writeString('@-moz-document domain("' + domain.split(",").join('"),domain("') + '"){\n');
- else
- {
- // Only allow unqualified rules on a few protocols to prevent them from blocking chrome
- writeString('@-moz-document url-prefix("http://"),url-prefix("https://"),'
- + 'url-prefix("mailbox://"),url-prefix("imap://"),'
- + 'url-prefix("news://"),url-prefix("snews://"){\n');
- }
-
- for (let selector in list)
- writeString(selector + "{" + cssTemplate.replace("%ID%", list[selector]) + "}\n");
- writeString('}\n');
- }
- writeString("", true);
- try
- {
- stream.QueryInterface(Ci.nsISafeOutputStream).finish();
- }
- catch(e)
- {
- Cu.reportError(e);
- TimeLine.leave("ElemHide.apply() done (error closing file)");
- return;
- }
- TimeLine.log("done writing CSS data");
- }
-
- // Inserting new stylesheet
- TimeLine.log("start inserting stylesheet");
- try
- {
- Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- ElemHide.applied = true;
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- TimeLine.leave("ElemHide.apply() done");
- }
- finally
- {
- FilterStorage.triggerObservers("elemhideupdate");
- }
- },
-
- /**
- * Unapplies current stylesheet URL
- */
- unapply: function()
- {
- if (ElemHide.applied)
- {
- try
- {
- Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- ElemHide.applied = false;
- }
- },
-
- /**
- * Retrieves the currently applied stylesheet URL
- * @type String
- */
- get styleURL() ElemHide.applied ? styleURL.spec : null,
-
- /**
- * Retrieves an element hiding filter by the corresponding protocol key
- */
- getFilterByKey: function(/**String*/ key) /**Filter*/
- {
- return (key in filterByKey ? Filter.knownFilters[filterByKey[key]] : null);
- },
-
- /**
- * Stores current state in a JSON'able object.
- */
- toCache: function(/**Object*/ cache)
- {
- cache.elemhide = {filterByKey: filterByKey};
- },
-
- /**
- * Restores current state from an object.
- */
- fromCache: function(/**Object*/ cache)
- {
- filterByKey = cache.elemhide.filterByKey;
- filterByKey.__proto__ = null;
-
- // We don't want to initialize keyByFilter yet, do it when it is needed
- delete ElemHide.keyByFilter;
- ElemHide.__defineGetter__("keyByFilter", function()
- {
- let result = {__proto__: null};
- for (let k in filterByKey)
- result[filterByKey[k]] = k;
- return ElemHide.keyByFilter = result;
- });
- ElemHide.__defineSetter__("keyByFilter", function(value)
- {
- delete ElemHide.keyByFilter;
- return ElemHide.keyByFilter = value;
- });
- }
+ /**
+ * Indicates whether filters have been added or removed since the last apply() call.
+ * @type Boolean
+ */
+ isDirty: false,
+
+ /**
+ * Inidicates whether the element hiding stylesheet is currently applied.
+ * @type Boolean
+ */
+ applied: false,
+
+ /**
+ * Lookup table, keys of the filters by filter text
+ * @type Object
+ */
+ keyByFilter: {__proto__: null},
+
+ /**
+ * Called on module startup.
+ */
+ init: function()
+ {
+
+ Prefs.addListener(function(name)
+ {
+ if (name == "enabled")
+ ElemHide.apply();
+ });
+
+
+
+ let styleFile = Utils.resolveFilePath(Prefs.data_directory);
+ styleFile.append("elemhide.css");
+ styleURL = Utils.ioService.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL);
+
+
+
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(ElemHidePrivate.classID, ElemHidePrivate.classDescription,
+ "@mozilla.org/network/protocol/about;1?what=" + ElemHidePrivate.aboutPrefix, ElemHidePrivate);
+
+
+ },
+
+ /**
+ * Removes all known filters
+ */
+ clear: function()
+ {
+ filterByKey = {__proto__: null};
+ ElemHide.keyByFilter = {__proto__: null};
+ ElemHide.isDirty = false;
+ ElemHide.unapply();
+ },
+
+ /**
+ * Add a new element hiding filter
+ * @param {ElemHideFilter} filter
+ */
+ add: function(filter)
+ {
+ if (filter.text in ElemHide.keyByFilter)
+ return;
+
+ let key;
+ do {
+ key = Math.random().toFixed(15).substr(5);
+ } while (key in filterByKey);
+
+ filterByKey[key] = filter.text;
+ ElemHide.keyByFilter[filter.text] = key;
+ ElemHide.isDirty = true;
+ },
+
+ /**
+ * Removes an element hiding filter
+ * @param {ElemHideFilter} filter
+ */
+ remove: function(filter)
+ {
+ if (!(filter.text in ElemHide.keyByFilter))
+ return;
+
+ let key = ElemHide.keyByFilter[filter.text];
+ delete filterByKey[key];
+ delete ElemHide.keyByFilter[filter.text];
+ ElemHide.isDirty = true;
+ },
+
+ /**
+ * Generates stylesheet URL and applies it globally
+ */
+ apply: function()
+ {
+
+
+ if (ElemHide.applied)
+ ElemHide.unapply();
+
+
+ try
+ {
+ // Return immediately if disabled
+ if (!Prefs.enabled)
+ {
+
+ return;
+ }
+
+ // CSS file doesn't need to be rewritten if nothing changed (e.g. we
+ // were disabled and reenabled)
+ if (ElemHide.isDirty)
+ {
+ ElemHide.isDirty = false;
+
+ // Grouping selectors by domains
+
+ let domains = {__proto__: null};
+ let hasFilters = false;
+ for (let key in filterByKey)
+ {
+ let filter = Filter.knownFilters[filterByKey[key]];
+ if (!filter)
+ {
+ // Something is wrong, we probably shouldn't have this filter in the first place
+ delete filterByKey[key];
+ continue;
+ }
+ let domain = filter.selectorDomain || "";
+
+ let list;
+ if (domain in domains)
+ list = domains[domain];
+ else
+ {
+ list = {__proto__: null};
+ domains[domain] = list;
+ }
+ list[filter.selector] = key;
+ hasFilters = true;
+ }
+
+
+ if (!hasFilters)
+ {
+
+ return;
+ }
+
+ // Writing out domains list
+
+
+ try {
+ // Make sure the file's parent directory exists
+ styleURL.file.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
+ } catch (e) {}
+
+ let stream;
+ try
+ {
+ stream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ stream.init(styleURL.file, 0x02 | 0x08 | 0x20, 0644, 0);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+
+ return;
+ }
+
+ let buf = [];
+ let maxBufLen = 1024;
+ function escapeChar(match)
+ {
+ return "\\" + match.charCodeAt(0).toString(16) + " ";
+ }
+ function writeString(str, forceWrite)
+ {
+ buf.push(str);
+ if (buf.length >= maxBufLen || forceWrite)
+ {
+ let output = buf.join("").replace(/[^\x01-\x7F]/g, escapeChar);
+ stream.write(output, output.length);
+ buf.splice(0, buf.length);
+ }
+ }
+
+ let cssTemplate = "-moz-binding: url(about:" + ElemHidePrivate.aboutPrefix + "?%ID%#dummy) !important;";
+ for (let domain in domains)
+ {
+ let rules = [];
+ let list = domains[domain];
+
+ if (domain)
+ writeString('@-moz-document domain("' + domain.split(",").join('"),domain("') + '"){\n');
+ else
+ {
+ // Only allow unqualified rules on a few protocols to prevent them from blocking chrome
+ writeString('@-moz-document url-prefix("http://"),url-prefix("https://"),'
+ + 'url-prefix("mailbox://"),url-prefix("imap://"),'
+ + 'url-prefix("news://"),url-prefix("snews://"){\n');
+ }
+
+ for (let selector in list)
+ writeString(selector + "{" + cssTemplate.replace("%ID%", list[selector]) + "}\n");
+ writeString('}\n');
+ }
+ writeString("", true);
+ try
+ {
+ stream.QueryInterface(Ci.nsISafeOutputStream).finish();
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+
+ return;
+ }
+
+ }
+
+ // Inserting new stylesheet
+
+ try
+ {
+ Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
+ ElemHide.applied = true;
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+
+ }
+ finally
+ {
+ FilterStorage.triggerObservers("elemhideupdate");
+ }
+ },
+
+ /**
+ * Unapplies current stylesheet URL
+ */
+ unapply: function()
+ {
+ if (ElemHide.applied)
+ {
+ try
+ {
+ Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ ElemHide.applied = false;
+ }
+ },
+
+ /**
+ * Retrieves the currently applied stylesheet URL
+ * @type String
+ */
+ get styleURL() ElemHide.applied ? styleURL.spec : null,
+
+ /**
+ * Retrieves an element hiding filter by the corresponding protocol key
+ */
+ getFilterByKey: function(/**String*/ key) /**Filter*/
+ {
+ return (key in filterByKey ? Filter.knownFilters[filterByKey[key]] : null);
+ },
+
+ /**
+ * Stores current state in a JSON'able object.
+ */
+ toCache: function(/**Object*/ cache)
+ {
+ cache.elemhide = {filterByKey: filterByKey};
+ },
+
+ /**
+ * Restores current state from an object.
+ */
+ fromCache: function(/**Object*/ cache)
+ {
+ filterByKey = cache.elemhide.filterByKey;
+ filterByKey.__proto__ = null;
+
+ // We don't want to initialize keyByFilter yet, do it when it is needed
+ delete ElemHide.keyByFilter;
+ ElemHide.__defineGetter__("keyByFilter", function()
+ {
+ let result = {__proto__: null};
+ for (let k in filterByKey)
+ result[filterByKey[k]] = k;
+ return ElemHide.keyByFilter = result;
+ });
+ ElemHide.__defineSetter__("keyByFilter", function(value)
+ {
+ delete ElemHide.keyByFilter;
+ return ElemHide.keyByFilter = value;
+ });
+ }
};
/**
@@ -368,40 +374,40 @@ var ElemHide =
*/
var ElemHidePrivate =
{
- classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
- classDescription: "Element hiding hit registration protocol handler",
- aboutPrefix: "abp-elemhidehit",
+ classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
+ classDescription: "Element hiding hit registration protocol handler",
+ aboutPrefix: "abp-elemhidehit",
- //
- // Factory implementation
- //
+ //
+ // Factory implementation
+ //
- createInstance: function(outer, iid)
- {
- if (outer != null)
- throw Cr.NS_ERROR_NO_AGGREGATION;
+ createInstance: function(outer, iid)
+ {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
- return this.QueryInterface(iid);
- },
+ return this.QueryInterface(iid);
+ },
- //
- // About module implementation
- //
+ //
+ // About module implementation
+ //
- getURIFlags: function(uri)
- {
- return ("HIDE_FROM_ABOUTABOUT" in Ci.nsIAboutModule ? Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT : 0);
- },
+ getURIFlags: function(uri)
+ {
+ return ("HIDE_FROM_ABOUTABOUT" in Ci.nsIAboutModule ? Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT : 0);
+ },
- newChannel: function(uri)
- {
- if (!/\?(\d+)/.test(uri.path))
- throw Cr.NS_ERROR_FAILURE;
+ newChannel: function(uri)
+ {
+ if (!/\?(\d+)/.test(uri.path))
+ throw Cr.NS_ERROR_FAILURE;
- return new HitRegistrationChannel(uri, RegExp.$1);
- },
+ return new HitRegistrationChannel(uri, RegExp.$1);
+ },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
};
/**
@@ -410,71 +416,71 @@ var ElemHidePrivate =
*/
function HitRegistrationChannel(uri, key)
{
- this.key = key;
- this.URI = this.originalURI = uri;
+ this.key = key;
+ this.URI = this.originalURI = uri;
}
HitRegistrationChannel.prototype = {
- key: null,
- URI: null,
- originalURI: null,
- contentCharset: "utf-8",
- contentLength: 0,
- contentType: "text/xml",
- owner: Utils.systemPrincipal,
- securityInfo: null,
- notificationCallbacks: null,
- loadFlags: 0,
- loadGroup: null,
- name: null,
- status: Cr.NS_OK,
-
- asyncOpen: function(listener, context)
- {
- let stream = this.open();
- Utils.runAsync(function()
- {
- try {
- listener.onStartRequest(this, context);
- } catch(e) {}
- try {
- listener.onDataAvailable(this, context, stream, 0, stream.available());
- } catch(e) {}
- try {
- listener.onStopRequest(this, context, Cr.NS_OK);
- } catch(e) {}
- }, this);
- },
-
- open: function()
- {
- let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy'/></bindings>";
- if (this.key in filterByKey)
- {
- let wnd = Utils.getRequestWindow(this);
- if (wnd && wnd.document && !Policy.processNode(wnd, wnd.document, Policy.type.ELEMHIDE, Filter.knownFilters[filterByKey[this.key]]))
- data = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
- }
-
- let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
- stream.setData(data, data.length);
- return stream;
- },
- isPending: function()
- {
- return false;
- },
- cancel: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- suspend: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- resume: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
+ key: null,
+ URI: null,
+ originalURI: null,
+ contentCharset: "utf-8",
+ contentLength: 0,
+ contentType: "text/xml",
+ owner: Utils.systemPrincipal,
+ securityInfo: null,
+ notificationCallbacks: null,
+ loadFlags: 0,
+ loadGroup: null,
+ name: null,
+ status: Cr.NS_OK,
+
+ asyncOpen: function(listener, context)
+ {
+ let stream = this.open();
+ Utils.runAsync(function()
+ {
+ try {
+ listener.onStartRequest(this, context);
+ } catch(e) {}
+ try {
+ listener.onDataAvailable(this, context, stream, 0, stream.available());
+ } catch(e) {}
+ try {
+ listener.onStopRequest(this, context, Cr.NS_OK);
+ } catch(e) {}
+ }, this);
+ },
+
+ open: function()
+ {
+ let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy'/></bindings>";
+ if (this.key in filterByKey)
+ {
+ let wnd = Utils.getRequestWindow(this);
+ if (wnd && wnd.document && !Policy.processNode(wnd, wnd.document, Policy.type.ELEMHIDE, Filter.knownFilters[filterByKey[this.key]]))
+ data = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
+ }
+
+ let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
+ stream.setData(data, data.length);
+ return stream;
+ },
+ isPending: function()
+ {
+ return false;
+ },
+ cancel: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ suspend: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ resume: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
};
diff --git a/modules/ElemHideRemote.jsm b/modules/ElemHideRemote.jsm
index 72ec0b6..eaa91c1 100644
--- a/modules/ElemHideRemote.jsm
+++ b/modules/ElemHideRemote.jsm
@@ -48,62 +48,62 @@ let styleURL = null;
*/
var ElemHideRemote =
{
- classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
- classDescription: "Element hiding hit registration protocol handler",
- aboutPrefix: "abp-elemhidehit",
-
- startup: function()
- {
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.registerFactory(ElemHideRemote.classID, ElemHideRemote.classDescription,
- "@mozilla.org/network/protocol/about;1?what=" + ElemHideRemote.aboutPrefix, ElemHideRemote);
-
- styleURL = Utils.makeURI(Utils.childMessageManager.sendSyncMessage("AdblockPlus:ElemHide:styleURL"));
- if (styleURL)
- Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
-
- // Get notified about style URL changes
- Utils.childMessageManager.addMessageListener("AdblockPlus:ElemHide:updateStyleURL", function(message)
- {
- if (styleURL)
- Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
-
- styleURL = Utils.makeURI(message.json);
- if (styleURL)
- Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
- });
- },
-
- //
- // Factory implementation
- //
-
- createInstance: function(outer, iid)
- {
- if (outer != null)
- throw Cr.NS_ERROR_NO_AGGREGATION;
-
- return this.QueryInterface(iid);
- },
-
- //
- // About module implementation
- //
-
- getURIFlags: function(uri)
- {
- return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
- },
-
- newChannel: function(uri)
- {
- if (!/\?(\d+)/.test(uri.path))
- throw Cr.NS_ERROR_FAILURE;
-
- return new HitRegistrationChannel(uri, RegExp.$1);
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
+ classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
+ classDescription: "Element hiding hit registration protocol handler",
+ aboutPrefix: "abp-elemhidehit",
+
+ startup: function()
+ {
+ let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
+ registrar.registerFactory(ElemHideRemote.classID, ElemHideRemote.classDescription,
+ "@mozilla.org/network/protocol/about;1?what=" + ElemHideRemote.aboutPrefix, ElemHideRemote);
+
+ styleURL = Utils.makeURI(Utils.childMessageManager.sendSyncMessage("AdblockPlus:ElemHide:styleURL"));
+ if (styleURL)
+ Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
+
+ // Get notified about style URL changes
+ Utils.childMessageManager.addMessageListener("AdblockPlus:ElemHide:updateStyleURL", function(message)
+ {
+ if (styleURL)
+ Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
+
+ styleURL = Utils.makeURI(message.json);
+ if (styleURL)
+ Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET);
+ });
+ },
+
+ //
+ // Factory implementation
+ //
+
+ createInstance: function(outer, iid)
+ {
+ if (outer != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+
+ return this.QueryInterface(iid);
+ },
+
+ //
+ // About module implementation
+ //
+
+ getURIFlags: function(uri)
+ {
+ return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
+ },
+
+ newChannel: function(uri)
+ {
+ if (!/\?(\d+)/.test(uri.path))
+ throw Cr.NS_ERROR_FAILURE;
+
+ return new HitRegistrationChannel(uri, RegExp.$1);
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
};
/**
@@ -112,78 +112,78 @@ var ElemHideRemote =
*/
function HitRegistrationChannel(uri, key)
{
- this.key = key;
- this.URI = this.originalURI = uri;
+ this.key = key;
+ this.URI = this.originalURI = uri;
}
HitRegistrationChannel.prototype = {
- key: null,
- URI: null,
- originalURI: null,
- contentCharset: "utf-8",
- contentLength: 0,
- contentType: "text/xml",
- owner: Utils.systemPrincipal,
- securityInfo: null,
- notificationCallbacks: null,
- loadFlags: 0,
- loadGroup: null,
- name: null,
- status: Cr.NS_OK,
-
- asyncOpen: function(listener, context)
- {
- let stream = this.open();
- Utils.runAsync(function()
- {
- try {
- listener.onStartRequest(this, context);
- } catch(e) {}
- try {
- listener.onDataAvailable(this, context, stream, 0, stream.available());
- } catch(e) {}
- try {
- listener.onStopRequest(this, context, Cr.NS_OK);
- } catch(e) {}
- }, this);
- },
-
- open: function()
- {
- let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy'/></bindings>";
- let wnd = Utils.getRequestWindow(this);
- if (wnd)
- {
- wnd = Utils.getOriginWindow(wnd);
- let result = Utils.childMessageManager.sendSyncMessage("AdblockPlus:ElemHide:checkHit", {
- key: this.key,
- wndLocation: wnd.location.href,
- topLocation: wnd.top.location.href})[0];
- if (result)
- data = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
- }
-
- let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
- stream.setData(data, data.length);
- return stream;
- },
- isPending: function()
- {
- return false;
- },
- cancel: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- suspend: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
- resume: function()
- {
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
+ key: null,
+ URI: null,
+ originalURI: null,
+ contentCharset: "utf-8",
+ contentLength: 0,
+ contentType: "text/xml",
+ owner: Utils.systemPrincipal,
+ securityInfo: null,
+ notificationCallbacks: null,
+ loadFlags: 0,
+ loadGroup: null,
+ name: null,
+ status: Cr.NS_OK,
+
+ asyncOpen: function(listener, context)
+ {
+ let stream = this.open();
+ Utils.runAsync(function()
+ {
+ try {
+ listener.onStartRequest(this, context);
+ } catch(e) {}
+ try {
+ listener.onDataAvailable(this, context, stream, 0, stream.available());
+ } catch(e) {}
+ try {
+ listener.onStopRequest(this, context, Cr.NS_OK);
+ } catch(e) {}
+ }, this);
+ },
+
+ open: function()
+ {
+ let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy'/></bindings>";
+ let wnd = Utils.getRequestWindow(this);
+ if (wnd)
+ {
+ wnd = Utils.getOriginWindow(wnd);
+ let result = Utils.childMessageManager.sendSyncMessage("AdblockPlus:ElemHide:checkHit", {
+ key: this.key,
+ wndLocation: wnd.location.href,
+ topLocation: wnd.top.location.href})[0];
+ if (result)
+ data = "<bindings xmlns='http://www.mozilla.org/xbl'/>";
+ }
+
+ let stream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
+ stream.setData(data, data.length);
+ return stream;
+ },
+ isPending: function()
+ {
+ return false;
+ },
+ cancel: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ suspend: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+ resume: function()
+ {
+ throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
};
ElemHideRemote.startup();
diff --git a/modules/FilterClasses.jsm b/modules/FilterClasses.jsm
index 8893f93..eb9317e 100644
--- a/modules/FilterClasses.jsm
+++ b/modules/FilterClasses.jsm
@@ -45,37 +45,37 @@ Cu.import(baseURL.spec + "Utils.jsm");
*/
function Filter(text)
{
- this.text = text;
- this.subscriptions = [];
+ this.text = text;
+ this.subscriptions = [];
}
Filter.prototype =
{
- /**
- * String representation of the filter
- * @type String
- */
- text: null,
-
- /**
- * Filter subscriptions the filter belongs to
- * @type Array of Subscription
- */
- subscriptions: null,
-
- /**
- * Serializes the filter to an array of strings for writing out on the disk.
- * @param {Array of String} buffer buffer to push the serialization results into
- */
- serialize: function(buffer)
- {
- buffer.push("[Filter]");
- buffer.push("text=" + this.text);
- },
-
- toString: function()
- {
- return this.text;
- }
+ /**
+ * String representation of the filter
+ * @type String
+ */
+ text: null,
+
+ /**
+ * Filter subscriptions the filter belongs to
+ * @type Array of Subscription
+ */
+ subscriptions: null,
+
+ /**
+ * Serializes the filter to an array of strings for writing out on the disk.
+ * @param {Array of String} buffer buffer to push the serialization results into
+ */
+ serialize: function(buffer)
+ {
+ buffer.push("[Filter]");
+ buffer.push("text=" + this.text);
+ },
+
+ toString: function()
+ {
+ return this.text;
+ }
};
/**
@@ -109,22 +109,22 @@ Filter.optionsRegExp = /\$(~?[\w\-]+(?:=[^,\s]+)?(?:,~?[\w\-]+(?:=[^,\s]+)?)*)$/
*/
Filter.fromText = function(text)
{
- if (text in Filter.knownFilters)
- return Filter.knownFilters[text];
-
- if (!/\S/.test(text))
- return null;
-
- let ret;
- if (Filter.elemhideRegExp.test(text))
- ret = ElemHideFilter.fromText(text, RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$4);
- else if (text[0] == "!")
- ret = new CommentFilter(text);
- else
- ret = RegExpFilter.fromText(text);
-
- Filter.knownFilters[ret.text] = ret;
- return ret;
+ if (text in Filter.knownFilters)
+ return Filter.knownFilters[text];
+
+ if (!/\S/.test(text))
+ return null;
+
+ let ret;
+ if (Filter.elemhideRegExp.test(text))
+ ret = ElemHideFilter.fromText(text, RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$4);
+ else if (text[0] == "!")
+ ret = new CommentFilter(text);
+ else
+ ret = RegExpFilter.fromText(text);
+
+ Filter.knownFilters[ret.text] = ret;
+ return ret;
}
/**
@@ -135,17 +135,17 @@ Filter.fromText = function(text)
*/
Filter.fromObject = function(obj)
{
- let ret = Filter.fromText(obj.text);
- if (ret instanceof ActiveFilter)
- {
- if ("disabled" in obj)
- ret.disabled = (obj.disabled == "true");
- if ("hitCount" in obj)
- ret.hitCount = parseInt(obj.hitCount) || 0;
- if ("lastHit" in obj)
- ret.lastHit = parseInt(obj.lastHit) || 0;
- }
- return ret;
+ let ret = Filter.fromText(obj.text);
+ if (ret instanceof ActiveFilter)
+ {
+ if ("disabled" in obj)
+ ret.disabled = (obj.disabled == "true");
+ if ("hitCount" in obj)
+ ret.hitCount = parseInt(obj.hitCount) || 0;
+ if ("lastHit" in obj)
+ ret.lastHit = parseInt(obj.lastHit) || 0;
+ }
+ return ret;
}
/**
@@ -154,26 +154,26 @@ Filter.fromObject = function(obj)
*/
Filter.normalize = function(/**String*/ text) /**String*/
{
- if (!text)
- return text;
-
- // Remove line breaks and such
- text = text.replace(/[^\S ]/g, "");
-
- if (/^\s*!/.test(text)) {
- // Don't remove spaces inside comments
- return text.replace(/^\s+/, "").replace(/\s+$/, "");
- }
- else if (Filter.elemhideRegExp.test(text)) {
- // Special treatment for element hiding filters, right side is allowed to contain spaces
- /^(.*?)(#+)(.*)$/.test(text); // .split(..., 2) will cut off the end of the string
- var domain = RegExp.$1;
- var separator = RegExp.$2;
- var selector = RegExp.$3;
- return domain.replace(/\s/g, "") + separator + selector.replace(/^\s+/, "").replace(/\s+$/, "");
- }
- else
- return text.replace(/\s/g, "");
+ if (!text)
+ return text;
+
+ // Remove line breaks and such
+ text = text.replace(/[^\S ]/g, "");
+
+ if (/^\s*!/.test(text)) {
+ // Don't remove spaces inside comments
+ return text.replace(/^\s+/, "").replace(/\s+$/, "");
+ }
+ else if (Filter.elemhideRegExp.test(text)) {
+ // Special treatment for element hiding filters, right side is allowed to contain spaces
+ /^(.*?)(#+)(.*)$/.test(text); // .split(..., 2) will cut off the end of the string
+ var domain = RegExp.$1;
+ var separator = RegExp.$2;
+ var selector = RegExp.$3;
+ return domain.replace(/\s/g, "") + separator + selector.replace(/^\s+/, "").replace(/\s+$/, "");
+ }
+ else
+ return text.replace(/\s/g, "");
}
/**
@@ -185,24 +185,24 @@ Filter.normalize = function(/**String*/ text) /**String*/
*/
function InvalidFilter(text, reason)
{
- Filter.call(this, text);
+ Filter.call(this, text);
- this.reason = reason;
+ this.reason = reason;
}
InvalidFilter.prototype =
{
- __proto__: Filter.prototype,
-
- /**
- * Reason why this filter is invalid
- * @type String
- */
- reason: null,
-
- /**
- * See Filter.serialize()
- */
- serialize: function(buffer) {}
+ __proto__: Filter.prototype,
+
+ /**
+ * Reason why this filter is invalid
+ * @type String
+ */
+ reason: null,
+
+ /**
+ * See Filter.serialize()
+ */
+ serialize: function(buffer) {}
};
/**
@@ -213,16 +213,16 @@ InvalidFilter.prototype =
*/
function CommentFilter(text)
{
- Filter.call(this, text);
+ Filter.call(this, text);
}
CommentFilter.prototype =
{
- __proto__: Filter.prototype,
+ __proto__: Filter.prototype,
- /**
- * See Filter.serialize()
- */
- serialize: function(buffer) {}
+ /**
+ * See Filter.serialize()
+ */
+ serialize: function(buffer) {}
};
/**
@@ -234,176 +234,176 @@ CommentFilter.prototype =
*/
function ActiveFilter(text, domains)
{
- Filter.call(this, text);
-
- if (domains)
- {
- this.domainSource = domains;
- this.__defineGetter__("includeDomains", this._getIncludeDomains);
- this.__defineGetter__("excludeDomains", this._getExcludeDomains);
- }
+ Filter.call(this, text);
+
+ if (domains)
+ {
+ this.domainSource = domains;
+ this.__defineGetter__("includeDomains", this._getIncludeDomains);
+ this.__defineGetter__("excludeDomains", this._getExcludeDomains);
+ }
}
ActiveFilter.prototype =
{
- __proto__: Filter.prototype,
-
- /**
- * Defines whether the filter is disabled
- * @type Boolean
- */
- disabled: false,
- /**
- * Number of hits on the filter since the last reset
- * @type Number
- */
- hitCount: 0,
- /**
- * Last time the filter had a hit (in milliseconds since the beginning of the epoch)
- * @type Number
- */
- lastHit: 0,
-
- /**
- * String that the includeDomains and excludeDomains properties should be generated from
- * @type String
- */
- domainSource: null,
-
- /**
- * Separator character used in domainSource property, must be overridden by subclasses
- * @type String
- */
- domainSeparator: null,
-
- /**
- * Map containing domains that this filter should match on or null if the filter should match on all domains
- * @type Object
- */
- includeDomains: null,
- /**
- * Map containing domains that this filter should not match on or null if the filter should match on all domains
- * @type Object
- */
- excludeDomains: null,
-
- /**
- * Called first time includeDomains property is requested, triggers _generateDomains method.
- */
- _getIncludeDomains: function()
- {
- this._generateDomains();
- return this.includeDomains;
- },
- /**
- * Called first time excludeDomains property is requested, triggers _generateDomains method.
- */
- _getExcludeDomains: function()
- {
- this._generateDomains();
- return this.excludeDomains;
- },
-
- /**
- * Generates includeDomains and excludeDomains properties when one of them is requested for the first time.
- */
- _generateDomains: function()
- {
- let domains = this.domainSource.split(this.domainSeparator);
-
- delete this.domainSource;
- delete this.includeDomains;
- delete this.excludeDomains;
-
- if (domains.length == 1 && domains[0][0] != "~")
- {
- // Fast track for the common one-domain scenario
- this.includeDomains = {__proto__: null};
- this.includeDomains[domains[0]] = true;
- }
- else
- {
- for each (let domain in domains)
- {
- if (domain == "")
- continue;
-
- let hash = "includeDomains";
- if (domain[0] == "~")
- {
- hash = "excludeDomains";
- domain = domain.substr(1);
- }
-
- if (!this[hash])
- this[hash] = {__proto__: null};
-
- this[hash][domain] = true;
- }
- }
- },
-
- /**
- * Checks whether this filter is active on a domain.
- */
- isActiveOnDomain: function(/**String*/ docDomain) /**Boolean*/
- {
- // If the document has no host name, match only if the filter isn't restricted to specific domains
- if (!docDomain)
- return (!this.includeDomains);
-
- if (!this.includeDomains && !this.excludeDomains)
- return true;
-
- docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
-
- while (true)
- {
- if (this.includeDomains && docDomain in this.includeDomains)
- return true;
- if (this.excludeDomains && docDomain in this.excludeDomains)
- return false;
-
- let nextDot = docDomain.indexOf(".");
- if (nextDot < 0)
- break;
- docDomain = docDomain.substr(nextDot + 1);
- }
- return (this.includeDomains == null);
- },
-
- /**
- * Checks whether this filter is active only on a domain and its subdomains.
- */
- isActiveOnlyOnDomain: function(/**String*/ docDomain) /**Boolean*/
- {
- if (!docDomain || !this.includeDomains)
- return false;
-
- docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
-
- for (let domain in this.includeDomains)
- if (domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))
- return false;
-
- return true;
- },
-
- /**
- * See Filter.serialize()
- */
- serialize: function(buffer)
- {
- if (this.disabled || this.hitCount || this.lastHit)
- {
- Filter.prototype.serialize.call(this, buffer);
- if (this.disabled)
- buffer.push("disabled=true");
- if (this.hitCount)
- buffer.push("hitCount=" + this.hitCount);
- if (this.lastHit)
- buffer.push("lastHit=" + this.lastHit);
- }
- }
+ __proto__: Filter.prototype,
+
+ /**
+ * Defines whether the filter is disabled
+ * @type Boolean
+ */
+ disabled: false,
+ /**
+ * Number of hits on the filter since the last reset
+ * @type Number
+ */
+ hitCount: 0,
+ /**
+ * Last time the filter had a hit (in milliseconds since the beginning of the epoch)
+ * @type Number
+ */
+ lastHit: 0,
+
+ /**
+ * String that the includeDomains and excludeDomains properties should be generated from
+ * @type String
+ */
+ domainSource: null,
+
+ /**
+ * Separator character used in domainSource property, must be overridden by subclasses
+ * @type String
+ */
+ domainSeparator: null,
+
+ /**
+ * Map containing domains that this filter should match on or null if the filter should match on all domains
+ * @type Object
+ */
+ includeDomains: null,
+ /**
+ * Map containing domains that this filter should not match on or null if the filter should match on all domains
+ * @type Object
+ */
+ excludeDomains: null,
+
+ /**
+ * Called first time includeDomains property is requested, triggers _generateDomains method.
+ */
+ _getIncludeDomains: function()
+ {
+ this._generateDomains();
+ return this.includeDomains;
+ },
+ /**
+ * Called first time excludeDomains property is requested, triggers _generateDomains method.
+ */
+ _getExcludeDomains: function()
+ {
+ this._generateDomains();
+ return this.excludeDomains;
+ },
+
+ /**
+ * Generates includeDomains and excludeDomains properties when one of them is requested for the first time.
+ */
+ _generateDomains: function()
+ {
+ let domains = this.domainSource.split(this.domainSeparator);
+
+ delete this.domainSource;
+ delete this.includeDomains;
+ delete this.excludeDomains;
+
+ if (domains.length == 1 && domains[0][0] != "~")
+ {
+ // Fast track for the common one-domain scenario
+ this.includeDomains = {__proto__: null};
+ this.includeDomains[domains[0]] = true;
+ }
+ else
+ {
+ for each (let domain in domains)
+ {
+ if (domain == "")
+ continue;
+
+ let hash = "includeDomains";
+ if (domain[0] == "~")
+ {
+ hash = "excludeDomains";
+ domain = domain.substr(1);
+ }
+
+ if (!this[hash])
+ this[hash] = {__proto__: null};
+
+ this[hash][domain] = true;
+ }
+ }
+ },
+
+ /**
+ * Checks whether this filter is active on a domain.
+ */
+ isActiveOnDomain: function(/**String*/ docDomain) /**Boolean*/
+ {
+ // If the document has no host name, match only if the filter isn't restricted to specific domains
+ if (!docDomain)
+ return (!this.includeDomains);
+
+ if (!this.includeDomains && !this.excludeDomains)
+ return true;
+
+ docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
+
+ while (true)
+ {
+ if (this.includeDomains && docDomain in this.includeDomains)
+ return true;
+ if (this.excludeDomains && docDomain in this.excludeDomains)
+ return false;
+
+ let nextDot = docDomain.indexOf(".");
+ if (nextDot < 0)
+ break;
+ docDomain = docDomain.substr(nextDot + 1);
+ }
+ return (this.includeDomains == null);
+ },
+
+ /**
+ * Checks whether this filter is active only on a domain and its subdomains.
+ */
+ isActiveOnlyOnDomain: function(/**String*/ docDomain) /**Boolean*/
+ {
+ if (!docDomain || !this.includeDomains)
+ return false;
+
+ docDomain = docDomain.replace(/\.+$/, "").toUpperCase();
+
+ for (let domain in this.includeDomains)
+ if (domain != docDomain && (domain.length <= docDomain.length || domain.indexOf("." + docDomain) != domain.length - docDomain.length - 1))
+ return false;
+
+ return true;
+ },
+
+ /**
+ * See Filter.serialize()
+ */
+ serialize: function(buffer)
+ {
+ if (this.disabled || this.hitCount || this.lastHit)
+ {
+ Filter.prototype.serialize.call(this, buffer);
+ if (this.disabled)
+ buffer.push("disabled=true");
+ if (this.hitCount)
+ buffer.push("hitCount=" + this.hitCount);
+ if (this.lastHit)
+ buffer.push("lastHit=" + this.lastHit);
+ }
+ }
};
/**
@@ -419,116 +419,116 @@ ActiveFilter.prototype =
*/
function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty)
{
- ActiveFilter.call(this, text, domains);
-
- if (contentType != null)
- this.contentType = contentType;
- if (matchCase)
- this.matchCase = matchCase;
- if (thirdParty != null)
- this.thirdParty = thirdParty;
-
- if (regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/")
- {
- // The filter is a regular expression - convert it immediately to catch syntax errors
- this.regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");
- }
- else
- {
- // No need to convert this filter to regular expression yet, do it on demand
- this.regexpSource = regexpSource;
- this.__defineGetter__("regexp", this._generateRegExp);
- }
+ ActiveFilter.call(this, text, domains);
+
+ if (contentType != null)
+ this.contentType = contentType;
+ if (matchCase)
+ this.matchCase = matchCase;
+ if (thirdParty != null)
+ this.thirdParty = thirdParty;
+
+ if (regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/")
+ {
+ // The filter is a regular expression - convert it immediately to catch syntax errors
+ this.regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i");
+ }
+ else
+ {
+ // No need to convert this filter to regular expression yet, do it on demand
+ this.regexpSource = regexpSource;
+ this.__defineGetter__("regexp", this._generateRegExp);
+ }
}
RegExpFilter.prototype =
{
- __proto__: ActiveFilter.prototype,
-
- /**
- * @see ActiveFilter.domainSeparator
- */
- domainSeparator: "|",
-
- /**
- * Expression from which a regular expression should be generated - for delayed creation of the regexp property
- * @type String
- */
- regexpSource: null,
- /**
- * Regular expression to be used when testing against this filter
- * @type RegExp
- */
- regexp: null,
- /**
- * Content types the filter applies to, combination of values from RegExpFilter.typeMap
- * @type Number
- */
- contentType: 0x7FFFFFFF,
- /**
- * Defines whether the filter should distinguish between lower and upper case letters
- * @type Boolean
- */
- matchCase: false,
- /**
- * Defines whether the filter should apply to third-party or first-party content only. Can be null (apply to all content).
- * @type Boolean
- */
- thirdParty: null,
-
- /**
- * Generates regexp property when it is requested for the first time.
- * @return {RegExp}
- */
- _generateRegExp: function()
- {
- // Remove multiple wildcards
- let source = this.regexpSource.replace(/\*+/g, "*");
-
- // Remove leading wildcards
- if (source[0] == "*")
- source = source.substr(1);
-
- // Remove trailing wildcards
- let pos = source.length - 1;
- if (pos >= 0 && source[pos] == "*")
- source = source.substr(0, pos);
-
- source = source.replace(/\^\|$/, "^") // remove anchors following separator placeholder
- .replace(/\W/g, "\\$&") // escape special symbols
- .replace(/\\\*/g, ".*") // replace wildcards by .*
- // process separator placeholders (all ANSI charaters but alphanumeric characters and _%.-)
- .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x80]|$)")
- .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^.\\/]+\\.)*?") // process extended anchor at expression start
- .replace(/^\\\|/, "^") // process anchor at expression start
- .replace(/\\\|$/, "$"); // process anchor at expression end
-
- let regexp = new RegExp(source, this.matchCase ? "" : "i");
-
- delete this.regexp;
- delete this.regexpSource;
- return (this.regexp = regexp);
- },
-
- /**
- * Tests whether the URL matches this filter
- * @param {String} location URL to be tested
- * @param {String} contentType content type identifier of the URL
- * @param {String} docDomain domain name of the document that loads the URL
- * @param {Boolean} thirdParty should be true if the URL is a third-party request
- * @return {Boolean} true in case of a match
- */
- matches: function(location, contentType, docDomain, thirdParty)
- {
- if (this.regexp.test(location) &&
- (RegExpFilter.typeMap[contentType] & this.contentType) != 0 &&
- (this.thirdParty == null || this.thirdParty == thirdParty) &&
- this.isActiveOnDomain(docDomain))
- {
- return true;
- }
-
- return false;
- }
+ __proto__: ActiveFilter.prototype,
+
+ /**
+ * @see ActiveFilter.domainSeparator
+ */
+ domainSeparator: "|",
+
+ /**
+ * Expression from which a regular expression should be generated - for delayed creation of the regexp property
+ * @type String
+ */
+ regexpSource: null,
+ /**
+ * Regular expression to be used when testing against this filter
+ * @type RegExp
+ */
+ regexp: null,
+ /**
+ * Content types the filter applies to, combination of values from RegExpFilter.typeMap
+ * @type Number
+ */
+ contentType: 0x7FFFFFFF,
+ /**
+ * Defines whether the filter should distinguish between lower and upper case letters
+ * @type Boolean
+ */
+ matchCase: false,
+ /**
+ * Defines whether the filter should apply to third-party or first-party content only. Can be null (apply to all content).
+ * @type Boolean
+ */
+ thirdParty: null,
+
+ /**
+ * Generates regexp property when it is requested for the first time.
+ * @return {RegExp}
+ */
+ _generateRegExp: function()
+ {
+ // Remove multiple wildcards
+ let source = this.regexpSource.replace(/\*+/g, "*");
+
+ // Remove leading wildcards
+ if (source[0] == "*")
+ source = source.substr(1);
+
+ // Remove trailing wildcards
+ let pos = source.length - 1;
+ if (pos >= 0 && source[pos] == "*")
+ source = source.substr(0, pos);
+
+ source = source.replace(/\^\|$/, "^") // remove anchors following separator placeholder
+ .replace(/\W/g, "\\$&") // escape special symbols
+ .replace(/\\\*/g, ".*") // replace wildcards by .*
+ // process separator placeholders (all ANSI charaters but alphanumeric characters and _%.-)
+ .replace(/\\\^/g, "(?:[\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x80]|$)")
+ .replace(/^\\\|\\\|/, "^[\\w\\-]+:\\/+(?!\\/)(?:[^.\\/]+\\.)*?") // process extended anchor at expression start
+ .replace(/^\\\|/, "^") // process anchor at expression start
+ .replace(/\\\|$/, "$"); // process anchor at expression end
+
+ let regexp = new RegExp(source, this.matchCase ? "" : "i");
+
+ delete this.regexp;
+ delete this.regexpSource;
+ return (this.regexp = regexp);
+ },
+
+ /**
+ * Tests whether the URL matches this filter
+ * @param {String} location URL to be tested
+ * @param {String} contentType content type identifier of the URL
+ * @param {String} docDomain domain name of the document that loads the URL
+ * @param {Boolean} thirdParty should be true if the URL is a third-party request
+ * @return {Boolean} true in case of a match
+ */
+ matches: function(location, contentType, docDomain, thirdParty)
+ {
+ if (this.regexp.test(location) &&
+ (RegExpFilter.typeMap[contentType] & this.contentType) != 0 &&
+ (this.thirdParty == null || this.thirdParty == thirdParty) &&
+ this.isActiveOnDomain(docDomain))
+ {
+ return true;
+ }
+
+ return false;
+ }
};
/**
@@ -537,98 +537,98 @@ RegExpFilter.prototype =
*/
RegExpFilter.fromText = function(text)
{
- let constructor = BlockingFilter;
- let origText = text;
- if (text.indexOf("@@") == 0)
- {
- constructor = WhitelistFilter;
- text = text.substr(2);
- }
-
- let contentType = null;
- let matchCase = null;
- let domains = null;
- let thirdParty = null;
- let collapse = null;
- let options;
- if (Filter.optionsRegExp.test(text))
- {
- options = RegExp.$1.toUpperCase().split(",");
- text = RegExp.leftContext;
- for each (let option in options)
- {
- let value;
- [option, value] = option.split("=", 2);
- option = option.replace(/-/, "_");
- if (option in RegExpFilter.typeMap)
- {
- if (contentType == null)
- contentType = 0;
- contentType |= RegExpFilter.typeMap[option];
- }
- else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap)
- {
- if (contentType == null)
- contentType = RegExpFilter.prototype.contentType;
- contentType &= ~RegExpFilter.typeMap[option.substr(1)];
- }
- else if (option == "MATCH_CASE")
- matchCase = true;
- else if (option == "DOMAIN" && typeof value != "undefined")
- domains = value;
- else if (option == "THIRD_PARTY")
- thirdParty = true;
- else if (option == "~THIRD_PARTY")
- thirdParty = false;
- else if (option == "COLLAPSE")
- collapse = true;
- else if (option == "~COLLAPSE")
- collapse = false;
- }
- }
-
- if (constructor == WhitelistFilter && (contentType == null || (contentType & RegExpFilter.typeMap.DOCUMENT)) &&
- (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text))
- {
- // Exception filters shouldn't apply to pages by default unless they start with a protocol name
- if (contentType == null)
- contentType = RegExpFilter.prototype.contentType;
- contentType &= ~RegExpFilter.typeMap.DOCUMENT;
- }
-
- try
- {
- return new constructor(origText, text, contentType, matchCase, domains, thirdParty, collapse);
- }
- catch (e)
- {
- return new InvalidFilter(text, e);
- }
+ let constructor = BlockingFilter;
+ let origText = text;
+ if (text.indexOf("@@") == 0)
+ {
+ constructor = WhitelistFilter;
+ text = text.substr(2);
+ }
+
+ let contentType = null;
+ let matchCase = null;
+ let domains = null;
+ let thirdParty = null;
+ let collapse = null;
+ let options;
+ if (Filter.optionsRegExp.test(text))
+ {
+ options = RegExp.$1.toUpperCase().split(",");
+ text = RegExp.leftContext;
+ for each (let option in options)
+ {
+ let value;
+ [option, value] = option.split("=", 2);
+ option = option.replace(/-/, "_");
+ if (option in RegExpFilter.typeMap)
+ {
+ if (contentType == null)
+ contentType = 0;
+ contentType |= RegExpFilter.typeMap[option];
+ }
+ else if (option[0] == "~" && option.substr(1) in RegExpFilter.typeMap)
+ {
+ if (contentType == null)
+ contentType = RegExpFilter.prototype.contentType;
+ contentType &= ~RegExpFilter.typeMap[option.substr(1)];
+ }
+ else if (option == "MATCH_CASE")
+ matchCase = true;
+ else if (option == "DOMAIN" && typeof value != "undefined")
+ domains = value;
+ else if (option == "THIRD_PARTY")
+ thirdParty = true;
+ else if (option == "~THIRD_PARTY")
+ thirdParty = false;
+ else if (option == "COLLAPSE")
+ collapse = true;
+ else if (option == "~COLLAPSE")
+ collapse = false;
+ }
+ }
+
+ if (constructor == WhitelistFilter && (contentType == null || (contentType & RegExpFilter.typeMap.DOCUMENT)) &&
+ (!options || options.indexOf("DOCUMENT") < 0) && !/^\|?[\w\-]+:/.test(text))
+ {
+ // Exception filters shouldn't apply to pages by default unless they start with a protocol name
+ if (contentType == null)
+ contentType = RegExpFilter.prototype.contentType;
+ contentType &= ~RegExpFilter.typeMap.DOCUMENT;
+ }
+
+ try
+ {
+ return new constructor(origText, text, contentType, matchCase, domains, thirdParty, collapse);
+ }
+ catch (e)
+ {
+ return new InvalidFilter(text, e);
+ }
}
/**
* Maps type strings like "SCRIPT" or "OBJECT" to bit masks
*/
RegExpFilter.typeMap = {
- OTHER: 1,
- SCRIPT: 2,
- IMAGE: 4,
- STYLESHEET: 8,
- OBJECT: 16,
- SUBDOCUMENT: 32,
- DOCUMENT: 64,
- XBL: 512,
- PING: 1024,
- XMLHTTPREQUEST: 2048,
- OBJECT_SUBREQUEST: 4096,
- DTD: 8192,
- MEDIA: 16384,
- FONT: 32768,
-
- BACKGROUND: 4, // Backwards compat, same as IMAGE
-
- DONOTTRACK: 0x20000000,
- ELEMHIDE: 0x40000000
+ OTHER: 1,
+ SCRIPT: 2,
+ IMAGE: 4,
+ STYLESHEET: 8,
+ OBJECT: 16,
+ SUBDOCUMENT: 32,
+ DOCUMENT: 64,
+ XBL: 512,
+ PING: 1024,
+ XMLHTTPREQUEST: 2048,
+ OBJECT_SUBREQUEST: 4096,
+ DTD: 8192,
+ MEDIA: 16384,
+ FONT: 32768,
+
+ BACKGROUND: 4, // Backwards compat, same as IMAGE
+
+ DONOTTRACK: 0x20000000,
+ ELEMHIDE: 0x40000000
};
// ELEMHIDE and DONOTTRACK option shouldn't be there by default
@@ -648,19 +648,19 @@ RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFi
*/
function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, collapse)
{
- RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
+ RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
- this.collapse = collapse;
+ this.collapse = collapse;
}
BlockingFilter.prototype =
{
- __proto__: RegExpFilter.prototype,
+ __proto__: RegExpFilter.prototype,
- /**
- * Defines whether the filter should collapse blocked content. Can be null (use the global preference).
- * @type Boolean
- */
- collapse: null
+ /**
+ * Defines whether the filter should collapse blocked content. Can be null (use the global preference).
+ * @type Boolean
+ */
+ collapse: null
};
/**
@@ -676,11 +676,11 @@ BlockingFilter.prototype =
*/
function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty)
{
- RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
+ RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty);
}
WhitelistFilter.prototype =
{
- __proto__: RegExpFilter.prototype
+ __proto__: RegExpFilter.prototype
}
/**
@@ -693,31 +693,31 @@ WhitelistFilter.prototype =
*/
function ElemHideFilter(text, domains, selector)
{
- ActiveFilter.call(this, text, domains ? domains.toUpperCase() : null);
+ ActiveFilter.call(this, text, domains ? domains.toUpperCase() : null);
- if (domains)
- this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "").toLowerCase();
- this.selector = selector;
+ if (domains)
+ this.selectorDomain = domains.replace(/,~[^,]+/g, "").replace(/^~[^,]+,?/, "").toLowerCase();
+ this.selector = selector;
}
ElemHideFilter.prototype =
{
- __proto__: ActiveFilter.prototype,
-
- /**
- * @see ActiveFilter.domainSeparator
- */
- domainSeparator: ",",
-
- /**
- * Host name or domain the filter should be restricted to (can be null for no restriction)
- * @type String
- */
- selectorDomain: null,
- /**
- * CSS selector for the HTML elements that should be hidden
- * @type String
- */
- selector: null
+ __proto__: ActiveFilter.prototype,
+
+ /**
+ * @see ActiveFilter.domainSeparator
+ */
+ domainSeparator: ",",
+
+ /**
+ * Host name or domain the filter should be restricted to (can be null for no restriction)
+ * @type String
+ */
+ selectorDomain: null,
+ /**
+ * CSS selector for the HTML elements that should be hidden
+ * @type String
+ */
+ selector: null
};
/**
@@ -732,37 +732,37 @@ ElemHideFilter.prototype =
*/
ElemHideFilter.fromText = function(text, domain, tagName, attrRules, selector)
{
- if (!selector)
- {
- if (tagName == "*")
- tagName = "";
-
- let id = null;
- let additional = "";
- if (attrRules) {
- attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g);
- for each (let rule in attrRules) {
- rule = rule.substr(1, rule.length - 2);
- let separatorPos = rule.indexOf("=");
- if (separatorPos > 0) {
- rule = rule.replace(/=/, '="') + '"';
- additional += "[" + rule + "]";
- }
- else {
- if (id)
- return new InvalidFilter(text, Utils.getString("filter_elemhide_duplicate_id"));
- else
- id = rule;
- }
- }
- }
-
- if (id)
- selector = tagName + "." + id + additional + "," + tagName + "#" + id + additional;
- else if (tagName || additional)
- selector = tagName + additional;
- else
- return new InvalidFilter(text, Utils.getString("filter_elemhide_nocriteria"));
- }
- return new ElemHideFilter(text, domain, selector);
+ if (!selector)
+ {
+ if (tagName == "*")
+ tagName = "";
+
+ let id = null;
+ let additional = "";
+ if (attrRules) {
+ attrRules = attrRules.match(/\([\w\-]+(?:[$^*]?=[^\(\)"]*)?\)/g);
+ for each (let rule in attrRules) {
+ rule = rule.substr(1, rule.length - 2);
+ let separatorPos = rule.indexOf("=");
+ if (separatorPos > 0) {
+ rule = rule.replace(/=/, '="') + '"';
+ additional += "[" + rule + "]";
+ }
+ else {
+ if (id)
+ return new InvalidFilter(text, Utils.getString("filter_elemhide_duplicate_id"));
+ else
+ id = rule;
+ }
+ }
+ }
+
+ if (id)
+ selector = tagName + "." + id + additional + "," + tagName + "#" + id + additional;
+ else if (tagName || additional)
+ selector = tagName + additional;
+ else
+ return new InvalidFilter(text, Utils.getString("filter_elemhide_nocriteria"));
+ }
+ return new ElemHideFilter(text, domain, selector);
}
diff --git a/modules/FilterListener.jsm b/modules/FilterListener.jsm
index f0aab55..683398f 100644
--- a/modules/FilterListener.jsm
+++ b/modules/FilterListener.jsm
@@ -35,7 +35,7 @@ const Cu = Components.utils;
let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
Cu.import(baseURL.spec + "FilterStorage.jsm");
Cu.import(baseURL.spec + "ElemHide.jsm");
Cu.import(baseURL.spec + "Matcher.jsm");
@@ -69,132 +69,132 @@ let isDirty = false;
*/
var FilterListener =
{
- /**
- * Called on module initialization, registers listeners for FilterStorage changes
- */
- startup: function()
- {
- TimeLine.enter("Entered FilterListener.startup()");
-
- FilterStorage.addObserver(function(action, items)
- {
- if (/^filters (.*)/.test(action))
- onFilterChange(RegExp.$1, items);
- else if (/^subscriptions (.*)/.test(action))
- onSubscriptionChange(RegExp.$1, items);
- else
- onGenericChange(action, items);
- });
-
- ElemHide.init();
-
- let initialized = false;
- let cacheFile = Utils.resolveFilePath(Prefs.data_directory);
- cacheFile.append("cache.js");
- if (cacheFile.exists())
- {
- // Yay, fast startup!
- try
- {
- TimeLine.log("Loading cache file");
- let stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- stream.init(cacheFile, 0x01, 0444, 0);
-
- let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
- let cache = json.decodeFromStream(stream, "UTF-8");
-
- stream.close();
-
- if (cache.version == cacheVersion && cache.patternsTimestamp == FilterStorage.sourceFile.clone().lastModifiedTime)
- {
- defaultMatcher.fromCache(cache);
- ElemHide.fromCache(cache);
-
- // We still need to load patterns.ini if certain properties are accessed
- var loadDone = false;
- function trapProperty(obj, prop)
- {
- var origValue = obj[prop];
- delete obj[prop];
- obj.__defineGetter__(prop, function()
- {
- delete obj[prop];
- obj[prop] = origValue;
- if (!loadDone)
- {
- TimeLine.enter("Entered delayed FilterStorage init");
- loadDone = true;
- FilterStorage.loadFromDisk(true);
- TimeLine.leave("Delayed FilterStorage init done");
- }
- return obj[prop];
- });
- obj.__defineSetter__(prop, function(value)
- {
- delete obj[prop];
- return obj[prop] = value;
- });
- }
-
- for each (let prop in ["fileProperties", "subscriptions", "knownSubscriptions",
- "addSubscription", "removeSubscription", "updateSubscriptionFilters",
- "addFilter", "removeFilter", "increaseHitCount", "resetHitCounts"])
- {
- trapProperty(FilterStorage, prop);
- }
- trapProperty(Filter, "fromText");
- trapProperty(Filter, "knownFilters");
- trapProperty(Subscription, "fromURL");
- trapProperty(Subscription, "knownSubscriptions");
-
- initialized = true;
- TimeLine.log("Done loading cache file");
-
- ElemHide.apply();
- }
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- }
-
- // If we failed to restore from cache - load patterns.ini
- if (!initialized)
- FilterStorage.loadFromDisk();
-
- TimeLine.log("done initializing data structures");
-
- Utils.observerService.addObserver(FilterListenerPrivate, "browser:purge-session-history", true);
- TimeLine.log("done adding observers");
-
- TimeLine.leave("FilterListener.startup() done");
- },
-
- /**
- * Called on module shutdown.
- */
- shutdown: function()
- {
- TimeLine.enter("Entered FilterListener.shutdown()");
- if (isDirty)
- FilterStorage.saveToDisk();
- TimeLine.leave("FilterListener.shutdown() done");
- },
-
- /**
- * Set to true when executing many changes, changes will only be fully applied after this variable is set to false again.
- * @type Boolean
- */
- get batchMode()
- {
- return batchMode;
- },
- set batchMode(value)
- {
- batchMode = value;
- flushElemHide();
- }
+ /**
+ * Called on module initialization, registers listeners for FilterStorage changes
+ */
+ startup: function()
+ {
+
+
+ FilterStorage.addObserver(function(action, items)
+ {
+ if (/^filters (.*)/.test(action))
+ onFilterChange(RegExp.$1, items);
+ else if (/^subscriptions (.*)/.test(action))
+ onSubscriptionChange(RegExp.$1, items);
+ else
+ onGenericChange(action, items);
+ });
+
+ ElemHide.init();
+
+ let initialized = false;
+ let cacheFile = Utils.resolveFilePath(Prefs.data_directory);
+ cacheFile.append("cache.js");
+ if (cacheFile.exists())
+ {
+ // Yay, fast startup!
+ try
+ {
+
+ let stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ stream.init(cacheFile, 0x01, 0444, 0);
+
+ let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+ let cache = json.decodeFromStream(stream, "UTF-8");
+
+ stream.close();
+
+ if (cache.version == cacheVersion && cache.patternsTimestamp == FilterStorage.sourceFile.clone().lastModifiedTime)
+ {
+ defaultMatcher.fromCache(cache);
+ ElemHide.fromCache(cache);
+
+ // We still need to load patterns.ini if certain properties are accessed
+ var loadDone = false;
+ function trapProperty(obj, prop)
+ {
+ var origValue = obj[prop];
+ delete obj[prop];
+ obj.__defineGetter__(prop, function()
+ {
+ delete obj[prop];
+ obj[prop] = origValue;
+ if (!loadDone)
+ {
+
+ loadDone = true;
+ FilterStorage.loadFromDisk(true);
+
+ }
+ return obj[prop];
+ });
+ obj.__defineSetter__(prop, function(value)
+ {
+ delete obj[prop];
+ return obj[prop] = value;
+ });
+ }
+
+ for each (let prop in ["fileProperties", "subscriptions", "knownSubscriptions",
+ "addSubscription", "removeSubscription", "updateSubscriptionFilters",
+ "addFilter", "removeFilter", "increaseHitCount", "resetHitCounts"])
+ {
+ trapProperty(FilterStorage, prop);
+ }
+ trapProperty(Filter, "fromText");
+ trapProperty(Filter, "knownFilters");
+ trapProperty(Subscription, "fromURL");
+ trapProperty(Subscription, "knownSubscriptions");
+
+ initialized = true;
+
+
+ ElemHide.apply();
+ }
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ }
+
+ // If we failed to restore from cache - load patterns.ini
+ if (!initialized)
+ FilterStorage.loadFromDisk();
+
+
+
+ Utils.observerService.addObserver(FilterListenerPrivate, "browser:purge-session-history", true);
+
+
+
+ },
+
+ /**
+ * Called on module shutdown.
+ */
+ shutdown: function()
+ {
+
+ if (isDirty)
+ FilterStorage.saveToDisk();
+
+ },
+
+ /**
+ * Set to true when executing many changes, changes will only be fully applied after this variable is set to false again.
+ * @type Boolean
+ */
+ get batchMode()
+ {
+ return batchMode;
+ },
+ set batchMode(value)
+ {
+ batchMode = value;
+ flushElemHide();
+ }
};
/**
@@ -203,17 +203,17 @@ var FilterListener =
*/
var FilterListenerPrivate =
{
- observe: function(subject, topic, data)
- {
- if (topic == "browser:purge-session-history" && Prefs.clearStatsOnHistoryPurge)
- {
- FilterStorage.resetHitCounts();
- FilterStorage.saveToDisk();
-
- Prefs.recentReports = "[]";
- }
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver])
+ observe: function(subject, topic, data)
+ {
+ if (topic == "browser:purge-session-history" && Prefs.clearStatsOnHistoryPurge)
+ {
+ FilterStorage.resetHitCounts();
+ FilterStorage.saveToDisk();
+
+ Prefs.recentReports = "[]";
+ }
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver])
};
/**
@@ -221,8 +221,8 @@ var FilterListenerPrivate =
*/
function flushElemHide()
{
- if (!batchMode && ElemHide.isDirty)
- ElemHide.apply();
+ if (!batchMode && ElemHide.isDirty)
+ ElemHide.apply();
}
/**
@@ -232,13 +232,13 @@ function flushElemHide()
*/
function addFilter(filter)
{
- if (!(filter instanceof ActiveFilter) || filter.disabled || (subscriptionFilter && filter.subscriptions.some(subscriptionFilter)))
- return;
+ if (!(filter instanceof ActiveFilter) || filter.disabled || (subscriptionFilter && filter.subscriptions.some(subscriptionFilter)))
+ return;
- if (filter instanceof RegExpFilter)
- defaultMatcher.add(filter);
- else if (filter instanceof ElemHideFilter)
- ElemHide.add(filter);
+ if (filter instanceof RegExpFilter)
+ defaultMatcher.add(filter);
+ else if (filter instanceof ElemHideFilter)
+ ElemHide.add(filter);
}
/**
@@ -248,13 +248,13 @@ function addFilter(filter)
*/
function removeFilter(filter)
{
- if (!(filter instanceof ActiveFilter) || (subscriptionFilter && filter.subscriptions.some(subscriptionFilter)))
- return;
+ if (!(filter instanceof ActiveFilter) || (subscriptionFilter && filter.subscriptions.some(subscriptionFilter)))
+ return;
- if (filter instanceof RegExpFilter)
- defaultMatcher.remove(filter);
- else if (filter instanceof ElemHideFilter)
- ElemHide.remove(filter);
+ if (filter instanceof RegExpFilter)
+ defaultMatcher.remove(filter);
+ else if (filter instanceof ElemHideFilter)
+ ElemHide.remove(filter);
}
/**
@@ -262,55 +262,55 @@ function removeFilter(filter)
*/
function onSubscriptionChange(action, subscriptions)
{
- isDirty = true;
-
- if (action != "remove")
- {
- subscriptions = subscriptions.filter(function(subscription)
- {
- // Ignore updates for subscriptions not in the list
- return subscription.url in FilterStorage.knownSubscriptions;
- });
- }
- if (!subscriptions.length)
- return;
-
- if (action == "add" || action == "enable" ||
- action == "remove" || action == "disable" ||
- action == "update")
- {
- let subscriptionMap = {__proto__: null};
- for each (let subscription in subscriptions)
- subscriptionMap[subscription.url] = true;
- subscriptionFilter = function(subscription)
- {
- return !(subscription.url in subscriptionMap) && !subscription.disabled;
- }
- }
- else
- subscriptionFilter = null;
-
- if (action == "add" || action == "enable" ||
- action == "remove" || action == "disable")
- {
- let method = (action == "add" || action == "enable" ? addFilter : removeFilter);
- for each (let subscription in subscriptions)
- if (subscription.filters && (action == "disable" || !subscription.disabled))
- subscription.filters.forEach(method);
- }
- else if (action == "update")
- {
- for each (let subscription in subscriptions)
- {
- if (!subscription.disabled)
- {
- subscription.oldFilters.forEach(removeFilter);
- subscription.filters.forEach(addFilter);
- }
- }
- }
-
- flushElemHide();
+ isDirty = true;
+
+ if (action != "remove")
+ {
+ subscriptions = subscriptions.filter(function(subscription)
+ {
+ // Ignore updates for subscriptions not in the list
+ return subscription.url in FilterStorage.knownSubscriptions;
+ });
+ }
+ if (!subscriptions.length)
+ return;
+
+ if (action == "add" || action == "enable" ||
+ action == "remove" || action == "disable" ||
+ action == "update")
+ {
+ let subscriptionMap = {__proto__: null};
+ for each (let subscription in subscriptions)
+ subscriptionMap[subscription.url] = true;
+ subscriptionFilter = function(subscription)
+ {
+ return !(subscription.url in subscriptionMap) && !subscription.disabled;
+ }
+ }
+ else
+ subscriptionFilter = null;
+
+ if (action == "add" || action == "enable" ||
+ action == "remove" || action == "disable")
+ {
+ let method = (action == "add" || action == "enable" ? addFilter : removeFilter);
+ for each (let subscription in subscriptions)
+ if (subscription.filters && (action == "disable" || !subscription.disabled))
+ subscription.filters.forEach(method);
+ }
+ else if (action == "update")
+ {
+ for each (let subscription in subscriptions)
+ {
+ if (!subscription.disabled)
+ {
+ subscription.oldFilters.forEach(removeFilter);
+ subscription.filters.forEach(addFilter);
+ }
+ }
+ }
+
+ flushElemHide();
}
/**
@@ -318,23 +318,23 @@ function onSubscriptionChange(action, subscriptions)
*/
function onFilterChange(action, filters)
{
- isDirty = true;
-
- if (action == "add" || action == "enable" ||
- action == "remove" || action == "disable")
- {
- subscriptionFilter = null;
-
- let method = (action == "add" || action == "enable" ? addFilter : removeFilter);
- filters = filters.filter(function(filter)
- {
- // For "remove" only consider filters that don't have any enabled
- // subscriptions, for other actions the filter that have them.
- return ((action != "remove") == filter.subscriptions.some(function(subscription) !subscription.disabled));
- });
- filters.forEach(method);
- flushElemHide();
- }
+ isDirty = true;
+
+ if (action == "add" || action == "enable" ||
+ action == "remove" || action == "disable")
+ {
+ subscriptionFilter = null;
+
+ let method = (action == "add" || action == "enable" ? addFilter : removeFilter);
+ filters = filters.filter(function(filter)
+ {
+ // For "remove" only consider filters that don't have any enabled
+ // subscriptions, for other actions the filter that have them.
+ return ((action != "remove") == filter.subscriptions.some(function(subscription) !subscription.disabled));
+ });
+ filters.forEach(method);
+ flushElemHide();
+ }
}
/**
@@ -342,50 +342,57 @@ function onFilterChange(action, filters)
*/
function onGenericChange(action)
{
- if (action == "load")
- {
- isDirty = false;
-
- defaultMatcher.clear();
- ElemHide.clear();
- for each (let subscription in FilterStorage.subscriptions)
- if (!subscription.disabled)
- subscription.filters.forEach(addFilter);
- flushElemHide();
- }
- else if (action == "save")
- {
- isDirty = false;
-
- let cache = {version: cacheVersion, patternsTimestamp: FilterStorage.sourceFile.clone().lastModifiedTime};
- defaultMatcher.toCache(cache);
- ElemHide.toCache(cache);
-
- let cacheFile = Utils.resolveFilePath(Prefs.data_directory);
- cacheFile.append("cache.js");
-
- try {
- // Make sure the file's parent directory exists
- cacheFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
- } catch (e) {}
-
- try
- {
- let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
- fileStream.init(cacheFile, 0x02 | 0x08 | 0x20, 0644, 0);
-
- let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
- stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
-
- // nsIJSON.encodeToStream would have been better but it is broken, see bug 633934
- let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
- stream.writeString(json.encode(cache));
- stream.close();
- }
- catch(e)
- {
- delete FilterStorage.fileProperties.cacheTimestamp;
- Cu.reportError(e);
- }
- }
+ if (action == "load")
+ {
+ isDirty = false;
+
+ defaultMatcher.clear();
+ ElemHide.clear();
+ for each (let subscription in FilterStorage.subscriptions)
+ if (!subscription.disabled)
+ subscription.filters.forEach(addFilter);
+ flushElemHide();
+ }
+ else if (action == "save")
+ {
+ isDirty = false;
+
+ let cache = {version: cacheVersion, patternsTimestamp: FilterStorage.sourceFile.clone().lastModifiedTime};
+ defaultMatcher.toCache(cache);
+ ElemHide.toCache(cache);
+
+ let cacheFile = Utils.resolveFilePath(Prefs.data_directory);
+ cacheFile.append("cache.js");
+
+ try {
+ // Make sure the file's parent directory exists
+ cacheFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
+ } catch (e) {}
+
+ try
+ {
+ let fileStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ fileStream.init(cacheFile, 0x02 | 0x08 | 0x20, 0644, 0);
+
+ let json = Cc["@mozilla.org/dom/json;1"].createInstance(Ci.nsIJSON);
+ if (Utils.versionComparator.compare(Utils.platformVersion, "5.0") >= 0)
+ {
+ json.encodeToStream(fileStream, "UTF-8", false, cache);
+ fileStream.close();
+ }
+ else
+ {
+ // nsIJSON.encodeToStream is broken in Gecko 4.0 and below, see bug 633934
+ let stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
+ stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ stream.writeString(json.encode(cache));
+ stream.close();
+ }
+ }
+ catch(e)
+ {
+ delete FilterStorage.fileProperties.cacheTimestamp;
+ Cu.reportError(e);
+ }
+ }
}
diff --git a/modules/FilterStorage.jsm b/modules/FilterStorage.jsm
index 9e9b0b0..0ac7c2b 100644
--- a/modules/FilterStorage.jsm
+++ b/modules/FilterStorage.jsm
@@ -39,7 +39,7 @@ Cu.import(baseURL.spec + "Utils.jsm");
Cu.import(baseURL.spec + "Prefs.jsm");
Cu.import(baseURL.spec + "FilterClasses.jsm");
Cu.import(baseURL.spec + "SubscriptionClasses.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
/**
* Version number of the filter storage file format.
@@ -59,520 +59,520 @@ let observers = [];
*/
var FilterStorage =
{
- /**
- * File that the filter list has been loaded from and should be saved to
- * @type nsIFile
- */
- get sourceFile()
- {
- let file = null;
- if (Prefs.patternsfile)
- {
- // Override in place, use it instead of placing the file in the regular data dir
- file = Utils.resolveFilePath(Prefs.patternsfile);
- }
- if (!file)
- {
- // Place the file in the data dir
- file = Utils.resolveFilePath(Prefs.data_directory);
- if (file)
- file.append("patterns.ini");
- }
- if (!file)
- {
- // Data directory pref misconfigured? Try the default value
- try
- {
- file = Utils.resolveFilePath(Prefs.defaultBranch.getCharPref("data_directory"));
- if (file)
- FilterStorage.sourceFile.append("patterns.ini");
- } catch(e) {}
- }
-
- if (!file)
- Cu.reportError("Adblock Plus: Failed to resolve filter file location from extensions.adblockplus.patternsfile preference");
-
- this.__defineGetter__("sourceFile", function() file);
- return this.sourceFile;
- },
-
- /**
- * Map of properties listed in the filter storage file before the sections
- * start. Right now this should be only the format version.
- */
- fileProperties: {__proto__: null},
-
- /**
- * List of filter subscriptions containing all filters
- * @type Array of Subscription
- */
- subscriptions: [],
-
- /**
- * Map of subscriptions already on the list, by their URL/identifier
- * @type Object
- */
- knownSubscriptions: {__proto__: null},
-
- /**
- * Adds an observer for filter and subscription changes (addition, deletion)
- * @param {function(String, Array)} observer
- */
- addObserver: function(observer)
- {
- if (observers.indexOf(observer) >= 0)
- return;
-
- observers.push(observer);
- },
-
- /**
- * Removes an observer previosly added with addObserver
- * @param {function(String, Array)} observer
- */
- removeObserver: function(observer)
- {
- let index = observers.indexOf(observer);
- if (index >= 0)
- observers.splice(index, 1);
- },
-
- /**
- * Calls observers after a change
- * @param {String} action change code ("load", "save", "elemhideupdate",
- * "subscriptions add", "subscriptions remove",
- * "subscriptions enable", "subscriptions disable",
- * "subscriptions update", "subscriptions updateinfo",
- * "filters add", "filters remove", "enable",
- * "filters disable", "filters hit")
- * @param {Array} items items that the change applies to
- * @param additionalData optional additional data, depends on change code
- */
- triggerObservers: function(action, items, additionalData)
- {
- for each (let observer in observers)
- observer(action, items, additionalData);
- },
-
- /**
- * Adds a filter subscription to the list
- * @param {Subscription} subscription filter subscription to be added
- * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
- */
- addSubscription: function(subscription, silent)
- {
- if (subscription.url in FilterStorage.knownSubscriptions)
- return;
-
- FilterStorage.subscriptions.push(subscription);
- FilterStorage.knownSubscriptions[subscription.url] = subscription;
- addSubscriptionFilters(subscription);
-
- if (!silent)
- FilterStorage.triggerObservers("subscriptions add", [subscription]);
- },
-
- /**
- * Removes a filter subscription from the list
- * @param {Subscription} subscription filter subscription to be removed
- * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
- */
- removeSubscription: function(subscription, silent)
- {
- for (let i = 0; i < FilterStorage.subscriptions.length; i++)
- {
- if (FilterStorage.subscriptions[i].url == subscription.url)
- {
- removeSubscriptionFilters(subscription);
-
- FilterStorage.subscriptions.splice(i--, 1);
- delete FilterStorage.knownSubscriptions[subscription.url];
- if (!silent)
- FilterStorage.triggerObservers("subscriptions remove", [subscription]);
- return;
- }
- }
- },
-
- /**
- * Replaces the list of filters in a subscription by a new list
- * @param {Subscription} subscription filter subscription to be updated
- * @param {Array of Filter} filters new filter lsit
- */
- updateSubscriptionFilters: function(subscription, filters)
- {
- removeSubscriptionFilters(subscription);
- subscription.oldFilters = subscription.filters;
- subscription.filters = filters;
- addSubscriptionFilters(subscription);
- FilterStorage.triggerObservers("subscriptions update", [subscription]);
- delete subscription.oldFilters;
-
- // Do not keep empty subscriptions disabled
- if (subscription instanceof SpecialSubscription && !subscription.filters.length && subscription.disabled)
- {
- subscription.disabled = false;
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- }
- },
-
- /**
- * Adds a user-defined filter to the list
- * @param {Filter} filter
- * @param {Filter} insertBefore filter to insert before (if possible)
- * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
- */
- addFilter: function(filter, insertBefore, silent)
- {
- let subscription = null;
- if (!subscription)
- {
- for each (let s in FilterStorage.subscriptions)
- {
- if (s instanceof SpecialSubscription && s.isFilterAllowed(filter))
- {
- if (s.filters.indexOf(filter) >= 0)
- return;
-
- if (!subscription || s.priority > subscription.priority)
- subscription = s;
- }
- }
- }
-
- if (!subscription)
- return;
-
- let insertIndex = -1;
- if (insertBefore)
- insertIndex = subscription.filters.indexOf(insertBefore);
-
- filter.subscriptions.push(subscription);
- if (insertIndex >= 0)
- subscription.filters.splice(insertIndex, 0, filter);
- else
- subscription.filters.push(filter);
- if (!silent)
- FilterStorage.triggerObservers("filters add", [filter], insertBefore);
- },
-
- /**
- * Removes a user-defined filter from the list
- * @param {Filter} filter
- * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
- */
- removeFilter: function(filter, silent)
- {
- for (let i = 0; i < filter.subscriptions.length; i++)
- {
- let subscription = filter.subscriptions[i];
- if (subscription instanceof SpecialSubscription)
- {
- for (let j = 0; j < subscription.filters.length; j++)
- {
- if (subscription.filters[j].text == filter.text)
- {
- filter.subscriptions.splice(i, 1);
- subscription.filters.splice(j, 1);
- if (!silent)
- FilterStorage.triggerObservers("filters remove", [filter]);
-
- // Do not keep empty subscriptions disabled
- if (!subscription.filters.length && subscription.disabled)
- {
- subscription.disabled = false;
- if (!silent)
- FilterStorage.triggerObservers("subscriptions enable", [subscription]);
- }
- return;
- }
- }
- }
- }
- },
-
- /**
- * Increases the hit count for a filter by one
- * @param {Filter} filter
- */
- increaseHitCount: function(filter)
- {
- if (!Prefs.savestats || Prefs.privateBrowsing || !(filter instanceof ActiveFilter))
- return;
-
- filter.hitCount++;
- filter.lastHit = Date.now();
- FilterStorage.triggerObservers("filters hit", [filter]);
- },
-
- /**
- * Resets hit count for some filters
- * @param {Array of Filter} filters filters to be reset, if null all filters will be reset
- */
- resetHitCounts: function(filters)
- {
- if (!filters)
- {
- filters = [];
- for each (let filter in Filter.knownFilters)
- filters.push(filter);
- }
- for each (let filter in filters)
- {
- filter.hitCount = 0;
- filter.lastHit = 0;
- }
- FilterStorage.triggerObservers("filters hit", filters);
- },
-
- /**
- * Loads all subscriptions from the disk
- * @param {Boolean} silent if true, no observers will be triggered (to be used when data is already initialized)
- */
- loadFromDisk: function(silent)
- {
- TimeLine.enter("Entered FilterStorage.loadFromDisk()");
-
- let realSourceFile = FilterStorage.sourceFile;
- if (!realSourceFile || !realSourceFile.exists())
- {
- // patterns.ini doesn't exist - but maybe we have a default one?
- let patternsURL = Utils.ioService.newURI("chrome://adblockplus-defaults/content/patterns.ini", null, null);
- patternsURL = Utils.chromeRegistry.convertChromeURL(patternsURL);
- if (patternsURL instanceof Ci.nsIFileURL)
- realSourceFile = patternsURL.file;
- }
-
- let userFilters = null;
- let backup = 0;
- while (true)
- {
- FilterStorage.subscriptions = [];
- FilterStorage.knownSubscriptions = {__proto__: null};
-
- try
- {
- if (realSourceFile && realSourceFile.exists())
- {
- let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- fileStream.init(realSourceFile, 0x01, 0444, 0);
-
- let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
- stream.init(fileStream, "UTF-8", 16384, 0);
- stream = stream.QueryInterface(Ci.nsIUnicharLineInputStream);
-
- userFilters = parseIniFile(stream);
- stream.close();
-
- if (!FilterStorage.subscriptions.length)
- {
- // No filter subscriptions in the file, this isn't right.
- throw "No data in the file";
- }
- }
-
- // We either successfully loaded filters or the source file doesn't exist
- // (already past last backup?). Either way, we should exit the loop now.
- break;
- }
- catch (e)
- {
- Cu.reportError("Adblock Plus: Failed to read filters from file " + realSourceFile.path);
- Cu.reportError(e);
- }
-
- // We failed loading filters, let's try next backup file
- realSourceFile = FilterStorage.sourceFile;
- if (realSourceFile)
- {
- let part1 = realSourceFile.leafName;
- let part2 = "";
- if (/^(.*)(\.\w+)$/.test(part1))
- {
- part1 = RegExp.$1;
- part2 = RegExp.$2;
- }
-
- realSourceFile = realSourceFile.clone();
- realSourceFile.leafName = part1 + "-backup" + (++backup) + part2;
- }
- }
-
- TimeLine.log("done parsing file");
-
- // Add missing special subscriptions if necessary
- for each (let specialSubscription in ["~il~", "~wl~", "~fl~", "~eh~"])
- {
- if (!(specialSubscription in FilterStorage.knownSubscriptions))
- {
- let subscription = Subscription.fromURL(specialSubscription);
- if (subscription)
- FilterStorage.addSubscription(subscription, true);
- }
- }
-
- if (userFilters)
- {
- for each (let filter in userFilters)
- {
- filter = Filter.fromText(filter);
- if (filter)
- FilterStorage.addFilter(filter, null, true);
- }
- }
-
- TimeLine.log("load complete, calling observers");
- if (!silent)
- FilterStorage.triggerObservers("load");
- TimeLine.leave("FilterStorage.loadFromDisk() done");
- },
-
- /**
- * Saves all subscriptions back to disk
- */
- saveToDisk: function()
- {
- if (!FilterStorage.sourceFile)
- return;
-
- TimeLine.enter("Entered FilterStorage.saveToDisk()");
-
- try {
- FilterStorage.sourceFile.normalize();
- } catch (e) {}
-
- // Make sure the file's parent directory exists
- try {
- FilterStorage.sourceFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
- } catch (e) {}
-
- let tempFile = FilterStorage.sourceFile.clone();
- tempFile.leafName += "-temp";
- let fileStream, stream;
- try {
- fileStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
- fileStream.init(tempFile, 0x02 | 0x08 | 0x20, 0644, 0);
-
- stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
- stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
- }
- catch (e)
- {
- Cu.reportError(e);
- TimeLine.leave("FilterStorage.saveToDisk() done (error opening file)");
- return;
- }
-
- TimeLine.log("created temp file");
-
- const maxBufLength = 1024;
- let buf = ["# Adblock Plus preferences", "version=" + formatVersion];
- let lineBreak = Utils.getLineBreak();
- function writeBuffer()
- {
- stream.writeString(buf.join(lineBreak) + lineBreak);
- buf.splice(0, buf.length);
- }
-
- let saved = {__proto__: null};
-
- // Save filter data
- for each (let subscription in FilterStorage.subscriptions)
- {
- // Do not persist external subscriptions
- if (subscription instanceof ExternalSubscription)
- continue;
-
- for each (let filter in subscription.filters)
- {
- if (!(filter.text in saved))
- {
- filter.serialize(buf);
- saved[filter.text] = filter;
- if (buf.length > maxBufLength)
- writeBuffer();
- }
- }
- }
- TimeLine.log("saved filter data");
-
- // Save subscriptions
- for each (let subscription in FilterStorage.subscriptions)
- {
- // Do not persist external subscriptions
- if (subscription instanceof ExternalSubscription)
- continue;
-
- buf.push("");
- subscription.serialize(buf);
- if (subscription.filters.length)
- {
- buf.push("", "[Subscription filters]")
- subscription.serializeFilters(buf);
- }
- if (buf.length > maxBufLength)
- writeBuffer();
- }
- TimeLine.log("saved subscription data");
-
- try
- {
- stream.writeString(buf.join(lineBreak) + lineBreak);
- stream.flush();
- fileStream.QueryInterface(Ci.nsISafeOutputStream).finish();
- }
- catch (e)
- {
- Cu.reportError(e);
- TimeLine.leave("FilterStorage.saveToDisk() done (error closing file)");
- return;
- }
- TimeLine.log("finalized file write");
-
- if (FilterStorage.sourceFile.exists()) {
- // Check whether we need to backup the file
- let part1 = FilterStorage.sourceFile.leafName;
- let part2 = "";
- if (/^(.*)(\.\w+)$/.test(part1))
- {
- part1 = RegExp.$1;
- part2 = RegExp.$2;
- }
-
- let doBackup = (Prefs.patternsbackups > 0);
- if (doBackup)
- {
- let lastBackup = FilterStorage.sourceFile.clone();
- lastBackup.leafName = part1 + "-backup1" + part2;
- if (lastBackup.exists() && (Date.now() - lastBackup.lastModifiedTime) / 3600000 < Prefs.patternsbackupinterval)
- doBackup = false;
- }
-
- if (doBackup)
- {
- let backupFile = FilterStorage.sourceFile.clone();
- backupFile.leafName = part1 + "-backup" + Prefs.patternsbackups + part2;
-
- // Remove oldest backup
- try {
- backupFile.remove(false);
- } catch (e) {}
-
- // Rename backup files
- for (let i = Prefs.patternsbackups - 1; i >= 0; i--) {
- backupFile.leafName = part1 + (i > 0 ? "-backup" + i : "") + part2;
- try {
- backupFile.moveTo(backupFile.parent, part1 + "-backup" + (i+1) + part2);
- } catch (e) {}
- }
- }
- }
-
- tempFile.moveTo(FilterStorage.sourceFile.parent, FilterStorage.sourceFile.leafName);
- TimeLine.log("created backups and renamed temp file");
- FilterStorage.triggerObservers("save");
- TimeLine.leave("FilterStorage.saveToDisk() done");
- }
+ /**
+ * File that the filter list has been loaded from and should be saved to
+ * @type nsIFile
+ */
+ get sourceFile()
+ {
+ let file = null;
+ if (Prefs.patternsfile)
+ {
+ // Override in place, use it instead of placing the file in the regular data dir
+ file = Utils.resolveFilePath(Prefs.patternsfile);
+ }
+ if (!file)
+ {
+ // Place the file in the data dir
+ file = Utils.resolveFilePath(Prefs.data_directory);
+ if (file)
+ file.append("patterns.ini");
+ }
+ if (!file)
+ {
+ // Data directory pref misconfigured? Try the default value
+ try
+ {
+ file = Utils.resolveFilePath(Prefs.defaultBranch.getCharPref("data_directory"));
+ if (file)
+ FilterStorage.sourceFile.append("patterns.ini");
+ } catch(e) {}
+ }
+
+ if (!file)
+ Cu.reportError("Adblock Plus: Failed to resolve filter file location from extensions.adblockplus.patternsfile preference");
+
+ this.__defineGetter__("sourceFile", function() file);
+ return this.sourceFile;
+ },
+
+ /**
+ * Map of properties listed in the filter storage file before the sections
+ * start. Right now this should be only the format version.
+ */
+ fileProperties: {__proto__: null},
+
+ /**
+ * List of filter subscriptions containing all filters
+ * @type Array of Subscription
+ */
+ subscriptions: [],
+
+ /**
+ * Map of subscriptions already on the list, by their URL/identifier
+ * @type Object
+ */
+ knownSubscriptions: {__proto__: null},
+
+ /**
+ * Adds an observer for filter and subscription changes (addition, deletion)
+ * @param {function(String, Array)} observer
+ */
+ addObserver: function(observer)
+ {
+ if (observers.indexOf(observer) >= 0)
+ return;
+
+ observers.push(observer);
+ },
+
+ /**
+ * Removes an observer previosly added with addObserver
+ * @param {function(String, Array)} observer
+ */
+ removeObserver: function(observer)
+ {
+ let index = observers.indexOf(observer);
+ if (index >= 0)
+ observers.splice(index, 1);
+ },
+
+ /**
+ * Calls observers after a change
+ * @param {String} action change code ("load", "save", "elemhideupdate",
+ * "subscriptions add", "subscriptions remove",
+ * "subscriptions enable", "subscriptions disable",
+ * "subscriptions update", "subscriptions updateinfo",
+ * "filters add", "filters remove", "enable",
+ * "filters disable", "filters hit")
+ * @param {Array} items items that the change applies to
+ * @param additionalData optional additional data, depends on change code
+ */
+ triggerObservers: function(action, items, additionalData)
+ {
+ for each (let observer in observers)
+ observer(action, items, additionalData);
+ },
+
+ /**
+ * Adds a filter subscription to the list
+ * @param {Subscription} subscription filter subscription to be added
+ * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
+ */
+ addSubscription: function(subscription, silent)
+ {
+ if (subscription.url in FilterStorage.knownSubscriptions)
+ return;
+
+ FilterStorage.subscriptions.push(subscription);
+ FilterStorage.knownSubscriptions[subscription.url] = subscription;
+ addSubscriptionFilters(subscription);
+
+ if (!silent)
+ FilterStorage.triggerObservers("subscriptions add", [subscription]);
+ },
+
+ /**
+ * Removes a filter subscription from the list
+ * @param {Subscription} subscription filter subscription to be removed
+ * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
+ */
+ removeSubscription: function(subscription, silent)
+ {
+ for (let i = 0; i < FilterStorage.subscriptions.length; i++)
+ {
+ if (FilterStorage.subscriptions[i].url == subscription.url)
+ {
+ removeSubscriptionFilters(subscription);
+
+ FilterStorage.subscriptions.splice(i--, 1);
+ delete FilterStorage.knownSubscriptions[subscription.url];
+ if (!silent)
+ FilterStorage.triggerObservers("subscriptions remove", [subscription]);
+ return;
+ }
+ }
+ },
+
+ /**
+ * Replaces the list of filters in a subscription by a new list
+ * @param {Subscription} subscription filter subscription to be updated
+ * @param {Array of Filter} filters new filter lsit
+ */
+ updateSubscriptionFilters: function(subscription, filters)
+ {
+ removeSubscriptionFilters(subscription);
+ subscription.oldFilters = subscription.filters;
+ subscription.filters = filters;
+ addSubscriptionFilters(subscription);
+ FilterStorage.triggerObservers("subscriptions update", [subscription]);
+ delete subscription.oldFilters;
+
+ // Do not keep empty subscriptions disabled
+ if (subscription instanceof SpecialSubscription && !subscription.filters.length && subscription.disabled)
+ {
+ subscription.disabled = false;
+ FilterStorage.triggerObservers("subscriptions enable", [subscription]);
+ }
+ },
+
+ /**
+ * Adds a user-defined filter to the list
+ * @param {Filter} filter
+ * @param {Filter} insertBefore filter to insert before (if possible)
+ * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
+ */
+ addFilter: function(filter, insertBefore, silent)
+ {
+ let subscription = null;
+ if (!subscription)
+ {
+ for each (let s in FilterStorage.subscriptions)
+ {
+ if (s instanceof SpecialSubscription && s.isFilterAllowed(filter))
+ {
+ if (s.filters.indexOf(filter) >= 0)
+ return;
+
+ if (!subscription || s.priority > subscription.priority)
+ subscription = s;
+ }
+ }
+ }
+
+ if (!subscription)
+ return;
+
+ let insertIndex = -1;
+ if (insertBefore)
+ insertIndex = subscription.filters.indexOf(insertBefore);
+
+ filter.subscriptions.push(subscription);
+ if (insertIndex >= 0)
+ subscription.filters.splice(insertIndex, 0, filter);
+ else
+ subscription.filters.push(filter);
+ if (!silent)
+ FilterStorage.triggerObservers("filters add", [filter], insertBefore);
+ },
+
+ /**
+ * Removes a user-defined filter from the list
+ * @param {Filter} filter
+ * @param {Boolean} silent if true, no observers will be triggered (to be used when filter list is reloaded)
+ */
+ removeFilter: function(filter, silent)
+ {
+ for (let i = 0; i < filter.subscriptions.length; i++)
+ {
+ let subscription = filter.subscriptions[i];
+ if (subscription instanceof SpecialSubscription)
+ {
+ for (let j = 0; j < subscription.filters.length; j++)
+ {
+ if (subscription.filters[j].text == filter.text)
+ {
+ filter.subscriptions.splice(i, 1);
+ subscription.filters.splice(j, 1);
+ if (!silent)
+ FilterStorage.triggerObservers("filters remove", [filter]);
+
+ // Do not keep empty subscriptions disabled
+ if (!subscription.filters.length && subscription.disabled)
+ {
+ subscription.disabled = false;
+ if (!silent)
+ FilterStorage.triggerObservers("subscriptions enable", [subscription]);
+ }
+ return;
+ }
+ }
+ }
+ }
+ },
+
+ /**
+ * Increases the hit count for a filter by one
+ * @param {Filter} filter
+ */
+ increaseHitCount: function(filter)
+ {
+ if (!Prefs.savestats || Prefs.privateBrowsing || !(filter instanceof ActiveFilter))
+ return;
+
+ filter.hitCount++;
+ filter.lastHit = Date.now();
+ FilterStorage.triggerObservers("filters hit", [filter]);
+ },
+
+ /**
+ * Resets hit count for some filters
+ * @param {Array of Filter} filters filters to be reset, if null all filters will be reset
+ */
+ resetHitCounts: function(filters)
+ {
+ if (!filters)
+ {
+ filters = [];
+ for each (let filter in Filter.knownFilters)
+ filters.push(filter);
+ }
+ for each (let filter in filters)
+ {
+ filter.hitCount = 0;
+ filter.lastHit = 0;
+ }
+ FilterStorage.triggerObservers("filters hit", filters);
+ },
+
+ /**
+ * Loads all subscriptions from the disk
+ * @param {Boolean} silent if true, no observers will be triggered (to be used when data is already initialized)
+ */
+ loadFromDisk: function(silent)
+ {
+
+
+ let realSourceFile = FilterStorage.sourceFile;
+ if (!realSourceFile || !realSourceFile.exists())
+ {
+ // patterns.ini doesn't exist - but maybe we have a default one?
+ let patternsURL = Utils.ioService.newURI("chrome://adblockplus-defaults/content/patterns.ini", null, null);
+ patternsURL = Utils.chromeRegistry.convertChromeURL(patternsURL);
+ if (patternsURL instanceof Ci.nsIFileURL)
+ realSourceFile = patternsURL.file;
+ }
+
+ let userFilters = null;
+ let backup = 0;
+ while (true)
+ {
+ FilterStorage.subscriptions = [];
+ FilterStorage.knownSubscriptions = {__proto__: null};
+
+ try
+ {
+ if (realSourceFile && realSourceFile.exists())
+ {
+ let fileStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ fileStream.init(realSourceFile, 0x01, 0444, 0);
+
+ let stream = Cc["@mozilla.org/intl/converter-input-stream;1"].createInstance(Ci.nsIConverterInputStream);
+ stream.init(fileStream, "UTF-8", 16384, 0);
+ stream = stream.QueryInterface(Ci.nsIUnicharLineInputStream);
+
+ userFilters = parseIniFile(stream);
+ stream.close();
+
+ if (!FilterStorage.subscriptions.length)
+ {
+ // No filter subscriptions in the file, this isn't right.
+ throw "No data in the file";
+ }
+ }
+
+ // We either successfully loaded filters or the source file doesn't exist
+ // (already past last backup?). Either way, we should exit the loop now.
+ break;
+ }
+ catch (e)
+ {
+ Cu.reportError("Adblock Plus: Failed to read filters from file " + realSourceFile.path);
+ Cu.reportError(e);
+ }
+
+ // We failed loading filters, let's try next backup file
+ realSourceFile = FilterStorage.sourceFile;
+ if (realSourceFile)
+ {
+ let part1 = realSourceFile.leafName;
+ let part2 = "";
+ if (/^(.*)(\.\w+)$/.test(part1))
+ {
+ part1 = RegExp.$1;
+ part2 = RegExp.$2;
+ }
+
+ realSourceFile = realSourceFile.clone();
+ realSourceFile.leafName = part1 + "-backup" + (++backup) + part2;
+ }
+ }
+
+
+
+ // Add missing special subscriptions if necessary
+ for each (let specialSubscription in ["~il~", "~wl~", "~fl~", "~eh~"])
+ {
+ if (!(specialSubscription in FilterStorage.knownSubscriptions))
+ {
+ let subscription = Subscription.fromURL(specialSubscription);
+ if (subscription)
+ FilterStorage.addSubscription(subscription, true);
+ }
+ }
+
+ if (userFilters)
+ {
+ for each (let filter in userFilters)
+ {
+ filter = Filter.fromText(filter);
+ if (filter)
+ FilterStorage.addFilter(filter, null, true);
+ }
+ }
+
+
+ if (!silent)
+ FilterStorage.triggerObservers("load");
+
+ },
+
+ /**
+ * Saves all subscriptions back to disk
+ */
+ saveToDisk: function()
+ {
+ if (!FilterStorage.sourceFile)
+ return;
+
+
+
+ try {
+ FilterStorage.sourceFile.normalize();
+ } catch (e) {}
+
+ // Make sure the file's parent directory exists
+ try {
+ FilterStorage.sourceFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, 0755);
+ } catch (e) {}
+
+ let tempFile = FilterStorage.sourceFile.clone();
+ tempFile.leafName += "-temp";
+ let fileStream, stream;
+ try {
+ fileStream = Cc["@mozilla.org/network/safe-file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
+ fileStream.init(tempFile, 0x02 | 0x08 | 0x20, 0644, 0);
+
+ stream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance(Ci.nsIConverterOutputStream);
+ stream.init(fileStream, "UTF-8", 16384, Ci.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+
+ return;
+ }
+
+
+
+ const maxBufLength = 1024;
+ let buf = ["# Adblock Plus preferences", "version=" + formatVersion];
+ let lineBreak = Utils.getLineBreak();
+ function writeBuffer()
+ {
+ stream.writeString(buf.join(lineBreak) + lineBreak);
+ buf.splice(0, buf.length);
+ }
+
+ let saved = {__proto__: null};
+
+ // Save filter data
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ // Do not persist external subscriptions
+ if (subscription instanceof ExternalSubscription)
+ continue;
+
+ for each (let filter in subscription.filters)
+ {
+ if (!(filter.text in saved))
+ {
+ filter.serialize(buf);
+ saved[filter.text] = filter;
+ if (buf.length > maxBufLength)
+ writeBuffer();
+ }
+ }
+ }
+
+
+ // Save subscriptions
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ // Do not persist external subscriptions
+ if (subscription instanceof ExternalSubscription)
+ continue;
+
+ buf.push("");
+ subscription.serialize(buf);
+ if (subscription.filters.length)
+ {
+ buf.push("", "[Subscription filters]")
+ subscription.serializeFilters(buf);
+ }
+ if (buf.length > maxBufLength)
+ writeBuffer();
+ }
+
+
+ try
+ {
+ stream.writeString(buf.join(lineBreak) + lineBreak);
+ stream.flush();
+ fileStream.QueryInterface(Ci.nsISafeOutputStream).finish();
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+
+ return;
+ }
+
+
+ if (FilterStorage.sourceFile.exists()) {
+ // Check whether we need to backup the file
+ let part1 = FilterStorage.sourceFile.leafName;
+ let part2 = "";
+ if (/^(.*)(\.\w+)$/.test(part1))
+ {
+ part1 = RegExp.$1;
+ part2 = RegExp.$2;
+ }
+
+ let doBackup = (Prefs.patternsbackups > 0);
+ if (doBackup)
+ {
+ let lastBackup = FilterStorage.sourceFile.clone();
+ lastBackup.leafName = part1 + "-backup1" + part2;
+ if (lastBackup.exists() && (Date.now() - lastBackup.lastModifiedTime) / 3600000 < Prefs.patternsbackupinterval)
+ doBackup = false;
+ }
+
+ if (doBackup)
+ {
+ let backupFile = FilterStorage.sourceFile.clone();
+ backupFile.leafName = part1 + "-backup" + Prefs.patternsbackups + part2;
+
+ // Remove oldest backup
+ try {
+ backupFile.remove(false);
+ } catch (e) {}
+
+ // Rename backup files
+ for (let i = Prefs.patternsbackups - 1; i >= 0; i--) {
+ backupFile.leafName = part1 + (i > 0 ? "-backup" + i : "") + part2;
+ try {
+ backupFile.moveTo(backupFile.parent, part1 + "-backup" + (i+1) + part2);
+ } catch (e) {}
+ }
+ }
+ }
+
+ tempFile.moveTo(FilterStorage.sourceFile.parent, FilterStorage.sourceFile.leafName);
+
+ FilterStorage.triggerObservers("save");
+
+ }
};
/**
@@ -581,11 +581,11 @@ var FilterStorage =
*/
function addSubscriptionFilters(subscription)
{
- if (!(subscription.url in FilterStorage.knownSubscriptions))
- return;
+ if (!(subscription.url in FilterStorage.knownSubscriptions))
+ return;
- for each (let filter in subscription.filters)
- filter.subscriptions.push(subscription);
+ for each (let filter in subscription.filters)
+ filter.subscriptions.push(subscription);
}
/**
@@ -594,15 +594,15 @@ function addSubscriptionFilters(subscription)
*/
function removeSubscriptionFilters(subscription)
{
- if (!(subscription.url in FilterStorage.knownSubscriptions))
- return;
-
- for each (let filter in subscription.filters)
- {
- let i = filter.subscriptions.indexOf(subscription);
- if (i >= 0)
- filter.subscriptions.splice(i, 1);
- }
+ if (!(subscription.url in FilterStorage.knownSubscriptions))
+ return;
+
+ for each (let filter in subscription.filters)
+ {
+ let i = filter.subscriptions.indexOf(subscription);
+ if (i >= 0)
+ filter.subscriptions.splice(i, 1);
+ }
}
/**
@@ -612,88 +612,88 @@ function removeSubscriptionFilters(subscription)
*/
function parseIniFile(/**nsIUnicharLineInputStream*/ stream) /**Array of String*/
{
- let wantObj = true;
- FilterStorage.fileProperties = {};
- let curObj = FilterStorage.fileProperties;
- let curSection = null;
- let line = {};
- let haveMore = true;
- let userFilters = null;
- while (true)
- {
- if (haveMore)
- haveMore = stream.readLine(line);
- else
- line.value = "[end]";
-
- let val = line.value;
- if (wantObj === true && /^(\w+)=(.*)$/.test(val))
- curObj[RegExp.$1] = RegExp.$2;
- else if (/^\s*\[(.+)\]\s*$/.test(val))
- {
- let newSection = RegExp.$1.toLowerCase();
- if (curObj)
- {
- // Process current object before going to next section
- switch (curSection)
- {
- case "filter":
- case "pattern":
- if ("text" in curObj)
- Filter.fromObject(curObj);
- break;
- case "subscription":
- let subscription = Subscription.fromObject(curObj);
- if (subscription)
- FilterStorage.addSubscription(subscription, true);
- break;
- case "subscription filters":
- case "subscription patterns":
- if (FilterStorage.subscriptions.length)
- {
- let subscription = FilterStorage.subscriptions[FilterStorage.subscriptions.length - 1];
- for each (let text in curObj)
- {
- let filter = Filter.fromText(text);
- if (filter)
- {
- subscription.filters.push(filter);
- filter.subscriptions.push(subscription);
- }
- }
- }
- break;
- case "user patterns":
- userFilters = curObj;
- break;
- }
- }
-
- if (newSection == 'end')
- break;
-
- curSection = newSection;
- switch (curSection)
- {
- case "filter":
- case "pattern":
- case "subscription":
- wantObj = true;
- curObj = {};
- break;
- case "subscription filters":
- case "subscription patterns":
- case "user patterns":
- wantObj = false;
- curObj = [];
- break;
- default:
- wantObj = undefined;
- curObj = null;
- }
- }
- else if (wantObj === false && val)
- curObj.push(val.replace(/\\\[/g, "["));
- }
- return userFilters;
+ let wantObj = true;
+ FilterStorage.fileProperties = {};
+ let curObj = FilterStorage.fileProperties;
+ let curSection = null;
+ let line = {};
+ let haveMore = true;
+ let userFilters = null;
+ while (true)
+ {
+ if (haveMore)
+ haveMore = stream.readLine(line);
+ else
+ line.value = "[end]";
+
+ let val = line.value;
+ if (wantObj === true && /^(\w+)=(.*)$/.test(val))
+ curObj[RegExp.$1] = RegExp.$2;
+ else if (/^\s*\[(.+)\]\s*$/.test(val))
+ {
+ let newSection = RegExp.$1.toLowerCase();
+ if (curObj)
+ {
+ // Process current object before going to next section
+ switch (curSection)
+ {
+ case "filter":
+ case "pattern":
+ if ("text" in curObj)
+ Filter.fromObject(curObj);
+ break;
+ case "subscription":
+ let subscription = Subscription.fromObject(curObj);
+ if (subscription)
+ FilterStorage.addSubscription(subscription, true);
+ break;
+ case "subscription filters":
+ case "subscription patterns":
+ if (FilterStorage.subscriptions.length)
+ {
+ let subscription = FilterStorage.subscriptions[FilterStorage.subscriptions.length - 1];
+ for each (let text in curObj)
+ {
+ let filter = Filter.fromText(text);
+ if (filter)
+ {
+ subscription.filters.push(filter);
+ filter.subscriptions.push(subscription);
+ }
+ }
+ }
+ break;
+ case "user patterns":
+ userFilters = curObj;
+ break;
+ }
+ }
+
+ if (newSection == 'end')
+ break;
+
+ curSection = newSection;
+ switch (curSection)
+ {
+ case "filter":
+ case "pattern":
+ case "subscription":
+ wantObj = true;
+ curObj = {};
+ break;
+ case "subscription filters":
+ case "subscription patterns":
+ case "user patterns":
+ wantObj = false;
+ curObj = [];
+ break;
+ default:
+ wantObj = undefined;
+ curObj = null;
+ }
+ }
+ else if (wantObj === false && val)
+ curObj.push(val.replace(/\\\[/g, "["));
+ }
+ return userFilters;
}
diff --git a/modules/Matcher.jsm b/modules/Matcher.jsm
index a443bc5..d205b06 100644
--- a/modules/Matcher.jsm
+++ b/modules/Matcher.jsm
@@ -42,271 +42,271 @@ Cu.import(baseURL.spec + "FilterClasses.jsm");
*/
function Matcher()
{
- this.clear();
+ this.clear();
}
Matcher.prototype = {
- /**
- * Lookup table for filters by their associated keyword
- * @type Object
- */
- filterByKeyword: null,
-
- /**
- * Lookup table for keywords by the filter text
- * @type Object
- */
- keywordByFilter: null,
-
- /**
- * Removes all known filters
- */
- clear: function()
- {
- this.filterByKeyword = {__proto__: null};
- this.keywordByFilter = {__proto__: null};
- },
-
- /**
- * Adds a filter to the matcher
- * @param {RegExpFilter} filter
- */
- add: function(filter)
- {
- if (filter.text in this.keywordByFilter)
- return;
-
- // Look for a suitable keyword
- let keyword = this.findKeyword(filter);
- switch (typeof this.filterByKeyword[keyword])
- {
- case "undefined":
- this.filterByKeyword[keyword] = filter.text;
- break;
- case "string":
- this.filterByKeyword[keyword] = [this.filterByKeyword[keyword], filter.text];
- break;
- default:
- this.filterByKeyword[keyword].push(filter.text);
- break;
- }
- this.keywordByFilter[filter.text] = keyword;
- },
-
- /**
- * Removes a filter from the matcher
- * @param {RegExpFilter} filter
- */
- remove: function(filter)
- {
- if (!(filter.text in this.keywordByFilter))
- return;
-
- let keyword = this.keywordByFilter[filter.text];
- let list = this.filterByKeyword[keyword];
- if (typeof list == "string")
- delete this.filterByKeyword[keyword];
- else
- {
- let index = list.indexOf(filter.text);
- if (index >= 0)
- {
- list.splice(index, 1);
- if (list.length == 1)
- this.filterByKeyword[keyword] = list[0];
- }
- }
-
- delete this.keywordByFilter[filter.text];
- },
-
- /**
- * Chooses a keyword to be associated with the filter
- * @param {String} text text representation of the filter
- * @return {String} keyword (might be empty string)
- */
- findKeyword: function(filter)
- {
- // For donottrack filters use "donottrack" as keyword if nothing else matches
- let defaultResult = (filter.contentType & RegExpFilter.typeMap.DONOTTRACK ? "donottrack" : "");
-
- let text = filter.text;
- if (Filter.regexpRegExp.test(text))
- return defaultResult;
-
- // Remove options
- if (Filter.optionsRegExp.test(text))
- text = RegExp.leftContext;
-
- // Remove whitelist marker
- if (text.substr(0, 2) == "@@")
- text = text.substr(2);
-
- let candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g);
- if (!candidates)
- return defaultResult;
-
- let hash = this.filterByKeyword;
- let result = defaultResult;
- let resultCount = 0xFFFFFF;
- let resultLength = 0;
- for (let i = 0, l = candidates.length; i < l; i++)
- {
- let candidate = candidates[i].substr(1);
- let count;
- switch (typeof hash[candidate])
- {
- case "undefined":
- count = 0;
- break;
- case "string":
- count = 1;
- break;
- default:
- count = hash[candidate].length;
- break;
- }
- if (count < resultCount || (count == resultCount && candidate.length > resultLength))
- {
- result = candidate;
- resultCount = count;
- resultLength = candidate.length;
- }
- }
- return result;
- },
-
- /**
- * Checks whether a particular filter is being matched against.
- */
- hasFilter: function(/**RegExpFilter*/ filter) /**Boolean*/
- {
- return (filter.text in this.keywordByFilter);
- },
-
- /**
- * Returns the keyword used for a filter, null for unknown filters.
- */
- getKeywordForFilter: function(/**RegExpFilter*/ filter) /**String*/
- {
- if (filter.text in this.keywordByFilter)
- return this.keywordByFilter[filter.text];
- else
- return null;
- },
-
- /**
- * Checks whether the entries for a particular keyword match a URL
- */
- _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty)
- {
- let list = this.filterByKeyword[keyword];
- if (typeof list == "string")
- {
- let filter = Filter.knownFilters[list];
- if (!filter)
- {
- // Something is wrong, we probably shouldn't have this filter in the first place
- delete this.filterByKeyword[keyword];
- return null;
- }
- return (filter.matches(location, contentType, docDomain, thirdParty) ? filter : null);
- }
- else
- {
- for (let i = 0; i < list.length; i++)
- {
- let filter = Filter.knownFilters[list[i]];
- if (!filter)
- {
- // Something is wrong, we probably shouldn't have this filter in the first place
- if (list.length == 1)
- {
- delete this.filterByKeyword[keyword];
- return null;
- }
- else
- {
- list.splice(i--, 1);
- continue;
- }
- }
- if (filter.matches(location, contentType, docDomain, thirdParty))
- return filter;
- }
- return null;
- }
- },
-
- /**
- * Tests whether the URL matches any of the known filters
- * @param {String} location URL to be tested
- * @param {String} contentType content type identifier of the URL
- * @param {String} docDomain domain name of the document that loads the URL
- * @param {Boolean} thirdParty should be true if the URL is a third-party request
- * @return {RegExpFilter} matching filter or null
- */
- matchesAny: function(location, contentType, docDomain, thirdParty)
- {
- let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
- if (candidates === null)
- candidates = [];
- if (contentType == "DONOTTRACK")
- candidates.unshift("donottrack");
- else
- candidates.push("");
- for (let i = 0, l = candidates.length; i < l; i++)
- {
- let substr = candidates[i];
- if (substr in this.filterByKeyword)
- {
- let result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
- if (result)
- return result;
- }
- }
-
- return null;
- },
-
- /**
- * Stores current state in a JSON'able object.
- */
- toCache: function(/**Object*/ cache)
- {
- cache.filterByKeyword = this.filterByKeyword;
- },
-
- /**
- * Restores current state from an object.
- */
- fromCache: function(/**Object*/ cache)
- {
- this.filterByKeyword = cache.filterByKeyword;
- this.filterByKeyword.__proto__ = null;
-
- // We don't want to initialize keywordByFilter yet, do it when it is needed
- delete this.keywordByFilter;
- this.__defineGetter__("keywordByFilter", function()
- {
- let result = {__proto__: null};
- for (let k in this.filterByKeyword)
- {
- let list = this.filterByKeyword[k];
- if (typeof list == "string")
- result[list] = k;
- else
- for (let i = 0, l = list.length; i < l; i++)
- result[list[i]] = k;
- }
- return this.keywordByFilter = result;
- });
- this.__defineSetter__("keywordByFilter", function(value)
- {
- delete this.keywordByFilter;
- return this.keywordByFilter = value;
- });
- }
+ /**
+ * Lookup table for filters by their associated keyword
+ * @type Object
+ */
+ filterByKeyword: null,
+
+ /**
+ * Lookup table for keywords by the filter text
+ * @type Object
+ */
+ keywordByFilter: null,
+
+ /**
+ * Removes all known filters
+ */
+ clear: function()
+ {
+ this.filterByKeyword = {__proto__: null};
+ this.keywordByFilter = {__proto__: null};
+ },
+
+ /**
+ * Adds a filter to the matcher
+ * @param {RegExpFilter} filter
+ */
+ add: function(filter)
+ {
+ if (filter.text in this.keywordByFilter)
+ return;
+
+ // Look for a suitable keyword
+ let keyword = this.findKeyword(filter);
+ switch (typeof this.filterByKeyword[keyword])
+ {
+ case "undefined":
+ this.filterByKeyword[keyword] = filter.text;
+ break;
+ case "string":
+ this.filterByKeyword[keyword] = [this.filterByKeyword[keyword], filter.text];
+ break;
+ default:
+ this.filterByKeyword[keyword].push(filter.text);
+ break;
+ }
+ this.keywordByFilter[filter.text] = keyword;
+ },
+
+ /**
+ * Removes a filter from the matcher
+ * @param {RegExpFilter} filter
+ */
+ remove: function(filter)
+ {
+ if (!(filter.text in this.keywordByFilter))
+ return;
+
+ let keyword = this.keywordByFilter[filter.text];
+ let list = this.filterByKeyword[keyword];
+ if (typeof list == "string")
+ delete this.filterByKeyword[keyword];
+ else
+ {
+ let index = list.indexOf(filter.text);
+ if (index >= 0)
+ {
+ list.splice(index, 1);
+ if (list.length == 1)
+ this.filterByKeyword[keyword] = list[0];
+ }
+ }
+
+ delete this.keywordByFilter[filter.text];
+ },
+
+ /**
+ * Chooses a keyword to be associated with the filter
+ * @param {String} text text representation of the filter
+ * @return {String} keyword (might be empty string)
+ */
+ findKeyword: function(filter)
+ {
+ // For donottrack filters use "donottrack" as keyword if nothing else matches
+ let defaultResult = (filter.contentType & RegExpFilter.typeMap.DONOTTRACK ? "donottrack" : "");
+
+ let text = filter.text;
+ if (Filter.regexpRegExp.test(text))
+ return defaultResult;
+
+ // Remove options
+ if (Filter.optionsRegExp.test(text))
+ text = RegExp.leftContext;
+
+ // Remove whitelist marker
+ if (text.substr(0, 2) == "@@")
+ text = text.substr(2);
+
+ let candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g);
+ if (!candidates)
+ return defaultResult;
+
+ let hash = this.filterByKeyword;
+ let result = defaultResult;
+ let resultCount = 0xFFFFFF;
+ let resultLength = 0;
+ for (let i = 0, l = candidates.length; i < l; i++)
+ {
+ let candidate = candidates[i].substr(1);
+ let count;
+ switch (typeof hash[candidate])
+ {
+ case "undefined":
+ count = 0;
+ break;
+ case "string":
+ count = 1;
+ break;
+ default:
+ count = hash[candidate].length;
+ break;
+ }
+ if (count < resultCount || (count == resultCount && candidate.length > resultLength))
+ {
+ result = candidate;
+ resultCount = count;
+ resultLength = candidate.length;
+ }
+ }
+ return result;
+ },
+
+ /**
+ * Checks whether a particular filter is being matched against.
+ */
+ hasFilter: function(/**RegExpFilter*/ filter) /**Boolean*/
+ {
+ return (filter.text in this.keywordByFilter);
+ },
+
+ /**
+ * Returns the keyword used for a filter, null for unknown filters.
+ */
+ getKeywordForFilter: function(/**RegExpFilter*/ filter) /**String*/
+ {
+ if (filter.text in this.keywordByFilter)
+ return this.keywordByFilter[filter.text];
+ else
+ return null;
+ },
+
+ /**
+ * Checks whether the entries for a particular keyword match a URL
+ */
+ _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty)
+ {
+ let list = this.filterByKeyword[keyword];
+ if (typeof list == "string")
+ {
+ let filter = Filter.knownFilters[list];
+ if (!filter)
+ {
+ // Something is wrong, we probably shouldn't have this filter in the first place
+ delete this.filterByKeyword[keyword];
+ return null;
+ }
+ return (filter.matches(location, contentType, docDomain, thirdParty) ? filter : null);
+ }
+ else
+ {
+ for (let i = 0; i < list.length; i++)
+ {
+ let filter = Filter.knownFilters[list[i]];
+ if (!filter)
+ {
+ // Something is wrong, we probably shouldn't have this filter in the first place
+ if (list.length == 1)
+ {
+ delete this.filterByKeyword[keyword];
+ return null;
+ }
+ else
+ {
+ list.splice(i--, 1);
+ continue;
+ }
+ }
+ if (filter.matches(location, contentType, docDomain, thirdParty))
+ return filter;
+ }
+ return null;
+ }
+ },
+
+ /**
+ * Tests whether the URL matches any of the known filters
+ * @param {String} location URL to be tested
+ * @param {String} contentType content type identifier of the URL
+ * @param {String} docDomain domain name of the document that loads the URL
+ * @param {Boolean} thirdParty should be true if the URL is a third-party request
+ * @return {RegExpFilter} matching filter or null
+ */
+ matchesAny: function(location, contentType, docDomain, thirdParty)
+ {
+ let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
+ if (candidates === null)
+ candidates = [];
+ if (contentType == "DONOTTRACK")
+ candidates.unshift("donottrack");
+ else
+ candidates.push("");
+ for (let i = 0, l = candidates.length; i < l; i++)
+ {
+ let substr = candidates[i];
+ if (substr in this.filterByKeyword)
+ {
+ let result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
+ if (result)
+ return result;
+ }
+ }
+
+ return null;
+ },
+
+ /**
+ * Stores current state in a JSON'able object.
+ */
+ toCache: function(/**Object*/ cache)
+ {
+ cache.filterByKeyword = this.filterByKeyword;
+ },
+
+ /**
+ * Restores current state from an object.
+ */
+ fromCache: function(/**Object*/ cache)
+ {
+ this.filterByKeyword = cache.filterByKeyword;
+ this.filterByKeyword.__proto__ = null;
+
+ // We don't want to initialize keywordByFilter yet, do it when it is needed
+ delete this.keywordByFilter;
+ this.__defineGetter__("keywordByFilter", function()
+ {
+ let result = {__proto__: null};
+ for (let k in this.filterByKeyword)
+ {
+ let list = this.filterByKeyword[k];
+ if (typeof list == "string")
+ result[list] = k;
+ else
+ for (let i = 0, l = list.length; i < l; i++)
+ result[list[i]] = k;
+ }
+ return this.keywordByFilter = result;
+ });
+ this.__defineSetter__("keywordByFilter", function(value)
+ {
+ delete this.keywordByFilter;
+ return this.keywordByFilter = value;
+ });
+ }
};
/**
@@ -316,9 +316,9 @@ Matcher.prototype = {
*/
function CombinedMatcher()
{
- this.blacklist = new Matcher();
- this.whitelist = new Matcher();
- this.resultCache = {__proto__: null};
+ this.blacklist = new Matcher();
+ this.whitelist = new Matcher();
+ this.resultCache = {__proto__: null};
}
/**
@@ -329,192 +329,192 @@ CombinedMatcher.maxCacheEntries = 1000;
CombinedMatcher.prototype =
{
- /**
- * Matcher for blocking rules.
- * @type Matcher
- */
- blacklist: null,
-
- /**
- * Matcher for exception rules.
- * @type Matcher
- */
- whitelist: null,
-
- /**
- * Lookup table of previous matchesAny results
- * @type Object
- */
- resultCache: null,
-
- /**
- * Number of entries in resultCache
- * @type Number
- */
- cacheEntries: 0,
-
- /**
- * @see Matcher#clear
- */
- clear: function()
- {
- this.blacklist.clear();
- this.whitelist.clear();
- this.resultCache = {__proto__: null};
- this.cacheEntries = 0;
- },
-
- /**
- * @see Matcher#add
- */
- add: function(filter)
- {
- if (filter instanceof WhitelistFilter)
- this.whitelist.add(filter);
- else
- this.blacklist.add(filter);
-
- if (this.cacheEntries > 0)
- {
- this.resultCache = {__proto__: null};
- this.cacheEntries = 0;
- }
- },
-
- /**
- * @see Matcher#remove
- */
- remove: function(filter)
- {
- if (filter instanceof WhitelistFilter)
- this.whitelist.remove(filter);
- else
- this.blacklist.remove(filter);
-
- if (this.cacheEntries > 0)
- {
- this.resultCache = {__proto__: null};
- this.cacheEntries = 0;
- }
- },
-
- /**
- * @see Matcher#findKeyword
- */
- findKeyword: function(filter)
- {
- if (filter instanceof WhitelistFilter)
- return this.whitelist.findKeyword(filter);
- else
- return this.blacklist.findKeyword(filter);
- },
-
- /**
- * @see Matcher#hasFilter
- */
- hasFilter: function(filter)
- {
- if (filter instanceof WhitelistFilter)
- return this.whitelist.hasFilter(filter);
- else
- return this.blacklist.hasFilter(filter);
- },
-
- /**
- * @see Matcher#getKeywordForFilter
- */
- getKeywordForFilter: function(filter)
- {
- if (filter instanceof WhitelistFilter)
- return this.whitelist.getKeywordForFilter(filter);
- else
- return this.blacklist.getKeywordForFilter(filter);
- },
-
- /**
- * Checks whether a particular filter is slow
- */
- isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/
- {
- let matcher = (filter instanceof WhitelistFilter ? this.whitelist : this.blacklist);
- if (matcher.hasFilter(filter))
- return !matcher.getKeywordForFilter(filter);
- else
- return !matcher.findKeyword(filter);
- },
-
- /**
- * Optimized filter matching testing both whitelist and blacklist matchers
- * simultaneously. For parameters see Matcher.matchesAny().
- * @see Matcher#matchesAny
- */
- matchesAnyInternal: function(location, contentType, docDomain, thirdParty)
- {
- let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
- if (candidates === null)
- candidates = [];
- if (contentType == "DONOTTRACK")
- candidates.unshift("donottrack");
- else
- candidates.push("");
-
- let blacklistHit = null;
- for (let i = 0, l = candidates.length; i < l; i++)
- {
- let substr = candidates[i];
- if (substr in this.whitelist.filterByKeyword)
- {
- let result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
- if (result)
- return result;
- }
- if (substr in this.blacklist.filterByKeyword && blacklistHit === null)
- blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
- }
- return blacklistHit;
- },
-
- /**
- * @see Matcher#matchesAny
- */
- matchesAny: function(location, contentType, docDomain, thirdParty)
- {
- let key = location + " " + contentType + " " + docDomain + " " + thirdParty;
- if (key in this.resultCache)
- return this.resultCache[key];
-
- let result = this.matchesAnyInternal(location, contentType, docDomain, thirdParty);
-
- if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)
- {
- this.resultCache = {__proto__: null};
- this.cacheEntries = 0;
- }
-
- this.resultCache[key] = result;
- this.cacheEntries++;
-
- return result;
- },
-
- /**
- * Stores current state in a JSON'able object.
- */
- toCache: function(/**Object*/ cache)
- {
- cache.matcher = {whitelist: {}, blacklist: {}};
- this.whitelist.toCache(cache.matcher.whitelist);
- this.blacklist.toCache(cache.matcher.blacklist);
- },
-
- /**
- * Restores current state from an object.
- */
- fromCache: function(/**Object*/ cache)
- {
- this.whitelist.fromCache(cache.matcher.whitelist);
- this.blacklist.fromCache(cache.matcher.blacklist);
- }
+ /**
+ * Matcher for blocking rules.
+ * @type Matcher
+ */
+ blacklist: null,
+
+ /**
+ * Matcher for exception rules.
+ * @type Matcher
+ */
+ whitelist: null,
+
+ /**
+ * Lookup table of previous matchesAny results
+ * @type Object
+ */
+ resultCache: null,
+
+ /**
+ * Number of entries in resultCache
+ * @type Number
+ */
+ cacheEntries: 0,
+
+ /**
+ * @see Matcher#clear
+ */
+ clear: function()
+ {
+ this.blacklist.clear();
+ this.whitelist.clear();
+ this.resultCache = {__proto__: null};
+ this.cacheEntries = 0;
+ },
+
+ /**
+ * @see Matcher#add
+ */
+ add: function(filter)
+ {
+ if (filter instanceof WhitelistFilter)
+ this.whitelist.add(filter);
+ else
+ this.blacklist.add(filter);
+
+ if (this.cacheEntries > 0)
+ {
+ this.resultCache = {__proto__: null};
+ this.cacheEntries = 0;
+ }
+ },
+
+ /**
+ * @see Matcher#remove
+ */
+ remove: function(filter)
+ {
+ if (filter instanceof WhitelistFilter)
+ this.whitelist.remove(filter);
+ else
+ this.blacklist.remove(filter);
+
+ if (this.cacheEntries > 0)
+ {
+ this.resultCache = {__proto__: null};
+ this.cacheEntries = 0;
+ }
+ },
+
+ /**
+ * @see Matcher#findKeyword
+ */
+ findKeyword: function(filter)
+ {
+ if (filter instanceof WhitelistFilter)
+ return this.whitelist.findKeyword(filter);
+ else
+ return this.blacklist.findKeyword(filter);
+ },
+
+ /**
+ * @see Matcher#hasFilter
+ */
+ hasFilter: function(filter)
+ {
+ if (filter instanceof WhitelistFilter)
+ return this.whitelist.hasFilter(filter);
+ else
+ return this.blacklist.hasFilter(filter);
+ },
+
+ /**
+ * @see Matcher#getKeywordForFilter
+ */
+ getKeywordForFilter: function(filter)
+ {
+ if (filter instanceof WhitelistFilter)
+ return this.whitelist.getKeywordForFilter(filter);
+ else
+ return this.blacklist.getKeywordForFilter(filter);
+ },
+
+ /**
+ * Checks whether a particular filter is slow
+ */
+ isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/
+ {
+ let matcher = (filter instanceof WhitelistFilter ? this.whitelist : this.blacklist);
+ if (matcher.hasFilter(filter))
+ return !matcher.getKeywordForFilter(filter);
+ else
+ return !matcher.findKeyword(filter);
+ },
+
+ /**
+ * Optimized filter matching testing both whitelist and blacklist matchers
+ * simultaneously. For parameters see Matcher.matchesAny().
+ * @see Matcher#matchesAny
+ */
+ matchesAnyInternal: function(location, contentType, docDomain, thirdParty)
+ {
+ let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g);
+ if (candidates === null)
+ candidates = [];
+ if (contentType == "DONOTTRACK")
+ candidates.unshift("donottrack");
+ else
+ candidates.push("");
+
+ let blacklistHit = null;
+ for (let i = 0, l = candidates.length; i < l; i++)
+ {
+ let substr = candidates[i];
+ if (substr in this.whitelist.filterByKeyword)
+ {
+ let result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
+ if (result)
+ return result;
+ }
+ if (substr in this.blacklist.filterByKeyword && blacklistHit === null)
+ blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty);
+ }
+ return blacklistHit;
+ },
+
+ /**
+ * @see Matcher#matchesAny
+ */
+ matchesAny: function(location, contentType, docDomain, thirdParty)
+ {
+ let key = location + " " + contentType + " " + docDomain + " " + thirdParty;
+ if (key in this.resultCache)
+ return this.resultCache[key];
+
+ let result = this.matchesAnyInternal(location, contentType, docDomain, thirdParty);
+
+ if (this.cacheEntries >= CombinedMatcher.maxCacheEntries)
+ {
+ this.resultCache = {__proto__: null};
+ this.cacheEntries = 0;
+ }
+
+ this.resultCache[key] = result;
+ this.cacheEntries++;
+
+ return result;
+ },
+
+ /**
+ * Stores current state in a JSON'able object.
+ */
+ toCache: function(/**Object*/ cache)
+ {
+ cache.matcher = {whitelist: {}, blacklist: {}};
+ this.whitelist.toCache(cache.matcher.whitelist);
+ this.blacklist.toCache(cache.matcher.blacklist);
+ },
+
+ /**
+ * Restores current state from an object.
+ */
+ fromCache: function(/**Object*/ cache)
+ {
+ this.whitelist.fromCache(cache.matcher.whitelist);
+ this.blacklist.fromCache(cache.matcher.blacklist);
+ }
}
diff --git a/modules/ObjectTabs.jsm b/modules/ObjectTabs.jsm
index 0193629..a390858 100644
--- a/modules/ObjectTabs.jsm
+++ b/modules/ObjectTabs.jsm
@@ -42,7 +42,7 @@ Cu.import(baseURL.spec + "RequestNotifier.jsm");
// Run asynchronously to prevent cyclic module loads
Utils.runAsync(function()
{
- Cu.import(baseURL.spec + "ContentPolicy.jsm");
+ Cu.import(baseURL.spec + "ContentPolicy.jsm");
});
/**
@@ -51,435 +51,435 @@ Utils.runAsync(function()
*/
var objTabs =
{
- /**
- * Number of milliseconds to wait until hiding tab after the mouse moves away.
- * @type Integer
- */
- HIDE_DELAY: 1000,
-
- /**
- * Flag used to trigger object tabs initialization first time object tabs are
- * used.
- * @type Boolean
- */
- initialized: false,
-
- /**
- * Will be set to true while initialization is in progress.
- * @type Boolean
- */
- initializing: false,
-
- /**
- * Parameters for _showTab, to be called once initialization is complete.
- */
- delayedShowParams: null,
-
- /**
- * Randomly generated class to be used for visible object tabs on top of object.
- * @type String
- */
- objTabClassVisibleTop: null,
-
- /**
- * Randomly generated class to be used for visible object tabs at the bottom of the object.
- * @type String
- */
- objTabClassVisibleBottom: null,
-
- /**
- * Randomly generated class to be used for invisible object tabs.
- * @type String
- */
- objTabClassHidden: null,
-
- /**
- * Document element the object tab is currently being displayed for.
- * @type Element
- */
- currentElement: null,
-
- /**
- * Windows that the window event handler is currently registered for.
- * @type Array of Window
- */
- windowListeners: null,
-
- /**
- * Panel element currently used as object tab.
- * @type Element
- */
- objtabElement: null,
-
- /**
- * Time of previous position update.
- * @type Integer
- */
- prevPositionUpdate: 0,
-
- /**
- * Timer used to update position of the object tab.
- * @type nsITimer
- */
- positionTimer: null,
-
- /**
- * Timer used to delay hiding of the object tab.
- * @type nsITimer
- */
- hideTimer: null,
-
- /**
- * Used when hideTimer is running, time when the tab should be hidden.
- * @type Integer
- */
- hideTargetTime: 0,
-
- /**
- * Will be true for Gecko 1.9/1.9.1, objects occupy the entire element
- * space there including border and padding.
- * @type Boolean
- */
- get _objectOverlapsBorder()
- {
- let result = (Utils.versionComparator.compare(Utils.platformVersion, "1.9.2") < 0);
- this.__defineGetter__("_objectOverlapsBorder", function() result);
- return result;
- },
-
- /**
- * Initializes object tabs (generates random classes and registers stylesheet).
- */
- _initCSS: function()
- {
- this.delayedShowParams = arguments;
-
- if (!this.initializing)
- {
- this.initializing = true;
-
- function processCSSData(data)
- {
- let rnd = [];
- let offset = "a".charCodeAt(0);
- for (let i = 0; i < 60; i++)
- rnd.push(offset + Math.random() * 26);
-
- this.objTabClassVisibleTop = String.fromCharCode.apply(String, rnd.slice(0, 20));
- this.objTabClassVisibleBottom = String.fromCharCode.apply(String, rnd.slice(20, 40));
- this.objTabClassHidden = String.fromCharCode.apply(String, rnd.slice(40, 60));
-
- let url = Utils.makeURI("data:text/css," + encodeURIComponent(data.replace(/%%CLASSVISIBLETOP%%/g, this.objTabClassVisibleTop)
- .replace(/%%CLASSVISIBLEBOTTOM%%/g, this.objTabClassVisibleBottom)
- .replace(/%%CLASSHIDDEN%%/g, this.objTabClassHidden)));
- Utils.styleService.loadAndRegisterSheet(url, Ci.nsIStyleSheetService.USER_SHEET);
-
- this.initializing = false;
- this.initialized = true;
-
- if (this.delayedShowParams)
- this._showTab.apply(this, this.delayedShowParams);
- }
-
- // Load CSS asynchronously
- try {
- let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIJSXMLHttpRequest);
- request.open("GET", "chrome://adblockplus/content/objtabs.css");
- request.overrideMimeType("text/plain");
-
- let me = this;
- request.onload = function()
- {
- processCSSData.call(me, request.responseText);
- }
- request.send(null);
- }
- catch (e)
- {
- Cu.reportError(e);
- this.initializing = false;
- }
- }
- },
-
- /**
- * Called to show object tab for an element.
- */
- showTabFor: function(/**Element*/ element)
- {
- if (!Prefs.frameobjects)
- return;
-
- if (this.hideTimer)
- {
- this.hideTimer.cancel();
- this.hideTimer = null;
- }
-
- if (this.objtabElement)
- this.objtabElement.style.setProperty("opacity", "1", "important");
-
- if (this.currentElement != element)
- {
- this._hideTab();
-
- let data = RequestNotifier.getDataForNode(element, true, Policy.type.OBJECT);
- if (data)
- {
- let hooks = this.getHooksForElement(element);
- if (hooks)
- {
- if (this.initialized)
- this._showTab(hooks, element, data[1]);
- else
- this._initCSS(hooks, element, data[1]);
- }
- }
- }
- },
-
- /**
- * Looks up the chrome window containing an element and returns abp-hooks
- * element for this window if any.
- */
- getHooksForElement: function(/**Element*/ element) /**Element*/
- {
- let doc = element.ownerDocument.defaultView
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow)
- .document;
- let hooks = doc.getElementById("abp-hooks");
- if (hooks && hooks.wrappedJSObject)
- hooks = hooks.wrappedJSObject;
- return hooks;
- },
-
- /**
- * Called to hide object tab for an element (actual hiding happens delayed).
- */
- hideTabFor: function(/**Element*/ element)
- {
- if (element != this.currentElement || this.hideTimer)
- return;
-
- this.hideTargetTime = Date.now() + this.HIDE_DELAY;
- this.hideTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.hideTimer.init(this, 40, Ci.nsITimer.TYPE_REPEATING_SLACK);
- },
-
- /**
- * Makes the tab element visible.
- */
- _showTab: function(/**Element*/ hooks, /**Element*/ element, /**RequestEntry*/ data)
- {
- let doc = element.ownerDocument.defaultView.top.document;
-
- this.objtabElement = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
- this.objtabElement.textContent = hooks.getAttribute("objtabtext");
- this.objtabElement.setAttribute("title", hooks.getAttribute("objtabtooltip"));
- this.objtabElement.setAttribute("href", data.location);
- this.objtabElement.setAttribute("class", this.objTabClassHidden);
- this.objtabElement.style.setProperty("opacity", "1", "important");
- this.objtabElement.nodeData = data;
- this.objtabElement.hooks = hooks;
-
- this.currentElement = element;
-
- // Register paint listeners for the relevant windows
- this.windowListeners = [];
- let wnd = element.ownerDocument.defaultView;
- while (wnd)
- {
- wnd.addEventListener("MozAfterPaint", objectWindowEventHandler, false);
- this.windowListeners.push(wnd);
- wnd = (wnd.parent != wnd ? wnd.parent : null);
- }
-
- // Register mouse listeners on the object tab
- this.objtabElement.addEventListener("mouseover", objectTabEventHander, false);
- this.objtabElement.addEventListener("mouseout", objectTabEventHander, false);
- this.objtabElement.addEventListener("click", objectTabEventHander, true);
-
- // Insert the tab into the document and adjust its position
- doc.documentElement.appendChild(this.objtabElement);
- if (!this.positionTimer)
- {
- this.positionTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.positionTimer.init(this, 200, Ci.nsITimer.TYPE_REPEATING_SLACK);
- }
- this._positionTab();
- },
-
- /**
- * Hides the tab element.
- */
- _hideTab: function()
- {
- this.delayedShowParams = null;
-
- if (this.objtabElement)
- {
- // Prevent recursive calls via popuphidden handler
- let objtab = this.objtabElement;
- this.objtabElement = null;
- this.currentElement = null;
-
- if (this.hideTimer)
- {
- this.hideTimer.cancel();
- this.hideTimer = null;
- }
-
- if (this.positionTimer)
- {
- this.positionTimer.cancel();
- this.positionTimer = null;
- }
-
- try {
- objtab.parentNode.removeChild(objtab);
- } catch (e) {}
- objtab.removeEventListener("mouseover", objectTabEventHander, false);
- objtab.removeEventListener("mouseout", objectTabEventHander, false);
- objtab.nodeData = null;
-
- for each (let wnd in this.windowListeners)
- wnd.removeEventListener("MozAfterPaint", objectWindowEventHandler, false);
- this.windowListeners = null;
- }
- },
-
- /**
- * Updates position of the tab element.
- */
- _positionTab: function()
- {
- // Test whether element is still in document
- let elementDoc = this.currentElement.ownerDocument;
- if (!this.currentElement.offsetWidth || !this.currentElement.offsetHeight ||
- !elementDoc || !elementDoc.defaultView || !elementDoc.documentElement)
- {
- this._hideTab();
- return;
- }
-
- let objRect = this._getElementPosition(this.currentElement);
-
- let className = this.objTabClassVisibleTop;
- let left = objRect.right - this.objtabElement.offsetWidth;
- let top = objRect.top - this.objtabElement.offsetHeight;
- if (top < 0)
- {
- top = objRect.bottom;
- className = this.objTabClassVisibleBottom;
- }
-
- if (this.objtabElement.style.left != left + "px")
- this.objtabElement.style.setProperty("left", left + "px", "important");
- if (this.objtabElement.style.top != top + "px")
- this.objtabElement.style.setProperty("top", top + "px", "important");
-
- if (this.objtabElement.getAttribute("class") != className)
- this.objtabElement.setAttribute("class", className);
-
- this.prevPositionUpdate = Date.now();
- },
-
- /**
- * Calculates element's position relative to the top frame and considering
- * clipping due to scrolling.
- * @return {left: Number, top: Number, right: Number, bottom: Number}
- */
- _getElementPosition: function(/**Element*/ element)
- {
- // Restrict rectangle coordinates by the boundaries of a window's client area
- function intersectRect(rect, wnd)
- {
- // Cannot use wnd.innerWidth/Height because they won't account for scrollbars
- let doc = wnd.document;
- let wndWidth = doc.documentElement.clientWidth;
- let wndHeight = doc.documentElement.clientHeight;
- if (doc.compatMode == "BackCompat") // clientHeight will be bogus in quirks mode
- wndHeight = Math.max(doc.documentElement.offsetHeight, doc.body.offsetHeight) - wnd.scrollMaxY - 1;
-
- rect.left = Math.max(rect.left, 0);
- rect.top = Math.max(rect.top, 0);
- rect.right = Math.min(rect.right, wndWidth);
- rect.bottom = Math.min(rect.bottom, wndHeight);
- }
-
- let rect = element.getBoundingClientRect();
- let wnd = element.ownerDocument.defaultView;
-
- let offsets = [0, 0, 0, 0];
- if (!this._objectOverlapsBorder)
- {
- let style = wnd.getComputedStyle(element, null);
- offsets[0] = parseFloat(style.borderLeftWidth) + parseFloat(style.paddingLeft);
- offsets[1] = parseFloat(style.borderTopWidth) + parseFloat(style.paddingTop);
- offsets[2] = parseFloat(style.borderRightWidth) + parseFloat(style.paddingRight);
- offsets[3] = parseFloat(style.borderBottomWidth) + parseFloat(style.paddingBottom);
- }
-
- rect = {left: rect.left + offsets[0], top: rect.top + offsets[1],
- right: rect.right - offsets[2], bottom: rect.bottom - offsets[3]};
- while (true)
- {
- intersectRect(rect, wnd);
-
- if (!wnd.frameElement)
- break;
-
- // Recalculate coordinates to be relative to frame's parent window
- let frameElement = wnd.frameElement;
- wnd = frameElement.ownerDocument.defaultView;
-
- let frameRect = frameElement.getBoundingClientRect();
- let frameStyle = wnd.getComputedStyle(frameElement, null);
- let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + parseFloat(frameStyle.paddingLeft);
- let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parseFloat(frameStyle.paddingTop);
-
- rect.left += relLeft;
- rect.right += relLeft;
- rect.top += relTop;
- rect.bottom += relTop;
- }
-
- return rect;
- },
-
- doBlock: function()
- {
- Cu.import(baseURL.spec + "AppIntegration.jsm");
- let wrapper = AppIntegration.getWrapperForWindow(this.objtabElement.hooks.ownerDocument.defaultView);
- if (wrapper)
- wrapper.blockItem(this.currentElement, this.objtabElement.nodeData);
- },
-
- /**
- * Called whenever a timer fires.
- */
- observe: function(/**nsISupport*/ subject, /**String*/ topic, /**String*/ data)
- {
- if (subject == this.positionTimer)
- {
- // Don't update position if it was already updated recently (via MozAfterPaint)
- if (Date.now() - this.prevPositionUpdate > 100)
- this._positionTab();
- }
- else if (subject == this.hideTimer)
- {
- let now = Date.now();
- if (now >= this.hideTargetTime)
- this._hideTab();
- else if (this.hideTargetTime - now < this.HIDE_DELAY / 2)
- this.objtabElement.style.setProperty("opacity", (this.hideTargetTime - now) * 2 / this.HIDE_DELAY, "important");
- }
- }
+ /**
+ * Number of milliseconds to wait until hiding tab after the mouse moves away.
+ * @type Integer
+ */
+ HIDE_DELAY: 1000,
+
+ /**
+ * Flag used to trigger object tabs initialization first time object tabs are
+ * used.
+ * @type Boolean
+ */
+ initialized: false,
+
+ /**
+ * Will be set to true while initialization is in progress.
+ * @type Boolean
+ */
+ initializing: false,
+
+ /**
+ * Parameters for _showTab, to be called once initialization is complete.
+ */
+ delayedShowParams: null,
+
+ /**
+ * Randomly generated class to be used for visible object tabs on top of object.
+ * @type String
+ */
+ objTabClassVisibleTop: null,
+
+ /**
+ * Randomly generated class to be used for visible object tabs at the bottom of the object.
+ * @type String
+ */
+ objTabClassVisibleBottom: null,
+
+ /**
+ * Randomly generated class to be used for invisible object tabs.
+ * @type String
+ */
+ objTabClassHidden: null,
+
+ /**
+ * Document element the object tab is currently being displayed for.
+ * @type Element
+ */
+ currentElement: null,
+
+ /**
+ * Windows that the window event handler is currently registered for.
+ * @type Array of Window
+ */
+ windowListeners: null,
+
+ /**
+ * Panel element currently used as object tab.
+ * @type Element
+ */
+ objtabElement: null,
+
+ /**
+ * Time of previous position update.
+ * @type Integer
+ */
+ prevPositionUpdate: 0,
+
+ /**
+ * Timer used to update position of the object tab.
+ * @type nsITimer
+ */
+ positionTimer: null,
+
+ /**
+ * Timer used to delay hiding of the object tab.
+ * @type nsITimer
+ */
+ hideTimer: null,
+
+ /**
+ * Used when hideTimer is running, time when the tab should be hidden.
+ * @type Integer
+ */
+ hideTargetTime: 0,
+
+ /**
+ * Will be true for Gecko 1.9/1.9.1, objects occupy the entire element
+ * space there including border and padding.
+ * @type Boolean
+ */
+ get _objectOverlapsBorder()
+ {
+ let result = (Utils.versionComparator.compare(Utils.platformVersion, "1.9.2") < 0);
+ this.__defineGetter__("_objectOverlapsBorder", function() result);
+ return result;
+ },
+
+ /**
+ * Initializes object tabs (generates random classes and registers stylesheet).
+ */
+ _initCSS: function()
+ {
+ this.delayedShowParams = arguments;
+
+ if (!this.initializing)
+ {
+ this.initializing = true;
+
+ function processCSSData(data)
+ {
+ let rnd = [];
+ let offset = "a".charCodeAt(0);
+ for (let i = 0; i < 60; i++)
+ rnd.push(offset + Math.random() * 26);
+
+ this.objTabClassVisibleTop = String.fromCharCode.apply(String, rnd.slice(0, 20));
+ this.objTabClassVisibleBottom = String.fromCharCode.apply(String, rnd.slice(20, 40));
+ this.objTabClassHidden = String.fromCharCode.apply(String, rnd.slice(40, 60));
+
+ let url = Utils.makeURI("data:text/css," + encodeURIComponent(data.replace(/%%CLASSVISIBLETOP%%/g, this.objTabClassVisibleTop)
+ .replace(/%%CLASSVISIBLEBOTTOM%%/g, this.objTabClassVisibleBottom)
+ .replace(/%%CLASSHIDDEN%%/g, this.objTabClassHidden)));
+ Utils.styleService.loadAndRegisterSheet(url, Ci.nsIStyleSheetService.USER_SHEET);
+
+ this.initializing = false;
+ this.initialized = true;
+
+ if (this.delayedShowParams)
+ this._showTab.apply(this, this.delayedShowParams);
+ }
+
+ // Load CSS asynchronously
+ try {
+ let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIJSXMLHttpRequest);
+ request.open("GET", "chrome://adblockplus/content/objtabs.css");
+ request.overrideMimeType("text/plain");
+
+ let me = this;
+ request.onload = function()
+ {
+ processCSSData.call(me, request.responseText);
+ }
+ request.send(null);
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ this.initializing = false;
+ }
+ }
+ },
+
+ /**
+ * Called to show object tab for an element.
+ */
+ showTabFor: function(/**Element*/ element)
+ {
+ if (!Prefs.frameobjects)
+ return;
+
+ if (this.hideTimer)
+ {
+ this.hideTimer.cancel();
+ this.hideTimer = null;
+ }
+
+ if (this.objtabElement)
+ this.objtabElement.style.setProperty("opacity", "1", "important");
+
+ if (this.currentElement != element)
+ {
+ this._hideTab();
+
+ let data = RequestNotifier.getDataForNode(element, true, Policy.type.OBJECT);
+ if (data)
+ {
+ let hooks = this.getHooksForElement(element);
+ if (hooks)
+ {
+ if (this.initialized)
+ this._showTab(hooks, element, data[1]);
+ else
+ this._initCSS(hooks, element, data[1]);
+ }
+ }
+ }
+ },
+
+ /**
+ * Looks up the chrome window containing an element and returns abp-hooks
+ * element for this window if any.
+ */
+ getHooksForElement: function(/**Element*/ element) /**Element*/
+ {
+ let doc = element.ownerDocument.defaultView
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .document;
+ let hooks = doc.getElementById("abp-hooks");
+ if (hooks && hooks.wrappedJSObject)
+ hooks = hooks.wrappedJSObject;
+ return hooks;
+ },
+
+ /**
+ * Called to hide object tab for an element (actual hiding happens delayed).
+ */
+ hideTabFor: function(/**Element*/ element)
+ {
+ if (element != this.currentElement || this.hideTimer)
+ return;
+
+ this.hideTargetTime = Date.now() + this.HIDE_DELAY;
+ this.hideTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this.hideTimer.init(this, 40, Ci.nsITimer.TYPE_REPEATING_SLACK);
+ },
+
+ /**
+ * Makes the tab element visible.
+ */
+ _showTab: function(/**Element*/ hooks, /**Element*/ element, /**RequestEntry*/ data)
+ {
+ let doc = element.ownerDocument.defaultView.top.document;
+
+ this.objtabElement = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
+ this.objtabElement.textContent = hooks.getAttribute("objtabtext");
+ this.objtabElement.setAttribute("title", hooks.getAttribute("objtabtooltip"));
+ this.objtabElement.setAttribute("href", data.location);
+ this.objtabElement.setAttribute("class", this.objTabClassHidden);
+ this.objtabElement.style.setProperty("opacity", "1", "important");
+ this.objtabElement.nodeData = data;
+ this.objtabElement.hooks = hooks;
+
+ this.currentElement = element;
+
+ // Register paint listeners for the relevant windows
+ this.windowListeners = [];
+ let wnd = element.ownerDocument.defaultView;
+ while (wnd)
+ {
+ wnd.addEventListener("MozAfterPaint", objectWindowEventHandler, false);
+ this.windowListeners.push(wnd);
+ wnd = (wnd.parent != wnd ? wnd.parent : null);
+ }
+
+ // Register mouse listeners on the object tab
+ this.objtabElement.addEventListener("mouseover", objectTabEventHander, false);
+ this.objtabElement.addEventListener("mouseout", objectTabEventHander, false);
+ this.objtabElement.addEventListener("click", objectTabEventHander, true);
+
+ // Insert the tab into the document and adjust its position
+ doc.documentElement.appendChild(this.objtabElement);
+ if (!this.positionTimer)
+ {
+ this.positionTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ this.positionTimer.init(this, 200, Ci.nsITimer.TYPE_REPEATING_SLACK);
+ }
+ this._positionTab();
+ },
+
+ /**
+ * Hides the tab element.
+ */
+ _hideTab: function()
+ {
+ this.delayedShowParams = null;
+
+ if (this.objtabElement)
+ {
+ // Prevent recursive calls via popuphidden handler
+ let objtab = this.objtabElement;
+ this.objtabElement = null;
+ this.currentElement = null;
+
+ if (this.hideTimer)
+ {
+ this.hideTimer.cancel();
+ this.hideTimer = null;
+ }
+
+ if (this.positionTimer)
+ {
+ this.positionTimer.cancel();
+ this.positionTimer = null;
+ }
+
+ try {
+ objtab.parentNode.removeChild(objtab);
+ } catch (e) {}
+ objtab.removeEventListener("mouseover", objectTabEventHander, false);
+ objtab.removeEventListener("mouseout", objectTabEventHander, false);
+ objtab.nodeData = null;
+
+ for each (let wnd in this.windowListeners)
+ wnd.removeEventListener("MozAfterPaint", objectWindowEventHandler, false);
+ this.windowListeners = null;
+ }
+ },
+
+ /**
+ * Updates position of the tab element.
+ */
+ _positionTab: function()
+ {
+ // Test whether element is still in document
+ let elementDoc = this.currentElement.ownerDocument;
+ if (!this.currentElement.offsetWidth || !this.currentElement.offsetHeight ||
+ !elementDoc || !elementDoc.defaultView || !elementDoc.documentElement)
+ {
+ this._hideTab();
+ return;
+ }
+
+ let objRect = this._getElementPosition(this.currentElement);
+
+ let className = this.objTabClassVisibleTop;
+ let left = objRect.right - this.objtabElement.offsetWidth;
+ let top = objRect.top - this.objtabElement.offsetHeight;
+ if (top < 0)
+ {
+ top = objRect.bottom;
+ className = this.objTabClassVisibleBottom;
+ }
+
+ if (this.objtabElement.style.left != left + "px")
+ this.objtabElement.style.setProperty("left", left + "px", "important");
+ if (this.objtabElement.style.top != top + "px")
+ this.objtabElement.style.setProperty("top", top + "px", "important");
+
+ if (this.objtabElement.getAttribute("class") != className)
+ this.objtabElement.setAttribute("class", className);
+
+ this.prevPositionUpdate = Date.now();
+ },
+
+ /**
+ * Calculates element's position relative to the top frame and considering
+ * clipping due to scrolling.
+ * @return {left: Number, top: Number, right: Number, bottom: Number}
+ */
+ _getElementPosition: function(/**Element*/ element)
+ {
+ // Restrict rectangle coordinates by the boundaries of a window's client area
+ function intersectRect(rect, wnd)
+ {
+ // Cannot use wnd.innerWidth/Height because they won't account for scrollbars
+ let doc = wnd.document;
+ let wndWidth = doc.documentElement.clientWidth;
+ let wndHeight = doc.documentElement.clientHeight;
+ if (doc.compatMode == "BackCompat") // clientHeight will be bogus in quirks mode
+ wndHeight = Math.max(doc.documentElement.offsetHeight, doc.body.offsetHeight) - wnd.scrollMaxY - 1;
+
+ rect.left = Math.max(rect.left, 0);
+ rect.top = Math.max(rect.top, 0);
+ rect.right = Math.min(rect.right, wndWidth);
+ rect.bottom = Math.min(rect.bottom, wndHeight);
+ }
+
+ let rect = element.getBoundingClientRect();
+ let wnd = element.ownerDocument.defaultView;
+
+ let offsets = [0, 0, 0, 0];
+ if (!this._objectOverlapsBorder)
+ {
+ let style = wnd.getComputedStyle(element, null);
+ offsets[0] = parseFloat(style.borderLeftWidth) + parseFloat(style.paddingLeft);
+ offsets[1] = parseFloat(style.borderTopWidth) + parseFloat(style.paddingTop);
+ offsets[2] = parseFloat(style.borderRightWidth) + parseFloat(style.paddingRight);
+ offsets[3] = parseFloat(style.borderBottomWidth) + parseFloat(style.paddingBottom);
+ }
+
+ rect = {left: rect.left + offsets[0], top: rect.top + offsets[1],
+ right: rect.right - offsets[2], bottom: rect.bottom - offsets[3]};
+ while (true)
+ {
+ intersectRect(rect, wnd);
+
+ if (!wnd.frameElement)
+ break;
+
+ // Recalculate coordinates to be relative to frame's parent window
+ let frameElement = wnd.frameElement;
+ wnd = frameElement.ownerDocument.defaultView;
+
+ let frameRect = frameElement.getBoundingClientRect();
+ let frameStyle = wnd.getComputedStyle(frameElement, null);
+ let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + parseFloat(frameStyle.paddingLeft);
+ let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parseFloat(frameStyle.paddingTop);
+
+ rect.left += relLeft;
+ rect.right += relLeft;
+ rect.top += relTop;
+ rect.bottom += relTop;
+ }
+
+ return rect;
+ },
+
+ doBlock: function()
+ {
+ Cu.import(baseURL.spec + "AppIntegration.jsm");
+ let wrapper = AppIntegration.getWrapperForWindow(this.objtabElement.hooks.ownerDocument.defaultView);
+ if (wrapper)
+ wrapper.blockItem(this.currentElement, this.objtabElement.nodeData);
+ },
+
+ /**
+ * Called whenever a timer fires.
+ */
+ observe: function(/**nsISupport*/ subject, /**String*/ topic, /**String*/ data)
+ {
+ if (subject == this.positionTimer)
+ {
+ // Don't update position if it was already updated recently (via MozAfterPaint)
+ if (Date.now() - this.prevPositionUpdate > 100)
+ this._positionTab();
+ }
+ else if (subject == this.hideTimer)
+ {
+ let now = Date.now();
+ if (now >= this.hideTargetTime)
+ this._hideTab();
+ else if (this.hideTargetTime - now < this.HIDE_DELAY / 2)
+ this.objtabElement.style.setProperty("opacity", (this.hideTargetTime - now) * 2 / this.HIDE_DELAY, "important");
+ }
+ }
};
/**
@@ -487,13 +487,13 @@ var objTabs =
*/
function objectMouseEventHander(/**Event*/ event)
{
- if (!event.isTrusted)
- return;
+ if (!event.isTrusted)
+ return;
- if (event.type == "mouseover")
- objTabs.showTabFor(event.target);
- else if (event.type == "mouseout")
- objTabs.hideTabFor(event.target);
+ if (event.type == "mouseover")
+ objTabs.showTabFor(event.target);
+ else if (event.type == "mouseout")
+ objTabs.hideTabFor(event.target);
}
/**
@@ -501,12 +501,12 @@ function objectMouseEventHander(/**Event*/ event)
*/
function objectWindowEventHandler(/**Event*/ event)
{
- if (!event.isTrusted)
- return;
+ if (!event.isTrusted)
+ return;
- // Don't trigger update too often, avoid overusing CPU on frequent page updates
- if (event.type == "MozAfterPaint" && Date.now() - objTabs.prevPositionUpdate > 20)
- objTabs._positionTab();
+ // Don't trigger update too often, avoid overusing CPU on frequent page updates
+ if (event.type == "MozAfterPaint" && Date.now() - objTabs.prevPositionUpdate > 20)
+ objTabs._positionTab();
}
/**
@@ -514,18 +514,18 @@ function objectWindowEventHandler(/**Event*/ event)
*/
function objectTabEventHander(/**Event*/ event)
{
- if (!event.isTrusted)
- return;
-
- if (event.type == "click" && event.button == 0)
- {
- event.preventDefault();
- event.stopPropagation();
-
- objTabs.doBlock();
- }
- else if (event.type == "mouseover")
- objTabs.showTabFor(objTabs.currentElement);
- else if (event.type == "mouseout")
- objTabs.hideTabFor(objTabs.currentElement);
+ if (!event.isTrusted)
+ return;
+
+ if (event.type == "click" && event.button == 0)
+ {
+ event.preventDefault();
+ event.stopPropagation();
+
+ objTabs.doBlock();
+ }
+ else if (event.type == "mouseover")
+ objTabs.showTabFor(objTabs.currentElement);
+ else if (event.type == "mouseout")
+ objTabs.hideTabFor(objTabs.currentElement);
}
diff --git a/modules/Prefs.jsm b/modules/Prefs.jsm
index 3ea21e0..4dae046 100644
--- a/modules/Prefs.jsm
+++ b/modules/Prefs.jsm
@@ -36,7 +36,7 @@ const Cu = Components.utils;
let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
Cu.import(baseURL.spec + "Utils.jsm");
const prefRoot = "extensions.adblockplus.";
@@ -67,113 +67,113 @@ let listeners = [];
*/
var Prefs =
{
- /**
- * Will be set to true if the user enters private browsing mode.
- * @type Boolean
- */
- privateBrowsing: false,
-
- /**
- * Called on module startup.
- */
- startup: function()
- {
- TimeLine.enter("Entered Prefs.startup()");
-
- // Initialize prefs list
- let defaultBranch = this.defaultBranch;
- for each (let name in defaultBranch.getChildList("", {}))
- {
- let type = defaultBranch.getPrefType(name);
- switch (type)
- {
- case Ci.nsIPrefBranch.PREF_INT:
- defineIntegerProperty(name);
- break;
- case Ci.nsIPrefBranch.PREF_BOOL:
- defineBooleanProperty(name);
- break;
- case Ci.nsIPrefBranch.PREF_STRING:
- defineStringProperty(name);
- break;
- }
- if ("_update_" + name in PrefsPrivate)
- PrefsPrivate["_update_" + name]();
- }
-
- // Always disable object tabs in Fennec, they aren't usable
- if (Utils.isFennec)
- Prefs.frameobjects = false;
-
- TimeLine.log("done loading initial values");
-
- // Register observers
- TimeLine.log("registering observers");
- registerObservers();
-
- TimeLine.leave("Prefs.startup() done");
- },
-
- /**
- * Backwards compatibility, this pref is optional
- */
- get patternsfile() /**String*/
- {
- let result = null;
- try
- {
- result = branch.getCharPref("patternsfile");
- } catch(e) {}
- this.__defineGetter__("patternsfile", function() result);
- return this.patternsfile;
- },
-
- /**
- * Retrieves the preferences branch containing default preference values.
- */
- get defaultBranch() /**nsIPreferenceBranch*/
- {
- return Utils.prefService.getDefaultBranch(prefRoot);
- },
-
- /**
- * Called on module shutdown.
- */
- shutdown: function()
- {
- TimeLine.enter("Entered Prefs.shutdown()");
-
- if (willBeUninstalled)
- {
- // Make sure that a new installation after uninstall will be treated like
- // an update.
- try {
- branch.clearUserPref("currentVersion");
- } catch(e) {}
- }
-
- TimeLine.leave("Prefs.shutdown() done");
- },
-
- /**
- * Adds a preferences listener that will be fired whenever preferences are
- * reloaded
- */
- addListener: function(/**Function*/ listener)
- {
- let index = listeners.indexOf(listener);
- if (index < 0)
- listeners.push(listener);
- },
- /**
- * Removes a preferences listener
- */
- removeListener: function(/**Function*/ listener)
- {
- let index = listeners.indexOf(listener);
- if (index >= 0)
- listeners.splice(index, 1);
- }
+ /**
+ * Will be set to true if the user enters private browsing mode.
+ * @type Boolean
+ */
+ privateBrowsing: false,
+
+ /**
+ * Called on module startup.
+ */
+ startup: function()
+ {
+
+
+ // Initialize prefs list
+ let defaultBranch = this.defaultBranch;
+ for each (let name in defaultBranch.getChildList("", {}))
+ {
+ let type = defaultBranch.getPrefType(name);
+ switch (type)
+ {
+ case Ci.nsIPrefBranch.PREF_INT:
+ defineIntegerProperty(name);
+ break;
+ case Ci.nsIPrefBranch.PREF_BOOL:
+ defineBooleanProperty(name);
+ break;
+ case Ci.nsIPrefBranch.PREF_STRING:
+ defineStringProperty(name);
+ break;
+ }
+ if ("_update_" + name in PrefsPrivate)
+ PrefsPrivate["_update_" + name]();
+ }
+
+ // Always disable object tabs in Fennec, they aren't usable
+ if (Utils.isFennec)
+ Prefs.frameobjects = false;
+
+
+
+ // Register observers
+
+ registerObservers();
+
+
+ },
+
+ /**
+ * Backwards compatibility, this pref is optional
+ */
+ get patternsfile() /**String*/
+ {
+ let result = null;
+ try
+ {
+ result = branch.getCharPref("patternsfile");
+ } catch(e) {}
+ this.__defineGetter__("patternsfile", function() result);
+ return this.patternsfile;
+ },
+
+ /**
+ * Retrieves the preferences branch containing default preference values.
+ */
+ get defaultBranch() /**nsIPreferenceBranch*/
+ {
+ return Utils.prefService.getDefaultBranch(prefRoot);
+ },
+
+ /**
+ * Called on module shutdown.
+ */
+ shutdown: function()
+ {
+
+
+ if (willBeUninstalled)
+ {
+ // Make sure that a new installation after uninstall will be treated like
+ // an update.
+ try {
+ branch.clearUserPref("currentVersion");
+ } catch(e) {}
+ }
+
+
+ },
+
+ /**
+ * Adds a preferences listener that will be fired whenever preferences are
+ * reloaded
+ */
+ addListener: function(/**Function*/ listener)
+ {
+ let index = listeners.indexOf(listener);
+ if (index < 0)
+ listeners.push(listener);
+ },
+ /**
+ * Removes a preferences listener
+ */
+ removeListener: function(/**Function*/ listener)
+ {
+ let index = listeners.indexOf(listener);
+ if (index >= 0)
+ listeners.splice(index, 1);
+ }
};
/**
@@ -182,35 +182,35 @@ var Prefs =
*/
var PrefsPrivate =
{
- /**
- * If set to true notifications about preference changes will no longer cause
- * a reload. This is to prevent unnecessary reloads while saving.
- * @type Boolean
- */
- ignorePrefChanges: false,
-
- /**
- * nsIObserver implementation
- */
- observe: function(subject, topic, data)
- {
- if (topic == "private-browsing")
- {
- if (data == "enter")
- Prefs.privateBrowsing = true;
- else if (data == "exit")
- Prefs.privateBrowsing = false;
- }
- else if (topic == "em-action-requested")
- {
- if (subject instanceof Ci.nsIUpdateItem && subject.id == Utils.addonID)
- willBeUninstalled = (data == "item-uninstalled");
- }
- else if (topic == "nsPref:changed" && !this.ignorePrefChanges && "_update_" + data in PrefsPrivate)
- PrefsPrivate["_update_" + data]();
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver])
+ /**
+ * If set to true notifications about preference changes will no longer cause
+ * a reload. This is to prevent unnecessary reloads while saving.
+ * @type Boolean
+ */
+ ignorePrefChanges: false,
+
+ /**
+ * nsIObserver implementation
+ */
+ observe: function(subject, topic, data)
+ {
+ if (topic == "private-browsing")
+ {
+ if (data == "enter")
+ Prefs.privateBrowsing = true;
+ else if (data == "exit")
+ Prefs.privateBrowsing = false;
+ }
+ else if (topic == "em-action-requested")
+ {
+ if (subject instanceof Ci.nsIUpdateItem && subject.id == Utils.addonID)
+ willBeUninstalled = (data == "item-uninstalled");
+ }
+ else if (topic == "nsPref:changed" && !this.ignorePrefChanges && "_update_" + data in PrefsPrivate)
+ PrefsPrivate["_update_" + data]();
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver])
}
/**
@@ -218,31 +218,31 @@ var PrefsPrivate =
*/
function registerObservers()
{
- // Observe preferences changes
- try {
- branch.QueryInterface(Ci.nsIPrefBranchInternal)
- .addObserver("", PrefsPrivate, true);
- }
- catch (e) {
- Cu.reportError(e);
- }
-
- let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
- observerService.addObserver(PrefsPrivate, "em-action-requested", true);
-
- // Add Private Browsing observer
- if ("@mozilla.org/privatebrowsing;1" in Cc)
- {
- try
- {
- Prefs.privateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService).privateBrowsingEnabled;
- observerService.addObserver(PrefsPrivate, "private-browsing", true);
- }
- catch(e)
- {
- Cu.reportError(e);
- }
- }
+ // Observe preferences changes
+ try {
+ branch.QueryInterface(Ci.nsIPrefBranchInternal)
+ .addObserver("", PrefsPrivate, true);
+ }
+ catch (e) {
+ Cu.reportError(e);
+ }
+
+ let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
+ observerService.addObserver(PrefsPrivate, "em-action-requested", true);
+
+ // Add Private Browsing observer
+ if ("@mozilla.org/privatebrowsing;1" in Cc)
+ {
+ try
+ {
+ Prefs.privateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].getService(Ci.nsIPrivateBrowsingService).privateBrowsingEnabled;
+ observerService.addObserver(PrefsPrivate, "private-browsing", true);
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+ }
+ }
}
/**
@@ -250,8 +250,8 @@ function registerObservers()
*/
function triggerListeners(/**String*/ name)
{
- for each (let listener in listeners)
- listener(name);
+ for each (let listener in listeners)
+ listener(name);
}
/**
@@ -259,42 +259,42 @@ function triggerListeners(/**String*/ name)
*/
function defineProperty(/**String*/ name, defaultValue, /**Function*/ readFunc, /**Function*/ writeFunc)
{
- let value = defaultValue;
- PrefsPrivate["_update_" + name] = function()
- {
- try
- {
- value = readFunc();
- triggerListeners(name);
- }
- catch(e)
- {
- Cu.reportError(e);
- }
- }
- Prefs.__defineGetter__(name, function() value);
- Prefs.__defineSetter__(name, function(newValue)
- {
- if (value == newValue)
- return value;
-
- try
- {
- PrefsPrivate.ignorePrefChanges = true;
- writeFunc(newValue);
- value = newValue;
- triggerListeners(name);
- }
- catch(e)
- {
- Cu.reportError(e);
- }
- finally
- {
- PrefsPrivate.ignorePrefChanges = false;
- }
- return value;
- });
+ let value = defaultValue;
+ PrefsPrivate["_update_" + name] = function()
+ {
+ try
+ {
+ value = readFunc();
+ triggerListeners(name);
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+ }
+ }
+ Prefs.__defineGetter__(name, function() value);
+ Prefs.__defineSetter__(name, function(newValue)
+ {
+ if (value == newValue)
+ return value;
+
+ try
+ {
+ PrefsPrivate.ignorePrefChanges = true;
+ writeFunc(newValue);
+ value = newValue;
+ triggerListeners(name);
+ }
+ catch(e)
+ {
+ Cu.reportError(e);
+ }
+ finally
+ {
+ PrefsPrivate.ignorePrefChanges = false;
+ }
+ return value;
+ });
}
/**
@@ -302,8 +302,8 @@ function defineProperty(/**String*/ name, defaultValue, /**Function*/ readFunc,
*/
function defineIntegerProperty(/**String*/ name)
{
- defineProperty(name, 0, function() branch.getIntPref(name),
- function(newValue) branch.setIntPref(name, newValue));
+ defineProperty(name, 0, function() branch.getIntPref(name),
+ function(newValue) branch.setIntPref(name, newValue));
}
/**
@@ -311,8 +311,8 @@ function defineIntegerProperty(/**String*/ name)
*/
function defineBooleanProperty(/**String*/ name)
{
- defineProperty(name, false, function() branch.getBoolPref(name),
- function(newValue) branch.setBoolPref(name, newValue));
+ defineProperty(name, false, function() branch.getBoolPref(name),
+ function(newValue) branch.setBoolPref(name, newValue));
}
/**
@@ -320,11 +320,11 @@ function defineBooleanProperty(/**String*/ name)
*/
function defineStringProperty(/**String*/ name)
{
- defineProperty(name, "", function() branch.getComplexValue(name, Ci.nsISupportsString).data,
- function(newValue)
- {
- let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
- str.data = newValue;
- branch.setComplexValue(name, Ci.nsISupportsString, str);
- });
+ defineProperty(name, "", function() branch.getComplexValue(name, Ci.nsISupportsString).data,
+ function(newValue)
+ {
+ let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
+ str.data = newValue;
+ branch.setComplexValue(name, Ci.nsISupportsString, str);
+ });
}
diff --git a/modules/Public.jsm b/modules/Public.jsm
index 5d81b49..da924f5 100644
--- a/modules/Public.jsm
+++ b/modules/Public.jsm
@@ -48,134 +48,134 @@ const externalPrefix = "~external~";
*/
var AdblockPlus =
{
- /**
- * Returns current subscription count
- * @type Integer
- */
- get subscriptionCount()
- {
- return FilterStorage.subscriptions.length;
- },
-
- /**
- * Gets a subscription by its URL
- */
- getSubscription: function(/**String*/ id) /**IAdblockPlusSubscription*/
- {
- if (id in FilterStorage.knownSubscriptions)
- return createSubscriptionWrapper(FilterStorage.knownSubscriptions[id]);
-
- return null;
- },
-
- /**
- * Gets a subscription by its position in the list
- */
- getSubscriptionAt: function(/**Integer*/ index) /**IAdblockPlusSubscription*/
- {
- if (index < 0 || index >= FilterStorage.subscriptions.length)
- return null;
-
- return createSubscriptionWrapper(FilterStorage.subscriptions[index]);
- },
-
- /**
- * Updates an external subscription and creates it if necessary
- */
- updateExternalSubscription: function(/**String*/ id, /**String*/ title, /**Array of Filter*/ filters) /**String*/
- {
- if (id.substr(0, externalPrefix.length) != externalPrefix)
- id = externalPrefix + id;
- let subscription = Subscription.fromURL(id);
- if (!subscription)
- subscription = new ExternalSubscription(id, title);
-
- subscription.lastDownload = parseInt(new Date().getTime() / 1000);
-
- let newFilters = [];
- for each (let filter in filters)
- {
- filter = Filter.fromText(Filter.normalize(filter));
- if (filter)
- newFilters.push(filter);
- }
-
- if (id in FilterStorage.knownSubscriptions)
- FilterStorage.updateSubscriptionFilters(subscription, newFilters);
- else
- {
- subscription.filters = newFilters;
- FilterStorage.addSubscription(subscription);
- }
- FilterStorage.saveToDisk();
-
- return id;
- },
-
- /**
- * Removes an external subscription by its identifier
- */
- removeExternalSubscription: function(/**String*/ id) /**Boolean*/
- {
- if (id.substr(0, externalPrefix.length) != externalPrefix)
- id = externalPrefix + id;
- if (!(id in FilterStorage.knownSubscriptions))
- return false;
-
- FilterStorage.removeSubscription(FilterStorage.knownSubscriptions[id]);
- return true;
- },
-
- /**
- * Adds user-defined filters to the list
- */
- addPatterns: function(/**Array of String*/ filters)
- {
- for each (let filter in filters)
- {
- filter = Filter.fromText(Filter.normalize(filter));
- if (filter)
- {
- if (filter.disabled)
- {
- filter.disabled = false;
- FilterStorage.triggerObservers("filters enable", [filter]);
- }
- FilterStorage.addFilter(filter);
- }
- }
- FilterStorage.saveToDisk();
- },
-
- /**
- * Removes user-defined filters from the list
- */
- removePatterns: function(/**Array of String*/ filters)
- {
- for each (let filter in filters)
- {
- filter = Filter.fromText(Filter.normalize(filter));
- if (filter)
- FilterStorage.removeFilter(filter);
- }
- FilterStorage.saveToDisk();
- },
-
- /**
- * Returns installed Adblock Plus version
- */
- getInstalledVersion: function() /**String*/
- {
- return Utils.addonVersion;
- },
-
- /**
- * Returns source code revision this Adblock Plus build was created from (if available)
- */
- getInstalledBuild: function() /**String*/
- {
- return Utils.addonBuild;
- },
+ /**
+ * Returns current subscription count
+ * @type Integer
+ */
+ get subscriptionCount()
+ {
+ return FilterStorage.subscriptions.length;
+ },
+
+ /**
+ * Gets a subscription by its URL
+ */
+ getSubscription: function(/**String*/ id) /**IAdblockPlusSubscription*/
+ {
+ if (id in FilterStorage.knownSubscriptions)
+ return createSubscriptionWrapper(FilterStorage.knownSubscriptions[id]);
+
+ return null;
+ },
+
+ /**
+ * Gets a subscription by its position in the list
+ */
+ getSubscriptionAt: function(/**Integer*/ index) /**IAdblockPlusSubscription*/
+ {
+ if (index < 0 || index >= FilterStorage.subscriptions.length)
+ return null;
+
+ return createSubscriptionWrapper(FilterStorage.subscriptions[index]);
+ },
+
+ /**
+ * Updates an external subscription and creates it if necessary
+ */
+ updateExternalSubscription: function(/**String*/ id, /**String*/ title, /**Array of Filter*/ filters) /**String*/
+ {
+ if (id.substr(0, externalPrefix.length) != externalPrefix)
+ id = externalPrefix + id;
+ let subscription = Subscription.fromURL(id);
+ if (!subscription)
+ subscription = new ExternalSubscription(id, title);
+
+ subscription.lastDownload = parseInt(new Date().getTime() / 1000);
+
+ let newFilters = [];
+ for each (let filter in filters)
+ {
+ filter = Filter.fromText(Filter.normalize(filter));
+ if (filter)
+ newFilters.push(filter);
+ }
+
+ if (id in FilterStorage.knownSubscriptions)
+ FilterStorage.updateSubscriptionFilters(subscription, newFilters);
+ else
+ {
+ subscription.filters = newFilters;
+ FilterStorage.addSubscription(subscription);
+ }
+ FilterStorage.saveToDisk();
+
+ return id;
+ },
+
+ /**
+ * Removes an external subscription by its identifier
+ */
+ removeExternalSubscription: function(/**String*/ id) /**Boolean*/
+ {
+ if (id.substr(0, externalPrefix.length) != externalPrefix)
+ id = externalPrefix + id;
+ if (!(id in FilterStorage.knownSubscriptions))
+ return false;
+
+ FilterStorage.removeSubscription(FilterStorage.knownSubscriptions[id]);
+ return true;
+ },
+
+ /**
+ * Adds user-defined filters to the list
+ */
+ addPatterns: function(/**Array of String*/ filters)
+ {
+ for each (let filter in filters)
+ {
+ filter = Filter.fromText(Filter.normalize(filter));
+ if (filter)
+ {
+ if (filter.disabled)
+ {
+ filter.disabled = false;
+ FilterStorage.triggerObservers("filters enable", [filter]);
+ }
+ FilterStorage.addFilter(filter);
+ }
+ }
+ FilterStorage.saveToDisk();
+ },
+
+ /**
+ * Removes user-defined filters from the list
+ */
+ removePatterns: function(/**Array of String*/ filters)
+ {
+ for each (let filter in filters)
+ {
+ filter = Filter.fromText(Filter.normalize(filter));
+ if (filter)
+ FilterStorage.removeFilter(filter);
+ }
+ FilterStorage.saveToDisk();
+ },
+
+ /**
+ * Returns installed Adblock Plus version
+ */
+ getInstalledVersion: function() /**String*/
+ {
+ return Utils.addonVersion;
+ },
+
+ /**
+ * Returns source code revision this Adblock Plus build was created from (if available)
+ */
+ getInstalledBuild: function() /**String*/
+ {
+ return Utils.addonBuild;
+ },
};
/**
@@ -183,27 +183,27 @@ var AdblockPlus =
*/
function createSubscriptionWrapper(/**Subscription*/ subscription) /**IAdblockPlusSubscription*/
{
- if (!subscription)
- return null;
-
- return {
- url: subscription.url,
- special: subscription instanceof SpecialSubscription,
- title: subscription.title,
- autoDownload: subscription instanceof DownloadableSubscription && subscription.autoDownload,
- disabled: subscription.disabled,
- external: subscription instanceof ExternalSubscription,
- lastDownload: subscription instanceof RegularSubscription ? subscription.lastDownload : 0,
- downloadStatus: subscription instanceof DownloadableSubscription ? subscription.downloadStatus : "synchronize_ok",
- lastModified: subscription instanceof DownloadableSubscription ? subscription.lastModified : null,
- expires: subscription instanceof DownloadableSubscription ? subscription.expires : 0,
- getPatterns: function()
- {
- let result = subscription.filters.map(function(filter)
- {
- return filter.text;
- });
- return result;
- }
- };
+ if (!subscription)
+ return null;
+
+ return {
+ url: subscription.url,
+ special: subscription instanceof SpecialSubscription,
+ title: subscription.title,
+ autoDownload: subscription instanceof DownloadableSubscription && subscription.autoDownload,
+ disabled: subscription.disabled,
+ external: subscription instanceof ExternalSubscription,
+ lastDownload: subscription instanceof RegularSubscription ? subscription.lastDownload : 0,
+ downloadStatus: subscription instanceof DownloadableSubscription ? subscription.downloadStatus : "synchronize_ok",
+ lastModified: subscription instanceof DownloadableSubscription ? subscription.lastModified : null,
+ expires: subscription instanceof DownloadableSubscription ? subscription.expires : 0,
+ getPatterns: function()
+ {
+ let result = subscription.filters.map(function(filter)
+ {
+ return filter.text;
+ });
+ return result;
+ }
+ };
}
diff --git a/modules/RequestNotifier.jsm b/modules/RequestNotifier.jsm
index 03b9feb..965279a 100644
--- a/modules/RequestNotifier.jsm
+++ b/modules/RequestNotifier.jsm
@@ -55,50 +55,50 @@ let attachData;
let retrieveData;
if (Utils.versionComparator.compare(Utils.platformVersion, "1.9.2.13") >= 0)
{
- // Gecko 1.9.2.13 and higher - the sane branch
- attachData = function(node, prop, data)
- {
- node.setUserData(prop, data, null);
- };
- retrieveData = function(node, prop)
- {
- if (typeof XPCNativeWrapper != "undefined" && node.wrappedJSObject)
- {
- // Rewrap node into a shallow XPCNativeWrapper. Otherwise we will get
- // our object wrapped causing weird permission exceptions in Gecko 1.9.1
- // and failed equality comparisons in Gecko 1.9.2.
- node = new XPCNativeWrapper(node, "getUserData()");
- }
- return node.getUserData(prop);
- }
+ // Gecko 1.9.2.13 and higher - the sane branch
+ attachData = function(node, prop, data)
+ {
+ node.setUserData(prop, data, null);
+ };
+ retrieveData = function(node, prop)
+ {
+ if (typeof XPCNativeWrapper != "undefined" && node.wrappedJSObject)
+ {
+ // Rewrap node into a shallow XPCNativeWrapper. Otherwise we will get
+ // our object wrapped causing weird permission exceptions in Gecko 1.9.1
+ // and failed equality comparisons in Gecko 1.9.2.
+ node = new XPCNativeWrapper(node, "getUserData()");
+ }
+ return node.getUserData(prop);
+ }
}
else
{
- // Gecko 1.9.1 - the insane branch. See bug 23689 to know why this is still
- // needed.
- var tempData = null;
- attachData = function(node, prop, data)
- {
- node.addEventListener(prop, function()
- {
- tempData = data;
- }, false);
- node = null;
- }
- retrieveData = function(node, prop)
- {
- let doc = (node.nodeType == node.DOCUMENT_NODE ? node : node.ownerDocument);
- if (!doc)
- return null;
-
- let event = doc.createEvent("Events");
- event.initEvent(prop, false, false);
- node.dispatchEvent(event);
-
- let result = tempData;
- tempData = null;
- return result;
- }
+ // Gecko 1.9.1 - the insane branch. See bug 23689 to know why this is still
+ // needed.
+ var tempData = null;
+ attachData = function(node, prop, data)
+ {
+ node.addEventListener(prop, function()
+ {
+ tempData = data;
+ }, false);
+ node = null;
+ }
+ retrieveData = function(node, prop)
+ {
+ let doc = (node.nodeType == node.DOCUMENT_NODE ? node : node.ownerDocument);
+ if (!doc)
+ return null;
+
+ let event = doc.createEvent("Events");
+ event.initEvent(prop, false, false);
+ node.dispatchEvent(event);
+
+ let result = tempData;
+ tempData = null;
+ return result;
+ }
}
/**
@@ -111,122 +111,122 @@ else
*/
function RequestNotifier(wnd, listener, listenerObj)
{
- this.window = wnd;
- this.listener = listener;
- this.listenerObj = listenerObj || null;
- activeNotifiers.push(this);
- if (wnd)
- this.startScan(wnd);
- else
- this.scanComplete = true;
+ this.window = wnd;
+ this.listener = listener;
+ this.listenerObj = listenerObj || null;
+ activeNotifiers.push(this);
+ if (wnd)
+ this.startScan(wnd);
+ else
+ this.scanComplete = true;
}
RequestNotifier.prototype =
{
- /**
- * The window this notifier is associated with.
- * @type Window
- */
- window: null,
-
- /**
- * The listener to be called when a new request is found.
- * @type Function
- */
- listener: null,
-
- /**
- * "this" pointer to be used when calling the listener.
- * @type Object
- */
- listenerObj: null,
-
- /**
- * Will be set to true once the initial window scan is complete.
- * @type Boolean
- */
- scanComplete: false,
-
- /**
- * Shuts down the notifier once it is no longer used. The listener
- * will no longer be called after that.
- */
- shutdown: function()
- {
- delete this.window;
- delete this.listener;
- delete this.listenerObj;
-
- for (let i = activeNotifiers.length - 1; i >= 0; i--)
- if (activeNotifiers[i] == this)
- activeNotifiers.splice(i, 1);
- },
-
- /**
- * Notifies listener about a new request.
- */
- notifyListener: function(/**Window*/ wnd, /**Node*/ node, /**RequestEntry*/ entry)
- {
- this.listener.call(this.listenerObj, wnd, node, entry, this.scanComplete);
- },
-
- /**
- * Number of currently posted scan events (will be 0 when the scan finishes
- * running).
- */
- eventsPosted: 0,
-
- /**
- * Starts the initial scan of the window (will recurse into frames).
- * @param {Window} wnd the window to be scanned
- */
- startScan: function(wnd)
- {
- let currentThread = Utils.threadManager.currentThread;
-
- let doc = wnd.document;
- let walker = doc.createTreeWalker(doc, Ci.nsIDOMNodeFilter.SHOW_ELEMENT, null, false);
-
- let runnable =
- {
- notifier: null,
-
- run: function()
- {
- if (!this.notifier.listener)
- return;
-
- let node = walker.currentNode;
- let data = retrieveData(node, nodeDataProp);
- if (data)
- for (let i = data.length - 1; i >= 0; i--)
- this.notifier.notifyListener(wnd, node, data[i]);
-
- if (walker.nextNode())
- currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
- else
- {
- // Done with the current window, start the scan for its frames
- for (let i = 0; i < wnd.frames.length; i++)
- this.notifier.startScan(wnd.frames[i]);
-
- this.notifier.eventsPosted--;
- if (!this.notifier.eventsPosted)
- {
- this.notifier.scanComplete = true;
- this.notifier.notifyListener(wnd, null, null);
- }
-
- this.notifier = null;
- }
- }
- };
- runnable.notifier = this;
-
- // Process each node in a separate event on current thread to allow other
- // events to process
- this.eventsPosted++;
- currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
- }
+ /**
+ * The window this notifier is associated with.
+ * @type Window
+ */
+ window: null,
+
+ /**
+ * The listener to be called when a new request is found.
+ * @type Function
+ */
+ listener: null,
+
+ /**
+ * "this" pointer to be used when calling the listener.
+ * @type Object
+ */
+ listenerObj: null,
+
+ /**
+ * Will be set to true once the initial window scan is complete.
+ * @type Boolean
+ */
+ scanComplete: false,
+
+ /**
+ * Shuts down the notifier once it is no longer used. The listener
+ * will no longer be called after that.
+ */
+ shutdown: function()
+ {
+ delete this.window;
+ delete this.listener;
+ delete this.listenerObj;
+
+ for (let i = activeNotifiers.length - 1; i >= 0; i--)
+ if (activeNotifiers[i] == this)
+ activeNotifiers.splice(i, 1);
+ },
+
+ /**
+ * Notifies listener about a new request.
+ */
+ notifyListener: function(/**Window*/ wnd, /**Node*/ node, /**RequestEntry*/ entry)
+ {
+ this.listener.call(this.listenerObj, wnd, node, entry, this.scanComplete);
+ },
+
+ /**
+ * Number of currently posted scan events (will be 0 when the scan finishes
+ * running).
+ */
+ eventsPosted: 0,
+
+ /**
+ * Starts the initial scan of the window (will recurse into frames).
+ * @param {Window} wnd the window to be scanned
+ */
+ startScan: function(wnd)
+ {
+ let currentThread = Utils.threadManager.currentThread;
+
+ let doc = wnd.document;
+ let walker = doc.createTreeWalker(doc, Ci.nsIDOMNodeFilter.SHOW_ELEMENT, null, false);
+
+ let runnable =
+ {
+ notifier: null,
+
+ run: function()
+ {
+ if (!this.notifier.listener)
+ return;
+
+ let node = walker.currentNode;
+ let data = retrieveData(node, nodeDataProp);
+ if (data)
+ for (let i = data.length - 1; i >= 0; i--)
+ this.notifier.notifyListener(wnd, node, data[i]);
+
+ if (walker.nextNode())
+ currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ else
+ {
+ // Done with the current window, start the scan for its frames
+ for (let i = 0; i < wnd.frames.length; i++)
+ this.notifier.startScan(wnd.frames[i]);
+
+ this.notifier.eventsPosted--;
+ if (!this.notifier.eventsPosted)
+ {
+ this.notifier.scanComplete = true;
+ this.notifier.notifyListener(wnd, null, null);
+ }
+
+ this.notifier = null;
+ }
+ }
+ };
+ runnable.notifier = this;
+
+ // Process each node in a separate event on current thread to allow other
+ // events to process
+ this.eventsPosted++;
+ currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ }
};
RequestNotifier.getDataSeed = function() dataSeed;
@@ -243,7 +243,7 @@ RequestNotifier.getDataSeed = function() dataSeed;
*/
RequestNotifier.addNodeData = function(/**Node*/ node, /**Window*/ topWnd, /**Integer*/ contentType, /**String*/ docDomain, /**Boolean*/ thirdParty, /**String*/ location, /**Filter*/ filter)
{
- return new RequestEntry(node, topWnd, contentType, docDomain, thirdParty, location, filter);
+ return new RequestEntry(node, topWnd, contentType, docDomain, thirdParty, location, filter);
}
/**
@@ -252,7 +252,7 @@ RequestNotifier.addNodeData = function(/**Node*/ node, /**Window*/ topWnd, /**In
*/
RequestNotifier.getWindowStatistics = function(/**Window*/ wnd)
{
- return retrieveData(wnd.document, wndStatProp);
+ return retrieveData(wnd.document, wndStatProp);
}
/**
@@ -266,138 +266,138 @@ RequestNotifier.getWindowStatistics = function(/**Window*/ wnd)
*/
RequestNotifier.getDataForNode = function(node, noParent, type, location)
{
- while (node)
- {
- let data = retrieveData(node, nodeDataProp);
- if (data)
- {
- // Look for matching entry starting at the end of the list (most recent first)
- for (let i = data.length - 1; i >= 0; i--)
- {
- let entry = data[i];
- if ((typeof type == "undefined" || entry.type == type) &&
- (typeof location == "undefined" || entry.location == location))
- {
- return [node, entry];
- }
- }
- }
-
- // If we don't have any match on this node then maybe its parent will do
- if ((typeof noParent != "boolean" || !noParent) &&
- node.parentNode instanceof Ci.nsIDOMElement)
- {
- node = node.parentNode;
- }
- else
- {
- node = null;
- }
- }
-
- return null;
+ while (node)
+ {
+ let data = retrieveData(node, nodeDataProp);
+ if (data)
+ {
+ // Look for matching entry starting at the end of the list (most recent first)
+ for (let i = data.length - 1; i >= 0; i--)
+ {
+ let entry = data[i];
+ if ((typeof type == "undefined" || entry.type == type) &&
+ (typeof location == "undefined" || entry.location == location))
+ {
+ return [node, entry];
+ }
+ }
+ }
+
+ // If we don't have any match on this node then maybe its parent will do
+ if ((typeof noParent != "boolean" || !noParent) &&
+ node.parentNode instanceof Ci.nsIDOMElement)
+ {
+ node = node.parentNode;
+ }
+ else
+ {
+ node = null;
+ }
+ }
+
+ return null;
};
function RequestEntry(node, topWnd, contentType, docDomain, thirdParty, location, filter)
{
- this.type = contentType;
- this.docDomain = docDomain;
- this.thirdParty = thirdParty;
- this.location = location;
- this.filter = filter;
-
- this.attachToNode(node);
-
- // Update window statistics
- let windowStats = retrieveData(topWnd.document, wndStatProp);
- if (!windowStats)
- {
- windowStats = {
- items: 0,
- hidden: 0,
- blocked: 0,
- whitelisted: 0,
- filters: {}
- };
-
- attachData(topWnd.document, wndStatProp, windowStats);
- }
-
- if (filter && filter instanceof ElemHideFilter)
- windowStats.hidden++;
- else
- windowStats.items++;
- if (filter)
- {
- if (filter instanceof BlockingFilter)
- windowStats.blocked++;
- else if (filter instanceof WhitelistFilter)
- windowStats.whitelisted++;
-
- if (filter.text in windowStats.filters)
- windowStats.filters[filter.text]++;
- else
- windowStats.filters[filter.text] = 1;
- }
-
- // Notify listeners
- for each (let notifier in activeNotifiers)
- if (!notifier.window || notifier.window == topWnd)
- notifier.notifyListener(topWnd, node, this);
+ this.type = contentType;
+ this.docDomain = docDomain;
+ this.thirdParty = thirdParty;
+ this.location = location;
+ this.filter = filter;
+
+ this.attachToNode(node);
+
+ // Update window statistics
+ let windowStats = retrieveData(topWnd.document, wndStatProp);
+ if (!windowStats)
+ {
+ windowStats = {
+ items: 0,
+ hidden: 0,
+ blocked: 0,
+ whitelisted: 0,
+ filters: {}
+ };
+
+ attachData(topWnd.document, wndStatProp, windowStats);
+ }
+
+ if (filter && filter instanceof ElemHideFilter)
+ windowStats.hidden++;
+ else
+ windowStats.items++;
+ if (filter)
+ {
+ if (filter instanceof BlockingFilter)
+ windowStats.blocked++;
+ else if (filter instanceof WhitelistFilter)
+ windowStats.whitelisted++;
+
+ if (filter.text in windowStats.filters)
+ windowStats.filters[filter.text]++;
+ else
+ windowStats.filters[filter.text] = 1;
+ }
+
+ // Notify listeners
+ for each (let notifier in activeNotifiers)
+ if (!notifier.window || notifier.window == topWnd)
+ notifier.notifyListener(topWnd, node, this);
}
RequestEntry.prototype =
{
- /**
- * Content type of the request (one of the nsIContentPolicy constants)
- * @type Integer
- */
- type: null,
- /**
- * Domain name of the requesting document
- * @type String
- */
- docDomain: null,
- /**
- * True if the request goes to a different domain than the domain of the containing document
- * @type Boolean
- */
- thirdParty: false,
- /**
- * Address being requested
- * @type String
- */
- location: null,
- /**
- * Filter that was applied to this request (if any)
- * @type Filter
- */
- filter: null,
- /**
- * String representation of the content type, e.g. "subdocument"
- * @type String
- */
- get typeDescr() Policy.typeDescr[this.type],
- /**
- * User-visible localized representation of the content type, e.g. "frame"
- * @type String
- */
- get localizedDescr() Policy.localizedDescr[this.type],
-
- /**
- * Attaches this request object to a DOM node.
- */
- attachToNode: function(/**Node*/ node)
- {
- let existingData = retrieveData(node, nodeDataProp);
- if (existingData)
- {
- // Add the new entry to the existing data
- existingData.push(this);
- }
- else
- {
- // Associate the node with a new array
- attachData(node, nodeDataProp, [this]);
- }
- }
+ /**
+ * Content type of the request (one of the nsIContentPolicy constants)
+ * @type Integer
+ */
+ type: null,
+ /**
+ * Domain name of the requesting document
+ * @type String
+ */
+ docDomain: null,
+ /**
+ * True if the request goes to a different domain than the domain of the containing document
+ * @type Boolean
+ */
+ thirdParty: false,
+ /**
+ * Address being requested
+ * @type String
+ */
+ location: null,
+ /**
+ * Filter that was applied to this request (if any)
+ * @type Filter
+ */
+ filter: null,
+ /**
+ * String representation of the content type, e.g. "subdocument"
+ * @type String
+ */
+ get typeDescr() Policy.typeDescr[this.type],
+ /**
+ * User-visible localized representation of the content type, e.g. "frame"
+ * @type String
+ */
+ get localizedDescr() Policy.localizedDescr[this.type],
+
+ /**
+ * Attaches this request object to a DOM node.
+ */
+ attachToNode: function(/**Node*/ node)
+ {
+ let existingData = retrieveData(node, nodeDataProp);
+ if (existingData)
+ {
+ // Add the new entry to the existing data
+ existingData.push(this);
+ }
+ else
+ {
+ // Associate the node with a new array
+ attachData(node, nodeDataProp, [this]);
+ }
+ }
};
diff --git a/modules/SubscriptionClasses.jsm b/modules/SubscriptionClasses.jsm
index d61b384..8467d8e 100644
--- a/modules/SubscriptionClasses.jsm
+++ b/modules/SubscriptionClasses.jsm
@@ -46,54 +46,54 @@ Cu.import(baseURL.spec + "FilterClasses.jsm");
*/
function Subscription(url)
{
- this.url = url;
- this.filters = [];
- Subscription.knownSubscriptions[url] = this;
+ this.url = url;
+ this.filters = [];
+ Subscription.knownSubscriptions[url] = this;
}
Subscription.prototype =
{
- /**
- * Download location of the subscription
- * @type String
- */
- url: null,
-
- /**
- * Filters contained in the filter subscription
- * @type Array of Filter
- */
- filters: null,
-
- /**
- * Defines whether the filters in the subscription should be disabled
- * @type Boolean
- */
- disabled: false,
-
- /**
- * Serializes the filter to an array of strings for writing out on the disk.
- * @param {Array of String} buffer buffer to push the serialization results into
- */
- serialize: function(buffer)
- {
- buffer.push("[Subscription]");
- buffer.push("url=" + this.url);
- if (this.disabled)
- buffer.push("disabled=true");
- },
-
- serializeFilters: function(buffer)
- {
- for each (let filter in this.filters)
- buffer.push(filter.text.replace(/\[/g, "\\["));
- },
-
- toString: function()
- {
- let buffer = [];
- this.serialize(buffer);
- return buffer.join("\n");
- }
+ /**
+ * Download location of the subscription
+ * @type String
+ */
+ url: null,
+
+ /**
+ * Filters contained in the filter subscription
+ * @type Array of Filter
+ */
+ filters: null,
+
+ /**
+ * Defines whether the filters in the subscription should be disabled
+ * @type Boolean
+ */
+ disabled: false,
+
+ /**
+ * Serializes the filter to an array of strings for writing out on the disk.
+ * @param {Array of String} buffer buffer to push the serialization results into
+ */
+ serialize: function(buffer)
+ {
+ buffer.push("[Subscription]");
+ buffer.push("url=" + this.url);
+ if (this.disabled)
+ buffer.push("disabled=true");
+ },
+
+ serializeFilters: function(buffer)
+ {
+ for each (let filter in this.filters)
+ buffer.push(filter.text.replace(/\[/g, "\\["));
+ },
+
+ toString: function()
+ {
+ let buffer = [];
+ this.serialize(buffer);
+ return buffer.join("\n");
+ }
};
/**
@@ -109,24 +109,24 @@ Subscription.knownSubscriptions = {__proto__: null};
*/
Subscription.fromURL = function(url)
{
- if (url in Subscription.knownSubscriptions)
- return Subscription.knownSubscriptions[url];
-
- if (url in SpecialSubscription.map && SpecialSubscription.map[url] instanceof Array)
- return new SpecialSubscription(url);
- else
- {
- try
- {
- // Test URL for validity
- url = Utils.ioService.newURI(url, null, null).spec;
- return new DownloadableSubscription(url, null);
- }
- catch (e)
- {
- return null;
- }
- }
+ if (url in Subscription.knownSubscriptions)
+ return Subscription.knownSubscriptions[url];
+
+ if (url in SpecialSubscription.map && SpecialSubscription.map[url] instanceof Array)
+ return new SpecialSubscription(url);
+ else
+ {
+ try
+ {
+ // Test URL for validity
+ url = Utils.ioService.newURI(url, null, null).spec;
+ return new DownloadableSubscription(url, null);
+ }
+ catch (e)
+ {
+ return null;
+ }
+ }
}
/**
@@ -137,60 +137,60 @@ Subscription.fromURL = function(url)
*/
Subscription.fromObject = function(obj)
{
- let result;
- if (obj.url in SpecialSubscription.map && SpecialSubscription.map[obj.url] instanceof Array)
- result = new SpecialSubscription(obj.url);
- else
- {
- if ("external" in obj && obj.external == "true")
- result = new ExternalSubscription(obj.url, obj.title);
- else
- {
- try
- {
- // Test URL for validity
- obj.url = Utils.ioService.newURI(obj.url, null, null).spec;
- }
- catch (e)
- {
- return null;
- }
-
- result = new DownloadableSubscription(obj.url, obj.title);
- if ("autoDownload" in obj)
- result.autoDownload = (obj.autoDownload == "true");
- if ("nextURL" in obj)
- result.nextURL = obj.nextURL;
- if ("downloadStatus" in obj)
- result.downloadStatus = obj.downloadStatus;
- if ("lastModified" in obj)
- result.lastModified = obj.lastModified;
- if ("lastSuccess" in obj)
- result.lastSuccess = parseInt(obj.lastSuccess) || 0;
- if ("lastCheck" in obj)
- result.lastCheck = parseInt(obj.lastCheck) || 0;
- if ("expires" in obj)
- result.expires = parseInt(obj.expires) || 0;
- if ("softExpiration" in obj)
- result.softExpiration = parseInt(obj.softExpiration) || 0;
- if ("errors" in obj)
- result.errors = parseInt(obj.errors) || 0;
- if ("requiredVersion" in obj)
- {
- result.requiredVersion = obj.requiredVersion;
- if (Utils.versionComparator.compare(result.requiredVersion, Utils.addonVersion) > 0)
- result.upgradeRequired = true;
- }
- if ("alternativeLocations" in obj)
- result.alternativeLocations = obj.alternativeLocations;
- }
- if ("lastDownload" in obj)
- result.lastDownload = parseInt(obj.lastDownload) || 0;
- }
- if ("disabled" in obj)
- result.disabled = (obj.disabled == "true");
-
- return result;
+ let result;
+ if (obj.url in SpecialSubscription.map && SpecialSubscription.map[obj.url] instanceof Array)
+ result = new SpecialSubscription(obj.url);
+ else
+ {
+ if ("external" in obj && obj.external == "true")
+ result = new ExternalSubscription(obj.url, obj.title);
+ else
+ {
+ try
+ {
+ // Test URL for validity
+ obj.url = Utils.ioService.newURI(obj.url, null, null).spec;
+ }
+ catch (e)
+ {
+ return null;
+ }
+
+ result = new DownloadableSubscription(obj.url, obj.title);
+ if ("autoDownload" in obj)
+ result.autoDownload = (obj.autoDownload == "true");
+ if ("nextURL" in obj)
+ result.nextURL = obj.nextURL;
+ if ("downloadStatus" in obj)
+ result.downloadStatus = obj.downloadStatus;
+ if ("lastModified" in obj)
+ result.lastModified = obj.lastModified;
+ if ("lastSuccess" in obj)
+ result.lastSuccess = parseInt(obj.lastSuccess) || 0;
+ if ("lastCheck" in obj)
+ result.lastCheck = parseInt(obj.lastCheck) || 0;
+ if ("expires" in obj)
+ result.expires = parseInt(obj.expires) || 0;
+ if ("softExpiration" in obj)
+ result.softExpiration = parseInt(obj.softExpiration) || 0;
+ if ("errors" in obj)
+ result.errors = parseInt(obj.errors) || 0;
+ if ("requiredVersion" in obj)
+ {
+ result.requiredVersion = obj.requiredVersion;
+ if (Utils.versionComparator.compare(result.requiredVersion, Utils.addonVersion) > 0)
+ result.upgradeRequired = true;
+ }
+ if ("alternativeLocations" in obj)
+ result.alternativeLocations = obj.alternativeLocations;
+ }
+ if ("lastDownload" in obj)
+ result.lastDownload = parseInt(obj.lastDownload) || 0;
+ }
+ if ("disabled" in obj)
+ result.disabled = (obj.disabled == "true");
+
+ return result;
}
/**
@@ -201,75 +201,75 @@ Subscription.fromObject = function(obj)
*/
function SpecialSubscription(url)
{
- Subscription.call(this, url);
+ Subscription.call(this, url);
- let data = SpecialSubscription.map[url];
- this._titleID = data[0];
- this._priority = data[1];
- this.filterTypes = data.slice(2);
+ let data = SpecialSubscription.map[url];
+ this._titleID = data[0];
+ this._priority = data[1];
+ this.filterTypes = data.slice(2);
}
SpecialSubscription.prototype =
{
- __proto__: Subscription.prototype,
-
- /**
- * ID of the string that should be used as the title of this subscription
- * @type String
- */
- _titleID: null,
-
- /**
- * Priority when adding new filters that are accepted by multiple subscriptions
- * @type Integer
- */
- _priority: null,
-
- /**
- * Priority based on which new filters are added to a subscription if multiple
- * subscriptions are possible
- * @type Integer
- */
- get priority()
- {
- return this._priority;
- },
-
- /**
- * Title of the subscription (read-only)
- * @type String
- */
- get title()
- {
- return Utils.getString(this._titleID);
- },
-
- /**
- * Filter classes that can be added to this subscription
- * @type Array of Function
- */
- filterTypes: null,
-
- /**
- * Tests whether a filter is allowed to be added to this subscription
- * @param {Filter} filter filter to be tested
- * @return {Boolean}
- */
- isFilterAllowed: function(filter)
- {
- for each (let type in this.filterTypes)
- if (filter instanceof type)
- return true;
-
- return false;
- }
+ __proto__: Subscription.prototype,
+
+ /**
+ * ID of the string that should be used as the title of this subscription
+ * @type String
+ */
+ _titleID: null,
+
+ /**
+ * Priority when adding new filters that are accepted by multiple subscriptions
+ * @type Integer
+ */
+ _priority: null,
+
+ /**
+ * Priority based on which new filters are added to a subscription if multiple
+ * subscriptions are possible
+ * @type Integer
+ */
+ get priority()
+ {
+ return this._priority;
+ },
+
+ /**
+ * Title of the subscription (read-only)
+ * @type String
+ */
+ get title()
+ {
+ return Utils.getString(this._titleID);
+ },
+
+ /**
+ * Filter classes that can be added to this subscription
+ * @type Array of Function
+ */
+ filterTypes: null,
+
+ /**
+ * Tests whether a filter is allowed to be added to this subscription
+ * @param {Filter} filter filter to be tested
+ * @return {Boolean}
+ */
+ isFilterAllowed: function(filter)
+ {
+ for each (let type in this.filterTypes)
+ if (filter instanceof type)
+ return true;
+
+ return false;
+ }
};
SpecialSubscription.map = {
- __proto__: null,
- "~il~": ["invalid_description", 1, InvalidFilter, CommentFilter],
- "~wl~": ["whitelist_description", 3, WhitelistFilter, CommentFilter],
- "~fl~": ["filterlist_description", 4, BlockingFilter, CommentFilter],
- "~eh~": ["elemhide_description", 2, ElemHideFilter, CommentFilter]
+ __proto__: null,
+ "~il~": ["invalid_description", 1, InvalidFilter, CommentFilter],
+ "~wl~": ["whitelist_description", 3, WhitelistFilter, CommentFilter],
+ "~fl~": ["filterlist_description", 4, BlockingFilter, CommentFilter],
+ "~eh~": ["elemhide_description", 2, ElemHideFilter, CommentFilter]
};
/**
@@ -281,36 +281,36 @@ SpecialSubscription.map = {
*/
function RegularSubscription(url, title)
{
- Subscription.call(this, url);
+ Subscription.call(this, url);
- this.title = title || url;
+ this.title = title || url;
}
RegularSubscription.prototype =
{
- __proto__: Subscription.prototype,
-
- /**
- * Title of the filter subscription
- * @type String
- */
- title: null,
-
- /**
- * Time of the last subscription download (in seconds since the beginning of the epoch)
- * @type Number
- */
- lastDownload: 0,
-
- /**
- * See Subscription.serialize()
- */
- serialize: function(buffer)
- {
- Subscription.prototype.serialize.call(this, buffer);
- buffer.push("title=" + this.title);
- if (this.lastDownload)
- buffer.push("lastDownload=" + this.lastDownload);
- }
+ __proto__: Subscription.prototype,
+
+ /**
+ * Title of the filter subscription
+ * @type String
+ */
+ title: null,
+
+ /**
+ * Time of the last subscription download (in seconds since the beginning of the epoch)
+ * @type Number
+ */
+ lastDownload: 0,
+
+ /**
+ * See Subscription.serialize()
+ */
+ serialize: function(buffer)
+ {
+ Subscription.prototype.serialize.call(this, buffer);
+ buffer.push("title=" + this.title);
+ if (this.lastDownload)
+ buffer.push("lastDownload=" + this.lastDownload);
+ }
};
/**
@@ -322,20 +322,20 @@ RegularSubscription.prototype =
*/
function ExternalSubscription(url, title)
{
- RegularSubscription.call(this, url, title);
+ RegularSubscription.call(this, url, title);
}
ExternalSubscription.prototype =
{
- __proto__: RegularSubscription.prototype,
-
- /**
- * See Subscription.serialize()
- */
- serialize: function(buffer)
- {
- RegularSubscription.prototype.serialize.call(this, buffer);
- buffer.push("external=true");
- }
+ __proto__: RegularSubscription.prototype,
+
+ /**
+ * See Subscription.serialize()
+ */
+ serialize: function(buffer)
+ {
+ RegularSubscription.prototype.serialize.call(this, buffer);
+ buffer.push("external=true");
+ }
};
/**
@@ -347,114 +347,114 @@ ExternalSubscription.prototype =
*/
function DownloadableSubscription(url, title)
{
- RegularSubscription.call(this, url, title);
+ RegularSubscription.call(this, url, title);
}
DownloadableSubscription.prototype =
{
- __proto__: RegularSubscription.prototype,
-
- /**
- * Defines whether the subscription should be downloaded automatically
- * @type Boolean
- */
- autoDownload: true,
-
- /**
- * Next URL the downloaded should be attempted from (in case of redirects)
- * @type String
- */
- nextURL: null,
-
- /**
- * Status of the last download (ID of a string)
- * @type String
- */
- downloadStatus: null,
-
- /**
- * Value of the Last-Modified header returned by the server on last download
- * @type String
- */
- lastModified: null,
-
- /**
- * Time of the last successful download (in seconds since the beginning of the
- * epoch).
- */
- lastSuccess: 0,
-
- /**
- * Time when the subscription was considered for an update last time (in seconds
- * since the beginning of the epoch). This will be used to increase softExpiration
- * if the user doesn't use Adblock Plus for some time.
- * @type Number
- */
- lastCheck: 0,
-
- /**
- * Hard expiration time of the filter subscription (in seconds since the beginning of the epoch)
- * @type Number
- */
- expires: 0,
-
- /**
- * Soft expiration time of the filter subscription (in seconds since the beginning of the epoch)
- * @type Number
- */
- softExpiration: 0,
-
- /**
- * Number of download failures since last success
- * @type Number
- */
- errors: 0,
-
- /**
- * Minimal Adblock Plus version required for this subscription
- * @type String
- */
- requiredVersion: null,
-
- /**
- * Should be true if requiredVersion is higher than current Adblock Plus version
- * @type Boolean
- */
- upgradeRequired: false,
-
- /**
- * Value of the X-Alternative-Locations header: comma-separated list of URLs
- * with their weighting factors, e.g.: http://foo.example.com/;q=0.5,http://bar.example.com/;q=2
- * @type String
- */
- alternativeLocations: null,
-
- /**
- * See Subscription.serialize()
- */
- serialize: function(buffer)
- {
- RegularSubscription.prototype.serialize.call(this, buffer);
- if (!this.autoDownload)
- buffer.push("autoDownload=false");
- if (this.nextURL)
- buffer.push("nextURL=" + this.nextURL);
- if (this.downloadStatus)
- buffer.push("downloadStatus=" + this.downloadStatus);
- if (this.lastModified)
- buffer.push("lastModified=" + this.lastModified);
- if (this.lastSuccess)
- buffer.push("lastSuccess=" + this.lastSuccess);
- if (this.lastCheck)
- buffer.push("lastCheck=" + this.lastCheck);
- if (this.expires)
- buffer.push("expires=" + this.expires);
- if (this.softExpiration)
- buffer.push("softExpiration=" + this.softExpiration);
- if (this.errors)
- buffer.push("errors=" + this.errors);
- if (this.requiredVersion)
- buffer.push("requiredVersion=" + this.requiredVersion);
- if (this.alternativeLocations)
- buffer.push("alternativeLocations=" + this.alternativeLocations);
- }
+ __proto__: RegularSubscription.prototype,
+
+ /**
+ * Defines whether the subscription should be downloaded automatically
+ * @type Boolean
+ */
+ autoDownload: true,
+
+ /**
+ * Next URL the downloaded should be attempted from (in case of redirects)
+ * @type String
+ */
+ nextURL: null,
+
+ /**
+ * Status of the last download (ID of a string)
+ * @type String
+ */
+ downloadStatus: null,
+
+ /**
+ * Value of the Last-Modified header returned by the server on last download
+ * @type String
+ */
+ lastModified: null,
+
+ /**
+ * Time of the last successful download (in seconds since the beginning of the
+ * epoch).
+ */
+ lastSuccess: 0,
+
+ /**
+ * Time when the subscription was considered for an update last time (in seconds
+ * since the beginning of the epoch). This will be used to increase softExpiration
+ * if the user doesn't use Adblock Plus for some time.
+ * @type Number
+ */
+ lastCheck: 0,
+
+ /**
+ * Hard expiration time of the filter subscription (in seconds since the beginning of the epoch)
+ * @type Number
+ */
+ expires: 0,
+
+ /**
+ * Soft expiration time of the filter subscription (in seconds since the beginning of the epoch)
+ * @type Number
+ */
+ softExpiration: 0,
+
+ /**
+ * Number of download failures since last success
+ * @type Number
+ */
+ errors: 0,
+
+ /**
+ * Minimal Adblock Plus version required for this subscription
+ * @type String
+ */
+ requiredVersion: null,
+
+ /**
+ * Should be true if requiredVersion is higher than current Adblock Plus version
+ * @type Boolean
+ */
+ upgradeRequired: false,
+
+ /**
+ * Value of the X-Alternative-Locations header: comma-separated list of URLs
+ * with their weighting factors, e.g.: http://foo.example.com/;q=0.5,http://bar.example.com/;q=2
+ * @type String
+ */
+ alternativeLocations: null,
+
+ /**
+ * See Subscription.serialize()
+ */
+ serialize: function(buffer)
+ {
+ RegularSubscription.prototype.serialize.call(this, buffer);
+ if (!this.autoDownload)
+ buffer.push("autoDownload=false");
+ if (this.nextURL)
+ buffer.push("nextURL=" + this.nextURL);
+ if (this.downloadStatus)
+ buffer.push("downloadStatus=" + this.downloadStatus);
+ if (this.lastModified)
+ buffer.push("lastModified=" + this.lastModified);
+ if (this.lastSuccess)
+ buffer.push("lastSuccess=" + this.lastSuccess);
+ if (this.lastCheck)
+ buffer.push("lastCheck=" + this.lastCheck);
+ if (this.expires)
+ buffer.push("expires=" + this.expires);
+ if (this.softExpiration)
+ buffer.push("softExpiration=" + this.softExpiration);
+ if (this.errors)
+ buffer.push("errors=" + this.errors);
+ if (this.requiredVersion)
+ buffer.push("requiredVersion=" + this.requiredVersion);
+ if (this.alternativeLocations)
+ buffer.push("alternativeLocations=" + this.alternativeLocations);
+ }
};
diff --git a/modules/Survey.jsm b/modules/Survey.jsm
new file mode 100644
index 0000000..b740eba
--- /dev/null
+++ b/modules/Survey.jsm
@@ -0,0 +1,163 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Adblock Plus.
+ *
+ * The Initial Developer of the Original Code is
+ * Wladimir Palant.
+ * Portions created by the Initial Developer are Copyright (C) 2006-2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+var EXPORTED_SYMBOLS = ["Survey"];
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+const Cu = Components.utils;
+
+let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
+
+Cu.import(baseURL.spec + "Utils.jsm");
+Cu.import(baseURL.spec + "Prefs.jsm");
+Cu.import(baseURL.spec + "AppIntegration.jsm");
+
+var Survey =
+{
+ startup: initSurvey
+};
+
+let surveyTimer = null;
+let surveyLang = null;
+
+let langData = {
+ en: {
+ title: "Tell us your opinion",
+ question: "We would like to ask you a few questions about Adblock Plus to help us improve it. If you can spare 5 minutes please click the button below to take the survey.",
+ note: "This is a one-time message and will not appear again.",
+ accept: "Take the survey",
+ decline: "Maybe some other time"
+ },
+ de: {
+ title: "Sagen Sie uns Ihre Meinung",
+ question: "Wir w\xFCrden Ihnen gerne einige Fragen zu Adblock Plus stellen, um es verbessern zu k\xF6nnen. Falls Sie gerade 5 Minuten haben, dr\xFCcken Sie bitte die Taste unten, um an der Nutzerumfrage teilzunehmen.",
+ note: "Das ist eine einmalige Nachricht, die nicht wieder erscheinen wird.",
+ accept: "An der Umfrage teilnehmen",
+ decline: "Vielleicht ein anderes Mal"
+ },
+ ru: {
+ title: decodeURIComponent("%D0%9F%D0%BE%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D0%B5%D1%81%D1%8C%20%D1%81%20%D0%BD%D0%B0%D0%BC%D0%B8%20%D1%81%D0%B2%D0%BE%D0%B8%D0%BC%20%D0%BC%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5%D0%BC"),
+ question: decodeURIComponent("%D0%9C%D1%8B%20%D1%85%D0%BE%D1%82%D0%B5%D0%BB%D0%B8%20%D0%B1%D1%8B%20%D0%B7%D0%B0%D0%B4%D0%B0%D1%82%D1%8C%20%D0%B2%D0%B0%D0%BC%20%D0%BD%D0%B5%D0%BA%D0%BE%D1%82%D0%BE%D1%80%D1%8B%D0%B5%20%D0%B2%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D1%8B%20%D0%BE%D0%B1%20Adblock%20Plus%2C%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%BB%D1%83%D1%87%D1%88%D0%B5%20%D0%BE%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B8%D1%82%D1%8C%20%D0%BD%D0%B0%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B4%D0%BB%D1%8F%20%D0%B5%D0%B3%D0%BE%20%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%B5%D0%B9%D1%88%D0%B5%D0%B3%D0%BE%20%D1%80%D0%B0%D0%B7%D0%B2%D0%B8%D1%82%D0%B8%D1%8F.%20%D0%95%D1%81%D0%BB%D0%B8%20%D1%83%20%D0%B2%D0%B0%D1%81%20%D0%B5%D1%81%D1%82%D1%8C%20%D1%81%D0%B2%D0%BE%D0%B1%D0%BE%D0%B4%D0%BD%D1%8B%D0%B5%205%20%D0%BC%D0%B8%D0%BD%D1%83%D1%82%2C%20%D1%82%D0%BE%20%D0%BD%D0%B0%D0%B6%D0%BC%D0%B8%D1%82%D0%B5%2C%20%D0%BF%D0%BE%D0%B6%D0%B0%D0%BB%D1%83%D0%B9%D1%81%D1%82%D0%B0%2C%20%D0%BD%D0%B0%20%D0%BA%D0%BD%D0%BE%D0%BF%D0%BA%D1%83%2C%20%D1%87%D1%82%D0%BE%D0%B1%D1%8B%20%D0%BF%D1%80%D0%B8%D0%BD%D1%8F%D1%82%D1%8C%20%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%B8%D0%B5%20%D0%B2%20%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%B5."),
+ note: decodeURIComponent("%D0%AD%D1%82%D0%BE%20%D0%BE%D0%B4%D0%BD%D0%BE%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%BE%D0%B5%20%D1%81%D0%BE%D0%BE%D0%B1%D1%89%D0%B5%D0%BD%D0%B8%D0%B5%2C%20%D0%BE%D0%BD%D0%BE%20%D0%B1%D0%BE%D0%BB%D1%8C%D1%88%D0%B5%20%D0%BD%D0%B5%20%D0%B1%D1%83%D0%B4%D0%B5%D1%82%20%D0%BF%D0%BE%D0%BA%D0%B0%D0%B7%D1%8B%D0%B2%D0%B0%D1%82%D1%8C%D1%81%D1%8F."),
+ accept: decodeURIComponent("%D0%9F%D1%80%D0%B8%D0%BD%D1%8F%D1%82%D1%8C%20%D1%83%D1%87%D0%B0%D1%81%D1%82%D0%B8%D0%B5%20%D0%B2%20%D0%BE%D0%BF%D1%80%D0%BE%D1%81%D0%B5"),
+ decline: decodeURIComponent("%D0%9C%D0%BE%D0%B6%D0%B5%D1%82%20%D0%B2%20%D0%B4%D1%80%D1%83%D0%B3%D0%BE%D0%B9%20%D1%80%D0%B0%D0%B7")
+ }
+};
+
+function initSurvey()
+{
+ // Only look at users updating from another 1.3.x version
+ let prevVersion = Prefs.currentVersion;
+ let currentVersion = Utils.addonVersion;
+ if (prevVersion == currentVersion || Utils.versionComparator.compare(prevVersion, "1.3") < 0)
+ return;
+
+ // Don't ask after 2011-11-10
+ if (Date.now() > 1320883200000)
+ return;
+
+ // Only Firefox users
+ if (Utils.appID != "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}")
+ return;
+
+ // Only Firefox 4 and higher
+ if (Utils.versionComparator.compare(Utils.platformVersion, "2.0") < 0)
+ return;
+
+ // Survey is only available in English/German/Russian
+ if (!/^(en|de|ru)\b/.test(Utils.appLocale))
+ return;
+ surveyLang = RegExp.$1;
+
+ // Only ask 0.5% of the users
+ if (Math.random() > 0.005)
+ return;
+
+ // Delay survey question by 20 seconds
+ surveyTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ surveyTimer.initWithCallback(runSurvey, 20000, Ci.nsITimer.TYPE_ONE_SHOT);
+}
+
+function runSurvey()
+{
+ surveyTimer = null;
+
+ let browser = Utils.windowMediator.getMostRecentWindow("navigator:browser");
+ if (!browser)
+ return;
+
+ let wrapper = AppIntegration.getWrapperForWindow(browser);
+ if (!wrapper)
+ return null;
+
+ let button = wrapper.E("abp-toolbarbutton") || wrapper.E("abp-status");
+ if (!button)
+ return;
+
+ let lang = langData[surveyLang];
+ let panel = new wrapper.window.DOMParser().parseFromString('\
+ <panel xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" id="abp-survey-message" type="arrow" orient="vertical">\
+ <description class="title"/>\
+ <description class="question" maxwidth="300"/>\
+ <hbox>\
+ <button class="accept" dlgtype="accept"/>\
+ <spacer flex="1"/>\
+ <button class="decline" dlgtype="cancel"/>\
+ </hbox>\
+ <description class="note" maxwidth="300"/>\
+ </panel>\
+ ', "text/xml").documentElement;
+ panel.getElementsByClassName("title")[0].setAttribute("value", lang.title);
+ panel.getElementsByClassName("question")[0].textContent = lang.question;
+ panel.getElementsByClassName("note")[0].textContent = lang.note;
+ let (button = panel.getElementsByClassName("accept")[0])
+ {
+ button.setAttribute("label", lang.accept);
+ button.addEventListener("command", function()
+ {
+ panel.hidePopup();
+ openSurveyTab(wrapper);
+ }, false);
+ }
+ let (button = panel.getElementsByClassName("decline")[0])
+ {
+ button.setAttribute("label", lang.decline);
+ button.addEventListener("command", function()
+ {
+ panel.hidePopup();
+ }, false);
+ }
+ wrapper.E("abp-popupset").appendChild(panel);
+ panel.openPopup(button, "bottomcenter topcenter", 0, 0, false, false, null);
+}
+
+function openSurveyTab(wrapper)
+{
+ wrapper.window.gBrowser.loadOneTab("http://adblockplus.org/usersurvey/index.php?sid=68316&lang=" + surveyLang, {
+ referrerURI: Utils.makeURI("http://adblock.plus/"),
+ inBackground: false
+ });
+}
diff --git a/modules/Sync.jsm b/modules/Sync.jsm
index 8f6c00e..e8b7ceb 100644
--- a/modules/Sync.jsm
+++ b/modules/Sync.jsm
@@ -55,306 +55,306 @@ var Tracker = null;
var Sync =
{
- /**
- * Will be set to true if/when Weave starts up.
- * @type Boolean
- */
- initialized: false,
-
- /**
- * Whether Weave requested us to track changes.
- * @type Boolean
- */
- trackingEnabled: false,
-
- /**
- * Called on module startup.
- */
- startup: function()
- {
- Utils.observerService.addObserver(SyncPrivate, "weave:service:ready", true);
- Utils.observerService.addObserver(SyncPrivate, "weave:engine:start-tracking", true);
- Utils.observerService.addObserver(SyncPrivate, "weave:engine:stop-tracking", true);
- },
-
- /**
- * Returns Adblock Plus sync engine.
- * @result Engine
- */
- getEngine: function()
- {
- if (this.initialized)
- return Weave.Engines.get("adblockplus");
- else
- return null;
- }
+ /**
+ * Will be set to true if/when Weave starts up.
+ * @type Boolean
+ */
+ initialized: false,
+
+ /**
+ * Whether Weave requested us to track changes.
+ * @type Boolean
+ */
+ trackingEnabled: false,
+
+ /**
+ * Called on module startup.
+ */
+ startup: function()
+ {
+ Utils.observerService.addObserver(SyncPrivate, "weave:service:ready", true);
+ Utils.observerService.addObserver(SyncPrivate, "weave:engine:start-tracking", true);
+ Utils.observerService.addObserver(SyncPrivate, "weave:engine:stop-tracking", true);
+ },
+
+ /**
+ * Returns Adblock Plus sync engine.
+ * @result Engine
+ */
+ getEngine: function()
+ {
+ if (this.initialized)
+ return Weave.Engines.get("adblockplus");
+ else
+ return null;
+ }
};
var SyncPrivate =
{
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
-
- observe: function(subject, topic, data)
- {
- switch (topic)
- {
- case "weave:service:ready":
- Cu.import("resource://services-sync/main.js");
-
- Tracker = Weave.SyncEngine.prototype._trackerObj;
- ABPEngine.prototype.__proto__ = Weave.SyncEngine.prototype;
- ABPStore.prototype.__proto__ = Weave.Store.prototype;
- ABPTracker.prototype.__proto__ = Tracker.prototype;
-
- Weave.Engines.register(ABPEngine);
- Sync.initialized = true;
- break;
- case "weave:engine:start-tracking":
- Sync.trackingEnabled = true;
- if (trackerInstance)
- trackerInstance.startTracking();
- break;
- case "weave:engine:stop-tracking":
- Sync.trackingEnabled = false;
- if (trackerInstance)
- trackerInstance.stopTracking();
- break;
- }
- }
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
+
+ observe: function(subject, topic, data)
+ {
+ switch (topic)
+ {
+ case "weave:service:ready":
+ Cu.import("resource://services-sync/main.js");
+
+ Tracker = Weave.SyncEngine.prototype._trackerObj;
+ ABPEngine.prototype.__proto__ = Weave.SyncEngine.prototype;
+ ABPStore.prototype.__proto__ = Weave.Store.prototype;
+ ABPTracker.prototype.__proto__ = Tracker.prototype;
+
+ Weave.Engines.register(ABPEngine);
+ Sync.initialized = true;
+ break;
+ case "weave:engine:start-tracking":
+ Sync.trackingEnabled = true;
+ if (trackerInstance)
+ trackerInstance.startTracking();
+ break;
+ case "weave:engine:stop-tracking":
+ Sync.trackingEnabled = false;
+ if (trackerInstance)
+ trackerInstance.stopTracking();
+ break;
+ }
+ }
};
function ABPEngine()
{
- Weave.SyncEngine.call(this, "AdblockPlus");
+ Weave.SyncEngine.call(this, "AdblockPlus");
}
ABPEngine.prototype =
{
- _storeObj: ABPStore,
- _trackerObj: ABPTracker,
- version: 1,
-
- _reconcile: function(item)
- {
- // Always process server data, we will do the merging ourselves
- return true;
- }
+ _storeObj: ABPStore,
+ _trackerObj: ABPTracker,
+ version: 1,
+
+ _reconcile: function(item)
+ {
+ // Always process server data, we will do the merging ourselves
+ return true;
+ }
};
function ABPStore(name)
{
- Weave.Store.call(this, name);
+ Weave.Store.call(this, name);
}
ABPStore.prototype =
{
- getAllIDs: function()
- {
- let result = {}
- result[filtersRecordID] = true;
- return result;
- },
-
- changeItemID: function(oldId, newId)
- {
- // This should not be called, our engine doesn't implement _findDupe
- throw Cr.NS_ERROR_UNEXPECTED;
- },
-
- itemExists: function(id)
- {
- // Only one id exists so far
- return (id == filtersRecordID);
- },
-
- createRecord: function(id, collection)
- {
- let record = new ABPEngine.prototype._recordObj(collection, id);
- if (id == filtersRecordID)
- {
- record.cleartext = {
- id: id,
- subscriptions: [],
- };
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (subscription instanceof ExternalSubscription)
- continue;
-
- let subscriptionEntry =
- {
- url: subscription.url,
- disabled: subscription.disabled
- };
- if (subscription instanceof SpecialSubscription)
- {
- subscriptionEntry.filters = [];
- for each (let filter in subscription.filters)
- {
- let filterEntry = {text: filter.text};
- if (filter instanceof ActiveFilter)
- filterEntry.disabled = filter.disabled;
- subscriptionEntry.filters.push(filterEntry);
- }
- }
- else
- {
- subscriptionEntry.title = subscription.title;
- subscriptionEntry.autoDownload = subscription.autoDownload;
- }
- record.cleartext.subscriptions.push(subscriptionEntry);
- }
-
- // Data sent, forget about local changes now
- trackerInstance.clearPrivateChanges()
- }
- else
- record.deleted = true;
-
- return record;
- },
-
- create: function(record)
- {
- // This should not be called because our record list doesn't change but
- // call update just in case.
- this.update(record);
- },
-
- update: function(record)
- {
- if (record.id != filtersRecordID)
- return;
-
- this._log.trace("Merging in remote data");
-
- let data = record.cleartext.subscriptions;
-
- // First make sure we have the same subscriptions on both sides
- let seenSubscription = {__proto__: null};
- for each (let remoteSubscription in data)
- {
- seenSubscription[remoteSubscription.url] = true;
- if (remoteSubscription.url in FilterStorage.knownSubscriptions)
- {
- let subscription = FilterStorage.knownSubscriptions[remoteSubscription.url];
- if (!trackerInstance.didSubscriptionChange(remoteSubscription))
- {
- // Only change local subscription if there were no changes, otherwise dismiss remote changes
- if (subscription.disabled != remoteSubscription.disabled)
- {
- subscription.disabled = remoteSubscription.disabled;
- FilterStorage.triggerObservers(subscription.disabled ? "subscriptions disable" : "subscriptions enable", [subscription]);
- }
-
- if (subscription instanceof DownloadableSubscription && (subscription.title != remoteSubscription.title ||
- subscription.autoDownload != remoteSubscription.autoDownload))
- {
- subscription.title = remoteSubscription.title;
- subscription.autoDownload = remoteSubscription.autoDownload;
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
- }
- }
- }
- else if (!trackerInstance.didSubscriptionChange(remoteSubscription))
- {
- // Subscription was added remotely, add it locally as well
- let subscription = Subscription.fromURL(remoteSubscription.url);
- if (!subscription)
- continue;
-
- subscription.disabled = remoteSubscription.disabled;
- if (subscription instanceof DownloadableSubscription)
- {
- subscription.title = remoteSubscription.title;
- subscription.autoDownload = remoteSubscription.autoDownload;
- FilterStorage.addSubscription(subscription);
- Synchronizer.execute(subscription);
- }
- }
- }
-
- for each (let subscription in FilterStorage.subscriptions.slice())
- {
- if (!(subscription.url in seenSubscription) && subscription instanceof DownloadableSubscription && !trackerInstance.didSubscriptionChange(subscription))
- {
- // Subscription was removed remotely, remove it locally as well
- FilterStorage.removeSubscription(subscription);
- }
- }
-
- // Now sync the custom filters
- let seenFilter = {__proto__: null};
- for each (let remoteSubscription in data)
- {
- if (!("filters" in remoteSubscription))
- continue;
-
- for each (let remoteFilter in remoteSubscription.filters)
- {
- seenFilter[remoteFilter.text] = true;
-
- let filter = Filter.fromText(remoteFilter.text);
- if (!filter || trackerInstance.didFilterChange(filter))
- continue;
-
- if (filter.subscriptions.some(function(subscription) subscription instanceof SpecialSubscription))
- {
- // Filter might have been changed remotely
- if (filter instanceof ActiveFilter && filter.disabled != remoteFilter.disabled)
- {
- filter.disabled = remoteFilter.disabled;
- FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter]);
- }
- }
- else
- {
- // Filter was added remotely, add it locally as well
- FilterStorage.addFilter(filter);
- }
- }
- }
-
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (!(subscription instanceof SpecialSubscription))
- continue;
-
- for each (let filter in subscription.filters.slice())
- {
- if (!(filter.text in seenFilter) && !trackerInstance.didFilterChange(filter))
- {
- // Filter was removed remotely, remove it locally as well
- FilterStorage.removeFilter(filter);
- }
- }
- }
-
- // Merge done, forget about local changes now
- trackerInstance.clearPrivateChanges()
- },
-
- remove: function(record)
- {
- // Shouldn't be called but if it is - ignore
- },
-
- wipe: function()
- {
- this._log.trace("Got wipe command, removing all data");
-
- for each (let subscription in FilterStorage.subscriptions.slice())
- {
- if (subscription instanceof DownloadableSubscription)
- FilterStorage.removeSubscription(subscription);
- else if (subscription instanceof SpecialSubscription)
- {
- for each (let filter in subscription.filters.slice())
- FilterStorage.removeFilter(filter);
- }
- }
-
- // Data wiped, forget about local changes now
- trackerInstance.clearPrivateChanges()
- }
+ getAllIDs: function()
+ {
+ let result = {}
+ result[filtersRecordID] = true;
+ return result;
+ },
+
+ changeItemID: function(oldId, newId)
+ {
+ // This should not be called, our engine doesn't implement _findDupe
+ throw Cr.NS_ERROR_UNEXPECTED;
+ },
+
+ itemExists: function(id)
+ {
+ // Only one id exists so far
+ return (id == filtersRecordID);
+ },
+
+ createRecord: function(id, collection)
+ {
+ let record = new ABPEngine.prototype._recordObj(collection, id);
+ if (id == filtersRecordID)
+ {
+ record.cleartext = {
+ id: id,
+ subscriptions: [],
+ };
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (subscription instanceof ExternalSubscription)
+ continue;
+
+ let subscriptionEntry =
+ {
+ url: subscription.url,
+ disabled: subscription.disabled
+ };
+ if (subscription instanceof SpecialSubscription)
+ {
+ subscriptionEntry.filters = [];
+ for each (let filter in subscription.filters)
+ {
+ let filterEntry = {text: filter.text};
+ if (filter instanceof ActiveFilter)
+ filterEntry.disabled = filter.disabled;
+ subscriptionEntry.filters.push(filterEntry);
+ }
+ }
+ else
+ {
+ subscriptionEntry.title = subscription.title;
+ subscriptionEntry.autoDownload = subscription.autoDownload;
+ }
+ record.cleartext.subscriptions.push(subscriptionEntry);
+ }
+
+ // Data sent, forget about local changes now
+ trackerInstance.clearPrivateChanges()
+ }
+ else
+ record.deleted = true;
+
+ return record;
+ },
+
+ create: function(record)
+ {
+ // This should not be called because our record list doesn't change but
+ // call update just in case.
+ this.update(record);
+ },
+
+ update: function(record)
+ {
+ if (record.id != filtersRecordID)
+ return;
+
+ this._log.trace("Merging in remote data");
+
+ let data = record.cleartext.subscriptions;
+
+ // First make sure we have the same subscriptions on both sides
+ let seenSubscription = {__proto__: null};
+ for each (let remoteSubscription in data)
+ {
+ seenSubscription[remoteSubscription.url] = true;
+ if (remoteSubscription.url in FilterStorage.knownSubscriptions)
+ {
+ let subscription = FilterStorage.knownSubscriptions[remoteSubscription.url];
+ if (!trackerInstance.didSubscriptionChange(remoteSubscription))
+ {
+ // Only change local subscription if there were no changes, otherwise dismiss remote changes
+ if (subscription.disabled != remoteSubscription.disabled)
+ {
+ subscription.disabled = remoteSubscription.disabled;
+ FilterStorage.triggerObservers(subscription.disabled ? "subscriptions disable" : "subscriptions enable", [subscription]);
+ }
+
+ if (subscription instanceof DownloadableSubscription && (subscription.title != remoteSubscription.title ||
+ subscription.autoDownload != remoteSubscription.autoDownload))
+ {
+ subscription.title = remoteSubscription.title;
+ subscription.autoDownload = remoteSubscription.autoDownload;
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+ }
+ }
+ }
+ else if (!trackerInstance.didSubscriptionChange(remoteSubscription))
+ {
+ // Subscription was added remotely, add it locally as well
+ let subscription = Subscription.fromURL(remoteSubscription.url);
+ if (!subscription)
+ continue;
+
+ subscription.disabled = remoteSubscription.disabled;
+ if (subscription instanceof DownloadableSubscription)
+ {
+ subscription.title = remoteSubscription.title;
+ subscription.autoDownload = remoteSubscription.autoDownload;
+ FilterStorage.addSubscription(subscription);
+ Synchronizer.execute(subscription);
+ }
+ }
+ }
+
+ for each (let subscription in FilterStorage.subscriptions.slice())
+ {
+ if (!(subscription.url in seenSubscription) && subscription instanceof DownloadableSubscription && !trackerInstance.didSubscriptionChange(subscription))
+ {
+ // Subscription was removed remotely, remove it locally as well
+ FilterStorage.removeSubscription(subscription);
+ }
+ }
+
+ // Now sync the custom filters
+ let seenFilter = {__proto__: null};
+ for each (let remoteSubscription in data)
+ {
+ if (!("filters" in remoteSubscription))
+ continue;
+
+ for each (let remoteFilter in remoteSubscription.filters)
+ {
+ seenFilter[remoteFilter.text] = true;
+
+ let filter = Filter.fromText(remoteFilter.text);
+ if (!filter || trackerInstance.didFilterChange(filter))
+ continue;
+
+ if (filter.subscriptions.some(function(subscription) subscription instanceof SpecialSubscription))
+ {
+ // Filter might have been changed remotely
+ if (filter instanceof ActiveFilter && filter.disabled != remoteFilter.disabled)
+ {
+ filter.disabled = remoteFilter.disabled;
+ FilterStorage.triggerObservers(filter.disabled ? "filters disable" : "filters enable", [filter]);
+ }
+ }
+ else
+ {
+ // Filter was added remotely, add it locally as well
+ FilterStorage.addFilter(filter);
+ }
+ }
+ }
+
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (!(subscription instanceof SpecialSubscription))
+ continue;
+
+ for each (let filter in subscription.filters.slice())
+ {
+ if (!(filter.text in seenFilter) && !trackerInstance.didFilterChange(filter))
+ {
+ // Filter was removed remotely, remove it locally as well
+ FilterStorage.removeFilter(filter);
+ }
+ }
+ }
+
+ // Merge done, forget about local changes now
+ trackerInstance.clearPrivateChanges()
+ },
+
+ remove: function(record)
+ {
+ // Shouldn't be called but if it is - ignore
+ },
+
+ wipe: function()
+ {
+ this._log.trace("Got wipe command, removing all data");
+
+ for each (let subscription in FilterStorage.subscriptions.slice())
+ {
+ if (subscription instanceof DownloadableSubscription)
+ FilterStorage.removeSubscription(subscription);
+ else if (subscription instanceof SpecialSubscription)
+ {
+ for each (let filter in subscription.filters.slice())
+ FilterStorage.removeFilter(filter);
+ }
+ }
+
+ // Data wiped, forget about local changes now
+ trackerInstance.clearPrivateChanges()
+ }
};
/**
@@ -364,98 +364,98 @@ let trackerInstance = null;
function ABPTracker(name)
{
- Tracker.call(this, name);
+ Tracker.call(this, name);
- this.privateTracker = new Tracker(name + ".private");
- trackerInstance = this;
+ this.privateTracker = new Tracker(name + ".private");
+ trackerInstance = this;
- this.onChange = this._bindMethod(this.onChange);
+ this.onChange = this._bindMethod(this.onChange);
- if (Sync.trackingEnabled)
- this.startTracking();
+ if (Sync.trackingEnabled)
+ this.startTracking();
}
ABPTracker.prototype =
{
- privateTracker: null,
-
- _bindMethod: function(method)
- {
- let me = this;
- return function() method.apply(me, arguments);
- },
-
- startTracking: function()
- {
- FilterStorage.addObserver(this.onChange);
- },
-
- stopTracking: function()
- {
- FilterStorage.removeObserver(this.onChange);
- },
-
- clearPrivateChanges: function()
- {
- this.privateTracker.clearChangedIDs();
- },
-
- addPrivateChange: function(id)
- {
- // Ignore changes during syncing
- if (this.ignoreAll)
- return;
-
- this.addChangedID(filtersRecordID);
- this.privateTracker.addChangedID(id);
- this.score += 10;
- },
-
- didSubscriptionChange: function(subscription)
- {
- return ("subscription " + subscription.url) in this.privateTracker.changedIDs;
- },
-
- didFilterChange: function(filter)
- {
- return ("filter " + filter.text) in this.privateTracker.changedIDs;
- },
-
- onChange: function(action, items)
- {
- for each (let item in items)
- {
- switch (action)
- {
- case "subscriptions update":
- if ("oldSubscription" in item)
- {
- // Subscription moved to a new address
- this.addPrivateChange("subscription " + item.url);
- this.addPrivateChange("subscription " + item.oldSubscription.url);
- }
- else if (item instanceof SpecialSubscription)
- {
- // User's filters changed via Preferences window
- for each (let filter in item.filters)
- this.addPrivateChange("filter " + filter.text);
- for each (let filter in item.oldFilters)
- this.addPrivateChange("filter " + filter.text);
- }
- break;
- case "subscriptions add":
- case "subscriptions remove":
- case "subscriptions enable":
- case "subscriptions disable":
- case "subscriptions updateinfo":
- this.addPrivateChange("subscription " + item.url);
- break;
- case "filters add":
- case "filters remove":
- case "filters enable":
- case "filters disable":
- this.addPrivateChange("filter " + item.text);
- break;
- }
- }
- }
+ privateTracker: null,
+
+ _bindMethod: function(method)
+ {
+ let me = this;
+ return function() method.apply(me, arguments);
+ },
+
+ startTracking: function()
+ {
+ FilterStorage.addObserver(this.onChange);
+ },
+
+ stopTracking: function()
+ {
+ FilterStorage.removeObserver(this.onChange);
+ },
+
+ clearPrivateChanges: function()
+ {
+ this.privateTracker.clearChangedIDs();
+ },
+
+ addPrivateChange: function(id)
+ {
+ // Ignore changes during syncing
+ if (this.ignoreAll)
+ return;
+
+ this.addChangedID(filtersRecordID);
+ this.privateTracker.addChangedID(id);
+ this.score += 10;
+ },
+
+ didSubscriptionChange: function(subscription)
+ {
+ return ("subscription " + subscription.url) in this.privateTracker.changedIDs;
+ },
+
+ didFilterChange: function(filter)
+ {
+ return ("filter " + filter.text) in this.privateTracker.changedIDs;
+ },
+
+ onChange: function(action, items)
+ {
+ for each (let item in items)
+ {
+ switch (action)
+ {
+ case "subscriptions update":
+ if ("oldSubscription" in item)
+ {
+ // Subscription moved to a new address
+ this.addPrivateChange("subscription " + item.url);
+ this.addPrivateChange("subscription " + item.oldSubscription.url);
+ }
+ else if (item instanceof SpecialSubscription)
+ {
+ // User's filters changed via Preferences window
+ for each (let filter in item.filters)
+ this.addPrivateChange("filter " + filter.text);
+ for each (let filter in item.oldFilters)
+ this.addPrivateChange("filter " + filter.text);
+ }
+ break;
+ case "subscriptions add":
+ case "subscriptions remove":
+ case "subscriptions enable":
+ case "subscriptions disable":
+ case "subscriptions updateinfo":
+ this.addPrivateChange("subscription " + item.url);
+ break;
+ case "filters add":
+ case "filters remove":
+ case "filters enable":
+ case "filters disable":
+ this.addPrivateChange("filter " + item.text);
+ break;
+ }
+ }
+ }
};
diff --git a/modules/Synchronizer.jsm b/modules/Synchronizer.jsm
index be5b463..296e374 100644
--- a/modules/Synchronizer.jsm
+++ b/modules/Synchronizer.jsm
@@ -36,7 +36,7 @@ const Cu = Components.utils;
let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import(baseURL.spec + "TimeLine.jsm");
+
Cu.import(baseURL.spec + "Utils.jsm");
Cu.import(baseURL.spec + "FilterStorage.jsm");
Cu.import(baseURL.spec + "FilterClasses.jsm");
@@ -70,331 +70,331 @@ let executing = {__proto__: null};
*/
var Synchronizer =
{
- /**
- * Called on module startup.
- */
- startup: function()
- {
- TimeLine.enter("Entered Synchronizer.startup()");
-
- let callback = function()
- {
- timer.delay = CHECK_INTERVAL * MILLISECONDS_IN_SECOND;
- checkSubscriptions();
- };
-
- timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- timer.initWithCallback(callback, INITIAL_DELAY * MILLISECONDS_IN_SECOND, Ci.nsITimer.TYPE_REPEATING_SLACK);
-
- TimeLine.leave("Synchronizer.startup() done");
- },
-
- /**
- * Checks whether a subscription is currently being downloaded.
- * @param {String} url URL of the subscription
- * @return {Boolean}
- */
- isExecuting: function(url)
- {
- return url in executing;
- },
-
- /**
- * Starts the download of a subscription.
- * @param {DownloadableSubscription} subscription Subscription to be downloaded
- * @param {Boolean} manual true for a manually started download (should not trigger fallback requests)
- * @param {Boolean} forceDownload if true, the subscription will even be redownloaded if it didn't change on the server
- */
- execute: function(subscription, manual, forceDownload)
- {
- // Delay execution, SeaMonkey 2.1 won't fire request's event handlers
- // otherwise if the window that called us is closed.
- Utils.runAsync(this.executeInternal, this, subscription, manual, forceDownload);
- },
-
- executeInternal: function(subscription, manual, forceDownload)
- {
- let url = subscription.url;
- if (url in executing)
- return;
-
- let newURL = subscription.nextURL;
- let hadTemporaryRedirect = false;
- subscription.nextURL = null;
-
- let curVersion = Utils.addonVersion;
- let loadFrom = newURL;
- let isBaseLocation = true;
- if (!loadFrom)
- loadFrom = url;
- if (loadFrom == url)
- {
- if (subscription.alternativeLocations)
- {
- // We have alternative download locations, choose one. "Regular"
- // subscription URL always goes in with weight 1.
- let options = [[1, url]];
- let totalWeight = 1;
- for each (let alternative in subscription.alternativeLocations.split(','))
- {
- if (!/^https?:\/\//.test(alternative))
- continue;
-
- let weight = 1;
- let weightingRegExp = /;q=([\d\.]+)$/;
- if (weightingRegExp.test(alternative))
- {
- weight = parseFloat(RegExp.$1);
- if (isNaN(weight) || !isFinite(weight) || weight < 0)
- weight = 1;
- if (weight > 10)
- weight = 10;
-
- alternative = alternative.replace(weightingRegExp, "");
- }
- options.push([weight, alternative]);
- totalWeight += weight;
- }
-
- let choice = Math.random() * totalWeight;
- for each (let [weight, alternative] in options)
- {
- choice -= weight;
- if (choice < 0)
- {
- loadFrom = alternative;
- break;
- }
- }
-
- isBaseLocation = (loadFrom == url);
- }
- }
- else
- {
- // Ignore modification date if we are downloading from a different location
- forceDownload = true;
- }
- loadFrom = loadFrom.replace(/%VERSION%/, "ABP" + curVersion);
-
- let request = null;
- function errorCallback(error)
- {
- let channelStatus = -1;
- try
- {
- channelStatus = request.channel.status;
- } catch (e) {}
- let responseStatus = "";
- try
- {
- responseStatus = request.channel.QueryInterface(Ci.nsIHttpChannel).responseStatus;
- } catch (e) {}
- setError(subscription, error, channelStatus, responseStatus, loadFrom, isBaseLocation, manual);
- }
-
- try
- {
- request = new XMLHttpRequest();
- request.mozBackgroundRequest = true;
- request.open("GET", loadFrom);
- }
- catch (e)
- {
- errorCallback("synchronize_invalid_url");
- return;
- }
-
- try {
- request.overrideMimeType("text/plain");
- request.channel.loadFlags = request.channel.loadFlags |
- request.channel.INHIBIT_CACHING |
- request.channel.VALIDATE_ALWAYS;
-
- // Override redirect limit from preferences, user might have set it to 1
- if (request.channel instanceof Ci.nsIHttpChannel)
- request.channel.redirectionLimit = 5;
-
- var oldNotifications = request.channel.notificationCallbacks;
- var oldEventSink = null;
- request.channel.notificationCallbacks =
- {
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor, Ci.nsIChannelEventSink]),
-
- getInterface: function(iid)
- {
- if (iid.equals(Ci.nsIChannelEventSink))
- {
- try {
- oldEventSink = oldNotifications.QueryInterface(iid);
- } catch(e) {}
- return this;
- }
-
- if (oldNotifications)
- return oldNotifications.QueryInterface(iid);
- else
- throw Cr.NS_ERROR_NO_INTERFACE;
- },
-
- // Old (Gecko 1.9.x) version
- onChannelRedirect: function(oldChannel, newChannel, flags)
- {
- if (isBaseLocation && !hadTemporaryRedirect && oldChannel instanceof Ci.nsIHttpChannel)
- {
- try
- {
- subscription.alternativeLocations = oldChannel.getResponseHeader("X-Alternative-Locations");
- }
- catch (e)
- {
- subscription.alternativeLocations = null;
- }
- }
-
- if (flags & Ci.nsIChannelEventSink.REDIRECT_TEMPORARY)
- hadTemporaryRedirect = true;
- else if (!hadTemporaryRedirect)
- newURL = newChannel.URI.spec;
-
- if (oldEventSink)
- oldEventSink.onChannelRedirect(oldChannel, newChannel, flags);
- },
-
- // New (Gecko 2.0) version
- asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
- {
- this.onChannelRedirect(oldChannel, newChannel, flags);
-
- // If onChannelRedirect didn't throw an exception indicate success
- callback.onRedirectVerifyCallback(Cr.NS_OK);
- }
- }
- }
- catch (e)
- {
- Cu.reportError(e)
- }
-
- if (subscription.lastModified && !forceDownload)
- request.setRequestHeader("If-Modified-Since", subscription.lastModified);
-
- request.onerror = function(ev)
- {
- delete executing[url];
- try {
- request.channel.notificationCallbacks = null;
- } catch (e) {}
-
- errorCallback("synchronize_connection_error");
- };
-
- request.onload = function(ev)
- {
- delete executing[url];
- try {
- request.channel.notificationCallbacks = null;
- } catch (e) {}
-
- // Status will be 0 for non-HTTP requests
- if (request.status && request.status != 200 && request.status != 304)
- {
- errorCallback("synchronize_connection_error");
- return;
- }
-
- let newFilters = null;
- if (request.status != 304)
- {
- newFilters = readFilters(subscription, request.responseText, errorCallback);
- if (!newFilters)
- return;
-
- subscription.lastModified = request.getResponseHeader("Last-Modified");
- }
-
- if (isBaseLocation && !hadTemporaryRedirect)
- subscription.alternativeLocations = request.getResponseHeader("X-Alternative-Locations");
- subscription.lastSuccess = subscription.lastDownload = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
- subscription.downloadStatus = "synchronize_ok";
- subscription.errors = 0;
-
- // Expiration header is relative to server time - use Date header if it exists, otherwise local time
- let now = Math.round((new Date(request.getResponseHeader("Date")).getTime() || Date.now()) / MILLISECONDS_IN_SECOND);
- let expires = Math.round(new Date(request.getResponseHeader("Expires")).getTime() / MILLISECONDS_IN_SECOND) || 0;
- let expirationInterval = (expires ? expires - now : 0);
- for each (let filter in newFilters || subscription.filters)
- {
- if (filter instanceof CommentFilter && /\bExpires\s*(?::|after)\s*(\d+)\s*(h)?/i.test(filter.text))
- {
- let interval = parseInt(RegExp.$1);
- if (RegExp.$2)
- interval *= SECONDS_IN_HOUR;
- else
- interval *= SECONDS_IN_DAY;
-
- if (interval > expirationInterval)
- expirationInterval = interval;
- }
- if (isBaseLocation && filter instanceof CommentFilter && /\bRedirect(?:\s*:\s*|\s+to\s+|\s+)(\S+)/i.test(filter.text))
- subscription.nextURL = RegExp.$1;
- }
-
- // Expiration interval should be within allowed range
- expirationInterval = Math.min(Math.max(expirationInterval, MIN_EXPIRATION_INTERVAL), MAX_EXPIRATION_INTERVAL);
-
- // Hard expiration: download immediately after twice the expiration interval
- subscription.expires = (subscription.lastDownload + expirationInterval * 2);
-
- // Soft expiration: use random interval factor between 0.8 and 1.2
- subscription.softExpiration = (subscription.lastDownload + Math.round(expirationInterval * (Math.random() * 0.4 + 0.8)));
-
- if (isBaseLocation && newURL && newURL != url)
- {
- let listed = (subscription.url in FilterStorage.knownSubscriptions);
- if (listed)
- FilterStorage.removeSubscription(subscription);
-
- url = newURL;
-
- let newSubscription = Subscription.fromURL(url);
- for (let key in newSubscription)
- delete newSubscription[key];
- for (let key in subscription)
- newSubscription[key] = subscription[key];
-
- delete Subscription.knownSubscriptions[subscription.url];
- newSubscription.oldSubscription = subscription;
- subscription = newSubscription;
- subscription.url = url;
-
- if (!(subscription.url in FilterStorage.knownSubscriptions) && listed)
- FilterStorage.addSubscription(subscription);
- }
-
- if (newFilters)
- FilterStorage.updateSubscriptionFilters(subscription, newFilters);
- else
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
- delete subscription.oldSubscription;
-
- FilterStorage.saveToDisk();
- };
-
- executing[url] = true;
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
-
- try
- {
- request.send(null);
- }
- catch (e)
- {
- delete executing[url];
- errorCallback("synchronize_connection_error");
- return;
- }
- }
+ /**
+ * Called on module startup.
+ */
+ startup: function()
+ {
+
+
+ let callback = function()
+ {
+ timer.delay = CHECK_INTERVAL * MILLISECONDS_IN_SECOND;
+ checkSubscriptions();
+ };
+
+ timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
+ timer.initWithCallback(callback, INITIAL_DELAY * MILLISECONDS_IN_SECOND, Ci.nsITimer.TYPE_REPEATING_SLACK);
+
+
+ },
+
+ /**
+ * Checks whether a subscription is currently being downloaded.
+ * @param {String} url URL of the subscription
+ * @return {Boolean}
+ */
+ isExecuting: function(url)
+ {
+ return url in executing;
+ },
+
+ /**
+ * Starts the download of a subscription.
+ * @param {DownloadableSubscription} subscription Subscription to be downloaded
+ * @param {Boolean} manual true for a manually started download (should not trigger fallback requests)
+ * @param {Boolean} forceDownload if true, the subscription will even be redownloaded if it didn't change on the server
+ */
+ execute: function(subscription, manual, forceDownload)
+ {
+ // Delay execution, SeaMonkey 2.1 won't fire request's event handlers
+ // otherwise if the window that called us is closed.
+ Utils.runAsync(this.executeInternal, this, subscription, manual, forceDownload);
+ },
+
+ executeInternal: function(subscription, manual, forceDownload)
+ {
+ let url = subscription.url;
+ if (url in executing)
+ return;
+
+ let newURL = subscription.nextURL;
+ let hadTemporaryRedirect = false;
+ subscription.nextURL = null;
+
+ let curVersion = Utils.addonVersion;
+ let loadFrom = newURL;
+ let isBaseLocation = true;
+ if (!loadFrom)
+ loadFrom = url;
+ if (loadFrom == url)
+ {
+ if (subscription.alternativeLocations)
+ {
+ // We have alternative download locations, choose one. "Regular"
+ // subscription URL always goes in with weight 1.
+ let options = [[1, url]];
+ let totalWeight = 1;
+ for each (let alternative in subscription.alternativeLocations.split(','))
+ {
+ if (!/^https?:\/\//.test(alternative))
+ continue;
+
+ let weight = 1;
+ let weightingRegExp = /;q=([\d\.]+)$/;
+ if (weightingRegExp.test(alternative))
+ {
+ weight = parseFloat(RegExp.$1);
+ if (isNaN(weight) || !isFinite(weight) || weight < 0)
+ weight = 1;
+ if (weight > 10)
+ weight = 10;
+
+ alternative = alternative.replace(weightingRegExp, "");
+ }
+ options.push([weight, alternative]);
+ totalWeight += weight;
+ }
+
+ let choice = Math.random() * totalWeight;
+ for each (let [weight, alternative] in options)
+ {
+ choice -= weight;
+ if (choice < 0)
+ {
+ loadFrom = alternative;
+ break;
+ }
+ }
+
+ isBaseLocation = (loadFrom == url);
+ }
+ }
+ else
+ {
+ // Ignore modification date if we are downloading from a different location
+ forceDownload = true;
+ }
+ loadFrom = loadFrom.replace(/%VERSION%/, "ABP" + curVersion);
+
+ let request = null;
+ function errorCallback(error)
+ {
+ let channelStatus = -1;
+ try
+ {
+ channelStatus = request.channel.status;
+ } catch (e) {}
+ let responseStatus = "";
+ try
+ {
+ responseStatus = request.channel.QueryInterface(Ci.nsIHttpChannel).responseStatus;
+ } catch (e) {}
+ setError(subscription, error, channelStatus, responseStatus, loadFrom, isBaseLocation, manual);
+ }
+
+ try
+ {
+ request = new XMLHttpRequest();
+ request.mozBackgroundRequest = true;
+ request.open("GET", loadFrom);
+ }
+ catch (e)
+ {
+ errorCallback("synchronize_invalid_url");
+ return;
+ }
+
+ try {
+ request.overrideMimeType("text/plain");
+ request.channel.loadFlags = request.channel.loadFlags |
+ request.channel.INHIBIT_CACHING |
+ request.channel.VALIDATE_ALWAYS;
+
+ // Override redirect limit from preferences, user might have set it to 1
+ if (request.channel instanceof Ci.nsIHttpChannel)
+ request.channel.redirectionLimit = 5;
+
+ var oldNotifications = request.channel.notificationCallbacks;
+ var oldEventSink = null;
+ request.channel.notificationCallbacks =
+ {
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIInterfaceRequestor, Ci.nsIChannelEventSink]),
+
+ getInterface: function(iid)
+ {
+ if (iid.equals(Ci.nsIChannelEventSink))
+ {
+ try {
+ oldEventSink = oldNotifications.QueryInterface(iid);
+ } catch(e) {}
+ return this;
+ }
+
+ if (oldNotifications)
+ return oldNotifications.QueryInterface(iid);
+ else
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ },
+
+ // Old (Gecko 1.9.x) version
+ onChannelRedirect: function(oldChannel, newChannel, flags)
+ {
+ if (isBaseLocation && !hadTemporaryRedirect && oldChannel instanceof Ci.nsIHttpChannel)
+ {
+ try
+ {
+ subscription.alternativeLocations = oldChannel.getResponseHeader("X-Alternative-Locations");
+ }
+ catch (e)
+ {
+ subscription.alternativeLocations = null;
+ }
+ }
+
+ if (flags & Ci.nsIChannelEventSink.REDIRECT_TEMPORARY)
+ hadTemporaryRedirect = true;
+ else if (!hadTemporaryRedirect)
+ newURL = newChannel.URI.spec;
+
+ if (oldEventSink)
+ oldEventSink.onChannelRedirect(oldChannel, newChannel, flags);
+ },
+
+ // New (Gecko 2.0) version
+ asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
+ {
+ this.onChannelRedirect(oldChannel, newChannel, flags);
+
+ // If onChannelRedirect didn't throw an exception indicate success
+ callback.onRedirectVerifyCallback(Cr.NS_OK);
+ }
+ }
+ }
+ catch (e)
+ {
+ Cu.reportError(e)
+ }
+
+ if (subscription.lastModified && !forceDownload)
+ request.setRequestHeader("If-Modified-Since", subscription.lastModified);
+
+ request.onerror = function(ev)
+ {
+ delete executing[url];
+ try {
+ request.channel.notificationCallbacks = null;
+ } catch (e) {}
+
+ errorCallback("synchronize_connection_error");
+ };
+
+ request.onload = function(ev)
+ {
+ delete executing[url];
+ try {
+ request.channel.notificationCallbacks = null;
+ } catch (e) {}
+
+ // Status will be 0 for non-HTTP requests
+ if (request.status && request.status != 200 && request.status != 304)
+ {
+ errorCallback("synchronize_connection_error");
+ return;
+ }
+
+ let newFilters = null;
+ if (request.status != 304)
+ {
+ newFilters = readFilters(subscription, request.responseText, errorCallback);
+ if (!newFilters)
+ return;
+
+ subscription.lastModified = request.getResponseHeader("Last-Modified");
+ }
+
+ if (isBaseLocation && !hadTemporaryRedirect)
+ subscription.alternativeLocations = request.getResponseHeader("X-Alternative-Locations");
+ subscription.lastSuccess = subscription.lastDownload = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
+ subscription.downloadStatus = "synchronize_ok";
+ subscription.errors = 0;
+
+ // Expiration header is relative to server time - use Date header if it exists, otherwise local time
+ let now = Math.round((new Date(request.getResponseHeader("Date")).getTime() || Date.now()) / MILLISECONDS_IN_SECOND);
+ let expires = Math.round(new Date(request.getResponseHeader("Expires")).getTime() / MILLISECONDS_IN_SECOND) || 0;
+ let expirationInterval = (expires ? expires - now : 0);
+ for each (let filter in newFilters || subscription.filters)
+ {
+ if (filter instanceof CommentFilter && /\bExpires\s*(?::|after)\s*(\d+)\s*(h)?/i.test(filter.text))
+ {
+ let interval = parseInt(RegExp.$1);
+ if (RegExp.$2)
+ interval *= SECONDS_IN_HOUR;
+ else
+ interval *= SECONDS_IN_DAY;
+
+ if (interval > expirationInterval)
+ expirationInterval = interval;
+ }
+ if (isBaseLocation && filter instanceof CommentFilter && /\bRedirect(?:\s*:\s*|\s+to\s+|\s+)(\S+)/i.test(filter.text))
+ subscription.nextURL = RegExp.$1;
+ }
+
+ // Expiration interval should be within allowed range
+ expirationInterval = Math.min(Math.max(expirationInterval, MIN_EXPIRATION_INTERVAL), MAX_EXPIRATION_INTERVAL);
+
+ // Hard expiration: download immediately after twice the expiration interval
+ subscription.expires = (subscription.lastDownload + expirationInterval * 2);
+
+ // Soft expiration: use random interval factor between 0.8 and 1.2
+ subscription.softExpiration = (subscription.lastDownload + Math.round(expirationInterval * (Math.random() * 0.4 + 0.8)));
+
+ if (isBaseLocation && newURL && newURL != url)
+ {
+ let listed = (subscription.url in FilterStorage.knownSubscriptions);
+ if (listed)
+ FilterStorage.removeSubscription(subscription);
+
+ url = newURL;
+
+ let newSubscription = Subscription.fromURL(url);
+ for (let key in newSubscription)
+ delete newSubscription[key];
+ for (let key in subscription)
+ newSubscription[key] = subscription[key];
+
+ delete Subscription.knownSubscriptions[subscription.url];
+ newSubscription.oldSubscription = subscription;
+ subscription = newSubscription;
+ subscription.url = url;
+
+ if (!(subscription.url in FilterStorage.knownSubscriptions) && listed)
+ FilterStorage.addSubscription(subscription);
+ }
+
+ if (newFilters)
+ FilterStorage.updateSubscriptionFilters(subscription, newFilters);
+ else
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+ delete subscription.oldSubscription;
+
+ FilterStorage.saveToDisk();
+ };
+
+ executing[url] = true;
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+
+ try
+ {
+ request.send(null);
+ }
+ catch (e)
+ {
+ delete executing[url];
+ errorCallback("synchronize_connection_error");
+ return;
+ }
+ }
};
/**
@@ -403,46 +403,46 @@ var Synchronizer =
*/
function checkSubscriptions()
{
- let hadDownloads = false;
- let time = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
- for each (let subscription in FilterStorage.subscriptions)
- {
- if (!(subscription instanceof DownloadableSubscription) || !subscription.autoDownload)
- continue;
-
- if (subscription.lastCheck && time - subscription.lastCheck > MAX_ABSENSE_INTERVAL)
- {
- // No checks for a long time interval - user must have been offline, e.g.
- // during a weekend. Increase soft expiration to prevent load peaks on the
- // server.
- subscription.softExpiration += time - subscription.lastCheck;
- }
- subscription.lastCheck = time;
-
- // Sanity check: do expiration times make sense? Make sure people changing
- // system clock don't get stuck with outdated subscriptions.
- if (subscription.expires - time > MAX_EXPIRATION_INTERVAL)
- subscription.expires = time + MAX_EXPIRATION_INTERVAL;
- if (subscription.softExpiration - time > MAX_EXPIRATION_INTERVAL)
- subscription.softExpiration = time + MAX_EXPIRATION_INTERVAL;
-
- if (subscription.softExpiration > time && subscription.expires > time)
- continue;
-
- // Do not retry downloads more often than synchronizationinterval pref dictates
- let interval = (time - subscription.lastDownload) / SECONDS_IN_HOUR;
- if (interval >= Prefs.synchronizationinterval)
- {
- hadDownloads = true;
- Synchronizer.execute(subscription, false);
- }
- }
-
- if (!hadDownloads)
- {
- // We didn't kick off any downloads - still save changes to lastCheck & Co.
- FilterStorage.saveToDisk();
- }
+ let hadDownloads = false;
+ let time = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
+ for each (let subscription in FilterStorage.subscriptions)
+ {
+ if (!(subscription instanceof DownloadableSubscription) || !subscription.autoDownload)
+ continue;
+
+ if (subscription.lastCheck && time - subscription.lastCheck > MAX_ABSENSE_INTERVAL)
+ {
+ // No checks for a long time interval - user must have been offline, e.g.
+ // during a weekend. Increase soft expiration to prevent load peaks on the
+ // server.
+ subscription.softExpiration += time - subscription.lastCheck;
+ }
+ subscription.lastCheck = time;
+
+ // Sanity check: do expiration times make sense? Make sure people changing
+ // system clock don't get stuck with outdated subscriptions.
+ if (subscription.expires - time > MAX_EXPIRATION_INTERVAL)
+ subscription.expires = time + MAX_EXPIRATION_INTERVAL;
+ if (subscription.softExpiration - time > MAX_EXPIRATION_INTERVAL)
+ subscription.softExpiration = time + MAX_EXPIRATION_INTERVAL;
+
+ if (subscription.softExpiration > time && subscription.expires > time)
+ continue;
+
+ // Do not retry downloads more often than synchronizationinterval pref dictates
+ let interval = (time - subscription.lastDownload) / SECONDS_IN_HOUR;
+ if (interval >= Prefs.synchronizationinterval)
+ {
+ hadDownloads = true;
+ Synchronizer.execute(subscription, false);
+ }
+ }
+
+ if (!hadDownloads)
+ {
+ // We didn't kick off any downloads - still save changes to lastCheck & Co.
+ FilterStorage.saveToDisk();
+ }
}
/**
@@ -454,51 +454,51 @@ function checkSubscriptions()
*/
function readFilters(subscription, text, errorCallback)
{
- let lines = text.split(/[\r\n]+/);
- if (!/\[Adblock(?:\s*Plus\s*([\d\.]+)?)?\]/i.test(lines[0]))
- {
- errorCallback("synchronize_invalid_data");
- return null;
- }
- let minVersion = RegExp.$1;
-
- for (let i = 0; i < lines.length; i++)
- {
- if (/!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(lines[i]))
- {
- lines.splice(i, 1);
- let checksumExpected = RegExp.$1;
- let checksum = Utils.generateChecksum(lines);
-
- if (checksum && checksum != checksumExpected)
- {
- errorCallback("synchronize_checksum_mismatch");
- return null;
- }
-
- break;
- }
- }
-
- delete subscription.requiredVersion;
- delete subscription.upgradeRequired;
- if (minVersion)
- {
- subscription.requiredVersion = minVersion;
- if (Utils.versionComparator.compare(minVersion, Utils.addonVersion) > 0)
- subscription.upgradeRequired = true;
- }
-
- lines.shift();
- let result = [];
- for each (let line in lines)
- {
- let filter = Filter.fromText(Filter.normalize(line));
- if (filter)
- result.push(filter);
- }
-
- return result;
+ let lines = text.split(/[\r\n]+/);
+ if (!/\[Adblock(?:\s*Plus\s*([\d\.]+)?)?\]/i.test(lines[0]))
+ {
+ errorCallback("synchronize_invalid_data");
+ return null;
+ }
+ let minVersion = RegExp.$1;
+
+ for (let i = 0; i < lines.length; i++)
+ {
+ if (/!\s*checksum[\s\-:]+([\w\+\/]+)/i.test(lines[i]))
+ {
+ lines.splice(i, 1);
+ let checksumExpected = RegExp.$1;
+ let checksum = Utils.generateChecksum(lines);
+
+ if (checksum && checksum != checksumExpected)
+ {
+ errorCallback("synchronize_checksum_mismatch");
+ return null;
+ }
+
+ break;
+ }
+ }
+
+ delete subscription.requiredVersion;
+ delete subscription.upgradeRequired;
+ if (minVersion)
+ {
+ subscription.requiredVersion = minVersion;
+ if (Utils.versionComparator.compare(minVersion, Utils.addonVersion) > 0)
+ subscription.upgradeRequired = true;
+ }
+
+ lines.shift();
+ let result = [];
+ for each (let line in lines)
+ {
+ let filter = Filter.fromText(Filter.normalize(line));
+ if (filter)
+ result.push(filter);
+ }
+
+ return result;
}
/**
@@ -513,66 +513,66 @@ function readFilters(subscription, text, errorCallback)
*/
function setError(subscription, error, channelStatus, responseStatus, downloadURL, isBaseLocation, manual)
{
- // If download from an alternative location failed, reset the list of
- // alternative locations - have to get an updated list from base location.
- if (!isBaseLocation)
- subscription.alternativeLocations = null;
-
- try {
- Cu.reportError("Adblock Plus: Downloading filter subscription " + subscription.title + " failed (" + Utils.getString(error) + ")\n" +
- "Download address: " + downloadURL + "\n" +
- "Channel status: " + channelStatus + "\n" +
- "Server response: " + responseStatus);
- } catch(e) {}
-
- subscription.lastDownload = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
- subscription.downloadStatus = error;
-
- // Request fallback URL if necessary - for automatic updates only
- if (!manual)
- {
- if (error == "synchronize_checksum_mismatch")
- {
- // No fallback for successful download with checksum mismatch, reset error counter
- subscription.errors = 0;
- }
- else
- subscription.errors++;
-
- if (subscription.errors >= Prefs.subscriptions_fallbackerrors && /^https?:\/\//i.test(subscription.url))
- {
- subscription.errors = 0;
-
- let fallbackURL = Prefs.subscriptions_fallbackurl;
- fallbackURL = fallbackURL.replace(/%VERSION%/g, encodeURIComponent(Utils.addonVersion));
- fallbackURL = fallbackURL.replace(/%SUBSCRIPTION%/g, encodeURIComponent(subscription.url));
- fallbackURL = fallbackURL.replace(/%URL%/g, encodeURIComponent(downloadURL));
- fallbackURL = fallbackURL.replace(/%ERROR%/g, encodeURIComponent(error));
- fallbackURL = fallbackURL.replace(/%CHANNELSTATUS%/g, encodeURIComponent(channelStatus));
- fallbackURL = fallbackURL.replace(/%RESPONSESTATUS%/g, encodeURIComponent(responseStatus));
-
- let request = new XMLHttpRequest();
- request.mozBackgroundRequest = true;
- request.open("GET", fallbackURL);
- request.overrideMimeType("text/plain");
- request.channel.loadFlags = request.channel.loadFlags |
- request.channel.INHIBIT_CACHING |
- request.channel.VALIDATE_ALWAYS;
- request.onload = function(ev)
- {
- if (/^301\s+(\S+)/.test(request.responseText)) // Moved permanently
- subscription.nextURL = RegExp.$1;
- else if (/^410\b/.test(request.responseText)) // Gone
- {
- subscription.autoDownload = false;
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
- }
- FilterStorage.saveToDisk();
- }
- request.send(null);
- }
- }
-
- FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
- FilterStorage.saveToDisk();
+ // If download from an alternative location failed, reset the list of
+ // alternative locations - have to get an updated list from base location.
+ if (!isBaseLocation)
+ subscription.alternativeLocations = null;
+
+ try {
+ Cu.reportError("Adblock Plus: Downloading filter subscription " + subscription.title + " failed (" + Utils.getString(error) + ")\n" +
+ "Download address: " + downloadURL + "\n" +
+ "Channel status: " + channelStatus + "\n" +
+ "Server response: " + responseStatus);
+ } catch(e) {}
+
+ subscription.lastDownload = Math.round(Date.now() / MILLISECONDS_IN_SECOND);
+ subscription.downloadStatus = error;
+
+ // Request fallback URL if necessary - for automatic updates only
+ if (!manual)
+ {
+ if (error == "synchronize_checksum_mismatch")
+ {
+ // No fallback for successful download with checksum mismatch, reset error counter
+ subscription.errors = 0;
+ }
+ else
+ subscription.errors++;
+
+ if (subscription.errors >= Prefs.subscriptions_fallbackerrors && /^https?:\/\//i.test(subscription.url))
+ {
+ subscription.errors = 0;
+
+ let fallbackURL = Prefs.subscriptions_fallbackurl;
+ fallbackURL = fallbackURL.replace(/%VERSION%/g, encodeURIComponent(Utils.addonVersion));
+ fallbackURL = fallbackURL.replace(/%SUBSCRIPTION%/g, encodeURIComponent(subscription.url));
+ fallbackURL = fallbackURL.replace(/%URL%/g, encodeURIComponent(downloadURL));
+ fallbackURL = fallbackURL.replace(/%ERROR%/g, encodeURIComponent(error));
+ fallbackURL = fallbackURL.replace(/%CHANNELSTATUS%/g, encodeURIComponent(channelStatus));
+ fallbackURL = fallbackURL.replace(/%RESPONSESTATUS%/g, encodeURIComponent(responseStatus));
+
+ let request = new XMLHttpRequest();
+ request.mozBackgroundRequest = true;
+ request.open("GET", fallbackURL);
+ request.overrideMimeType("text/plain");
+ request.channel.loadFlags = request.channel.loadFlags |
+ request.channel.INHIBIT_CACHING |
+ request.channel.VALIDATE_ALWAYS;
+ request.onload = function(ev)
+ {
+ if (/^301\s+(\S+)/.test(request.responseText)) // Moved permanently
+ subscription.nextURL = RegExp.$1;
+ else if (/^410\b/.test(request.responseText)) // Gone
+ {
+ subscription.autoDownload = false;
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+ }
+ FilterStorage.saveToDisk();
+ }
+ request.send(null);
+ }
+ }
+
+ FilterStorage.triggerObservers("subscriptions updateinfo", [subscription]);
+ FilterStorage.saveToDisk();
}
diff --git a/modules/TimeLine.jsm b/modules/TimeLine.jsm
deleted file mode 100644
index 09687cc..0000000
--- a/modules/TimeLine.jsm
+++ /dev/null
@@ -1,96 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Adblock Plus.
- *
- * The Initial Developer of the Original Code is
- * Wladimir Palant.
- * Portions created by the Initial Developer are Copyright (C) 2006-2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * @fileOverview Debugging module used for load time measurements.
- */
-
-var EXPORTED_SYMBOLS = ["TimeLine"];
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-let nestingCounter = 0;
-let firstTimeStamp = null;
-let lastTimeStamp = null;
-
-/**
- * Time logging module, used to measure startup time of Adblock Plus (development builds only).
- * @class
- */
-var TimeLine = {
- /**
- * Logs an event to console together with the time it took to get there.
- */
- log: function(/**String*/ message, /**Boolean*/ _forceDisplay)
- {
- if (!_forceDisplay && nestingCounter <= 0)
- return;
-
- let now = Date.now();
- let diff = lastTimeStamp ? Math.round(now - lastTimeStamp) : "first event";
- lastTimeStamp = now;
-
- // Indent message depending on current nesting level
- for (let i = 0; i < nestingCounter; i++)
- message = "* " + message;
-
- // Pad message with spaces
- let padding = [];
- for (let i = message.toString().length; i < 40; i++)
- padding.push(" ");
- dump("ABP timeline: " + message + padding.join("") + "\t (" + diff + ")\n");
- },
-
- /**
- * Called to indicate that application entered a block that needs to be timed.
- */
- enter: function(/**String*/ message)
- {
- if (nestingCounter <= 0)
- firstTimeStamp = Date.now();
-
- this.log(message, true);
- nestingCounter = (nestingCounter <= 0 ? 1 : nestingCounter + 1);
- },
-
- /**
- * Called when application exited a block that TimeLine.enter() was called for.
- */
- leave: function(/**String*/ message)
- {
- nestingCounter--;
- this.log(message, true);
-
- if (nestingCounter <= 0)
- {
- if (firstTimeStamp !== null)
- dump("ABP timeline: Total time elapsed: " + Math.round(Date.now() - firstTimeStamp) + "\n");
- firstTimeStamp = null;
- lastTimeStamp = null;
- }
- }
-};
diff --git a/modules/Utils.jsm b/modules/Utils.jsm
index 8317332..a214c84 100644
--- a/modules/Utils.jsm
+++ b/modules/Utils.jsm
@@ -43,511 +43,511 @@ let sidebarParams = null;
*/
var Utils =
{
- /**
- * Returns the add-on ID used by Adblock Plus
- */
- get addonID()
- {
- return "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}";
- },
-
- /**
- * Returns the installed Adblock Plus version
- */
- get addonVersion()
- {
- let version = "{{VERSION}}";
- return (version[0] == "{" ? "99.9" : version);
- },
-
- /**
- * Returns the VCS revision used for this Adblock Plus build
- */
- get addonBuild()
- {
- let build = "{{BUILD}}";
- return (build[0] == "{" ? "" : build);
- },
-
- /**
- * Returns ID of the application
- */
- get appID()
- {
- let id = Utils.appInfo.ID;
- Utils.__defineGetter__("appID", function() id);
- return Utils.appID;
- },
-
- /**
- * Returns whether we are running in Fennec, for Fennec-specific hacks
- * @type Boolean
- */
- get isFennec()
- {
- let result = (this.appID == "{a23983c0-fd0e-11dc-95ff-0800200c9a66}");
- Utils.__defineGetter__("isFennec", function() result);
- return result;
- },
-
- /**
- * Returns the user interface locale selected for adblockplus chrome package.
- */
- get appLocale()
- {
- let locale = "en-US";
- try
- {
- locale = Utils.chromeRegistry.getSelectedLocale("adblockplus");
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- Utils.__defineGetter__("appLocale", function() locale);
- return Utils.appLocale;
- },
-
- /**
- * Returns version of the Gecko platform
- */
- get platformVersion()
- {
- let platformVersion = Utils.appInfo.platformVersion;
- Utils.__defineGetter__("platformVersion", function() platformVersion);
- return Utils.platformVersion;
- },
-
- /**
- * Retrieves a string from global.properties string bundle, will throw if string isn't found.
- *
- * @param {String} name string name
- * @return {String}
- */
- getString: function(name)
- {
- let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
- .getService(Ci.nsIStringBundleService)
- .createBundle("chrome://adblockplus/locale/global.properties");
- Utils.getString = function(name)
- {
- return stringBundle.GetStringFromName(name);
- }
- return Utils.getString(name);
- },
-
- /**
- * Shows an alert message like window.alert() but with a custom title.
- *
- * @param {Window} parentWindow parent window of the dialog (can be null)
- * @param {String} message message to be displayed
- * @param {String} [title] dialog title, default title will be used if omitted
- */
- alert: function(parentWindow, message, title)
- {
- if (!title)
- title = Utils.getString("default_dialog_title");
- Utils.promptService.alert(parentWindow, title, message);
- },
-
- /**
- * Asks the user for a confirmation like window.confirm() but with a custom title.
- *
- * @param {Window} parentWindow parent window of the dialog (can be null)
- * @param {String} message message to be displayed
- * @param {String} [title] dialog title, default title will be used if omitted
- * @return {Bool}
- */
- confirm: function(parentWindow, message, title)
- {
- if (!title)
- title = Utils.getString("default_dialog_title");
- return Utils.promptService.confirm(parentWindow, title, message);
- },
-
- /**
- * Retrieves the window for a document node.
- * @return {Window} will be null if the node isn't associated with a window
- */
- getWindow: function(/**Node*/ node)
- {
- if ("ownerDocument" in node && node.ownerDocument)
- node = node.ownerDocument;
-
- if ("defaultView" in node)
- return node.defaultView;
-
- return null;
- },
-
- /**
- * If the window doesn't have its own security context (e.g. about:blank or
- * data: URL) walks up the parent chain until a window is found that has a
- * security context.
- */
- getOriginWindow: function(/**Window*/ wnd) /**Window*/
- {
- while (wnd != wnd.parent)
- {
- let uri = Utils.makeURI(wnd.location.href);
- if (uri.spec != "about:blank" && uri.spec != "moz-safe-about:blank" &&
- !Utils.netUtils.URIChainHasFlags(uri, Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT))
- {
- break;
- }
- wnd = wnd.parent;
- }
- return wnd;
- },
-
- /**
- * If a protocol using nested URIs like jar: is used - retrieves innermost
- * nested URI.
- */
- unwrapURL: function(/**nsIURI or String*/ url) /**nsIURI*/
- {
- if (!(url instanceof Ci.nsIURI))
- url = Utils.makeURI(url);
-
- if (url instanceof Ci.nsINestedURI)
- return url.innermostURI;
- else
- return url;
- },
-
- /**
- * Translates a string URI into its nsIURI representation, will return null for
- * invalid URIs.
- */
- makeURI: function(/**String*/ url) /**nsIURI*/
- {
- try
- {
- return Utils.ioService.newURI(url, null, null);
- }
- catch (e) {
- return null;
- }
- },
-
- /**
- * Posts an action to the event queue of the current thread to run it
- * asynchronously. Any additional parameters to this function are passed
- * as parameters to the callback.
- */
- runAsync: function(/**Function*/ callback, /**Object*/ thisPtr)
- {
- let params = Array.prototype.slice.call(arguments, 2);
- let runnable = {
- run: function()
- {
- callback.apply(thisPtr, params);
- }
- };
- Utils.threadManager.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
- },
-
- /**
- * Gets the DOM window associated with a particular request (if any).
- */
- getRequestWindow: function(/**nsIChannel*/ channel) /**nsIDOMWindow*/
- {
- try
- {
- if (channel.notificationCallbacks)
- return channel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch(e) {}
-
- try
- {
- if (channel.loadGroup && channel.loadGroup.notificationCallbacks)
- return channel.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch(e) {}
-
- return null;
- },
-
- /**
- * Retrieves the platform-dependent line break string.
- */
- getLineBreak: function()
- {
- // HACKHACK: Gecko doesn't expose NS_LINEBREAK, try to determine
- // plattform's line breaks by reading prefs.js
- let lineBreak = "\n";
- try {
- let prefFile = Utils.dirService.get("PrefF", Ci.nsIFile);
- let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
- inputStream.init(prefFile, 0x01, 0444, 0);
-
- let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
- scriptableStream.init(inputStream);
- let data = scriptableStream.read(1024);
- scriptableStream.close();
-
- if (/(\r\n?|\n\r?)/.test(data))
- lineBreak = RegExp.$1;
- } catch (e) {}
-
- Utils.getLineBreak = function() lineBreak;
- return lineBreak;
- },
-
- /**
- * Generates filter subscription checksum.
- *
- * @param {Array of String} lines filter subscription lines (with checksum line removed)
- * @return {String} checksum or null
- */
- generateChecksum: function(lines)
- {
- let stream = null;
- try
- {
- // Checksum is an MD5 checksum (base64-encoded without the trailing "=") of
- // all lines in UTF-8 without the checksum line, joined with "\n".
-
- let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
- converter.charset = "UTF-8";
- stream = converter.convertToInputStream(lines.join("\n"));
-
- let hashEngine = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
- hashEngine.init(hashEngine.MD5);
- hashEngine.updateFromStream(stream, stream.available());
- return hashEngine.finish(true).replace(/=+$/, "");
- }
- catch (e)
- {
- return null;
- }
- finally
- {
- if (stream)
- stream.close();
- }
- },
-
- /**
- * Opens preferences dialog or focused already open dialog.
- * @param {String} location (optional) filter suggestion
- * @param {Filter} filter (optional) filter to be selected
- */
- openSettingsDialog: function(location, filter)
- {
- var dlg = Utils.windowMediator.getMostRecentWindow("abp:settings");
- var func = function()
- {
- if (typeof location != "undefined")
- dlg.setLocation(location);
- if (typeof filter != "undefined")
- dlg.selectFilter(filter);
- }
-
- if (dlg)
- {
- func();
-
- try
- {
- dlg.focus();
- }
- catch (e) {}
-
- if (Utils.windowMediator.getMostRecentWindow(null) != dlg)
- {
- // There must be some modal dialog open
- dlg = Utils.windowMediator.getMostRecentWindow("abp:subscriptionSelection") || Utils.windowMediator.getMostRecentWindow("abp:about");
- if (dlg)
- dlg.focus();
- }
- }
- else
- {
- dlg = Utils.windowWatcher.openWindow(null, "chrome://adblockplus/content/ui/settings.xul", "_blank", "chrome,centerscreen,resizable,dialog=no", null);
- dlg.addEventListener("post-load", func, false);
- }
- },
-
- /**
- * Opens a URL in the browser window. If browser window isn't passed as parameter,
- * this function attempts to find a browser window. If an event is passed in
- * it should be passed in to the browser if possible (will e.g. open a tab in
- * background depending on modifiers keys).
- */
- loadInBrowser: function(/**String*/ url, /**Window*/ currentWindow, /**Event*/ event)
- {
- let abpHooks = currentWindow ? currentWindow.document.getElementById("abp-hooks") : null;
- if (!abpHooks || !abpHooks.addTab)
- {
- let enumerator = Utils.windowMediator.getZOrderDOMWindowEnumerator(null, true);
- if (!enumerator.hasMoreElements())
- {
- // On Linux the list returned will be empty, see bug 156333. Fall back to random order.
- enumerator = Utils.windowMediator.getEnumerator(null);
- }
- while (enumerator.hasMoreElements())
- {
- let window = enumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
- abpHooks = window.document.getElementById("abp-hooks");
- if (abpHooks && abpHooks.addTab)
- {
- if (!currentWindow)
- window.focus();
- break;
- }
- }
- }
-
- if (abpHooks && abpHooks.addTab)
- abpHooks.addTab(url, event);
- else
- {
- let protocolService = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
- protocolService.loadURI(Utils.makeURI(url), null);
- }
- },
-
- /**
- * Opens a pre-defined documentation link in the browser window. This will
- * send the UI language to adblockplus.org so that the correct language
- * version of the page can be selected.
- */
- loadDocLink: function(/**String*/ linkID)
- {
- let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
- Cu.import(baseURL.spec + "Prefs.jsm");
-
- let link = Prefs.documentation_link.replace(/%LINK%/g, linkID).replace(/%LANG%/g, Utils.appLocale);
- Utils.loadInBrowser(link);
- },
-
- /**
- * Formats a unix time according to user's locale.
- * @param {Integer} time unix time in milliseconds
- * @return {String} formatted date and time
- */
- formatTime: function(time)
- {
- try
- {
- let date = new Date(time);
- return Utils.dateFormatter.FormatDateTime("", Ci.nsIScriptableDateFormat.dateFormatShort,
- Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
- date.getFullYear(), date.getMonth() + 1, date.getDate(),
- date.getHours(), date.getMinutes(), date.getSeconds());
- }
- catch(e)
- {
- // Make sure to return even on errors
- Cu.reportError(e);
- return "";
- }
- },
-
- /**
- * Tries to interpret a file path as an absolute path or a path relative to
- * user's profile. Returns a file or null on failure.
- */
- resolveFilePath: function(/**String*/ path) /**nsIFile*/
- {
- if (!path)
- return null;
-
- try {
- // Assume an absolute path first
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
- file.initWithPath(path);
- return file;
- } catch (e) {}
-
- try {
- // Try relative path now
- let profileDir = Utils.dirService.get("ProfD", Ci.nsIFile);
- let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
- file.setRelativeDescriptor(profileDir, path);
- return file;
- } catch (e) {}
-
- return null;
- },
-
- /**
- * Saves sidebar state before detaching/reattaching
- */
- setParams: function(params)
- {
- sidebarParams = params;
- },
-
- /**
- * Retrieves and removes sidebar state after detaching/reattaching
- */
- getParams: function()
- {
- let ret = sidebarParams;
- sidebarParams = null;
- return ret;
- },
-
- /**
- * Randomly generated class for collapsed nodes.
- * @type String
- */
- collapsedClass: null,
-
- /**
- * Nodes scheduled for post-processing (might be null).
- * @type Array of Node
- */
- scheduledNodes: null,
-
- /**
- * Schedules a node for post-processing.
- */
- schedulePostProcess: function(node)
- {
- if (Utils.scheduledNodes)
- Utils.scheduledNodes.push(node);
- else
- {
- Utils.scheduledNodes = [node];
- Utils.runAsync(Utils.postProcessNodes);
- }
- },
-
- /**
- * Processes nodes scheduled for post-processing (typically hides them).
- */
- postProcessNodes: function()
- {
- let nodes = Utils.scheduledNodes;
- Utils.scheduledNodes = null;
-
- for each (let node in nodes)
- {
- // adjust frameset's cols/rows for frames
- let parentNode = node.parentNode;
- if (parentNode && parentNode instanceof Ci.nsIDOMHTMLFrameSetElement)
- {
- let hasCols = (parentNode.cols && parentNode.cols.indexOf(",") > 0);
- let hasRows = (parentNode.rows && parentNode.rows.indexOf(",") > 0);
- if ((hasCols || hasRows) && !(hasCols && hasRows))
- {
- let index = -1;
- for (let frame = node; frame; frame = frame.previousSibling)
- if (frame instanceof Ci.nsIDOMHTMLFrameElement || frame instanceof Ci.nsIDOMHTMLFrameSetElement)
- index++;
-
- let property = (hasCols ? "cols" : "rows");
- let weights = parentNode[property].split(",");
- weights[index] = "0";
- parentNode[property] = weights.join(",");
- }
- }
- else
- node.className += " " + Utils.collapsedClass;
- }
- }
+ /**
+ * Returns the add-on ID used by Adblock Plus
+ */
+ get addonID()
+ {
+ return "{d10d0bf8-f5b5-c8b4-a8b2-2b9879e08c5d}";
+ },
+
+ /**
+ * Returns the installed Adblock Plus version
+ */
+ get addonVersion()
+ {
+ let version = "1.3.10";
+ return (version[0] == "{" ? "99.9" : version);
+ },
+
+ /**
+ * Returns the VCS revision used for this Adblock Plus build
+ */
+ get addonBuild()
+ {
+ let build = "3154";
+ return (build[0] == "{" ? "" : build);
+ },
+
+ /**
+ * Returns ID of the application
+ */
+ get appID()
+ {
+ let id = Utils.appInfo.ID;
+ Utils.__defineGetter__("appID", function() id);
+ return Utils.appID;
+ },
+
+ /**
+ * Returns whether we are running in Fennec, for Fennec-specific hacks
+ * @type Boolean
+ */
+ get isFennec()
+ {
+ let result = (this.appID == "{a23983c0-fd0e-11dc-95ff-0800200c9a66}");
+ Utils.__defineGetter__("isFennec", function() result);
+ return result;
+ },
+
+ /**
+ * Returns the user interface locale selected for adblockplus chrome package.
+ */
+ get appLocale()
+ {
+ let locale = "en-US";
+ try
+ {
+ locale = Utils.chromeRegistry.getSelectedLocale("adblockplus");
+ }
+ catch (e)
+ {
+ Cu.reportError(e);
+ }
+ Utils.__defineGetter__("appLocale", function() locale);
+ return Utils.appLocale;
+ },
+
+ /**
+ * Returns version of the Gecko platform
+ */
+ get platformVersion()
+ {
+ let platformVersion = Utils.appInfo.platformVersion;
+ Utils.__defineGetter__("platformVersion", function() platformVersion);
+ return Utils.platformVersion;
+ },
+
+ /**
+ * Retrieves a string from global.properties string bundle, will throw if string isn't found.
+ *
+ * @param {String} name string name
+ * @return {String}
+ */
+ getString: function(name)
+ {
+ let stringBundle = Cc["@mozilla.org/intl/stringbundle;1"]
+ .getService(Ci.nsIStringBundleService)
+ .createBundle("chrome://adblockplus/locale/global.properties");
+ Utils.getString = function(name)
+ {
+ return stringBundle.GetStringFromName(name);
+ }
+ return Utils.getString(name);
+ },
+
+ /**
+ * Shows an alert message like window.alert() but with a custom title.
+ *
+ * @param {Window} parentWindow parent window of the dialog (can be null)
+ * @param {String} message message to be displayed
+ * @param {String} [title] dialog title, default title will be used if omitted
+ */
+ alert: function(parentWindow, message, title)
+ {
+ if (!title)
+ title = Utils.getString("default_dialog_title");
+ Utils.promptService.alert(parentWindow, title, message);
+ },
+
+ /**
+ * Asks the user for a confirmation like window.confirm() but with a custom title.
+ *
+ * @param {Window} parentWindow parent window of the dialog (can be null)
+ * @param {String} message message to be displayed
+ * @param {String} [title] dialog title, default title will be used if omitted
+ * @return {Bool}
+ */
+ confirm: function(parentWindow, message, title)
+ {
+ if (!title)
+ title = Utils.getString("default_dialog_title");
+ return Utils.promptService.confirm(parentWindow, title, message);
+ },
+
+ /**
+ * Retrieves the window for a document node.
+ * @return {Window} will be null if the node isn't associated with a window
+ */
+ getWindow: function(/**Node*/ node)
+ {
+ if ("ownerDocument" in node && node.ownerDocument)
+ node = node.ownerDocument;
+
+ if ("defaultView" in node)
+ return node.defaultView;
+
+ return null;
+ },
+
+ /**
+ * If the window doesn't have its own security context (e.g. about:blank or
+ * data: URL) walks up the parent chain until a window is found that has a
+ * security context.
+ */
+ getOriginWindow: function(/**Window*/ wnd) /**Window*/
+ {
+ while (wnd != wnd.parent)
+ {
+ let uri = Utils.makeURI(wnd.location.href);
+ if (uri.spec != "about:blank" && uri.spec != "moz-safe-about:blank" &&
+ !Utils.netUtils.URIChainHasFlags(uri, Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT))
+ {
+ break;
+ }
+ wnd = wnd.parent;
+ }
+ return wnd;
+ },
+
+ /**
+ * If a protocol using nested URIs like jar: is used - retrieves innermost
+ * nested URI.
+ */
+ unwrapURL: function(/**nsIURI or String*/ url) /**nsIURI*/
+ {
+ if (!(url instanceof Ci.nsIURI))
+ url = Utils.makeURI(url);
+
+ if (url instanceof Ci.nsINestedURI)
+ return url.innermostURI;
+ else
+ return url;
+ },
+
+ /**
+ * Translates a string URI into its nsIURI representation, will return null for
+ * invalid URIs.
+ */
+ makeURI: function(/**String*/ url) /**nsIURI*/
+ {
+ try
+ {
+ return Utils.ioService.newURI(url, null, null);
+ }
+ catch (e) {
+ return null;
+ }
+ },
+
+ /**
+ * Posts an action to the event queue of the current thread to run it
+ * asynchronously. Any additional parameters to this function are passed
+ * as parameters to the callback.
+ */
+ runAsync: function(/**Function*/ callback, /**Object*/ thisPtr)
+ {
+ let params = Array.prototype.slice.call(arguments, 2);
+ let runnable = {
+ run: function()
+ {
+ callback.apply(thisPtr, params);
+ }
+ };
+ Utils.threadManager.currentThread.dispatch(runnable, Ci.nsIEventTarget.DISPATCH_NORMAL);
+ },
+
+ /**
+ * Gets the DOM window associated with a particular request (if any).
+ */
+ getRequestWindow: function(/**nsIChannel*/ channel) /**nsIDOMWindow*/
+ {
+ try
+ {
+ if (channel.notificationCallbacks)
+ return channel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
+ } catch(e) {}
+
+ try
+ {
+ if (channel.loadGroup && channel.loadGroup.notificationCallbacks)
+ return channel.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
+ } catch(e) {}
+
+ return null;
+ },
+
+ /**
+ * Retrieves the platform-dependent line break string.
+ */
+ getLineBreak: function()
+ {
+ // HACKHACK: Gecko doesn't expose NS_LINEBREAK, try to determine
+ // plattform's line breaks by reading prefs.js
+ let lineBreak = "\n";
+ try {
+ let prefFile = Utils.dirService.get("PrefF", Ci.nsIFile);
+ let inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
+ inputStream.init(prefFile, 0x01, 0444, 0);
+
+ let scriptableStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
+ scriptableStream.init(inputStream);
+ let data = scriptableStream.read(1024);
+ scriptableStream.close();
+
+ if (/(\r\n?|\n\r?)/.test(data))
+ lineBreak = RegExp.$1;
+ } catch (e) {}
+
+ Utils.getLineBreak = function() lineBreak;
+ return lineBreak;
+ },
+
+ /**
+ * Generates filter subscription checksum.
+ *
+ * @param {Array of String} lines filter subscription lines (with checksum line removed)
+ * @return {String} checksum or null
+ */
+ generateChecksum: function(lines)
+ {
+ let stream = null;
+ try
+ {
+ // Checksum is an MD5 checksum (base64-encoded without the trailing "=") of
+ // all lines in UTF-8 without the checksum line, joined with "\n".
+
+ let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
+ converter.charset = "UTF-8";
+ stream = converter.convertToInputStream(lines.join("\n"));
+
+ let hashEngine = Cc["@mozilla.org/security/hash;1"].createInstance(Ci.nsICryptoHash);
+ hashEngine.init(hashEngine.MD5);
+ hashEngine.updateFromStream(stream, stream.available());
+ return hashEngine.finish(true).replace(/=+$/, "");
+ }
+ catch (e)
+ {
+ return null;
+ }
+ finally
+ {
+ if (stream)
+ stream.close();
+ }
+ },
+
+ /**
+ * Opens preferences dialog or focused already open dialog.
+ * @param {String} location (optional) filter suggestion
+ * @param {Filter} filter (optional) filter to be selected
+ */
+ openSettingsDialog: function(location, filter)
+ {
+ var dlg = Utils.windowMediator.getMostRecentWindow("abp:settings");
+ var func = function()
+ {
+ if (typeof location != "undefined")
+ dlg.setLocation(location);
+ if (typeof filter != "undefined")
+ dlg.selectFilter(filter);
+ }
+
+ if (dlg)
+ {
+ func();
+
+ try
+ {
+ dlg.focus();
+ }
+ catch (e) {}
+
+ if (Utils.windowMediator.getMostRecentWindow(null) != dlg)
+ {
+ // There must be some modal dialog open
+ dlg = Utils.windowMediator.getMostRecentWindow("abp:subscriptionSelection") || Utils.windowMediator.getMostRecentWindow("abp:about");
+ if (dlg)
+ dlg.focus();
+ }
+ }
+ else
+ {
+ dlg = Utils.windowWatcher.openWindow(null, "chrome://adblockplus/content/ui/settings.xul", "_blank", "chrome,centerscreen,resizable,dialog=no", null);
+ dlg.addEventListener("post-load", func, false);
+ }
+ },
+
+ /**
+ * Opens a URL in the browser window. If browser window isn't passed as parameter,
+ * this function attempts to find a browser window. If an event is passed in
+ * it should be passed in to the browser if possible (will e.g. open a tab in
+ * background depending on modifiers keys).
+ */
+ loadInBrowser: function(/**String*/ url, /**Window*/ currentWindow, /**Event*/ event)
+ {
+ let abpHooks = currentWindow ? currentWindow.document.getElementById("abp-hooks") : null;
+ if (!abpHooks || !abpHooks.addTab)
+ {
+ let enumerator = Utils.windowMediator.getZOrderDOMWindowEnumerator(null, true);
+ if (!enumerator.hasMoreElements())
+ {
+ // On Linux the list returned will be empty, see bug 156333. Fall back to random order.
+ enumerator = Utils.windowMediator.getEnumerator(null);
+ }
+ while (enumerator.hasMoreElements())
+ {
+ let window = enumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
+ abpHooks = window.document.getElementById("abp-hooks");
+ if (abpHooks && abpHooks.addTab)
+ {
+ if (!currentWindow)
+ window.focus();
+ break;
+ }
+ }
+ }
+
+ if (abpHooks && abpHooks.addTab)
+ abpHooks.addTab(url, event);
+ else
+ {
+ let protocolService = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
+ protocolService.loadURI(Utils.makeURI(url), null);
+ }
+ },
+
+ /**
+ * Opens a pre-defined documentation link in the browser window. This will
+ * send the UI language to adblockplus.org so that the correct language
+ * version of the page can be selected.
+ */
+ loadDocLink: function(/**String*/ linkID)
+ {
+ let baseURL = Cc["@adblockplus.org/abp/private;1"].getService(Ci.nsIURI);
+ Cu.import(baseURL.spec + "Prefs.jsm");
+
+ let link = Prefs.documentation_link.replace(/%LINK%/g, linkID).replace(/%LANG%/g, Utils.appLocale);
+ Utils.loadInBrowser(link);
+ },
+
+ /**
+ * Formats a unix time according to user's locale.
+ * @param {Integer} time unix time in milliseconds
+ * @return {String} formatted date and time
+ */
+ formatTime: function(time)
+ {
+ try
+ {
+ let date = new Date(time);
+ return Utils.dateFormatter.FormatDateTime("", Ci.nsIScriptableDateFormat.dateFormatShort,
+ Ci.nsIScriptableDateFormat.timeFormatNoSeconds,
+ date.getFullYear(), date.getMonth() + 1, date.getDate(),
+ date.getHours(), date.getMinutes(), date.getSeconds());
+ }
+ catch(e)
+ {
+ // Make sure to return even on errors
+ Cu.reportError(e);
+ return "";
+ }
+ },
+
+ /**
+ * Tries to interpret a file path as an absolute path or a path relative to
+ * user's profile. Returns a file or null on failure.
+ */
+ resolveFilePath: function(/**String*/ path) /**nsIFile*/
+ {
+ if (!path)
+ return null;
+
+ try {
+ // Assume an absolute path first
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.initWithPath(path);
+ return file;
+ } catch (e) {}
+
+ try {
+ // Try relative path now
+ let profileDir = Utils.dirService.get("ProfD", Ci.nsIFile);
+ let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
+ file.setRelativeDescriptor(profileDir, path);
+ return file;
+ } catch (e) {}
+
+ return null;
+ },
+
+ /**
+ * Saves sidebar state before detaching/reattaching
+ */
+ setParams: function(params)
+ {
+ sidebarParams = params;
+ },
+
+ /**
+ * Retrieves and removes sidebar state after detaching/reattaching
+ */
+ getParams: function()
+ {
+ let ret = sidebarParams;
+ sidebarParams = null;
+ return ret;
+ },
+
+ /**
+ * Randomly generated class for collapsed nodes.
+ * @type String
+ */
+ collapsedClass: null,
+
+ /**
+ * Nodes scheduled for post-processing (might be null).
+ * @type Array of Node
+ */
+ scheduledNodes: null,
+
+ /**
+ * Schedules a node for post-processing.
+ */
+ schedulePostProcess: function(node)
+ {
+ if (Utils.scheduledNodes)
+ Utils.scheduledNodes.push(node);
+ else
+ {
+ Utils.scheduledNodes = [node];
+ Utils.runAsync(Utils.postProcessNodes);
+ }
+ },
+
+ /**
+ * Processes nodes scheduled for post-processing (typically hides them).
+ */
+ postProcessNodes: function()
+ {
+ let nodes = Utils.scheduledNodes;
+ Utils.scheduledNodes = null;
+
+ for each (let node in nodes)
+ {
+ // adjust frameset's cols/rows for frames
+ let parentNode = node.parentNode;
+ if (parentNode && parentNode instanceof Ci.nsIDOMHTMLFrameSetElement)
+ {
+ let hasCols = (parentNode.cols && parentNode.cols.indexOf(",") > 0);
+ let hasRows = (parentNode.rows && parentNode.rows.indexOf(",") > 0);
+ if ((hasCols || hasRows) && !(hasCols && hasRows))
+ {
+ let index = -1;
+ for (let frame = node; frame; frame = frame.previousSibling)
+ if (frame instanceof Ci.nsIDOMHTMLFrameElement || frame instanceof Ci.nsIDOMHTMLFrameSetElement)
+ index++;
+
+ let property = (hasCols ? "cols" : "rows");
+ let weights = parentNode[property].split(",");
+ weights[index] = "0";
+ parentNode[property] = weights.join(",");
+ }
+ }
+ else
+ node.className += " " + Utils.collapsedClass;
+ }
+ }
};
/**
@@ -557,61 +557,61 @@ var Utils =
*/
function Cache(/**Integer*/ size)
{
- this._ringBuffer = new Array(size);
- this.data = {__proto__: null};
+ this._ringBuffer = new Array(size);
+ this.data = {__proto__: null};
}
Cache.prototype =
{
- /**
- * Ring buffer storing hash keys, allows determining which keys need to be
- * evicted.
- * @type Array
- */
- _ringBuffer: null,
-
- /**
- * Index in the ring buffer to be written next.
- * @type Integer
- */
- _bufferIndex: 0,
-
- /**
- * Cache data, maps values to the keys. Read-only access, for writing use
- * add() method.
- * @type Object
- */
- data: null,
-
- /**
- * Adds a key and the corresponding value to the cache.
- */
- add: function(/**String*/ key, value)
- {
- if (!(key in this.data))
- {
- // This is a new key - we need to add it to the ring buffer and evict
- // another entry instead.
- let oldKey = this._ringBuffer[this._bufferIndex];
- if (typeof oldKey != "undefined")
- delete this.data[oldKey];
- this._ringBuffer[this._bufferIndex] = key;
-
- this._bufferIndex++;
- if (this._bufferIndex >= this._ringBuffer.length)
- this._bufferIndex = 0;
- }
-
- this.data[key] = value;
- },
-
- /**
- * Clears cache contents.
- */
- clear: function()
- {
- this._ringBuffer = new Array(this._ringBuffer.length);
- this.data = {__proto__: null};
- }
+ /**
+ * Ring buffer storing hash keys, allows determining which keys need to be
+ * evicted.
+ * @type Array
+ */
+ _ringBuffer: null,
+
+ /**
+ * Index in the ring buffer to be written next.
+ * @type Integer
+ */
+ _bufferIndex: 0,
+
+ /**
+ * Cache data, maps values to the keys. Read-only access, for writing use
+ * add() method.
+ * @type Object
+ */
+ data: null,
+
+ /**
+ * Adds a key and the corresponding value to the cache.
+ */
+ add: function(/**String*/ key, value)
+ {
+ if (!(key in this.data))
+ {
+ // This is a new key - we need to add it to the ring buffer and evict
+ // another entry instead.
+ let oldKey = this._ringBuffer[this._bufferIndex];
+ if (typeof oldKey != "undefined")
+ delete this.data[oldKey];
+ this._ringBuffer[this._bufferIndex] = key;
+
+ this._bufferIndex++;
+ if (this._bufferIndex >= this._ringBuffer.length)
+ this._bufferIndex = 0;
+ }
+
+ this.data[key] = value;
+ },
+
+ /**
+ * Clears cache contents.
+ */
+ clear: function()
+ {
+ this._ringBuffer = new Array(this._ringBuffer.length);
+ this.data = {__proto__: null};
+ }
}
/**
@@ -621,84 +621,84 @@ Cache.prototype =
*/
function TraceableChannelCleanup(request)
{
- // This has to run asynchronously due to bug 646370, nsHttpChannel triggers
- // http-on-modify-request observers before setting listener!
- Utils.runAsync(this.attach, this, request);
+ // This has to run asynchronously due to bug 646370, nsHttpChannel triggers
+ // http-on-modify-request observers before setting listener!
+ Utils.runAsync(this.attach, this, request);
}
TraceableChannelCleanup.prototype =
{
- originalListener: null,
-
- attach: function(request)
- {
- if (request.isPending())
- {
- try
- {
- this.originalListener = request.setNewListener(this);
- }
- catch (e if e.result == Cr.NS_ERROR_NOT_IMPLEMENTED)
- {
- // Bug 646373 :-( Remove data even though this means that we won't be
- // able to block redirects.
- this.cleanup(request);
- }
- }
- else
- this.cleanup(request);
- },
-
- cleanup: function(request)
- {
- try
- {
- if (request instanceof Ci.nsIWritablePropertyBag)
- request.deleteProperty("abpRequestData");
- }
- catch(e) {} // Ignore errors due to missing property
- },
-
- onStartRequest: function(request, context)
- {
- try
- {
- this.originalListener.onStartRequest(request, context);
- }
- catch (e if e instanceof Ci.nsIException)
- {
- request.cancel(e.result);
- }
- },
-
- onDataAvailable: function(request, context, inputStream, offset, count)
- {
- try
- {
- this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
- }
- catch (e if e instanceof Ci.nsIException)
- {
- request.cancel(e.result);
- }
- },
-
- onStopRequest: function(request, context, statusCode)
- {
- try
- {
- this.originalListener.onStopRequest(request, context, statusCode);
- }
- catch (e if e instanceof Ci.nsIException)
- {
- // No point cancelling the channel when it is done already
- }
- finally
- {
- this.cleanup(request);
- }
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIRequestObserver])
+ originalListener: null,
+
+ attach: function(request)
+ {
+ if (request.isPending())
+ {
+ try
+ {
+ this.originalListener = request.setNewListener(this);
+ }
+ catch (e if e.result == Cr.NS_ERROR_NOT_IMPLEMENTED)
+ {
+ // Bug 646373 :-( Remove data even though this means that we won't be
+ // able to block redirects.
+ this.cleanup(request);
+ }
+ }
+ else
+ this.cleanup(request);
+ },
+
+ cleanup: function(request)
+ {
+ try
+ {
+ if (request instanceof Ci.nsIWritablePropertyBag)
+ request.deleteProperty("abpRequestData");
+ }
+ catch(e) {} // Ignore errors due to missing property
+ },
+
+ onStartRequest: function(request, context)
+ {
+ try
+ {
+ this.originalListener.onStartRequest(request, context);
+ }
+ catch (e if e instanceof Ci.nsIException)
+ {
+ request.cancel(e.result);
+ }
+ },
+
+ onDataAvailable: function(request, context, inputStream, offset, count)
+ {
+ try
+ {
+ this.originalListener.onDataAvailable(request, context, inputStream, offset, count);
+ }
+ catch (e if e instanceof Ci.nsIException)
+ {
+ request.cancel(e.result);
+ }
+ },
+
+ onStopRequest: function(request, context, statusCode)
+ {
+ try
+ {
+ this.originalListener.onStopRequest(request, context, statusCode);
+ }
+ catch (e if e instanceof Ci.nsIException)
+ {
+ // No point cancelling the channel when it is done already
+ }
+ finally
+ {
+ this.cleanup(request);
+ }
+ },
+
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIStreamListener, Ci.nsIRequestObserver])
}
// Getters for common services, this should be replaced by Services.jsm in future
@@ -724,6 +724,6 @@ XPCOMUtils.defineLazyServiceGetter(Utils, "childMessageManager", "@mozilla.org/c
XPCOMUtils.defineLazyServiceGetter(Utils, "parentMessageManager", "@mozilla.org/parentprocessmessagemanager;1", "nsIFrameMessageManager");
if ("@mozilla.org/messenger/headerparser;1" in Cc)
- XPCOMUtils.defineLazyServiceGetter(Utils, "headerParser", "@mozilla.org/messenger/headerparser;1", "nsIMsgHeaderParser");
+ XPCOMUtils.defineLazyServiceGetter(Utils, "headerParser", "@mozilla.org/messenger/headerparser;1", "nsIMsgHeaderParser");
else
- Utils.headerParser = null;
+ Utils.headerParser = null;
diff --git a/normalizeLocales.pl b/normalizeLocales.pl
deleted file mode 100644
index 78b0f8b..0000000
--- a/normalizeLocales.pl
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/perl
-
-# This script will adjust the locales as received from Babelzilla - normalize
-# newlines and remove comments that have been pointlessly copied over from
-# en-US.
-
-use strict;
-use warnings;
-
-$0 =~ s/(.*[\\\/])//g;
-chdir($1) if $1;
-
-opendir(local* LOCALES, "chrome/locale") or die "Failed to open directory chrome/locale";
-foreach my $locale (readdir(LOCALES))
-{
- next if $locale =~ /^\./ || $locale eq "en-US" || $locale eq "de" || $locale eq "ru";
-
- foreach my $file (<chrome/locale/$locale/*.properties>)
- {
- my $data = readFile($file);
- $data =~ s/\r//g; # Normalize newlines
- $data =~ s/\n+/\n/g; # Remove empty lines
- $data =~ s/^\s*#.*\n*//gm; # Remove pointless comments
- writeFile($file, $data);
- }
-
- foreach my $file (<chrome/locale/$locale/*.dtd>)
- {
- my $data = readFile($file);
- $data =~ s/\r//g; # Normalize newlines
- $data =~ s/\n+/\n/g; # Remove empty lines
- $data =~ s/[^\S\n]*<!--.*?-->\s*?\n*//gs; # Remove pointless comments
- writeFile($file, $data);
- }
-}
-closedir(LOCALES);
-
-sub readFile
-{
- my $file = shift;
-
- open(local *FILE, "<", $file) || die "Could not read file '$file'";
- binmode(FILE);
- local $/;
- my $result = <FILE>;
- close(FILE);
-
- return $result;
-}
-
-sub writeFile
-{
- my ($file, $contents) = @_;
-
- open(local *FILE, ">", $file) || die "Could not write file '$file'";
- binmode(FILE);
- print FILE $contents;
- close(FILE);
-}
diff --git a/remove_string.pl b/remove_string.pl
deleted file mode 100755
index c0aaee2..0000000
--- a/remove_string.pl
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-
-my ($file, $string) = @ARGV;
-
-opendir(local *DIR, "chrome/locale") or die "Could not open directory chrome/locale";
-my @locales = sort {$a cmp $b} grep {!/[^\w\-]/} readdir(DIR);
-closedir(DIR);
-
-foreach my $locale (@locales) {
- open(local *FILE, "chrome/locale/$locale/$file") or ((warn "Could not open file chrome/locale/$locale/$file") && next);
- binmode(FILE);
- local $/;
- my $data = <FILE>;
- close(FILE);
-
- if ($file =~ /\.dtd$/) {
- $data =~ s/<!ENTITY\s+$string\s+"[^"]*">\s*//gs or ((warn "String $string not found in file chrome/locale/$locale/$file") && next);
- }
- else {
- $data =~ s/^$string=.*\n//gm or (warn "String $string not found in file chrome/locale/$locale/$file" && next);
- }
-
- open(FILE, ">chrome/locale/$locale/$file") or die "Could not write file chrome/locale/$locale/$file";
- binmode(FILE);
- print FILE $data;
- close(FILE);
-}
diff --git a/search_and_replace.pl b/search_and_replace.pl
deleted file mode 100755
index aad47d2..0000000
--- a/search_and_replace.pl
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-
-my $exec = 0;
-for (my $i = 0; $i < @ARGV; $i++)
-{
- if ($ARGV[$i] eq "-e")
- {
- $exec = 1;
- splice(@ARGV, $i--, 1);
- }
-}
-
-die "Usage: $^X $0 [-e] <regexp> <replaceBy>\n" unless @ARGV >= 2;
-my ($from, $to) = @ARGV;
-
-doDir('.');
-
-sub doDir
-{
- my $dir = shift;
-
- opendir(local *DIR, $dir) or die "Could not open directory $dir";
- foreach (readdir(DIR))
- {
- next if /^\./;
-
- my $path = "$dir/$_";
- if (-f $path)
- {
- doFile($path);
- }
- elsif (-d $path)
- {
- doDir($path);
- }
- }
- closedir(DIR);
-}
-
-sub doFile
-{
- my $file = shift;
-
- print "$file\n";
- open(local *FILE, $file) or die "Could not read file $file";
- binmode(FILE);
- local $/;
- my $data = <FILE>;
- my $count;
- if ($exec)
- {
- $count = ($data =~ s/$from/$to/gee);
- }
- else
- {
- $count = ($data =~ s/$from/$to/g);
- }
- close(FILE);
-
- if ($count)
- {
- open(FILE, ">$file") or die "Could not write file $file";
- binmode(FILE);
- print FILE $data;
- close(FILE);
- }
-}
diff --git a/test_locales.pl b/test_locales.pl
deleted file mode 100755
index 11f387e..0000000
--- a/test_locales.pl
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/perl
-
-use strict;
-use warnings;
-use lib qw(buildtools);
-
-$0 =~ s/(.*[\\\/])//g;
-chdir($1) if $1;
-
-system("hg", "clone", "https://hg.adblockplus.org/buildtools/") unless -e "buildtools";
-
-require LocaleTester;
-
-my %paths = (
- abp => 'chrome/locale',
- ehh => '../elemhidehelper/chrome/locale',
-);
-
-my @mustDiffer = (
- ['abp:overlay:opensidebar.accesskey', 'abp:overlay:sendReport.accesskey', 'abp:overlay:settings.accesskey', 'abp:settings:options.accesskey', 'ehh:overlay:selectelement.accesskey'],
- ['abp:settings:filters.accesskey', 'abp:settings:edit.accesskey', 'abp:settings:view.accesskey', 'abp:settings:options.accesskey', 'abp:settings:help.accesskey', 'abp:settings:add.accesskey', 'abp:settings:apply.accesskey'],
- ['abp:settings:add.accesskey', 'abp:settings:addsubscription.accesskey', 'abp:settings:synchsubscriptions.accesskey', 'abp:settings:import.accesskey', 'abp:settings:export.accesskey', 'abp:settings:clearall.accesskey', 'abp:settings:resethitcounts.accesskey'],
- ['abp:settings:cut.accesskey', 'abp:settings:copy.accesskey', 'abp:settings:paste.accesskey', 'abp:settings:remove.accesskey', 'abp:settings:menu.find.accesskey', 'abp:settings:menu.findagain.accesskey'],
- ['abp:settings:filter.accesskey', 'abp:settings:slow.accesskey', 'abp:settings:enabled.accesskey', 'abp:settings:hitcount.accesskey', 'abp:settings:lasthit.accesskey', 'abp:settings:sort.accesskey'],
- ['abp:settings:sort.none.accesskey', 'abp:settings:filter.accesskey', 'abp:settings:slow.accesskey', 'abp:settings:enabled.accesskey', 'abp:settings:hitcount.accesskey', 'abp:settings:lasthit.accesskey', 'abp:settings:sort.ascending.accesskey', 'abp:settings:sort.descending.accesskey'],
- ['abp:settings:enable.accesskey', 'abp:settings:showintoolbar.accesskey', 'abp:settings:showinstatusbar.accesskey', 'abp:settings:objecttabs.accesskey', 'abp:settings:collapse.accesskey', 'abp:settings:sync.accesskey'],
- ['abp:settings:gettingStarted.accesskey', 'abp:settings:faq.accesskey', 'abp:settings:filterdoc.accesskey', 'abp:settings:about.accesskey'],
- ['abp:subscriptionSelection:other.accesskey', 'abp:subscriptionSelection:title.accesskey', 'abp:subscriptionSelection:location.accesskey', 'abp:subscriptionSelection:autodownload.accesskey', 'abp:subscriptionSelection:addMain.accesskey'],
- ['abp:composer:filter.accesskey', 'abp:composer:preferences.accesskey', 'abp:composer:type.filter.accesskey', 'abp:composer:type.whitelist.accesskey', 'abp:composer:custom.pattern.accesskey', 'abp:composer:anchor.start.accesskey', 'abp:composer:anchor.end.accesskey', 'abp:composer:domainRestriction.accesskey', 'abp:composer:firstParty.accesskey', 'abp:composer:thirdParty.accesskey', 'abp:composer:matchCase.accesskey', 'abp:composer:collapse.accesskey'],
- ['abp:sendReport:typeSelector.falsePositive.accesskey', 'abp:sendReport:typeSelector.falseNegative.accesskey', 'abp:sendReport:typeSelector.other.accesskey', 'abp:sendReport:recentReports.clear.accesskey'],
- ['abp:sendReport:typeWarning.override.accesskey', 'abp:sendReport:reloadButton.accesskey'],
- ['abp:sendReport:screenshot.attach.accesskey', 'abp:sendReport:screenshot.mark.accesskey', 'abp:sendReport:screenshot.remove.accesskey', 'abp:sendReport:screenshot.undo.accesskey'],
- ['abp:sendReport:comment.accesskey', 'abp:sendReport:email.accesskey', 'abp:sendReport:attachExtensions.accesskey', 'abp:sendReport:sendButton.accesskey', 'abp:sendReport:data.accesskey'],
- [
- 'ehh:global:command.select.key', 'ehh:global:command.select.alternativeKey',
- 'ehh:global:command.wider.key', 'ehh:global:command.wider.alternativeKey',
- 'ehh:global:command.narrower.key', 'ehh:global:command.narrower.alternativeKey',
- 'ehh:global:command.lock.key', 'ehh:global:command.lock.alternativeKey',
- 'ehh:global:command.quit.key', 'ehh:global:command.quit.alternativeKey',
- 'ehh:global:command.blinkElement.key', 'ehh:global:command.blinkElement.alternativeKey',
- 'ehh:global:command.viewSource.key', 'ehh:global:command.viewSource.alternativeKey',
- 'ehh:global:command.viewSourceWindow.key', 'ehh:global:command.viewSourceWindow.alternativeKey',
- 'ehh:global:command.showMenu.key', 'ehh:global:command.showMenu.alternativeKey',
- ],
-);
-
-my @mustEqual = (
- ['abp:overlay:opensidebar.accesskey', 'abp:overlay:closesidebar.accesskey'],
- ['abp:composer:anchor.start.accesskey', 'abp:composer:anchor.start.flexible.accesskey'],
- ['ehh:overlay:selectelement.accesskey', 'ehh:overlay:stopselection.accesskey'],
-);
-
-my @ignoreUntranslated = (
- qr/\.url$/,
- quotemeta("abp:about:caption.title"),
- quotemeta("abp:about:version.title"),
- quotemeta("abp:global:default_dialog_title"),
- quotemeta("abp:global:status_active_label"),
- quotemeta("abp:global:type_label_document"),
- quotemeta("abp:global:type_label_dtd"),
- quotemeta("abp:global:type_label_ping"),
- quotemeta("abp:global:type_label_script"),
- quotemeta("abp:global:type_label_stylesheet"),
- quotemeta("abp:global:type_label_xbl"),
- quotemeta("abp:global:subscription_status"),
- quotemeta("abp:global:subscription_status_lastdownload_unknown"),
- quotemeta("abp:overlay:status.tooltip"),
- quotemeta("abp:overlay:toolbarbutton.label"),
- quotemeta("abp:settings:filters.label"),
- quotemeta("abp:sidebar:filter.label"),
- quotemeta("abp:meta:name"),
- quotemeta("abp:meta:homepage"),
- quotemeta("ehh:composer:nodes-tree.class.label"),
- quotemeta("ehh:composer:nodes-tree.id.label"),
- quotemeta("ehh:global:noabp_warning_title"),
- quotemeta("ehh:meta:name"),
-);
-
-my %lengthRestrictions = (
- 'abp:meta:description.short' => 250,
- 'ehh:meta:description.short' => 250,
-);
-
-LocaleTester::testLocales(
- paths => \%paths,
- locales => \@ARGV,
- mustDiffer => \@mustDiffer,
- mustEqual => \@mustEqual,
- ignoreUntranslated => \@ignoreUntranslated,
- lengthRestrictions => \%lengthRestrictions,
-);
diff --git a/validateChecksum.pl b/validateChecksum.pl
deleted file mode 100755
index a0b2d81..0000000
--- a/validateChecksum.pl
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/perl
-
-# Copyright 2011 Wladimir Palant
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-#############################################################################
-# This is a reference script to validate the checksum in downloadable #
-# subscription. This performs the same validation as Adblock Plus when it #
-# downloads the subscription. #
-# #
-# To validate a subscription file, run the script like this: #
-# #
-# perl validateChecksum.pl subscription.txt #
-# #
-# Note: your subscription file should be saved in UTF-8 encoding, otherwise #
-# the validation result might be incorrect. #
-# #
-#############################################################################
-
-use strict;
-use warnings;
-use Digest::MD5 qw(md5_base64);
-
-die "Usage: $^X $0 subscription.txt\n" unless @ARGV;
-
-my $file = $ARGV[0];
-my $data = readFile($file);
-
-# Normalize data
-$data =~ s/\r//g;
-$data =~ s/\n+/\n/g;
-
-# Extract checksum
-
-# Remove checksum
-$data =~ s/^\s*!\s*checksum[\s\-:]+([\w\+\/=]+).*\n//mi;
-my $checksum = $1;
-die "Couldn't find a checksum in the file\n" unless $checksum;
-
-# Calculate new checksum
-my $checksumExpected = md5_base64($data);
-
-# Compare checksums
-if ($checksum eq $checksumExpected)
-{
- print "Checksum is valid\n";
- exit(0);
-}
-else
-{
- print "Wrong checksum: found $checksum, expected $checksumExpected\n";
- exit(1);
-}
-
-sub readFile
-{
- my $file = shift;
-
- open(local *FILE, "<", $file) || die "Could not read file '$file'";
- binmode(FILE);
- local $/;
- my $result = <FILE>;
- close(FILE);
-
- return $result;
-}
--
Advertisement filter extension for the Iceweasel/Iceape
More information about the Pkg-mozext-commits
mailing list