generic-skin 2.5.2 → 2.6.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,862 +1,954 @@
1
1
  const FNR = {
2
- execFn: (callback) => {
3
- document.addEventListener('forumReady', callback, false);
4
- },
5
- forum: {
6
- getColors: () => {
7
- return Object.values(forumColours)
8
- .map((item) => {
9
- return {
10
- name: item.code,
11
- hex: item.hex
12
- }
13
- });
14
- },
15
- getTopics: (array, limit) => {
16
- return new Promise((resolve, reject) => {
17
- const addContent = (elmt) => {
18
- const titleElmnt = $(elmt).find('.topictitle');
19
- const dateElmnt = $(elmt).children().last();
20
-
21
- finalArray.push({
22
- name: titleElmnt.text().trim(),
23
- url: Vue.filter('url-to-normal')(titleElmnt.attr('href')),
24
- lastpost: {
25
- url: Vue.filter('url-to-normal')(dateElmnt.children().last().attr('href')),
26
- date: dateElmnt.text().split('por')[0].trim(),
27
- who: {
28
- name: dateElmnt.find('strong a').length ? dateElmnt.find('strong a').text().trim() : 'Invitado',
29
- url: Vue.filter('url-to-normal')(dateElmnt.find('strong a').length ? dateElmnt.find('strong a').attr('href') : '/'),
30
- color: dateElmnt.find('strong a').length ? dateElmnt.find('strong a span').attr('style').split('color:')[1] : 'initial',
31
- },
32
- },
33
- forum: {
34
- name: $(elmt).find('.row2 + .row2:not(.centered) a').text().trim(),
35
- url: Vue.filter('url-to-normal')($(elmt).find('.row2 + .row2:not(.centered) a').attr('href')),
36
- },
37
- });
38
- };
39
-
40
- const getPage = (url) => {
41
- $.get(url, (data) => {
42
- $(data).find('.ipbform').find('tbody').find('tr').each(function() {
43
- if (finalArray.length < limit && array.indexOf(parseInt($(this).find('.row2 + .row2:not(.centered) a').attr('href').split('/f')[1].split('-')[0])) === -1) {
44
- addContent(this);
45
- }
46
- });
47
-
48
- if (finalArray.length === limit || !$(data).find('.pagination')[0].children.length || $(data).find('.pagination').children().last()[0].localName === 'b') {
49
- resolve(finalArray);
50
- } else {
51
- getPage($(data).find('.pagination').children().last().attr('href'));
52
- }
53
- });
54
- };
55
-
56
- let finalArray = [];
57
-
58
- getPage('/latest?change_version=invision');
59
- });
60
- },
61
- getMembers: (option) => {
62
- return new Promise((resolve, reject) => {
63
- let members = [];
64
-
65
- const getUserData = (user, color) => {
66
- return {
67
- user: $(user).find('.membername span').text().trim(),
68
- id: $(user).find('.popupmenu .popupmenu-item a').attr('href').split('?')[0],
69
- img: $(user).find('.mini-avatar img').attr('src'),
70
- color: color
71
- };
72
- };
73
-
74
- const getUsersPage = (page) => {
75
- let users = [];
76
-
77
- $(page).find('.member-list .member').each(function() {
78
- const group = FNR.utility.getGroup($(this).find('.membername span').attr('style').split('color:')[1]);
79
-
80
- if (option) {
81
- users.push(getUserData(this, group));
82
- } else {
83
- if (group !== 'unknown' && group !== forumConfig.skinOptions.adminGroup) {
84
- users.push(getUserData(this, group));
85
- }
86
- }
87
- });
88
-
89
- return users;
90
- };
91
-
92
- const getPage = (url) => {
93
- $.get(url, (data) => {
94
- const nextURL = $(data).find('.pagination img[alt="Siguiente"]').parent().attr('href') || false;
95
-
96
- members = members.concat(getUsersPage(data));
97
-
98
- if (nextURL) {
99
- getPage(nextURL);
100
- } else {
101
- resolve(members.sort((a, b) => {
102
- if (a.user < b.user) return -1;
103
- if (a.user > b.user) return 1;
104
- return 0;
105
- }));
106
- }
107
- });
108
- };
109
-
110
- getPage('/memberlist?change_version=invision');
111
- });
112
- },
113
- getGroups: (cache) => {
114
- const getData = () => {
115
- return new Promise((resolve, reject) => {
116
- $.get('/groups?change_version=invision', (data) => {
117
- let groups = [];
118
-
119
- $(data).find('.group_list > li').each(function() {
120
- groups.push({
121
- id: parseInt($(this).find('a').attr('href').split('/g')[1].split('-')[0]),
122
- name: $(this).find('a').text().trim(),
123
- color: $(this).find('a').css('color'),
124
- url: Vue.filter('url-to-normal')($(this).find('a').attr('href')),
125
- count: parseInt($(this).find('div > span').text()) - 1
126
- });
127
- });
128
-
129
- resolve(groups);
130
- });
131
- });
132
- };
133
-
134
- const readGroupsCache = () => {
135
- return new Promise((resolve, reject) => {
136
- FNR.cache.useData('groups', cache).then(
137
- (result) => {
138
- resolve(result);
139
- },
140
- (err) => {
141
- getData().then((data) => {
142
- FNR.cache.setData('groups', data);
143
-
144
- resolve(data);
145
- });
146
- }
147
- );
148
- });
149
- };
150
-
151
- return readGroupsCache();
152
- },
153
- getAffiliates: () => {
154
- return new Promise((resolve, reject) => {
155
- const tops = forumConfig.affiliatesMax;
156
-
157
- const data = Object.entries(forumAffiliates).map((item) => {
158
- let final = '';
159
-
160
- item[1].forEach((item) => {
161
- final += '<li><a href="' + item.url + '" title="' + item.title + '" target="_blank"><img src="' + item.img + '" alt="' + item.title + '"/></a></li>';
162
- });
163
-
164
- for (let i = 0; i < (tops[item[0]] - item[1].length); i++) {
165
- final += '<li><a href="/" title="' + forumData.name + '"><img src="' + forumDefaults.affiliates[item[0]] + '" alt="' + forumData.name + '"/></a></li>';
166
- }
167
-
168
- return final;
169
- });
170
-
171
- resolve({
172
- normal: data[0],
173
- elite: data[1],
174
- directory: data[2],
175
- sister: data[3],
176
- });
177
- });
178
- },
179
- },
180
- content: {
181
- isAutosave: () => {
182
- if (document.post === undefined) return false;
183
- else return _userdata.user_id !== -1 && document.post.mode.value === 'reply' && document.post.t !== undefined
184
- },
185
- getPost: (url) => {
186
- return new Promise((resolve, reject) => {
187
- $.get(Vue.filter('url-to-invision')(url), (data) => {
188
- const post = $(data).find("#p" + url.split("#")[1]);
189
-
190
- resolve({
191
- author: {
192
- text: post.find(".author a").text(),
193
- color: post.find(".author a span").css("color"),
194
- url: Vue.filter('url-to-normal')(post.find(".author a").attr("href")),
195
- },
196
- content: post.find(".post-entry > div").html(),
197
- date: post.find(".author").html().split("</a>")[1],
198
- });
199
- });
200
- });
201
- },
202
- genPost: (id, content) => {
203
- return new Promise((resolve, reject) => {
204
- let save = document.createElement('iframe');
205
-
206
- save.id = 'forum-save';
207
- save.src = '/post?t=' + id + '&mode=reply&change_version=invision';
208
- save.width = 0;
209
- save.height = 0;
210
- save.onload = () => {
211
- saveDOM.onload = () => {
212
- $('#forum-save').remove();
213
-
214
- console.clear();
215
-
216
- resolve(true);
217
- };
218
-
219
- $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
220
- $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
221
- };
222
-
223
- document.querySelector('body > header').prepend(save);
224
-
225
- const saveDOM = document.getElementById('forum-save');
226
- });
227
- },
228
- genTopic: (id, name, content) => {
229
- return new Promise((resolve, reject) => {
230
- let save = document.createElement('iframe');
231
-
232
- save.id = 'forum-save';
233
- save.src = '/post?f=' + id + '&mode=newtopic&change_version=invision';
234
- save.width = 0;
235
- save.height = 0;
236
- save.onload = () => {
237
- saveDOM.onload = () => {
238
- $('#forum-save').remove();
239
-
240
- console.clear();
241
-
242
- resolve(true);
243
- };
244
-
245
- $('#forum-save').contents().find('dl dt:contains("Título del tema")').parent().find('input').val(name);
246
- $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
247
- $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
248
- };
249
-
250
- document.querySelector('body > header').prepend(save);
251
-
252
- const saveDOM = document.getElementById('forum-save');
253
- });
254
- }
255
- },
256
- user: {
257
- getUrl: (name) => {
258
- let character =
259
- name !== undefined ? encodeURIComponent(name)
260
- .replace(/[!'()]/g, escape)
261
- .replace(/\*/g, "%2A") :
262
- _userdata.user_id;
263
-
264
- return "/profile?mode=viewprofile&u=" + character;
265
- },
266
- getLevel: () => {
267
- return new Promise((resolve, reject) => {
268
- switch (_userdata.user_level) {
269
- case 2:
270
- resolve('mod');
271
- case 1:
272
- resolve('admin');
273
- case 0:
274
- return -1 == _userdata.user_id ? resolve('guest') : resolve('user');
275
- }
276
- });
277
- },
278
- getGroup: () => {
279
- return new Promise((resolve, reject) => {
280
- FNR.user.getLevel().then((status) => {
281
- if (status === 'guest') {
282
- resolve('unknown');
283
- } else {
284
- FNR.user.getProfile(_userdata.user_id, .25).then((data) => {
285
- resolve(data['colour']);
286
- });
287
- }
288
- });
289
- });
290
- },
291
- getProfile: (name, time) => {
292
- const character = name != undefined ? FNR.user.getUrl(name) : FNR.user.getUrl();
293
- const cache = time || 5;
294
-
295
- const processData = (content) => {
296
- if (content.find('a').length) return Vue.filter('url-to-normal')(content.find('a').attr('href'));
297
- else if (content.find('table').length) return content.find('table').html();
298
- else if (content.find('img').length) return content.find('img').attr('src');
299
- else if (content.find('textarea').length) return content.find('textarea').val();
300
- else if (content.find('span').length) return content.find('span').text().trim();
301
- else if (content.text().trim() === '-') return '';
302
- else return content.text();
303
- };
304
-
305
- const getData = () => {
306
- return new Promise((resolve, reject) => {
307
- $.get(character + '&change_version=invision', (data) => {
308
- let user = {};
309
-
310
- user['name'] = $(data).find('.maintitle h1 span').text();
311
- user['lastvisit'] = $(data).find('dt:contains("Última visita")').parent().find('dd').text();
312
- user['colour'] = FNR.utility.getGroup($(data).find('.maintitle h1 span').css('color').replace('rgb(', 'rgb_').replace(/, /g, '_').replace(')', ''));
313
- user['avatar'] = $(data).find('.real_avatar img').attr('src');
314
-
315
- user['links'] = {
316
- profile: '/u' + character.split('&u=')[1],
317
- mp: '/privmsg?mode=post&u=' + character.split('&u=')[1],
318
- };
319
-
320
- user['messages'] = {
321
- public: parseInt($(data).find('span:contains("Mensajes")').parent().parent().find('dd > div').text()) || 0,
322
- private: parseInt($(data).find('dt:contains("Mensajes privados")').parent().find('dd').text()) || 0
323
- };
324
-
325
- user['fields'] = {};
326
-
327
- $(data).find('dl[id^="field_id"]').each(function() {
328
- if ($(this).find('dt span').text() !== '') {
329
- if ($(this).find('dt span').text() === 'Mensajes') return;
330
-
331
- user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
332
- name: $(this).find('dt span').text(),
333
- content: processData($(this).find('dd .field_uneditable'))
334
- }
335
- }
336
- });
337
-
338
- $(data).find('.ipbform2 > dl').each(function() {
339
- if ($(this).find('dt span').length && $(this).find('dt span').text() !== '') {
340
- if ($(this).find('dt span').text() === 'Mensajes') return;
341
-
342
- user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
343
- name: $(this).find('dt span').text(),
344
- content: processData($(this).find('dd'))
345
- }
346
- }
347
- });
348
-
349
- user.fields['rango'] = {
350
- name: 'Rango',
351
- content: $(data).find('dt:contains("Rango:")').parent().find('dd').text()
352
- }
353
-
354
- resolve(user);
355
- });
356
- });
357
- };
358
-
359
- const readUserCache = (dat) => {
360
- const id = "userInfo" + dat;
361
-
362
- return new Promise((resolve, reject) => {
363
- FNR.cache.useData(id, cache).then(
364
- (result) => {
365
- resolve(result);
366
- },
367
- (err) => {
368
- getData().then((data) => {
369
- FNR.cache.setData(id, data);
370
-
371
- resolve(data);
372
- });
373
- }
374
- );
375
- });
376
- };
377
-
378
- return readUserCache(name);
379
- },
380
- changeAccount: (out, username, password) => {
381
- return new Promise((resolve, reject) => {
382
- let save = document.createElement('iframe');
383
-
384
- save.id = 'forum-save';
385
- save.src = out;
386
- save.width = 0;
387
- save.height = 0;
388
- save.onload = () => {
389
- save.onload = () => {
390
- save.onload = () => {
391
- console.clear();
392
-
393
- resolve(true);
394
- };
395
-
396
- $('#forum-save').contents().find('input[name="username"]').val(username);
397
- $('#forum-save').contents().find('input[name="password"]').val(password);
398
- $('#forum-save').contents().find('input[type="submit"][name="login"]').click();
399
- };
400
-
401
- saveDOM.src = '/login?change_version=invision';
402
- };
403
-
404
- document.querySelector('body > header').prepend(save);
405
-
406
- const saveDOM = document.getElementById('forum-save');
407
- });
408
- },
409
- profile: {
410
- getData: (array) => {
411
- return new Promise((resolve, reject) => {
412
- $.get('/profile?change_version=invision&mode=editprofile', (data) => {
413
- const fields = data;
414
-
415
- $.get('/profile?change_version=invision&mode=editprofile&page_profil=avatars', (data) => {
416
- const avatar = data;
417
-
418
- let result = [];
419
-
420
- [].forEach.call(array, (item) => {
421
- let value = '',
422
- options = [];
423
-
424
- switch (item.type) {
425
- case 'input':
426
- value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('input').val();
427
- break;
428
-
429
- case 'textarea':
430
- value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('textarea').val();
431
- break;
432
-
433
- case 'select':
434
- value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option:selected').attr('value');
435
-
436
- $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option').each(function() {
437
- if ($(this).attr('value') === '') return;
438
-
439
- options.push({
440
- name: $(this).text(),
441
- value: $(this).attr('value')
442
- });
443
- });
444
- break;
445
-
446
- case 'avatar':
447
- value = $(avatar).find('.box-content img').attr('src');
448
- break;
449
- }
450
-
451
- if (item.type === 'select' && value === undefined || item.type === 'select' && value === '') return;
452
-
453
- let final = {
454
- type: item.type,
455
- name: item.name,
456
- value: value
457
- };
458
-
459
- if (item.validation) {
460
- final.validation = item.validation;
461
- }
462
-
463
- if (options.length) {
464
- final.options = options;
465
- }
466
-
467
- result.push(final);
468
- });
469
-
470
- resolve(result);
471
- });
472
- });
473
- });
474
- },
475
- setData: (array) => {
476
- return new Promise((resolve, reject) => {
477
- const resolveSetter = () => {
478
- $('#forum-save').remove();
479
-
480
- console.clear();
481
-
482
- resolve(true);
483
- };
484
-
485
- let save = document.createElement('iframe');
486
-
487
- save.id = 'forum-save';
488
- save.src = '/profile?change_version=invision&mode=editprofile';
489
- save.width = 0;
490
- save.height = 0;
491
- save.onload = () => {
492
- let avatar = false;
493
-
494
- [].forEach.call(array, (item) => {
495
- switch (item.type) {
496
- case 'input':
497
- $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('input').first().val(item.value);
498
- break;
499
-
500
- case 'textarea':
501
- $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('textarea').val(item.value);
502
- break;
503
-
504
- case 'select':
505
- $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('select option[value="' + item.value + '"]').attr('selected', 'selected');
506
- break;
507
-
508
- case 'avatar':
509
- avatar = item.value;
510
- break;
511
- }
512
- });
513
-
514
- saveDOM.onload = () => {
515
- if (!avatar) {
516
- resolveSetter();
517
- } else {
518
- saveDOM.onload = () => {
519
- saveDOM.onload = () => {
520
- resolveSetter();
521
- }
522
-
523
- $('#forum-save').contents().find('input[name="avatarremoteurl"]').val(avatar);
524
- $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
525
- }
526
-
527
- saveDOM.src = '/profile?change_version=invision&mode=editprofile&page_profil=avatars';
528
- }
529
- };
530
-
531
- $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
532
- };
533
-
534
- document.querySelector('body > header').prepend(save);
535
-
536
- const saveDOM = document.getElementById('forum-save');
537
- });
538
- },
539
- getDrafts: () => {
540
- return new Promise((resolve, reject) => {
541
- $.get('/search?search_id=draftsearch&change_version=invision', (data) => {
542
- if (parseFloat($(data).find('.maintitle > h3').text()) !== 0) {
543
- let final = [];
544
-
545
- $(data).find('.ipbform .ipbtable tbody > tr').each(function() {
546
- const cells = $(this).find('td');
547
-
548
- final.push({
549
- topic: {
550
- name: cells[1].textContent.trim(),
551
- url: Vue.filter('url-to-normal')(cells[1].querySelector('a').href)
552
- },
553
- info: {
554
- location: cells[2].textContent.trim(),
555
- date: cells[3].textContent.trim()
556
- },
557
- modify: Vue.filter('url-to-normal')(cells[4].querySelector('a').href)
558
- });
559
- });
560
-
561
- resolve(final);
562
- } else {
563
- resolve(false);
564
- }
565
- });
566
- });
567
- }
568
- }
569
- },
570
- cache: {
571
- getData: (id) => {
572
- if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
573
- else return JSON.parse(localStorage.getItem(forumData.prefix + '_' + id)).content;
574
- },
575
- setData: (id, data, time) => {
576
- let cur_date = time === -1 ? 'undefined' : new Date().getTime();
577
-
578
- localStorage.setItem(
579
- forumData.prefix + '_' + id,
580
- JSON.stringify({
581
- cached_at: cur_date,
582
- content: data,
583
- })
584
- );
585
- },
586
- delData: (id) => {
587
- if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
588
- else return localStorage.removeItem(forumData.prefix + '_' + id);
589
- },
590
- useData: (id, time) => {
591
- return new Promise((resolve, reject) => {
592
- let item = localStorage.getItem(forumData.prefix + '_' + id),
593
- cur_date = new Date(),
594
- timeMil = time == -1 ? 'undefined' : time * 86400000;
595
-
596
- if ((item != null && time == -1) || (item != null && parseInt(JSON.parse(item).cached_at) + timeMil > cur_date.getTime())) {
597
- resolve(JSON.parse(item).content);
598
- } else {
599
- reject(false);
600
- }
601
- });
602
- },
603
- },
604
- utility: {
605
- genSlug: (text, alt) => {
606
- const slug = (Q) => {
607
- const R = '\xE0\xE1\xE4\xE2\xE8\xE9\xEB\xEA\xEC\xED\xEF\xEE\xF2\xF3\xF6\xF4\xF9\xFA\xFC\xFB\xF1\xE7\xB7/_,:;';
608
- Q = Q.trim().toLowerCase();
609
- for (var T = 0, U = R.length; T < U; T++) Q = Q.replace(new RegExp(R.charAt(T), 'g'), 'aaaaeeeeiiiioooouuuunc------'.charAt(T));
610
- return Q.replace(/[^a-z0-9 -]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-');
611
- };
612
-
613
- const replace = alt || '_';
614
-
615
- return slug(text).replace(/-/g, replace);
616
- },
617
- genArray: (string) => {
618
- return JSON.parse(string.replace(/`/g, '"'));
619
- },
620
- genValidation: (array) => {
621
- let final = '';
622
-
623
- [].forEach.call(array, (item) => {
624
- switch (item.validation) {
625
- case 'hex':
626
- if (!item.value.match(/^#[a-f0-9]{6}$/i)) {
627
- final += '<li>El campo de ' + item.name.toLowerCase() + ' debe incluir un código de color hexadecimal.</li>';
628
- }
629
- break;
630
-
631
- case 'img':
632
- if (!item.value.match(/(jpg|jpeg|png)$/i)) {
633
- final += '<li>El campo de ' + item.name.toLowerCase() + ' debe ser el enlace a una imagen (formato png, jpg o jpeg).</li>';
634
- }
635
- break;
636
- }
637
- });
638
-
639
- return final;
640
- },
641
- getGroup: (color) => {
642
- const returnHexVer = (code) => {
643
- let status = 'unknown';
644
-
645
- Object.values(forumColours).map((item) => {
646
- if (item.hex === code.toLowerCase()) status = FNR.utility.genSlug(item.code);
647
- });
648
-
649
- return status;
650
- };
651
-
652
- const returnIdVer = (code) => {
653
- let status = 'unknown';
654
-
655
- Object.values(forumColours).map((item) => {
656
- if (item.id === code) status = FNR.utility.genSlug(item.code);
657
- });
658
-
659
- return status;
660
- };
661
-
662
- if (color === undefined) return 'unknown';
663
- else if (color.indexOf('#') > -1) return returnHexVer(color);
664
- else if (color.indexOf('id_') > -1) return returnIdVer(parseFloat(color.split('_')[1]));
665
- else if (forumColours[color] === undefined) return 'unknown';
666
- else return FNR.utility.genSlug(forumColours[color].code);
667
- }
668
- },
669
- html: {
670
- genModal: (title, content, buttons) => {
671
- if (title === '' || title === undefined || title === null) return;
672
- if (content === '' || content === undefined || content === null) return;
673
-
674
- let modal = document.createElement('div');
675
-
676
- modal.id = 'forum-modal';
677
-
678
- document.body.appendChild(modal);
679
-
680
- let final = '';
681
-
682
- final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="modal-element">';
683
- final += '<div class="modal-title">';
684
- final += '<h3>' + title + '</h3>';
685
- final += '<a onclick="document.getElementById(`forum-modal`).remove()">';
686
- final += '<i class="fas fa-times"></i>';
687
- final += '</a>';
688
- final += '</div>';
689
- final += '<div class="modal-content">';
690
- final += '<div class="is-content">';
691
- final += content.replace(/\n/g, '<br>');
692
- final += '</div>';
693
-
694
- if (buttons !== '' && buttons !== undefined && buttons !== null) {
695
- final += '<div class="modal-buttons">';
696
- final += buttons;
697
- final += '</div>';
698
- }
699
-
700
- final += '</div>';
701
- final += '</div>';
702
-
703
- final += '<div class="is-bgmodal bg-active" onclick="document.getElementById(`forum-modal`).remove()"></div>';
704
-
705
- document.getElementById('forum-modal').innerHTML = final;
706
- },
707
- genPrompt: (title, content, placeholder, text) => {
708
- if (title === '' || title === undefined || title === null) return;
709
- if (content === '' || content === undefined || content === null) return;
710
-
711
- return new Promise((resolve, reject) => {
712
- FNR.html.genModal(title, '<p>' + content + '</p><p><input id="modal-prompt" type="text" placeholder="' + placeholder + '" value="' + text + '"></p>', '<button id="modal-button-enter" class="button1 btn-main">Confirmar</button><button id="modal-button-cancel" class="button1">Cancelar</button>');
713
-
714
- document.querySelector('#modal-button-enter').onclick = () => {
715
- const result = document.querySelector('#modal-prompt').value;
716
-
717
- if (result === '') {
718
- resolve(false);
719
- } else {
720
- resolve(result);
721
- }
722
-
723
- document.getElementById(`forum-modal`).remove();
724
- };
725
-
726
- document.querySelector('#modal-button-cancel').onclick = () => {
727
- reject(false);
728
- document.getElementById(`forum-modal`).remove();
729
- };
730
-
731
- document.querySelector('.modal-title a').onclick = () => {
732
- reject(false);
733
- document.getElementById(`forum-modal`).remove();
734
- };
735
-
736
- document.querySelector('.is-bgmodal.bg-active').onclick = () => {
737
- reject(false);
738
- document.getElementById(`forum-modal`).remove();
739
- };
740
- });
741
- },
742
- genNotification: (title, content, icon, url) => {
743
- if (title === '' || title === undefined || title === null) return;
744
- if (content === '' || content === undefined || content === null) return;
745
- if (content.length > 50) return;
746
- if (icon === '' || icon === undefined || icon === null) return;
747
-
748
- if (document.querySelectorAll('forum-notification').length) {
749
- document.getElementById('forum-notification').remove();
750
- clearTimeout();
751
- }
752
-
753
- let notification = document.createElement('div');
754
-
755
- notification.id = 'forum-notification';
756
-
757
- document.body.appendChild(notification);
758
-
759
- let final = '';
760
-
761
- if (url === '' || url === undefined || url === null) {
762
- final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
763
- } else {
764
- final += '<a href="' + url + '" target="_blank" id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
765
- }
766
-
767
- final += '<div class="notification-icon">';
768
- final += '<i class="' + icon + '"></i>';
769
- final += '</div>';
770
- final += '<div class="notification-content">';
771
- final += '<h3>' + title + '</h3>';
772
- final += '<p>' + content + '</p>';
773
- final += '</div>';
774
- final += '<div class="notification-controls">';
775
- final += '<i class="fas fa-times"></i>';
776
- final += '</div>';
777
-
778
- if (url === '' || url === undefined || url === null) {
779
- final += '</div>';
780
- } else {
781
- final += '</a>';
782
- }
783
-
784
- document.getElementById('forum-notification').innerHTML = final;
785
-
786
- setTimeout(() => {
787
- document.getElementById(`forum-notification`).classList.add('notification-show');
788
- }, 500);
789
-
790
- setTimeout(() => {
791
- document.getElementById(`forum-notification`).classList.remove('notification-show');
792
- }, 8000);
793
-
794
- setTimeout(() => {
795
- document.getElementById(`forum-notification`).remove();
796
- }, 10000);
797
- }
798
- },
799
- behaviour: {
800
- genWiki: () => {
801
- if (document.querySelector('.wiki-cascade')) {
802
- [].forEach.call(document.getElementsByClassName('wiki-cascade'), (item) => {
803
- item.onclick = () => {
804
- const element = item.parentElement.parentElement;
805
-
806
- if (element.classList.contains('is-active')) {
807
- element.classList.remove('is-active');
808
- } else {
809
- element.classList.add('is-active');
810
- }
811
- };
812
- });
813
- }
814
-
815
- if (document.querySelector('.wiki-controls .router-link-active')) {
816
- [].forEach.call(document.querySelectorAll('.wiki-controls .router-link-active'), (item) => {
817
- if (!item.parentElement.parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
818
- const setActive = (element, isFirst) => {
819
- let parentElement = element.parentElement.parentElement;
820
-
821
- if (isFirst) {
822
- parentElement = parentElement.parentElement.parentElement;
823
- }
824
-
825
- parentElement.classList.add('is-active');
826
- parentElement.classList.add('is-selected');
827
-
828
- if (!parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
829
- setActive(parentElement, false);
830
- }
831
- };
832
-
833
- setActive(item, true);
834
- }
835
- });
836
- }
837
-
838
- if (document.querySelector('aside.wiki-index > .select-container > select')) {
839
- document.querySelector('aside.wiki-index > .select-container > select').onchange = () => {
840
- router.push(document.querySelector('aside.wiki-index > .select-container > select').value);
841
- };
842
- }
843
- },
844
- genDropeable: () => {
845
- if (document.querySelector('.is-dropeable')) {
846
- [].forEach.call(document.getElementsByClassName('is-dropeable'), (item) => {
847
- item.onclick = () => {
848
- if (!item.classList.contains('is-active')) {
849
- [].forEach.call(document.getElementsByClassName('is-dropeable'), (drops) => {
850
- drops.classList.remove('is-active');
851
- });
852
-
853
- item.classList.add('is-active');
854
- } else {
855
- item.classList.remove('is-active');
856
- }
857
- };
858
- });
859
- }
860
- }
861
- }
2
+ execFn: (callback) => {
3
+ document.addEventListener('forumReady', callback, false);
4
+ },
5
+ forum: {
6
+ getColors: () => {
7
+ return Object.values(forumColours)
8
+ .map((item) => {
9
+ return {
10
+ name: item.code,
11
+ hex: item.hex
12
+ }
13
+ });
14
+ },
15
+ getTopics: async (exclusions, limit) => {
16
+ const addContent = (elmt) => {
17
+ const titleElmnt = $(elmt).find('.topictitle');
18
+ const dateElmnt = $(elmt).children().last();
19
+
20
+ finalArray.push({
21
+ name: titleElmnt.text().trim(),
22
+ url: Vue.filter('url-to-normal')(titleElmnt.attr('href')),
23
+ lastpost: {
24
+ url: Vue.filter('url-to-normal')(dateElmnt.children().last().attr('href')),
25
+ date: dateElmnt.text().split('por')[0].trim(),
26
+ who: {
27
+ name: dateElmnt.find('strong a').length ? dateElmnt.find('strong a').text().trim() : 'Invitado',
28
+ url: Vue.filter('url-to-normal')(dateElmnt.find('strong a').length ? dateElmnt.find('strong a').attr('href') : '/'),
29
+ color: dateElmnt.find('strong a').length ? dateElmnt.find('strong a span').attr('style').split('color:')[1] : 'initial',
30
+ },
31
+ },
32
+ forum: {
33
+ name: $(elmt).find('.row2 + .row2:not(.centered) a').text().trim(),
34
+ url: Vue.filter('url-to-normal')($(elmt).find('.row2 + .row2:not(.centered) a').attr('href')),
35
+ },
36
+ });
37
+ };
38
+
39
+ const getPage = async (url) => {
40
+ $.get(url, (data) => {
41
+ $(data).find('.ipbform').find('tbody').find('tr').each(function() {
42
+ if (finalArray.length < limit && exclusions.indexOf(parseInt($(this).find('.row2 + .row2:not(.centered) a').attr('href').split('/f')[1].split('-')[0])) === -1) {
43
+ addContent(this);
44
+ }
45
+ });
46
+
47
+ if (finalArray.length === limit || !$(data).find('.pagination')[0].children.length || $(data).find('.pagination').children().last()[0].localName === 'b') {
48
+ return finalArray;
49
+ } else {
50
+ return getPage($(data).find('.pagination').children().last().attr('href'));
51
+ }
52
+ });
53
+ };
54
+
55
+ await getPage('/latest?change_version=invision');
56
+
57
+ let finalArray = [];
58
+
59
+ return finalArray;
60
+ },
61
+ getMembers: (option) => {
62
+ return new Promise((resolve, reject) => {
63
+ let members = [];
64
+
65
+ const getUserData = (user, color) => {
66
+ return {
67
+ user: $(user).find('.membername span').text().trim(),
68
+ id: $(user).find('.popupmenu .popupmenu-item a').attr('href').split('?')[0],
69
+ img: $(user).find('.mini-avatar img').attr('src'),
70
+ color: color
71
+ };
72
+ };
73
+
74
+ const getUsersPage = (page) => {
75
+ let users = [];
76
+
77
+ $(page).find('.member-list .member').each(function() {
78
+ const group = FNR.utility.getGroup($(this).find('.membername span').attr('style').split('color:')[1]);
79
+
80
+ if (option) {
81
+ users.push(getUserData(this, group));
82
+ } else {
83
+ if (group !== 'unknown' && group !== forumConfig.skinOptions.adminGroup) {
84
+ users.push(getUserData(this, group));
85
+ }
86
+ }
87
+ });
88
+
89
+ return users;
90
+ };
91
+
92
+ const getPage = (url) => {
93
+ $.get(url, (data) => {
94
+ const nextURL = $(data).find('.pagination img[alt="Siguiente"]').parent().attr('href') || false;
95
+
96
+ members = members.concat(getUsersPage(data));
97
+
98
+ if (nextURL) {
99
+ getPage(nextURL);
100
+ } else {
101
+ resolve(members.sort((a, b) => {
102
+ if (a.user < b.user) return -1;
103
+ if (a.user > b.user) return 1;
104
+ return 0;
105
+ }));
106
+ }
107
+ });
108
+ };
109
+
110
+ getPage('/memberlist?change_version=invision');
111
+ });
112
+ },
113
+ getGroups: (cache) => {
114
+ const getData = () => {
115
+ return new Promise((resolve, reject) => {
116
+ $.get('/groups?change_version=invision', (data) => {
117
+ let groups = [];
118
+
119
+ $(data).find('.group_list > li').each(function() {
120
+ groups.push({
121
+ id: parseInt($(this).find('a').attr('href').split('/g')[1].split('-')[0]),
122
+ name: $(this).find('a').text().trim(),
123
+ color: $(this).find('a').css('color'),
124
+ url: Vue.filter('url-to-normal')($(this).find('a').attr('href')),
125
+ count: parseInt($(this).find('div > span').text()) - 1
126
+ });
127
+ });
128
+
129
+ resolve(groups);
130
+ });
131
+ });
132
+ };
133
+
134
+ const readGroupsCache = () => {
135
+ return new Promise((resolve, reject) => {
136
+ FNR.cache.useData('groups', cache).then(
137
+ (result) => {
138
+ resolve(result);
139
+ },
140
+ (err) => {
141
+ getData().then((data) => {
142
+ FNR.cache.setData('groups', data);
143
+
144
+ resolve(data);
145
+ });
146
+ }
147
+ );
148
+ });
149
+ };
150
+
151
+ return readGroupsCache();
152
+ },
153
+ getAffiliates: () => {
154
+ return new Promise((resolve, reject) => {
155
+ const tops = forumConfig.affiliatesMax;
156
+
157
+ const data = Object.entries(forumAffiliates).map((item) => {
158
+ let final = '';
159
+
160
+ item[1].forEach((item) => {
161
+ final += '<li><a href="' + item.url + '" title="' + item.title + '" target="_blank"><img src="' + item.img + '" alt="' + item.title + '"/></a></li>';
162
+ });
163
+
164
+ for (let i = 0; i < (tops[item[0]] - item[1].length); i++) {
165
+ final += '<li><a href="/" title="' + forumData.name + '"><img src="' + forumDefaults.affiliates[item[0]] + '" alt="' + forumData.name + '"/></a></li>';
166
+ }
167
+
168
+ return final;
169
+ });
170
+
171
+ resolve({
172
+ normal: data[0],
173
+ elite: data[1],
174
+ directory: data[2],
175
+ sister: data[3],
176
+ });
177
+ });
178
+ },
179
+ },
180
+ content: {
181
+ isAutosave: () => {
182
+ if (document.post === undefined) return false;
183
+ else return _userdata.user_id !== -1 && document.post.mode.value === 'reply' && document.post.t !== undefined
184
+ },
185
+ getPost: (url) => {
186
+ return new Promise((resolve, reject) => {
187
+ $.get(Vue.filter('url-to-invision')(url), (data) => {
188
+ const post = $(data).find("#p" + url.split("#")[1]);
189
+
190
+ resolve({
191
+ author: {
192
+ text: post.find(".author a").text(),
193
+ color: post.find(".author a span").css("color"),
194
+ url: Vue.filter('url-to-normal')(post.find(".author a").attr("href")),
195
+ },
196
+ content: post.find(".post-entry > div").html(),
197
+ date: post.find(".author").html().split("</a>")[1],
198
+ });
199
+ });
200
+ });
201
+ },
202
+ genPost: (id, content) => {
203
+ return new Promise((resolve, reject) => {
204
+ let save = document.createElement('iframe');
205
+
206
+ save.id = 'forum-save';
207
+ save.src = '/post?t=' + id + '&mode=reply&change_version=invision';
208
+ save.width = 0;
209
+ save.height = 0;
210
+ save.onload = () => {
211
+ saveDOM.onload = () => {
212
+ $('#forum-save').remove();
213
+
214
+ console.clear();
215
+
216
+ resolve(true);
217
+ };
218
+
219
+ $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
220
+ $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
221
+ };
222
+
223
+ document.querySelector('body > header').prepend(save);
224
+
225
+ const saveDOM = document.getElementById('forum-save');
226
+ });
227
+ },
228
+ genTopic: (id, name, content) => {
229
+ return new Promise((resolve, reject) => {
230
+ let save = document.createElement('iframe');
231
+
232
+ save.id = 'forum-save';
233
+ save.src = '/post?f=' + id + '&mode=newtopic&change_version=invision';
234
+ save.width = 0;
235
+ save.height = 0;
236
+ save.onload = () => {
237
+ saveDOM.onload = () => {
238
+ $('#forum-save').remove();
239
+
240
+ console.clear();
241
+
242
+ resolve(true);
243
+ };
244
+
245
+ $('#forum-save').contents().find('dl dt:contains("Título del tema")').parent().find('input').val(name);
246
+ $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
247
+ $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
248
+ };
249
+
250
+ document.querySelector('body > header').prepend(save);
251
+
252
+ const saveDOM = document.getElementById('forum-save');
253
+ });
254
+ }
255
+ },
256
+ user: {
257
+ getUrl: (name) => {
258
+ let character =
259
+ name !== undefined ? encodeURIComponent(name)
260
+ .replace(/[!'()]/g, escape)
261
+ .replace(/\*/g, "%2A") :
262
+ _userdata.user_id;
263
+
264
+ return "/profile?mode=viewprofile&u=" + character;
265
+ },
266
+ getLevel: async () => {
267
+ switch (_userdata.user_level) {
268
+ case 2:
269
+ return 'mod';
270
+ case 1:
271
+ return 'admin';
272
+ case 0:
273
+ return -1 == _userdata.user_id ? 'guest' : 'user';
274
+ }
275
+ },
276
+ getGroup: async () => {
277
+ const level = await FNR.user.getLevel();
278
+
279
+ if (level === 'guest') {
280
+ return 'unknown';
281
+ }
282
+
283
+ const { colour } = await FNR.user.getProfile(_userdata.user_id, .25);
284
+
285
+ return colour;
286
+ },
287
+ getProfile: (name, time) => {
288
+ const character = name != undefined ? FNR.user.getUrl(name) : FNR.user.getUrl();
289
+ const cache = time || 5;
290
+
291
+ const processData = (content) => {
292
+ if (content.find('a').length) return Vue.filter('url-to-normal')(content.find('a').attr('href'));
293
+ else if (content.find('table').length) return content.find('table').html();
294
+ else if (content.find('img').length) return content.find('img').attr('src');
295
+ else if (content.find('textarea').length) return content.find('textarea').val();
296
+ else if (content.find('span').length) return content.find('span').text().trim();
297
+ else if (content.text().trim() === '-') return '';
298
+ else return content.text();
299
+ };
300
+
301
+ const getData = () => {
302
+ return new Promise((resolve, reject) => {
303
+ $.get(character + '&change_version=invision', (data) => {
304
+ let user = {};
305
+
306
+ user['name'] = $(data).find('.maintitle h1 span').text();
307
+ user['lastvisit'] = $(data).find('dt:contains("Última visita")').parent().find('dd').text();
308
+ user['colour'] = FNR.utility.getGroup($(data).find('.maintitle h1 span').css('color').replace('rgb(', 'rgb_').replace(/, /g, '_').replace(')', ''));
309
+ user['avatar'] = $(data).find('.real_avatar img').attr('src');
310
+
311
+ user['links'] = {
312
+ profile: '/u' + character.split('&u=')[1],
313
+ mp: '/privmsg?mode=post&u=' + character.split('&u=')[1],
314
+ };
315
+
316
+ user['messages'] = {
317
+ public: parseInt($(data).find('span:contains("Mensajes")').parent().parent().find('dd > div').text()) || 0,
318
+ private: parseInt($(data).find('dt:contains("Mensajes privados")').parent().find('dd').text()) || 0
319
+ };
320
+
321
+ user['fields'] = {};
322
+
323
+ $(data).find('dl[id^="field_id"]').each(function() {
324
+ if ($(this).find('dt span').text() !== '') {
325
+ if ($(this).find('dt span').text() === 'Mensajes') return;
326
+
327
+ user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
328
+ name: $(this).find('dt span').text(),
329
+ content: processData($(this).find('dd .field_uneditable'))
330
+ }
331
+ }
332
+ });
333
+
334
+ $(data).find('.ipbform2 > dl').each(function() {
335
+ if ($(this).find('dt span').length && $(this).find('dt span').text() !== '') {
336
+ if ($(this).find('dt span').text() === 'Mensajes') return;
337
+
338
+ user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
339
+ name: $(this).find('dt span').text(),
340
+ content: processData($(this).find('dd'))
341
+ }
342
+ }
343
+ });
344
+
345
+ user.fields['rango'] = {
346
+ name: 'Rango',
347
+ content: $(data).find('dt:contains("Rango:")').parent().find('dd').text()
348
+ }
349
+
350
+ resolve(user);
351
+ });
352
+ });
353
+ };
354
+
355
+ const readUserCache = (id) => {
356
+ const userId = `userInfo${id}`;
357
+
358
+ return new Promise((resolve, reject) => {
359
+ FNR.cache.useData(userId, cache).then(
360
+ (result) => {
361
+ resolve(result);
362
+ },
363
+ (err) => {
364
+ getData().then((data) => {
365
+ FNR.cache.setData(userId, data);
366
+
367
+ resolve(data);
368
+ });
369
+ }
370
+ );
371
+ });
372
+ };
373
+
374
+ return readUserCache(name);
375
+ },
376
+ changeAccount: async (out, username, password) => {
377
+ try {
378
+ await fetch(out);
379
+ await fetch('/login', {
380
+ method: 'POST',
381
+ headers: {
382
+ 'Content-Type': 'application/x-www-form-urlencoded',
383
+ },
384
+ body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&autologin=1&login=1`
385
+ })
386
+
387
+ return true;
388
+ } catch (error) {
389
+ console.error('Error inesperado', error);
390
+ return false;
391
+ }
392
+ },
393
+ profile: {
394
+ getData: (array) => {
395
+ return new Promise((resolve, reject) => {
396
+ $.get('/profile?change_version=invision&mode=editprofile', (data) => {
397
+ const fields = data;
398
+
399
+ $.get('/profile?change_version=invision&mode=editprofile&page_profil=avatars', (data) => {
400
+ const avatar = data;
401
+
402
+ let result = [];
403
+
404
+ [].forEach.call(array, (item) => {
405
+ let value = '',
406
+ options = [];
407
+
408
+ switch (item.type) {
409
+ case 'input':
410
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('input').val();
411
+ break;
412
+
413
+ case 'textarea':
414
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('textarea').val();
415
+ break;
416
+
417
+ case 'select':
418
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option:selected').attr('value');
419
+
420
+ $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option').each(function() {
421
+ if ($(this).attr('value') === '') return;
422
+
423
+ options.push({
424
+ name: $(this).text(),
425
+ value: $(this).attr('value')
426
+ });
427
+ });
428
+ break;
429
+
430
+ case 'avatar':
431
+ value = $(avatar).find('.box-content img').attr('src');
432
+ break;
433
+ }
434
+
435
+ if (item.type === 'select' && value === undefined || item.type === 'select' && value === '') return;
436
+
437
+ let final = {
438
+ type: item.type,
439
+ name: item.name,
440
+ value: value
441
+ };
442
+
443
+ if (item.validation) {
444
+ final.validation = item.validation;
445
+ }
446
+
447
+ if (options.length) {
448
+ final.options = options;
449
+ }
450
+
451
+ result.push(final);
452
+ });
453
+
454
+ resolve(result);
455
+ });
456
+ });
457
+ });
458
+ },
459
+ setData: (array) => {
460
+ return new Promise((resolve, reject) => {
461
+ const resolveSetter = () => {
462
+ $('#forum-save').remove();
463
+
464
+ console.clear();
465
+
466
+ resolve(true);
467
+ };
468
+
469
+ let save = document.createElement('iframe');
470
+
471
+ save.id = 'forum-save';
472
+ save.src = '/profile?change_version=invision&mode=editprofile';
473
+ save.width = 0;
474
+ save.height = 0;
475
+ save.onload = () => {
476
+ let avatar = false;
477
+
478
+ [].forEach.call(array, (item) => {
479
+ switch (item.type) {
480
+ case 'input':
481
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('input').first().val(item.value);
482
+ break;
483
+
484
+ case 'textarea':
485
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('textarea').val(item.value);
486
+ break;
487
+
488
+ case 'select':
489
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('select option[value="' + item.value + '"]').attr('selected', 'selected');
490
+ break;
491
+
492
+ case 'avatar':
493
+ avatar = item.value;
494
+ break;
495
+ }
496
+ });
497
+
498
+ saveDOM.onload = () => {
499
+ if (!avatar) {
500
+ resolveSetter();
501
+ } else {
502
+ saveDOM.onload = () => {
503
+ saveDOM.onload = () => {
504
+ resolveSetter();
505
+ }
506
+
507
+ $('#forum-save').contents().find('input[name="avatarremoteurl"]').val(avatar);
508
+ $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
509
+ }
510
+
511
+ saveDOM.src = '/profile?change_version=invision&mode=editprofile&page_profil=avatars';
512
+ }
513
+ };
514
+
515
+ $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
516
+ };
517
+
518
+ document.querySelector('body > header').prepend(save);
519
+
520
+ const saveDOM = document.getElementById('forum-save');
521
+ });
522
+ },
523
+ followed: {
524
+ getPages: async () => {
525
+ try {
526
+ const followedPage = await fetch('/search?search_id=watchsearch&change_version=invision');
527
+ const bodyFollowedPage = await followedPage.text();
528
+ const htmlFollowedPage = document.createElement('html');
529
+
530
+ htmlFollowedPage.innerHTML = bodyFollowedPage;
531
+
532
+ const totalPages = htmlFollowedPage.querySelectorAll('.pagination a');
533
+ const finalPage = totalPages[totalPages.length - 2];
534
+ const finalPageUrl = finalPage.href.split(finalPage.origin)[1];
535
+ const finalPageNumberArray = finalPageUrl.match(/[0-9]/g) || [];
536
+ const finalPageNumber = parseInt(finalPageNumberArray.join('')) || 0;
537
+
538
+ const firstPage = totalPages[1];
539
+ const firstPageUrl = firstPage.href.split(firstPage.origin)[1];
540
+ const firstPageNumberArray = firstPageUrl.match(/[0-9]/g) || [];
541
+ const firstPageNumber = parseInt(firstPageNumberArray.join('')) || 0;
542
+
543
+ const arrayPages = finalPageNumber / firstPageNumber || 0
544
+ const arrayItems = Array(arrayPages).fill(null);
545
+
546
+ return {
547
+ items: htmlFollowedPage.querySelectorAll('.ipbtable tbody tr').length,
548
+ pages: ['/search?search_id=watchsearch&change_version=invision', ...arrayItems.map((page, index) => `/search?search_id=watchsearch&start=${firstPageNumber * (index + 1)}&change_version=invision`)],
549
+ }
550
+ } catch (error) {
551
+ console.error('Error inesperado', error);
552
+ return false;
553
+ }
554
+ },
555
+ getFollowed: async (page) => {
556
+ try {
557
+ const followedPage = await fetch(page);
558
+ const bodyFollowedPage = await followedPage.text();
559
+ const htmlFollowedPage = document.createElement('html');
560
+
561
+ htmlFollowedPage.innerHTML = bodyFollowedPage;
562
+
563
+ return Array.from(htmlFollowedPage.querySelectorAll('.ipbtable tbody tr')).map(row => {
564
+ const cells = row.children;
565
+
566
+ return {
567
+ id: parseInt(cells[7].children[0].value),
568
+ name: cells[1].querySelector('a').textContent.trim(),
569
+ url: Vue.filter('url-to-normal')(cells[1].querySelector('a').href),
570
+ views: parseInt(cells[5].textContent),
571
+ replies: parseInt(cells[3].textContent),
572
+ }
573
+ });
574
+ } catch (error) {
575
+ console.error('Error inesperado', error);
576
+ return false;
577
+ }
578
+ },
579
+ delFollowed: async (topics) => {
580
+ try {
581
+ await fetch('/search?search_id=watchsearch', {
582
+ method: 'POST',
583
+ headers: {
584
+ 'Content-Type': 'application/x-www-form-urlencoded',
585
+ },
586
+ body: `confirm=confirm${topics.map(topic => `&mark${encodeURIComponent(`[]`)}2=${topic}`)}`
587
+ })
588
+
589
+ return true;
590
+ } catch (error) {
591
+ console.error('Error inesperado', error);
592
+ return false;
593
+ }
594
+ },
595
+ },
596
+ drafts: {
597
+ getDrafts: async () => {
598
+ const getPage = (content, baseIndex) => {
599
+ final = [];
600
+
601
+ if (content.querySelectorAll('.maintitle > h3').length && parseInt(content.querySelectorAll('.maintitle > h3')[0].textContent) !== 0) {
602
+ [].forEach.call(content.querySelectorAll('.ipbform .ipbtable tbody > tr'), (item) => {
603
+ const cells = item.querySelectorAll('td');
604
+
605
+ final.push({
606
+ topic: {
607
+ name: cells[baseIndex + 1].textContent.trim(),
608
+ url: Vue.filter('url-to-normal')(cells[baseIndex + 1].querySelector('a').href)
609
+ },
610
+ info: {
611
+ location: cells[baseIndex + 2].textContent.trim(),
612
+ date: cells[baseIndex + 3].textContent.trim()
613
+ },
614
+ modify: Vue.filter('url-to-normal')(cells[baseIndex + 4].querySelector('a').href)
615
+ });
616
+ });
617
+ }
618
+
619
+ return final;
620
+ };
621
+
622
+ try {
623
+ const msgDraft = await fetch('/search?search_id=draftsearch&change_version=invision');
624
+ const topicDraft = await fetch('/search?search_id=topicdraftsearch&change_version=invision');
625
+
626
+ const bodyMsgDraft = await msgDraft.text();
627
+ const bodyTopicDraft = await topicDraft.text();
628
+
629
+ const htmlMsgDraft = document.createElement('html');
630
+ const htmlTopicDraft = document.createElement('html');
631
+
632
+ htmlMsgDraft.innerHTML = bodyMsgDraft;
633
+ htmlTopicDraft.innerHTML = bodyTopicDraft;
634
+
635
+ return {
636
+ msgDrafts: getPage(htmlMsgDraft, 0),
637
+ topicDrafts: getPage(htmlTopicDraft, -1)
638
+ };
639
+ } catch (error) {
640
+ return false;
641
+ }
642
+ },
643
+ delDrafts: async (type, drafts) => {
644
+ try {
645
+ const deleteType = type === 'draft' ? 'draft' : 'topic_draft';
646
+
647
+ await fetch(`/search?search_id=${type}search`, {
648
+ method: 'POST',
649
+ headers: {
650
+ 'Content-Type': 'application/x-www-form-urlencoded',
651
+ },
652
+ body: `confirm=confirm${drafts.map(draft => `&delete_${deleteType}${encodeURIComponent(`[${draft}]`)}=on`)}`
653
+ })
654
+
655
+ return true;
656
+ } catch (error) {
657
+ console.error('Error inesperado', error);
658
+ return false;
659
+ }
660
+ }
661
+ }
662
+ }
663
+ },
664
+ cache: {
665
+ getData: (id) => {
666
+ if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
667
+ else return JSON.parse(localStorage.getItem(forumData.prefix + '_' + id)).content;
668
+ },
669
+ setData: (id, data, time) => {
670
+ let cur_date = time === -1 ? 'undefined' : new Date().getTime();
671
+
672
+ localStorage.setItem(
673
+ forumData.prefix + '_' + id,
674
+ JSON.stringify({
675
+ cached_at: cur_date,
676
+ content: data,
677
+ })
678
+ );
679
+ },
680
+ delData: (id) => {
681
+ if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
682
+ else return localStorage.removeItem(forumData.prefix + '_' + id);
683
+ },
684
+ useData: async (id, time) => {
685
+ const item = localStorage.getItem(forumData.prefix + '_' + id);
686
+ const cur_date = new Date();
687
+ const timeMil = time == -1 ? 'undefined' : time * 86400000;
688
+
689
+ if ((item != null && time == -1) || (item != null && parseInt(JSON.parse(item).cached_at) + timeMil > cur_date.getTime())) {
690
+ return JSON.parse(item).content;
691
+ } else {
692
+ return Promise.reject(false);
693
+ }
694
+ },
695
+ },
696
+ utility: {
697
+ genSlug: (text, alt) => {
698
+ const slug = (Q) => {
699
+ const R = '\xE0\xE1\xE4\xE2\xE8\xE9\xEB\xEA\xEC\xED\xEF\xEE\xF2\xF3\xF6\xF4\xF9\xFA\xFC\xFB\xF1\xE7\xB7/_,:;';
700
+ Q = Q.trim().toLowerCase();
701
+ for (var T = 0, U = R.length; T < U; T++) Q = Q.replace(new RegExp(R.charAt(T), 'g'), 'aaaaeeeeiiiioooouuuunc------'.charAt(T));
702
+ return Q.replace(/[^a-z0-9 -]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-');
703
+ };
704
+
705
+ const replace = alt || '_';
706
+
707
+ return slug(text).replace(/-/g, replace);
708
+ },
709
+ genArray: (string) => {
710
+ return JSON.parse(string.replace(/`/g, '"'));
711
+ },
712
+ genValidation: (array) => {
713
+ let final = '';
714
+
715
+ [].forEach.call(array, (item) => {
716
+ switch (item.validation) {
717
+ case 'hex':
718
+ if (!item.value.match(/^#[a-f0-9]{6}$/i)) {
719
+ final += '<li>El campo de ' + item.name.toLowerCase() + ' debe incluir un código de color hexadecimal.</li>';
720
+ }
721
+ break;
722
+
723
+ case 'img':
724
+ if (!item.value.match(/(jpg|jpeg|png)$/i)) {
725
+ final += '<li>El campo de ' + item.name.toLowerCase() + ' debe ser el enlace a una imagen (formato png, jpg o jpeg).</li>';
726
+ }
727
+ break;
728
+ }
729
+ });
730
+
731
+ return final;
732
+ },
733
+ getGroup: (color) => {
734
+ const returnHexVer = (code) => {
735
+ let status = 'unknown';
736
+
737
+ Object.values(forumColours).map((item) => {
738
+ if (item.hex === code.toLowerCase()) status = FNR.utility.genSlug(item.code);
739
+ });
740
+
741
+ return status;
742
+ };
743
+
744
+ const returnIdVer = (code) => {
745
+ let status = 'unknown';
746
+
747
+ Object.values(forumColours).map((item) => {
748
+ if (item.id === code) status = FNR.utility.genSlug(item.code);
749
+ });
750
+
751
+ return status;
752
+ };
753
+
754
+ if (color === undefined) return 'unknown';
755
+ else if (color.indexOf('#') > -1) return returnHexVer(color);
756
+ else if (color.indexOf('id_') > -1) return returnIdVer(parseFloat(color.split('_')[1]));
757
+ else if (forumColours[color] === undefined) return 'unknown';
758
+ else return FNR.utility.genSlug(forumColours[color].code);
759
+ }
760
+ },
761
+ html: {
762
+ genModal: (title, content, buttons) => {
763
+ if (title === '' || title === undefined || title === null) return;
764
+ if (content === '' || content === undefined || content === null) return;
765
+
766
+ let modal = document.createElement('div');
767
+
768
+ modal.id = 'forum-modal';
769
+
770
+ document.body.appendChild(modal);
771
+
772
+ let final = '';
773
+
774
+ final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="modal-element">';
775
+ final += '<div class="modal-title">';
776
+ final += '<h3>' + title + '</h3>';
777
+ final += '<a onclick="document.getElementById(`forum-modal`).remove()">';
778
+ final += '<i class="fas fa-times"></i>';
779
+ final += '</a>';
780
+ final += '</div>';
781
+ final += '<div class="modal-content">';
782
+ final += '<div class="is-content">';
783
+ final += content.replace(/\n/g, '<br>');
784
+ final += '</div>';
785
+
786
+ if (buttons !== '' && buttons !== undefined && buttons !== null) {
787
+ final += '<div class="modal-buttons">';
788
+ final += buttons;
789
+ final += '</div>';
790
+ }
791
+
792
+ final += '</div>';
793
+ final += '</div>';
794
+
795
+ final += '<div class="is-bgmodal bg-active" onclick="document.getElementById(`forum-modal`).remove()"></div>';
796
+
797
+ document.getElementById('forum-modal').innerHTML = final;
798
+ },
799
+ genPrompt: (title, content, placeholder, text) => {
800
+ if (title === '' || title === undefined || title === null) return;
801
+ if (content === '' || content === undefined || content === null) return;
802
+
803
+ return new Promise((resolve, reject) => {
804
+ FNR.html.genModal(title, '<p>' + content + '</p><p><input id="modal-prompt" type="text" placeholder="' + placeholder + '" value="' + text + '"></p>', '<button id="modal-button-enter" class="button1 btn-main">Confirmar</button><button id="modal-button-cancel" class="button1">Cancelar</button>');
805
+
806
+ document.querySelector('#modal-button-enter').onclick = () => {
807
+ const result = document.querySelector('#modal-prompt').value;
808
+
809
+ if (result === '') {
810
+ resolve(false);
811
+ } else {
812
+ resolve(result);
813
+ }
814
+
815
+ document.getElementById(`forum-modal`).remove();
816
+ };
817
+
818
+ document.querySelector('#modal-button-cancel').onclick = () => {
819
+ reject(false);
820
+ document.getElementById(`forum-modal`).remove();
821
+ };
822
+
823
+ document.querySelector('.modal-title a').onclick = () => {
824
+ reject(false);
825
+ document.getElementById(`forum-modal`).remove();
826
+ };
827
+
828
+ document.querySelector('.is-bgmodal.bg-active').onclick = () => {
829
+ reject(false);
830
+ document.getElementById(`forum-modal`).remove();
831
+ };
832
+ });
833
+ },
834
+ genNotification: (title, content, icon, url) => {
835
+ if (title === '' || title === undefined || title === null) return;
836
+ if (content === '' || content === undefined || content === null) return;
837
+ if (content.length > 50) return;
838
+ if (icon === '' || icon === undefined || icon === null) return;
839
+
840
+ if (document.querySelectorAll('forum-notification').length) {
841
+ document.getElementById('forum-notification').remove();
842
+ clearTimeout();
843
+ }
844
+
845
+ let notification = document.createElement('div');
846
+
847
+ notification.id = 'forum-notification';
848
+
849
+ document.body.appendChild(notification);
850
+
851
+ let final = '';
852
+
853
+ if (url === '' || url === undefined || url === null) {
854
+ final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
855
+ } else {
856
+ final += '<a href="' + url + '" target="_blank" id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
857
+ }
858
+
859
+ final += '<div class="notification-icon">';
860
+ final += '<i class="' + icon + '"></i>';
861
+ final += '</div>';
862
+ final += '<div class="notification-content">';
863
+ final += '<h3>' + title + '</h3>';
864
+ final += '<p>' + content + '</p>';
865
+ final += '</div>';
866
+ final += '<div class="notification-controls">';
867
+ final += '<i class="fas fa-times"></i>';
868
+ final += '</div>';
869
+
870
+ if (url === '' || url === undefined || url === null) {
871
+ final += '</div>';
872
+ } else {
873
+ final += '</a>';
874
+ }
875
+
876
+ document.getElementById('forum-notification').innerHTML = final;
877
+
878
+ setTimeout(() => {
879
+ document.getElementById(`forum-notification`).classList.add('notification-show');
880
+ }, 250);
881
+
882
+ setTimeout(() => {
883
+ document.getElementById(`forum-notification`).classList.remove('notification-show');
884
+ }, 8000);
885
+
886
+ setTimeout(() => {
887
+ document.getElementById(`forum-notification`).remove();
888
+ }, 10000);
889
+ }
890
+ },
891
+ behaviour: {
892
+ genWiki: () => {
893
+ if (document.querySelector('.wiki-cascade')) {
894
+ [].forEach.call(document.getElementsByClassName('wiki-cascade'), (item) => {
895
+ item.onclick = () => {
896
+ const element = item.parentElement.parentElement;
897
+
898
+ if (element.classList.contains('is-active')) {
899
+ element.classList.remove('is-active');
900
+ } else {
901
+ element.classList.add('is-active');
902
+ }
903
+ };
904
+ });
905
+ }
906
+
907
+ if (document.querySelector('.wiki-controls .router-link-active')) {
908
+ [].forEach.call(document.querySelectorAll('.wiki-controls .router-link-active'), (item) => {
909
+ if (!item.parentElement.parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
910
+ const setActive = (element, isFirst) => {
911
+ let parentElement = element.parentElement.parentElement;
912
+
913
+ if (isFirst) {
914
+ parentElement = parentElement.parentElement.parentElement;
915
+ }
916
+
917
+ parentElement.classList.add('is-active');
918
+ parentElement.classList.add('is-selected');
919
+
920
+ if (!parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
921
+ setActive(parentElement, false);
922
+ }
923
+ };
924
+
925
+ setActive(item, true);
926
+ }
927
+ });
928
+ }
929
+
930
+ if (document.querySelector('aside.wiki-index > .select-container > select')) {
931
+ document.querySelector('aside.wiki-index > .select-container > select').onchange = () => {
932
+ router.push(document.querySelector('aside.wiki-index > .select-container > select').value);
933
+ };
934
+ }
935
+ },
936
+ genDropeable: () => {
937
+ if (document.querySelector('.is-dropeable')) {
938
+ [].forEach.call(document.getElementsByClassName('is-dropeable'), (item) => {
939
+ item.onclick = () => {
940
+ if (!item.classList.contains('is-active')) {
941
+ [].forEach.call(document.getElementsByClassName('is-dropeable'), (drops) => {
942
+ drops.classList.remove('is-active');
943
+ });
944
+
945
+ item.classList.add('is-active');
946
+ } else {
947
+ item.classList.remove('is-active');
948
+ }
949
+ };
950
+ });
951
+ }
952
+ }
953
+ }
862
954
  };