neon_arch commited on
Commit
8e9fe4d
1 Parent(s): d659589

✨ feat: Reducing the amount of js used and improving code functionality (#36) (#37)

Browse files
public/static/cookies.js ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // After the settings page finishes loading
2
+ document.addEventListener(
3
+ 'DOMContentLoaded',
4
+ () => {
5
+ let cookie = decodeURIComponent(document.cookie)
6
+ if (cookie !== '') {
7
+ document.querySelector('.cookies input').value = cookie
8
+ } else {
9
+ document.querySelector('.cookies input').value =
10
+ 'No cookies has been saved on your system'
11
+ }
12
+ },
13
+ false
14
+ )
public/static/settings.js CHANGED
@@ -1,186 +1,73 @@
1
- /*
2
- UI: Method for selecting all search engines
3
-
4
- This function is called when user click on
5
- `select all` and `deselect all` toogle element.
6
-
7
- - If select all is pressed toggle all options and insert all value
8
- joined with comma to input which is saved in cookie.
9
- then changes text to `deselect all`.
10
- eg value: 'ddg,searx,'
11
-
12
- - If deselect all is pressed uncheck all options and insert empty
13
- value to input which is saved in cookie.
14
- */
15
- function selectAllHandler(elem) {
16
- let span = elem.parentElement.querySelector("span");
17
- let mainInput = document.getElementsByName("searchEng")[0];
18
- let prevStateSelectAll = span.innerText == "Select all" ? true : false;
19
- document.querySelectorAll(".searchEng-elem").forEach((engine) => {
20
- if (prevStateSelectAll) {
21
- engine.querySelector('input[type="checkbox"]').checked = true;
22
- } else {
23
- engine.querySelector('input[type="checkbox"]').checked = false;
24
- }
25
- });
26
- if (prevStateSelectAll) {
27
- let getValues = () => {
28
- let value = "";
29
- document
30
- .querySelectorAll('[data-isCheckbox]:not([data-value="all"])')
31
- .forEach((elem) => {
32
- value += elem.getAttribute("data-value") + ",";
33
- });
34
- return value;
35
- };
36
- mainInput.value = getValues();
37
- } else {
38
- mainInput.value = "";
39
- }
40
- span.innerText = prevStateSelectAll ? "Deselect all" : "Select all";
41
  }
42
 
43
- /*
44
- UI: Filter settings as per category
45
-
46
- There are two elements one is `category` and `detail`.
47
- Category contains `data-id` when a user click it
48
- we need to show detail element having
49
- `data-detailId` whose value is same as `data-id`.
50
-
51
- When a user clicks on a category on sidebar, view
52
- settings containing `data-id` of sidebar element's `data-detailId`
53
- and hide other settings
 
54
 
55
- - if `all` is clicked then show all settings.
56
- */
57
- document.querySelectorAll(".settings-sidebar .set-name").forEach((filter) => {
58
- let target = filter.getAttribute("data-detailId");
59
- filter.addEventListener("click", () => {
60
- try {
61
- document.querySelector(".set-name.active").classList.remove("active");
62
- } catch (e) {}
63
- filter.classList.add("active");
64
- if (target == "all") {
65
- document.querySelectorAll(".set-item").forEach((elem) => {
66
- elem.style.display = "block";
67
- });
68
- return;
69
  }
70
- document
71
- .querySelectorAll('.set-item[data-id="' + target + '"]')
72
- .forEach((elem) => {
73
- elem.style.display = "block";
74
- });
75
- document
76
- .querySelectorAll('.set-item:not([data-id="' + target + '"])')
77
- .forEach((elem) => {
78
- elem.style.display = "none";
79
- });
80
- });
81
- });
 
82
 
 
 
83
 
84
- /*
85
- This function is called when a user click on submit button
86
- it validates all user inputs and saves to a cookie.
87
-
88
- - if input having `required` attr and is empty it generates a
89
- error text and insert above the setting element
90
-
91
- - else store setttings to a cookie.
92
- */
93
- function submitSettings() {
94
- let form = document.settings;
95
- let stopProceeding = false;
96
- document.querySelectorAll(".errTxt").forEach((e) => e.remove());
97
- for (let i = 0; i < form.elements.length; i++) {
98
- let input = form.elements[i];
99
- if (input.value == "" && input.hasAttribute("required")) {
100
- stopProceeding = true;
101
- let elem = input.parentElement.querySelector("[takeInput]");
102
- let errTxt = document.createElement("p");
103
- errTxt.classList.add("errTxt");
104
- errTxt.innerText = "This setting can't be empty!!";
105
- elem.classList.add("invalid");
106
- elem.parentElement.insertBefore(errTxt, elem);
107
- let sidebarElement = input.closest(".set-item").getAttribute("data-id");
108
- document
109
- .querySelector(
110
- `.settings-sidebar .set-name[data-detailId="${sidebarElement}`
111
- )
112
- .click();
113
- stopProceeding = true;
114
- }
115
- }
116
- if (!stopProceeding) {
117
- var expiration_date = new Date();
118
- expiration_date.setFullYear(expiration_date.getFullYear() + 1);
119
- let formData = new FormData(document.querySelector("form"));
120
- for (var [key, value] of formData.entries()) {
121
- document.cookie = `${key}=${value}; expires=${expiration_date.toUTCString()}`;
122
- }
123
- } else {
124
- return false;
125
- }
126
- // On settings saved successfully
127
- alert("Settings saved succssfully!");
128
- window.location.reload();
129
  }
130
 
 
 
131
 
132
- /*
133
- This function will be called on page ready.
134
- it iterates over saved cookies and if cookie name is
135
- in the list of valid cookies then load it.
136
-
137
- - if cookie is searchEng(type=toggle/checkbox) we deselect
138
- all checkboxes and select those which are stored in cookie.
139
 
140
- - if cookie is of type `select` we deselect default selected
141
- option and then select option which is stored in cookie.
142
- */
143
- function loadUserSettings() {
144
- let inputs = ["searchEng", "theme", "color-sch"];
145
- var keyValuePairs = document.cookie.split(";");
146
- for (var i = 0; i < keyValuePairs.length; i++) {
147
- var name = keyValuePairs[i].substring(0, keyValuePairs[i].indexOf("="));
148
- var value = keyValuePairs[i].substring(keyValuePairs[i].indexOf("=") + 1);
149
- name = name.trim();
150
- if (!inputs.includes(name)) {
151
- continue;
152
- }
153
- let input = document.getElementsByName(name)[0];
154
- input.value = value;
155
- if (name == "searchEng") {
156
- // Unload all checked engines
157
- document
158
- .querySelectorAll(".searchEng-elem input[type=checkbox]")
159
- .forEach((e) => {
160
- e.checked = false;
161
- });
162
- value = value.replace(" ", "");
163
- value.split(",").forEach((val) => {
164
- if (!val) {
165
- return;
166
  }
167
- document
168
- .querySelector(`[data-isCheckbox][data-value="${val}"]`)
169
- .parentElement.querySelector("input").checked = true;
170
- });
171
- } else {
172
- // Unload all selected options
173
- document
174
- .querySelector(
175
- `[data-input="${name}"] .options span[data-value="${value}"]`
176
- )
177
- .removeAttribute("selected");
178
- singleSelectClickHandler(
179
- document.querySelector(`.options span[data-value="${value}"]`)
180
- );
181
- }
182
  }
183
  }
184
-
185
- // Code where settings are loaded from cookie.
186
- loadUserSettings();
 
1
+ function toggleAllSelection() {
2
+ document
3
+ .querySelectorAll('.engine')
4
+ .forEach(
5
+ (engine_checkbox) =>
6
+ (engine_checkbox.checked =
7
+ document.querySelector('.select_all').checked)
8
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
11
+ function setActiveTab(current_tab) {
12
+ document
13
+ .querySelectorAll('.tab')
14
+ .forEach((tab) => tab.classList.remove('active'))
15
+ document
16
+ .querySelectorAll('.btn')
17
+ .forEach((tab) => tab.classList.remove('active'))
18
+ current_tab.classList.add('active')
19
+ document
20
+ .querySelector(`.${current_tab.innerText.toLowerCase().replace(' ', '_')}`)
21
+ .classList.add('active')
22
+ }
23
 
24
+ function setClientSettings() {
25
+ let cookie_dictionary = new Object()
26
+ document.querySelectorAll('select').forEach((select_tag) => {
27
+ if (select_tag.name === 'themes') {
28
+ cookie_dictionary['theme'] = select_tag.value
29
+ } else if (select_tag.name === 'colorschemes') {
30
+ cookie_dictionary['colorscheme'] = select_tag.value
 
 
 
 
 
 
 
31
  }
32
+ })
33
+ let engines = []
34
+ document.querySelectorAll('.engine').forEach((engine_checkbox) => {
35
+ if (engine_checkbox.checked === true) {
36
+ engines.push(engine_checkbox.parentNode.parentNode.innerText.trim())
37
+ }
38
+ })
39
+ cookie_dictionary['engines'] = engines
40
+ let expiration_date = new Date()
41
+ expiration_date.setFullYear(expiration_date.getFullYear() + 1)
42
+ document.cookie = `appCookie=${JSON.stringify(
43
+ cookie_dictionary
44
+ )}; expires=${expiration_date.toUTCString()}`
45
 
46
+ document.querySelector('.message').innerText =
47
+ '✅ The settings have been saved sucessfully!!'
48
 
49
+ setTimeout(() => {
50
+ document.querySelector('.message').innerText = ''
51
+ }, 10000)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  }
53
 
54
+ function getClientSettings() {
55
+ let cookie = decodeURIComponent(document.cookie)
56
 
57
+ if (cookie !== '') {
58
+ let cookie_value = decodeURIComponent(document.cookie)
59
+ .split(';')
60
+ .map((item) => item.split('='))
61
+ .reduce((acc, [_, v]) => (acc = JSON.parse(v)) && acc, {})
 
 
62
 
63
+ let links = Array.from(document.querySelectorAll('link')).forEach(
64
+ (item) => {
65
+ if (item.href.includes('static/themes')) {
66
+ item.href = `static/themes/${cookie_value['theme']}.css`
67
+ } else if (item.href.includes('static/colorschemes')) {
68
+ item.href = `static/colorschemes/${cookie_value['colorscheme']}.css`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  }
70
+ }
71
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  }
73
  }
 
 
 
public/static/themes/simple.css CHANGED
@@ -263,38 +263,38 @@ footer {
263
 
264
  /* Styles for the about page */
265
 
266
- .about-container article{
267
  font-size: 1.5rem;
268
- color:var(--fg);
269
  padding-bottom: 10px;
270
  }
271
 
272
- .about-container article h1{
273
  color: var(--2);
274
  font-size: 2.8rem;
275
  }
276
 
277
- .about-container article div{
278
  padding-bottom: 15px;
279
  }
280
 
281
- .about-container a{
282
- color:var(--3);
283
  }
284
 
285
- .about-container article h2{
286
  color: var(--3);
287
  font-size: 1.8rem;
288
  padding-bottom: 10px;
289
  }
290
 
291
- .about-container p{
292
- color:var(--fg);
293
- font-size: 1.6rem;
294
  padding-bottom: 10px;
295
  }
296
 
297
- .about-container h3{
298
  font-size: 1.5rem;
299
  }
300
 
@@ -302,12 +302,10 @@ footer {
302
  width: 80%;
303
  }
304
 
305
- /* css for settings page t */
306
- .settings {
307
- margin: 2rem;
308
- width: 80%;
309
- height: 100%;
310
- color: var(--fg);
311
  }
312
 
313
  .settings h1 {
@@ -315,268 +313,187 @@ footer {
315
  font-size: 2.5rem;
316
  }
317
 
318
-
319
  .settings hr {
320
  border-color: var(--3);
321
- margin: .3rem 0 1rem 0;
322
  }
323
 
324
- .settings-view {
325
- display: flex;
326
- flex: 1 0 auto;
327
- margin: 1.5rem 0;
328
- }
329
-
330
- .settings-sidebar {
331
- width: 25%;
332
- height: 100%;
333
- }
334
-
335
- .settings-sidebar .set-name {
336
  cursor: pointer;
337
  font-size: 2rem;
338
- display: block;
339
- margin-right: .5rem;
340
- margin-left: -.7rem;
341
- padding: .7rem;
 
342
  border-radius: 5px;
343
  font-weight: bold;
344
- margin-bottom: .5rem;
 
 
 
345
  }
346
 
347
- .settings-sidebar .set-name:hover, .settings-sidebar .set-name.active {
348
- background-color: rgba(255, 255, 255, 0.15);
 
 
349
 
 
 
350
  }
351
 
352
- .settings-detail {
 
353
  border-left: 1.5px solid var(--3);
354
  padding-left: 3rem;
355
  }
356
 
357
- .settings-detail .set-item {
358
- margin: 2rem 0;
359
- margin-top: 0;
360
- }
361
-
362
- .settings-detail .set-name {
363
- font-size: 2rem;
364
- font-weight: bold;
365
- color: var(--4)
366
- }
367
-
368
- .settings-detail .set-desc {
369
- font-size: 1.5rem;
370
- margin-bottom: .5rem;
371
- }
372
-
373
- /* css for custom select */
374
- .custom-select, .options {
375
- font-size: 1.5rem;
376
- background-color: var(--bg);
377
- width: 250px;
378
- padding: 1rem 1.7rem;
379
- border-radius: 7px;
380
- }
381
-
382
- .custom-select {
383
- position: relative;
384
- vertical-align: middle;
385
- margin: .7rem 0;
386
- }
387
-
388
- .custom-select.invalid {
389
- border: 1px solid red;
390
- }
391
-
392
- .custom-select svg {
393
- float: right;
394
- }
395
-
396
- .options {
397
  display: none;
398
- position: absolute;
399
- left: 0;
400
- margin-top: 1.3rem;
401
- width: 100%;
402
- padding: .7rem 1rem;
403
- cursor: pointer;
404
- z-index: 3;
405
- max-height: 15rem;
406
- overflow-y: auto;
407
- }
408
-
409
- .options span {
410
- display: block;
411
- padding: 1rem;
412
- width: 100%;
413
- border-radius: 5px;
414
- vertical-align: middle;
415
  }
416
 
417
- .options span:hover {
418
- background-color: var(--1);
419
- }
420
-
421
- .selected-multiple-option {
422
- padding: .8rem;
423
- border-radius: 5px;
424
- background-color: var(--bg);
425
- margin: .5rem .3rem;
426
- }
427
-
428
- .selected-multiple-option svg {
429
- width: 1.3rem;
430
- height: 1.3rem;
431
- vertical-align: middle;
432
- margin-bottom: .5rem;
433
- cursor: pointer;
434
- }
435
-
436
- .select-multiple-show {
437
- margin: 1rem 0;
438
- font-size: 1.5rem;
439
- }
440
-
441
- .underlined-text {
442
- font-size: 1.7rem;
443
- cursor: pointer;
444
- margin-bottom: .5rem;
445
- display: block;
446
  }
447
 
448
- .settings .submit-btn {
 
449
  padding: 1rem 2rem;
450
  font-size: 1.5rem;
451
  background: var(--3);
452
  color: var(--bg);
453
- border-radius: .5rem;
454
  border: 2px solid transparent;
455
  font-weight: bold;
456
- transition: all .1s ease-out;
457
  cursor: pointer;
458
  box-shadow: 5px 5px;
 
459
  }
460
 
461
- .settings .submit-btn:active {
462
- outline: none;
463
  box-shadow: none;
464
  translate: 5px 5px;
465
  }
466
 
467
- /* Css for error text */
468
-
469
- .errTxt {
470
- color: white;
471
- background: red;
472
- padding: .5rem;
473
- border-radius: 5px;
474
- font-size: 1.3rem;
475
- width: max-content;
476
  }
477
 
478
- /* Css for toggle element */
479
-
480
- label,
481
- label::before,
482
- label::after {
483
- transition: 200ms all ease-in-out 50ms;
484
- box-sizing: border-box;
485
- backface-visibility: hidden;
486
  }
487
 
488
- input[type="checkbox"] {
489
- display: none;
 
 
490
  }
491
 
492
- /*Button is :CHECKED*/
493
-
494
- input[type="checkbox"]:checked ~ div[data-isCheckbox] {
495
- background: rgba(73,168,68,1);
496
- box-shadow: 0 0 2px rgba(73,168,68,1);
 
 
 
 
 
497
  }
498
 
499
- input[type="checkbox"]:checked ~ div[data-isCheckbox] label {
500
- left: 25px;
501
- transform: rotate(360deg);
502
  }
503
 
504
-
505
- /*shared*/
506
-
507
- div[data-isCheckbox],
508
- label {
509
- border-radius: 50px;
510
  }
511
 
 
 
 
 
 
 
 
512
 
513
- /*'un':checked state*/
 
 
514
 
515
- div[data-isCheckbox] {
516
- height: 25px;
517
- width: 50px;
518
- background: rgba(43, 43, 43, 1);
519
  position: relative;
520
- box-shadow: 0 0 2px rgba(43,43,43,1);
521
-
 
522
  }
523
 
524
- label {
525
- height: 20px;
526
- width: 20px;
527
- background: rgba(255, 255, 255, 1);
528
- position: absolute;
529
- top: 3px;
530
- left: 3px;
531
- cursor: pointer;
532
  }
533
 
534
- label::before {
535
- content: '';
536
- height: 15px;
537
- width: 3px;
538
  position: absolute;
539
- top: calc(50% - 8px);
540
- left: calc(50% - 1.5px);
541
- transform: rotate(45deg);
 
 
 
 
 
542
  }
543
 
544
- label::after {
545
- content: '';
546
- height: 3px;
547
- width: 15px;
548
  position: absolute;
549
- top: calc(50% - 2.5px);
550
- left: calc(50% - 8px);
551
- transform: rotate(45deg);
 
 
 
 
 
552
  }
553
 
554
- label::before,
555
- label::after{
556
- background: rgba(43,43,43,1);
557
- border-radius: 5px;
558
  }
559
 
560
- /* pesduo class on toggle */
 
 
561
 
562
- input[type="checkbox"]:checked ~ div label::before{
563
- height: 15px;
564
- top: calc(55% - 8px);
565
- left: calc(60% - 2px);
566
- background: rgba(73,168,68,1);
567
  }
568
 
569
- input[type="checkbox"]:checked ~ div label::after{
570
- width: 7px;
571
- top: calc(95% - 7px);
572
- left: calc(22.5% - 2px);
573
- background: rgba(73,168,68,1);
574
  }
575
 
576
- .searchEng-elem {
577
- display: flex;
578
- gap: 3rem;
579
- align-items: center;
580
- font-size: 1.5rem;
581
- margin: 1rem 0;
582
  }
 
263
 
264
  /* Styles for the about page */
265
 
266
+ .about-container article {
267
  font-size: 1.5rem;
268
+ color: var(--fg);
269
  padding-bottom: 10px;
270
  }
271
 
272
+ .about-container article h1 {
273
  color: var(--2);
274
  font-size: 2.8rem;
275
  }
276
 
277
+ .about-container article div {
278
  padding-bottom: 15px;
279
  }
280
 
281
+ .about-container a {
282
+ color: var(--3);
283
  }
284
 
285
+ .about-container article h2 {
286
  color: var(--3);
287
  font-size: 1.8rem;
288
  padding-bottom: 10px;
289
  }
290
 
291
+ .about-container p {
292
+ color: var(--fg);
293
+ font-size: 1.6rem;
294
  padding-bottom: 10px;
295
  }
296
 
297
+ .about-container h3 {
298
  font-size: 1.5rem;
299
  }
300
 
 
302
  width: 80%;
303
  }
304
 
305
+ .settings_container {
306
+ display: flex;
307
+ justify-content: space-around;
308
+ width: 80dvw;
 
 
309
  }
310
 
311
  .settings h1 {
 
313
  font-size: 2.5rem;
314
  }
315
 
 
316
  .settings hr {
317
  border-color: var(--3);
318
+ margin: 0.3rem 0 1rem 0;
319
  }
320
 
321
+ .settings_container .sidebar {
322
+ width: 30%;
 
 
 
 
 
 
 
 
 
 
323
  cursor: pointer;
324
  font-size: 2rem;
325
+ display: flex;
326
+ flex-direction: column;
327
+ margin-right: 0.5rem;
328
+ margin-left: -0.7rem;
329
+ padding: 0.7rem;
330
  border-radius: 5px;
331
  font-weight: bold;
332
+ margin-bottom: 0.5rem;
333
+ color: var(--fg);
334
+ text-transform: capitalize;
335
+ gap: 1.5rem;
336
  }
337
 
338
+ .settings_container .sidebar .btn {
339
+ padding: 0.5rem;
340
+ border-radius: 0.5rem;
341
+ }
342
 
343
+ .settings_container .sidebar .btn.active {
344
+ background-color: var(--2);
345
  }
346
 
347
+ .settings_container .main_container {
348
+ width: 70%;
349
  border-left: 1.5px solid var(--3);
350
  padding-left: 3rem;
351
  }
352
 
353
+ .settings_container .tab {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
  display: none;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  }
356
 
357
+ .settings_container .tab.active {
358
+ display: flex;
359
+ flex-direction: column;
360
+ justify-content: space-around;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
361
  }
362
 
363
+ .settings_container button {
364
+ margin-top: 1rem;
365
  padding: 1rem 2rem;
366
  font-size: 1.5rem;
367
  background: var(--3);
368
  color: var(--bg);
369
+ border-radius: 0.5rem;
370
  border: 2px solid transparent;
371
  font-weight: bold;
372
+ transition: all 0.1s ease-out;
373
  cursor: pointer;
374
  box-shadow: 5px 5px;
375
+ outline: none;
376
  }
377
 
378
+ .settings_container button:active {
 
379
  box-shadow: none;
380
  translate: 5px 5px;
381
  }
382
 
383
+ .settings_container .main_container .message {
384
+ font-size: 1.5rem;
385
+ color: var(--fg);
 
 
 
 
 
 
386
  }
387
 
388
+ .settings_container .tab h3 {
389
+ font-size: 2rem;
390
+ font-weight: bold;
391
+ color: var(--4);
392
+ margin-top: 1.5rem;
393
+ text-transform: capitalize;
 
 
394
  }
395
 
396
+ .settings_container .tab .description {
397
+ font-size: 1.5rem;
398
+ margin-bottom: 0.5rem;
399
+ color: var(--fg);
400
  }
401
 
402
+ .settings_container .user_interface select {
403
+ margin: 0.7rem 0;
404
+ width: 20rem;
405
+ background-color: var(--bg);
406
+ color: var(--fg);
407
+ padding: 1rem 2rem;
408
+ border-radius: 0.5rem;
409
+ outline: none;
410
+ border: none;
411
+ text-transform: capitalize;
412
  }
413
 
414
+ .settings_container .user_interface option:hover {
415
+ background-color: var(--1);
 
416
  }
417
 
418
+ .settings_container .engines .engine_selection {
419
+ display: flex;
420
+ flex-direction: column;
421
+ justify-content: center;
422
+ gap: 1rem;
423
+ padding: 1rem 0;
424
  }
425
 
426
+ .settings_container .engines .toggle_btn {
427
+ color: var(--fg);
428
+ font-size: 1.5rem;
429
+ display: flex;
430
+ gap: 0.5rem;
431
+ align-items: center;
432
+ }
433
 
434
+ .settings_container .engines hr {
435
+ margin: 0;
436
+ }
437
 
438
+ /* The switch - the box around the slider */
439
+ .switch {
 
 
440
  position: relative;
441
+ display: inline-block;
442
+ width: 6rem;
443
+ height: 3.4rem;
444
  }
445
 
446
+ /* Hide default HTML checkbox */
447
+ .switch input {
448
+ opacity: 0;
449
+ width: 0;
450
+ height: 0;
 
 
 
451
  }
452
 
453
+ /* The slider */
454
+ .slider {
 
 
455
  position: absolute;
456
+ cursor: pointer;
457
+ top: 0;
458
+ left: 0;
459
+ right: 0;
460
+ bottom: 0;
461
+ background-color: var(--bg);
462
+ -webkit-transition: 0.4s;
463
+ transition: 0.4s;
464
  }
465
 
466
+ .slider:before {
 
 
 
467
  position: absolute;
468
+ content: '';
469
+ height: 2.6rem;
470
+ width: 2.6rem;
471
+ left: 0.4rem;
472
+ bottom: 0.4rem;
473
+ background-color: var(--fg);
474
+ -webkit-transition: 0.4s;
475
+ transition: 0.4s;
476
  }
477
 
478
+ input:checked + .slider {
479
+ background-color: var(--3);
 
 
480
  }
481
 
482
+ input:focus + .slider {
483
+ box-shadow: 0 0 1px var(--3);
484
+ }
485
 
486
+ input:checked + .slider:before {
487
+ -webkit-transform: translateX(2.6rem);
488
+ -ms-transform: translateX(2.6rem);
489
+ transform: translateX(2.6rem);
 
490
  }
491
 
492
+ /* Rounded sliders */
493
+ .slider.round {
494
+ border-radius: 3.4rem;
 
 
495
  }
496
 
497
+ .slider.round:before {
498
+ border-radius: 50%;
 
 
 
 
499
  }
public/static/ui_plugins.js DELETED
@@ -1,110 +0,0 @@
1
- /*
2
- Select plugin
3
- Note: Only for single select option
4
- Usage example:
5
- ```
6
- <input name="theme" disabled style="display: none;" required></input>
7
- <div class="custom-select" tabindex="0" data-input="theme" data-default="Select" takeInput>
8
- Svg Icon here
9
- <div class="options">
10
- <span data-value="simple">Simple</span>
11
- </div>
12
- </div>
13
- ```
14
- */
15
-
16
- let svg_tick = `
17
- <svg fill="currentColor" height="1.5rem" width="1.5rem" viewBox="0 0 490 490" xml:space="preserve">
18
- <g id="SVGRepo_iconCarrier">
19
- <polygon points="452.253,28.326 197.831,394.674 29.044,256.875 0,292.469 207.253,461.674 490,54.528 "></polygon>
20
- </g>
21
- </svg>`;
22
-
23
- function toggleSelectOptions(elem, state) {
24
- elem.classList.remove("invalid");
25
- try { elem.parentElement.querySelector('.errTxt').remove();} catch (error) {}
26
- let options = elem.querySelector('.options');
27
- const pos = elem.getBoundingClientRect();
28
- const windowWidth = document.getElementsByTagName("body")[0].clientHeight;
29
- if(pos.y + 250 > windowWidth) {
30
- options.style.bottom = '40px';
31
- } else { options.style.bottom = null }
32
- options.style.display = state != 'close' ? getComputedStyle(options).display == 'none' ? 'block': 'none' : 'none';
33
- }
34
-
35
- let selectElements = document.querySelectorAll('.custom-select').forEach(element => {
36
- let value = element.getAttribute('data-default')
37
- element.childNodes[0].nodeValue = value;
38
- element.querySelector(`.options span[data-value="${value.toLowerCase()}"]`).
39
- innerHTML = `${value} ${svg_tick}`;
40
- element.addEventListener('click', (e) => {if (e.target === element) toggleSelectOptions(element)});
41
- element.addEventListener('focusout', (e) => {if (e.target === element) toggleSelectOptions(element, 'close')});
42
- });
43
-
44
- function singleSelectClickHandler(elem) {
45
- let selectDiv = elem.closest('.custom-select');
46
- let selectedOption = selectDiv.querySelector('span[selected]');
47
- let input = document.querySelector(`[name="${selectDiv.getAttribute('data-input')}"]`);
48
- if (!elem.hasAttribute('selected')) {
49
- if (selectedOption != null) {
50
- selectedOption.removeAttribute('selected');
51
- selectedOption.querySelector('svg').remove();
52
- }
53
- elem.setAttribute('selected', '');
54
- elem.innerHTML = `${elem.innerText} ${svg_tick}`
55
- // Code where value is inserted to input
56
- input.value = elem.getAttribute('data-value') ? elem.getAttribute('data-value') : '';
57
- selectDiv.childNodes[0].nodeValue = elem.innerText;
58
- } else {
59
- elem.removeAttribute('selected');
60
- elem.querySelector('svg').remove();
61
- selectDiv.childNodes[0].nodeValue = selectDiv.getAttribute('data-defaultIfNone');
62
-
63
- input.value = "";
64
- }
65
- selectDiv.blur();
66
- }
67
-
68
- let singleSelectOptions = document.querySelectorAll('.custom-select:not([data-multiple="1"])>.options span');
69
- for (let i = 0; i < singleSelectOptions.length; i++) {
70
- singleSelectOptions[i].addEventListener('click', () => {singleSelectClickHandler(singleSelectOptions[i])});
71
- singleSelectOptions[i].setAttribute('id', 'option-'+i.toString());
72
- }
73
-
74
-
75
- /*
76
- Toggle switch plugin
77
- Usage example:
78
- ```
79
- <input type="hidden" name="searchEng" disabled>
80
- <div class="searchEng">
81
- <div class="searchEng-elem">
82
- <input type="checkbox" id="toggle"/>
83
- <div data-isCheckbox data-input="searchEng" data-value="ddg">
84
- <label for="toggle"></label>
85
- </div>
86
- <span>Duck duck go</span>
87
- </div>
88
- <div class="searchEng-elem">
89
- <input type="checkbox" id="toggle1"/>
90
- <div data-isCheckbox data-input="searchEng" data-value="searx">
91
- <label for="toggle1"></label>
92
- </div>
93
- <span>Searx</span>
94
- </div>
95
- </div>
96
- ```
97
- */
98
-
99
- document.querySelectorAll('[data-isCheckbox]:not([data-value="all"]) label').forEach(checkBoxLabel => {
100
- checkBoxLabel.addEventListener('click', () => {
101
- let checkBox = checkBoxLabel.parentElement;
102
- let helperInput = checkBox.parentElement.querySelector('input[type="checkbox"]');
103
- let mainInput = document.getElementsByName(checkBox.getAttribute('data-input'))[0];
104
- if (helperInput.checked == true) {
105
- mainInput.value = mainInput.value.replace(checkBox.getAttribute('data-value') + ',', '');
106
- } else {
107
- mainInput.value += checkBox.getAttribute('data-value') + ',';
108
- }
109
- });
110
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/templates/cookies_tab.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ <div class="cookies tab">
2
+ <h1>Cookies</h1>
3
+ <p class="description"></p>
4
+ <input type="text" name="cookie_field" value="" readonly />
5
+ </div>
public/templates/engines_tab.html ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="engines tab">
2
+ <h3>select search engines</h3>
3
+ <p class="description">
4
+ Select the search engines from the list of engines that you want results
5
+ from
6
+ </p>
7
+ <div class="engine_selection">
8
+ <div class="toggle_btn">
9
+ <label class="switch">
10
+ <input type="checkbox" class="select_all" onchange="toggleAllSelection()" />
11
+ <span class="slider round"></span>
12
+ </label>
13
+ Select All
14
+ </div>
15
+ <hr />
16
+ <div class="toggle_btn">
17
+ <label class="switch">
18
+ <input type="checkbox" class="engine" />
19
+ <span class="slider round"></span>
20
+ </label>
21
+ Duckduckgo
22
+ </div>
23
+ <div class="toggle_btn">
24
+ <label class="switch">
25
+ <input type="checkbox" class="engine" />
26
+ <span class="slider round"></span>
27
+ </label>
28
+ Searx
29
+ </div>
30
+ </div>
31
+ </div>
public/templates/footer.html CHANGED
@@ -10,6 +10,7 @@
10
  </ul>
11
  </div>
12
  </footer>
 
13
  </body>
14
 
15
  </html>
 
10
  </ul>
11
  </div>
12
  </footer>
13
+ <script src="static/settings.js"></script>
14
  </body>
15
 
16
  </html>
public/templates/general_tab.html ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ <div class="general tab active">
2
+ <h1>General</h1>
3
+ <p class="description">Coming soon!!</p>
4
+ </div>
public/templates/header.html CHANGED
@@ -1,29 +1,14 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
- <head>
 
4
  <title>Websurfx</title>
5
  <meta charset="UTF-8" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
- <!-- <link href="static/colorschemes/{{colorscheme}}.css" rel="stylesheet" type="text/css" /> -->
8
- <!-- <link href="static/themes/{{theme}}.css" rel="stylesheet" type="text/css" /> -->
9
- </head>
10
 
11
- <body>
12
  <header>{{>navbar}}</header>
13
- <script>
14
- const cookies = document.cookie.split(';').map(item => item.split('=')).
15
- reduce((acc, [k, v]) => (acc[k.trim().replace('"', '')] = v) && acc, {});
16
- // Load colorscheme and theme from cookie
17
- function addCss(fileName) {
18
- var head = document.head;
19
- var link = document.createElement("link");
20
-
21
- link.type = "text/css";
22
- link.rel = "stylesheet";
23
- link.href = fileName;
24
 
25
- head.appendChild(link);
26
- }
27
- addCss('static/themes/'+ (cookies["theme"] || '{{theme}}') + '.css');
28
- addCss('static/colorschemes/'+ (cookies["color-sch"] || '{{colorscheme}}') + '.css');
29
- </script>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
+
4
+ <head>
5
  <title>Websurfx</title>
6
  <meta charset="UTF-8" />
7
  <meta name="viewport" content="width=device-width, initial-scale=1" />
8
+ <link href="static/colorschemes/{{colorscheme}}.css" rel="stylesheet" type="text/css" />
9
+ <link href="static/themes/{{theme}}.css" rel="stylesheet" type="text/css" />
10
+ </head>
11
 
12
+ <body onload="getClientSettings()">
13
  <header>{{>navbar}}</header>
 
 
 
 
 
 
 
 
 
 
 
14
 
 
 
 
 
 
public/templates/navbar.html CHANGED
@@ -1,7 +1,6 @@
1
  <nav>
2
- <ul>
3
- <li><a href="/">search</a></li>
4
- <li><a href="about">about</a></li>
5
- <li><a href="settings">settings</a></li>
6
- </ul>
7
  </nav>
 
1
  <nav>
2
+ <ul>
3
+ <li><a href="about">about</a></li>
4
+ <li><a href="settings">settings</a></li>
5
+ </ul>
 
6
  </nav>
public/templates/settings.html CHANGED
@@ -1,107 +1,22 @@
1
  {{>header this}}
2
- <main class="settings">
3
- <h1>Settings</h1>
4
- <hr>
5
- <div class="settings-view">
6
- <div class="settings-sidebar">
7
- <span class="set-name active" data-detailId="all">All</span>
8
- <span class="set-name" data-detailId="searchEng">Search Engine</span>
9
- <span class="set-name" data-detailId="theme">Theme</span>
10
- </div>
11
- <div class="settings-detail">
12
- <form name="settings" onsubmit="submitSettings(); return false;">
13
- <!-- Search engine settings -->
14
- <div class="set-item" data-id="searchEng">
15
- <h3 class="set-name">Select search engines</h3>
16
- <p class="set-desc">Select the search engines from the list of engines that you want results from</p>
17
- <!-- toggle element -->
18
- <input type="hidden" name="searchEng" required value="ddg,searx,">
19
- <div class="searchEng" takeInput>
20
- <div class="searchEng-elem">
21
- <input type="checkbox" id="selectAll-eng" onclick="return selectAllHandler(this);"/>
22
- <div data-isCheckbox data-input="searchEng" data-value="all">
23
- <label for="selectAll-eng"></label>
24
- </div>
25
- <span>Select all</span>
26
- </div>
27
- <hr>
28
- <div class="searchEng-elem">
29
- <input type="checkbox" id="toggle" checked/>
30
- <div data-isCheckbox data-input="searchEng" data-value="ddg">
31
- <label for="toggle"></label>
32
- </div>
33
- <span>Duck duck go</span>
34
- </div>
35
- <div class="searchEng-elem">
36
- <input type="checkbox" id="toggle1" checked/>
37
- <div data-isCheckbox data-input="searchEng" data-value="searx">
38
- <label for="toggle1"></label>
39
- </div>
40
- <span>Searx</span>
41
- </div>
42
- </div>
43
- <!-- End search select -->
44
- </div>
45
- <!-- End search engine setting -->
46
-
47
- <!-- Theme selection settings -->
48
- <div class="set-item" data-id="theme">
49
- <h3 class="set-name">Select theme</h3>
50
- <p class="set-desc">Select the theme from the available themes to be used in user interface</p>
51
- <!-- Select element -->
52
- <input type="hidden" name="theme" style="display: none;" required value="simple"></input>
53
- <div class="custom-select" tabindex="0" data-input="theme" data-default="simple" takeInput
54
- data-defaultIfNone="Select">
55
- <svg viewBox="0 0 24 24" width="2rem" height="2rem" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
56
- <path d="M6.1018 8C5.02785 8 4.45387 9.2649 5.16108 10.0731L10.6829 16.3838C11.3801 17.1806 12.6197 17.1806
57
- 13.3169 16.3838L18.8388 10.0731C19.5459 9.2649 18.972 8 17.898 8H6.1018Z">
58
- </path>
59
- </svg>
60
- <div class="options">
61
- <span data-value="simple" selected>simple</span>
62
- </div>
63
- </div>
64
- <!-- End select element -->
65
- </div>
66
- <!-- End theme selection select -->
67
-
68
- <!-- Color scheme selection settings -->
69
- <div class="set-item" data-id="theme">
70
- <h3 class="set-name">Select Color Scheme</h3>
71
- <p class="set-desc">Select the color scheme for your theme to be used in user interface</p>
72
- <!-- Select element -->
73
- <input type="hidden" name="color-sch" style="display: none;" required value="catppuccin-mocha"></input>
74
- <div class="custom-select" tabindex="0" data-input="color-sch" data-default="catppuccin-mocha" takeInput
75
- data-defaultIfNone="Select">
76
- <svg viewBox="0 0 24 24" width="2rem" height="2rem" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
77
- <path d="M6.1018 8C5.02785 8 4.45387 9.2649 5.16108 10.0731L10.6829 16.3838C11.3801 17.1806 12.6197 17.1806
78
- 13.3169 16.3838L18.8388 10.0731C19.5459 9.2649 18.972 8 17.898 8H6.1018Z">
79
- </path>
80
- </svg>
81
- <div class="options">
82
- <span data-value="catppuccin-mocha" selected>catppuccin-mocha</span>
83
- <span data-value="dracula">dracula</span>
84
- <span data-value="monokai">monokai</span>
85
- <span data-value="nord">nord</span>
86
- <span data-value="oceanic-next">oceanic-next</span>
87
- <span data-value="solarized-dark">solarized-dark</span>
88
- <span data-value="solarized-light">solarized-light</span>
89
- <span data-value="tomorrow-night">tomorrow-night</span>
90
- </div>
91
- </div>
92
- <!-- End select element -->
93
- </div>
94
- <!-- End color scheme selection -->
95
-
96
- <!-- ACTIONS -->
97
- <div class="actions">
98
- <input type="submit" value="Submit" class="submit-btn">
99
- </div>
100
- <!-- End Actions -->
101
- </form>
102
- </div>
103
- </div>
104
  </main>
105
- <script src="static/ui_plugins.js"></script>
106
  <script src="static/settings.js"></script>
 
107
  {{>footer}}
 
1
  {{>header this}}
2
+ <main class="settings" >
3
+ <h1>Settings</h1>
4
+ <hr />
5
+ <div class="settings_container">
6
+ <div class="sidebar">
7
+ <div class="btn active" onclick="setActiveTab(this)">general</div>
8
+ <div class="btn" onclick="setActiveTab(this)">user interface</div>
9
+ <div class="btn" onclick="setActiveTab(this)">engines</div>
10
+ <div class="btn" onclick="setActiveTab(this)">cookies</div>
11
+ </div>
12
+ <div class="main_container">
13
+ {{> general_tab}} {{> user_interface_tab}} {{> engines_tab}} {{>
14
+ cookies_tab}}
15
+ <p class="message"></p>
16
+ <button type="submit" onclick="setClientSettings()">Save</button>
17
+ </div>
18
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  </main>
 
20
  <script src="static/settings.js"></script>
21
+ <script src="static/cookies.js"></script>
22
  {{>footer}}
public/templates/user_interface_tab.html ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="user_interface tab">
2
+ <h3>select theme</h3>
3
+ <p class="description">
4
+ Select the theme from the available themes to be used in user interface
5
+ </p>
6
+ <select name="themes">
7
+ <option value="simple">simple</option>
8
+ </select>
9
+ <h3>select color scheme</h3>
10
+ <p class="description">
11
+ Select the color scheme for your theme to be used in user interface
12
+ </p>
13
+ <select name="colorschemes">
14
+ <option value="catppuccin-mocha">catppuccin mocha</option>
15
+ <option value="dark-chocolate">dark chocolate</option>
16
+ <option value="dracula">dracula</option>
17
+ <option value="gruvbox-dark">gruvbox dark</option>
18
+ <option value="monokai">monokai</option>
19
+ <option value="nord">nord</option>
20
+ <option value="oceanic-next">oceanic next</option>
21
+ <option value="one-dark">one dark</option>
22
+ <option value="solarized-dark">solarized dark</option>
23
+ <option value="solarized-light">solarized light</option>
24
+ <option value="tokyo-night">tokyo night</option>
25
+ <option value="tomorrow-night">tomorrow night</option>
26
+ </select>
27
+ </div>