Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
amethystnetwork-dev
GitHub Repository: amethystnetwork-dev/Incognito
Path: blob/main/static/script/options.js
917 views
1
/**
2
* Incognito
3
*
4
* This program is free software: you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation, either version 3 of the License, or
7
* (at your option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program. If not, see <https://www.gnu.org/licenses/>.
16
*/
17
18
/*
19
_____ _ _ _
20
| __ \ | | | | | |
21
| |__) | ___ _ __ | |_ ___ __| | | |__ _ _
22
| ___/ / _ \ | '__| | __| / _ \ / _` | | '_ \ | | | |
23
| | | (_) | | | | |_ | __/ | (_| | | |_) | | |_| |
24
|_| \___/ |_| \__| \___| \__,_| |_.__/ \__, |
25
__/ |
26
|___/
27
_ _ _ _ _ _ _
28
/\ | | | | | | | \ | | | | | |
29
/ \ _ __ ___ ___ | |_ | |__ _ _ ___ | |_ | \| | ___ | |_ __ __ ___ _ __ | | __
30
/ /\ \ | '_ ` _ \ / _ \ | __| | '_ \ | | | | / __| | __| | . ` | / _ \ | __| \ \ /\ / / / _ \ | '__| | |/ /
31
/ ____ \ | | | | | | | __/ | |_ | | | | | |_| | \__ \ | |_ | |\ | | __/ | |_ \ V V / | (_) | | | | <
32
/_/ \_\ |_| |_| |_| \___| \__| |_| |_| \__, | |___/ \__| |_| \_| \___| \__| \_/\_/ \___/ |_| |_|\_\
33
__/ |
34
|___/
35
*/
36
import { Selection } from './selection.js';
37
import { Tabs } from './tabs.js';
38
39
async function options(app) {
40
document.querySelector('#open-nav').setAttribute('data-open', '');
41
app.search.title.style.display = 'block';
42
app.search.title.textContent = 'Options';
43
app.search.input.style.display = 'none';
44
45
const tabs = new Tabs(app);
46
47
const themes = [
48
{ id: 'ocean', content: 'Ocean' },
49
{ id: 'midnight', content: 'Midnight' },
50
{ id: 'simple', content: 'Simple' },
51
{ id: 'space', content: 'Space' },
52
{ id: 'morning', content: 'Morning' },
53
{ id: 'terminal', content: 'Terminal' },
54
{ id: 'resilent', content: 'Resilient' },
55
{ id: 'fancy', content: 'Fancy' }
56
]
57
58
const backgroundThemes = [
59
{ id: 'particles', content: 'Particles' },
60
{ id: 'stars', content: 'Stars' },
61
{ id: 'none', content: 'None' }
62
]
63
64
const searchEngines = [
65
{ id: 'google', content: 'Google' },
66
{ id: 'ddg', content: 'DuckDuckGo' },
67
{ id: 'bing', content: 'Bing' },
68
{ id: 'brave', content: 'Brave' },
69
{ id: 'startpage', content: 'Startpage' }
70
]
71
72
const searchEngineSuggestions = [
73
...searchEngines,
74
{ id: 'ecosia', content: 'Ecosia' },
75
{ id: 'none', content: 'None' }
76
]
77
78
const enableTips = [
79
{ id: 'enabled', content: 'Enabled' },
80
{ id: 'none', content: 'None' }
81
]
82
83
const selection = new Selection(app);
84
const backgroundSelection = new Selection(app);
85
const searchSelection = new Selection(app);
86
const searchSuggestionSelection = new Selection(app);
87
const disableTips = new Selection(app);
88
89
themes.forEach(entry => {
90
selection.createSelector(entry.id, app.createElement('li', entry.content, {
91
class: 'selector'
92
}))
93
});
94
selection.on('select', id => {
95
if (id in selection.selectors) {
96
selection.selectors[id].setAttribute('data-selected', '');
97
};
98
document.body.setAttribute('data-appearance', id);
99
localStorage.setItem('incog||appearance', id);
100
});
101
selection.switchSelector((localStorage.getItem('incog||appearance') || 'ocean'));
102
103
backgroundThemes.forEach(entry => {
104
backgroundSelection.createSelector(entry.id, app.createElement('li', entry.content, {
105
class: 'selector'
106
}))
107
});
108
backgroundSelection.on('select', id => {
109
if (id in backgroundSelection.selectors) {
110
backgroundSelection.selectors[id].setAttribute('data-selected', '');
111
};
112
if (id === 'none') {
113
app.destroyParticles();
114
} else if (localStorage.getItem('incog||background') !== id) {
115
switch(id) {
116
case 'particles':
117
app.destroyParticles();
118
particlesJS.load('.particles', './json/particles.json');
119
break;
120
case 'stars':
121
app.destroyParticles();
122
particlesJS.load('.particles', './json/stars.json');
123
};
124
};
125
localStorage.setItem('incog||background', id);
126
})
127
backgroundSelection.switchSelector((localStorage.getItem('incog||background') || 'none'));
128
129
searchEngines.forEach(entry => {
130
searchSelection.createSelector(entry.id, app.createElement('li', entry.content, {
131
class: 'selector'
132
}))
133
});
134
searchSelection.on('select', id => {
135
if (id in searchSelection.selectors) {
136
searchSelection.selectors[id].setAttribute('data-selected', '');
137
};
138
localStorage.setItem('incog||search', id)
139
})
140
141
searchEngineSuggestions.forEach(entry => {
142
searchSuggestionSelection.createSelector(entry.id, app.createElement('li', entry.content, {
143
class: 'selector'
144
}))
145
});
146
searchSuggestionSelection.on('select', id => {
147
if (id in searchSuggestionSelection.selectors) {
148
searchSuggestionSelection.selectors[id].setAttribute('data-selected', '');
149
};
150
localStorage.setItem('incog||suggestions', id)
151
})
152
153
// I am not going to style a on-off switch
154
enableTips.forEach(entry => {
155
disableTips.createSelector(entry.id, app.createElement('li', entry.content, {
156
class: 'selector'
157
}))
158
});
159
160
disableTips.on('select', id => {
161
if (id in disableTips.selectors) {
162
disableTips.selectors[id].setAttribute('data-selected', '');
163
};
164
localStorage.setItem('incog||disabletips', id)
165
})
166
167
disableTips.switchSelector((localStorage.getItem('incog||disabletips') || 'enabled'));
168
169
tabs.on('switch', id => {
170
document.querySelectorAll('[data-selected]').forEach(node => {
171
node.removeAttribute('data-selected');
172
});
173
if (app.nav[id]) {
174
app.nav[id].setAttribute('data-selected', '');
175
};
176
});
177
178
tabs.createTab('appearance', app.createElement('div', [
179
app.createElement('section', [
180
app.createElement('span', 'Theme', {
181
style: {
182
display: 'block',
183
'margin-bottom': '10px',
184
'font-size': '18px',
185
'font-weight': '500'
186
}
187
}),
188
selection.element
189
], { class: 'data-section' }),
190
app.createElement('section', [
191
app.createElement('span', 'Background', {
192
style: {
193
display: 'block',
194
'margin-bottom': '10px',
195
'font-size': '18px',
196
'font-weight': '500'
197
}
198
}),
199
backgroundSelection.element
200
], { class: 'data-section' }),
201
app.createElement('section', [
202
app.createElement('span', 'Tips', {
203
style: {
204
display: 'block',
205
'margin-bottom': '10px',
206
'font-size': '18px',
207
'font-weight': '500'
208
}
209
}),
210
disableTips.element
211
], {
212
class: 'data-section'
213
}),
214
app.createElement('section', [
215
app.createElement('button', 'Reset Appearance', {
216
style: {
217
'width': '300px',
218
display: 'inline-block',
219
'padding': '14px 18px',
220
'margin': '5px 0',
221
'color': 'var(--text-color)',
222
'text-decoration': 'none',
223
'font-size': '14px',
224
'background': '0 0',
225
'border': '1px solid var(--border-color)',
226
'border-radius': '2px',
227
'outline': 'none',
228
'font-family': 'inherit',
229
},
230
events: {
231
click() {
232
localStorage.removeItem('incog||appearance')
233
localStorage.removeItem('incog||background')
234
localStorage.removeItem('incog||disabletips')
235
window.location.hash = '';
236
window.location.reload()
237
}
238
}
239
})
240
], { class: 'data-section' })
241
], { class: 'appearance' }));
242
243
tabs.createTab('tabs', app.createElement('div', [
244
app.createElement('section', [
245
app.createElement('span', 'Auto Tab', {
246
style: {
247
display: 'block',
248
'margin-bottom': '6px',
249
'font-size': '18px',
250
'font-weight': '500'
251
}
252
}),
253
app.createElement('input', [], {
254
attrs: {
255
placeholder: 'Enter a URL'
256
},
257
style: {
258
width: '300px',
259
},
260
events: {
261
keydown(event) {
262
if(event.key === 'Enter') {
263
if(!(event.target.value == null || event.target.value == '')) {
264
var url;
265
try {url = new URL(event.target.value) } catch {
266
try {url = new URL('http://' + event.target.value)} catch {}
267
}
268
if(url) tabURL(url.toString());
269
}
270
}
271
}
272
}
273
})
274
], { class: 'data-section' }),
275
app.createElement('section', [
276
app.createElement('span', 'Tab Title', {
277
style: {
278
display: 'block',
279
'margin-bottom': '6px',
280
'font-size': '18px',
281
'font-weight': '500'
282
}
283
}),
284
app.createElement('input', [], {
285
id: 'data-title',
286
attrs: {
287
value: document.title,
288
placeholder: 'Empty title'
289
},
290
style: {
291
width: '300px',
292
},
293
events: {
294
input(event) {
295
document.title = event.target.value;
296
localStorage.setItem('incog||title', event.target.value);
297
}
298
}
299
}),
300
app.createElement('p', 'Change the title of Incognito\'s browser tab title.', {
301
style: {
302
'margin-bottom': '0'
303
}
304
})
305
], { class: 'data-section' }),
306
app.createElement('section', [
307
app.createElement('span', 'Tab Icon', {
308
style: {
309
display: 'block',
310
'margin-bottom': '6px',
311
'font-size': '18px',
312
'font-weight': '500'
313
}
314
}),
315
app.createElement('input', [], {
316
id: 'data-icon',
317
attrs: {
318
value: app.icon.href,
319
placeholder: 'No icon'
320
},
321
style: {
322
width: '300px',
323
},
324
events: {
325
input(event) {
326
app.icon.href = event.target.value;
327
localStorage.setItem('incog||icon', event.target.value);
328
}
329
}
330
}),
331
app.createElement('p', 'Change the icon of Incognito\'s browser tab. To change it into something like Google, type in "https://www.google.com/favicon.ico"', {
332
style: {
333
'margin-bottom': '0'
334
}
335
})
336
], { class: 'data-section' }),
337
app.createElement('section', [
338
app.createElement('span', 'about:blank cloaking', {
339
style: {
340
display: 'block',
341
'margin-bottom': '6px',
342
'font-size': '18px',
343
'font-weight': '500'
344
}
345
}),
346
app.createElement('button', 'Go about:blank', {
347
style: {
348
'width': '300px',
349
display: 'inline-block',
350
'padding': '14px 18px',
351
'margin': '5px 0',
352
'color': 'var(--text-color)',
353
'text-decoration': 'none',
354
'font-size': '14px',
355
'background': '0 0',
356
'border': '1px solid var(--border-color)',
357
'border-radius': '2px',
358
'outline': 'none',
359
'font-family': 'inherit',
360
},
361
events: {
362
click() {
363
/*
364
The about:blank script is based off of ABC by
365
_____ _ _ _ _
366
| ___|__ __ _ | \ | | ___| |___ _____ _ __| | __
367
| |_ / _ \ / _` | | \| |/ _ \ __\ \ /\ / / _ \| '__| |/ /
368
| _| (_) | (_| | | |\ | __/ |_ \ V V / (_) | | | <
369
|_| \___/ \__, | |_| \_|\___|\__| \_/\_/ \___/|_| |_|\_\
370
*/
371
try {
372
var page = window.open()
373
page.document.body.innerHTML = `<iframe style="height:100%; width: 100%; border: none; position: fixed; top: 0; right: 0; left: 0; bottom: 0; border: none" sandbox="allow-forms allow-modals allow-orientation-lock allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation allow-top-navigation-by-user-activation" src="${window.location.href}"></iframe>`
374
} catch {return}
375
window.location.replace((localStorage.getItem('incog||ab') || 'https://google.com'))
376
}
377
}
378
}),
379
app.createElement('p', 'Use about:blank to cloak your tab. (opens in a new tab)', {
380
style: {
381
'margin-bottom': '0'
382
}
383
})
384
], { class: 'data-section' }),
385
app.createElement('section', [
386
app.createElement('span', 'about:blank redirect', {
387
style: {
388
display: 'block',
389
'margin-bottom': '6px',
390
'font-size': '18px',
391
'font-weight': '500'
392
}
393
}),
394
app.createElement('input', [], {
395
attrs: {
396
value: (localStorage.getItem('incog||ab') || 'https://google.com'),
397
placeholder: 'Enter a URL'
398
},
399
style: {
400
width: '300px',
401
},
402
events: {
403
input(event) {
404
try {
405
new URL(event.target.value)
406
localStorage.setItem('incog||ab', event.target.value)
407
} catch {}
408
}
409
}
410
}),
411
app.createElement('p', 'The URL that Incognito redirects to when using about:blank.', {
412
style: {
413
'margin-bottom': '0'
414
}
415
})
416
], { class: 'data-section' }),
417
app.createElement('section', [
418
app.createElement('button', 'Reset Tab', {
419
style: {
420
'width': '300px',
421
display: 'inline-block',
422
'padding': '14px 18px',
423
'margin': '5px 0',
424
'color': 'var(--text-color)',
425
'text-decoration': 'none',
426
'font-size': '14px',
427
'background': '0 0',
428
'border': '1px solid var(--border-color)',
429
'border-radius': '2px',
430
'outline': 'none',
431
'font-family': 'inherit',
432
},
433
events: {
434
click() {
435
localStorage.removeItem('incog||ab')
436
localStorage.removeItem('incog||icon')
437
localStorage.removeItem('incog||title')
438
window.location.hash = '';
439
window.location.reload()
440
}
441
}
442
})
443
], { class: 'data-section' })
444
]));
445
446
tabs.createTab('search', app.createElement('div', [
447
app.createElement('section', [
448
app.createElement('span', 'Search Engine', {
449
style: {
450
display: 'block',
451
'margin-bottom': '10px',
452
'font-size': '18px',
453
'font-weight': '500'
454
}
455
}),
456
searchSelection.element,
457
app.createElement('p', 'Change the search engine used.', {
458
style: {
459
'margin-bottom': '0'
460
}
461
})
462
], { class: 'data-section' }),
463
app.createElement('section', [
464
app.createElement('span', 'Search Suggestions', {
465
style: {
466
display: 'block',
467
'margin-bottom': '6px',
468
'font-size': '18px',
469
'font-weight': '500'
470
}
471
}),
472
searchSuggestionSelection.element,
473
app.createElement('p', 'Change the search engine used in the search suggestions.', {
474
style: {
475
'margin-bottom': '0'
476
}
477
})
478
], { class: 'data-section' }),
479
app.createElement('section', [
480
app.createElement('button', 'Reset Search Engine', {
481
style: {
482
'width': '300px',
483
display: 'inline-block',
484
'padding': '14px 18px',
485
'margin': '5px 0',
486
'color': 'var(--text-color)',
487
'text-decoration': 'none',
488
'font-size': '14px',
489
'background': '0 0',
490
'border': '1px solid var(--border-color)',
491
'border-radius': '2px',
492
'outline': 'none',
493
'font-family': 'inherit',
494
},
495
events: {
496
click() {
497
localStorage.removeItem('incog||search')
498
localStorage.removeItem('incog||suggestions')
499
window.location.hash = '';
500
}
501
}
502
})
503
], { class: 'data-section' })
504
]));
505
506
tabs.createTab('about', app.createElement('div', await createAbout(app)))
507
508
app.nav.about = app.createElement('a', 'About', {
509
events: {
510
click() {
511
tabs.switchTab('about');
512
}
513
},
514
id: 'about'
515
});
516
517
app.nav.search = app.createElement('a', 'Search Engine', {
518
events: {
519
click() {
520
tabs.switchTab('search');
521
searchSelection.switchSelector((localStorage.getItem('incog||search') || 'google'));
522
searchSuggestionSelection.switchSelector((localStorage.getItem('incog||suggestions') || 'ddg'));
523
}
524
},
525
id: 'search'
526
});
527
528
app.nav.tabs = app.createElement('a', 'Browser Tab', {
529
events: {
530
click() {
531
tabs.switchTab('tabs');
532
}
533
},
534
id: 'tabs'
535
});
536
537
app.nav.appearance = app.createElement('a', 'Appearance', {
538
events: {
539
click() {
540
tabs.switchTab('appearance');
541
selection.switchSelector((localStorage.getItem('incog||appearance') || 'ocean'));
542
backgroundSelection.switchSelector((localStorage.getItem('incog||background') || 'none'));
543
disableTips.switchSelector((localStorage.getItem('incog||disabletips') || 'enabled'));
544
}
545
},
546
id: 'appearance',
547
});
548
549
tabs.switchTab('appearance');
550
551
app.search.back.style.display = 'inline';
552
app.search.back.href = '#';
553
app.main.content = tabs.element;
554
}
555
556
async function createAbout(app) {
557
const res = await fetch('./about.json');
558
const json = await res.json();
559
560
const authors = [];
561
const socials = [];
562
const contacts = [];
563
564
for (const entry of json.authors) {
565
authors.push(
566
app.createElement('p', `${entry.name}${entry.data ? ' - ' + entry.data : ''}`, {
567
style: { 'margin-bottom': '0' }
568
})
569
)
570
};
571
572
for (const entry of json.socials) {
573
socials.push(
574
app.createElement('p', `${entry.name}${entry.data ? ' - ' + entry.data : ''}`, {
575
style: { 'margin-bottom': '0' }
576
})
577
)
578
};
579
580
for (const entry of json.contact) {
581
contacts.push(
582
app.createElement('p', `${entry.name}${entry.data ? ' - ' + entry.data : ''}`, {
583
style: { 'margin-bottom': '0' }
584
})
585
)
586
};
587
588
const license = `Incognito
589
590
This program is free software: you can redistribute it and/or modify
591
it under the terms of the GNU General Public License as published by
592
the Free Software Foundation, either version 3 of the License, or
593
(at your option) any later version.
594
595
This program is distributed in the hope that it will be useful,
596
but WITHOUT ANY WARRANTY; without even the implied warranty of
597
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
598
GNU General Public License for more details.
599
600
You should have received a copy of the GNU General Public License
601
along with this program. If not, see <https://www.gnu.org/licenses/>.`.split("").map(c => c == "\n" ? app.createElement("br") : c);
602
603
return [
604
app.createElement('section', [
605
app.createElement('span', json.main.title, {
606
style: {
607
display: 'block',
608
'margin-bottom': '6px',
609
'font-size': '18px',
610
'font-weight': '500'
611
}
612
}),
613
app.createElement('p', json.main.data, {
614
style: { 'margin-bottom': '0' }
615
})
616
], { class: 'data-section' }),
617
app.createElement('section', [
618
app.createElement('span', 'Authors', {
619
style: {
620
display: 'block',
621
'margin-bottom': '6px',
622
'font-size': '18px',
623
'font-weight': '500'
624
}
625
}),
626
app.createElement('div', authors)
627
], { class: 'data-section' }),
628
app.createElement('section', [
629
app.createElement('span', 'Socials', {
630
style: {
631
display: 'block',
632
'margin-bottom': '6px',
633
'font-size': '18px',
634
'font-weight': '500'
635
}
636
}),
637
app.createElement('div', socials)
638
], { class: 'data-section' }),
639
contacts.length ? app.createElement('section', [
640
app.createElement('span', 'Contact', {
641
style: {
642
display: 'block',
643
'margin-bottom': '6px',
644
'font-size': '18px',
645
'font-weight': '500'
646
}
647
}),
648
app.createElement('div', contacts)
649
], { class: 'data-section' }) : null,
650
app.createElement('section', [
651
app.createElement('span', 'License', {
652
style: {
653
display: 'block',
654
'margin-bottom': '6px',
655
'font-size': '18px',
656
'font-weight': '500'
657
}
658
}),
659
app.createElement("p", license)
660
], { class: 'data-section' })
661
]
662
};
663
664
async function tabURL(url) {
665
// A mess of code from Tsunami 2.0 and HolyUB modified to work with Incognito
666
const res = await app.bare.fetch(url);
667
const parsedURL = new URL(res.finalURL);
668
var dom = new DOMParser().parseFromString(await res.text(), "text/html");
669
var title = parsedURL.href;
670
if(dom.getElementsByTagName("title")[0]) title = dom.getElementsByTagName("title")[0].innerText;
671
var icon = "data:,"
672
if(dom.querySelector("link[rel='shortcut icon']")) icon = dom.querySelector("link[rel='shortcut icon']").attributes.href.value;
673
if(dom.querySelector("link[rel='icon']")) icon = dom.querySelector("link[rel='icon']").attributes.href.value;
674
if(icon.startsWith('/')) icon = parsedURL.origin + icon; else if(icon.startsWith('./')) {
675
if(parsedURL.href.endsWith('/')) icon = parsedURL.href + icon.slice(2); else icon = parsedURL.href + icon.slice(1)
676
}
677
app.icon.href = icon
678
document.title = title
679
document.getElementById('data-icon').value = icon;
680
document.getElementById('data-title').value = title;
681
localStorage.setItem('incog||icon', icon)
682
localStorage.setItem('incog||title', title);
683
}
684
685
export { options }
686
687