diff -Nru adblock-plus-1.3.9/addChecksum.pl adblock-plus-1.3.10/addChecksum.pl --- adblock-plus-1.3.9/addChecksum.pl 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/addChecksum.pl 1970-01-01 00:00:00.000000000 +0000 @@ -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 = ; - 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 -Nru adblock-plus-1.3.9/build.py adblock-plus-1.3.10/build.py --- adblock-plus-1.3.9/build.py 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/build.py 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/buildtools/build.py adblock-plus-1.3.10/buildtools/build.py --- adblock-plus-1.3.9/buildtools/build.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/build.py 1970-01-01 00:00:00.000000000 +0000 @@ -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 --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] ' - 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 -Nru adblock-plus-1.3.9/buildtools/.hg_archival.txt adblock-plus-1.3.10/buildtools/.hg_archival.txt --- adblock-plus-1.3.9/buildtools/.hg_archival.txt 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/.hg_archival.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -repo: 3926c055e81d4c11d3249479e18a92ce1bebb5cc -node: a0ba2a9a53af62f151e0cbafa9126e02bb94c7cf -branch: default -latesttag: ABP_WATCHER_1_1_5_RELEASE -latesttagdistance: 1 diff -Nru adblock-plus-1.3.9/buildtools/install.rdf.tmpl adblock-plus-1.3.10/buildtools/install.rdf.tmpl --- adblock-plus-1.3.9/buildtools/install.rdf.tmpl 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/install.rdf.tmpl 1970-01-01 00:00:00.000000000 +0000 @@ -1,92 +0,0 @@ - - - - - - {{metadata.get('general', 'id')}} - {{version}} - {{localeMetadata[defaultLocale].name}} - {{localeMetadata[defaultLocale].description}} - {{metadata.get('general', 'author')}} - {{metadata.get('homepage', 'default')}} - 2 - - {%- if not releaseBuild or metadata.has_option('general', '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%' -}} - - {%- endif %} - - {%- if metadata.has_option('general', 'icon') %} - {{metadata.get('general', 'icon')}} - {%- endif %} - - {%- if metadata.has_option('general', 'about') %} - {{metadata.get('general', 'about')}} - {%- endif %} - - {%- if metadata.has_option('general', 'options') %} - {{metadata.get('general', 'options')}} - {%- endif %} - - {%- if metadata.has_section('contributors') %} - {%- for option in metadata.options('contributors')|sort %} - {{metadata.get('contributors', option)}} - {%- endfor %} - {%- endif %} - - {%- for translator in localeMetadata|translators %} - {{translator}} - {%- endfor %} - - {%- if not limitMetadata %} - {%- for localeCode in localeMetadata.keys()|sort %} - {%- set locale = localeMetadata[localeCode] %} - - - {{localeCode}} - - {%- if 'name' in locale -%} - {{locale.name}} - {%- else -%} - {{localeMetadata[defaultLocale].name}} - {%- endif -%} - - - {%- if 'description' in locale -%} - {{locale.description}} - {%- else -%} - {{localeMetadata[defaultLocale].description}} - {%- endif -%} - - {{metadata.get('general', 'author')}} - - {%- 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 -%} - - - - {%- endfor %} - {%- endif %} - - {%- for appName in metadata.options('compat')|sort %} - {%- if appName in KNOWN_APPS %} - - - - {{KNOWN_APPS[appName]}} - {{metadata.get('compat', appName).split('/')[0]}} - {{metadata.get('compat', appName).split('/')[1]}} - - - {%- endif %} - {%- endfor %} - - diff -Nru adblock-plus-1.3.9/buildtools/LocaleTester.pm adblock-plus-1.3.10/buildtools/LocaleTester.pm --- adblock-plus-1.3.9/buildtools/LocaleTester.pm 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/LocaleTester.pm 1970-01-01 00:00:00.000000000 +0000 @@ -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 = ; - 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 =~ //gs) - { - my ($name, $value) = ($1, $2 || $3); - $result{$name} = processEntityValue($value); - } - - # Remove entities - $data =~ 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 -Nru adblock-plus-1.3.9/buildtools/localeTools.py adblock-plus-1.3.10/buildtools/localeTools.py --- adblock-plus-1.3.9/buildtools/localeTools.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/localeTools.py 1970-01-01 00:00:00.000000000 +0000 @@ -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('', 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 '\n' % (cgi.escape(key, True), cgi.escape(value, True)) - else: - return '%s=%s\n' % (key, value) diff -Nru adblock-plus-1.3.9/buildtools/packagerKMeleon.py adblock-plus-1.3.10/buildtools/packagerKMeleon.py --- adblock-plus-1.3.9/buildtools/packagerKMeleon.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/packagerKMeleon.py 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/buildtools/packager.py adblock-plus-1.3.10/buildtools/packager.py --- adblock-plus-1.3.9/buildtools/packager.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/packager.py 1970-01-01 00:00:00.000000000 +0000 @@ -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@emusic.com', - 'fennec': '{a23983c0-fd0e-11dc-95ff-0800200c9a66}', - 'firefox': '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}', - 'midbrowser': '{aa5ca914-c309-495d-91cf-3141bbb04115}', - 'prism': 'prism@developer.mozilla.org', - 'seamonkey': '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}', - 'songbird': 'songbird@songbirdnest.com', - 'thunderbird': '{3550f703-e582-4d05-9a08-453d09bdfdc6}', - 'toolkit': 'toolkit@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 -Nru adblock-plus-1.3.9/buildtools/releaseAutomationKMeleon.py adblock-plus-1.3.10/buildtools/releaseAutomationKMeleon.py --- adblock-plus-1.3.9/buildtools/releaseAutomationKMeleon.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/releaseAutomationKMeleon.py 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/buildtools/releaseAutomation.py adblock-plus-1.3.10/buildtools/releaseAutomation.py --- adblock-plus-1.3.9/buildtools/releaseAutomation.py 2011-06-27 11:06:15.000000000 +0000 +++ adblock-plus-1.3.10/buildtools/releaseAutomation.py 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/chrome/adblockplus.jar!/content/errors.html adblock-plus-1.3.10/chrome/adblockplus.jar!/content/errors.html --- adblock-plus-1.3.9/chrome/adblockplus.jar!/content/errors.html 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/chrome/adblockplus.jar!/content/errors.html 2011-09-27 18:43:34.000000000 +0000 @@ -0,0 +1,97 @@ + + + Adblock Plus Errors + + + + + + + + + diff -Nru adblock-plus-1.3.9/chrome/adblockplus.jar!/content/fennecContent.js adblock-plus-1.3.10/chrome/adblockplus.jar!/content/fennecContent.js --- adblock-plus-1.3.9/chrome/adblockplus.jar!/content/fennecContent.js 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/chrome/adblockplus.jar!/content/fennecContent.js 2011-09-27 18:43:34.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/chrome/adblockplus.jar!/content/objtabs.css adblock-plus-1.3.10/chrome/adblockplus.jar!/content/objtabs.css --- adblock-plus-1.3.9/chrome/adblockplus.jar!/content/objtabs.css 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/chrome/adblockplus.jar!/content/objtabs.css 2011-09-27 18:43:34.000000000 +0000 @@ -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 ***** */ + +@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 -Nru adblock-plus-1.3.9/chrome/adblockplus.jar!/content/ui/about.js adblock-plus-1.3.10/chrome/adblockplus.jar!/content/ui/about.js --- adblock-plus-1.3.9/chrome/adblockplus.jar!/content/ui/about.js 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/chrome/adblockplus.jar!/content/ui/about.js 2011-09-27 18:43:34.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/chrome/adblockplus.jar!/content/ui/about.xul adblock-plus-1.3.10/chrome/adblockplus.jar!/content/ui/about.xul --- adblock-plus-1.3.9/chrome/adblockplus.jar!/content/ui/about.xul 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/chrome/adblockplus.jar!/content/ui/about.xul 2011-09-27 18:43:34.000000000 +0000 @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + - -
- -
- - - - - - - -
PassedFailedTodo -
  • Test Files
-
-
- - - - - - diff -Nru adblock-plus-1.3.9/mochitest/httpd.js adblock-plus-1.3.10/mochitest/httpd.js --- adblock-plus-1.3.9/mochitest/httpd.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/httpd.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 (v3, netwerk/test/httpserver/httpd.js) - * Robert Sayre - * - * 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 = '\ - \ - ' + path + '\ - \ - \ -

' + path + '

\ -
    '; - - 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 = '
  1. ' + - htmlEscape(name) + sep + - '
  2. '; - - body += item; - } - catch (e) { /* some file system error, ignore the file */ } - } - - body += '
\ - \ - '; - - 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 - // "/foo/../bar" but prevents paths such as "/../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 = "\ - 403 Forbidden\ - \ -

403 Forbidden

\ - \ - "; - 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 = "\ - 404 Not Found\ - \ -

404 Not Found

\ -

\ - " + - htmlEscape(metadata.path) + - " was not found.\ -

\ - \ - "; - 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 = "\ - \ - 416 Requested Range Not Satisfiable\ - \ -

416 Requested Range Not Satisfiable

\ -

The byte range was not valid for the\ - requested resource.\ -

\ - \ - "; - 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 = "\ - 500 Internal Server Error\ - \ -

500 Internal Server Error

\ -

Something's broken in this server and\ - needs to be fixed.

\ - \ - "; - 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 = "\ - 501 Not Implemented\ - \ -

501 Not Implemented

\ -

This server is not (yet) Apache.

\ - \ - "; - 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 = "\ - 505 HTTP Version Not Supported\ - \ -

505 HTTP Version Not Supported

\ -

This server only supports HTTP/1.0 and HTTP/1.1\ - connections.

\ - \ - "; - 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 = "\ - httpd.js\ - \ -

httpd.js

\ -

If you're seeing this page, httpd.js is up and\ - serving requests! Now set a base path and serve some\ - files!

\ - \ - "; - - 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 = * -// CHAR = -// CTL = -// 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 = - // - // 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 = - // TEXT = - // LWS = [CRLF] 1*( SP | HT ) - // - // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> ) - // qdtext = > - // quoted-pair = "\" CHAR - // CHAR = - - // 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 - 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Async.js adblock-plus-1.3.10/mochitest/MochiKit/Async.js --- adblock-plus-1.3.9/mochitest/MochiKit/Async.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Async.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,681 +0,0 @@ -/*** - -MochiKit.Async 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Base.js adblock-plus-1.3.10/mochitest/MochiKit/Base.js --- adblock-plus-1.3.9/mochitest/MochiKit/Base.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Base.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,1398 +0,0 @@ -/*** - -MochiKit.Base 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Color.js adblock-plus-1.3.10/mochitest/MochiKit/Color.js --- adblock-plus-1.3.9/mochitest/MochiKit/Color.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Color.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,902 +0,0 @@ -/*** - -MochiKit.Color 1.4 - -See 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 - -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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Controls.js adblock-plus-1.3.10/mochitest/MochiKit/Controls.js --- adblock-plus-1.3.9/mochitest/MochiKit/Controls.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Controls.js 1970-01-01 00:00:00.000000000 +0000 @@ -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_@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: '(?:)((\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, - ''); - 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('
  • ' + elem.substr(0, entry.length) + '' + - elem.substr(entry.length) + '
  • '); - 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('
  • ' + elem.substr(0, foundPos) + '' + - elem.substr(foundPos, entry.length) + '' + elem.substr( - foundPos + entry.length) + '
  • '); - 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 '
      ' + ret.join('') + '
    '; - } - }, 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(/
    /i); - }, - -/** @id Ajax.InPlaceEditor.prototype.convertHTMLLineBreaks */ - convertHTMLLineBreaks: function (string) { - return string.replace(/
    /gi, '\n').replace(//gi, '\n').replace(/<\/p>/gi, '\n').replace(/

    /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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/DateTime.js adblock-plus-1.3.10/mochitest/MochiKit/DateTime.js --- adblock-plus-1.3.9/mochitest/MochiKit/DateTime.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/DateTime.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,216 +0,0 @@ -/*** - -MochiKit.DateTime 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/DOM.js adblock-plus-1.3.10/mochitest/MochiKit/DOM.js --- adblock-plus-1.3.9/mochitest/MochiKit/DOM.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/DOM.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,1043 +0,0 @@ -/*** - -MochiKit.DOM 1.4 - -See 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, ">"); - }, - - /** @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(""); - 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/DragAndDrop.js adblock-plus-1.3.10/mochitest/MochiKit/DragAndDrop.js --- adblock-plus-1.3.9/mochitest/MochiKit/DragAndDrop.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/DragAndDrop.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,821 +0,0 @@ -/*** -MochiKit.DragAndDrop 1.4 - -See for documentation, downloads, license, etc. - -Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) - Mochi-ized By Thomas Herve (_firstname_@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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Format.js adblock-plus-1.3.10/mochitest/MochiKit/Format.js --- adblock-plus-1.3.9/mochitest/MochiKit/Format.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Format.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,304 +0,0 @@ -/*** - -MochiKit.Format 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Iter.js adblock-plus-1.3.10/mochitest/MochiKit/Iter.js --- adblock-plus-1.3.9/mochitest/MochiKit/Iter.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Iter.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,843 +0,0 @@ -/*** - -MochiKit.Iter 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/LICENSE.txt adblock-plus-1.3.10/mochitest/MochiKit/LICENSE.txt --- adblock-plus-1.3.9/mochitest/MochiKit/LICENSE.txt 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/LICENSE.txt 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Logging.js adblock-plus-1.3.10/mochitest/MochiKit/Logging.js --- adblock-plus-1.3.9/mochitest/MochiKit/Logging.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Logging.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,321 +0,0 @@ -/*** - -MochiKit.Logging 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/LoggingPane.js adblock-plus-1.3.10/mochitest/MochiKit/LoggingPane.js --- adblock-plus-1.3.9/mochitest/MochiKit/LoggingPane.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/LoggingPane.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,371 +0,0 @@ -/*** - -MochiKit.LoggingPane 1.4 - -See 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( - '' - + '[MochiKit.LoggingPane]' - + '' - ); - 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/MochiKit.js adblock-plus-1.3.10/mochitest/MochiKit/MochiKit.js --- adblock-plus-1.3.9/mochitest/MochiKit/MochiKit.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/MochiKit.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ -/*** - -MochiKit.MochiKit 1.4 - -See 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(''); - } - }; - })(); -} diff -Nru adblock-plus-1.3.9/mochitest/MochiKit/MockDOM.js adblock-plus-1.3.10/mochitest/MochiKit/MockDOM.js --- adblock-plus-1.3.9/mochitest/MochiKit/MockDOM.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/MockDOM.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,100 +0,0 @@ -/*** - -MochiKit.MockDOM 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/New.js adblock-plus-1.3.10/mochitest/MochiKit/New.js --- adblock-plus-1.3.9/mochitest/MochiKit/New.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/New.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/__package__.js adblock-plus-1.3.10/mochitest/MochiKit/__package__.js --- adblock-plus-1.3.9/mochitest/MochiKit/__package__.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/__package__.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/packed.js adblock-plus-1.3.10/mochitest/MochiKit/packed.js --- adblock-plus-1.3.9/mochitest/MochiKit/packed.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/packed.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 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=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>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 al){ -_90=l; -} -} -_8e=[]; -for(i=0;i<_90;i++){ -var _92=[]; -for(var j=1;j=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(ab){ -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=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;i0))){ -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=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;i0&&_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=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_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;i1){ -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=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;i0){ -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/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(""); -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;i0){ -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<&-]/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(""+"[MochiKit.LoggingPane]"+""); -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;i1){ -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="

    "+el.innerHTML+"
    "; -},_roundTopCorners:function(el,_532,_533){ -var _534=this._createCorner(_533); -for(var i=0;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=(_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"); -} -} -})(); -} - - diff -Nru adblock-plus-1.3.9/mochitest/MochiKit/Signal.js adblock-plus-1.3.10/mochitest/MochiKit/Signal.js --- adblock-plus-1.3.9/mochitest/MochiKit/Signal.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Signal.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,857 +0,0 @@ -/*** - -MochiKit.Signal 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Sortable.js adblock-plus-1.3.10/mochitest/MochiKit/Sortable.js --- adblock-plus-1.3.9/mochitest/MochiKit/Sortable.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Sortable.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,588 +0,0 @@ -/*** -Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) - Mochi-ized By Thomas Herve (_firstname_@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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Style.js adblock-plus-1.3.10/mochitest/MochiKit/Style.js --- adblock-plus-1.3.9/mochitest/MochiKit/Style.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Style.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,475 +0,0 @@ -/*** - -MochiKit.Style 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Test.js adblock-plus-1.3.10/mochitest/MochiKit/Test.js --- adblock-plus-1.3.9/mochitest/MochiKit/Test.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Test.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ -/*** - -MochiKit.Test 1.4 - -See 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 -Nru adblock-plus-1.3.9/mochitest/MochiKit/Visual.js adblock-plus-1.3.10/mochitest/MochiKit/Visual.js --- adblock-plus-1.3.9/mochitest/MochiKit/Visual.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/MochiKit/Visual.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,1823 +0,0 @@ -/*** - -MochiKit.Visual 1.4 - -See 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 = "
    " + el.innerHTML + "
    "; - }, - - _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 -Nru adblock-plus-1.3.9/mochitest/server.js adblock-plus-1.3.10/mochitest/server.js --- adblock-plus-1.3.9/mochitest/server.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/server.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 . - * Portions created by the Initial Developer are Copyright (C) 2006 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Robert Sayre - * - * 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 += "\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 -Nru adblock-plus-1.3.9/mochitest/static/harness.css adblock-plus-1.3.10/mochitest/static/harness.css --- adblock-plus-1.3.9/mochitest/static/harness.css 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/static/harness.css 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/common.js adblock-plus-1.3.10/mochitest/tests/common.js --- adblock-plus-1.3.9/mochitest/tests/common.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/common.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 + "
    \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 -Nru adblock-plus-1.3.9/mochitest/tests/performance/common.js adblock-plus-1.3.10/mochitest/tests/performance/common.js --- adblock-plus-1.3.9/mochitest/tests/performance/common.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/common.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/performance/data/addresses.txt adblock-plus-1.3.10/mochitest/tests/performance/data/addresses.txt --- adblock-plus-1.3.9/mochitest/tests/performance/data/addresses.txt 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/data/addresses.txt 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/performance/data/elemhide_selectors_testdata.html adblock-plus-1.3.10/mochitest/tests/performance/data/elemhide_selectors_testdata.html --- adblock-plus-1.3.9/mochitest/tests/performance/data/elemhide_selectors_testdata.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/data/elemhide_selectors_testdata.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ - - - - - - \ No newline at end of file diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/data/filters.txt adblock-plus-1.3.10/mochitest/tests/performance/data/filters.txt --- adblock-plus-1.3.9/mochitest/tests/performance/data/filters.txt 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/data/filters.txt 1970-01-01 00:00:00.000000000 +0000 @@ -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@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 Binary files /tmp/IxaUYK3tvl/adblock-plus-1.3.9/mochitest/tests/performance/data/testpages.jar and /tmp/5zyxSOC5kg/adblock-plus-1.3.10/mochitest/tests/performance/data/testpages.jar differ diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/elemhide_selectors.html adblock-plus-1.3.10/mochitest/tests/performance/elemhide_selectors.html --- adblock-plus-1.3.9/mochitest/tests/performance/elemhide_selectors.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/elemhide_selectors.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ - - - - Element hiding performance measurements - - - - -

    Please wait while performance measurement is in progress...

    - - - -
    
    -
    -  
    -
    -
    diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/filter_fromText.html adblock-plus-1.3.10/mochitest/tests/performance/filter_fromText.html
    --- adblock-plus-1.3.9/mochitest/tests/performance/filter_fromText.html	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/performance/filter_fromText.html	1970-01-01 00:00:00.000000000 +0000
    @@ -1,67 +0,0 @@
    -
    -
    -
    -  Filter initialization performance measurements
    -  
    -  
    -
    -
    -  

    - Filters to be used:
    -
    - -

    - - - -
    
    -
    -  
    -
    -
    diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/matcher_init.html adblock-plus-1.3.10/mochitest/tests/performance/matcher_init.html
    --- adblock-plus-1.3.9/mochitest/tests/performance/matcher_init.html	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/performance/matcher_init.html	1970-01-01 00:00:00.000000000 +0000
    @@ -1,71 +0,0 @@
    -
    -
    -
    -  Matcher initialization performance measurements
    -  
    -  
    -
    -
    -  

    - Filters to be used:
    -
    - -

    - - - -
    
    -
    -  
    -
    -
    diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/matching.html adblock-plus-1.3.10/mochitest/tests/performance/matching.html
    --- adblock-plus-1.3.9/mochitest/tests/performance/matching.html	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/performance/matching.html	1970-01-01 00:00:00.000000000 +0000
    @@ -1,93 +0,0 @@
    -
    -
    -
    -  Filter matching performance measurements
    -  
    -  
    -
    -
    -  

    - Filters to be used:
    -
    - - Addresses to check:
    -
    - -

    - - - -
    
    -
    -  
    -
    -
    diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/memory_use1.html adblock-plus-1.3.10/mochitest/tests/performance/memory_use1.html
    --- adblock-plus-1.3.9/mochitest/tests/performance/memory_use1.html	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/performance/memory_use1.html	1970-01-01 00:00:00.000000000 +0000
    @@ -1,46 +0,0 @@
    -
    -
    -
    -  Memory use while an image with the same address is being created continuously
    -  
    -
    -
    -  

    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.

    - - - - - - diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/memory_use2.html adblock-plus-1.3.10/mochitest/tests/performance/memory_use2.html --- adblock-plus-1.3.9/mochitest/tests/performance/memory_use2.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/memory_use2.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,46 +0,0 @@ - - - - Memory use while images with different addresses are being created continuously - - - -

    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.

    - - - - - - diff -Nru adblock-plus-1.3.9/mochitest/tests/performance/page_load_overhead.html adblock-plus-1.3.10/mochitest/tests/performance/page_load_overhead.html --- adblock-plus-1.3.9/mochitest/tests/performance/page_load_overhead.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/performance/page_load_overhead.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,133 +0,0 @@ - - - - Page load overhead measurement (no filters) - - - - - -

    - -
    - Filters to be used:
    -
    - -

    - - - -
    
    -
    -  
    -
    -  
    -
    -
    -
    diff -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/EventUtils.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/EventUtils.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/EventUtils.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/EventUtils.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/MozillaFileLogger.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/MozillaFileLogger.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/MozillaFileLogger.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/MozillaFileLogger.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/quit.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/quit.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/quit.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/quit.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 
    - *   Jeff Walden 
    - *
    - * 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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/setup.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/setup.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/setup.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/setup.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 
    - *
    - * 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 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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/test.css adblock-plus-1.3.10/mochitest/tests/SimpleTest/test.css
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/test.css	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/test.css	1970-01-01 00:00:00.000000000 +0000
    @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/TestRunner.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/TestRunner.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/TestRunner.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/TestRunner.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 = "Finished";
    -        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 -Nru adblock-plus-1.3.9/mochitest/tests/SimpleTest/WindowSnapshot.js adblock-plus-1.3.10/mochitest/tests/SimpleTest/WindowSnapshot.js
    --- adblock-plus-1.3.9/mochitest/tests/SimpleTest/WindowSnapshot.js	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/SimpleTest/WindowSnapshot.js	1970-01-01 00:00:00.000000000 +0000
    @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/test_domainRestrictions.html adblock-plus-1.3.10/mochitest/tests/test_domainRestrictions.html
    --- adblock-plus-1.3.9/mochitest/tests/test_domainRestrictions.html	2011-06-28 14:52:21.000000000 +0000
    +++ adblock-plus-1.3.10/mochitest/tests/test_domainRestrictions.html	1970-01-01 00:00:00.000000000 +0000
    @@ -1,116 +0,0 @@
    -
    -
    -
    -  Tests for domain-restricted filters
    -
    -  
    -
    -  
    -  
    -
    -  
    -  
    -
    -
    -  

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_elemhide.html adblock-plus-1.3.10/mochitest/tests/test_elemhide.html --- adblock-plus-1.3.9/mochitest/tests/test_elemhide.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_elemhide.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ - - - - Element hiding tests - - - - - - - - - - -

    - - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_filterClasses.html adblock-plus-1.3.10/mochitest/tests/test_filterClasses.html --- adblock-plus-1.3.9/mochitest/tests/test_filterClasses.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_filterClasses.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,248 +0,0 @@ - - - - Filter classes tests - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_filterListener.html adblock-plus-1.3.10/mochitest/tests/test_filterListener.html --- adblock-plus-1.3.9/mochitest/tests/test_filterListener.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_filterListener.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ - - - - Filter listeners tests - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_filterStorage.html adblock-plus-1.3.10/mochitest/tests/test_filterStorage.html --- adblock-plus-1.3.9/mochitest/tests/test_filterStorage.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_filterStorage.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,324 +0,0 @@ - - - - Filter storage tests - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_filterStorage_readwrite.html adblock-plus-1.3.10/mochitest/tests/test_filterStorage_readwrite.html --- adblock-plus-1.3.9/mochitest/tests/test_filterStorage_readwrite.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_filterStorage_readwrite.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,4783 +0,0 @@ - - - - Filter storage read/write tests - - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_matcher.html adblock-plus-1.3.10/mochitest/tests/test_matcher.html --- adblock-plus-1.3.9/mochitest/tests/test_matcher.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_matcher.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,205 +0,0 @@ - - - - Filter matcher tests - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_policy.html adblock-plus-1.3.10/mochitest/tests/test_policy.html --- adblock-plus-1.3.9/mochitest/tests/test_policy.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_policy.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,355 +0,0 @@ - - - - Content policy tests - - - - - - - - - - -

    - - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_regexpFilters_matching.html adblock-plus-1.3.10/mochitest/tests/test_regexpFilters_matching.html --- adblock-plus-1.3.9/mochitest/tests/test_regexpFilters_matching.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_regexpFilters_matching.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,288 +0,0 @@ - - - - Regexp filter matching tests - - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_requestList.html adblock-plus-1.3.10/mochitest/tests/test_requestList.html --- adblock-plus-1.3.9/mochitest/tests/test_requestList.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_requestList.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,251 +0,0 @@ - - - - Tests for request data - - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_subscriptionClasses.html adblock-plus-1.3.10/mochitest/tests/test_subscriptionClasses.html --- adblock-plus-1.3.9/mochitest/tests/test_subscriptionClasses.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_subscriptionClasses.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,91 +0,0 @@ - - - - Subscription classes tests - - - - - - - - - -

    - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/test_synchronizer.html adblock-plus-1.3.10/mochitest/tests/test_synchronizer.html --- adblock-plus-1.3.9/mochitest/tests/test_synchronizer.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/test_synchronizer.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,855 +0,0 @@ - - - - Subscription synchronizer tests - - - - - - - - - - - -

    - - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/mochitest/tests/ui/common.js adblock-plus-1.3.10/mochitest/tests/ui/common.js --- adblock-plus-1.3.9/mochitest/tests/ui/common.js 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/ui/common.js 1970-01-01 00:00:00.000000000 +0000 @@ -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 -Nru adblock-plus-1.3.9/mochitest/tests/ui/test_icon_status.html adblock-plus-1.3.10/mochitest/tests/ui/test_icon_status.html --- adblock-plus-1.3.9/mochitest/tests/ui/test_icon_status.html 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/mochitest/tests/ui/test_icon_status.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,127 +0,0 @@ - - - - ABP icon status tests - - - - - - - - - - -

    - - -
    -  
    -  
    - - diff -Nru adblock-plus-1.3.9/modules/AppIntegrationFennec.jsm adblock-plus-1.3.10/modules/AppIntegrationFennec.jsm --- adblock-plus-1.3.9/modules/AppIntegrationFennec.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/AppIntegrationFennec.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -56,15 +56,15 @@ */ 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 @@ */ 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 @@ */ 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 @@ */ 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; + 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); + 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; - - // We only allow one subscription, remove existing one before adding - if (currentSubscription) - FilterStorage.removeSubscription(currentSubscription); - - currentSubscription = Subscription.fromURL(url); - currentSubscription.title = title; - - FilterStorage.addSubscription(currentSubscription); - Synchronizer.execute(currentSubscription, false); - FilterStorage.saveToDisk(); + 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); + + currentSubscription = Subscription.fromURL(url); + currentSubscription.title = title; + + 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 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); + 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); + siteInfo.setAttribute("title", statusText); + siteInfo.setAttribute("abpstate", status); } function toggleFennecWhitelist(event) { - if (!Prefs.enabled) - return; + 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")); + 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); + updateFennecStatusUI(wrapper); } diff -Nru adblock-plus-1.3.9/modules/AppIntegration.jsm adblock-plus-1.3.10/modules/AppIntegration.jsm --- adblock-plus-1.3.9/modules/AppIntegration.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/AppIntegration.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -37,7 +37,7 @@ 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 + "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 @@ */ function init() { - // Process preferences - 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); + // 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 @@ */ 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 @@ */ 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 WindowWrapper(window, hooks) { - TimeLine.enter("Entered WindowWrapper constructor") - this.window = window; - this.initializeHooks(hooks); - TimeLine.log("Hooks element initialized") + 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); - 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") } 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; + /** + * 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); - } + this.window.openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", [node], item); + } }; /** @@ -1322,30 +1322,30 @@ * @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 @@ */ function reloadPrefs() { - if (currentlyShowingInToolbar != Prefs.showintoolbar) - { - currentlyShowingInToolbar = Prefs.showintoolbar; - if (Prefs.showintoolbar) - for each (let wrapper in wrappers) - wrapper.installToolbarIcon(); - } + 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(); + for each (let wrapper in wrappers) + wrapper.updateState(); } /** @@ -1372,31 +1372,31 @@ */ 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; - } - } + 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; + shouldHideImageManager = function() result; + return result; } /** @@ -1405,28 +1405,28 @@ */ function showSubscriptions() { - let wrapper = (wrappers.length ? wrappers[0] : 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); - } + // 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 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 -Nru adblock-plus-1.3.9/modules/Bootstrap.jsm adblock-plus-1.3.10/modules/Bootstrap.jsm --- adblock-plus-1.3.9/modules/Bootstrap.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/Bootstrap.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -43,26 +43,26 @@ 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 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 @@ */ 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 BootstrapPrivate = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), + 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; - } - } + 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 -Nru adblock-plus-1.3.9/modules/ContentPolicy.jsm adblock-plus-1.3.10/modules/ContentPolicy.jsm --- adblock-plus-1.3.9/modules/ContentPolicy.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/ContentPolicy.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -36,7 +36,7 @@ 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 @@ */ 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 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 @@ */ 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 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 isThirdParty(/**nsIURI*/location, /**String*/ docDomain) /**Boolean*/ { - if (!location || !docDomain) - return true; + 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; - } + 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 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 -Nru adblock-plus-1.3.9/modules/ContentPolicyRemote.jsm adblock-plus-1.3.10/modules/ContentPolicyRemote.jsm --- adblock-plus-1.3.9/modules/ContentPolicyRemote.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/ContentPolicyRemote.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -43,190 +43,190 @@ */ 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 -Nru adblock-plus-1.3.9/modules/ElemHide.jsm adblock-plus-1.3.10/modules/ElemHide.jsm --- adblock-plus-1.3.9/modules/ElemHide.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/ElemHide.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -41,7 +41,7 @@ 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 @@ */ 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 ElemHidePrivate = { - classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"), - classDescription: "Element hiding hit registration protocol handler", - aboutPrefix: "abp-elemhidehit", - - // - // 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 ("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; + classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"), + classDescription: "Element hiding hit registration protocol handler", + aboutPrefix: "abp-elemhidehit", + + // + // 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 ("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; - 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 @@ */ 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 = ""; - 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 = ""; - } - - 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; - }, + 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 = ""; + 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 = ""; + } + + 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]) + QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]) }; diff -Nru adblock-plus-1.3.9/modules/ElemHideRemote.jsm adblock-plus-1.3.10/modules/ElemHideRemote.jsm --- adblock-plus-1.3.9/modules/ElemHideRemote.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/ElemHideRemote.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -48,62 +48,62 @@ */ 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; + 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); - }, + return new HitRegistrationChannel(uri, RegExp.$1); + }, - QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule]) + QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule]) }; /** @@ -112,78 +112,78 @@ */ 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 = ""; - 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 = ""; - } - - 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; - }, + 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 = ""; + 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 = ""; + } + + 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]) + QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest]) }; ElemHideRemote.startup(); diff -Nru adblock-plus-1.3.9/modules/FilterClasses.jsm adblock-plus-1.3.10/modules/FilterClasses.jsm --- adblock-plus-1.3.9/modules/FilterClasses.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/FilterClasses.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -45,37 +45,37 @@ */ 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.fromText = function(text) { - if (text in Filter.knownFilters) - return Filter.knownFilters[text]; + if (text in Filter.knownFilters) + return Filter.knownFilters[text]; - if (!/\S/.test(text)) - return null; + 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); + 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; + Filter.knownFilters[ret.text] = ret; + return ret; } /** @@ -135,17 +135,17 @@ */ 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.normalize = function(/**String*/ text) /**String*/ { - if (!text) - return text; + if (!text) + return text; - // Remove line breaks and such - text = text.replace(/[^\S ]/g, ""); + // 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 (/^\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 @@ */ function InvalidFilter(text, reason) { - Filter.call(this, text); + Filter.call(this, text); - this.reason = reason; + this.reason = reason; } InvalidFilter.prototype = { - __proto__: Filter.prototype, + __proto__: Filter.prototype, - /** - * Reason why this filter is invalid - * @type String - */ - reason: null, - - /** - * See Filter.serialize() - */ - serialize: function(buffer) {} + /** + * Reason why this filter is invalid + * @type String + */ + reason: null, + + /** + * See Filter.serialize() + */ + serialize: function(buffer) {} }; /** @@ -213,16 +213,16 @@ */ 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 @@ */ function ActiveFilter(text, domains) { - Filter.call(this, text); + Filter.call(this, text); - if (domains) - { - this.domainSource = domains; - this.__defineGetter__("includeDomains", this._getIncludeDomains); - this.__defineGetter__("excludeDomains", this._getExcludeDomains); - } + if (domains) + { + this.domainSource = domains; + this.__defineGetter__("includeDomains", this._getIncludeDomains); + this.__defineGetter__("excludeDomains", this._getExcludeDomains); + } } ActiveFilter.prototype = { - __proto__: Filter.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); - } - } + /** + * 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 @@ */ function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty) { - ActiveFilter.call(this, text, domains); + 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); - } + 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, + __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; - } + /** + * @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; - } + return false; + } }; /** @@ -537,98 +537,98 @@ */ 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, + 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 + BACKGROUND: 4, // Backwards compat, same as IMAGE - DONOTTRACK: 0x20000000, - ELEMHIDE: 0x40000000 + DONOTTRACK: 0x20000000, + ELEMHIDE: 0x40000000 }; // ELEMHIDE and DONOTTRACK option shouldn't be there by default @@ -648,19 +648,19 @@ */ 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 @@ */ 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 @@ */ 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, + __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 + /** + * @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.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 -Nru adblock-plus-1.3.9/modules/FilterListener.jsm adblock-plus-1.3.10/modules/FilterListener.jsm --- adblock-plus-1.3.9/modules/FilterListener.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/FilterListener.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -35,7 +35,7 @@ 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 @@ */ 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 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 @@ */ function flushElemHide() { - if (!batchMode && ElemHide.isDirty) - ElemHide.apply(); + if (!batchMode && ElemHide.isDirty) + ElemHide.apply(); } /** @@ -232,13 +232,13 @@ */ 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 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 onSubscriptionChange(action, subscriptions) { - isDirty = true; + 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); - } - } - } + 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(); + flushElemHide(); } /** @@ -318,23 +318,23 @@ */ function onFilterChange(action, filters) { - isDirty = true; + 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(); - } + 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 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 -Nru adblock-plus-1.3.9/modules/FilterStorage.jsm adblock-plus-1.3.10/modules/FilterStorage.jsm --- adblock-plus-1.3.9/modules/FilterStorage.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/FilterStorage.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -39,7 +39,7 @@ 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 @@ */ 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 @@ */ 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 removeSubscriptionFilters(subscription) { - if (!(subscription.url in FilterStorage.knownSubscriptions)) - return; + 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); - } + 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 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 -Nru adblock-plus-1.3.9/modules/Matcher.jsm adblock-plus-1.3.10/modules/Matcher.jsm --- adblock-plus-1.3.9/modules/Matcher.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/Matcher.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -42,271 +42,271 @@ */ 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 @@ */ 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.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 -Nru adblock-plus-1.3.9/modules/ObjectTabs.jsm adblock-plus-1.3.10/modules/ObjectTabs.jsm --- adblock-plus-1.3.9/modules/ObjectTabs.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/ObjectTabs.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -42,7 +42,7 @@ // 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 @@ */ 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 @@ */ 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 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 objectTabEventHander(/**Event*/ event) { - if (!event.isTrusted) - return; + 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.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 -Nru adblock-plus-1.3.9/modules/Prefs.jsm adblock-plus-1.3.10/modules/Prefs.jsm --- adblock-plus-1.3.9/modules/Prefs.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/Prefs.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -36,7 +36,7 @@ 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 @@ */ 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 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](); - }, + /** + * 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]) + QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver]) } /** @@ -218,31 +218,31 @@ */ 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 triggerListeners(/**String*/ name) { - for each (let listener in listeners) - listener(name); + for each (let listener in listeners) + listener(name); } /** @@ -259,42 +259,42 @@ */ 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 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 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 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 -Nru adblock-plus-1.3.9/modules/Public.jsm adblock-plus-1.3.10/modules/Public.jsm --- adblock-plus-1.3.9/modules/Public.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/Public.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -48,134 +48,134 @@ */ 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 @@ */ function createSubscriptionWrapper(/**Subscription*/ subscription) /**IAdblockPlusSubscription*/ { - if (!subscription) - return null; + 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; - } - }; + 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 -Nru adblock-plus-1.3.9/modules/RequestNotifier.jsm adblock-plus-1.3.10/modules/RequestNotifier.jsm --- adblock-plus-1.3.9/modules/RequestNotifier.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/RequestNotifier.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -55,50 +55,50 @@ 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 @@ */ 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.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.getWindowStatistics = function(/**Window*/ wnd) { - return retrieveData(wnd.document, wndStatProp); + return retrieveData(wnd.document, wndStatProp); } /** @@ -266,138 +266,138 @@ */ 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; - } - } + 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; + 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 -Nru adblock-plus-1.3.9/modules/SubscriptionClasses.jsm adblock-plus-1.3.10/modules/SubscriptionClasses.jsm --- adblock-plus-1.3.9/modules/SubscriptionClasses.jsm 2011-06-28 14:52:21.000000000 +0000 +++ adblock-plus-1.3.10/modules/SubscriptionClasses.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -46,54 +46,54 @@ */ 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.fromURL = function(url) { - if (url in Subscription.knownSubscriptions) - return Subscription.knownSubscriptions[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 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.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"); + 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; + return result; } /** @@ -201,75 +201,75 @@ */ 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, + __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; + /** + * 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; - } + 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 @@ */ 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, + __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); - } + /** + * 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 @@ */ function ExternalSubscription(url, title) { - RegularSubscription.call(this, url, title); + RegularSubscription.call(this, url, title); } ExternalSubscription.prototype = { - __proto__: RegularSubscription.prototype, + __proto__: RegularSubscription.prototype, - /** - * See Subscription.serialize() - */ - serialize: function(buffer) - { - RegularSubscription.prototype.serialize.call(this, buffer); - buffer.push("external=true"); - } + /** + * See Subscription.serialize() + */ + serialize: function(buffer) + { + RegularSubscription.prototype.serialize.call(this, buffer); + buffer.push("external=true"); + } }; /** @@ -347,114 +347,114 @@ */ function DownloadableSubscription(url, title) { - RegularSubscription.call(this, url, title); + RegularSubscription.call(this, url, title); } DownloadableSubscription.prototype = { - __proto__: RegularSubscription.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); - } + /** + * 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 -Nru adblock-plus-1.3.9/modules/Survey.jsm adblock-plus-1.3.10/modules/Survey.jsm --- adblock-plus-1.3.9/modules/Survey.jsm 1970-01-01 00:00:00.000000000 +0000 +++ adblock-plus-1.3.10/modules/Survey.jsm 2011-09-27 18:43:36.000000000 +0000 @@ -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('\ + \ + \ + \ + \ +