This repository has been archived by the owner on Feb 24, 2022. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path_templates.ts
766 lines (736 loc) · 19.6 KB
/
_templates.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
/**
* The _templates.ts file gives a template for creating a new *Templates.ts file.
* This is used to add new Languages to the view creation.
*
* Prefilled sections can and should be copy pasted.
*
* Every subreddit, article and user field should be
* a reference to the object. This is done with the handleMessageSending function.
*
* I know that using a file for every language is not the prettiest,
* best maintainable or even a good solution for the feature.
*/
/**
* Import the used interfaces.
*/
import { ITemplateData, IConfigData } from "../interfaces";
/**
* The `head` function returns the head of the HTML string.
* It contains the link to the stylesheet to load the colors
* of element types. The stylesheet path needs to be formatted as
* vscode webview uri and can be found in the config param.
*
* To pass the editor font configuration to the template the parameter
* `fontFamily`, `fontSize`, `fontWeight` and `fontHeight` are used.
*
* The `onload="scrollTop()"` in the body is used to reset the scroll-level
* back to the top when changing a view. The `scrollTop` function can be found in
* `script()`.
*
* ```html
* <!DOCTYPE html>
* <html lang="en">
* <head>
* <meta charset="UTF-8">
* <meta name="viewport" content="width=device-width, initial-scale=1.0">
* <link rel="stylesheet" href="${data.stylesheet}">
* </head>
* <body onload="scrollTop()" style="
* font-family: ${data.fontFamily};
* font-size: ${data.fontSize}px;
* font-weight: ${data.fontWeight};
* line-height: ${data.lineHeight}px;
* ">
* ```
*
* @param config
* @category View - Template
*/
export function head(data: any): string {
let HTML: string = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="${data.stylesheet}">
</head>
<body onload="scrollTop()" style="
font-family: ${data.fontFamily};
font-size: ${data.fontSize}px;
font-weight: ${data.fontWeight};
line-height: ${data.lineHeight}px;
">
`;
return HTML;
}
/**
* The `tail` function returns the tail of the HTML string.
* It closes the body and html tag.
*
* ```html
* </body>
* </html>
* ```
*
* @category View - Template
*/
export function tail(): string {
let HTML: string = `</body></html>`;
return HTML;
}
/**
* The `script` function returns the script section of the HTML string.
* It's functions are absolutely necessary for Reddit-Viewer to work.
*
*
*
* The function `handleMessageSending` is used to send messages to the vscode webview.
* It contains the params `command`, `view` and `args`.
* - command: The action to be executed. E.g. when opening a subreddit the command is `subreddit`.
* - view: The view from which the command is fired. E.g. when opening a subreddit from the home
* view the view is `home`.
* - args: Array of optional arguments for the command. E.g. when opening a subreddit the name of
* subreddit is needed and is provided as `arg[0]`.
*
* Code:
* ```javascript
* \// get an instance of the vscode api
* const vscode = acquireVsCodeApi();
*
* \// handle vscode extension message passing (from webview to extension)
* function handleMessageSending(command, view, args) {
* vscode.postMessage({
* command: command,
* view: view,
* args: args,
* });
* }
* ```
*
* Usage:
* ```html
* <a href="" onclick="handleMessageSending('foo', 'bar', 'pub')">
* ```
*
* The function `executeSearch` is used to retrieve the value of the
* search input field, validate it and then parse it to be send to
* the vscode webview.
* - view: The view from which the command is fired. E.g. when opening a subreddit from the home
* view the view is `home`.
*
* Code:
* ```javascript
* \// execute the search
* function executeSearch(view) {
* let val = document.getElementById('searchQuery').value;
* if(val.trim().length != 0){
* let args = [];
* args.push(val);
* handleMessageSending('search', view, args);
* } else {
* val = "";
* \// error
* }
* }
* ```
*
* Usage:
* ```html
* <a href="" onclick="executeSearch('foo')">
* ```
*
* The function `openSubreddit` is used to retrieve the value of the
* open input field, validate it and then parse it to be send to the
* vscode webview.
* - view: The view from which the command is fired. E.g. when opening a subreddit from the home
* view the view is `home`.
*
* Code:
* ```javascript
* \// open a subreddit
* function openSubreddit(view) {
* let val = document.getElementById('openQuery').value;
* if(val.trim().length != 0){
* let args = [];
* args.push(val);
* handleMessageSending('subreddit', view, args);
* } else {
* val = "";
* \// error
* }
* }
* ```
*
* Usage:
* ```html
* <a href="" onclick="openSubreddit('foo')">
* ```
*
* The `login` function is used to send the login information to the
* extension script. It will color the inputs red if there is missing
* information.
*
* Code:
* ```javascript
* \// log the user into reddit
* function login() {
* let username = document.getElementById('username').value;
* let password = document.getElementById('password').value;
* if(username.trim().length != 0 && password.trim().length != 0) {
* let args = [];
* args.push(username);
* args.push(password);
* handleMessageSending('login', 'home', args);
* } else {
* document.getElementById('username').style.color = "red";
* document.getElementById('password').style.color = "red";
* }
* }
* ```
*
* Usage:
* ```html
* <a onclick="login()"></a>
* ```
*
* The function `resetError` is used to reset the styling for
* incorrect login input.
*
* Code:
* ```javascript
* \// reset the error colors of the login
* function resetError() {
* document.getElementById('username').style.color = "inherit";
* document.getElementById('password').style.color = "inherit";
* }
* ```
*
* Usage:
* ```html
* <input onfocus="resetError()">
* ```
*
* The function `expandElement` is used to change the display style
* of a given element to make it appear or disappear.
* It is used used to unhide/hide media and comments.
* - id: The id of the element to be expanded. E.g. if the element with the id `foo` should
* be hidden/unhidden the id is `foo`.
*
* Code:
* ```javascript
* \// switches between display:none and display:inherit
* function expandElement(id) {
* element = document.getElementById(id);
* if(element.style.display === "none") {
* element.style.display = "inherit";
* } else {
* element.style.display = "none";
* }
* }
* ```
*
* Usage:
* ```html
* <a href="" onclick="expandElement('foo')">
* ```
*
* The function `scrollTop` is used to set the scroll-level of
* the webview to zero. If this isn't done the webview would stay
* on the same level after changing views.
*
* Code:
* ```javascript
* \// called on body load
* \// scrolls to top
* function scrollTop() {
* document.body.scrollTop = document.documentElement.scrollTop = 0;
* }
* ```
*
* Usage:
* ```html
* <body onload="scrollTop()">
* ```
*
* The function `checkKey` checks a keyup event for
* the keycode and fires the action of the element
* if the pressed key is enter.
*
* Code:
* ```javascript
* \// checks if enter is pressed
* function checkKey(element) {
* if(event.keyCode === 13) {
* switch(element){
* case "search":
* executeSearch('home');
* break;
* case "open":
* openSubreddit('home');
* break;
* case "login":
* login();
* break;
* default:
* break;
* }
* }
* }
* ```
*
* Usage:
* ```html
* <input onkeyup="checkKey('foo')">
* ```
*
* @category View - Template
*/
export function script(): string {
let HTML: string = `
<script>
const vscode = acquireVsCodeApi();
// handle vscode extension message passing (from webview to extension)
function handleMessageSending(command, view, args) {
vscode.postMessage({
command: command,
view: view,
args: args,
});
}
// execute the search
function executeSearch(view) {
let val = document.getElementById('searchQuery').value;
if(val.trim().length != 0){
let args = [];
args.push(val);
handleMessageSending('search', view, args);
} else {
val = "";
// error
}
}
// open a subreddit
function openSubreddit(view) {
let val = document.getElementById('openQuery').value;
if(val.trim().length != 0){
let args = [];
args.push(val);
handleMessageSending('subreddit', view, args);
} else {
val = "";
// error
}
}
// log the user into reddit
function login() {
let username = document.getElementById('username').value;
let password = document.getElementById('password').value;
if(username.trim().length != 0 && password.trim().length != 0) {
let args = [];
args.push(username);
args.push(password);
handleMessageSending('login', 'home', args);
} else {
document.getElementById('username').style.color = "red";
document.getElementById('password').style.color = "red";
}
}
// reset the error colors of the login
function resetError() {
document.getElementById('username').style.color = "inherit";
document.getElementById('password').style.color = "inherit";
}
// switches between display:none and display:inherit
function expandElement(id) {
element = document.getElementById(id);
if(element.style.display === "none") {
element.style.display = "inherit";
} else {
element.style.display = "none";
}
}
// called on body load
// scrolls to top
function scrollTop() {
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
// checks if enter is pressed
function checkKey(element) {
if(event.keyCode === 13) {
switch(element){
case "search":
executeSearch('home');
break;
case "open":
openSubreddit('home');
break;
case "login":
login();
break;
default:
break;
}
}
}
</script>
`;
return HTML;
}
/**
* The `functionHead` function returns the head of a function section.
* A function section encloses other templates and should always close with
* the `functionTail` function.
*
* There are no functional parts in this template section.
*
* Javascript example:
* ```javascript
* function name(param) {
* ```
*
* @param data
* @category View - Template
*/
export function functionHead(data: ITemplateData): string {
return "template";
}
/**
* The `functionTail` function returns the tail of a function section.
* This is needed to close the div of the section and should contain a
* suitable closing to the head.
*
* Javascript example:
* ```javascript
* }
* ```
*
* @category View - Template
*/
export function functionTail(): string {
return "template";
}
/**
* The `lineComment` function returns the HTML string of a line comment.
* It is used to display the view name and additional info like the
* description of a subreddit.
*
* Javascript example:
* ```javascript
* \// COMMENT
* ```
*
* @param comment
* @category View - Template
*/
export function lineComment(comment: string): string {
return "template";
}
/**
* The `open` function returns the HTML string of the section to open
* a subreddit. It needs to contain an element to fire the `openSubreddit`
* function and an input element with the id `openQuery`.
*
* - `openSubreddit` element example:
* ```html
* <a href="" onlcick="openSubreddit('foo')">
* ```
*
* - `openQuery` input example:
* ```html
* <input id="openQuery">
* ```
*
* Javascript example:
* ```javascript
* open("____________");
* ```
*
* @category View - Template
*/
export function open(): string {
return "template";
}
/**
* The `search` function returns the HTML string of the section to search
* for subreddits and articles. It needs to contain an element to fire the
* `executeSearch` function and an input element with the id `searchQuery`.
*
* - `executeSearch` element example:
* ```html
* <a onclick="executeSearch('foo')">
* ```
*
* - `searchQuery` input example:
* ```html
* <input id="searchQuery">
* ```
*
* Javascript example:
* ```javascript
* search("____________");
* ```
*
* @category View - Template
*/
export function search(): string {
return "template";
}
/**
* The `login` function returns the HTML string of the section to log an account
* into reddit. It needs to contain two input fields for the username and password.
* It needs a field to fire the `login` function.
*
* - `login` element example:
* ```
* <a onclick="login()">
* ```
*
* - Input example:
* ```
* <input id="username"> <input id="password">
* ```
*
* Javascript example:
* ```javascript
* login(____________, ____________);
* ```
*
* @category View - Template
*/
export function login(): string {
return "template";
}
/**
* The `logout` function returns the HTML string of the section to log an account
* out of reddit. It needs to contain an element that fires the `handleMessageSending`
* to send the `logout` command to the extension.
*
* - Logout command example:
* ```html
* <a onclick="handleMessageSending('logout', view, args)">
* ```
*
* Javascript example:
* ```javascript
* logout(username);
* ```
*
* @param data
* @category View - Template
*/
export function logout(data: ITemplateData): string {
return "template";
}
/**
* The `trend` function returns the HTML string of the section to browse the
* currently trending subreddits. The names need to fire the `subreddit` command
* to the extension and contain its name in the args param.
*
* - Subreddit command example:
* ```html
* <a onclick="handleMessageSending('subreddit', view, ['subreddit'])">
* ```
*
* Javascript example:
* ```javascript
* let trends = [ "trend1", "trend2", "trend3" ];
* ```
*
* @param data
* @category View - Template
*/
export function trend(data: ITemplateData): string {
return "template";
}
/**
* The `sort` function returns the HTML string of the section to sort
* the current view by its sort types. The sort names need to fire the
* corresponding sort command. E.g. sort1 fires the command sort1.
*
* - Sort command example:
* ```html
* <a onclick="handleMessageSending('sort1', view, args)">
* ```
*
* Javascript example:
* ```javascript
* const sort = require( "sort1", "sort2", "sort3" );
* ```
*
* @param data
* @category View - Template
*/
export function sort(data: ITemplateData): string {
return "template";
}
/**
* The `time` function returns the HTML string of the section to set the interval
* of the current view. The time names need to fire the corresponding time command.
* E.g. time1 fires the command time1.
*
* - Time command example:
* ```html
* <a onclick="handleMessageSending('time1', view, args)">
* ```
*
* Javascript example:
* ```javascript
* const time = require( "time1", "time2", "time3" );
* ```
*
* @param data
* @category View - Template
*/
export function time(data: ITemplateData): string {
return "template";
}
/**
* The `article` function returns the HTML string of the section to
* represent an article entry. It should display the score, subreddit, author, title and preview.
* It needs at least the title which sends the `article` command with the subreddit and
* article_id to the extension.
*
* - Article command example:
* ```html
* <a onclick="handleMessageSending('article', view, ['subreddit', 'article_id'])">
*
* Javascript example:
* ```javascript
* if (123 in ('r/reddit.com', ekarbe )) {
* return { title: "article title", pre: show() };
* }
* ```
*
* @param data
* @category View - Template
*/
export function article(data: ITemplateData): string {
return "template";
}
/**
* The `pagination` function returns the HTML string of the section to browse
* multiple pages of the current view. It needs an element to send the
* `prev` command and the before param and an element to send the `next` command and the after param.
*
* - Prev command example:
* ```html
* <a onclick="handleMessageSending('prev', view, [count, undefined, 'before'])">
* ```
*
* - Next command example:
* ```html
* <a onclick="handleMessageSending('next', view, [count, 'after', undefined])">
* ```
*
* Javascript example:
* ```javascript
* export default { prev(this) { return this-1 }, next(this) { return this+1 } };
* ```
*
* @param data
* @category View - Template
*/
export function pagination(data: ITemplateData): string {
return "template";
}
/**
* The `breadcrumb` function returns the HTML string of the section to navigate
* through multiple views. The breadcrumb names need to send their corresponding
* commands to the extensiom. E.g. breadcrumb1 send the command breadcrumb1.
*
* - Breadcrumb command example:
* ```html
* <a onclick="handleMessageSending('breadcrumb1', view, args)">
* ```
*
* Javascript example:
* ```javascript
* \// import the environment constants
* import { breadcrumb1, breadcrumb2, breadcrumb3 } from "extension/environment";
* ```
*
* @param data
* @category View - Template
*/
export function breadcrumb(data: ITemplateData): string {
return "template";
}
/**
* The `articleDetail` function returns the HTML string of the article view section.
* It should display the score, upvote_ratio, subreddit, author, date, media_url and
* a view of the media or selftext.
*
* Javascript example:
* ```javascript
* data.parse(123, 90%, 'r/reddit.com', ekarbe, '01/01/2001T14:42');
* let comments = 30;
* let media = parseMedia(data.path);
* showMedia(media);
* ```
*
* @param data
* @category View - Template
*/
export function articleDetail(data: ITemplateData): string {
return "template";
}
/**
* The `comment` function returns the HTML string of a comment chain section.
* It should display the score, author, time and selftext. It needs to recursively
* call itself to show the child comment/replies.
*
* Javascript example:
* ```javascript
* if (123 in (ekarbe, '01/01/2001T14:42')) {
* let body = { };
* }
* ```
*
* @param data
* @category View - Template
*/
export function comment(data: ITemplateData): string {
return "template";
}
/**
* The `userAbout` function returns the HTML string of the users information section.
* It should display the karma, submitted_karma and comment_karma.
*
* Javascript example:
* ```javascript
* let splittedData = data.split(",");
* let karma = splittedData[3242];
* let posts = splittedData[213];
* let comments = splittedData[2900];
* ```
*
* @param data
* @category View - Template
*/
export function userAbout(data: ITemplateData): string {
return "template";
}
/**
* The `subredditSearch` function returns the HTML string of the subreddit search section.
* The subreddit names need to send the `subreddit` command to the extension.
*
* - Subreddit command example:
* ```html
* <a onclick="handleMessageSending('subreddit', view, ['subreddit1'])">
* ```
*
* Javascript example:
* ```javascript
* const subs = {
* "GetMotivated": params,
* "blaReddit": params,
* }
* ```
*
* @param data
* @category View - Template
*/
export function subredditSearch(data: ITemplateData): string {
return "template";
}