165 Commits

Author SHA1 Message Date
Kevin R
96a0a6e8cb Cleaning 2020-11-08 23:51:10 +01:00
Kevin R
d5fe894414 From scratch 2020-11-08 23:32:31 +01:00
Kevin R
307b487f64 Merge branch 'master' into ts-port 2020-09-25 02:39:54 +02:00
Kevin R
606c51733f Update README.md 2020-09-25 02:39:38 +02:00
Kevin R
d82fca2972 Changes 2020-09-10 01:09:22 +02:00
Kevin R
7ea819d26a Added test ci test results 2020-09-10 00:58:38 +02:00
Kevin R
68f10ac9ac Update .gitlab-ci.yml 2020-09-10 00:44:54 +02:00
Kevin R
1df39c76f4 Update .gitlab-ci.yml 2020-09-10 00:44:16 +02:00
Kevin R
2ac158ca88 Update .gitlab-ci.yml 2020-09-10 00:27:49 +02:00
Kevin R
73d330655a Update .gitlab-ci.yml 2020-09-10 00:26:23 +02:00
Kevin R
fedc0c4230 Update .gitlab-ci.yml 2020-09-10 00:25:00 +02:00
Kevin R
e2b638eafb Changes 2020-09-10 00:23:56 +02:00
Kevin R
0c694d86ad Merge branch 'master' into ts-port 2020-09-09 23:17:20 +02:00
Kevin R
6430bcc124 added infos to rules repo 2020-09-02 00:07:44 +02:00
Kevin R
e8264eefe8 Update data.min.json 2020-09-01 23:33:36 +02:00
Kevin R
79e54f8b5f Update FUNDING.yml 2020-08-22 00:26:59 +02:00
Kevin R
6b8e515d9a Update logEntry.ts 2020-08-21 22:02:58 +02:00
Kevin R
b0c20ac780 Update lockdown.yml 2020-08-21 00:52:27 +00:00
Kevin R
c6e92a7f29 Merge branch 'master' into ts-port 2020-08-21 00:27:01 +02:00
Kevin R
ad64f98a28 Update data.min.json 2020-08-21 00:22:53 +02:00
Kevin R
2ffdf4d77b Merge branch 'master' of https://gitlab.com/KevinRoebert/ClearUrls 2020-08-21 00:19:31 +02:00
Kevin R
951d1c9f7b Added new rule
https://github.com/ClearURLs/Addon/pull/57
2020-08-21 00:19:25 +02:00
Kevin R
3a20e97354 Update lockdown.yml 2020-08-20 22:12:55 +00:00
Kevin R
c138e3387b refactor 2020-08-20 23:42:46 +02:00
Kevin R
4432fb46bf init 2 2020-08-20 04:01:58 +02:00
Kevin R
4d4a418a95 Update utils.ts 2020-08-19 23:54:08 +02:00
Kevin R
843aeed109 init 2020-08-19 23:41:12 +02:00
Kevin R
b7e209bf15 Merge branch 'performance-optimizations-for-rules' into 'master'
Performance optimizations for rules

See merge request KevinRoebert/ClearUrls!75
2020-08-19 03:34:04 +00:00
Kevin R
0469156237 Update README.md 2020-08-18 22:45:28 +00:00
Kevin R
7ac9fe7d4d Update CHANGELOG.md 2020-08-19 00:03:58 +02:00
Kevin R
de876c0ff2 Update data.min.json 2020-08-18 23:46:41 +02:00
Kevin R
3ea3f347ba added ya.ru 2020-08-18 23:42:28 +02:00
Kevin R
329c78ff88 Update data.min.json 2020-08-18 21:01:29 +02:00
Kevin R
a4d15ece2f Merge branch 'cherry-pick-b2efd0ee' into 'performance-optimizations-for-rules'
Optimized rules list

See merge request KevinRoebert/ClearUrls!74
2020-08-18 18:31:09 +00:00
Teodor Atroshenko
c6ed12808b Optimized rules list
(cherry picked from commit b2efd0eea3)
2020-08-18 18:29:01 +00:00
Kevin R
db5bd659f0 Version 1.19.0
#570
#578
#580
#581
#587
#599
2020-07-22 00:30:09 +02:00
Kevin R
6c775b9bba Merge branch 'master' into 'master'
fix typo in urlPattern for argos.co.uk

See merge request KevinRoebert/ClearUrls!68
2020-07-02 01:55:44 +00:00
Kevin R
47dfe256eb Merge branch 'patch-1' into 'master'
removed the localization from the firefox-URL

See merge request KevinRoebert/ClearUrls!69
2020-07-02 01:55:36 +00:00
DJCrashdummy
3bac289758 removed the localization from the firefox-URL 2020-07-01 13:57:12 +00:00
swrup
53035f6bb2 fix typo in urlPattern for argos.co.uk 2020-06-29 21:49:01 +00:00
Kevin R
86fb5c469a Merge branch 'patch-1' into 'master'
added rule for cnbc.com (to fix #573)

Closes #573

See merge request KevinRoebert/ClearUrls!67
2020-06-24 14:12:14 +00:00
DJCrashdummy
f1086f8889 added rule for cnbc.com (to fix #573) 2020-06-24 14:12:14 +00:00
Kevin Röbert
bf27040864 Update .gitlab-ci.yml 2020-06-24 16:00:25 +02:00
Kevin Röbert
ca7df33fa3 Update .gitlab-ci.yml 2020-06-24 15:54:40 +02:00
Kevin Röbert
e017a8838e Update .gitlab-ci.yml
+ Test stage
+ Trigger page and hash only on change
2020-06-24 15:51:14 +02:00
Kevin R
1987634095 Merge branch 'patch-2' into 'master'
Yet another global rule

See merge request KevinRoebert/ClearUrls!66
2020-06-24 13:35:59 +00:00
Anton Yablokov
6e2d082eea Yet another global rule (from https://www.behance.net/gallery/88977751/Deep-Inside-Stockholm?tracking_source=curated_galleries_photography) 2020-06-23 05:46:32 +00:00
Kevin Röbert
fa3a33962b Update data.min.json
#523
2020-06-21 23:08:16 +02:00
Kevin Röbert
abaa5fe2c6 Updated rules and exceptions
#558
#460
#504
#508
#525
#530
#532
#538
#542
#450
#544
#563
2020-06-21 23:02:35 +02:00
Kevin R
992cd351af Merge branch 'patch-1' into 'master'
added `countview` for marketscreener.com...

Closes #448

See merge request KevinRoebert/ClearUrls!64
2020-06-18 20:27:01 +00:00
DJCrashdummy
6992302e23 added countview for marketscreener.com according to https://gitlab.com/KevinRoebert/ClearUrls/-/issues/448#note_363577772 2020-06-18 11:00:15 +00:00
Kevin Röbert
bc2e2510e8 Update FUNDING.yml 2020-06-17 02:18:58 +02:00
Kevin Röbert
1ec5838a98 Create FUNDING.yml 2020-06-17 01:29:59 +02:00
Kevin Röbert
c7b1f85672 Updated Japanese by Shitennouji & Euglena0211 2020-06-07 21:46:34 +02:00
Kevin Röbert
ac2d5da41c Hotfix v. 1.18.1 2020-06-07 21:32:24 +02:00
Kevin R
27af2c8c49 Merge branch 'jquery-removal' into 'master'
Removed jQuery from core scripts

See merge request KevinRoebert/ClearUrls!62
2020-06-05 22:24:04 +00:00
Kevin Röbert
01a911557b Version 1.18.0 2020-06-06 00:23:04 +02:00
Kevin Röbert
54210b71c5 Cleanup 2020-06-06 00:05:50 +02:00
Kevin Röbert
da5fb0b3c0 Removed even more jQuery dependencies 2020-06-06 00:02:03 +02:00
Kevin Röbert
08b62c0d94 Merge branch 'master' into jquery-removal 2020-06-05 21:51:52 +02:00
Kevin R
879fcdae03 Merge branch '475-too-many-protocol-entries-cut-off-the-internet-connection' into 'master'
Resolve "Too many protocol entries cut off the internet connection"

Closes #475

See merge request KevinRoebert/ClearUrls!63
2020-06-05 19:50:56 +00:00
Kevin Röbert
762d83e46c Hard limit for the log of 5000 entries 2020-06-05 21:50:03 +02:00
Kevin Röbert
ae30c0eb53 Removed jQuery from core scripts 2020-06-05 20:13:21 +02:00
Kevin R
0acd24d716 Update data.min.json 2020-05-26 18:28:07 +00:00
Kevin R
22e58ba0e6 Temporarily removed until a whitelist feature is available.
#527
#526
#520
#519
#514
#512
#505
2020-05-26 17:47:41 +00:00
Kevin Röbert
3ade08f344 Merge branch 'master' of https://gitlab.com/KevinRoebert/ClearUrls 2020-05-19 17:37:37 +02:00
Kevin Röbert
ea256a8081 Exception for api.bilibili.com 2020-05-19 17:37:30 +02:00
Kevin
90ab42a510 Merge branch 'add-privacytools-recommendation' into 'master'
Add PrivacyTools recommendation

See merge request KevinRoebert/ClearUrls!60
2020-05-19 15:34:54 +00:00
Kevin Röbert
c60e33d327 Added exception for zoom.us websocket
#513
2020-05-19 17:26:30 +02:00
Luca Trevisani
9f47a35318 Add PrivacyTools recommendation 2020-05-16 17:25:40 +00:00
Kevin Röbert
e931674dfe Added rules & exceptions
#501
#499
#493
#492
#491
#487
#486
#485
#484
#482
#479
#477
#473
2020-05-15 15:54:14 +02:00
Kevin
ed87f72c75 Merge branch 'patch-1' into 'master'
added some fields for marketscreener.com...

Closes #448

See merge request KevinRoebert/ClearUrls!59
2020-05-15 12:03:31 +00:00
DJCrashdummy
ee2e544223 added some fields for marketscreener.com (https://gitlab.com/KevinRoebert/ClearUrls/-/issues/448#note_343173596) 2020-05-15 09:48:40 +00:00
Kevin
9aaf4718f3 Update README.md 2020-04-28 22:50:21 +00:00
Kevin Röbert
bdca5d8659 Merge branch 'master' of https://gitlab.com/KevinRoebert/ClearUrls 2020-04-27 23:57:37 +02:00
Kevin Röbert
caca49b712 Change default logLimit to 100
#475
2020-04-27 23:57:35 +02:00
Röbert
4a1fad9a90 removed overlapping permissions 2020-04-25 15:05:23 +02:00
Kevin Röbert
9fbf5a839a Update rules
#463
#468
#469
#470
2020-04-24 01:19:44 +02:00
Kevin Röbert
8b815c5f50 Revert "Updated rules"
This reverts commit 201f3a9edb.
2020-04-24 01:19:06 +02:00
Kevin Röbert
4370912baa Merge branch 'master' of https://gitlab.com/KevinRoebert/ClearUrls 2020-04-24 01:18:46 +02:00
Kevin Röbert
201f3a9edb Updated rules
#463
#468
#469
#470
2020-04-24 01:17:58 +02:00
Kevin
349c0a79ce Update Bug.md
#478
2020-04-23 22:41:47 +00:00
Kevin Röbert
d74d53c40d Added exception
#471
2020-04-20 22:46:06 +02:00
Kevin Röbert
4030d9325b Update lockdown.yml 2020-04-15 09:05:34 +00:00
Kevin Röbert
fbac0bd1a9 Update lockdown.yml 2020-04-15 09:03:34 +00:00
Kevin Röbert
85ca03fdc0 Merge branch 'KevinRoebert-master-patch-74614' into 'master'
Update .github/lockdown.yml

See merge request KevinRoebert/ClearUrls!58
2020-04-14 23:28:09 +00:00
Kevin Röbert
0fc822a302 Update .github/lockdown.yml 2020-04-14 23:27:57 +00:00
Kevin Röbert
6cc57eae1a Merge branch 'KevinRoebert-master-patch-74450' into 'master'
Update lockdown.yml

See merge request KevinRoebert/ClearUrls!57
2020-04-14 23:26:58 +00:00
Kevin Röbert
694cc4613a Update lockdown.yml 2020-04-14 23:26:16 +00:00
Kevin Röbert
c81dbee1c7 Update data.min.json 2020-04-14 23:12:45 +00:00
Kevin Röbert
3f707bfd3a Version 1.17.0
#457
#462
#445
2020-04-15 00:53:01 +02:00
Kevin Röbert
9d62ddf1b0 Update messages.json (POEditor.com) 2020-04-14 21:26:24 +00:00
Kevin Röbert
1344fd8636 Update messages.json (POEditor.com) 2020-04-14 21:26:23 +00:00
Kevin Röbert
54915cf0de Update messages.json (POEditor.com) 2020-04-14 21:19:19 +00:00
Kevin Röbert
ab325759cd Update messages.json (POEditor.com) 2020-04-14 21:18:17 +00:00
Kevin Röbert
12f63e7f71 Update messages.json (POEditor.com) 2020-04-14 21:16:58 +00:00
Kevin Röbert
7bc3891072 Update messages.json (POEditor.com) 2020-04-14 21:15:14 +00:00
Kevin Röbert
9ff50c965d Update messages.json (POEditor.com) 2020-04-14 21:13:24 +00:00
Kevin Röbert
4014195da8 Update messages.json (POEditor.com) 2020-04-14 21:10:59 +00:00
Kevin Röbert
50aa5e5a73 Update messages.json (POEditor.com) 2020-04-14 21:10:57 +00:00
Kevin Röbert
4a571794dc Update messages.json (POEditor.com) 2020-04-14 21:10:56 +00:00
Kevin Röbert
23d13b0710 Update messages.json (POEditor.com) 2020-04-14 21:10:55 +00:00
Kevin Röbert
d060acae08 Update messages.json (POEditor.com) 2020-04-14 21:10:53 +00:00
Kevin Röbert
28dfe00ff7 Update messages.json (POEditor.com) 2020-04-14 21:10:51 +00:00
Kevin Röbert
5ee667eb92 Update messages.json (POEditor.com) 2020-04-14 21:10:50 +00:00
Kevin Röbert
fda7da7f13 Update messages.json (POEditor.com) 2020-04-14 21:10:48 +00:00
Kevin Röbert
578d4bc48d Update messages.json (POEditor.com) 2020-04-14 21:10:47 +00:00
Kevin Röbert
c7a1c40f9d Update messages.json (POEditor.com) 2020-04-14 21:10:45 +00:00
Kevin Röbert
57e6ed704f Update messages.json (POEditor.com) 2020-04-14 21:10:43 +00:00
Kevin Röbert
9ee55e6536 Update messages.json (POEditor.com) 2020-04-14 21:10:42 +00:00
Kevin Röbert
755db29738 Update messages.json (POEditor.com) 2020-04-14 21:10:40 +00:00
Kevin Röbert
66671aec68 Update messages.json (POEditor.com) 2020-04-14 21:10:38 +00:00
Kevin Röbert
c2f500e060 Update messages.json (POEditor.com) 2020-04-14 21:10:37 +00:00
Kevin Röbert
cfad3d2b23 Update messages.json (POEditor.com) 2020-04-14 21:09:26 +00:00
Kevin Röbert
6d27c8a906 Update messages.json (POEditor.com) 2020-04-14 21:01:06 +00:00
Kevin Röbert
ab19cfd714 Merge branch 'revert-2878af17' into 'master'
Revert "Update messages.json (POEditor.com)"

See merge request KevinRoebert/ClearUrls!56
2020-04-14 20:55:32 +00:00
Kevin Röbert
c64cfbfe86 Revert "Update messages.json (POEditor.com)"
This reverts commit 2878af17b6
2020-04-14 20:55:06 +00:00
Kevin Röbert
b70e0d4912 Update messages.json (POEditor.com) 2020-04-14 20:12:11 +00:00
Kevin Röbert
badc78a954 Added rules and exceptions
#459
#441
#457
#448
#452
2020-04-08 21:20:26 +02:00
Kevin Röbert
c0b7ad9b06 Update README.md 2020-04-02 23:21:38 +00:00
Kevin Röbert
d984b512c0 Update messages.json (POEditor.com) 2020-04-02 22:55:11 +00:00
Kevin Röbert
d4ca4b0362 Update messages.json (POEditor.com) 2020-04-02 22:55:08 +00:00
Kevin Röbert
2878af17b6 Update messages.json (POEditor.com) 2020-04-02 22:55:07 +00:00
Kevin Röbert
86ef50ce91 Update messages.json (POEditor.com) 2020-04-02 22:55:05 +00:00
Kevin Röbert
9afb4fa167 Updated French translation
Special thanks again to Lucifer for the translation into French.
2020-03-23 23:23:06 +01:00
Kevin Röbert
6ee6591019 source fix 2020-03-20 13:20:28 +01:00
Kevin Röbert
eb45b51bcb Updated description 2020-03-20 01:57:46 +01:00
Kevin Röbert
0298792aa1 Version 1.16.0
#362
#440
#429
#428
#431
2020-03-20 01:50:22 +01:00
Kevin Röbert
b1a5b5fcb0 Update README.md 2020-03-19 11:34:27 +00:00
Kevin Röbert
6ae8dd7d22 Add button for MEA 2020-03-19 12:31:00 +01:00
Kevin Röbert
afdf172716 Added rule
#434
#404
2020-03-18 16:12:32 +01:00
Kevin Röbert
31d63fa777 Added rules and exception
#433
#434
#432
#437
#438
2020-03-18 14:52:49 +01:00
Kevin Röbert
59707d7918 Added exception
#427
2020-03-10 20:33:42 +01:00
Kevin Röbert
f0bfe4c8dd Added rules and exception
#409
#411
#414
#418
#419
#420
#421
#424
2020-03-09 22:13:59 +01:00
Kevin Röbert
975ce2fea5 Added new rules 2020-02-27 17:57:32 +01:00
Kevin R
0d5fd4b452 Added new rule
#395
2020-02-27 17:12:09 +01:00
Kevin R
02a26d3231 Added new rules and exceptions
#390 #388 #408
2020-02-27 16:55:31 +01:00
Kevin R
88890b853a Fixed spm rule
Added missing question mark
2020-02-27 16:06:06 +01:00
Kevin R
53fb25f43d Added new rules
#402
#405
2020-02-25 21:13:31 +01:00
Kevin Röbert
3370985ee2 Update data.min.json 2020-02-22 21:49:54 +01:00
Kevin Röbert
95fe7eb17d Added new rules
#398
#393
2020-02-22 21:49:23 +01:00
Kevin Röbert
f7949e89f6 Added catch statements 2020-02-20 14:12:06 +01:00
Kevin Röbert
a44e13645c Updated localized extension description 2020-02-20 13:11:19 +01:00
Kevin Röbert
21cf8ec613 Added localized extension description 2020-02-19 18:55:50 +01:00
Kevin Röbert
a8d50a102c Create PRIVACY.md 2020-02-18 16:43:16 +01:00
Kevin Röbert
e79039d210 MS Store promotion 2020-02-17 17:20:55 +01:00
Kevin Röbert
019c2e64a3 Added rules and exception
#385
#387
2020-02-16 17:10:41 +01:00
Kevin Röbert
aaa46b5e6a Version 1.15.0
+ Updated Italian translation by @gioxx
2020-02-16 16:42:18 +01:00
Kevin Röbert
dd116ece8f Update messages.json (POEditor.com) 2020-02-16 15:38:13 +00:00
Kevin Röbert
b66b22f3e4 Added rules 2020-02-11 16:30:11 +01:00
Kevin Röbert
24bf821b59 Update data.min.json 2020-02-05 20:24:44 +01:00
Kevin Röbert
6012329278 Update test site 2020-02-05 20:24:18 +01:00
Kevin Röbert
be3909f5c0 Create bla.html 2020-02-05 20:09:49 +01:00
Kevin Röbert
f1c6599638 Update test page 2020-02-05 20:02:36 +01:00
Kevin Röbert
9aaf7eeb2e Update test page 2020-02-05 18:54:11 +01:00
Kevin Röbert
4b2b528248 Added rules
#352
2020-02-05 17:07:44 +01:00
Kevin Röbert
d28b81e97b Added rule and fixed (?) Disqus redirection
#342
#373
2020-02-05 16:53:12 +01:00
Kevin Röbert
6c7c5b18ac Added missing assets 2020-02-05 16:03:54 +01:00
Kevin Röbert
3f325201df Use only sources from same origin for GitLab pages 2020-02-05 15:54:20 +01:00
Kevin Röbert
5789640b75 Added exception
Fixed #369
2020-02-02 16:40:05 +01:00
Kevin Röbert
f8b7a1740a Update ClearURLs_in_action.png 2020-02-01 21:23:23 +01:00
Kevin Röbert
2f45e18a89 Updated Readme and changelog 2020-02-01 15:00:32 +01:00
Kevin Röbert
081890759d Version 1.14.0
Changed icon
2020-02-01 14:51:39 +01:00
Kevin Röbert
7d655baab4 Added rules
#352
2020-02-01 12:56:18 +01:00
Kevin Röbert
7972e24f4c New promo stuff 2020-02-01 12:43:05 +01:00
209 changed files with 11978 additions and 18080 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100
[*.md]
trim_trailing_whitespace = false

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
# These are supported funding model platforms
custom: ['https://www.paypal.me/KevinRoebert', 'https://liberapay.com/kroeb', 'https://www.buymeacoffee.com/KevinRoebert']# Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

39
.github/lockdown.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
# Configuration for Repo Lockdown - https://github.com/dessant/repo-lockdown
# Skip issues and pull requests created before a given timestamp. Timestamp must
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
#skipCreatedBefore: false
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
#exemptLabels: []
# Comment to post before closing or locking. Set to `false` to disable
#comment: true
# Label to add before closing or locking. Set to `false` to disable
#label: true
# Close issues and pull requests
#close: true
# Lock issues and pull requests
#lock: true
# Limit to only `issues` or `pulls`
#only: pulls
# Optionally, specify configuration settings just for `issues` or `pulls`
issues:
comment: >
This repository is only a mirror of https://gitlab.com/KevinRoebert/ClearUrls. Issues are read here, but it can take longer until they are addressed. If possible, please use the GitLab repo or this support mail address: support (at) clearurls.xyz.
lock: false
close: false
pulls:
comment: >
This repository is just a mirror of https://gitlab.com/KevinRoebert/ClearUrls. Only there pull requests accepted.
lock: false
close: true
# Repository to extend settings from
# _extends: repo

9
.gitignore vendored
View File

@@ -17,4 +17,11 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
# WebStorm # WebStorm
.idea/ .idea/
node_modules
yarn.lock
distribution
coverage
size-plugin.json
junit.xml

View File

@@ -3,64 +3,113 @@ image: debian:latest
before_script: before_script:
- export DEBIAN_FRONTEND= noninteractive - export DEBIAN_FRONTEND= noninteractive
- apt-get update -y - apt-get update -y
- apt-get install -y zip unzip jq nodejs - apt-get install -y zip unzip nodejs jsonlint
# This folder is cached between builds
# http://docs.gitlab.com/ce/ci/yaml/README.html#cache
cache:
paths:
- node_modules/
stages: stages:
- install
- test
- build - build
- deploy # - deploy
hash rules: # test rules:
# stage: test
# script:
# - jsonlint-php data/data.min.json
# only:
# changes:
# - data/data.min.json
#
# hash rules:
# stage: build
# script:
# - sha256sum data/data.min.json | awk '{print $1}' > rules.min.hash
# - node build_tools/minifyDataJSON.js "data/data.min.json" "data.minify.json"
# - sha256sum data.minify.json | awk '{print $1}' > rules.minify.hash
# artifacts:
# paths:
# - rules.min.hash
# - data.minify.json
# - rules.minify.hash
# only:
# refs:
# - merge_requests
# - master
# changes:
# - data/data.min.json
install dependencies:
image: node:latest
stage: install
script:
- npm install
test:lint:
image: node:latest
stage: test
dependencies:
- install dependencies
script:
- npm run lint
test:vulnerabilities:
image: node:latest
stage: test
dependencies:
- install dependencies
script:
- npm audit
test:addon:
image: node:latest
stage: test
dependencies:
- install dependencies
script:
- npm run test:ci
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
artifacts:
when: always
paths:
- coverage
reports:
junit: junit.xml
expire_in: 30 days
bundle addon:
stage: build stage: build
script: script:
- sha256sum data/data.min.json | awk '{print $1}' > rules.min.hash - zip ClearURLs -r -FS distribution/*
- node build_tools/minifyDataJSON.js "data/data.min.json" "data.minify.json"
- sha256sum data.minify.json | awk '{print $1}' > rules.minify.hash
artifacts:
paths:
- rules.min.hash
- data.minify.json
- rules.minify.hash
only: only:
- master - master
build firefox:
stage: build
script:
- zip ClearUrls_firefox -r -FS clearurls.js browser-polyfill.js manifest.json img/* external_js/* html/* core_js/* css/* fonts/* _locales/*
only:
- master
artifacts: artifacts:
paths: paths:
- ClearUrls_firefox.zip - ClearURLs.zip
build chrome: # pages:
stage: build # stage: deploy
script: # script:
- jq 'del(.applications) | .description=""' manifest.json > manifest.json.tmp && mv manifest.json.tmp manifest.json # - mkdir public
- zip ClearUrls_chrome -r -FS clearurls.js browser-polyfill.js manifest.json img/* external_js/* html/* core_js/* css/* fonts/* _locales/* # - mkdir public/data
# - mv GitLabPages/* public/
only: # - cp img/clearurls.svg public/clearurls.svg
- master # - cp data/data.min.json public/data/data.min.json
# - sha256sum public/data/data.min.json | awk '{print $1}' > public/data/rules.min.hash
artifacts: # - node build_tools/minifyDataJSON.js "public/data/data.min.json" "public/data/data.minify.json"
paths: # - sha256sum public/data/data.minify.json | awk '{print $1}' > public/data/rules.minify.hash
- ClearUrls_chrome.zip # artifacts:
# paths:
pages: # - public
stage: deploy # only:
script: # refs:
- mkdir public # - merge_requests
- mkdir public/data # - master
- mv GitLabPages/* public/ # changes:
- cp img/clearurls.svg public/clearurls.svg # - GitLabPages/*
- cp data/data.min.json public/data/data.min.json # - img/clearurls.svg
- sha256sum public/data/data.min.json | awk '{print $1}' > public/data/rules.min.hash # - data/data.min.json
- node build_tools/minifyDataJSON.js "public/data/data.min.json" "public/data/data.minify.json" # - build_tools/minifyDataJSON.js
- sha256sum public/data/data.minify.json | awk '{print $1}' > public/data/rules.minify.hash
artifacts:
paths:
- public
only:
- master

View File

@@ -36,7 +36,7 @@ You do not have to reinstall Firefox or disable all addons. You can just create
* **Version**: [compulsory. you must provide your version] * **Version**: [compulsory. you must provide your version]
* **Platform**: [either `uname -a` output, or if Windows, version and 32-bit or * **Platform**: [either `uname -a` output, or if Windows, version and 32-bit or
64-bit] 64-bit]
* **Country**: [The country from which you called the page. You can found your country here: http://ip-api.com/json/?fields=country] * **Country**: [The country from which you called the page. You can found your country here: https://ipapi.co//country_capital]
### Log ### Log
<!-- Please enable the log functionality of ClearURLs and attach the exported log to this bug report. --> <!-- Please enable the log functionality of ClearURLs and attach the exported log to this bug report. -->

6
.prettierrc Normal file
View File

@@ -0,0 +1,6 @@
{
"trailingComma": "all",
"tabWidth": 2,
"semi": false,
"singleQuote": true
}

View File

@@ -4,6 +4,125 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Ongoing
### Changed
- Performance optimizations for rules by [@thexeos](https://gitlab.com/thexeos)
## [1.19.0] - 2020-07-22
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 37
### Changed
- Changed url decoding to prevent endless loop
## [1.18.1] - 2020-06-07
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 37
### Changed
- Hotfix for the endless loop on new log limit ([#545](https://gitlab.com/KevinRoebert/ClearUrls/issues/545), [#541](https://gitlab.com/KevinRoebert/ClearUrls/issues/541), [#539](https://gitlab.com/KevinRoebert/ClearUrls/issues/539))
## [1.18.0] - 2020-06-06
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 37
### Removed
- sha256.jquery.plugin
- Popper.js v1.16.0
- Bootstrap Colorpicker v3.2.0
- Removed `xbl` type from request types, because it throws since 78.0b3 exceptions (no longer supported)
### Added
- Pickr v1.7.0
### Changed
- Replaced sha256.jquery.plugin with native hashing
- Replaced jQuery dependencies with native JavaScript in all core files (jQuery is only required for the log page)
- Hopefully this fixes the performance problems that some users experience when using this addon in conjunction with other addons
- [#256](https://gitlab.com/KevinRoebert/ClearUrls/issues/256)
- [#535](https://gitlab.com/KevinRoebert/ClearUrls/issues/535)
- Restricted the log limit to max. 5000 entries
- Default value is now 100
- Too many log entries have resulted in performance losses for users who have forgotten that they have turned on the log. This step should prevent this.
## [1.17.0] - 2020-04-14
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 22
### Changed
- Updated some strings of Spanish translation
- Updated some strings of French translation
- Updated some strings of Italian translation
- Updated some strings of Russian translation
- Updated some strings of Swedish translation
- Updated some strings of Turkish translation
- Updated some strings of Ukrainian translation
- Updated some strings of Chinese Simple translation
### Fixed
- Fixed a typo in the path to the Datatables JavaScript file
- Fixed [#445](https://gitlab.com/KevinRoebert/ClearUrls/issues/445)
- Fixed [#462](https://gitlab.com/KevinRoebert/ClearUrls/issues/462)
### Added
- Added check for setBadgeTextColor function (only supported in Firefox)
### Removed
- Removed browser-polyfill content script import (seems no longer needed)
- Removed old `applications` value
## [1.16.0] - 2020-03-20
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 22
### Added
- Added ETag header filtering [#362](https://gitlab.com/KevinRoebert/ClearUrls/issues/362), [#440](https://gitlab.com/KevinRoebert/ClearUrls/issues/440). Hint: Cache must be cleared before first use, to delete the already existing ETags.
### Fixed
- Fixed spontaneous disappearance of the badged
- Fixed wrong counting of blocked elements (too little was ;D)
### Changed
- Updated all translation
- Changed badged font color to #FFFFFF
- Changed watchdog behavior as follows [#428](https://gitlab.com/KevinRoebert/ClearUrls/issues/428), [#431](https://gitlab.com/KevinRoebert/ClearUrls/issues/431), [#429](https://gitlab.com/KevinRoebert/ClearUrls/issues/429):
- Increased watchdog interval to 60 seconds
- Executed watchdog only if ClearURLs is also active
- Watchdog restarts ClearURLs at most 3 times and only if ClearURLs has rules
- Changed behavior of downloading rules [#428](https://gitlab.com/KevinRoebert/ClearUrls/issues/428), [#431](https://gitlab.com/KevinRoebert/ClearUrls/issues/431), [#429](https://gitlab.com/KevinRoebert/ClearUrls/issues/429):
- If download of hash file fails and no local rules are available, then ClearURLs displays `hash_status_code_5` and deactivates itself
- If download of rules file fails and no local rules are available, then ClearURLs displays `hash_status_code_5` and deactivates itself
## [1.15.0] - 2020-02-16
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 22
### Changed
- Updated Italian translation by [@gioxx](https://gitlab.com/gioxx)
## [1.14.0] - 2020-02-01
### Compatibility note
- Require Firefox >= 55
- Require Chrome >= 22
### Changed
- Changed icon
## [1.13.0] - 2020-02-01 ## [1.13.0] - 2020-02-01
### Compatibility note ### Compatibility note

View File

@@ -1,16 +0,0 @@
body {
background-color: #FFFFFF;
}
.ui.menu .item img.logo {
margin-right: 1.5em;
}
.main.container {
margin-top: 7em;
}
.wireframe {
margin-top: 2em;
}
.ui.footer.segment {
margin: 5em 0em 0em;
padding: 5em 0em;
}

View File

@@ -1,42 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ClearURLs - Issue 253</title>
<meta name="description" content="ClearURLs test page">
<meta name="author" content="Kevin Röbert">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="ui inverted menu">
<div class="ui container">
<a href="#" class="header item">
<img class="logo" src="clearurls.svg">
ClearURLs
</a>
</div>
</div>
<div class="ui main text container">
<h1 class="ui header">ClearURLs - Issue 253</h1>
<div class="ui negative icon message">
<i class="huge warning sign icon"></i>
<div class="content">
<p>
Your ClearURLs version is vulnerable to the problem from issue 253.
Please update your ClearURLs installation to at least version <b>1.8.4 or higher</b>.
</p>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
</body>
</html>

View File

@@ -1,58 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ClearURLs test page</title>
<meta name="description" content="ClearURLs test page">
<meta name="author" content="Kevin Röbert">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css">
<link rel="stylesheet" href="css/styles.css">
</head>
<body>
<div class="ui inverted menu">
<div class="ui container">
<a href="#" class="header item">
<img class="logo" src="clearurls.svg">
ClearURLs
</a>
</div>
</div>
<div class="ui main text container">
<h1 class="ui header">ClearURLs test page</h1>
<p>
On this page you can automatically check whether ClearURLs works correctly.
If you are using an obsolete ClearURLs version that is affected by a potential security vulnerability,
you will also be notified on this page.
</p>
<br />
<div class="ui icon message" id="rules_filter_test"></div>
<div class="ui icon message" id="redirection_filter_test"></div>
<div class="ui icon message" id="block_filter_test"></div>
<div class="ui icon message" id="issue_253_test"></div>
<iframe src="https://kevinroebert.gitlab.io/ClearUrls/void/index.html?ref=gitlab"
height="1" width="1" id="void_roebert_eu_iframe" style="border:0; border:none;"></iframe>
<iframe src="https://youtube.com/redirect?q=https%3A%2F%2Fkevinroebert.gitlab.io%2FClearUrls%2Fvoid%2Findex.html%3Fref%3Dgitlab"
height="1" width="1" id="redirect_roebert_eu_iframe" style="border:0; border:none;"></iframe>
<iframe src="https://www.google.com/url?rct=j&url=https%3A%2F%2Fkevinroebert.gitlab.io%2FClearUrls%2Fi253.html"
height="1" width="1" id="i253_roebert_eu_iframe" style="border:0; border:none;"></iframe>
<img id="i253_roebert_eu_img" height="1" width="1"/>
<img id="block_roebert_eu_img" height="1" width="1"/>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
<script src="js/scripts.js"></script>
</body>
</html>

View File

@@ -1,113 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
function checkRule() {
let resURL;
try {
resURL = document.getElementById("void_roebert_eu_iframe").contentWindow.location.href;
} catch(e) {
resURL = "error";
}
let segment = $('#rules_filter_test');
if(resURL === 'https://kevinroebert.gitlab.io/ClearUrls/void/index.html') {
segment.addClass('positive');
segment.append('<i class="large smile outline icon"></i>');
segment.append('<div class="content"><p>The tracking filter function of ClearURLs works correctly.</p></div>');
} else {
segment.addClass('warning');
segment.append('<i class="large frown outline icon"></i>');
segment.append('<div class="content"><p>The tracking filter function of ClearURLs does <b>not</b> work properly. ' +
'Maybe the addon is disabled or the rules could not be downloaded.</p></div>');
}
}
function checkRedirection() {
let resURL;
try {
resURL = document.getElementById("redirect_roebert_eu_iframe").contentWindow.location.href;
} catch(e) {
resURL = "error";
}
let segment = $('#redirection_filter_test');
if(resURL === 'https://kevinroebert.gitlab.io/ClearUrls/void/index.html') {
segment.addClass('positive');
segment.append('<i class="large smile outline icon"></i>');
segment.append('<div class="content"><p>The redirection function of ClearURLs works correctly.</p></div>');
} else {
segment.addClass('warning');
segment.append('<i class="large frown outline icon"></i>');
segment.append('<div class="content"><p>The redirection function of ClearURLs does <b>not</b> work properly. ' +
'Maybe the addon is disabled or the rules could not be downloaded.</p></div>');
}
}
function checkBlock() {
let segment = $('#block_filter_test');
$('#block_roebert_eu_img')
.on('load', function() {
segment.addClass('warning');
segment.append('<i class="large frown outline icon"></i>');
segment.append('<div class="content"><p>The block function of ClearURLs does <b>not</b> work properly. ' +
'Maybe the addon is disabled or the rules could not be downloaded.</p></div>');
})
.on('error', function() {
segment.addClass('positive');
segment.append('<i class="large smile outline icon"></i>');
segment.append('<div class="content"><p>The block function of ClearURLs works correctly.</p></div>');
})
.attr("src", 'https://www.contentpass.de/img/logo.svg');
}
function checkIssue253() {
let segment = $('#issue_253_test');
$('#i253_roebert_eu_img')
.on('load', function() {
segment.addClass('negative');
segment.append('<i class="large frown outline icon"></i>');
segment.append('<div class="content"><p>Your ClearURLs version is vulnerable to the problem from issue 253. ' +
'Please update your ClearURLs installation to at least version <b>1.8.3 or higher</b>.</p></div>');
})
.on('error', function() {
segment.addClass('positive');
segment.append('<i class="large smile outline icon"></i>');
segment.append('<div class="content"><p>Your ClearURLs version is not vulnerable to the problem from Issue 253.</p></div>');
})
.attr("src", 'https://www.google.com/url?rct=j&url=https%3A%2F%2Fkevinroebert.gitlab.io%2FClearUrls%2Fi253.html');
}
$(window).on('load', function () {
try {
checkRule();
} catch(e) {}
try {
checkRedirection();
} catch(e) {}
try {
checkBlock();
} catch(e) {}
try {
checkIssue253();
} catch(e) {}
});

6
PRIVACY.md Normal file
View File

@@ -0,0 +1,6 @@
ClearURLs protects and respects your privacy.
We do not collect any of your usage data. Furthermore ClearURLs has no home server nor embed any kind of analytic hooks in its code.
The only time ClearURLs connects to a remote server (gitlab.io) is to update the rules file and the associated hash file. You can replace the default update address with your own address at any time in the settings.
The project and the rule file is currently hosted on gitlab.com, which is owned by GitLab Inc. and thus is unrelated to ClearURLs.

View File

@@ -1,8 +1,10 @@
<a href="https://www.buymeacoffee.com/KevinRoebert" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="51" width="217"></a> <a href="https://www.paypal.me/KevinRoebert" target="_blank"><img src="https://raw.githubusercontent.com/KevinRoebert/DonateButtons/master/Paypal.png" alt="Buy Me A Coffee" height="55"></a>
<a href="https://liberapay.com/kroeb" target="_blank"><img src="https://raw.githubusercontent.com/KevinRoebert/DonateButtons/master/LiberaPay.png" alt="Buy Me A Coffee" height="55"></a>
<a href="https://www.buymeacoffee.com/KevinRoebert" target="_blank"><img src="https://raw.githubusercontent.com/KevinRoebert/DonateButtons/master/BuyMeACoffee.png" alt="Buy Me A Coffee" height="55"></a>
[<img src="https://addons.cdn.mozilla.net/static/img/addons-buttons/AMO-button_1.png" alt="for Firefox">](https://addons.mozilla.org/en-US/firefox/addon/clearurls/) [<img src="https://developer.chrome.com/webstore/images/ChromeWebStore_BadgeWBorder_v2_206x58.png" alt="for Chrome">](https://chrome.google.com/webstore/detail/clearurls/lckanjgmijmafbedllaakclkaicjfmnk) [<img src="https://blog.mozilla.org/addons/files/2020/04/get-the-addon-fx-apr-2020.svg" alt="for Firefox" height="60px">](https://addons.mozilla.org/firefox/addon/clearurls/) [<img src="https://gitlab.com/KevinRoebert/ClearUrls/-/raw/master/promotion/MEA-button.png" alt="for Edge" height="60px">](https://microsoftedge.microsoft.com/addons/detail/mdkdmaickkfdekbjdoojfalpbkgaddei) [<img src="https://developer.chrome.com/webstore/images/ChromeWebStore_BadgeWBorder_v2_206x58.png" alt="for Chrome" height="60px">](https://chrome.google.com/webstore/detail/clearurls/lckanjgmijmafbedllaakclkaicjfmnk)
# <sub><img src="https://gitlab.com/KevinRoebert/ClearUrls/raw/master/img/clearurls.svg" width="64px" height="64px"></sub> ClearURLs # <sub><img src="https://gitlab.com/KevinRoebert/ClearUrls/raw/master/img/clearurls.svg" width="64px" height="64px"></sub> ClearURLs [![Gitter](https://badges.gitter.im/ClearURLs/community.svg)](https://gitter.im/ClearURLs/community)
**ClearURLs** is an add-on based on the new WebExtensions technology and is optimized for *Firefox* and *Chrome* based browsers. **ClearURLs** is an add-on based on the new WebExtensions technology and is optimized for *Firefox* and *Chrome* based browsers.
@@ -29,6 +31,7 @@ Indeed most of the above URL is tracking code. Once ClearURLs has cleaned the ad
* Supports redirection to the destination, without tracking services as middleman * Supports redirection to the destination, without tracking services as middleman
* Adds an entry to the context menu so that links can be copied quickly and cleanly * Adds an entry to the context menu so that links can be copied quickly and cleanly
* Blocks hyperlink auditing, also known as *ping tracking* (see also [this article](https://html.spec.whatwg.org/multipage/links.html#hyperlink-auditing)) * Blocks hyperlink auditing, also known as *ping tracking* (see also [this article](https://html.spec.whatwg.org/multipage/links.html#hyperlink-auditing))
* Prevents ETag tracking
* Prevents tracking injection over history API (see also: [The replaceState() method](https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_replaceState()_method)) * Prevents tracking injection over history API (see also: [The replaceState() method](https://developer.mozilla.org/en-US/docs/Web/API/History_API#The_replaceState()_method))
* Prevents Google from rewriting the search results (to include tracking elements) * Prevents Google from rewriting the search results (to include tracking elements)
* Prevents Yandex from rewriting the search results (to include tracking elements) * Prevents Yandex from rewriting the search results (to include tracking elements)
@@ -37,21 +40,21 @@ Indeed most of the above URL is tracking code. Once ClearURLs has cleaned the ad
Reasoning for needed permissions can be found under [here](https://gitlab.com/KevinRoebert/ClearUrls/issues/159). Reasoning for needed permissions can be found under [here](https://gitlab.com/KevinRoebert/ClearUrls/issues/159).
## Screenshot ## Screenshot
![Interface (version 1.11.0)](https://gitlab.com/KevinRoebert/ClearUrls/raw/master/promotion/screens/Popup_v_1.11.0.png) ![Interface (version 1.14.0)](https://gitlab.com/KevinRoebert/ClearUrls/raw/master/promotion/screens/Popup_v_1.14.0.png)
## CI/CD Artifacts Download (for Firefox- and Chrome-Dev only) ## CI/CD Artifacts Download (for Firefox- and Chrome-Dev only)
Here you can download the packed files for the Firefox- and Chrome-Dev: Here you can download the packed files for the Firefox- and Chrome-Dev:
[Firefox](https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/ClearUrls_firefox.zip?job=build%20firefox) [<img src="promotion/download-128.png"/>](https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/ClearURLs.zip?job=bundle%20addon)
[Chrome](https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/ClearUrls_chrome.zip?job=build%20chrome)
## Test ## Test
If you want to test whether ClearURLs works correctly on your system, you can go to this test page: [https://clearurls.roebert.eu/](https://clearurls.roebert.eu/) If you want to test whether ClearURLs works correctly on your system, you can go to this test page: [https://test.clearurls.xyz/](https://test.clearurls.xyz/)
## Contribute ## Contribute
If you have any suggestions or complaints, please [create an issue.](https://gitlab.com/KevinRoebert/ClearUrls/issues/new) If you have any suggestions or complaints, please [create an issue.](https://gitlab.com/KevinRoebert/ClearUrls/issues/new)
**Note: If you have any suggestions or complaints regarding the rules, please [create an issue in this repo](https://gitlab.com/anti-tracking/ClearURLs/rules/-/issues/new) or email us rules.support (at) clearurls.xyz (this mail will automatically create a new issue in this repo).**
### Translate ClearURLs ### Translate ClearURLs
You want to help translating ClearURLs into many languages? Nice You want to help translating ClearURLs into many languages? Nice
@@ -61,7 +64,7 @@ You can choose between two options to contribute. You can create a merge request
It is not necessary to translate the description field; in the most cases it is empty.* It is not necessary to translate the description field; in the most cases it is empty.*
#### Merge request #### Merge request
If you want to create a merge request, you must open the path [`_locales/en/messages.json`](https://github.com/KevinRoebert/ClearUrls/blob/master/_locales/en/messages.json) in the ClearURLs repo If you want to create a merge request, you must open the path [`source/_locales/en/messages.json`](https://github.com/KevinRoebert/ClearUrls/blob/master/source/_locales/en/messages.json) in the ClearURLs repo
and translate the english terms into terms of your language. Once you have translated all the terms, you make a pull request of your translation. and translate the english terms into terms of your language. Once you have translated all the terms, you make a pull request of your translation.
Please push your translation into the folder `_locales/{country code}/messages.json`. Please push your translation into the folder `_locales/{country code}/messages.json`.
@@ -71,12 +74,14 @@ Please push your translation into the folder `_locales/{country code}/messages.j
## Projects that use parts of ClearURLs ## Projects that use parts of ClearURLs
* [Uroute](https://github.com/walterl/uroute) used ClearURLs to filter/clean URL before launching browser * [Uroute](https://github.com/walterl/uroute) used ClearURLs to filter/clean URL before launching browser
* [Scrub](https://gitlab.com/CrunchBangDev/cbd-cogs/-/tree/master/Scrub) used ClearURLs to filter/clean URLs as cog for the Red Discord bot
## Recommended by... ## Recommended by...
* [ghacks-user.js](https://github.com/ghacksuserjs/ghacks-user.js/wiki/4.1-Extensions) * [ghacks-user.js](https://github.com/ghacksuserjs/ghacks-user.js/wiki/4.1-Extensions)
* [Awesome Humane Tech List](https://github.com/humanetech-community/awesome-humane-tech#tracking) * [Awesome Humane Tech List](https://github.com/humanetech-community/awesome-humane-tech#tracking)
* [PrivacyTools](https://www.privacytools.io/browsers/#addons)
* ClearURLs is part of Mozilla's recommended extensions program * ClearURLs is part of Mozilla's recommended extensions program
## Permissions ## Permissions
Reasoning for needed permissions you can find under [this discussion](https://gitlab.com/KevinRoebert/ClearUrls/issues/159). Reasoning for needed permissions you can find under [this discussion](https://gitlab.com/KevinRoebert/ClearUrls/issues/159).
@@ -91,14 +96,8 @@ We use some third-party scripts in our add-on. The authors and licenses are list
- [jQuery v3.4.1](https://github.com/jquery/jquery/tree/3.4.1) | - [jQuery v3.4.1](https://github.com/jquery/jquery/tree/3.4.1) |
Copyright JS Foundation and other contributors | Copyright JS Foundation and other contributors |
[MIT](https://jquery.org/license/) [MIT](https://jquery.org/license/)
- [sha256.jquery.plugin](https://github.com/orsozed/sha256.jquery.plugin) |
Copyright 2003, Christoph Bichlmeier |
[MIT](https://raw.github.com/orsozed/JQuery-Plugins/master/license/MIT-LICENSE.txt) |
[GPLv2](https://raw.github.com/orsozed/JQuery-Plugins/master/license/GPL-LICENSE.txt)
- [DataTables v1.10.20](https://github.com/DataTables/DataTables/tree/master) | Copyright (c) 2008-2015 SpryMedia Limited | [MIT](https://datatables.net/license/) - [DataTables v1.10.20](https://github.com/DataTables/DataTables/tree/master) | Copyright (c) 2008-2015 SpryMedia Limited | [MIT](https://datatables.net/license/)
- [Popper.js v1.16.0](https://github.com/popperjs/popper.js/tree/v1.16.0) | Copyright (c) 2016 Federico Zivolo and contributors | - [Pickr v1.7.0](https://github.com/Simonwep/pickr/tree/1.7.0) | Copyright (c) 2018 - 2020 Simon Reinisch |
[MIT](https://github.com/popperjs/popper.js/blob/master/LICENSE.md) [MIT](https://github.com/Simonwep/pickr/blob/master/LICENSE)
- [Bootstrap Colorpicker v3.2.0](https://github.com/itsjavi/bootstrap-colorpicker/tree/3.2.0) | Copyright (c) 2017 Javi Aguilar |
[MIT](https://github.com/itsjavi/bootstrap-colorpicker/blob/master/LICENSE)
- [Font Awesome v5.12.0](https://github.com/FortAwesome/Font-Awesome/tree/5.12.0) | Copyright (c) @fontawesome | - [Font Awesome v5.12.0](https://github.com/FortAwesome/Font-Awesome/tree/5.12.0) | Copyright (c) @fontawesome |
[Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt) [Font Awesome Free License](https://github.com/FortAwesome/Font-Awesome/blob/master/LICENSE.txt)

46
__tests__/rules/rule.ts Normal file
View File

@@ -0,0 +1,46 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import Rule from '../../source/rules/rule';
import SimpleRule from '../../source/rules/simpleRule';
describe('RuleTest', () => {
let rule: Rule
it('should create correct RegExp', () => {
rule = new SimpleRule('test')
expect(rule.value.toString()).toBe(new RegExp('([\/?#]|(&|&amp;))+(test=[^&]*)', 'gi').toString())
})
it('should return correct value on toString', () => {
rule = new SimpleRule('test')
expect(rule.toString()).toBe('([\/?#]|(&|&amp;))+(test=[^&]*)')
})
it('should be set active value correctly', () => {
rule = new SimpleRule('test')
expect(rule.isActive).toBe(true)
rule.deactivate()
expect(rule.isActive).toBe(false)
rule.activate()
expect(rule.isActive).toBe(true)
})
})

View File

@@ -0,0 +1,44 @@
import CircularBuffer from '../../source/utils/circularBuffer'
describe('CircularBuffer', () => {
let capacity: number
let buffer: CircularBuffer<string>
beforeEach(() => {
capacity = 10
buffer = new CircularBuffer<string>(capacity)
})
it('should creates a buffer with the specified capacity', () => {
expect(buffer.capacity).toBe(capacity)
})
it('should add item to the buffer', () => {
expect(buffer.size).toBe(0)
buffer.enqueue('foo')
expect(buffer.size).toBe(1)
})
it('should remove oldest item if the buffer is full on adding new items', () => {
buffer = new CircularBuffer<string>(2)
buffer.enqueue('foo1')
buffer.enqueue('foo2')
buffer.enqueue('foo3')
buffer.enqueue('foo4')
expect(buffer.toArray()).toEqual(['foo3', 'foo4'])
})
it('should return the current size via the size() getter', () => {
buffer.enqueue('foo')
expect(buffer.size).toBe(1)
})
it('should return true if buffer is empty', () => {
expect(buffer.isEmpty()).toBe(true)
})
it('should throw exception on illegal argument', () => {
expect(() => new CircularBuffer<any>(0)).toThrow('The capacity must be > 0')
})
})

View File

@@ -1,202 +0,0 @@
{
"hash_status_code_1": {
"message": "не потребує оновлення",
"description": "This status code says, that no update is available for the ClearURLs rules and everything is up to date."
},
"hash_status_code_2": {
"message": "оновлено",
"description": "This status code says, that the ClearURLs rules are successfully updated."
},
"hash_status_code_3": {
"message": "наявне оновлення",
"description": "This status code says, that an update is available for the ClearURLs rules."
},
"hash_status_code_4": {
"message": "помилка",
"description": "This status code says, that the ClearURLs could not be started correctly."
},
"hash_status_code_5": {
"message": "Ой, щось не так!",
"description": "This status code says, that an error occurred while updating the ClearURLs rules."
},
"log_redirect": {
"message": "Ця URL-адреса перенаправляється",
"description": "This string is used on redirections in the ClearURLs log."
},
"log_domain_blocked": {
"message": "Цей домен заблоковано",
"description": "This string is used on blocked domains in the ClearURLs log."
},
"check_os_log": {
"message": "[ClearURLs]: listener журналу додано.",
"description": "This string is used on ClearURLs log startup."
},
"log_html_page_title": {
"message": "Журнал ClearURLs",
"description": "This string is used as header on the log page."
},
"log_html_table_head_1": {
"message": "Перед обробкою",
"description": "This string is used as table title on the log page."
},
"log_html_table_head_2": {
"message": "Після обробки",
"description": "This string is used as table title on the log page."
},
"log_html_table_head_3": {
"message": "Правило",
"description": "This string is used as table title on the log page."
},
"log_html_table_head_4": {
"message": "Час",
"description": "This string is used as table title on the log page."
},
"log_html_reset_button": {
"message": "Скинути",
"description": "This string is used for the reset button on the log page."
},
"log_html_reset_button_title": {
"message": "Скидання глобального журналу",
"description": "This string is used as title for the reset button on the log page."
},
"popup_html_configs_head": {
"message": "Налаштування",
"description": "This string is used as title for the configs on the popup page."
},
"popup_html_configs_switch_filter": {
"message": "Фільтр",
"description": "This string is used as name for the filter switch button on the popup page."
},
"popup_html_configs_switch_filter_title": {
"message": "Активує функцію очищення ClearURLs. Якщо вимкнути - додаток не працюватиме",
"description": "This string is used as title for the filter switch button on the popup page."
},
"popup_html_configs_switch_log": {
"message": "Журнал",
"description": "This string is used as name for the logging switch button on the popup page."
},
"popup_html_configs_switch_log_title": {
"message": "Журнал зберігається лише локально. Не активуйте цю функцію, якщо вона вам не потрібна",
"description": "This string is used as title for the logging switch button on the popup page."
},
"popup_html_configs_switch_badges": {
"message": "Позначки",
"description": "This string is used as name for the badges switch button on the popup page."
},
"popup_html_configs_switch_badges_title": {
"message": "Показати кількість очищених URL",
"description": "This string is used as title for the badges switch button on the popup page."
},
"popup_html_statistics_head": {
"message": "Статистика",
"description": "This string is used as title for the statistics on the popup page."
},
"popup_html_statistics_elements": {
"message": "Елементи",
"description": "This string is used as name for the elements on the popup page."
},
"popup_html_statistics_blocked": {
"message": "Заблоковано",
"description": "This string is used as name for the blocked elements on the popup page."
},
"popup_html_statistics_percentage": {
"message": "Відсоток",
"description": "This string is used as name for the percentage of blocked elements on the popup page."
},
"popup_html_statistics_reset_button": {
"message": "Скинути",
"description": "This string is used as name for the statistics reset button on the popup page."
},
"popup_html_statistics_reset_button_title": {
"message": "Скидання глобальної статистики",
"description": "This string is used as title for the statistics reset button on the popup page."
},
"popup_html_rules_status_head": {
"message": "Актуальність правил",
"description": "This string is used as title for the rules-status section on the popup page."
},
"popup_html_log_head": {
"message": "Журнал",
"description": "This string is used as name for the log button on the popup page."
},
"popup_html_log_head_title": {
"message": "Відкрити журнал",
"description": "This string is used as title for the log button on the popup page."
},
"popup_html_report_button": {
"message": "Повідомити про URL",
"description": "Note: Currently not used."
},
"popup_html_report_button_title": {
"message": "Повідомити про URL з цієї вкладки.",
"description": "Currently not used."
},
"core_save_on_disk": {
"message": "[ClearURLs]: Зберегти на диск.",
"description": "This string is used to tell the user, that ClearURLs saved the settings on disk."
},
"core_error": {
"message": "[ClearURLs]: Не вдалося запустити додаток.",
"description": "This string is used to tell the user, that ClearURLs could not be started."
},
"configs_switch_statistics": {
"message": "Статистика",
"description": "This string is used as name for the statistics switch button on the popup page."
},
"configs_switch_statistics_title": {
"message": "Увімкнення чи вимкнення статистики",
"description": "This string is used as title for the statistics switch button on the popup page."
},
"settings_html_page_title": {
"message": "Налаштування ClearURLs",
"description": "This string is used as title on the settings page."
},
"badged_color_label": {
"message": "Колір піктограми",
"description": "This string is used as name for the badged color label."
},
"setting_html_reset_button": {
"message": "Скинути",
"description": "This string is used as name for the reset button on the settings page."
},
"setting_html_reset_button_title": {
"message": "Скинути все",
"description": "This string is used as title for the reset button on the settings page."
},
"setting_rule_url_label": {
"message": "Посилання на файл data.json (правила)",
"description": "This string is used as name for the rule url label."
},
"settings_html_save_button": {
"message": "Зберегти і перезавантажити додаток",
"description": "This string is used as name for the save&reload button on the settings page."
},
"settings_html_save_button_title": {
"message": "Збереження налаштувань",
"description": "This string is used as title for the save&reload button on the settings page."
},
"setting_hash_url_label": {
"message": "Посилання на файл rules.hash (хеш)",
"description": "This string is used as name for the rule.hash url label."
},
"setting_types_label": {
"message": "<a href='https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/ResourceType' target='_blank'>Типи запитів</a> (експертний рівень)",
"description": "This string is used as name for the types label."
},
"setting_report_server_label": {
"message": "Звіт про сервер URL",
"description": "Note: Currently not used."
},
"success_report_url": {
"message": "Успішно повідомлено про URL-адресу. Ми невдовзі це перевіримо.",
"description": "Note: Currently not used."
},
"error_report_url": {
"message": "Схоже, про цю URL-адресу вже повідомлено.",
"description": "Note: Currently not used."
},
"donate_button": {
"message": "Внесок для розробників ClearURLs.",
"description": "This string is used to refer to a donation page."
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,87 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for minification of the data.min.json file and deletes also empty entries.
*/
let fs = require('fs');
const inFileLocation = process.argv.slice(2)[0];
const outFileLocation = process.argv.slice(2)[1];
if(inFileLocation === undefined || outFileLocation === undefined) {
throw "in- and output must be set!";
}
const fileContent = fs.readFileSync(inFileLocation).toString();
/**
* Builds a minify version of the data.min.json file.
*/
function build() {
const data = JSON.parse(fileContent);
let minifiedData = {"providers":{}};
for(let provider in data.providers) {
minifiedData.providers[provider] = {};
let self = minifiedData.providers[provider];
if(data.providers[provider].completeProvider === true) {
self.completeProvider = true;
}
if(data.providers[provider].forceRedirection === true) {
self.forceRedirection = true;
}
if(data.providers[provider].urlPattern !== "") {
self.urlPattern = data.providers[provider].urlPattern;
}
if(data.providers[provider].rules.length !== 0) {
self.rules = data.providers[provider].rules;
}
if(data.providers[provider].rawRules.length !== 0) {
self.rawRules = data.providers[provider].rawRules;
}
if(data.providers[provider].referralMarketing.length !== 0) {
self.referralMarketing = data.providers[provider].referralMarketing;
}
if(data.providers[provider].exceptions.length !== 0) {
self.exceptions = data.providers[provider].exceptions;
}
if(data.providers[provider].redirections.length !== 0) {
self.redirections = data.providers[provider].redirections;
}
}
fs.writeFile(outFileLocation, JSON.stringify(minifiedData), function(err) {
if(err) {
return console.log(err);
}
console.log("The file was saved!");
});
}
build();

View File

@@ -1,749 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for the core functionalities.
*/
var providers = [];
var prvKeys = [];
var badges = [];
var tabid = 0;
var siteBlockedAlert = 'javascript:void(0)';
var dataHash;
var localDataHash;
var os;
var currentURL;
/**
* Helper function which remove the tracking fields
* for each provider given as parameter.
*
* @param {Provider} provider Provider-Object
* @param pureUrl URL as String
* @param {boolean} quiet if the action should be displayed in log and statistics
* @return {Array} Array with changes and url fields
*/
function removeFieldsFormURL(provider, pureUrl, quiet = false) {
let url = pureUrl;
let domain = "";
let fragments = "";
let fields = "";
let rules = provider.getRules();
let changes = false;
let cancel = false;
let rawRules = provider.getRawRules();
if (storage.localHostsSkipping && checkLocalURL(pureUrl)) {
return {
"changes": false,
"url": url,
"cancel": false
};
}
/*
* Apply raw rules to the URL.
*/
rawRules.forEach(function (rawRule) {
let beforeReplace = url;
url = url.replace(new RegExp(rawRule, "gi"), "");
if (beforeReplace !== url) {
//Log the action
if (storage.loggingStatus && !quiet) {
pushToLog(beforeReplace, url, rawRule);
}
increaseBadged(quiet);
changes = true;
}
});
if (existsFragments(url)) {
domain = url.replace(new RegExp("#.*", "i"), "");
}
if (existsFields(url)) {
domain = url.replace(new RegExp("\\?.*", "i"), "");
}
/*
* Expand the url by provider redirections. So no tracking on
* url redirections form sites to sites.
*/
let re = provider.getRedirection(url);
if (re !== null) {
url = decodeURL(re);
//Log the action
if (!quiet) pushToLog(pureUrl, url, translate('log_redirect'));
return {
"redirect": true,
"url": url
};
}
if (existsFields(url)) {
fields = "?" + extractFileds(url).rmEmpty().join("&");
}
if (existsFragments(url)) {
fragments = "#" + extractFragments(url).rmEmpty().join("&");
}
/**
* Only test for matches, if there are fields or fragments that can be cleaned.
*/
if (fields !== "" || fragments !== "") {
rules.forEach(function (rule) {
let beforeReplace = fields;
let beforeReplaceFragments = fragments;
fields = fields.replace(new RegExp(rule, "gi"), "");
fragments = fragments.replace(new RegExp(rule, "gi"), "");
if (beforeReplace !== fields || beforeReplaceFragments !== fragments) {
//Log the action
if (storage.loggingStatus) {
let tempURL = domain;
let tempBeforeURL = domain;
if (fields !== "") tempURL += "?" + fields.replace("?&", "?").replace("?", "");
if (fragments !== "") tempURL += "#" + fragments.replace("#&", "#").replace("#", "");
if (beforeReplace !== "") tempBeforeURL += "?" + beforeReplace.replace("?&", "?").replace("?", "");
if (beforeReplaceFragments !== "") tempBeforeURL += "#" + beforeReplaceFragments.replace("#&", "#").replace("#", "");
if (!quiet) pushToLog(tempBeforeURL, tempURL, rule);
}
increaseBadged(quiet);
changes = true;
}
});
let finalURL = domain;
if (fields !== "") finalURL += "?" + fields.replace("?", "");
if (fragments !== "") finalURL += "#" + fragments.replace("#", "");
url = finalURL.replace(new RegExp("\\?&"), "?").replace(new RegExp("#&"), "#");
}
if (provider.isCaneling() && storage.domainBlocking) {
if (!quiet) pushToLog(pureUrl, pureUrl, translate('log_domain_blocked'));
increaseBadged(quiet);
cancel = true;
}
return {
"changes": changes,
"url": url,
"cancel": cancel
};
}
function start() {
/**
* Initialize the JSON provider object keys.
*
* @param {object} obj
*/
function getKeys(obj) {
for (const key in obj) {
prvKeys.push(key);
}
}
/**
* Initialize the providers form the JSON object.
*
*/
function createProviders() {
let data = storage.ClearURLsData;
for (let p = 0; p < prvKeys.length; p++) {
//Create new provider
providers.push(new Provider(prvKeys[p], data.providers[prvKeys[p]].getOrDefault('completeProvider', false),
data.providers[prvKeys[p]].getOrDefault('forceRedirection', false)));
//Add URL Pattern
providers[p].setURLPattern(data.providers[prvKeys[p]].getOrDefault('urlPattern', ''));
let rules = data.providers[prvKeys[p]].getOrDefault('rules', []);
//Add rules to provider
for (let r = 0; r < rules.length; r++) {
providers[p].addRule(rules[r]);
}
let rawRules = data.providers[prvKeys[p]].getOrDefault('rawRules', []);
//Add raw rules to provider
for (let raw = 0; raw < rawRules.length; raw++) {
providers[p].addRawRule(rawRules[raw]);
}
let referralMarketingRules = data.providers[prvKeys[p]].getOrDefault('referralMarketing', []);
//Add referral marketing rules to provider
for (let referralMarketing = 0; referralMarketing < referralMarketingRules.length; referralMarketing++) {
providers[p].addReferralMarketing(referralMarketingRules[referralMarketing]);
}
let exceptions = data.providers[prvKeys[p]].getOrDefault('exceptions', []);
//Add exceptions to provider
for (let e = 0; e < exceptions.length; e++) {
providers[p].addException(exceptions[e]);
}
let redirections = data.providers[prvKeys[p]].getOrDefault('redirections', []);
//Add redirections to provider
for (let re = 0; re < redirections.length; re++) {
providers[p].addRedirection(redirections[re]);
}
}
}
/**
* Convert the external data to Objects and
* call the create provider function.
*
* @param {String} retrievedText - pure data form github
*/
function toObject(retrievedText) {
getKeys(storage.ClearURLsData.providers);
createProviders();
}
/**
* Get the hash for the rule file on github.
* Check the hash with the hash form the local file.
* If the hash has changed, then download the new rule file.
* Else do nothing.
*/
function getHash() {
//Get the target hash from github
fetch(storage.hashURL)
.then(function (response) {
const responseTextHash = response.clone().text().then(function (responseTextHash) {
if (response.ok && $.trim(responseTextHash)) {
dataHash = responseTextHash;
if ($.trim(dataHash) !== $.trim(localDataHash)) {
fetchFromURL();
} else {
toObject(storage.ClearURLsData);
storeHashStatus(1);
saveOnDisk(['hashStatus']);
}
} else {
dataHash = false;
}
});
});
}
/*
* ##################################################################
* # Fetch Rules & Exception from URL #
* ##################################################################
*/
function fetchFromURL() {
fetch(storage.ruleURL)
.then(checkResponse);
function checkResponse(response) {
const responseText = response.clone().text().then(function (responseText) {
if (response.ok && $.trim(responseText)) {
const downloadedFileHash = $.sha256(responseText);
if ($.trim(downloadedFileHash) === $.trim(dataHash)) {
storage.ClearURLsData = responseText;
storage.dataHash = downloadedFileHash;
storeHashStatus(2);
} else {
storeHashStatus(3);
}
storage.ClearURLsData = JSON.parse(storage.ClearURLsData);
toObject(storage.ClearURLsData);
saveOnDisk(['ClearURLsData', 'dataHash', 'hashStatus']);
}
});
}
}
// ##################################################################
/*
* ##################################################################
* # Supertyp Provider #
* ##################################################################
*/
/**
* Declare constructor
*
* @param {String} _name Provider name
* @param {boolean} _completeProvider Set URL Pattern as rule
* @param {boolean} _forceRedirection Whether redirects should be enforced via a "tabs.update"
* @param {boolean} _isActive Is the provider active?
*/
function Provider(_name, _completeProvider = false, _forceRedirection = false, _isActive = true) {
let name = _name;
let urlPattern;
let enabled_rules = {};
let disabled_rules = {};
let enabled_exceptions = {};
let disabled_exceptions = {};
let canceling = _completeProvider;
let enabled_redirections = {};
let disabled_redirections = {};
let active = _isActive;
let enabled_rawRules = {};
let disabled_rawRules = {};
let enabled_referralMarketing = {};
let disabled_referralMarketing = {};
if (_completeProvider) {
enabled_rules[".*"] = true;
}
/**
* Returns whether redirects should be enforced via a "tabs.update"
* @return {boolean} whether redirects should be enforced
*/
this.shouldForceRedirect = function () {
return _forceRedirection;
};
/**
* Returns the provider name.
* @return {String}
*/
this.getName = function () {
return name;
};
/**
* Add URL pattern.
*
* @require urlPatterns as RegExp
*/
this.setURLPattern = function (urlPatterns) {
urlPattern = new RegExp(urlPatterns, "i");
};
/**
* Return if the Provider Request is canceled
* @return {Boolean} isCanceled
*/
this.isCaneling = function () {
return canceling;
};
/**
* Check the url is matching the ProviderURL.
*
* @return {boolean} ProviderURL as RegExp
*/
this.matchURL = function (url) {
return urlPattern.test(url) && !(this.matchException(url));
};
/**
* Apply a rule to a given tuple of rule array.
* @param enabledRuleArray array for enabled rules
* @param disabledRulesArray array for disabled rules
* @param {String} rule RegExp as string
* @param {boolean} isActive Is this rule active?
*/
this.applyRule = (enabledRuleArray, disabledRulesArray, rule, isActive = true) => {
if (isActive) {
enabledRuleArray[rule] = true;
if (disabledRulesArray[rule] !== undefined) {
delete disabledRulesArray[rule];
}
} else {
disabledRulesArray[rule] = true;
if (enabledRuleArray[rule] !== undefined) {
delete enabledRuleArray[rule];
}
}
};
/**
* Add a rule to the rule array
* and replace old rule with new rule.
*
* @param {String} rule RegExp as string
* @param {boolean} isActive Is this rule active?
*/
this.addRule = function (rule, isActive = true) {
rule = "([\\/\\?#]|(&|&amp;))+(" + rule + "=[^&]*)";
this.applyRule(enabled_rules, disabled_rules, rule, isActive);
};
/**
* Return all active rules as an array.
*
* @return Array RegExp strings
*/
this.getRules = function () {
if (!storage.referralMarketing) {
return Object.keys(Object.assign(enabled_rules, enabled_referralMarketing));
}
return Object.keys(enabled_rules);
};
/**
* Add a raw rule to the raw rule array
* and replace old raw rule with new raw rule.
*
* @param {String} rule RegExp as string
* @param {boolean} isActive Is this rule active?
*/
this.addRawRule = function (rule, isActive = true) {
this.applyRule(enabled_rawRules, disabled_rawRules, rule, isActive);
};
/**
* Return all active raw rules as an array.
*
* @return Array RegExp strings
*/
this.getRawRules = function () {
return Object.keys(enabled_rawRules);
};
/**
* Add a referral marketing rule to the referral marketing array
* and replace old referral marketing rule with new referral marketing rule.
*
* @param {String} rule RegExp as string
* @param {boolean} isActive Is this rule active?
*/
this.addReferralMarketing = function (rule, isActive = true) {
rule = "([\\/\\?#]|(&|&amp;))+(" + rule + "=[^\\/\\?&]*)";
this.applyRule(enabled_referralMarketing, disabled_referralMarketing, rule, isActive);
};
/**
* Add a exception to the exceptions array
* and replace old with new exception.
*
* @param {String} exception RegExp as string
* @param {Boolean} isActive Is this exception acitve?
*/
this.addException = function (exception, isActive = true) {
if (isActive) {
enabled_exceptions[exception] = true;
if (disabled_exceptions[exception] !== undefined) {
delete disabled_exceptions[exception];
}
} else {
disabled_exceptions[exception] = true;
if (enabled_exceptions[exception] !== undefined) {
delete enabled_exceptions[exception];
}
}
};
/**
* Private helper method to check if the url
* an exception.
*
* @param {String} url RegExp as string
* @return {boolean} if matching? true: false
*/
this.matchException = function (url) {
let result = false;
//Add the site blocked alert to every exception
if (url === siteBlockedAlert) return true;
for (const exception in enabled_exceptions) {
if (result) break;
let exception_regex = new RegExp(exception, "i");
result = exception_regex.test(url);
}
return result;
};
/**
* Add a redirection to the redirections array
* and replace old with new redirection.
*
* @param {String} redirection RegExp as string
* @param {Boolean} isActive Is this redirection active?
*/
this.addRedirection = function (redirection, isActive = true) {
if (isActive) {
enabled_redirections[redirection] = true;
if (disabled_redirections[redirection] !== undefined) {
delete disabled_redirections[redirection];
}
} else {
disabled_redirections[redirection] = true;
if (enabled_redirections[redirection] !== undefined) {
delete enabled_redirections[redirection];
}
}
};
/**
* Return all redirection.
*
* @return url
*/
this.getRedirection = function (url) {
let re = null;
for (const redirection in enabled_redirections) {
let result = (url.match(new RegExp(redirection, "i")));
if (result && result.length > 0 && redirection) {
re = (new RegExp(redirection, "i")).exec(url)[1];
break;
}
}
return re;
};
}
// ##################################################################
/**
* Function which called from the webRequest to
* remove the tracking fields from the url.
*
* @param {webRequest} request webRequest-Object
* @return {Array} redirectUrl or none
*/
function clearUrl(request) {
const URLbeforeReplaceCount = countFields(request.url);
//Add Fields form Request to global url counter
increaseGlobalURLCounter(URLbeforeReplaceCount);
if (storage.globalStatus) {
let result = {
"changes": false,
"url": "",
"redirect": false,
"cancel": false
};
if (storage.pingBlocking && storage.pingRequestTypes.includes(request.type)) {
pushToLog(request.url, request.url, translate('log_ping_blocked'));
increaseBadged();
return {cancel: true};
}
/*
* Call for every provider the removeFieldsFormURL method.
*/
for (let i = 0; i < providers.length; i++) {
if (providers[i].matchURL(request.url)) {
result = removeFieldsFormURL(providers[i], request.url);
}
/*
* Expand urls and bypass tracking.
* Cancel the active request.
*/
if (result.redirect) {
if (providers[i].shouldForceRedirect() &&
request.type === 'main_frame') {
browser.tabs.update(request.tabId, {url: result.url});
return {cancel: true};
}
return {
redirectUrl: result.url
};
}
/*
* Cancel the Request and redirect to the site blocked alert page,
* to inform the user about the full url blocking.
*/
if (result.cancel) {
if (request.type === 'main_frame') {
const blockingPage = browser.extension.getURL("html/siteBlockedAlert.html?source=" + encodeURIComponent(request.url));
browser.tabs.update(request.tabId, {url: blockingPage});
return {cancel: true};
} else {
return {
redirectUrl: siteBlockedAlert
};
}
}
/*
* Ensure that the function go not into
* a loop.
*/
if (result.changes) {
return {
redirectUrl: result.url
};
}
}
}
// Default case
return {};
}
/**
* Call loadOldDataFromStore, getHash, counter, status and log functions
*/
loadOldDataFromStore();
getHash();
setBadgedStatus();
/**
* Call by each tab is updated.
* And if url has changed.
*/
function handleUpdated(tabId, changeInfo, tabInfo) {
if (changeInfo.url) {
delete badges[tabId];
}
currentURL = tabInfo.url;
}
/**
* Call by each tab is updated.
*/
browser.tabs.onUpdated.addListener(handleUpdated);
/**
* Call by each tab change to set the actual tab id
*/
function handleActivated(activeInfo) {
tabid = activeInfo.tabId;
browser.tabs.get(tabid).then(function (tab) {
if (!browser.runtime.lastError) { // https://gitlab.com/KevinRoebert/ClearUrls/issues/346
currentURL = tab.url;
}
});
}
/**
* Call by each tab change.
*/
browser.tabs.onActivated.addListener(handleActivated);
/**
* Check the request.
*/
function promise(requestDetails) {
if (isDataURL(requestDetails)) {
return {};
} else {
return clearUrl(requestDetails);
}
}
/**
* To prevent long loading on data urls
* we will check here for data urls.
*
* @type {requestDetails}
* @return {boolean}
*/
function isDataURL(requestDetails) {
const s = requestDetails.url;
return s.substring(0, 4) === "data";
}
/**
* Call by each Request and checking the url.
*
* @type {Array}
*/
browser.webRequest.onBeforeRequest.addListener(
promise,
{urls: ["<all_urls>"], types: getData("types").concat(getData("pingRequestTypes"))},
["blocking"]
);
}
/**
* Function to log all activities from ClearUrls.
* Only logging when activated.
* The log is only temporary saved in the cache and will
* permanently saved with the saveLogOnClose function.
*
* @param beforeProcessing the url before the clear process
* @param afterProcessing the url after the clear process
* @param rule the rule that triggered the process
*/
function pushToLog(beforeProcessing, afterProcessing, rule) {
const limit = storage.logLimit;
if (storage.loggingStatus && limit !== 0) {
if (limit > 0 && !isNaN(limit)) {
while (storage.log.log.length >= limit) {
storage.log.log.shift();
}
}
storage.log.log.push(
{
"before": beforeProcessing,
"after": afterProcessing,
"rule": rule,
"timestamp": Date.now()
}
);
deferSaveOnDisk('log');
}
}
/**
* Increases the badged by one.
*/
function increaseBadged(quiet = false) {
if (badges[tabid] == null) badges[tabid] = 0;
if (!quiet) increaseURLCounter();
checkOSAndroid().then((res) => {
if (!res) {
if (storage.badgedStatus && !quiet) {
browser.browserAction.setBadgeText({text: (++badges[tabid]).toString(), tabId: tabid});
} else {
browser.browserAction.setBadgeText({text: "", tabId: tabid});
}
}
});
}

View File

@@ -1,80 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
var cleanedURLs = [];
var i = 0;
var length = 0;
/**
* Load only when document is ready
*/
$(document).ready(function(){
setText();
$('#cleaning_tool_btn').on("click", cleanURLs);
});
/**
* This function cleans all URLs line by line in the textarea.
*/
function cleanURLs() {
const cleanTArea = $('#cleanURLs');
const dirtyTArea = $('#dirtyURLs');
const urls = dirtyTArea.val().split('\n');
cleanedURLs = [];
length = urls.length;
for(i=0; i < length; i++) {
browser.runtime.sendMessage({
function: "pureCleaning",
params: [urls[i]]
}).then((data) => {
cleanedURLs.push(data.response);
if(i >= length-1) {
cleanTArea.val(cleanedURLs.join('\n'));
}
}, handleError);
}
}
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
*/
function translate(string)
{
return browser.i18n.getMessage(string);
}
/**
* Set the text for the UI.
*/
function setText()
{
document.title = translate('cleaning_tool_page_title');
$('#page_title').text(translate('cleaning_tool_page_title'));
$('#cleaning_tool_description').text(translate('cleaning_tool_description'));
$('#cleaning_tool_btn').text(translate('cleaning_tool_btn'));
$('#cleaning_tool_dirty_urls_label').text(translate('cleaning_tool_dirty_urls_label'));
$('#cleaning_tool_clean_urls_label').text(translate('cleaning_tool_clean_urls_label'));
}
function handleError(error) {
console.log(`Error: ${error}`);
}

View File

@@ -1,57 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for context menu cleaning functions
* and based on: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
*/
function contextMenuStart() {
if(storage.contextMenuEnabled) {
browser.contextMenus.create({
id: "copy-link-to-clipboard",
title: translate("clipboard_copy_link"),
contexts: ["link"]
});
browser.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === "copy-link-to-clipboard") {
const url = pureCleaning(info.linkUrl);
const code = "copyToClipboard(" +
JSON.stringify(url)+");";
browser.tabs.executeScript({
code: "typeof copyToClipboard === 'function';",
}).then((results) => {
if (!results || results[0] !== true) {
return browser.tabs.executeScript(tab.id, {
file: "/external_js/clipboard-helper.js",
});
}
}).then(() => {
return browser.tabs.executeScript(tab.id, {
code,
});
}).catch((error) => {
console.error("Failed to copy text: " + error);
});
}
});
}
}

View File

@@ -1,67 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Based on:
* Remove Google Redirection
* https://github.com/kodango/Remove-Google-Redirection/blob/master/extension/chrome/remove-google-redirection.user.js
* Copyright (c) 2017 kodango
* MIT License: https://github.com/kodango/Remove-Google-Redirection/blob/master/LICENSE
*/
(function (window) {
"use strict";
function injectFunction() {
let ele = document.createElement('script');
let s = document.getElementsByTagName('script')[0];
ele.type = 'text/javascript';
ele.textContent = "Object.defineProperty(window, 'rwt', {" +
" value: function() { return false; }," +
" writable: false," +
" configurable: false" +
"});";
s.parentNode.insertBefore(ele, s);
}
/*
* The main entry
*/
function main()
{
injectFunction();
document.addEventListener('mouseover', function (event) {
let a = event.target, depth = 1;
while (a && a.tagName !== 'A' && depth-- > 0) {
a = a.parentNode;
}
if (a && a.tagName === 'A') {
try {
a.removeAttribute('data-cthref');
delete a.dataset.cthref;
} catch(e) {
console.log(e);
}
}
}, true);
}
main();
})(window);

View File

@@ -1,55 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for listen on history changes.
* This technique is often used to inject tracking code into the location bar,
* because all feature events will use the updated URL.
*/
function historyListenerStart() {
if(storage.historyListenerEnabled) {
browser.webNavigation.onHistoryStateUpdated.addListener(historyCleaner);
}
}
/**
* Function that is triggered on history changes. Injects script into page
* to clean links that were pushed to the history stack with the
* history.replaceState method.
* @param {state object} details The state object is a JavaScript object
* which is associated with the new history entry created by replaceState()
*/
function historyCleaner(details) {
if(storage.globalStatus) {
const urlBefore = details.url;
const urlAfter = pureCleaning(details.url);
if(urlBefore !== urlAfter) {
browser.tabs.executeScript(details.tabId, {
frameId: details.frameId,
code: 'history.replaceState({state: "cleaned_history"},"",'+JSON.stringify(urlAfter)+');'
}).then(() => {}, onError);
}
}
}
function onError(error) {
console.log(`[ClearURLs] Error: ${error}`);
}

View File

@@ -1,174 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/**
* Get the log and display the data as table.
*/
var log = {};
/**
* Reset the global log
*/
function resetGlobalLog(){
let obj = {"log": []};
browser.runtime.sendMessage({
function: "setData",
params: ['log', JSON.stringify(obj)]
});
location.reload();
}
/**
* Get the log and display to the user
*/
function getLog()
{
browser.runtime.sendMessage({
function: "getData",
params: ['log']
}).then((data) => {
log = data.response;
// Sort the log | issue #70
log.log.sort(function(a,b) {
return b.timestamp - a.timestamp;
});
const length = Object.keys(log.log).length;
let row;
if(length !== 0)
{
for(let i=0; i<length;i++)
{
row = "<tr>" +
"<td>"+log.log[i].before+"</td>" +
"<td>"+log.log[i].after+"</td>" +
"<td>"+log.log[i].rule+"</td>" +
"<td>"+toDate(log.log[i].timestamp)+"</td>";
$('#tbody').append(row);
}
}
$('#logTable').DataTable({
"pageLength": 10,
"language": {
"url": getDataTableTranslation()
}
} ).order([3, 'desc']).draw();
});
}
/**
* Get the translation file for the DataTable
*/
function getDataTableTranslation()
{
let lang = browser.i18n.getUILanguage();
lang = lang.substring(0,2);
return browser.extension.getURL('./external_js/dataTables/i18n/' + lang + '.lang');
}
/**
* Convert timestamp to date
*/
function toDate(time)
{
return new Date(time).toLocaleString();
}
/**
* This function export the global log as json file.
*/
function exportGlobalLog() {
browser.runtime.sendMessage({
function: "getData",
params: ['log']
}).then((data) => {
let blob = new Blob([JSON.stringify(data.response)], {type: 'application/json'});
browser.downloads.download({
'url': URL.createObjectURL(blob),
'filename': 'ClearURLsLogExport.json',
'saveAs': true
});
});
}
/**
* This function imports an exported global log and overwrites the old one.
*/
function importGlobalLog(evt) {
let file = evt.target.files[0];
let fileReader = new FileReader();
fileReader.onload = function(e) {
browser.runtime.sendMessage({
function: "setData",
params: ["log", e.target.result]
}).then(() => {
location.reload();
}, handleError);
};
fileReader.readAsText(file);
}
/**
* Load only when document is ready
*/
$(document).ready(function(){
setText();
getLog();
$('#reset_log_btn').on("click", resetGlobalLog);
$('#export_log_btn').on("click", exportGlobalLog);
$('#importLog').on("change", importGlobalLog);
});
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
*/
function translate(string)
{
return browser.i18n.getMessage(string);
}
/**
* Set the text for the UI.
*/
function setText()
{
document.title = translate('log_html_page_title');
$('#page_title').text(translate('log_html_page_title'));
$('#reset_log_btn').text(translate('log_html_reset_button'))
.prop('title', translate('log_html_reset_button_title'));
$('#head_1').text(translate('log_html_table_head_1'));
$('#head_2').text(translate('log_html_table_head_2'));
$('#head_3').text(translate('log_html_table_head_3'));
$('#head_4').text(translate('log_html_table_head_4'));
$('#export_log_btn_text').text(translate('log_html_export_button'));
$('#export_log_btn').prop('title', translate('log_html_export_button_title'));
$('#import_log_btn_text').text(translate('log_html_import_button'));
$('#importLog').prop('title', translate('log_html_import_button_title'));
}
function handleError(error) {
console.log(`Error: ${error}`);
}

View File

@@ -1,42 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for the communication between background and content_scripts.
*/
/**
* [handleMessage description]
* @param request The message itself. This is a JSON-ifiable object.
* @param sender A runtime.MessageSender object representing the sender of the message.
* @param sendResponse A function to call, at most once, to send a response to the message. The function takes a single argument, which may be any JSON-ifiable object. This argument is passed back to the message sender.
*/
function handleMessage(request, sender, sendResponse)
{
let fn = window[request.function];
if(typeof fn === "function")
{
let response = fn.apply(null, request.params);
return Promise.resolve({response});
}
}
browser.runtime.onMessage.addListener(handleMessage);

View File

@@ -1,281 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
var element = $("#statistics_value");
var elGlobalPercentage = $("#statistics_value_global_percentage");
var elProgressbar_blocked = $('#progress_blocked');
var elProgressbar_non_blocked = $('#progress_non_blocked');
var elTotal = $('#statistics_total_elements');
var globalPercentage = 0;
var globalCounter;
var globalurlcounter;
var globalStatus;
var badgedStatus;
var hashStatus;
var loggingStatus;
var statisticsStatus;
var currentURL;
/**
* Initialize the UI.
*
*/
function init()
{
setSwitchButton("globalStatus", "globalStatus");
setSwitchButton("tabcounter", "badgedStatus");
setSwitchButton("logging", "loggingStatus");
setSwitchButton("statistics", "statisticsStatus");
setHashStatus();
changeStatistics();
}
/**
* Get the globalCounter and globalurlcounter value from the storage
*/
function changeStatistics()
{
globalPercentage = ((globalCounter/globalurlcounter)*100).toFixed(3);
if(isNaN(Number(globalPercentage))) globalPercentage = 0;
element.text(globalCounter.toLocaleString());
elGlobalPercentage.text(globalPercentage+"%");
elProgressbar_blocked.css('width', globalPercentage+'%');
elProgressbar_non_blocked.css('width', (100-globalPercentage)+'%');
elTotal.text(globalurlcounter.toLocaleString());
}
/**
* Set the value for the hashStatus on startUp.
*/
function setHashStatus()
{
let element = $('#hashStatus');
if(hashStatus)
{
element.text(translate(hashStatus));
}
else {
element.text(translate('hash_status_code_5'));
}
}
/**
* Change the value of a switch button.
* @param {string} id HTML id
* @param {string} storageID storage internal id
*/
function changeSwitchButton(id, storageID)
{
let element = $('#'+id);
changeVisibility(id, storageID);
element.on('change', function(){
browser.runtime.sendMessage({
function: "setData",
params: [storageID, element.is(':checked')]
}).then((data) => {
if(storageID === "globalStatus"){
browser.runtime.sendMessage({
function: "changeIcon",
params: []
});
}
changeVisibility(id, storageID);
browser.runtime.sendMessage({
function: "saveOnExit",
params: []
});
});
});
}
/**
* Change the visibility of sections.
*/
function changeVisibility(id, storageID)
{
let element;
switch(storageID)
{
case "loggingStatus":
element = $('#log_section');
break;
case "statisticsStatus":
element = $('#statistic_section');
break;
default:
element = "undefine";
}
if(element !== "undefine")
{
if($('#'+id).is(':checked'))
{
element.css('display', '');
element.css('display', '');
}
else {
element.css('display', 'none');
element.css('display', 'none');
}
}
}
/**
* Set the value of a switch button.
* @param {string} id HTML id
* @param {string} varname js internal variable name
*/
function setSwitchButton(id, varname)
{
let element = $('#'+id);
element.prop('checked', this[varname]);
}
/**
* Reset the global statistic
*/
function resetGlobalCounter(){
browser.runtime.sendMessage({
function: "setData",
params: ['globalCounter', 0]
});
browser.runtime.sendMessage({
function: "setData",
params: ['globalurlcounter', 0]
});
browser.runtime.sendMessage({
function: "saveOnExit",
params: []
});
globalCounter = 0;
globalurlcounter = 0;
changeStatistics();
}
$(document).ready(function(){
loadData("globalCounter")
.then(() => loadData("globalurlcounter"))
.then(() => loadData("globalStatus"))
.then(() => loadData("badgedStatus"))
.then(() => loadData("hashStatus"))
.then(() => loadData("loggingStatus"))
.then(() => loadData("statisticsStatus"))
.then(() => loadData("getCurrentURL", "currentURL"))
.then(() => {
init();
$('#reset_counter_btn').on("click", resetGlobalCounter);
changeSwitchButton("globalStatus", "globalStatus");
changeSwitchButton("tabcounter", "badgedStatus");
changeSwitchButton("logging", "loggingStatus");
changeSwitchButton("statistics", "statisticsStatus");
$('#loggingPage').attr('href', browser.extension.getURL('./html/log.html'));
$('#settings').attr('href', browser.extension.getURL('./html/settings.html'));
$('#cleaning_tools').attr('href', browser.extension.getURL('./html/cleaningTool.html'));
setText();
});
});
/**
* Set the text for the UI.
*/
function setText()
{
injectText('loggingPage','popup_html_log_head');
injectText('reset_counter_btn','popup_html_statistics_reset_button');
injectText('rules_status_head','popup_html_rules_status_head');
injectText('statistics_percentage','popup_html_statistics_percentage');
injectText('statistics_blocked','popup_html_statistics_blocked');
injectText('statistics_elements','popup_html_statistics_elements');
injectText('statistics_head','popup_html_statistics_head');
injectText('configs_switch_badges','popup_html_configs_switch_badges');
injectText('configs_switch_log','popup_html_configs_switch_log');
injectText('configs_switch_filter','popup_html_configs_switch_filter');
injectText('configs_head','popup_html_configs_head');
injectText('configs_switch_statistics','configs_switch_statistics');
$('#donate').prop('title', translate('donate_button'));
}
/**
* Helper function to inject the translated text and tooltip.
*
* @param {string} id ID of the HTML element
* @param {string} attribute Name of the attribute used for localization
* @param {string} tooltip
*/
function injectText(id, attribute, tooltip = "")
{
let object = $('#'+id);
object.text(translate(attribute));
/*
This function will throw an error if no translation
is found for the tooltip. This is a planned error.
*/
tooltip = translate(attribute+"_title");
if(tooltip !== "")
{
object.prop('title', tooltip);
}
}
/**
* Loads data from storage and saves into local variable.
*
* @param name data name
* @param varName variable name
* @returns {Promise<data>} requested data
*/
async function loadData(name, varName=name) {
return new Promise((resolve, reject) => {
browser.runtime.sendMessage({
function: "getData",
params: [name]
}).then(data => {
this[varName] = data.response;
resolve(data);
}, handleError);
});
}
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
*/
function translate(string)
{
return browser.i18n.getMessage(string);
}
function handleError(error) {
console.log(`Error: ${error}`);
}

View File

@@ -1,58 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/**
* Cleans given links. Also do automatic redirection.
*
* @param {String} url url as string
* @param {boolean} quiet if the action should be displayed in log and statistics
* @return {String} redirectUrl or none
*/
function pureCleaning(url, quiet = false) {
let cleanURL = url;
const URLbeforeReplaceCount = countFields(url);
if(!quiet) {
//Add Fields form Request to global url counter
increaseGlobalURLCounter(URLbeforeReplaceCount);
}
for (let i = 0; i < providers.length; i++) {
let result = {
"changes": false,
"url": "",
"redirect": false,
"cancel": false
};
if(providers[i].matchURL(cleanURL))
{
result = removeFieldsFormURL(providers[i], cleanURL, quiet);
cleanURL = result.url;
}
if(result.redirect)
{
return result.url;
}
}
return cleanURL;
}

View File

@@ -1,310 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
var settings = [];
getData();
/**
* Load only when document is ready
*/
$(document).ready(function(){
setText();
$("#badged-color-picker").colorpicker({
format: "hex"
});
$('#reset_settings_btn').on("click", reset);
$('#export_settings_btn').on("click", exportSettings);
$('#importSettings').on("change", importSettings);
$('#save_settings_btn').on("click", save);
});
/**
* Reset everything.
* Set everthing to the default values.
*/
function reset()
{
browser.runtime.sendMessage({
function: "initSettings",
params: []
}).then(handleResponse, handleError);
browser.runtime.sendMessage({
function: "saveOnExit",
params: []
}).then(handleResponse, handleError);
browser.runtime.sendMessage({
function: "reload",
params: []
}).then(handleResponse, handleError);
}
/**
* Saves the settings.
*/
function save()
{
saveData("badged_color", $('input[name=badged_color]').val())
.then(() => saveData("ruleURL", $('input[name=ruleURL]').val()))
.then(() => saveData("hashURL", $('input[name=hashURL]').val()))
.then(() => saveData("types", $('input[name=types]').val()))
.then(() => saveData("logLimit", $('input[name=logLimit]').val()))
.then(() => browser.runtime.sendMessage({
function: "setBadgedStatus",
params: []
}), handleError)
.then(() => browser.runtime.sendMessage({
function: "saveOnExit",
params: []
}), handleError)
.then(() => browser.runtime.sendMessage({
function: "reload",
params: []
}), handleError);
}
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
* @param {string[]} placeholders Array of placeholders
*/
function translate(string, ...placeholders)
{
return browser.i18n.getMessage(string, placeholders);
}
/**
* Get the data.
*/
function getData()
{
loadData("badged_color")
.then(() => loadData("ruleURL"))
.then(() => loadData("hashURL"))
.then(() => loadData("types"))
.then(() => loadData("logLimit"))
.then(logData => {
if(logData.response === undefined || logData.response === -1) {
$('#logLimit_label').text(translate('setting_log_limit_label', "∞"));
} else {
$('#logLimit_label').text(translate('setting_log_limit_label', logData.response));
}
});
loadData("contextMenuEnabled")
.then(() => loadData("historyListenerEnabled"))
.then(() => loadData("localHostsSkipping"))
.then(() => loadData("referralMarketing"))
.then(() => loadData("domainBlocking"))
.then(() => loadData("pingBlocking"))
.then(() => {
changeSwitchButton("localHostsSkipping", "localHostsSkipping");
changeSwitchButton("historyListenerEnabled", "historyListenerEnabled");
changeSwitchButton("contextMenuEnabled", "contextMenuEnabled");
changeSwitchButton("referralMarketing", "referralMarketing");
changeSwitchButton("domainBlocking", "domainBlocking");
changeSwitchButton("pingBlocking", "pingBlocking");
});
}
/**
* Loads data from storage and saves into local variable.
*
* @param name data/variable name
* @returns {Promise<data>} requested data
*/
async function loadData(name) {
return new Promise((resolve, reject) => {
browser.runtime.sendMessage({
function: "getData",
params: [name]
}).then(data => {
settings[name] = data.response;
$('input[name='+name+']').val(data.response);
resolve(data);
}, handleError);
});
}
/**
* Saves data to storage.
*
* @param key key of the data that should be saved
* @param data data that should be saved
* @returns {Promise<message>} message from background script
*/
async function saveData(key, data) {
return new Promise((resolve, reject) => {
browser.runtime.sendMessage({
function: "setData",
params: [key, data]
}).then(message => {
handleResponse(message);
resolve(message);
}, handleError);
});
}
/**
* Set the text for the UI.
*/
function setText()
{
document.title = translate('settings_html_page_title');
$('#page_title').text(translate('settings_html_page_title'));
$('#badged_color_label').text(translate('badged_color_label'));
$('#reset_settings_btn').text(translate('setting_html_reset_button'))
.prop('title', translate('setting_html_reset_button_title'));
$('#rule_url_label').text(translate('setting_rule_url_label'));
$('#hash_url_label').text(translate('setting_hash_url_label'));
$('#types_label').html(translate('setting_types_label'));
$('#save_settings_btn').text(translate('settings_html_save_button'))
.prop('title', translate('settings_html_save_button_title'));
injectText("context_menu_enabled", "context_menu_enabled");
$('#history_listener_enabled').html(translate('history_listener_enabled'));
injectText("local_hosts_skipping", "local_hosts_skipping");
$('#export_settings_btn_text').text(translate('setting_html_export_button'));
$('#export_settings_btn').prop('title', translate('setting_html_export_button_title'));
$('#import_settings_btn_text').text(translate('setting_html_import_button'));
$('#importSettings').prop('title', translate('setting_html_import_button_title'));
injectText("referral_marketing_enabled", "referral_marketing_enabled");
injectText("domain_blocking_enabled", "domain_blocking_enabled");
$('#ping_blocking_enabled').html(translate('ping_blocking_enabled'))
.prop('title', translate('ping_blocking_enabled_title'));
}
/**
* This function exports all ClearURLs settings with statistics and rules.
*/
function exportSettings() {
browser.runtime.sendMessage({
function: "storageAsJSON",
params: []
}).then((data) => {
let blob = new Blob([JSON.stringify(data.response)], {type: 'application/json'});
browser.downloads.download({
'url': URL.createObjectURL(blob),
'filename': 'ClearURLs.conf',
'saveAs': true
});
});
}
/**
* This function imports an exported ClearURLs setting and overwrites the old one.
*/
function importSettings(evt) {
let file = evt.target.files[0];
let fileReader = new FileReader();
fileReader.onload = function(e) {
let data = JSON.parse(e.target.result);
const length = Object.keys(data).length;
let i=0;
Object.entries(data).forEach(([key, value]) => {
browser.runtime.sendMessage({
function: "setData",
params: [key, value]
}).then(() => {
i++;
if(i === length) {
location.reload();
}
}, handleError);
});
};
fileReader.readAsText(file);
}
function handleResponse(message) {
console.log(`Message from the background script: ${message.response}`);
}
function handleError(error) {
console.log(`Error: ${error}`);
}
/**
* Change the value of a switch button.
* @param {string} id HTML id
* @param {string} storageID storage internal id
*/
function changeSwitchButton(id, storageID)
{
let element = $('#'+id);
element.on('change', function(){
browser.runtime.sendMessage({
function: "setData",
params: [storageID, element.is(':checked')]
}).then((data) => {
if(storageID === "globalStatus"){
browser.runtime.sendMessage({
function: "changeIcon",
params: []
});
}
browser.runtime.sendMessage({
function: "saveOnExit",
params: []
});
});
});
setSwitchButton(id, storageID);
}
/**
* Helper function to inject the translated text and tooltip.
*
* @param {string} id ID of the HTML element
* @param {string} attribute Name of the attribute used for localization
* @param {boolean} tooltip
*/
function injectText(id, attribute, tooltip = "")
{
let object = $('#'+id);
object.text(translate(attribute));
/*
This function will throw an error if no translation
is found for the tooltip. This is a planned error.
*/
tooltip = translate(attribute+"_title");
if(tooltip !== "")
{
object.prop('title', tooltip);
}
}
/**
* Set the value of a switch button.
* @param {string} id HTML id
* @param {string} varname js internal variable name
*/
function setSwitchButton(id, varname)
{
let element = $('#'+id);
element.prop('checked', settings[varname]);
}

View File

@@ -1,51 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for the blocked alert page.
*/
/**
* Set the text for the UI.
*/
function setText()
{
document.title = translate('blocked_html_title');
$('#title').html(translate('blocked_html_title'));
$('#body').html(translate('blocked_html_body'));
$('#page').text(translate('blocked_html_button'));
}
$(document).ready(function(){
setText();
let source = new URLSearchParams(window.location.search).get("source");
$('#page').attr('href', decodeURIComponent(source));
});
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
*/
function translate(string)
{
return browser.i18n.getMessage(string);
}

View File

@@ -1,287 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for the storage.
*/
var storage = [];
var hasPendingSaves = false;
var pendingSaves = new Set();
/**
* Writes the storage variable to the disk.
*/
function saveOnExit() {
saveOnDisk(Object.keys(storage));
}
/**
* Returns the storage as JSON.
*/
function storageAsJSON() {
let json = {};
Object.entries(storage).forEach(([key, value]) => {
json[key] = storageDataAsString(key);
});
return json;
}
/**
* Converts a given storage data to its string representation.
* @param key key of the storage data
* @returns {string} string representation
*/
function storageDataAsString(key) {
let value = storage[key];
switch (key) {
case "ClearURLsData":
case "log":
return JSON.stringify(value);
case "types":
return value.toString();
default:
return value;
}
}
/**
* Save multiple keys on the disk.
* @param {String[]} keys
*/
function saveOnDisk(keys) {
let json = {};
keys.forEach(function (key) {
json[key] = storageDataAsString(key);
});
console.log(translate('core_save_on_disk'));
browser.storage.local.set(json);
}
/**
* Schedule to save a key to disk in 30 seconds.
* @param {String} key
*/
function deferSaveOnDisk(key) {
if (hasPendingSaves) {
pendingSaves.add(key);
return;
}
setTimeout(function () {
saveOnDisk(Array.from(pendingSaves));
pendingSaves.clear();
hasPendingSaves = false;
}, 30000);
hasPendingSaves = true;
}
/**
* Start sequence for ClearURLs.
*/
function genesis() {
browser.storage.local.get(null).then((items) => {
initStorage(items);
// Start the clearurls.js
start();
//Set correct icon on startup
changeIcon();
// Start the context_menu
contextMenuStart();
// Start history listener
historyListenerStart();
}, error);
}
/**
* Return the value under the key.
* @param {String} key
* @return {Object}
*/
function getData(key) {
return storage[key];
}
/**
* Return the entire storage object.
* @return {Object}
*/
function getEntireData() {
return storage;
}
/**
* Save the value under the key on the RAM.
*
* Note: To store the data on the hard disk, one of
* deferSaveOnDisk(), saveOnDisk(), or saveOnExit()
* must be called.
* @param {String} key
* @param {Object} value
*/
function setData(key, value) {
switch (key) {
case "ClearURLsData":
case "log":
storage[key] = JSON.parse(value);
break;
case "hashURL":
case "ruleURL":
storage[key] = replaceOldURLs(value);
break;
case "types":
storage[key] = value.split(',');
break;
case "logLimit":
storage[key] = Number(value);
break;
default:
storage[key] = value;
}
}
/**
* Write error on console.
*/
function error(e) {
console.log(translate('core_error'));
console.error(e);
}
/**
* Set default values, if the storage is empty.
* @param {Object} items
*/
function initStorage(items) {
initSettings();
if (!isEmpty(items)) {
Object.entries(items).forEach(([key, value]) => {
setData(key, value);
});
}
}
/**
* Set default values for the settings.
*/
function initSettings() {
storage.ClearURLsData = [];
storage.dataHash = "";
storage.badgedStatus = true;
storage.globalStatus = true;
storage.globalurlcounter = 0;
storage.globalCounter = 0;
storage.hashStatus = "error";
storage.loggingStatus = false;
storage.log = {"log": []};
storage.statisticsStatus = true;
storage.badged_color = "#ffa500";
storage.hashURL = "https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash";
storage.ruleURL = "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
storage.contextMenuEnabled = true;
storage.historyListenerEnabled = true;
storage.localHostsSkipping = true;
storage.referralMarketing = false;
storage.logLimit = -1;
storage.domainBlocking = true;
storage.pingBlocking = true;
if (getBrowser() === "Firefox") {
storage.types = ["font", "image", "imageset", "main_frame", "media", "object", "object_subrequest", "other", "script", "stylesheet", "sub_frame", "websocket", "xbl", "xml_dtd", "xmlhttprequest", "xslt"];
storage.pingRequestTypes = ["ping", "beacon"];
} else if (getBrowser() === "Chrome") {
storage.types = ["main_frame", "sub_frame", "stylesheet", "script", "image", "font", "object", "xmlhttprequest", "ping", "csp_report", "media", "websocket", "other"];
storage.pingRequestTypes = ["ping"];
}
}
/**
* Replace the old URLs with the
* new GitLab URLs.
*/
function replaceOldURLs(url) {
switch (url) {
case "https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/rules.hash?flush_cache=true":
return "https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash";
case "https://raw.githubusercontent.com/KevinRoebert/ClearUrls/master/data/data.json?flush_cache=true":
return "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/rules.hash":
return "https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.json":
return "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.min.hash?job=hash%20rules":
return "https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.min.json":
return "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/raw/master/data/data.minify.json":
return "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/data.minify.json?job=hash%20rules":
return "https://kevinroebert.gitlab.io/ClearUrls/data/data.minify.json";
case "https://gitlab.com/KevinRoebert/ClearUrls/-/jobs/artifacts/master/raw/rules.minify.hash?job=hash%20rules":
return "https://kevinroebert.gitlab.io/ClearUrls/data/rules.minify.hash";
default:
return url;
}
}
/**
* Load local saved data, if the browser is offline or
* some other network trouble.
*/
function loadOldDataFromStore() {
localDataHash = storage.dataHash;
}
/**
* Save the hash status to the local storage (RAM).
* The status can have the following values:
* 1 "up to date"
* 2 "updated"
* 3 "update available"
* @param status_code the number for the status
*/
function storeHashStatus(status_code) {
switch (status_code) {
case 1:
status_code = "hash_status_code_1";
break;
case 2:
status_code = "hash_status_code_2";
break;
case 3:
status_code = "hash_status_code_3";
break;
default:
status_code = "hash_status_code_4";
}
storage.hashStatus = status_code;
}
// Start storage and ClearURLs
genesis();

View File

@@ -1,304 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible for some tools.
*/
/*
* To support Waterfox.
*/
Array.prototype.rmEmpty = function () {
return this.filter(v => v);
};
/*
* To support Waterfox.
*/
Array.prototype.flatten = function () {
return this.reduce((a, b) => a.concat(b), []);
};
/**
* Check if an object is empty.
* @param {Object} obj
* @return {Boolean}
*/
function isEmpty(obj) {
return (Object.getOwnPropertyNames(obj).length === 0);
}
/**
* Translate a string with the i18n API.
*
* @param {string} string Name of the attribute used for localization
*/
function translate(string) {
return browser.i18n.getMessage(string);
}
/**
* Reloads the extension.
*/
function reload() {
browser.runtime.reload();
}
/**
* Check if it is an android device.
* @return bool
*/
async function checkOSAndroid() {
if (os === undefined || os === null || os === "") {
await chrome.runtime.getPlatformInfo(function (info) {
os = info.os;
});
}
return os === "android";
}
/**
* Extract the host without port from an url.
* @param {String} url URL as String
* @return {String} host as string
*/
function extractHost(url) {
let parsed_url = new URL(url);
return parsed_url.hostname;
}
/**
* Returns true if the url has a local host.
* @param {String} url URL as String
* @return {boolean}
*/
function checkLocalURL(url) {
let host = extractHost(url);
return ipRangeCheck(host, ["10.0.0.0/8", "172.16.0.0/12",
"192.168.0.0/16", "100.64.0.0/10",
"169.254.0.0/16", "127.0.0.1"]) ||
host === 'localhost';
}
/**
* Return the number of parameters query strings.
* @param {String} url URL as String
* @return {int} Number of Parameters
*/
function countFields(url) {
return extractFileds(url).length;
}
/**
* Returns true if fields exists.
* @param {String} url URL as String
* @return {boolean}
*/
function existsFields(url) {
let matches = (url.match(/\?.+/i) || []);
let count = matches.length;
return (count > 0);
}
/**
* Extract the fields from an url.
* @param {String} url URL as String
* @return {Array} Fields as array
*/
function extractFileds(url) {
if (existsFields(url)) {
let fields = url.replace(new RegExp(".*?\\?", "i"), "");
if (existsFragments(url)) {
fields = fields.replace(new RegExp("#.*", "i"), "");
}
return (fields.match(/[^\/|\?|&]+=?[^&]*/gi) || []);
}
return [];
}
/**
* Return the number of fragments query strings.
* @param {String} url URL as String
* @return {int} Number of fragments
*/
function countFragments(url) {
return extractFragments(url).length;
}
/**
* Extract the fragments from an url.
* @param {String} url URL as String
* @return {Array} fragments as array
*/
function extractFragments(url) {
if (existsFragments(url)) {
let fragments = url.replace(new RegExp(".*?#", "i"), "");
return (fragments.match(/[^&]+=?[^&]*/gi) || []);
}
return [];
}
/**
* Returns true if fragments exists.
* @param {String} url URL as String
* @return {boolean}
*/
function existsFragments(url) {
let matches = (url.match(/\#.+/i) || []);
let count = matches.length;
return (count > 0);
}
/**
* Load local saved data, if the browser is offline or
* some other network trouble.
*/
function loadOldDataFromStore() {
localDataHash = storage.dataHash;
}
/**
* Save the hash status to the local storage (RAM).
* The status can have the following values:
* 1 "up to date"
* 2 "updated"
* 3 "update available"
* @param status_code the number for the status
*/
function storeHashStatus(status_code) {
switch (status_code) {
case 1:
status_code = "hash_status_code_1";
break;
case 2:
status_code = "hash_status_code_2";
break;
case 3:
status_code = "hash_status_code_3";
break;
default:
status_code = "hash_status_code_4";
}
storage.hashStatus = status_code;
}
/**
* Increase by {number} the GlobalURLCounter
* @param {int} number
*/
function increaseGlobalURLCounter(number) {
if (storage.statisticsStatus) {
storage.globalurlcounter += number;
deferSaveOnDisk('globalurlcounter');
}
}
/**
* Increase by one the URLCounter
*/
function increaseURLCounter() {
if (storage.statisticsStatus) {
storage.globalCounter++;
deferSaveOnDisk('globalCounter');
}
}
/**
* Change the icon.
*/
function changeIcon() {
checkOSAndroid().then((res) => {
if (!res) {
if (storage.globalStatus) {
browser.browserAction.setIcon({path: "img/clearurls_128x128.png"});
} else {
browser.browserAction.setIcon({path: "img/clearurls_gray_128x128.png"});
}
}
});
}
/**
* Get the badged status from the browser storage and put the value
* into a local variable.
*
*/
function setBadgedStatus() {
checkOSAndroid().then((res) => {
if (!res && storage.badgedStatus) {
let color = storage.badged_color;
if(storage.badged_color.charAt(0) !== '#')
color = '#' + storage.badged_color;
browser.browserAction.setBadgeBackgroundColor({
'color': color
});
}
});
}
/**
* Returns the current URL.
* @return {String} [description]
*/
function getCurrentURL() {
return currentURL;
}
/**
* Check for browser.
*/
function getBrowser() {
if (typeof InstallTrigger !== 'undefined') {
return "Firefox";
} else {
return "Chrome";
}
}
/**
* Decodes an URL, also one that is encoded multiple times.
* @param url the url, that should be decoded
*/
function decodeURL(url) {
const rtn = decodeURIComponent(url);
if (rtn.indexOf("http://") === -1 && rtn.indexOf("https://") === -1) {
return decodeURL(rtn);
}
return rtn;
}
/**
* Gets the value of at `key` an object. If the resolved value is `undefined`, the `defaultValue` is returned in its place.
*
* @param {string} key the key of the object
* @param {object} defaultValue the default value
*/
Object.prototype.getOrDefault = function (key, defaultValue) {
return this[key] === undefined ? defaultValue : this[key];
};

View File

@@ -1,38 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*jshint esversion: 6 */
/*
* This script is responsible to check in fixed intervals, that ClearURLs works properly.
* In issue #203, some users reported, that ClearURLs filter function doesn't work after
* some time, but without any recognizable reason.
*
* This watchdog restarts the whole Add-on, when the check fails.
*/
const CHECK_INTERVAL = 15000;
setInterval(function() {
const dirtyURL = "https://clearurls.roebert.eu?utm_source=addon";
const cleanURL = "https://clearurls.roebert.eu";
if(pureCleaning(dirtyURL, true) !== cleanURL) {
console.log(translate('watchdog'));
saveOnExit();
reload();
}
}, CHECK_INTERVAL);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,89 +0,0 @@
/*
* ClearURLs
* Copyright (c) 2017-2020 Kevin Röbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* Stylesheet for the switch buttons.
*/
/* Box around the slider */
.switch {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #FF7800;
-webkit-transition: .4s;
transition: .4s;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 4px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
}
input:checked + .slider {
background-color: #B5E61D;
}
input:focus + .slider {
box-shadow: 0 0 1px #B5E61D;
}
input:checked + .slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(26px);
}
/* Rounded sliders */
.slider.round {
border-radius: 34px;
}
.slider.round:before {
border-radius: 50%;
}
.switch label {
position: absolute;
left: 60px;
}
label {
font-weight: normal;
}

View File

@@ -1,461 +0,0 @@
{
"providers": {
"amazon": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(amazon)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"pf_rd_[a-zA-Z]=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"qid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sr=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"srs=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(adsensecustomsearchads\\.com)\\/.*",
"pd_rd_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"__mk_[a-zA-Z]{1,3}_[a-zA-Z]{1,3}=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"spIA=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ms3_c=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"[a-zA-Z%0-9]*ie=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"refRID=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"colid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"coliid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"[^a-zA-Z%0-9]adId=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"qualifier=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"_encoding=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"smid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"field-lbr_brands_browse-bin=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [
".*(amazon\\.).*(\\/gp).*\\/redirector.html\\/.*"
],
"redirections": []
},
"fls-na.amazon": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(fls-na\\.amazon)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"google": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(google)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"ved=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"bi[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"gfe_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ei=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"source=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"gs_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"site=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"&\\.[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"oq=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"esrc=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"uact=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"cd=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"cad=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"gws_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"atyp=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"vet=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"zx=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"_u=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"je=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"dcr=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ie=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sei=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sa=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"dpr=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"hl=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"btn[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sa=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"usg=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"cd=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"cad=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"uact=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [
".*(mail\\.google\\.).*(\\/mail\\/u\\/0).*",
".*(google\\.).*(\\/upload)?(\\/drive)\\/.*",
".*(docs\\.google\\.).*\\/.*",
".*(accounts\\.google\\.).*",
".*(google\\.).*\\/searchbyimage\\?image_url=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(hangouts\\.google\\.).*\\/webchat.*zx=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(client-channel\\.google\\.).*\\/client-channel.*zx=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(google\\.).*\\/complete\\/search\\?.*gs_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(google\\.).*\\/s\\?tbm=map.*gs_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(news\\.google\\.).*\\?hl=.*",
".*(google\\.).*\\/setprefs\\?.*hl=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
".*(google\\.).*\\/appsactivity\\/.*",
".*(google\\.).*\\/recaptcha\\/.*"
],
"redirections": [
".*google\\..*\\/.*url\\?.*url=((https|http)[^&]*)",
".*google\\..*\\/.*url\\?.*q=((https|http)[^&]*)"
]
},
"googlesyndication": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(googlesyndication)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"doubleclick": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(doubleclick)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": [
".*doubleclick\\..*\\/.*tag_for_child_directed_treatment=;%3F(.*)"
]
},
"globalRules": {
"urlPattern": ".*",
"completeProvider": false,
"rules": [
"utm_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_source=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_medium=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_term=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_content=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_campaign=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ga_place=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"yclid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"_openstat=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"fb_action_ids=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"fb_action_types=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"fb_source=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"fb_ref=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"fbclid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"action_object_map=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"action_type_map=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"action_ref_map=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"gs_l=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"mkt_tok=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"hmb_campaign=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"hmb_medium=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"hmb_source=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"[\\?|&]ref[\\_]?=[^\\/|\\?|&]*",
"\\?$",
"\\&$"
],
"exceptions": [
".*([\\.]?matrix\\.org)(\\/_matrix)\\/.*",
".*([\\.]?prismic\\.io).*",
".*([\\.]?gitlab\\.com).*",
".*([\\.]?gcsip\\.com).*[\\?|&]ref[\\_]?=[^\\/|\\?|&]*.*",
".*([\\.]?cloudflare\\.com).*",
".*([\\.]?tv2\\.no)(\\/api)\\/.*"
],
"redirections": []
},
"adtech": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(adtech)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"contentpass.net": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(contentpass\\.net).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"bf-ad": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(bf-ad)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"amazon-adsystem": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(amazon-adsystem)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"adsensecustomsearchads": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(adsensecustomsearchads)(\\.[a-zA-Z]{2,}).*",
"completeProvider": true,
"rules": [],
"exceptions": [],
"redirections": []
},
"youtube": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(youtube)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"feature=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"gclid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"kw=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"facebook": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(facebook)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"hc_[a-zA-Z_\\[\\]0-9]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"[a-zA-Z]*ref[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"__tn__=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"eid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"__xts__%5B[0-9]%5D=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [
".*(facebook\\.)\\w{2,}.*(\\/plugins\\/).*"
],
"redirections": [
".*l\\.facebook\\..*\\/.*l\\.php\\?.*u=((https%3A%2F%2F|http%3A%2F%2F)[^&]*)"
]
},
"twitter": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(twitter)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"(ref_)?src=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"reddit": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(reddit)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [],
"exceptions": [],
"redirections": [
"out\\.reddit\\.\\w{2,}\\/.*url=([^&]*)"
]
}
,
"netflix": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(netflix)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"trackId=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"tctx=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"jb[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"techcrunch": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?([\\.]?techcrunch\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"ncid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sr=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sr_share=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"guccounter=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"guce_referrer_[a-z]+=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"bing": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(bing)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"cvid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"form=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sk=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sp=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"sc=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"qs=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"qp=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"tweakers": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(tweakers\\.net)(.*\\?.*)",
"completeProvider": false,
"rules": [
"nb=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"u=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"twitch": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(twitch)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"tt_medium=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"tt_content=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"vivaldi": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(vivaldi\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"pk_campaign=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"pk_kwd=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"indeed": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(indeed\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"from=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"alid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"[a-zA-Z]*tk=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"hhdotru": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(hh\\.ru)(.*\\?.*)",
"completeProvider": false,
"rules": [
"vss=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"t=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"swnt=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"grpos=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ptl=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"stl=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"exp=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"plim=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"ebay": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(ebay)(\\.[a-zA-Z]{2,})(.*\\?.*)",
"completeProvider": false,
"rules": [
"_trkparms=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"_trksid=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"_from=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"cnet": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(cnet\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"ftag=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"imdb.com": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(imdb\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"ref_=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"pf_rd_[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"govdelivery.com": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(govdelivery\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [],
"exceptions": [],
"redirections": [
".*links\\.govdelivery\\.com.*\\/track\\?.*(http:\\/\\/.*)",
".*links\\.govdelivery\\.com.*\\/track\\?.*(https:\\/\\/.*)"
]
},
"walmart.com": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(walmart\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"u1=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"ath[a-zA-Z]*=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"net-parade.it": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(net\\-parade\\.it)(.*\\?.*)",
"completeProvider": false,
"rules": [
"pl=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"prvnizpravy.cz": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(prvnizpravy\\.cz)(.*\\?.*)",
"completeProvider": false,
"rules": [
"xid=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"youku.com": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(youku\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"spm=[^\\/|\\?|&]*(\\/|&(amp;)?)?",
"tpa=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"nytimes.com": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(nytimes\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"smid=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"tchibo.de": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(tchibo\\.de)(.*\\?.*)",
"completeProvider": false,
"rules": [
"wbdcd=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"steam": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(steampowered\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"snr=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
},
"disq.us": {
"urlPattern": "(https:\\/\\/|http:\\/\\/)([a-zA-Z0-9-]*\\.)?(disq\\.us)(.*\\?.*)",
"completeProvider": false,
"rules": [],
"exceptions": [],
"redirections": [
".*disq\\.us.*\\/.*url\\?.*url=((https%3A%2F%2F|http%3A%2F%2F).*)%3A"
]
},
"mozaws.net": {
"urlPattern": "https?://outgoing\\.prod\\.mozaws\\.net/.*",
"completeProvider": false,
"rules": [],
"exceptions": [],
"redirections": [
"https?://[^/]+/v1/[0-9a-f]{64}/(.*)"
]
},
"shutterstock.com": {
"urlPattern": "https?://([a-zA-Z0-9-]*\\.)?(shutterstock\\.com)(.*\\?.*)",
"completeProvider": false,
"rules": [
"src=[^\\/|\\?|&]*(\\/|&(amp;)?)?"
],
"exceptions": [],
"redirections": []
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1 +0,0 @@
b0e1fc948f5e391a53a57092b1c29e8cff474402d5411f4045cfb4a7db37d2bc

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +0,0 @@
/*
* Source: https://github.com/mdn/webextensions-examples/tree/master/context-menu-copy-link-with-types
*/
function copyToClipboard(text) {
function oncopy(event) {
document.removeEventListener("copy", oncopy, true);
event.stopImmediatePropagation();
event.preventDefault();
event.clipboardData.setData("text/plain", text);
}
document.addEventListener("copy", oncopy, true);
document.execCommand("copy");
}

View File

@@ -1,426 +0,0 @@
/**
* Albanian translation
* @name Albanian
* @anchor Albanian
* @author Besnik Belegu
*/
/**
* Afrikaans translation
* @name Afrikaans
* @anchor Afrikaans
* @author <a href="http://www.ajoft.com">Ajoft Software</a>
*/
/**
* Welsh translation
* @name Welsh
* @anchor Welsh
* @author <a href="https://eveoh.nl/">Marco Krikke</a>
*/
/**
* Vietnamese translation
* @name Vietnamese
* @anchor Vietnamese
* @author Trinh Phuoc Thai
*/
/**
* Uzbek translation
* @name Uzbek
* @anchor Uzbek
* @author <a href="http://davlat.info">Farkhod Dadajanov</a>
*/
/**
* Urdu translation
* @name Urdu
* @anchor Urdu
* @author Zafar Subzwari
*/
/**
* Ukranian translation
* @name Ukranian
* @anchor Ukranian
* @author <i>antyrat</i>
*/
/**
* Turkish translation
* @name Turkish
* @anchor Turkish
* @author Umit Gorkem & Erdal TAŞKESEN
*/
/**
* Thai translation
* @name Thai
* @anchor Thai
* @author Thanva Thonglor , <a href="http://auycro.github.io/about/">Gumpanat Keardkeawfa</a>
*/
/**
* Telugu translation (te, te-IN)
* @name Telugu
* @anchor Telugu
* @author <a href="https://in.linkedin.com/in/srinivas-rathikrindi-0405973a">Srinivas Rathikrindi</a>
**/
/**
* Tamil translation
* @name Tamil
* @anchor Tamil
* @author Sam Arul Raj
*/
/**
* Swedish translation
* @name Swedish
* @anchor Swedish
* @author <a href="http://www.kmmtiming.se/">Kristoffer Karlström</a>
*/
/**
* Swahili translation
* @name Swahili
* @anchor Swahili
* @author <a href="http://zoop.co.tz/schoolpesa/">Roy Owino</a>
*/
/**
* Spanish translation
* @name Spanish
* @anchor Spanish
* @author Giovanni Ariza, Aristobulo Gomez and Roberto Poo
*/
/**
* Slovenian translation
* @name Slovenian
* @anchor Slovenian
* @author Marko Kroflic, Blaž Brenčič and Andrej Florjančič
*/
/**
* Slovak translation
* @name Slovak
* @anchor Slovak
* @author <a href="https://github.com/dlugos">Ivan Dlugoš</a>
* @author (original translation) <a href="http://miskerik.com/">Maroš Miškerik</a>
*/
/**
* Sinhala translation
* @name Sinhala
* @anchor Sinhala
* @author Isuru Sampath Ratnayake
*/
/**
* Serbian translation (Latin alphabet)
* @name Serbian (Latin)
* @anchor Serbian (Latin)
* @author <a href="http://mnovakovic.byteout.com">Marko Novakovic</a>
*/
/**
* Russian translation
* @name Russian
* @anchor Russian
* @author Tjoma
* @autor aspyatkin
*/
/**
* Romanian translation
* @name Romanian
* @anchor Romanian
* @author <a href="http://www.jurubita.ro/">Alexandru Jurubita</a>
*/
/**
* Portuguese Brasil translation
* @name Portuguese Brasil
* @anchor Portuguese Brasil
* @author Julio Cesar Viana Palma
*/
/**
* Portuguese translation
* @name Portuguese
* @anchor Portuguese
* @author Nuno Felicio
*/
/**
* Polish translation
* @name Polish
* @anchor Polish
* @author Tomasz Kowalski
* @author Michał Grzelak
*/
/**
* Persian translation
* @name Persian
* @anchor Persian
* @author <a href="http://www.chavoshi.com/">Ehsan Chavoshi</a>
* @author <a href="http://www.robowiki.ir/">Mohammad Babazadeh</a>
*/
/**
* Pashto translation
* @name Pashto
* @anchor Pashto
* @author <a href="http://mbrig.com/">MBrig | Muhammad Nasir Rahimi</a>
*/
/**
* Norwegian Nynorsk translation
* @name Norwegian-Nynorsk
* @anchor Norwegian-Nynorsk
* @author Andreas-Johann Østerdal Ulvestad
*/
/**
* Norwegian Bokmål translation
* @name Norwegian-Bokmal
* @anchor Norwegian-Bokmal
* @author Petter Ekrann
* @author Vegard Johannessen
*/
/**
* Nepali
* @name Nepali
* @anchor Nepali
* @author Bishwo Adhikari
*/
/**
* Mongolian - Монгол хэлний орчуулга
* @name Mongolian
* @anchor Mongolian
* @author <a href="http://www.Batmandakh.com/">Batmandakh Erdenebileg</a>
*/
/**
* Malay translation
* @name Malay
* @anchor Malay
* @author Mohamad Zharif
*/
/**
* Macedonian translation
* @name Macedonian
* @anchor Macedonian
* @author Bojan Petkovski
*/
/**
* Lithuanian translation
* @name Lithuanian
* @anchor Lithuanian
* @author <a href="http://www.kurdingopinigai.lt">Kęstutis Morkūnas</a>
* @author Algirdas Brazas
*/
/**
* Latvian translation
* @name Latvian
* @anchor Latvian
* @author Oskars Podans, Ruslans Jermakovičs and Edgars
*/
/**
* @name Kyrgyz
* @anchor Kyrgyz
* @author <a href="https://github.com/nursultan92/">Nursultan Turdaliev</a> and _tynar_
*/
/**
* Korean translation
* @name Korean
* @anchor Korean
* @author WonGoo Lee
*/
/**
* Kazakh translation
* @name Kazakh
* @anchor Kazakh
* @author <a href="https://github.com/talgautb">Talgat Uspanov</a>
*/
/**
* Japanese translation
* @name Japanese
* @anchor Japanese
* @author <i>yusuke</i> and <a href="https://github.com/wiraqutra">Seigo ISHINO</a>
*/
/**
* Italian translation
* @name Italian
* @anchor Italian
* @author Nicola Zecchin & Giulio Quaresima
*/
/**
* Irish translation
* @name Irish
* @anchor Irish
* @author <a href="http://letsbefamous.com">Lets Be Famous Journal</a>
*/
/**
* Indonesian translation
* @name Indonesian
* @anchor Indonesian
* @author Landung Wahana
*/
/**
* Indonesian translation
* @name Indonesian
* @anchor Indonesian
* @author Cipto Hadi
*/
/**
* Icelandic translation
* @name Icelandic
* @anchor Icelandic
* @author Finnur Kolbeinsson
*/
/**
* Hungarian translation
* @name Hungarian
* @anchor Hungarian
* @author <a href="http://www.maschek.hu">Adam Maschek</a> and Lajos Cseppentő
*/
/**
* Hindi translation
* @name Hindi
* @anchor Hindi
* @author <a href="http://outshinesolutions.com">Outshine Solutions</a>
*/
/**
* Hebrew translation
* @name Hebrew
* @anchor Hebrew
* @author <a href="http://ww3.co.il/">Neil Osman (WW3)</a>
*/
/**
* Gujarati translation
* @name Gujarati
* @anchor Gujarati
* @author <a href="http://www.apoto.com/">Apoto</a>
*/
/**
* Greek translation
* @name Greek
* @anchor Greek
* @author Abraam Ziogas
* @author Leonidas Arvanitis
*/
/**
* German translation
* @name German
* @anchor German
* @author Joerg Holz
* @author DJmRek - Markus Bergt
* @author OSWorX https://osworx.net
*/
/**
* Georgian translation
* @name Georgian
* @anchor Georgian
* @author Mikheil Nadareishvili, updated by <a href="http://www.brunjadze.xyz/">Mirza Brunjadze</a>
*/
/**
* Galician translation
* @name Galician
* @anchor Galician
* @author <i>Emilio</i>
* @author <i>Xosé Antonio Rubal López</i>
*/
/**
* French translation
* @name French
* @anchor French
* @author
*/
/**
* Finnish translation
* @name Finnish
* @anchor Finnish
* @author Seppo Äyräväinen
* @author Viktors Cvetkovs
* @author <a href="https://ironlions.fi">Niko Granö</a>
*/
/**
* Filipino translation
* @name Filipino
* @anchor Filipino
* @author <a href="http://citi360.com/">Citi360</a>
*/
/**
* Estonian translation
* @name Estonian
* @anchor Estonian
* @author <a href="http://www.arts9.com/">Janek Todoruk</a>
*/
/**
* English - this is the default DataTables ships with
* @name English
* @anchor English
* @author <a href="http://www.sprymedia.co.uk/">Allan Jardine</a>
*/
/**
* Dutch translation
* @name Dutch
* @anchor Dutch
* @author <a href="http://www.blikgooien.nl/">Erwin Kerk</a> and <i>ashwin</i>
*/
/**
* Danish translation
* @name Danish
* @anchor Danish
* @author <a href="http://www.kor.dk/">Werner Knudsen</a>
*/
/**
* Czech translation
* @name Czech
* @anchor Czech
* @author <a href="http://blog.magerio.cz/">Magerio</a>
*/
/**
* Croatian translation
* @name Croatian
* @anchor Croatian
* @author Predrag Mušić and _hrvoj3e_
*/
/**
* Chinese (traditional) translation
* @name Chinese (traditional)
* @anchor Chinese (traditional)
* @author <a href="https://gimmerank.com/">GimmeRank Affiliate</a>
* @author <a href="https://github.com/PeterDaveHello">Peter Dave Hello</a>
*/
/**
* Catalan translation
* @name Catalan
* @anchor Catalan
* @author Sergi
*/
/**
* Amharic translation
* @name Amharic
* @anchor Amharic
* @author veduket
*/
/**
* Arabic translation
* @name Arabic
* @anchor Arabic
* @author Ossama Khayat
*/
/**
* Armenian - translation
* @name Armenian
* @anchor Armenian
* @author <a href="http://www.voznisoft.com/">Levon Levonyan</a>
*/
/**
* Azerbaijan translation
* @name Azerbaijan
* @anchor Azerbaijan
* @author H.Huseyn
*/
/**
* Bangla translation
* @name Bangla
* @anchor Bangla
* @author <a href="http://khaledcse06.wordpress.com">Md. Khaled Ben Islam</a>
*/
/**
* Basque translation
* @name Basque
* @anchor Basque
* @author <a href="https://github.com/xabikip/">Xabi Pico</a>
*/
/**
* Belarusian translation
* @name Belarusian
* @anchor Belarusian
* @author vkachurka
*/
/**
* Bulgarian translation
* @name Bulgarian
* @anchor Bulgarian
* @author Rostislav Stoyanov, Oliwier Thomas
*/

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Geen data beskikbaar in tabel",
"sInfo": "uitstalling _START_ to _END_ of _TOTAL_ inskrywings",
"sInfoEmpty": "uitstalling 0 to 0 of 0 inskrywings",
"sInfoFiltered": "(gefiltreer uit _MAX_ totaal inskrywings)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "uitstal _MENU_ inskrywings",
"sLoadingRecords": "laai...",
"sProcessing": "verwerking...",
"sSearch": "soektog:",
"sZeroRecords": "Geen treffers gevind",
"oPaginate": {
"sFirst": "eerste",
"sLast": "laaste",
"sNext": "volgende",
"sPrevious": "vorige"
},
"oAria": {
"sSortAscending": ": aktiveer kolom stygende te sorteer",
"sSortDescending": ": aktiveer kolom orde te sorteer"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "ባዶ ሰንጠረዥ",
"sInfo": "ከጠቅላላው _TOTAL_ ዝርዝሮች ውስጥ ከ _START_ እስከ _END_ ያሉት ዝርዝር",
"sInfoEmpty": "ከጠቅላላው 0 ዝርዝሮች ውስጥ ከ 0 እስከ 0 ያሉት ዝርዝር",
"sInfoFiltered": "(ከጠቅላላው _MAX_ የተመረጡ ዝርዝሮች)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "የዝርዝሮች ብዛት _MENU_",
"sLoadingRecords": "በማቅረብ ላይ...",
"sProcessing": "በማቀናበር ላይ...",
"sSearch": "ፈልግ:",
"sZeroRecords": "ከሚፈለገው ጋር የሚሚሳሰል ዝርዝር አልተገኘም",
"oPaginate": {
"sFirst": "መጀመሪያ",
"sLast": "መጨረሻ",
"sNext": "ቀጣዩ",
"sPrevious": "የበፊቱ"
},
"oAria": {
"sSortAscending": ": ከመጀመሪያ ወደ መጨረሻ(ወጪ) አደራደር",
"sSortDescending": ": ከመጨረሻ ወደ መጀመሪያ(ወራጅ) አደራደር"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "جارٍ التحميل...",
"sLengthMenu": "أظهر _MENU_ مدخلات",
"sZeroRecords": "لم يعثر على أية سجلات",
"sInfo": "إظهار _START_ إلى _END_ من أصل _TOTAL_ مدخل",
"sInfoEmpty": "يعرض 0 إلى 0 من أصل 0 سجل",
"sInfoFiltered": "(منتقاة من مجموع _MAX_ مُدخل)",
"sInfoPostFix": "",
"sSearch": "ابحث:",
"sUrl": "",
"oPaginate": {
"sFirst": "الأول",
"sPrevious": "السابق",
"sNext": "التالي",
"sLast": "الأخير"
}
}

View File

@@ -1,21 +0,0 @@
{
"sProcessing": "Пачакайце...",
"sLengthMenu": "Паказваць _MENU_ запісаў",
"sZeroRecords": "Запісы адсутнічаюць.",
"sInfo": "Запісы з _START_ па _END_ з _TOTAL_ запісаў",
"sInfoEmpty": "Запісы з 0 па 0 з 0 запісаў",
"sInfoFiltered": "(адфільтравана з _MAX_ запісаў)",
"sInfoPostFix": "",
"sSearch": "Пошук:",
"sUrl": "",
"oPaginate": {
"sFirst": "Першая",
"sPrevious": "Папярэдняя",
"sNext": "Наступная",
"sLast": "Апошняя"
},
"oAria": {
"sSortAscending": ": актываваць для сартавання слупка па ўзрастанні",
"sSortDescending": ": актываваць для сартавання слупка па змяншэнні"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "Обработка на резултатите...",
"sLengthMenu": "Показване на _MENU_ резултата",
"sZeroRecords": "Няма намерени резултати",
"sInfo": "Показване на резултати от _START_ до _END_ от общо _TOTAL_",
"sInfoEmpty": "Показване на резултати от 0 до 0 от общо 0",
"sInfoFiltered": "(филтрирани от общо _MAX_ резултата)",
"sInfoPostFix": "",
"sSearch": "Търсене:",
"sUrl": "",
"oPaginate": {
"sFirst": "Първа",
"sPrevious": "Предишна",
"sNext": "Следваща",
"sLast": "Последна"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "Processant...",
"sLengthMenu": "Mostra _MENU_ registres",
"sZeroRecords": "No s'han trobat registres.",
"sInfo": "Mostrant de _START_ a _END_ de _TOTAL_ registres",
"sInfoEmpty": "Mostrant de 0 a 0 de 0 registres",
"sInfoFiltered": "(filtrat de _MAX_ total registres)",
"sInfoPostFix": "",
"sSearch": "Filtrar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primer",
"sPrevious": "Anterior",
"sNext": "Següent",
"sLast": "Últim"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Tabulka neobsahuje žádná data",
"sInfo": "Zobrazuji _START_ až _END_ z celkem _TOTAL_ záznamů",
"sInfoEmpty": "Zobrazuji 0 až 0 z 0 záznamů",
"sInfoFiltered": "(filtrováno z celkem _MAX_ záznamů)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "Zobraz záznamů _MENU_",
"sLoadingRecords": "Načítám...",
"sProcessing": "Provádím...",
"sSearch": "Hledat:",
"sZeroRecords": "Žádné záznamy nebyly nalezeny",
"oPaginate": {
"sFirst": "První",
"sLast": "Poslední",
"sNext": "Další",
"sPrevious": "Předchozí"
},
"oAria": {
"sSortAscending": ": aktivujte pro řazení sloupce vzestupně",
"sSortDescending": ": aktivujte pro řazení sloupce sestupně"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Dim data ar gael yn y tabl",
"sInfo": "Dangos _START_ i _END_ o _TOTAL_ cofnod",
"sInfoEmpty": "Dangos 0 i 0 o 0 cofnod",
"sInfoFiltered": "(wedi hidlo o gyfanswm o _MAX_ cofnod)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Dangos _MENU_ cofnod",
"sLoadingRecords": "Wrthi'n llwytho...",
"sProcessing": "Wrthi'n prosesu...",
"sSearch": "Chwilio:",
"sZeroRecords": "Heb ddod o hyd i gofnodion sy'n cyfateb",
"oPaginate": {
"sFirst": "Cyntaf",
"sLast": "Olaf",
"sNext": "Nesaf",
"sPrevious": "Blaenorol"
},
"oAria": {
"sSortAscending": ": rhoi ar waith i drefnu colofnau o'r lleiaf i'r mwyaf",
"sSortDescending": ": rhoi ar waith i drefnu colofnau o'r mwyaf i'r lleiaf"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "Henter...",
"sLengthMenu": "Vis _MENU_ linjer",
"sZeroRecords": "Ingen linjer matcher s&oslash;gningen",
"sInfo": "Viser _START_ til _END_ af _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 af 0 linjer",
"sInfoFiltered": "(filtreret fra _MAX_ linjer)",
"sInfoPostFix": "",
"sSearch": "S&oslash;g:",
"sUrl": "",
"oPaginate": {
"sFirst": "F&oslash;rste",
"sPrevious": "Forrige",
"sNext": "N&aelig;ste",
"sLast": "Sidste"
}
}

View File

@@ -1,41 +0,0 @@
{
"sEmptyTable": "Keine Daten in der Tabelle vorhanden",
"sInfo": "_START_ bis _END_ von _TOTAL_ Einträgen",
"sInfoEmpty": "Keine Daten vorhanden",
"sInfoFiltered": "(gefiltert von _MAX_ Einträgen)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "_MENU_ Einträge anzeigen",
"sLoadingRecords": "Wird geladen ..",
"sProcessing": "Bitte warten ..",
"sSearch": "Suchen",
"sZeroRecords": "Keine Einträge vorhanden",
"oPaginate": {
"sFirst": "Erste",
"sPrevious": "Zurück",
"sNext": "Nächste",
"sLast": "Letzte"
},
"oAria": {
"sSortAscending": ": aktivieren, um Spalte aufsteigend zu sortieren",
"sSortDescending": ": aktivieren, um Spalte absteigend zu sortieren"
},
"select": {
"rows": {
"_": "%d Zeilen ausgewählt",
"0": "",
"1": "1 Zeile ausgewählt"
}
},
"buttons": {
"print": "Drucken",
"colvis": "Spalten",
"copy": "Kopieren",
"copyTitle": "In Zwischenablage kopieren",
"copyKeys": "Taste <i>ctrl</i> oder <i>\u2318</i> + <i>C</i> um Tabelle<br>in Zwischenspeicher zu kopieren.<br><br>Um abzubrechen die Nachricht anklicken oder Escape drücken.",
"copySuccess": {
"_": "%d Spalten kopiert",
"1": "1 Spalte kopiert"
}
}
}

View File

@@ -1,27 +0,0 @@
{
"sDecimal": ",",
"sEmptyTable": "Δεν υπάρχουν δεδομένα στον πίνακα",
"sInfo": "Εμφανίζονται _START_ έως _END_ από _TOTAL_ εγγραφές",
"sInfoEmpty": "Εμφανίζονται 0 έως 0 από 0 εγγραφές",
"sInfoFiltered": "(φιλτραρισμένες από _MAX_ συνολικά εγγραφές)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Δείξε _MENU_ εγγραφές",
"sLoadingRecords": "Φόρτωση...",
"sProcessing": "Επεξεργασία...",
"sSearch": "Αναζήτηση:",
"sSearchPlaceholder": "Αναζήτηση",
"sThousands": ".",
"sUrl": "",
"sZeroRecords": "Δεν βρέθηκαν εγγραφές που να ταιριάζουν",
"oPaginate": {
"sFirst": "Πρώτη",
"sPrevious": "Προηγούμενη",
"sNext": "Επόμενη",
"sLast": "Τελευταία"
},
"oAria": {
"sSortAscending": ": ενεργοποιήστε για αύξουσα ταξινόμηση της στήλης",
"sSortDescending": ": ενεργοποιήστε για φθίνουσα ταξινόμηση της στήλης"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "No data available in table",
"sInfo": "Showing _START_ to _END_ of _TOTAL_ entries",
"sInfoEmpty": "Showing 0 to 0 of 0 entries",
"sInfoFiltered": "(filtered from _MAX_ total entries)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Show _MENU_ entries",
"sLoadingRecords": "Loading...",
"sProcessing": "Processing...",
"sSearch": "Search:",
"sZeroRecords": "No matching records found",
"oPaginate": {
"sFirst": "First",
"sLast": "Last",
"sNext": "Next",
"sPrevious": "Previous"
},
"oAria": {
"sSortAscending": ": activate to sort column ascending",
"sSortDescending": ": activate to sort column descending"
}
}

View File

@@ -1,24 +0,0 @@
{
"sProcessing": "Procesando...",
"sLengthMenu": "Mostrar _MENU_ registros",
"sZeroRecords": "No se encontraron resultados",
"sEmptyTable": "Ningún dato disponible en esta tabla",
"sInfo": "Mostrando registros del _START_ al _END_ de un total de _TOTAL_ registros",
"sInfoEmpty": "Mostrando registros del 0 al 0 de un total de 0 registros",
"sInfoFiltered": "(filtrado de un total de _MAX_ registros)",
"sInfoPostFix": "",
"sSearch": "Buscar:",
"sUrl": "",
"sInfoThousands": ",",
"sLoadingRecords": "Cargando...",
"oPaginate": {
"sFirst": "Primero",
"sLast": "Último",
"sNext": "Siguiente",
"sPrevious": "Anterior"
},
"oAria": {
"sSortAscending": ": Activar para ordenar la columna de manera ascendente",
"sSortDescending": ": Activar para ordenar la columna de manera descendente"
}
}

View File

@@ -1,16 +0,0 @@
{
"sProcessing": "Palun oodake, koostan kuvamiseks nimekirja!",
"sLengthMenu": "N&auml;ita kirjeid _MENU_ kaupa",
"sZeroRecords": "Otsitavat vastet ei leitud.",
"sInfo": "Kuvatud: _TOTAL_ kirjet (_START_-_END_)",
"sInfoEmpty": "Otsinguvasteid ei leitud",
"sInfoFiltered": " - filteeritud _MAX_ kirje seast.",
"sInfoPostFix": "K&otilde;ik kuvatud kirjed p&otilde;hinevad reaalsetel tulemustel.",
"sSearch": "Otsi k&otilde;ikide tulemuste seast:",
"oPaginate": {
"sFirst": "Algus",
"sPrevious": "Eelmine",
"sNext": "J&auml;rgmine",
"sLast": "Viimane"
}
}

View File

@@ -1,24 +0,0 @@
{
"sProcessing": "Prozesatzen...",
"sLengthMenu": "Erakutsi _MENU_ erregistro",
"sZeroRecords": "Ez da emaitzarik aurkitu",
"sEmptyTable": "Taula hontan ez dago inongo datu erabilgarririk",
"sInfo": "_START_ -etik _END_ -erako erregistroak erakusten, guztira _TOTAL_ erregistro",
"sInfoEmpty": "0tik 0rako erregistroak erakusten, guztira 0 erregistro",
"sInfoFiltered": "(guztira _MAX_ erregistro iragazten)",
"sInfoPostFix": "",
"sSearch": "Aurkitu:",
"sUrl": "",
"sInfoThousands": ",",
"sLoadingRecords": "Abiarazten...",
"oPaginate": {
"sFirst": "Lehena",
"sLast": "Azkena",
"sNext": "Hurrengoa",
"sPrevious": "Aurrekoa"
},
"oAria": {
"sSortAscending": ": Zutabea goranzko eran ordenatzeko aktibatu ",
"sSortDescending": ": Zutabea beheranzko eran ordenatzeko aktibatu"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "هیچ داده ای در جدول وجود ندارد",
"sInfo": "نمایش _START_ تا _END_ از _TOTAL_ رکورد",
"sInfoEmpty": "نمایش 0 تا 0 از 0 رکورد",
"sInfoFiltered": "(فیلتر شده از _MAX_ رکورد)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "نمایش _MENU_ رکورد",
"sLoadingRecords": "در حال بارگزاری...",
"sProcessing": "در حال پردازش...",
"sSearch": "جستجو:",
"sZeroRecords": "رکوردی با این مشخصات پیدا نشد",
"oPaginate": {
"sFirst": "ابتدا",
"sLast": "انتها",
"sNext": "بعدی",
"sPrevious": "قبلی"
},
"oAria": {
"sSortAscending": ": فعال سازی نمایش به صورت صعودی",
"sSortDescending": ": فعال سازی نمایش به صورت نزولی"
}
}

View File

@@ -1,39 +0,0 @@
{
"sEmptyTable": "Ei näytettäviä tuloksia.",
"sInfo": "Näytetään rivit _START_ - _END_ (yhteensä _TOTAL_ )",
"sInfoEmpty": "Näytetään 0 - 0 (yhteensä 0)",
"sInfoFiltered": "(suodatettu _MAX_ tuloksen joukosta)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Näytä kerralla _MENU_ riviä",
"sLoadingRecords": "Ladataan...",
"sProcessing": "Hetkinen...",
"sSearch": "Etsi:",
"sZeroRecords": "Tietoja ei löytynyt",
"oPaginate": {
"sFirst": "Ensimmäinen",
"sLast": "Viimeinen",
"sNext": "Seuraava",
"sPrevious": "Edellinen"
},
"oAria": {
"sSortAscending": ": lajittele sarake nousevasti",
"sSortDescending": ": lajittele sarake laskevasti"
},
"select": {
"rows": {
"_": "Valittuna %d riviä",
"0": "Klikkaa riviä valitaksesi sen",
"1": "Valittuna vain yksi rivi"
}
},
"buttons": {
"copy": "Kopioi",
"copySuccess": {
"1": "Yksi rivi kopioitu leikepöydälle",
"_": "%d riviä kopioitu leikepöydälle"
},
"copyTitle": "Kopioi leikepöydälle",
"copyKeys": "Paina <i>ctrl</i> tai <i>\u2318</i> + <i>C</i> kopioidaksesi taulukon arvot<br> leikepöydälle. <br><br>Peruuttaaksesi klikkaa tähän tai Esc."
}
}

View File

@@ -1,29 +0,0 @@
{
"sProcessing": "Traitement en cours...",
"sSearch": "Rechercher&nbsp;:",
"sLengthMenu": "Afficher _MENU_ &eacute;l&eacute;ments",
"sInfo": "Affichage de l'&eacute;l&eacute;ment _START_ &agrave; _END_ sur _TOTAL_ &eacute;l&eacute;ments",
"sInfoEmpty": "Affichage de l'&eacute;l&eacute;ment 0 &agrave; 0 sur 0 &eacute;l&eacute;ment",
"sInfoFiltered": "(filtr&eacute; de _MAX_ &eacute;l&eacute;ments au total)",
"sInfoPostFix": "",
"sLoadingRecords": "Chargement en cours...",
"sZeroRecords": "Aucun &eacute;l&eacute;ment &agrave; afficher",
"sEmptyTable": "Aucune donn&eacute;e disponible dans le tableau",
"oPaginate": {
"sFirst": "Premier",
"sPrevious": "Pr&eacute;c&eacute;dent",
"sNext": "Suivant",
"sLast": "Dernier"
},
"oAria": {
"sSortAscending": ": activer pour trier la colonne par ordre croissant",
"sSortDescending": ": activer pour trier la colonne par ordre d&eacute;croissant"
},
"select": {
"rows": {
_: "%d lignes séléctionnées",
0: "Aucune ligne séléctionnée",
1: "1 ligne séléctionnée"
}
}
}

View File

@@ -1,24 +0,0 @@
{
"sProcessing": "Procesando...",
"sLengthMenu": "Mostrar _MENU_ rexistros",
"sZeroRecords": "Non se atoparon resultados",
"sEmptyTable": "Ningún dato dispoñible nesta táboa",
"sInfo": "Mostrando rexistros do _START_ ao _END_ dun total de _TOTAL_ rexistros",
"sInfoEmpty": "Mostrando rexistros do 0 ao 0 dun total de 0 rexistros",
"sInfoFiltered": "(filtrado dun total de _MAX_ rexistros)",
"sInfoPostFix": "",
"sSearch": "Buscar:",
"sUrl": "",
"sInfoThousands": ",",
"sLoadingRecords": "Cargando...",
"oPaginate": {
"sFirst": "Primeiro",
"sLast": "Último",
"sNext": "Seguinte",
"sPrevious": "Anterior"
},
"oAria": {
"sSortAscending": ": Activar para ordenar a columna de maneira ascendente",
"sSortDescending": ": Activar para ordenar a columna de maneira descendente"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "કોષ્ટકમાં કોઈ ડેટા ઉપલબ્ધ નથી",
"sInfo": "કુલ_પ્રવેશો_અંત_પ્રારંભ_દર્શાવે_છે",
"sInfoEmpty": "0 પ્રવેશો 0 0 બતાવી રહ્યું છે",
"sInfoFiltered": "(_MAX_ કુલ પ્રવેશો માંથી ફિલ્ટર)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "બતાવો _MENU_ પ્રવેશો",
"sLoadingRecords": "લોડ કરી રહ્યું છે ...",
"sProcessing": "પ્રક્રિયા ...",
"sSearch": "શોધો:",
"sZeroRecords": "કોઈ મેળ ખાતા રેકોર્ડ મળી",
"oPaginate": {
"sFirst": "પ્રથમ",
"sLast": "અંતિમ",
"sNext": "આગામી",
"sPrevious": "ગત"
},
"oAria": {
"sSortAscending": ": સ્તંભ ચડતા ક્રમમાં ગોઠવવા માટે સક્રિય",
"sSortDescending": ": કૉલમ ઉતરતા ક્રમમાં ગોઠવવા માટે સક્રિય"
}
}

View File

@@ -1,18 +0,0 @@
{
"processing": "מעבד...",
"lengthMenu": "הצג _MENU_ פריטים",
"zeroRecords": "לא נמצאו רשומות מתאימות",
"emptyTable": "לא נמצאו רשומות מתאימות",
"info": "_START_ עד _END_ מתוך _TOTAL_ רשומות" ,
"infoEmpty": "0 עד 0 מתוך 0 רשומות",
"infoFiltered": "(מסונן מסך _MAX_ רשומות)",
"infoPostFix": "",
"search": "חפש:",
"url": "",
"paginate": {
"first": "ראשון",
"previous": "קודם",
"next": "הבא",
"last": "אחרון"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "प्रगति पे हैं ...",
"sLengthMenu": " _MENU_ प्रविष्टियां दिखाएं ",
"sZeroRecords": "रिकॉर्ड्स का मेल नहीं मिला",
"sInfo": "_START_ to _END_ of _TOTAL_ प्रविष्टियां दिखा रहे हैं",
"sInfoEmpty": "0 में से 0 से 0 प्रविष्टियां दिखा रहे हैं",
"sInfoFiltered": "(_MAX_ कुल प्रविष्टियों में से छठा हुआ)",
"sInfoPostFix": "",
"sSearch": "खोजें:",
"sUrl": "",
"oPaginate": {
"sFirst": "प्रथम",
"sPrevious": "पिछला",
"sNext": "अगला",
"sLast": "अंतिम"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Nema podataka u tablici",
"sInfo": "Prikazano _START_ do _END_ od _TOTAL_ rezultata",
"sInfoEmpty": "Prikazano 0 do 0 od 0 rezultata",
"sInfoFiltered": "(filtrirano iz _MAX_ ukupnih rezultata)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Prikaži _MENU_ rezultata po stranici",
"sLoadingRecords": "Dohvaćam...",
"sProcessing": "Obrađujem...",
"sSearch": "Pretraži:",
"sZeroRecords": "Ništa nije pronađeno",
"oPaginate": {
"sFirst": "Prva",
"sPrevious": "Nazad",
"sNext": "Naprijed",
"sLast": "Zadnja"
},
"oAria": {
"sSortAscending": ": aktiviraj za rastući poredak",
"sSortDescending": ": aktiviraj za padajući poredak"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Nincs rendelkezésre álló adat",
"sInfo": "Találatok: _START_ - _END_ Összesen: _TOTAL_",
"sInfoEmpty": "Nulla találat",
"sInfoFiltered": "(_MAX_ összes rekord közül szűrve)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "_MENU_ találat oldalanként",
"sLoadingRecords": "Betöltés...",
"sProcessing": "Feldolgozás...",
"sSearch": "Keresés:",
"sZeroRecords": "Nincs a keresésnek megfelelő találat",
"oPaginate": {
"sFirst": "Első",
"sPrevious": "Előző",
"sNext": "Következő",
"sLast": "Utolsó"
},
"oAria": {
"sSortAscending": ": aktiválja a növekvő rendezéshez",
"sSortDescending": ": aktiválja a csökkenő rendezéshez"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Տվյալները բացակայում են",
"sProcessing": "Կատարվում է...",
"sInfoThousands": ",",
"sLengthMenu": "Ցուցադրել _MENU_ արդյունքներ մեկ էջում",
"sLoadingRecords": "Բեռնվում է ...",
"sZeroRecords": "Հարցմանը համապատասխանող արդյունքներ չկան",
"sInfo": "Ցուցադրված են _START_-ից _END_ արդյունքները ընդհանուր _TOTAL_-ից",
"sInfoEmpty": "Արդյունքներ գտնված չեն",
"sInfoFiltered": "(ֆիլտրվել է ընդհանուր _MAX_ արդյունքներից)",
"sInfoPostFix": "",
"sSearch": "Փնտրել",
"oPaginate": {
"sFirst": "Առաջին էջ",
"sPrevious": "Նախորդ էջ",
"sNext": "Հաջորդ էջ",
"sLast": "Վերջին էջ"
},
"oAria": {
"sSortAscending": ": ակտիվացրեք աճման կարգով դասավորելու համար",
"sSortDescending": ": ակտիվացրեք նվազման կարգով դասավորելու համար"
}
}

View File

@@ -1,18 +0,0 @@
{
"sEmptyTable": "Tidak ada data yang tersedia pada tabel ini",
"sProcessing": "Sedang memproses...",
"sLengthMenu": "Tampilkan _MENU_ entri",
"sZeroRecords": "Tidak ditemukan data yang sesuai",
"sInfo": "Menampilkan _START_ sampai _END_ dari _TOTAL_ entri",
"sInfoEmpty": "Menampilkan 0 sampai 0 dari 0 entri",
"sInfoFiltered": "(disaring dari _MAX_ entri keseluruhan)",
"sInfoPostFix": "",
"sSearch": "Cari:",
"sUrl": "",
"oPaginate": {
"sFirst": "Pertama",
"sPrevious": "Sebelumnya",
"sNext": "Selanjutnya",
"sLast": "Terakhir"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Engin gögn eru í þessari töflu",
"sInfo": "Sýni _START_ til _END_ af _TOTAL_ færslum",
"sInfoEmpty": "Sýni 0 til 0 af 0 færslum",
"sInfoFiltered": "(síað út frá _MAX_ færslum)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Sýna _MENU_ færslur",
"sLoadingRecords": "Hleð...",
"sProcessing": "Úrvinnsla...",
"sSearch": "Leita:",
"sZeroRecords": "Engar færslur fundust",
"oPaginate": {
"sFirst": "Fyrsta",
"sLast": "Síðasta",
"sNext": "Næsta",
"sPrevious": "Fyrri"
},
"oAria": {
"sSortAscending": ": virkja til að raða dálki í hækkandi röð",
"sSortDescending": ": virkja til að raða dálki lækkandi í röð"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Nessun dato presente nella tabella",
"sInfo": "Vista da _START_ a _END_ di _TOTAL_ elementi",
"sInfoEmpty": "Vista da 0 a 0 di 0 elementi",
"sInfoFiltered": "(filtrati da _MAX_ elementi totali)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "Visualizza _MENU_ elementi",
"sLoadingRecords": "Caricamento...",
"sProcessing": "Elaborazione...",
"sSearch": "Cerca:",
"sZeroRecords": "La ricerca non ha portato alcun risultato.",
"oPaginate": {
"sFirst": "Inizio",
"sPrevious": "Precedente",
"sNext": "Successivo",
"sLast": "Fine"
},
"oAria": {
"sSortAscending": ": attiva per ordinare la colonna in ordine crescente",
"sSortDescending": ": attiva per ordinare la colonna in ordine decrescente"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "テーブルにデータがありません",
"sInfo": " _TOTAL_ 件中 _START_ から _END_ まで表示",
"sInfoEmpty": " 0 件中 0 から 0 まで表示",
"sInfoFiltered": "(全 _MAX_ 件より抽出)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "_MENU_ 件表示",
"sLoadingRecords": "読み込み中...",
"sProcessing": "処理中...",
"sSearch": "検索:",
"sZeroRecords": "一致するレコードがありません",
"oPaginate": {
"sFirst": "先頭",
"sLast": "最終",
"sNext": "次",
"sPrevious": "前"
},
"oAria": {
"sSortAscending": ": 列を昇順に並べ替えるにはアクティブにする",
"sSortDescending": ": 列を降順に並べ替えるにはアクティブにする"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "ცხრილში არ არის მონაცემები",
"sInfo": "ნაჩვენებია ჩანაწერები _START_დან _END_მდე, _TOTAL_ ჩანაწერიდან",
"sInfoEmpty": "ნაჩვენებია ჩანაწერები 0დან 0მდე, 0 ჩანაწერიდან",
"sInfoFiltered": "(გაფილტრული შედეგი _MAX_ ჩანაწერიდან)",
"sInfoPostFix": "",
"sInfoThousands": ".",
"sLengthMenu": "აჩვენე _MENU_ ჩანაწერი",
"sLoadingRecords": "იტვირთება...",
"sProcessing": "მუშავდება...",
"sSearch": "ძიება:",
"sZeroRecords": "არაფერი მოიძებნა",
"oPaginate": {
"sFirst": "პირველი",
"sLast": "ბოლო",
"sNext": "შემდეგი",
"sPrevious": "წინა"
},
"oAria": {
"sSortAscending": ": სვეტის დალაგება ზრდის მიხედვით",
"sSortDescending": ": სვეტის დალაგება კლების მიხედვით"
}
}

View File

@@ -1,22 +0,0 @@
{
"processing": "Күте тұрыңыз...",
"search": "Іздеу:",
"lengthMenu": "Жазбалар _MENU_ көрсету",
"info": "_TOTAL_ жазбалары бойынша _START_ бастап _END_ дейінгі жазбалар",
"infoEmpty": "0 жазбалары бойынша 0 бастап 0 дейінгі жазбалар",
"infoFiltered": "(_MAX_ жазбасынан сұрыпталды)",
"infoPostFix": "",
"loadingRecords": "Жазбалар жүктемесі...",
"zeroRecords": "Жазбалар жоқ",
"emptyTable": "Кестеде деректер жоқ",
"paginate": {
"first": "Бірінші",
"previous": "Алдыңғысы",
"next": "Келесі",
"last": "Соңғы"
},
"aria": {
"sortAscending": ": өсімі бойынша бағанды сұрыптау үшін активациялау",
"sortDescending": ": кемуі бойынша бағанды сұрыптау үшін активациялау"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "데이터가 없습니다",
"sInfo": "_START_ - _END_ / _TOTAL_",
"sInfoEmpty": "0 - 0 / 0",
"sInfoFiltered": "(총 _MAX_ 개)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "페이지당 줄수 _MENU_",
"sLoadingRecords": "읽는중...",
"sProcessing": "처리중...",
"sSearch": "검색:",
"sZeroRecords": "검색 결과가 없습니다",
"oPaginate": {
"sFirst": "처음",
"sLast": "마지막",
"sNext": "다음",
"sPrevious": "이전"
},
"oAria": {
"sSortAscending": ": 오름차순 정렬",
"sSortDescending": ": 내림차순 정렬"
}
}

View File

@@ -1,22 +0,0 @@
{
"sEmptyTable": "Lentelėje nėra duomenų",
"sInfo": "Rodomi įrašai nuo _START_ iki _END_ iš _TOTAL_ įrašų",
"sInfoEmpty": "Rodomi įrašai nuo 0 iki 0 iš 0",
"sInfoFiltered": "(atrinkta iš _MAX_ įrašų)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLengthMenu": "Rodyti _MENU_ įrašus",
"sLoadingRecords": "Įkeliama...",
"sProcessing": "Apdorojama...",
"sSearch": "Ieškoti:",
"sThousands": " ",
"sUrl": "",
"sZeroRecords": "Įrašų nerasta",
"oPaginate": {
"sFirst": "Pirmas",
"sPrevious": "Ankstesnis",
"sNext": "Tolimesnis",
"sLast": "Paskutinis"
}
}

View File

@@ -1,22 +0,0 @@
{
"processing": "Uzgaidiet ...",
"search": "Meklēt:",
"lengthMenu": "Rādīt _MENU_ ierakstus",
"info": "Parādīti _START_ līdz _END_ no _TOTAL_ ierakstiem",
"infoEmpty": "Nav ierakstu",
"infoFiltered": "(atlasīts no pavisam _MAX_ ierakstiem)",
"infoPostFix": "",
"loadingRecords": "Notiek ielāde ...",
"zeroRecords": "Nav atrasti vaicājumam atbilstoši ieraksti",
"emptyTable": "Tabulā nav datu",
"paginate": {
"first": "Pirmā",
"previous": "Iepriekšējā",
"next": "Nākošā",
"last": "Pēdējā"
},
"aria": {
"sortAscending": ": aktivizēt kolonnu, lai kārtotu augoši",
"sortDescending": ": aktivizēt kolonnu, lai kārtotu dilstoši"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Хүснэгт хоосон байна",
"sInfo": "Нийт _TOTAL_ бичлэгээс _START_ - _END_ харуулж байна",
"sInfoEmpty": "Тохирох үр дүн алга",
"sInfoFiltered": "(нийт _MAX_ бичлэгээс шүүв)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Дэлгэцэд _MENU_ бичлэг харуулна",
"sLoadingRecords": "Ачааллаж байна...",
"sProcessing": "Боловсруулж байна...",
"sSearch": "Хайлт:",
"sZeroRecords": "Тохирох бичлэг олдсонгүй",
"oPaginate": {
"sFirst": "Эхнийх",
"sLast": "Сүүлийнх",
"sNext": "Өмнөх",
"sPrevious": "Дараах"
},
"oAria": {
"sSortAscending": ": цагаан толгойн дарааллаар эрэмбэлэх",
"sSortDescending": ": цагаан толгойн эсрэг дарааллаар эрэмбэлэх"
}
}

View File

@@ -1,23 +0,0 @@
{
"sEmptyTable": "Tiada data",
"sInfo": "Paparan dari _START_ hingga _END_ dari _TOTAL_ rekod",
"sInfoEmpty": "Paparan 0 hingga 0 dari 0 rekod",
"sInfoFiltered": "(Ditapis dari jumlah _MAX_ rekod)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": "Papar _MENU_ rekod",
"sLoadingRecords": "Diproses...",
"sProcessing": "Sedang diproses...",
"sSearch": "Carian:",
"sZeroRecords": "Tiada padanan rekod yang dijumpai.",
"oPaginate": {
"sFirst": "Pertama",
"sPrevious": "Sebelum",
"sNext": "Kemudian",
"sLast": "Akhir"
},
"oAria": {
"sSortAscending": ": diaktifkan kepada susunan lajur menaik",
"sSortDescending": ": diaktifkan kepada susunan lajur menurun"
}
}

View File

@@ -1,25 +0,0 @@
{
"sEmptyTable": "Ingen data tilgjengelig i tabellen",
"sInfo": "Viser _START_ til _END_ av _TOTAL_ linjer",
"sInfoEmpty": "Viser 0 til 0 av 0 linjer",
"sInfoFiltered": "(filtrert fra _MAX_ totalt antall linjer)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLoadingRecords": "Laster...",
"sLengthMenu": "Vis _MENU_ linjer",
"sLoadingRecords": "Laster...",
"sProcessing": "Laster...",
"sSearch": "S&oslash;k:",
"sUrl": "",
"sZeroRecords": "Ingen linjer matcher s&oslash;ket",
"oPaginate": {
"sFirst": "F&oslash;rste",
"sPrevious": "Forrige",
"sNext": "Neste",
"sLast": "Siste"
},
"oAria": {
"sSortAscending": ": aktiver for å sortere kolonnen stigende",
"sSortDescending": ": aktiver for å sortere kolonnen synkende"
}
}

View File

@@ -1,24 +0,0 @@
{
"sEmptyTable": "टेबलमा डाटा उपलब्ध भएन",
"sInfo": "_TOTAL_ रेकर्ड मध्य _START_ देखि _END_ रेकर्ड देखाउंदै",
"sInfoEmpty": "0 मध्य 0 देखि 0 रेकर्ड देखाउंदै",
"sInfoFiltered": "(_MAX_ कुल रेकर्डबाट छनौट गरिएको)",
"sInfoPostFix": "",
"sInfoThousands": ",",
"sLengthMenu": " _MENU_ रेकर्ड देखाउने ",
"sLoadingRecords": "लोड हुँदैछ...",
"sProcessing": "प्रगति हुदैंछ ...",
"sSearch": "खोजी:",
"sUrl": "",
"sZeroRecords": "कुनै मिल्ने रेकर्ड फेला परेन",
"oPaginate": {
"sFirst": "प्रथम",
"sPrevious": "पछिल्लो",
"sNext": "अघिल्लो",
"sLast": "अन्तिम"
},
"oAria": {
"sSortAscending": ": अगाडिबाट अक्षरात्मक रूपमा क्रमबद्ध गराउने",
"sSortDescending": ": पछाडिबाट अक्षरात्मक रूपमा क्रमबद्ध गराउने"
}
}

View File

@@ -1,23 +0,0 @@
{
"sProcessing": "Bezig...",
"sLengthMenu": "_MENU_ resultaten weergeven",
"sZeroRecords": "Geen resultaten gevonden",
"sInfo": "_START_ tot _END_ van _TOTAL_ resultaten",
"sInfoEmpty": "Geen resultaten om weer te geven",
"sInfoFiltered": " (gefilterd uit _MAX_ resultaten)",
"sInfoPostFix": "",
"sSearch": "Zoeken:",
"sEmptyTable": "Geen resultaten aanwezig in de tabel",
"sInfoThousands": ".",
"sLoadingRecords": "Een moment geduld aub - bezig met laden...",
"oPaginate": {
"sFirst": "Eerste",
"sLast": "Laatste",
"sNext": "Volgende",
"sPrevious": "Vorige"
},
"oAria": {
"sSortAscending": ": activeer om kolom oplopend te sorteren",
"sSortDescending": ": activeer om kolom aflopend te sorteren"
}
}

View File

@@ -1,25 +0,0 @@
{
"sEmptyTable": "Inga data tilgjengeleg i tabellen",
"sInfo": "Syner _START_ til _END_ av _TOTAL_ linjer",
"sInfoEmpty": "Syner 0 til 0 av 0 linjer",
"sInfoFiltered": "(filtrert frå _MAX_ totalt antal linjer)",
"sInfoPostFix": "",
"sInfoThousands": " ",
"sLoadingRecords": "Lastar...",
"sLengthMenu": "Syn _MENU_ linjer",
"sLoadingRecords": "Lastar...",
"sProcessing": "Lastar...",
"sSearch": "S&oslash;k:",
"sUrl": "",
"sZeroRecords": "Inga linjer treff p&aring; s&oslash;ket",
"oPaginate": {
"sFirst": "Fyrste",
"sPrevious": "Forrige",
"sNext": "Neste",
"sLast": "Siste"
},
"oAria": {
"sSortAscending": ": aktiver for å sortere kolonna stigande",
"sSortDescending": ": aktiver for å sortere kolonna synkande"
}
}

View File

@@ -1,22 +0,0 @@
{
"processing": "Przetwarzanie...",
"search": "Szukaj:",
"lengthMenu": "Pokaż _MENU_ pozycji",
"info": "Pozycje od _START_ do _END_ z _TOTAL_ łącznie",
"infoEmpty": "Pozycji 0 z 0 dostępnych",
"infoFiltered": "(filtrowanie spośród _MAX_ dostępnych pozycji)",
"infoPostFix": "",
"loadingRecords": "Wczytywanie...",
"zeroRecords": "Nie znaleziono pasujących pozycji",
"emptyTable": "Brak danych",
"paginate": {
"first": "Pierwsza",
"previous": "Poprzednia",
"next": "Następna",
"last": "Ostatnia"
},
"aria": {
"sortAscending": ": aktywuj, by posortować kolumnę rosnąco",
"sortDescending": ": aktywuj, by posortować kolumnę malejąco"
}
}

View File

@@ -1,22 +0,0 @@
{
"sEmptyTable": "Nenhum registros encontrado",
"sProcessing": "A processar...",
"sLengthMenu": "Mostrar _MENU_ registros",
"sZeroRecords": "Não foram encontrados resultados",
"sInfo": "Mostrando de _START_ até _END_ de _TOTAL_ registros",
"sInfoEmpty": "Mostrando de 0 até 0 de 0 registros",
"sInfoFiltered": "(filtrado de _MAX_ registros no total)",
"sInfoPostFix": "",
"sSearch": "Procurar:",
"sUrl": "",
"oPaginate": {
"sFirst": "Primeiro",
"sPrevious": "Anterior",
"sNext": "Seguinte",
"sLast": "Último"
},
"oAria": {
"sSortAscending": ": Ordenar colunas de forma ascendente",
"sSortDescending": ": Ordenar colunas de forma descendente"
}
}

View File

@@ -1,17 +0,0 @@
{
"sProcessing": "Procesează...",
"sLengthMenu": "Afișează _MENU_ înregistrări pe pagină",
"sZeroRecords": "Nu am găsit nimic - ne pare rău",
"sInfo": "Afișate de la _START_ la _END_ din _TOTAL_ înregistrări",
"sInfoEmpty": "Afișate de la 0 la 0 din 0 înregistrări",
"sInfoFiltered": "(filtrate dintr-un total de _MAX_ înregistrări)",
"sInfoPostFix": "",
"sSearch": "Caută:",
"sUrl": "",
"oPaginate": {
"sFirst": "Prima",
"sPrevious": "Precedenta",
"sNext": "Următoarea",
"sLast": "Ultima"
}
}

View File

@@ -1,22 +0,0 @@
{
"processing": "Подождите...",
"search": "Поиск:",
"lengthMenu": "Показать _MENU_ записей",
"info": "Записи с _START_ до _END_ из _TOTAL_ записей",
"infoEmpty": "Записи с 0 до 0 из 0 записей",
"infoFiltered": "(отфильтровано из _MAX_ записей)",
"infoPostFix": "",
"loadingRecords": "Загрузка записей...",
"zeroRecords": "Записи отсутствуют.",
"emptyTable": "В таблице отсутствуют данные",
"paginate": {
"first": "Первая",
"previous": "Предыдущая",
"next": "Следующая",
"last": "Последняя"
},
"aria": {
"sortAscending": ": активировать для сортировки столбца по возрастанию",
"sortDescending": ": активировать для сортировки столбца по убыванию"
}
}

Some files were not shown because too many files have changed in this diff Show More