├── .eslintignore
├── .eslintrc.json
├── .gitattributes
├── .gitignore
├── .gitmodules
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
└── images
│ ├── lightbeam-launch.gif
│ ├── lightbeam.gif
│ └── lightbeam.png
├── karma.conf.js
├── package.json
├── src
├── css
│ ├── OpenSans.css
│ ├── first-run.css
│ └── style.css
├── first-run.html
├── fonts
│ ├── OpenSans-Bold.ttf
│ ├── OpenSans-Light.ttf
│ ├── OpenSans-LightItalic.ttf
│ └── OpenSans-Regular.ttf
├── images
│ ├── defaultFavicon.svg
│ ├── lightbeam-48.png
│ ├── lightbeam-96.png
│ ├── lightbeam-icon-charcoal.svg
│ ├── lightbeam-icon.svg
│ ├── lightbeam_150x45.png
│ ├── lightbeam_dialog_warningreset.png
│ ├── lightbeam_icon_about.png
│ ├── lightbeam_icon_download.png
│ ├── lightbeam_icon_feedback.png
│ ├── lightbeam_icon_graph.png
│ ├── lightbeam_icon_help.png
│ ├── lightbeam_icon_list.png
│ ├── lightbeam_icon_reset.png
│ ├── lightbeam_icon_website.png
│ ├── lightbeam_logo-only_16x16.png
│ └── lightbeam_logo-wordmark_300x150.png
├── index.html
├── js
│ ├── background.js
│ ├── capture.js
│ ├── lightbeam.js
│ ├── store.js
│ ├── storeChild.js
│ └── viz.js
└── manifest.json
└── test
└── unit
└── store.test.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | /shavar-prod-lists/*
2 | /src/ext-libs/*
3 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "mocha": true
6 | },
7 | "globals": {
8 | "browser": true,
9 | "store": true,
10 | "storeChild": true,
11 | "capture": true,
12 | "lightbeam": true,
13 | "viz": true,
14 | "d3": true,
15 | "Dexie": true
16 | },
17 | "plugins": [
18 | "json",
19 | "mocha",
20 | "no-unsanitized"
21 | ],
22 | "extends": ["eslint:recommended"],
23 | "parserOptions": {
24 | "ecmaVersion": "2017"
25 | },
26 | "rules": {
27 | "no-unsanitized/method": "error",
28 | "no-unsanitized/property": "error",
29 | "space-infix-ops": [
30 | "error"
31 | ],
32 | "indent": [
33 | "error",
34 | 2,
35 | {
36 | "CallExpression":
37 | { "arguments": 1 },
38 | "FunctionDeclaration":
39 | { "parameters": 1 },
40 | "SwitchCase": 1
41 | }
42 | ],
43 | "linebreak-style": [
44 | "error",
45 | "unix"
46 | ],
47 | "object-property-newline": [
48 | "error"
49 | ],
50 | "no-multi-assign": [
51 | "error"
52 | ],
53 | "no-new-object": [
54 | "error"
55 | ],
56 | "func-call-spacing": [
57 | "error",
58 | "never"
59 | ],
60 | "brace-style": [
61 | "error",
62 | "1tbs"
63 | ],
64 | "object-curly-newline": [
65 | "error",
66 | {"multiline": true}
67 | ],
68 | "no-implied-eval": [
69 | "error"
70 | ],
71 | "operator-linebreak": [
72 | "error",
73 | "before"
74 | ],
75 | "no-lonely-if": [
76 | "error"
77 | ],
78 | "no-multi-str": [
79 | "error"
80 | ],
81 | "prefer-const": [
82 | "error"
83 | ],
84 | "prefer-template": [
85 | "error"
86 | ],
87 | "require-await": [
88 | "error"
89 | ],
90 | "spaced-comment": [
91 | "error",
92 | "always"
93 | ],
94 | "max-len": [
95 | "error", {
96 | "code": 80,
97 | "tabWidth": 2,
98 | "ignoreUrls": true
99 | }
100 | ],
101 | "semi": [
102 | "error",
103 | "always"
104 | ],
105 | "quotes": [
106 | "error",
107 | "single"
108 | ],
109 | "no-trailing-spaces": [
110 | "error"
111 | ],
112 | "keyword-spacing": [
113 | "error", {
114 | "before": true,
115 | "after": true
116 | }
117 | ],
118 | "space-before-blocks": [
119 | "error", {
120 | "functions": "always",
121 | "keywords": "always"
122 | }
123 | ],
124 | "arrow-body-style": [
125 | "error",
126 | "always"
127 | ]
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | text eol=lf
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | npm-debug.log
4 | src/ext-libs
5 | src/web-ext-artifacts
6 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "shavar-prod-lists"]
2 | path = shavar-prod-lists
3 | url = https://github.com/mozilla-services/shavar-prod-lists.git
4 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | addons:
2 | firefox: latest
3 | before_script:
4 | - export DISPLAY=:99.0
5 | - sh -e /etc/init.d/xvfb start
6 | - sleep 3
7 | language: node_js
8 | node_js:
9 | - '6.1'
10 | notifications:
11 | slack:
12 | secure: B+WoTn0JfBWEdFZ8hKzXdYLc2W5cwngBrLoW9YM2jBFcXvidW8m/Aslq7koRw8F21R/sYlqtA1bYssmBBya4dLzGNZZA0+R8g0rwJwg5FjpJ/1DYfz7u5f/nhe5K2Wll7+4EPfuhN8LfK+38te6JBOc0xGBZdawTvFZkF2hBljFf2+YWutiUg9Vzmr/q51DffDCV9mziYGH+M30WBCTa9f+m7YNvAJxWzF3ckBLLhDUOj74P1a2bua2RICV3KZoVt2KeZ3VdERDk2xtRlqThJALJJzb/x8nkisb/DKWzuYzwrrtyT9IH/86tOz2rh/Dex26VH3piD76SqAl2VAjuS8TzIbKoXDxKLYyRNeAeLCNyiMT7049g5tTxug1sQ4uVAz97jH+sqP1CG3V67RhHRhC2zm6zKrU8biqoYLzFIKYUuYHHhek+2zizvYAzL5Z0z0+0VbtCd4zo5cL013jDvzzoFRmNKDMZqWjW52qYFrZDAccu5dNUuY7eXhnkQFC+Z1XY1WucBNyDg7O4iBTEy9RgkxapfCKqGPJKknArKD5YGp4xgnT/5g9mGQuRYtn86qzZVS76hKhSN15J9arjDRHNJYm/HVGRqWMFkCIolcrtRkyUFiiQgOMPCoNk7a2nPif0IgY5TqIxMojsF5jDoKzRT3JQ4TvJ6Ng7l5b6IDw=
13 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Community Participation Guidelines
2 |
3 | This repository is governed by Mozilla's code of conduct and etiquette guidelines.
4 | For more details, please read the
5 | [Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
6 |
7 | ## How to Report
8 | For more information on how to report violations of the Community Participation Guidelines, please read our [How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/) page.
9 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Everyone is welcome to contribute to Lightbeam. Reach out to team members if you have questions:
4 |
5 | - Email: lightbeam-feedback@mozilla.org
6 |
7 | ## Filing bugs
8 |
9 | If you find a bug with Lightbeam, please file an issue.
10 |
11 | Check first if the bug might already exist: [Existing issues](https://github.com/mozilla/lightbeam-we/issues)
12 |
13 | [Open an issue](https://github.com/mozilla/lightbeam-we/issues/new)
14 |
15 | 1. Visit `about:support`
16 | 2. Click "Copy raw data to clipboard" and paste into the bug. Alternatively, copy the following sections into the issue:
17 | - Application Basics
18 | - Nightly Features (if you are in Nightly)
19 | - Extensions
20 | - Experimental Features
21 | 3. Include clear steps to reproduce the issue you have experienced.
22 | 4. Include screenshots if possible.
23 |
24 | ## Sending Pull Requests
25 |
26 | Patches should be submitted as pull requests. When submitting patches as PRs:
27 |
28 | - You agree to license your code under the project's open source license (MPL 2.0).
29 | - Base your branch off the current master (see below for an example workflow).
30 | - Add both your code and new tests if relevant.
31 | - Run `npm test` to make sure all tests still pass.
32 | - Please do not include merge commits in pull requests; include only commits with the new relevant code.
33 |
34 | See the main [README](./README.md) for information on prerequisites, installing, running and testing.
35 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Mozilla Public License Version 2.0
2 | ==================================
3 |
4 | 1. Definitions
5 | --------------
6 |
7 | 1.1. "Contributor"
8 | means each individual or legal entity that creates, contributes to
9 | the creation of, or owns Covered Software.
10 |
11 | 1.2. "Contributor Version"
12 | means the combination of the Contributions of others (if any) used
13 | by a Contributor and that particular Contributor's Contribution.
14 |
15 | 1.3. "Contribution"
16 | means Covered Software of a particular Contributor.
17 |
18 | 1.4. "Covered Software"
19 | means Source Code Form to which the initial Contributor has attached
20 | the notice in Exhibit A, the Executable Form of such Source Code
21 | Form, and Modifications of such Source Code Form, in each case
22 | including portions thereof.
23 |
24 | 1.5. "Incompatible With Secondary Licenses"
25 | means
26 |
27 | (a) that the initial Contributor has attached the notice described
28 | in Exhibit B to the Covered Software; or
29 |
30 | (b) that the Covered Software was made available under the terms of
31 | version 1.1 or earlier of the License, but not also under the
32 | terms of a Secondary License.
33 |
34 | 1.6. "Executable Form"
35 | means any form of the work other than Source Code Form.
36 |
37 | 1.7. "Larger Work"
38 | means a work that combines Covered Software with other material, in
39 | a separate file or files, that is not Covered Software.
40 |
41 | 1.8. "License"
42 | means this document.
43 |
44 | 1.9. "Licensable"
45 | means having the right to grant, to the maximum extent possible,
46 | whether at the time of the initial grant or subsequently, any and
47 | all of the rights conveyed by this License.
48 |
49 | 1.10. "Modifications"
50 | means any of the following:
51 |
52 | (a) any file in Source Code Form that results from an addition to,
53 | deletion from, or modification of the contents of Covered
54 | Software; or
55 |
56 | (b) any new file in Source Code Form that contains any Covered
57 | Software.
58 |
59 | 1.11. "Patent Claims" of a Contributor
60 | means any patent claim(s), including without limitation, method,
61 | process, and apparatus claims, in any patent Licensable by such
62 | Contributor that would be infringed, but for the grant of the
63 | License, by the making, using, selling, offering for sale, having
64 | made, import, or transfer of either its Contributions or its
65 | Contributor Version.
66 |
67 | 1.12. "Secondary License"
68 | means either the GNU General Public License, Version 2.0, the GNU
69 | Lesser General Public License, Version 2.1, the GNU Affero General
70 | Public License, Version 3.0, or any later versions of those
71 | licenses.
72 |
73 | 1.13. "Source Code Form"
74 | means the form of the work preferred for making modifications.
75 |
76 | 1.14. "You" (or "Your")
77 | means an individual or a legal entity exercising rights under this
78 | License. For legal entities, "You" includes any entity that
79 | controls, is controlled by, or is under common control with You. For
80 | purposes of this definition, "control" means (a) the power, direct
81 | or indirect, to cause the direction or management of such entity,
82 | whether by contract or otherwise, or (b) ownership of more than
83 | fifty percent (50%) of the outstanding shares or beneficial
84 | ownership of such entity.
85 |
86 | 2. License Grants and Conditions
87 | --------------------------------
88 |
89 | 2.1. Grants
90 |
91 | Each Contributor hereby grants You a world-wide, royalty-free,
92 | non-exclusive license:
93 |
94 | (a) under intellectual property rights (other than patent or trademark)
95 | Licensable by such Contributor to use, reproduce, make available,
96 | modify, display, perform, distribute, and otherwise exploit its
97 | Contributions, either on an unmodified basis, with Modifications, or
98 | as part of a Larger Work; and
99 |
100 | (b) under Patent Claims of such Contributor to make, use, sell, offer
101 | for sale, have made, import, and otherwise transfer either its
102 | Contributions or its Contributor Version.
103 |
104 | 2.2. Effective Date
105 |
106 | The licenses granted in Section 2.1 with respect to any Contribution
107 | become effective for each Contribution on the date the Contributor first
108 | distributes such Contribution.
109 |
110 | 2.3. Limitations on Grant Scope
111 |
112 | The licenses granted in this Section 2 are the only rights granted under
113 | this License. No additional rights or licenses will be implied from the
114 | distribution or licensing of Covered Software under this License.
115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a
116 | Contributor:
117 |
118 | (a) for any code that a Contributor has removed from Covered Software;
119 | or
120 |
121 | (b) for infringements caused by: (i) Your and any other third party's
122 | modifications of Covered Software, or (ii) the combination of its
123 | Contributions with other software (except as part of its Contributor
124 | Version); or
125 |
126 | (c) under Patent Claims infringed by Covered Software in the absence of
127 | its Contributions.
128 |
129 | This License does not grant any rights in the trademarks, service marks,
130 | or logos of any Contributor (except as may be necessary to comply with
131 | the notice requirements in Section 3.4).
132 |
133 | 2.4. Subsequent Licenses
134 |
135 | No Contributor makes additional grants as a result of Your choice to
136 | distribute the Covered Software under a subsequent version of this
137 | License (see Section 10.2) or under the terms of a Secondary License (if
138 | permitted under the terms of Section 3.3).
139 |
140 | 2.5. Representation
141 |
142 | Each Contributor represents that the Contributor believes its
143 | Contributions are its original creation(s) or it has sufficient rights
144 | to grant the rights to its Contributions conveyed by this License.
145 |
146 | 2.6. Fair Use
147 |
148 | This License is not intended to limit any rights You have under
149 | applicable copyright doctrines of fair use, fair dealing, or other
150 | equivalents.
151 |
152 | 2.7. Conditions
153 |
154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
155 | in Section 2.1.
156 |
157 | 3. Responsibilities
158 | -------------------
159 |
160 | 3.1. Distribution of Source Form
161 |
162 | All distribution of Covered Software in Source Code Form, including any
163 | Modifications that You create or to which You contribute, must be under
164 | the terms of this License. You must inform recipients that the Source
165 | Code Form of the Covered Software is governed by the terms of this
166 | License, and how they can obtain a copy of this License. You may not
167 | attempt to alter or restrict the recipients' rights in the Source Code
168 | Form.
169 |
170 | 3.2. Distribution of Executable Form
171 |
172 | If You distribute Covered Software in Executable Form then:
173 |
174 | (a) such Covered Software must also be made available in Source Code
175 | Form, as described in Section 3.1, and You must inform recipients of
176 | the Executable Form how they can obtain a copy of such Source Code
177 | Form by reasonable means in a timely manner, at a charge no more
178 | than the cost of distribution to the recipient; and
179 |
180 | (b) You may distribute such Executable Form under the terms of this
181 | License, or sublicense it under different terms, provided that the
182 | license for the Executable Form does not attempt to limit or alter
183 | the recipients' rights in the Source Code Form under this License.
184 |
185 | 3.3. Distribution of a Larger Work
186 |
187 | You may create and distribute a Larger Work under terms of Your choice,
188 | provided that You also comply with the requirements of this License for
189 | the Covered Software. If the Larger Work is a combination of Covered
190 | Software with a work governed by one or more Secondary Licenses, and the
191 | Covered Software is not Incompatible With Secondary Licenses, this
192 | License permits You to additionally distribute such Covered Software
193 | under the terms of such Secondary License(s), so that the recipient of
194 | the Larger Work may, at their option, further distribute the Covered
195 | Software under the terms of either this License or such Secondary
196 | License(s).
197 |
198 | 3.4. Notices
199 |
200 | You may not remove or alter the substance of any license notices
201 | (including copyright notices, patent notices, disclaimers of warranty,
202 | or limitations of liability) contained within the Source Code Form of
203 | the Covered Software, except that You may alter any license notices to
204 | the extent required to remedy known factual inaccuracies.
205 |
206 | 3.5. Application of Additional Terms
207 |
208 | You may choose to offer, and to charge a fee for, warranty, support,
209 | indemnity or liability obligations to one or more recipients of Covered
210 | Software. However, You may do so only on Your own behalf, and not on
211 | behalf of any Contributor. You must make it absolutely clear that any
212 | such warranty, support, indemnity, or liability obligation is offered by
213 | You alone, and You hereby agree to indemnify every Contributor for any
214 | liability incurred by such Contributor as a result of warranty, support,
215 | indemnity or liability terms You offer. You may include additional
216 | disclaimers of warranty and limitations of liability specific to any
217 | jurisdiction.
218 |
219 | 4. Inability to Comply Due to Statute or Regulation
220 | ---------------------------------------------------
221 |
222 | If it is impossible for You to comply with any of the terms of this
223 | License with respect to some or all of the Covered Software due to
224 | statute, judicial order, or regulation then You must: (a) comply with
225 | the terms of this License to the maximum extent possible; and (b)
226 | describe the limitations and the code they affect. Such description must
227 | be placed in a text file included with all distributions of the Covered
228 | Software under this License. Except to the extent prohibited by statute
229 | or regulation, such description must be sufficiently detailed for a
230 | recipient of ordinary skill to be able to understand it.
231 |
232 | 5. Termination
233 | --------------
234 |
235 | 5.1. The rights granted under this License will terminate automatically
236 | if You fail to comply with any of its terms. However, if You become
237 | compliant, then the rights granted under this License from a particular
238 | Contributor are reinstated (a) provisionally, unless and until such
239 | Contributor explicitly and finally terminates Your grants, and (b) on an
240 | ongoing basis, if such Contributor fails to notify You of the
241 | non-compliance by some reasonable means prior to 60 days after You have
242 | come back into compliance. Moreover, Your grants from a particular
243 | Contributor are reinstated on an ongoing basis if such Contributor
244 | notifies You of the non-compliance by some reasonable means, this is the
245 | first time You have received notice of non-compliance with this License
246 | from such Contributor, and You become compliant prior to 30 days after
247 | Your receipt of the notice.
248 |
249 | 5.2. If You initiate litigation against any entity by asserting a patent
250 | infringement claim (excluding declaratory judgment actions,
251 | counter-claims, and cross-claims) alleging that a Contributor Version
252 | directly or indirectly infringes any patent, then the rights granted to
253 | You by any and all Contributors for the Covered Software under Section
254 | 2.1 of this License shall terminate.
255 |
256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all
257 | end user license agreements (excluding distributors and resellers) which
258 | have been validly granted by You or Your distributors under this License
259 | prior to termination shall survive termination.
260 |
261 | ************************************************************************
262 | * *
263 | * 6. Disclaimer of Warranty *
264 | * ------------------------- *
265 | * *
266 | * Covered Software is provided under this License on an "as is" *
267 | * basis, without warranty of any kind, either expressed, implied, or *
268 | * statutory, including, without limitation, warranties that the *
269 | * Covered Software is free of defects, merchantable, fit for a *
270 | * particular purpose or non-infringing. The entire risk as to the *
271 | * quality and performance of the Covered Software is with You. *
272 | * Should any Covered Software prove defective in any respect, You *
273 | * (not any Contributor) assume the cost of any necessary servicing, *
274 | * repair, or correction. This disclaimer of warranty constitutes an *
275 | * essential part of this License. No use of any Covered Software is *
276 | * authorized under this License except under this disclaimer. *
277 | * *
278 | ************************************************************************
279 |
280 | ************************************************************************
281 | * *
282 | * 7. Limitation of Liability *
283 | * -------------------------- *
284 | * *
285 | * Under no circumstances and under no legal theory, whether tort *
286 | * (including negligence), contract, or otherwise, shall any *
287 | * Contributor, or anyone who distributes Covered Software as *
288 | * permitted above, be liable to You for any direct, indirect, *
289 | * special, incidental, or consequential damages of any character *
290 | * including, without limitation, damages for lost profits, loss of *
291 | * goodwill, work stoppage, computer failure or malfunction, or any *
292 | * and all other commercial damages or losses, even if such party *
293 | * shall have been informed of the possibility of such damages. This *
294 | * limitation of liability shall not apply to liability for death or *
295 | * personal injury resulting from such party's negligence to the *
296 | * extent applicable law prohibits such limitation. Some *
297 | * jurisdictions do not allow the exclusion or limitation of *
298 | * incidental or consequential damages, so this exclusion and *
299 | * limitation may not apply to You. *
300 | * *
301 | ************************************************************************
302 |
303 | 8. Litigation
304 | -------------
305 |
306 | Any litigation relating to this License may be brought only in the
307 | courts of a jurisdiction where the defendant maintains its principal
308 | place of business and such litigation shall be governed by laws of that
309 | jurisdiction, without reference to its conflict-of-law provisions.
310 | Nothing in this Section shall prevent a party's ability to bring
311 | cross-claims or counter-claims.
312 |
313 | 9. Miscellaneous
314 | ----------------
315 |
316 | This License represents the complete agreement concerning the subject
317 | matter hereof. If any provision of this License is held to be
318 | unenforceable, such provision shall be reformed only to the extent
319 | necessary to make it enforceable. Any law or regulation which provides
320 | that the language of a contract shall be construed against the drafter
321 | shall not be used to construe this License against a Contributor.
322 |
323 | 10. Versions of the License
324 | ---------------------------
325 |
326 | 10.1. New Versions
327 |
328 | Mozilla Foundation is the license steward. Except as provided in Section
329 | 10.3, no one other than the license steward has the right to modify or
330 | publish new versions of this License. Each version will be given a
331 | distinguishing version number.
332 |
333 | 10.2. Effect of New Versions
334 |
335 | You may distribute the Covered Software under the terms of the version
336 | of the License under which You originally received the Covered Software,
337 | or under the terms of any subsequent version published by the license
338 | steward.
339 |
340 | 10.3. Modified Versions
341 |
342 | If you create software not governed by this License, and you want to
343 | create a new license for such software, you may create and use a
344 | modified version of this License if you rename the license and remove
345 | any references to the name of the license steward (except to note that
346 | such modified license differs from this License).
347 |
348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary
349 | Licenses
350 |
351 | If You choose to distribute Source Code Form that is Incompatible With
352 | Secondary Licenses under the terms of this version of the License, the
353 | notice described in Exhibit B of this License must be attached.
354 |
355 | Exhibit A - Source Code Form License Notice
356 | -------------------------------------------
357 |
358 | This Source Code Form is subject to the terms of the Mozilla Public
359 | License, v. 2.0. If a copy of the MPL was not distributed with this
360 | file, You can obtain one at http://mozilla.org/MPL/2.0/.
361 |
362 | If it is not possible or desirable to put the notice in a particular
363 | file, then You may include the notice in a location (such as a LICENSE
364 | file in a relevant directory) where a recipient would be likely to look
365 | for such a notice.
366 |
367 | You may add additional accurate notices of copyright ownership.
368 |
369 | Exhibit B - "Incompatible With Secondary Licenses" Notice
370 | ---------------------------------------------------------
371 |
372 | This Source Code Form is "Incompatible With Secondary Licenses", as
373 | defined by the Mozilla Public License, v. 2.0.
374 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Firefox Lightbeam
2 | This is the web extension version of the Firefox Lightbeam add-on for visualizing HTTP requests between websites in real time.
3 |
4 | The Firefox Lightbeam extension by Mozilla is a key tool for Mozilla to educate the public about privacy.
5 |
6 | 
7 |
8 | ## Quick Start
9 |
10 | ### Clone the repository
11 |
12 | **Note** This repository uses a [submodule](https://github.com/mozilla-services/shavar-prod-lists) to allow some third party requests. To ensure the submodule is cloned along with this repository, use a modified `clone` command:
13 | `git clone --recursive https://github.com/mozilla/lightbeam-we.git`
14 |
15 | ### Run the web extension
16 |
17 | There are a couple ways to try out this web extension:
18 |
19 | 1. Open Firefox and load `about:debugging` in the URL bar.
20 | - Click the [Load Temporary Add-on](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Temporary_Installation_in_Firefox) button and select the `manifest.json` file within the directory of this repository.
21 | - You should now see the Lightbeam icon on the top right bar of the browser.
22 | - Click the Lightbeam icon to launch the web extension.
23 |
24 | 2. Install the [web-ext](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext) tool, change into the `src` directory of this repository, and type `web-ext run`.
25 | - This will launch Firefox and install the extension automatically.
26 | - This tool gives you some additional development features such as [automatic reloading](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Getting_started_with_web-ext#Automatic_extension_reloading).
27 |
28 | ## Development Guide
29 |
30 | ### Download dependencies
31 | Run `npm run build`.
32 |
33 | ### Update the submodule
34 | To manually update the submodule at any time during development, run `git submodule update`.
35 |
36 | ### Testing
37 | Run `npm run test` to check that everything is OK.
38 |
39 | * If you have installed `eslint` globally, you will have to install globally the following `eslint` plugins too:
40 | - `eslint-plugin-json`
41 | - `eslint-plugin-mocha`
42 | * Test suites include lint and unit testing. You can individually run lint or unit tests using the following commands:
43 | * `npm run lint:eslint`
44 | * `npm run test:karma`
45 |
46 | Eslint is used for linting. Karma, Mocha & Chai are used for unit testing. Additionally the test suites are run on the Travis service providing continuous integration support.
47 |
--------------------------------------------------------------------------------
/docs/images/lightbeam-launch.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/lightbeam-we/ddd4c0545a43b3e3ba435adf137308571587d211/docs/images/lightbeam-launch.gif
--------------------------------------------------------------------------------
/docs/images/lightbeam.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/lightbeam-we/ddd4c0545a43b3e3ba435adf137308571587d211/docs/images/lightbeam.gif
--------------------------------------------------------------------------------
/docs/images/lightbeam.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mozilla/lightbeam-we/ddd4c0545a43b3e3ba435adf137308571587d211/docs/images/lightbeam.png
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | /* eslint no-undef: "off" */
2 |
3 | /*
4 | * @todo resolve 'module' is undefined and turn 'on' the eslint rule
5 | */
6 |
7 | module.exports = function(config) {
8 | config.set({
9 | singleRun: true,
10 | browsers: ['Firefox'],
11 | frameworks: ['mocha', 'chai'],
12 | files: [
13 | 'test/unit/*.test.js'
14 | ],
15 | plugins: [
16 | 'karma-chai',
17 | 'karma-firefox-launcher',
18 | 'karma-mocha'
19 | ]
20 | });
21 | };
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "lightbeam-we",
3 | "version": "2.1.0",
4 | "description": "Firefox Lightbeam web extension",
5 | "main": "background.js",
6 | "scripts": {
7 | "build": "npm install && npm run updatesubmodule && npm run createlib && cd src && web-ext build --overwrite-dest",
8 | "updatesubmodule": "git submodule init && git submodule update",
9 | "createlib": "cd src && rm -rf ext-libs/ && mkdir ext-libs && npm run movelibcontents",
10 | "movelibcontents": "cp node_modules/dexie/dist/dexie.js src/ext-libs && cp node_modules/d3/build/d3.min.js src/ext-libs && cp node_modules/dialog-polyfill/dialog-polyfill.js src/ext-libs && node node_modules/json/lib/json.js -f shavar-prod-lists/disconnect-entitylist.json > src/ext-libs/disconnect-entitylist.json",
11 | "lint": "npm-run-all lint:*",
12 | "lint:eslint": "eslint --ext=.js,.json .",
13 | "lint:webext": "web-ext -s js lint",
14 | "precommit": "npm run lint:eslint",
15 | "prepush": "npm run test",
16 | "test": "npm-run-all test:*",
17 | "test:lint": "npm run lint:eslint",
18 | "test:karma": "karma start --browsers Firefox --single-run"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/mozilla/lightbeam-we.git"
23 | },
24 | "author": "Mozilla",
25 | "license": "MPL-2.0",
26 | "bugs": {
27 | "url": "https://github.com/mozilla/lightbeam-we/issues"
28 | },
29 | "homepage": "https://github.com/mozilla/lightbeam-we/blob/master/README.md",
30 | "dependencies": {
31 | "d3": "^4.9.1",
32 | "dexie": "^2.0.1",
33 | "dialog-polyfill": "^0.4.9"
34 | },
35 | "devDependencies": {
36 | "chai": "^3.5.0",
37 | "eslint": "^3.19.0",
38 | "eslint-plugin-json": "^1.2.0",
39 | "eslint-plugin-mocha": "^4.9.0",
40 | "eslint-plugin-no-unsanitized": "^2.0.0",
41 | "husky": "^0.13.4",
42 | "json": "^9.0.6",
43 | "karma": "^1.7.0",
44 | "karma-chai": "^0.1.0",
45 | "karma-firefox-launcher": "^1.0.1",
46 | "karma-mocha": "^1.3.0",
47 | "mocha": "^3.4.1",
48 | "npm-run-all": "^4.0.2",
49 | "sinon": "^2.3.1",
50 | "sinon-chrome": "^2.2.1"
51 | },
52 | "directories": {
53 | "test": "test"
54 | },
55 | "keywords": [
56 | "webextension",
57 | "mozilla",
58 | "web",
59 | "security"
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/src/css/OpenSans.css:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 | @font-face {
5 | font-family: 'Open Sans';
6 | font-style: italic;
7 | font-weight: 400;
8 | src: url('../fonts/OpenSans-LightItalic.ttf') format('truetype')
9 | }
10 |
11 | @font-face {
12 | font-family: 'Open Sans';
13 | font-style: bold;
14 | font-weight: 700;
15 | src: url('../fonts/OpenSans-Bold.ttf') format('truetype')
16 | }
17 |
18 | @font-face {
19 | font-family: 'Open Sans';
20 | font-style: normal;
21 | font-weight: 400;
22 | src: url('../fonts/OpenSans-Light.ttf') format('truetype')
23 | }
24 |
--------------------------------------------------------------------------------
/src/css/first-run.css:
--------------------------------------------------------------------------------
1 | /* This Source Code Form is subject to the terms of the Mozilla Public
2 | * License, v. 2.0. If a copy of the MPL was not distributed with this
3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 | body {
5 | background: #5d667a;
6 | color:#333;
7 | font-family: "Open Sans", sans-serif;
8 | margin:0; /* unset browser styles */
9 | padding-bottom:16px;
10 | }
11 |
12 | h1 {
13 | color: white;
14 | font-weight: normal;
15 | }
16 |
17 | .center { text-align: center; }
18 | img.center, button.center, a.center { display: block; margin: 0 auto; }
19 |
20 | img#lightbeam-logo { margin-bottom:-18px; }
21 |
22 | body > ol, body > ul, body > #start { width: 578px; margin: 0 auto; }
23 |
24 | ol#steps {
25 | /* unset default styles */
26 | list-style-type:none;
27 | padding:0px;
28 | /* counter for custom numbers */
29 | counter-reset: steps-counter;
30 | }
31 | ol#steps > li {
32 | background:white;
33 | padding:20px;
34 | border-radius: 0.5em;
35 | margin-bottom:24px;
36 | position:relative;
37 | }
38 | ol#steps > li:before {
39 | content: counter(steps-counter);
40 | counter-increment: steps-counter;
41 | font-size:31px;
42 | font-weight:bold;
43 | position: absolute;
44 | top: 8px;
45 | left: -68px;
46 | background:white;
47 | width:48px;
48 | height:48px;
49 | border-radius:24px;
50 | text-align:center;
51 | }
52 | ol#steps p {
53 | margin:0; /* unset default styles */
54 | margin-bottom: 16px;
55 | }
56 | ol#steps > li p:last-child {
57 | margin-bottom: 0;
58 | }
59 |
60 | ul {
61 | padding-left:16px
62 | }
63 |
64 | ul li {
65 | padding-bottom: 10px;
66 | }
67 |
68 | ul li:last-child {
69 | padding-bottom: 0;
70 | }
71 |
72 | div#start {
73 | background: white;
74 | border-radius: 0.5em;
75 | transition: all 0.3s;
76 | }
77 | #start a {
78 | text-decoration: none;
79 | padding: 10px;
80 | color: #5D667A;
81 | font-weight: bold;
82 | outline: none;
83 | transition: all 0.3s;
84 | }
85 |
86 | #start:hover {
87 | box-shadow: 5px 5px 5px #111111;
88 | background: #4BC599;
89 | }
90 | #start a:hover {
91 | color: white;
92 | }
93 |
--------------------------------------------------------------------------------
/src/css/style.css:
--------------------------------------------------------------------------------
1 |
2 | /* ----------- VISUALIZATION ----------- */
3 |
4 | .links line {
5 | stroke: #999;
6 | stroke-opacity: 0.6;
7 | }
8 |
9 | .nodes circle {
10 | stroke: #fff;
11 | stroke-width: 1.5px;
12 | }
13 |
14 | /* ----------- UI - General ----------- */
15 |
16 | @font-face {
17 | font-family: "Open Sans";
18 | src: url("../fonts/OpenSans-Regular.ttf");
19 | }
20 |
21 | [hidden] {
22 | display: none !important;
23 | }
24 |
25 | :root {
26 | --primary-color: #000;
27 | --secondary-color: #404850;
28 | --tertiary-color: #eaeaea;
29 | --button-color: #171e25;
30 | --button-border-color: #12181b;
31 | --button-active-color: #73a4b8;
32 | --button-active-border-color: #6fc3e5;
33 | --primary-text-color: #eaeaea;
34 | --secondary-text-color: #73a4b8;
35 | --dialog-header-color: #4cc7e6;
36 | --dialog-button-color: #4cc7e6;
37 | }
38 |
39 | *::before, *::after, * {
40 | box-sizing: border-box;
41 | }
42 |
43 | body {
44 | display: grid;
45 | grid-template-columns: 170px 1fr;
46 | height: 100vh;
47 | width: 100%;
48 | margin: 0;
49 | font-family: "Open Sans", sans-serif;
50 | font-weight: normal;
51 | }
52 |
53 | h1, h2, h3, dt, dd, label {
54 | margin: 0;
55 | font-weight: 400;
56 | }
57 |
58 | h1 {
59 | font-size: 1.75em;
60 | }
61 |
62 | h2, dt, label {
63 | font-size: .75em;
64 | font-weight: 700;
65 | text-transform: uppercase;
66 | }
67 |
68 | h3, dd {
69 | font-size: 1.2em;
70 | color: var(--secondary-text-color);
71 | text-transform: uppercase;
72 | }
73 |
74 | var {
75 | font-style: normal;
76 | }
77 |
78 | button {
79 | display: flex;
80 | align-items: center;
81 | justify-content: flex-start;
82 | width: 100%;
83 | margin-top: 10px;
84 | text-align: left;
85 | padding: 10px;
86 | font-size: .75em;
87 | border: none;
88 | border-width: 1px;
89 | border-radius: 3px;
90 | cursor: pointer;
91 | color: var(--primary-text-color);
92 | background-color: var(--button-color);
93 | border-color: var(--button-border-color);
94 | box-shadow: 0 3px 3px #12181B;
95 | }
96 |
97 | button:hover {
98 | background-color: var(--button-active-color);
99 | }
100 |
101 | button::before, a.thumbs-up::before {
102 | content: "";
103 | display: inline-block;
104 | background-repeat: no-repeat;
105 | background-position: center;
106 | width: 15px;
107 | height: 15px;
108 | background-size: contain;
109 | margin-right: 10px;
110 | }
111 |
112 | dialog {
113 | display: block;
114 | position: fixed;
115 | transform: translate(0, -50%);
116 | top: 50%;
117 | left: 2em;
118 | right: 2em;
119 | width: -moz-fit-content;
120 | width: -webkit-fit-content;
121 | width: fit-content;
122 | max-width: 40em;
123 | height: -moz-fit-content;
124 | height: -webkit-fit-content;
125 | height: fit-content;
126 | margin: auto;
127 | padding: 1em;
128 | background: white;
129 | color: black;
130 | border: none;
131 | border-radius: 0.5em;
132 | box-shadow: 0.5em 0.5em 0 rgba(0,0,0,0.5);
133 | overflow: hidden;
134 | }
135 |
136 | dialog:not([open]) {
137 | display: none;
138 | }
139 |
140 | dialog::backdrop, dialog + .backdrop {
141 | background: rgba(0,0,0,0.25);
142 | }
143 |
144 | dialog + .backdrop {
145 | position: fixed;
146 | top: 0;
147 | right: 0;
148 | bottom: 0;
149 | left: 0;
150 | }
151 |
152 | dialog .dialog-wrapper {
153 | display: grid;
154 | grid-template-columns: repeat(4, 1fr);
155 | grid-gap: 10px;
156 | grid-auto-rows: auto;
157 | }
158 |
159 | dialog .dialog-title {
160 | background: var(--dialog-header-color);
161 | color: #FFF;
162 | margin: -1em -1em 0;
163 | padding: 1em;
164 | font-size: 1em;
165 | text-transform: uppercase;
166 | grid-column: 1 / 5;
167 | grid-row: 1;
168 | }
169 |
170 | dialog .dialog-icon {
171 | grid-column: 1;
172 | grid-row: 2;
173 | width: 100%;
174 | display: block;
175 | }
176 |
177 | dialog .dialog-content {
178 | grid-column: 1 / 5;
179 | grid-row: 2;
180 | }
181 |
182 | dialog .dialog-icon + .dialog-content {
183 | grid-column: 2 / 5;
184 | }
185 |
186 | dialog .dialog-options {
187 | text-align: right;
188 | display: block;
189 | margin: 0;
190 | padding: 0;
191 | grid-column: 1 / 5;
192 | grid-row: 3;
193 | }
194 |
195 | dialog .dialog-options button {
196 | background: var(--dialog-button-color);
197 | display: inline-block;
198 | width: auto;
199 | min-width: 6em;
200 | box-shadow: none;
201 | margin: 0;
202 | padding: 0.5em 1em;
203 | font-size: inherit;
204 | text-align: center;
205 | }
206 |
207 | dialog .dialog-options button::before {
208 | display: none;
209 | }
210 |
211 | dialog .dialog-options button::-moz-focus-inner {
212 | padding: 0;
213 | border: none;
214 | }
215 |
216 | dialog .dialog-options button:focus {
217 | outline: dotted 1px grey;
218 | }
219 |
220 | @media (max-width: 44em) {
221 | dialog .dialog-icon {
222 | display: none;
223 | }
224 |
225 | dialog .dialog-content,
226 | dialog .dialog-icon + .dialog-content {
227 | grid-column: 1 / 5;
228 | }
229 | }
230 |
231 | ._dialog_overlay {
232 | position: fixed;
233 | top: 0;
234 | right: 0;
235 | bottom: 0;
236 | left: 0;
237 | }
238 |
239 | .active {
240 | background-color: var(--button-active-color);
241 | border-top: 2px solid var(--button-active-border-color);
242 | }
243 |
244 | .active:hover {
245 | border-top-color: var(--tertiary-color);
246 | }
247 |
248 | a {
249 | color: var(--secondary-text-color);
250 | font-size: .75em;
251 | }
252 |
253 | .filter-menu button:first-child {
254 | margin-top: 10px;
255 | border-radius: 3px 3px 0 0;
256 | }
257 |
258 | .filter-menu button:last-child {
259 | border-radius: 0 0 3px 3px;
260 | }
261 |
262 | .filter-menu button {
263 | margin-top: 0;
264 | border-radius: 0;
265 | border-top: 2px solid var(--button-border-color);
266 | }
267 |
268 | .filter-menu button:hover {
269 | background-color: var(--button-active-color);
270 | }
271 |
272 | .filter-menu .active {
273 | border-color: var(--button-active-border-color);
274 | }
275 |
276 | .filter-menu .active:hover {
277 | border-color: #fff;
278 | }
279 |
280 | /* ----------- UI - Side Bar ----------- */
281 |
282 | aside {
283 | background-color: var(--secondary-color);
284 | padding: 15px;
285 | }
286 |
287 | aside h1 {
288 | color: var(--tertiary-color);
289 | }
290 |
291 | .logo {
292 | max-width: 100%;
293 | }
294 |
295 | aside h2 {
296 | margin-top: 20px;
297 | color: var(--primary-text-color);
298 | }
299 |
300 | .nav-links {
301 | margin-top: 20px;
302 | text-align: center;
303 | }
304 |
305 | .nav-links .icon {
306 | margin-right: 0;
307 | }
308 |
309 | .graph::before {
310 | background-image: url("../images/lightbeam_icon_graph.png");
311 | }
312 |
313 | .list:before {
314 | background-image: url("../images/lightbeam_icon_list.png");
315 | }
316 |
317 | .download::before {
318 | background-image: url("../images/lightbeam_icon_download.png");
319 | }
320 |
321 | .reset::before {
322 | background-image: url("../images/lightbeam_icon_reset.png");
323 | }
324 |
325 | .thumbs-up::before {
326 | background-image: url("../images/lightbeam_icon_feedback.png");
327 | }
328 |
329 | /* ----------- UI - Top Bar ----------- */
330 |
331 | main {
332 | display: grid;
333 | grid-template-rows: 10% 60% 30%;
334 | background-color: var(--primary-color);
335 | height: 100%;
336 | }
337 |
338 | .top-bar {
339 | display: flex;
340 | justify-content: space-between;
341 | align-items: center;
342 | background-color: var(--tertiary-color);
343 | padding: 20px;
344 | }
345 |
346 | .top-bar > dl {
347 | display: flex;
348 | flex-wrap: wrap;
349 | }
350 |
351 | .top-bar > dl > div {
352 | margin-right: 15px;
353 | }
354 |
355 | .tracking-protection {
356 | display: flex;
357 | align-items: center;
358 | flex-wrap: wrap;
359 | }
360 |
361 | #tracking-protection-disabled > div {
362 | display: inline-block;
363 | width: 140px;
364 | margin-inline-start: 10px;
365 | }
366 |
367 | #tracking-protection-disabled > div > a {
368 | font-size: 1rem;
369 | text-decoration: none;
370 | }
371 |
372 | .toggle-switch {
373 | display: inline-flex;
374 | align-items: center;
375 | justify-content: space-around;
376 | height: 30px;
377 | width: 55px;
378 | margin-left: 5px;
379 | background-color: var(--secondary-color);
380 | border-radius: 5px;
381 | position: relative;
382 | cursor: pointer;
383 | }
384 |
385 | .toggle-switch input {
386 | -moz-appearance: none;
387 | opacity: 0;
388 | }
389 |
390 | .toggle-switch:active {
391 | border:1px solid var(--button-active-border-color);
392 | }
393 |
394 | .toggle:before {
395 | content: "";
396 | height: 24px;
397 | width: 25px;
398 | background-color: var(--primary-color);
399 | border-radius: 5px;
400 | transition: all 0.4s;
401 | position: absolute;
402 | left: 5px;
403 | top: 10%;
404 | }
405 |
406 | .toggle:after {
407 | content: "OFF";
408 | font-size: .75em;
409 | font-weight: 700;
410 | text-transform: uppercase;
411 | color: var(--primary-text-color);
412 | position: absolute;
413 | right: 10%;
414 | top: 30%;
415 | }
416 |
417 | .toggle-switch input:checked + .toggle:before {
418 | transform: translateX(20px);
419 | right: 10%;
420 | background-color: var(--secondary-text-color);
421 | }
422 |
423 | .toggle-switch input:checked + .toggle:after {
424 | content: "ON";
425 | left: 10%;
426 | }
427 |
428 | /* ----------- UI - Graph ----------- */
429 |
430 | .vis {
431 | display: grid;
432 | grid-template-rows: 60px 1fr;
433 | grid-template-columns: 1fr 40px;
434 | }
435 |
436 | .vis-header {
437 | padding-left: 20px;
438 | padding-top: 10px;
439 | background-color: var(--primary-color);
440 | }
441 |
442 | .vis-header > h1 {
443 | color: var(--primary-text-color);
444 | }
445 |
446 | .vis-header > h2 {
447 | color: var(--secondary-text-color);
448 | }
449 |
450 | .vis-content {
451 | position: absolute;
452 | top: 0;
453 | bottom: 0;
454 | left: 0;
455 | right: 0;
456 | overflow: hidden;
457 | }
458 |
459 | #tooltip {
460 | position: absolute;
461 | z-index: 1;
462 | display: none;
463 | background-color: #FFF;
464 | color: #010203;
465 | padding: 5px 10px;
466 | box-shadow: 0px 2px #4CC7E6;
467 | border-radius: 5px;
468 | }
469 |
470 | #tooltip::after {
471 | content: '';
472 | width: 0;
473 | height: 0;
474 | border: 10px solid transparent;
475 | border-top: 10px solid #FFF;
476 | position: absolute;
477 | top: 100%;
478 | left: 50%;
479 | margin-left: -10px;
480 | }
481 |
482 | .vis-controls {
483 | grid-row-end: span 3;
484 | }
485 |
486 | .info-panel-controls {
487 |
488 | }
489 |
490 | .info-panel {
491 | border-radius: 3px 0 0 3px;
492 | margin-top: 5px;
493 | }
494 |
495 | .info-panel::before {
496 | margin-right: 0;
497 | }
498 |
499 | .info-panel:first-child {
500 | background-color: transparent;
501 | box-shadow: none;
502 | margin-top: 0;
503 | }
504 |
505 | .website::before {
506 | background-image: url('../images/lightbeam_icon_website.png');
507 | opacity: .5;
508 | }
509 |
510 | .help::before {
511 | background-image: url('../images/lightbeam_icon_help.png');
512 | }
513 |
514 | .about::before {
515 | background-image: url('../images/lightbeam_icon_about.png');
516 | }
517 |
518 | /* ----------- UI - vis Controls ----------- */
519 | footer {
520 | display: grid;
521 | grid-template-columns: repeat(4, 1fr) minmax(150px, auto);
522 | padding: 0 30px;
523 | }
524 |
525 | .footer-heading {
526 | display: flex;
527 | border-bottom: 1px solid var(--primary-text-color);
528 | justify-content: space-between;
529 | }
530 |
531 | .footer-heading h2 {
532 | padding-bottom: 5px;
533 | color: var(--primary-text-color);
534 | }
535 |
536 | .footer-heading .hide {
537 | text-transform: none;
538 | font-weight: 400;
539 | }
540 |
541 | .footer-toggle {
542 | grid-column: 1 / 5;
543 | }
544 |
545 | .footer-filter {
546 | grid-column-start: 5;
547 | }
548 |
549 | .footer-toggle-buttons {
550 | display: grid;
551 | grid-column-gap: 10px;
552 | grid-template-columns: repeat(3, minmax(auto, 150px));
553 | grid-template-rows: repeat(3, 1fr);
554 | }
555 |
556 | .footer-toggle-buttons .connections {
557 | grid-column-start: 1;
558 | }
559 |
560 | .visited-sites::before {
561 | background-image: url('data:image/svg+xml,');
562 | }
563 |
564 | .third-party-sites::before {
565 | background-image: url('data:image/svg+xml,');
566 | }
567 |
568 | .connections::before {
569 | background-image: url('data:image/svg+xml,');
570 | }
571 |
572 | .two-icons::before {
573 | width: 30px;
574 | }
575 |
576 | .watched-sites::before {
577 | background-image: url('data:image/svg+xml,'), url('data:image/svg+xml,');
578 | }
579 |
580 | .blocked-sites::before {
581 | background-image: url('data:image/svg+xml,'), url('data:image/svg+xml,');
582 | }
583 |
584 | .cookies::before {
585 | background-image: url('data:image/svg+xml,');
586 | }
587 |
588 | .filter-menu {
589 | max-width: 150px;
590 | }
591 |
592 | @media (max-width: 800px) {
593 | footer {
594 | grid-template-columns: 1fr 1fr;
595 | }
596 |
597 | .footer-toggle {
598 | grid-column: 1 / 1;
599 | }
600 |
601 | .footer-filter {
602 | grid-column-start: 2;
603 | }
604 |
605 | .footer-toggle-buttons {
606 | grid-template-columns: minmax(auto, 150px);
607 | }
608 |
609 | .watched-sites {
610 | order: 4;
611 | }
612 |
613 | .blocked-sites {
614 | order: 5;
615 | }
616 |
617 | .cookies {
618 | order: 6;
619 | }
620 | }
621 |
622 | @media (max-width: 600px) {
623 | main {
624 | display: block;
625 | }
626 |
627 | .vis {
628 | height: 600px;
629 | }
630 |
631 | footer {
632 | grid-template-columns: 1fr;
633 | }
634 |
635 | .footer-toggle {
636 | grid-column: 1;
637 | }
638 |
639 | .footer-filter {
640 | grid-column-start: 1;
641 | }
642 | }
643 |
644 | .unimplemented {
645 | visibility: hidden;
646 | }
647 |
648 | .unimplemented.list,
649 | footer.unimplemented {
650 | display: none;
651 | }
652 |
653 | .max-graph {
654 | position: relative;
655 | z-index: 2;
656 | }
657 |
--------------------------------------------------------------------------------
/src/first-run.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |