]> git.gir.st - subscriptionfeed.git/blob - app/reddit/static/client.js
reddit: textarea hack does't escape quotes
[subscriptionfeed.git] / app / reddit / static / client.js
1 function template(tpl, replacements) {
2 function safetify(s) {
3 // decodes and re-encodes html entities
4 let e = document.createElement("textarea");
5 e.innerHTML = s;
6 e.innerText = e.value;
7 return e.innerHTML.replaceAll('"','"').replaceAll("'","'");
8 }
9
10 for (let key in replacements) {
11 tpl = tpl.replaceAll("{{"+key+"}}", safetify(replacements[key]));
12 }
13 return tpl;
14 }
15
16 function load_page(subreddits, {sorted_by='hot', time='', limit=36, count='', before='', after=''}) {
17
18 let multireddit = subreddits.join("+");
19 let query = new URLSearchParams({
20 count, before, after, limit,
21 t: time, // hour,week,month,year,all
22 }).toString();
23
24 fetch_jsonp(`https://www.reddit.com/r/${multireddit}/${sorted_by}.json?${query}`).then(json => {
25 for (entry of json.data.children) {
26 let e = entry.data;
27 if (e.score == 0) continue; /*more downvotes than upvotes, ignore*/
28 if (!['youtube.com', 'youtu.be', 'youtube-nocookie.com'].includes(e.domain)) continue;
29 let match = e.url.match(/^https?:\/\/(?:www.|m.)?(?:youtube.com\/watch\?(?:.*&)?v=|youtu.be\/|youtube(?:-nocookie)?.com\/(?:embed|shorts|live)\/|youtube.com\/)([-_0-9A-Za-z]+)(?:[?&#]t=([0-9hms:]+))?/);
30 if (!match) continue;
31 let video_id = match[1], timestamp = match[2], maybe_length=null;
32 match = e.title.match(/.*[\[(](?:00:)?(\d\d?(?::\d\d){1,2})[\])]/);
33 if (match) {
34 maybe_length = match[1];
35 // 20:59:00 => 20:59 (we're assuming no video is >10h)
36 maybe_length = maybe_length.replace(/([1-9]\d:\d\d):00/, "$1")
37 }
38 document.querySelector('#cards').innerHTML += template(window.card.innerHTML, {
39 karma: e.score,
40 title: e.title,
41 url: e.permalink,
42 videoid: video_id,
43 length: maybe_length||'',
44 timestamp: timestamp||'',
45 comments: e.num_comments,
46 subreddit: e.subreddit,
47 });
48 }
49 document.querySelector('#cards').innerHTML += window.dummycards.innerHTML;
50 document.querySelector('.pagination-container').innerHTML = window.pagination.innerHTML
51 .replaceAll(/%7B%7Bafter%7D%7D/g, json.data.after);
52 }).catch(e=>{
53 console.error(e);
54 document.querySelector('#cards').innerHTML = `
55 <ul class=flashes><li class="error">Loading reddit content failed. Make sure requests to reddit.com are not blocked by your browser or an addon.</li></ul>
56 `;
57 });
58 }
59
60 /* the following code has been adapted from https://xkcd.wtf (AGPLv3) */
61 let __fetch_jsonp_index = 0;
62 let abort = new AbortController();
63 function fetch_jsonp(url, cbparam = 'jsonp') {
64 abort.abort(); //cancel previous request
65 abort = new AbortController(); //re-init aborter
66 return new Promise((resolve, reject) => {
67 let tmp = '__fetch_jsonp_'+__fetch_jsonp_index++;
68 let s = document.createElement("script");
69 s.src = url + '&' + cbparam + '=' + tmp;
70 s.onerror = err => reject(err);
71 window[tmp] = json => resolve(json);
72 abort.signal.addEventListener('abort', ()=> {
73 s.src="";
74 reject(new DOMException('Aborted', 'AbortError'))
75 });
76 document.body.appendChild(s);
77 });
78 }
Imprint / Impressum