├── .gitignore
├── source
├── assets
│ ├── icon_off_48.png
│ ├── icon_on_128.png
│ ├── icon_on_32.png
│ ├── icon_on_48.png
│ ├── montserrat-v12-latin-regular.woff
│ ├── montserrat-v12-latin-regular.woff2
│ ├── icon_on.svg
│ └── icon_off.svg
├── manifest.json
├── options
│ ├── options.html
│ ├── options.css
│ └── options.js
├── popup
│ ├── popup.js
│ ├── popup.html
│ └── popup.css
└── background.js
├── README.md
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | # build files
2 |
3 | *.pem
4 | *.crx
5 | *.zip
6 |
--------------------------------------------------------------------------------
/source/assets/icon_off_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/icon_off_48.png
--------------------------------------------------------------------------------
/source/assets/icon_on_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/icon_on_128.png
--------------------------------------------------------------------------------
/source/assets/icon_on_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/icon_on_32.png
--------------------------------------------------------------------------------
/source/assets/icon_on_48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/icon_on_48.png
--------------------------------------------------------------------------------
/source/assets/montserrat-v12-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/montserrat-v12-latin-regular.woff
--------------------------------------------------------------------------------
/source/assets/montserrat-v12-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ecoify/chrome-extension/HEAD/source/assets/montserrat-v12-latin-regular.woff2
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | What is Ecoify all about?
2 | =========================
3 |
4 | Every time we ask google to search something for us, requests are sent
5 | back and forth, Internet Service Providers need power to keep the
6 | internet running and google needs power for their servers.
7 |
8 | Careful estimates believe that each google search amounts to at least
9 | 0.4 Wh, which in turn amounts to no less than 0.2 g of CO2.
10 |
11 | We want to cut down your own carbon footprint by preventing unneccessary
12 | google searches:
13 |
14 | Every time you enter the name of your favourite website and the browser
15 | triggers a google search, we intercept it and instead open the page
16 | directly for you - while also saving your time and reducing your CO2
17 | emissions!
18 |
--------------------------------------------------------------------------------
/source/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "ecoify",
3 | "manifest_version": 2,
4 | "name": "Ecoify Extension",
5 | "description": "This extension will eco-ify your browsing behaviour.",
6 | "version": "2.0",
7 | "icons": {
8 | "32": "assets/icon_on_32.png",
9 | "48": "assets/icon_on_48.png",
10 | "128": "assets/icon_on_128.png"
11 | },
12 | "browser_action": {
13 | "default_icon": "assets/icon_on_48.png",
14 | "default_popup": "popup/popup.html"
15 | },
16 | "background": {
17 | "scripts": [
18 | "background.js"
19 | ]
20 | },
21 | "options_ui": {
22 | "page": "options/options.html",
23 | "open_in_tab": false
24 | },
25 | "permissions": [
26 | "activeTab",
27 | "webRequest",
28 | "storage",
29 | "unlimitedStorage",
30 | "webRequestBlocking",
31 | "*://*.google.com/*",
32 | "*://*.google.de/*",
33 | "https://5tepzfsmxg.execute-api.eu-central-1.amazonaws.com/*"
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/source/options/options.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Ecoify Options
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
23 | Edit redirects:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 ecoify
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/source/options/options.css:
--------------------------------------------------------------------------------
1 | /* montserrat-regular - latin */
2 | @font-face {
3 | font-family: 'Montserrat';
4 | font-style: normal;
5 | font-weight: 400;
6 | src: local('Montserrat Regular'), local('Montserrat-Regular'),
7 | url('../assets/montserrat-v12-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
8 | url('../assets/montserrat-v12-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
9 | }
10 |
11 | /* Global */
12 |
13 | body {
14 | font-family: Montserrat;
15 | padding: 0;
16 | margin: 0;
17 | }
18 |
19 | .content {
20 | margin-top: 0em;
21 | margin-left: 2em;
22 | margin-right: 2em;
23 | margin-bottom: 2em;
24 |
25 | text-align: center;
26 | }
27 |
28 |
29 | /* Redirects */
30 |
31 | .redirects .label {
32 | font-size: 2em;
33 |
34 | text-align: left;
35 | }
36 |
37 | #redirects-text {
38 | width: 30em;
39 | height: 20em;
40 |
41 | overflow: scroll;
42 | resize: none;
43 | outline: none;
44 | white-space: pre;
45 |
46 | font-size: 1.2em;
47 | text-align: left;
48 | }
49 |
50 | /* Save */
51 |
52 | #save {
53 | padding: 0.5em 1em;
54 | font-size: 2em;
55 | }
56 |
--------------------------------------------------------------------------------
/source/options/options.js:
--------------------------------------------------------------------------------
1 | // background page
2 | bgPage = chrome.extension.getBackgroundPage();
3 |
4 | // Saves options to chrome.storage
5 | function save_options() {
6 | // redirects
7 | let parse_json_error = false;
8 | let newRedirects = {};
9 | try {
10 | newRedirects = JSON.parse(document.getElementById('redirects-text').value);
11 | } catch(e) {
12 | //console.log("Error parsing JSON: ", e);
13 | parse_json_error = true;
14 | }
15 | if (!parse_json_error) {
16 | bgPage.setRedirects(newRedirects);
17 | }
18 |
19 | // stats
20 | const stats_consent = document.getElementById('stats-checkbox').checked;
21 | bgPage.setStatsConsent(stats_consent);
22 |
23 | const status = document.getElementById('status');
24 | if (parse_json_error) {
25 | status.style.color = 'red';
26 | status.textContent = 'Error parsing JSON. NOT SAVED! Check your JSON.';
27 | } else {
28 | status.style.color = 'green';
29 | status.textContent = 'Options saved.';
30 | setTimeout(function() {
31 | status.textContent = '';
32 | window.close();
33 | }, 1500);
34 | }
35 | }
36 |
37 | // loads options from chrome.storage
38 | function restore_options() {
39 | // redirects
40 | document.getElementById('redirects-text').value =
41 | JSON.stringify(bgPage.getRedirects(), null, " ");
42 | document.getElementById('stats-checkbox').checked = bgPage.getStatsConsent();
43 | }
44 |
45 | // init
46 | document.addEventListener('DOMContentLoaded', function() {
47 | document.getElementById('save').addEventListener('click', save_options);
48 | restore_options();
49 | });
50 |
--------------------------------------------------------------------------------
/source/popup/popup.js:
--------------------------------------------------------------------------------
1 | // popup opened
2 | document.addEventListener('DOMContentLoaded', function() {
3 | // background page
4 | var bgPage = chrome.extension.getBackgroundPage();
5 |
6 | // init share buttons
7 | bgPage.readCounter().then((counter) => {
8 | var text = "I saved "+encodeURIComponent(countToCarbon(counter))+" CO2 using Ecoify for Chrome. Join now!";
9 | document.getElementById('share_twitter').href = "https://twitter.com/intent/tweet/?text="+text+"&url=https%3A%2F%2Fecoify.org%2F";
10 | });
11 |
12 | // options page
13 | document.getElementById('options_link').addEventListener('click', function() {
14 | if (chrome.runtime.openOptionsPage) {
15 | chrome.runtime.openOptionsPage();
16 | } else {
17 | window.open(chrome.runtime.getURL('options/options.html'));
18 | }
19 | });
20 |
21 | // toggle
22 | var toggle = document.getElementById('toggle');
23 | bgPage.readToggle().then((new_toggle) => {
24 | toggle.checked = new_toggle;
25 | updateToggle(toggle.checked);
26 | });
27 | toggle.addEventListener('click', function () {
28 | updateToggle(toggle.checked);
29 | });
30 |
31 | // update carbon grams counter
32 | var carbon_grams = document.getElementById('carbon_grams');
33 | bgPage.readCounter().then((counter) => {
34 | carbon_grams.innerHTML = countToCarbon(counter);
35 | });
36 |
37 | }, false);
38 |
39 | function countToCarbon(count) {
40 | new_carbon_grams = count * 0.2;
41 |
42 | var new_carbon_grams_text;
43 | if (new_carbon_grams < 1000) {
44 | new_carbon_grams_text = parseFloat((new_carbon_grams).toFixed(4)) + " g";
45 | } else if (new_carbon_grams < 1000000) {
46 | new_carbon_grams_text = parseFloat((new_carbon_grams / 1000).toFixed(4)) + " kg";
47 | } else {
48 | new_carbon_grams_text = parseFloat((new_carbon_grams / 1000000).toFixed(4)) + " t";
49 | }
50 |
51 | return new_carbon_grams_text;
52 | }
53 |
54 | function updateToggle(toggle) {
55 | var body = document.getElementsByTagName("BODY")[0];
56 | var bgPage = chrome.extension.getBackgroundPage();
57 | if (toggle) {
58 | // listener
59 | bgPage.addReqListener();
60 | // popup background
61 | body.classList.remove('off');
62 | body.classList.add('on');
63 | } else {
64 | // listener
65 | bgPage.removeReqListener();
66 | // popup background
67 | body.classList.remove('on');
68 | body.classList.add('off');
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/source/popup/popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Ecoify
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 | Ecoify your browsing!
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
Skip Google:
28 |
29 |
33 |
34 |
35 |
36 |
39 |
40 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/source/popup/popup.css:
--------------------------------------------------------------------------------
1 | /* montserrat-regular - latin */
2 | @font-face {
3 | font-family: 'Montserrat';
4 | font-style: normal;
5 | font-weight: 400;
6 | src: local('Montserrat Regular'), local('Montserrat-Regular'),
7 | url('../assets/montserrat-v12-latin-regular.woff2') format('woff2'), /* Chrome 26+, Opera 23+, Firefox 39+ */
8 | url('../assets/montserrat-v12-latin-regular.woff') format('woff'); /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
9 | }
10 |
11 | /* Global */
12 |
13 | body {
14 | font-family: Montserrat;
15 | padding: 0;
16 | margin: 0;
17 | }
18 |
19 | body.on {
20 | background-color: #9BCB58;
21 | }
22 |
23 | body.off {
24 | background-color: #e44;
25 | }
26 |
27 |
28 | /* Head */
29 |
30 | .branding {
31 | margin: 0 0 0.7em 0;
32 | width: 100%;
33 |
34 | height: 3em;
35 | line-height: 3em;
36 |
37 | background-color: rgba(0,0,0,0.3);
38 | color: #fff;
39 | font-size: 1.5em;
40 | text-align: center;
41 | }
42 |
43 | .info_link {
44 | position: absolute;
45 | top: 1.4em;
46 | right: 1.4em;
47 | }
48 |
49 | .info_link:focus {
50 | outline:0 !important;
51 | }
52 |
53 | .info_link svg {
54 | width: 1.8em;
55 | height: 1.8em;
56 | }
57 |
58 | #options_link {
59 | position: absolute;
60 | top: 1.4em;
61 | left: 1.4em;
62 | }
63 |
64 | #options_link:focus {
65 | outline:0 !important;
66 | }
67 |
68 | #options_link svg {
69 | width: 1.8em;
70 | height: 1.8em;
71 | }
72 |
73 | /* Content */
74 |
75 | .content {
76 | width: 25em;
77 | text-align: center;
78 | padding: 0 0 1.5em 0;
79 | margin: 0 1em;
80 | }
81 |
82 | .container {
83 | width: 100%;
84 | }
85 |
86 | /* Toggle */
87 |
88 | .container.toggle {
89 | display: table;
90 |
91 | font-size: 1.2em;
92 | color: rgba(0, 0, 0, 0.7);
93 | }
94 |
95 | .container.toggle .label {
96 | display: table-cell;
97 | vertical-align: middle;
98 | text-align: right;
99 | width: 54%;
100 | }
101 |
102 | .container.toggle .switch_container {
103 | display: table-cell;
104 | text-align: left;
105 | padding-left: 0.5em;
106 | }
107 |
108 | /* Saved */
109 |
110 | .container.saved {
111 | margin-top: 1.3em;
112 | }
113 |
114 | .container.saved a {
115 | font-size: 2em;
116 | padding: 0.3em 1em;
117 |
118 | border: 0;
119 | border-radius: 25px;
120 |
121 | background-color: rgba(0, 0, 0, 0.3);
122 | color: #fff;
123 | }
124 |
125 | .container.saved a:hover {
126 | /* color: #aaa;
127 | cursor: pointer; */
128 | }
129 |
130 | /* Share */
131 |
132 | .container.social {
133 | margin-top: 1.5em;
134 | }
135 |
136 | .resp-sharing-button__link,
137 | .resp-sharing-button__icon {
138 | display: inline-block
139 | }
140 |
141 | .resp-sharing-button__link {
142 | text-decoration: none;
143 | color: #fff;
144 | margin: 0.5em
145 | }
146 |
147 | .resp-sharing-button {
148 | border-radius: 5px;
149 | transition: 25ms ease-out;
150 | padding: 0.5em 0.75em;
151 | font-family: Helvetica Neue,Helvetica,Arial,sans-serif
152 | }
153 |
154 | .resp-sharing-button__icon svg {
155 | width: 1em;
156 | height: 1em;
157 | margin-right: 0.4em;
158 | vertical-align: top
159 | }
160 |
161 | .resp-sharing-button--small svg {
162 | margin: 0;
163 | vertical-align: middle
164 | }
165 |
166 | /* Non solid icons get a stroke */
167 | .resp-sharing-button__icon {
168 | stroke: #fff;
169 | fill: none
170 | }
171 |
172 | /* Solid icons get a fill */
173 | .resp-sharing-button__icon--solid,
174 | .resp-sharing-button__icon--solidcircle {
175 | fill: #fff;
176 | stroke: none
177 | }
178 |
179 | .resp-sharing-button--twitter {
180 | background-color: #55acee
181 | }
182 |
183 | .resp-sharing-button--twitter:hover {
184 | background-color: #2795e9
185 | }
186 |
187 | .resp-sharing-button--facebook {
188 | background-color: #3b5998
189 | }
190 |
191 | .resp-sharing-button--facebook:hover {
192 | background-color: #2d4373
193 | }
194 |
195 | .resp-sharing-button--facebook {
196 | background-color: #3b5998;
197 | border-color: #3b5998;
198 | }
199 |
200 | .resp-sharing-button--facebook:hover,
201 | .resp-sharing-button--facebook:active {
202 | background-color: #2d4373;
203 | border-color: #2d4373;
204 | }
205 |
206 | .resp-sharing-button--twitter {
207 | background-color: #55acee;
208 | border-color: #55acee;
209 | }
210 |
211 | .resp-sharing-button--twitter:hover,
212 | .resp-sharing-button--twitter:active {
213 | background-color: #2795e9;
214 | border-color: #2795e9;
215 | }
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 | /* The switch - the box around the slider */
227 | .switch {
228 | position: relative;
229 | display: inline-block;
230 | width: 60px;
231 | height: 34px;
232 | }
233 |
234 | /* Hide default HTML checkbox */
235 | .switch input {display:none;}
236 |
237 | /* The slider */
238 | .slider {
239 | position: absolute;
240 | cursor: pointer;
241 | top: 0;
242 | left: 0;
243 | right: 0;
244 | bottom: 0;
245 | background-color: #ccc;
246 | -webkit-transition: .4s;
247 | transition: .4s;
248 | }
249 |
250 | .slider:before {
251 | position: absolute;
252 | content: "";
253 | height: 26px;
254 | width: 26px;
255 | left: 4px;
256 | bottom: 4px;
257 | background-color: white;
258 | -webkit-transition: .4s;
259 | transition: .4s;
260 | }
261 |
262 | #toggle:checked + .slider {
263 | background-color: #2196F3;
264 | }
265 |
266 | #toggle:focus + .slider {
267 | box-shadow: 0 0 1px #2196F3;
268 | }
269 |
270 | #toggle:checked + .slider:before {
271 | -webkit-transform: translateX(26px);
272 | -ms-transform: translateX(26px);
273 | transform: translateX(26px);
274 | }
275 |
276 | /* Rounded sliders */
277 | .slider.round {
278 | border-radius: 34px;
279 | }
280 |
281 | .slider.round:before {
282 | border-radius: 50%;
283 | }
284 |
285 | .settings.editor{
286 | display:none;
287 | text-align: center;
288 | }
289 | .settings.editor form {
290 | text-align: center;
291 | }
292 |
--------------------------------------------------------------------------------
/source/background.js:
--------------------------------------------------------------------------------
1 | // defaults
2 | const redirects_default = {
3 | 'facebook': 'https://www.facebook.com/',
4 | 'fb': 'https://www.facebook.com/',
5 | 'facebook log in': 'https://www.facebook.com/',
6 | 'facebook login': 'https://www.facebook.com/',
7 | 'facebook.com': 'https://www.facebook.com/',
8 | 'facebook.de': 'https://www.facebook.de/',
9 | 'stackoverflow': 'https://stackoverflow.com/',
10 | 'stackoverflow.com': 'https://stackoverflow.com/',
11 | 'netflix': 'https://www.netflix.com/',
12 | 'netflix.com': 'https://www.netflix.com/',
13 | 'youtube': 'https://www.youtube.com/',
14 | 'youtube.com': 'https://www.youtube.com/',
15 | 'youtube.de': 'https://www.youtube.de/',
16 | 'pinterest': 'https://www.pinterest.de/',
17 | 'gmx': 'https://www.gmx.net/',
18 | 'gmx.net': 'https://www.gmx.net/',
19 | 'gmx.de': 'https://www.gmx.de/',
20 | 'amazon': 'https://www.amazon.com/',
21 | 'amazon.com': 'https://www.amazon.com/',
22 | 'wikipedia': 'https://wikipedia.org/',
23 | 'wikipedia.de': 'https://wikipedia.de/',
24 | 'twitter': 'https://twitter.com/',
25 | 'twitter.com': 'https://twitter.com/',
26 | 'ebay': 'https://www.ebay.com/',
27 | 'ebay.com': 'https://www.ebay.com/',
28 | 'instagram': 'https://www.instagram.com/',
29 | 'instagram.com': 'https://www.instagram.com/',
30 | };
31 |
32 | let req_listener_active = false;
33 | let userId = '';
34 | getBrowserId()
35 | .then(result => {
36 | userId = result;
37 | })
38 |
39 | function getRedirects() {
40 | return this.redirects;
41 | }
42 |
43 | function setRedirects(redirects) {
44 | this.redirects = redirects;
45 | setData('redirects', redirects);
46 | }
47 |
48 | function getStatsConsent() {
49 | return this.stats_consent;
50 | }
51 |
52 | function setStatsConsent(stats_consent) {
53 | this.stats_consent = stats_consent;
54 | setData('stats_consent', stats_consent);
55 | }
56 |
57 | function getDataWithDefault(sKey, default_value) {
58 | return new Promise((resolve, reject) => {
59 | const data = {}
60 | data[sKey] = default_value;
61 | chrome.storage.sync.get(data, (items) => {
62 | if (chrome.runtime.lastError) {
63 | console.error(chrome.runtime.lastError.message);
64 | reject(chrome.runtime.lastError.message);
65 | } else {
66 | resolve(items[sKey]);
67 | }
68 | });
69 | });
70 | }
71 |
72 | function getData(sKey) {
73 | return new Promise((resolve, reject) => {
74 | chrome.storage.sync.get(sKey, (items) => {
75 | if (chrome.runtime.lastError) {
76 | console.error(chrome.runtime.lastError.message);
77 | reject(chrome.runtime.lastError.message);
78 | } else {
79 | resolve(items[sKey]);
80 | }
81 | });
82 | });
83 | }
84 |
85 | function setData(sKey, sValue) {
86 | return new Promise((resolve, reject) => {
87 | const data = {}
88 | data[sKey] = sValue
89 | chrome.storage.sync.set(data, () => {
90 | if (chrome.runtime.lastError) {
91 | console.error(chrome.runtime.lastError.message);
92 | reject(chrome.runtime.lastError.message);
93 | } else {
94 | resolve(true);
95 | }
96 | });
97 | });
98 | }
99 |
100 | function readToggle() {
101 | return new Promise((resolve, reject) => {
102 | getData('ecoify_toggle').then((ecoify_toggle) => {
103 | if (typeof ecoify_toggle === 'undefined' || isNaN(ecoify_toggle)) {
104 | ecoify_toggle = true;
105 | }
106 | resolve(ecoify_toggle)
107 | })
108 | })
109 | }
110 |
111 | function setToggle(new_ecoify_toggle) {
112 | setData('ecoify_toggle', new_ecoify_toggle);
113 | }
114 |
115 | function setBrowserId() {
116 | var browserId = Date.now() + '-' + Math.floor(Math.random() * Math.floor(Date.now()));
117 | setData('browserId', browserId)
118 | return browserId
119 | }
120 |
121 | function getBrowserId() {
122 | return new Promise((resolve, reject) => {
123 | getData('browserId').then((browserId) => {
124 | if (browserId) {
125 | browserId = setBrowserId();
126 | }
127 | resolve(browserId)
128 | })
129 | })
130 | }
131 |
132 | function readCounter() {
133 | return new Promise((resolve, reject) => {
134 | getData('blockedCounter').then((counter) => {
135 | if (tisNaN(counter)) {
136 | counter = 0;
137 | }
138 | resolve(counter)
139 | })
140 | })
141 | }
142 |
143 | function increaseCounter() {
144 | readCounter().then((counter) => {
145 | const thisCounter = counter + 1
146 | setData('blockedCounter', thisCounter);
147 | if (thisCounter % 11 == 0) {
148 | if (this.stats_consent) {
149 | const data = {carbon: thisCounter * 0.2};
150 | const xhr = new XMLHttpRequest();
151 | xhr.open('PUT', 'https://5tepzfsmxg.execute-api.eu-central-1.amazonaws.com/dev/carbon/' + userId, true);
152 | xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
153 | xhr.send(JSON.stringify(data));
154 | }
155 | }
156 | })
157 | }
158 |
159 | function req_callback(details) {
160 | try {
161 | if (/[&?]q=(.+?)&/.test(details.url) && /[&?]oq=(.+?)&/.test(details.url)) {
162 | const term = details.url.match(/[&?]q=(.+?)&/)[1]
163 | if (this.redirects && this.redirects[term]) {
164 | increaseCounter()
165 | return { redirectUrl: this.redirects[term] };
166 | }
167 | }
168 | }
169 | catch (error) {
170 | console.error(error);
171 | }
172 | };
173 |
174 | const filter = { urls: ['*://*.google.de/*', '*://*.google.com/*'] };
175 | const extraInfoSpec = ['blocking'];
176 | function addReqListener() {
177 | if (!req_listener_active) {
178 | chrome.webRequest.onBeforeRequest.addListener(req_callback, filter, extraInfoSpec);
179 | req_listener_active = true;
180 | setToggle(true);
181 | }
182 | chrome.browserAction.setIcon({ path: '../assets/icon_on_48.png' });
183 | }
184 |
185 | function removeReqListener() {
186 | if (req_listener_active) {
187 | chrome.webRequest.onBeforeRequest.removeListener(req_callback);
188 | req_listener_active = false;
189 | setToggle(false);
190 | }
191 | chrome.browserAction.setIcon({ path: '../assets/icon_off_48.png' });
192 | }
193 |
194 | const startup = () => {
195 | getDataWithDefault('redirects', redirects_default)
196 | .then((redirects) => {
197 | this.redirects = redirects;
198 | });
199 |
200 | getDataWithDefault('stats_consent', true)
201 | .then((stats_consent) => {
202 | this.stats_consent = stats_consent;
203 | });
204 |
205 | readToggle()
206 | .then((toggle) => {
207 | if (toggle) {
208 | addReqListener();
209 | } else {
210 | removeReqListener();
211 | }
212 | });
213 | }
214 |
215 | startup();
216 |
--------------------------------------------------------------------------------
/source/assets/icon_on.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/source/assets/icon_off.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------