Skip to content

Commit f748fe5

Browse files
committed
Trackers list on settings page
1 parent 5e2c0d0 commit f748fe5

File tree

16 files changed

+330
-39
lines changed

16 files changed

+330
-39
lines changed

extension-manifest-v2/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"foundation-sites": "^6.6.2",
5252
"ghostery-common": "^1.3.12",
5353
"history": "^4.10.1",
54-
"hybrids": "^8.2.16",
54+
"hybrids": "^8.2.17",
5555
"linkedom": "^0.14.21",
5656
"moment": "^2.29.1",
5757
"prop-types": "^15.6.2",

extension-manifest-v3/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"@ghostery/ui": "^1.0.0",
4040
"@github/relative-time-element": "^4.3.0",
4141
"@whotracksme/webextension-packages": "5.0.5",
42-
"hybrids": "^8.2.16",
42+
"hybrids": "^8.2.17",
4343
"idb": "^7.1.1",
4444
"jwt-decode": "^4.0.0",
4545
"tldts-experimental": "^6.0.19"

extension-manifest-v3/src/pages/panel/views/tracker-details.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export default {
116116
</ui-panel-action>`,
117117
),
118118
)}
119-
<ui-panel-action>
119+
<ui-panel-action layout="width:4.5">
120120
<a
121121
href="${chrome.runtime.getURL(
122122
'/pages/settings/index.html#@gh-settings-trackers',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Ghostery Browser Extension
3+
* https://www.ghostery.com/
4+
*
5+
* Copyright 2017-present Ghostery GmbH. All rights reserved.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0
10+
*/
11+
12+
import { html } from 'hybrids';
13+
14+
export default {
15+
render: () => html`
16+
<template layout="grid">
17+
<ui-panel-action layout="height:5">
18+
<button layout="padding:1:1.5">
19+
<ui-text type="label-m"><slot></slot></ui-text>
20+
</button>
21+
</ui-panel-action>
22+
</template>
23+
`,
24+
};

extension-manifest-v3/src/pages/settings/components/input.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ export default {
3232
background: var(--ui-color-white);
3333
border: 1px solid var(--ui-color-gray-200);
3434
border-radius: 8px;
35-
padding: 13px;
35+
padding: 11px;
3636
margin: 0;
37-
font: var(--ui-font-body-l);
37+
font: var(--ui-font-body-m);
3838
}
3939
4040
::slotted(textarea) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* Ghostery Browser Extension
3+
* https://www.ghostery.com/
4+
*
5+
* Copyright 2017-present Ghostery GmbH. All rights reserved.
6+
*
7+
* This Source Code Form is subject to the terms of the Mozilla Public
8+
* License, v. 2.0. If a copy of the MPL was not distributed with this
9+
* file, You can obtain one at http://mozilla.org/MPL/2.0
10+
*/
11+
12+
import { html, dispatch } from 'hybrids';
13+
import * as labels from '@ghostery/ui/labels';
14+
15+
export default {
16+
name: '',
17+
description: '',
18+
blocked: 0,
19+
trusted: 0,
20+
open: false,
21+
render: ({ name, description, blocked, trusted, open }) => html`
22+
<template layout="column gap:2 padding:1.5">
23+
<header layout="row items:center gap:1.5" layout@768px="gap:2">
24+
<ui-action>
25+
<button
26+
onclick="${(host) => dispatch(host, 'toggle')}"
27+
layout="block:left row items:center gap:1.5 padding:0.5 grow"
28+
layout@768px="gap:2"
29+
>
30+
<ui-icon id="arrow" name="arrow-down" layout="size:3"></ui-icon>
31+
<ui-panel-category-icon
32+
name="${name}"
33+
layout="size:5 padding"
34+
></ui-panel-category-icon>
35+
<div layout="column gap:0.5">
36+
<ui-text type="label-l">
37+
${labels.categories[name]}<ui-tooltip delay="0.0" wrap inline>
38+
<span slot="content" layout="block width:200px">
39+
${description}
40+
</span>
41+
<ui-icon
42+
name="info"
43+
color="gray-400"
44+
layout="margin:top:1px"
45+
></ui-icon>
46+
</ui-tooltip>
47+
</ui-text>
48+
<div layout="column" layout@768px="row gap">
49+
<ui-text type="body-s" color="gray-600" layout="width::90px">
50+
Blocked: ${blocked}
51+
</ui-text>
52+
<ui-text type="body-s" color="gray-600" layout="width::90px">
53+
Trusted: ${trusted}
54+
</ui-text>
55+
</div>
56+
</div>
57+
</button>
58+
</ui-action>
59+
60+
<ui-panel-action>
61+
<ui-icon name="refresh"></ui-icon>
62+
</ui-panel-action>
63+
</header>
64+
65+
${open &&
66+
html`
67+
<div layout="column gap:2">
68+
<ui-line></ui-line>
69+
70+
<div layout="column gap:2" layout@768px="padding:left:100px">
71+
<slot></slot>
72+
</div>
73+
</div>
74+
`}
75+
</template>
76+
`.css`
77+
:host {
78+
border-radius: 8px;
79+
border: 1px solid var(--ui-color-gray-200);
80+
background: var(--ui-color-white);
81+
}
82+
83+
:host([open]) #arrow {
84+
transform: rotate(180deg);
85+
}
86+
`,
87+
};

extension-manifest-v3/src/pages/settings/views/trackers.js

+131-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,66 @@
1-
import { html, store } from 'hybrids';
1+
import { html, msg, store } from 'hybrids';
22

33
import Options from '/store/options.js';
4+
import { getCategories } from '/utils/trackerdb';
5+
6+
const PATTERNS_LIMIT = 50;
7+
8+
function loadMore(category) {
9+
return (host) => {
10+
host.limits = {
11+
...host.limits,
12+
[category]: (host.limits[category] || PATTERNS_LIMIT) + PATTERNS_LIMIT,
13+
};
14+
};
15+
}
16+
17+
function search(categories, query) {
18+
if (!query || query.length < 3) return categories;
19+
query = query.trim().toLowerCase();
20+
21+
const result = [];
22+
23+
for (const category of categories) {
24+
const patterns = category.patterns.filter((p) => {
25+
return (
26+
p.name.toLowerCase().includes(query) ||
27+
p.organization?.name.toLowerCase().includes(query)
28+
);
29+
});
30+
31+
if (patterns.length) {
32+
result.push({ ...category, patterns });
33+
}
34+
}
35+
36+
return result;
37+
}
438

539
export default {
640
options: store(Options),
7-
content: ({ options }) => html`
41+
categories: () => getCategories(),
42+
limits: {
43+
set: (host, value = {}) => value,
44+
},
45+
query: {
46+
value: '',
47+
observe(host, value) {
48+
if (value.length >= 3) {
49+
host.category = '_all';
50+
} else {
51+
host.category = '';
52+
}
53+
54+
host.limits = {};
55+
},
56+
},
57+
category: {
58+
value: '',
59+
observe(host) {
60+
host.limits = {};
61+
},
62+
},
63+
content: ({ options, categories, category, limits, query }) => html`
864
<template layout="column gap:4">
965
${store.ready(options) &&
1066
html`
@@ -34,6 +90,79 @@ export default {
3490
</a>
3591
</ui-text>
3692
</div>
93+
<div layout="row gap items:center">
94+
<gh-settings-button
95+
onclick="${html.set(
96+
'category',
97+
category !== '_all' ? '_all' : '',
98+
)}"
99+
layout="width::12"
100+
>
101+
${category !== '_all' ? msg`Expand` : msg`Collapse`}
102+
</gh-settings-button>
103+
<gh-settings-input layout="grow">
104+
<input
105+
type="search"
106+
value="${query}"
107+
oninput="${html.set('query')}"
108+
placeholder="Search for a tracker or organization..."
109+
/>
110+
</gh-settings-input>
111+
</div>
112+
<div layout="column gap:0.5">
113+
${html.resolve(
114+
categories.then((list) =>
115+
search(list, query).map(
116+
({ key, description, patterns }) =>
117+
html`
118+
<gh-settings-trackers-list
119+
name="${key}"
120+
description="${description}"
121+
open="${key === category || category === '_all'}"
122+
blocked="${patterns.length}"
123+
ontoggle="${html.set(
124+
'category',
125+
key === category || category === '_all' ? '' : key,
126+
)}"
127+
>
128+
${(key === category || category === '_all') &&
129+
patterns.map(
130+
(p, index) =>
131+
index <= (limits[key] || PATTERNS_LIMIT) &&
132+
html`
133+
<div layout="row items:center gap">
134+
<div
135+
layout="column grow"
136+
layout@768px="row gap:2"
137+
>
138+
<ui-text type="label-m"> ${p.name} </ui-text>
139+
${p.organization &&
140+
html`
141+
<ui-text color="gray-600">
142+
${p.organization.name}
143+
</ui-text>
144+
`}
145+
</div>
146+
<ui-panel-protection-status-toggle
147+
responsive
148+
></ui-panel-protection-status-toggle>
149+
</div>
150+
`,
151+
)}
152+
${(limits[key] || PATTERNS_LIMIT) < patterns.length &&
153+
html`
154+
<div layout="row center margin:bottom:2">
155+
<gh-settings-button onclick="${loadMore(key)}">
156+
Load more
157+
</gh-settings-button>
158+
</div>
159+
`}
160+
</gh-settings-trackers-list>
161+
`,
162+
),
163+
),
164+
)}
165+
</div>
37166
</section>
38167
`}
39168
</template>

extension-manifest-v3/src/utils/trackerdb.js

+24
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ export async function getMetadata(request) {
5252
return metadata;
5353
}
5454

55+
export async function getCategories() {
56+
if (promise) await promise;
57+
58+
const engine = engines.get('trackerdb');
59+
if (!engine) return [];
60+
61+
const categories = new Map(
62+
engine.metadata.categories
63+
.getValues()
64+
.map(({ key, description }) => [key, { key, description, patterns: [] }]),
65+
);
66+
67+
const organizations = engine.metadata.organizations.getValues();
68+
69+
for (const p of engine.metadata.getPatterns()) {
70+
categories.get(p.category).patterns.push({
71+
...p,
72+
organization: organizations.find((o) => o.key === p.organization),
73+
});
74+
}
75+
76+
return [...categories.values().filter((c) => c.patterns.length > 0)];
77+
}
78+
5579
const patterns = new Map();
5680
export async function getPattern(key) {
5781
if (promise) await promise;

package-lock.json

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/ui/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@
2121
"test": "npm run lint"
2222
},
2323
"dependencies": {
24-
"hybrids": "^8.2.16"
24+
"hybrids": "^8.2.17"
2525
}
2626
}

0 commit comments

Comments
 (0)