generic-skin 2.5.3 → 2.9.56

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,1147 @@
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
+ post: {
186
+ getPost: (url) => {
187
+ return new Promise((resolve, reject) => {
188
+ $.get(Vue.filter('url-to-invision')(url), (data) => {
189
+ const post = $(data).find("#p" + url.split("#")[1]);
190
+
191
+ resolve({
192
+ author: {
193
+ text: post.find(".author a").text(),
194
+ color: post.find(".author a span").css("color"),
195
+ url: Vue.filter('url-to-normal')(post.find(".author a").attr("href")),
196
+ },
197
+ content: post.find(".post-entry > div").html(),
198
+ date: post.find(".author").html().split("</a>")[1],
199
+ });
200
+ });
201
+ });
202
+ },
203
+ genPost: (id, content) => {
204
+ return new Promise((resolve, reject) => {
205
+ let save = document.createElement('iframe');
206
+
207
+ save.id = 'forum-save';
208
+ save.src = '/post?t=' + id + '&mode=reply&change_version=invision';
209
+ save.width = 0;
210
+ save.height = 0;
211
+ save.onload = () => {
212
+ saveDOM.onload = () => {
213
+ $('#forum-save').remove();
214
+
215
+ console.clear();
216
+
217
+ resolve(true);
218
+ };
219
+
220
+ $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
221
+ $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
222
+ };
223
+
224
+ document.querySelector('body > header').prepend(save);
225
+
226
+ const saveDOM = document.getElementById('forum-save');
227
+ });
228
+ },
229
+ },
230
+ topic: {
231
+ getType: (src) => {
232
+ const classes = [];
233
+
234
+ if (src.indexOf('unread') > -1) {
235
+ classes.push('is-unread');
236
+ } else {
237
+ classes.push('is-read');
238
+ }
239
+
240
+ if (src.indexOf('locked') > -1) {
241
+ classes.push('is-closed');
242
+ } else if (src.indexOf('sticky') > 1) {
243
+ classes.push('is-sticky');
244
+ } else if (src.indexOf('global_announce') > 1) {
245
+ classes.push('is-global-announcement');
246
+ } else if (src.indexOf('announce') > 1) {
247
+ classes.push('is-announcement');
248
+ }
249
+
250
+ return classes;
251
+ },
252
+ genTopic: (id, name, content) => {
253
+ return new Promise((resolve, reject) => {
254
+ let save = document.createElement('iframe');
255
+
256
+ save.id = 'forum-save';
257
+ save.src = '/post?f=' + id + '&mode=newtopic&change_version=invision';
258
+ save.width = 0;
259
+ save.height = 0;
260
+ save.onload = () => {
261
+ saveDOM.onload = () => {
262
+ $('#forum-save').remove();
263
+
264
+ console.clear();
265
+
266
+ resolve(true);
267
+ };
268
+
269
+ $('#forum-save').contents().find('dl dt:contains("Título del tema")').parent().find('input').val(name);
270
+ $('#forum-save').contents().find('.subtitle:contains("Mensaje")').next().find('textarea').val(content);
271
+ $('#forum-save').contents().find('.formbuttonrow.center input[value="Enviar"]').click();
272
+ };
273
+
274
+ document.querySelector('body > header').prepend(save);
275
+
276
+ const saveDOM = document.getElementById('forum-save');
277
+ });
278
+ },
279
+ }
280
+ },
281
+ user: {
282
+ getUrl: (name) => {
283
+ let character =
284
+ name !== undefined ? encodeURIComponent(name)
285
+ .replace(/[!'()]/g, escape)
286
+ .replace(/\*/g, "%2A") :
287
+ _userdata.user_id;
288
+
289
+ return "/profile?mode=viewprofile&u=" + character;
290
+ },
291
+ getLevel: async () => {
292
+ switch (_userdata.user_level) {
293
+ case 2:
294
+ return 'mod';
295
+ case 1:
296
+ return 'admin';
297
+ case 0:
298
+ return -1 == _userdata.user_id ? 'guest' : 'user';
299
+ }
300
+ },
301
+ getGroup: async () => {
302
+ const level = await FNR.user.getLevel();
303
+
304
+ if (level === 'guest') {
305
+ return 'unknown';
306
+ }
307
+
308
+ const { colour } = await FNR.user.getProfile(_userdata.user_id, .25);
309
+
310
+ return colour;
311
+ },
312
+ getProfile: (name, time) => {
313
+ const character = name != undefined ? FNR.user.getUrl(name) : FNR.user.getUrl();
314
+ const cache = time || 5;
315
+
316
+ const processData = (content) => {
317
+ if (content.find('a').length) return Vue.filter('url-to-normal')(content.find('a').attr('href'));
318
+ else if (content.find('table').length) return content.find('table').html();
319
+ else if (content.find('img').length) return content.find('img').attr('src');
320
+ else if (content.find('textarea').length) return content.find('textarea').val();
321
+ else if (content.find('span').length) return content.find('span').text().trim();
322
+ else if (content.text().trim() === '-') return '';
323
+ else return content.text();
324
+ };
325
+
326
+ const getData = () => {
327
+ return new Promise((resolve, reject) => {
328
+ $.get(character + '&change_version=invision', (data) => {
329
+ let user = {};
330
+
331
+ user['name'] = $(data).find('.maintitle h1 span').text();
332
+ user['lastvisit'] = $(data).find('dt:contains("Última visita")').parent().find('dd').text();
333
+ user['colour'] = FNR.utility.getGroup($(data).find('.maintitle h1 span').css('color').replace('rgb(', 'rgb_').replace(/, /g, '_').replace(')', ''));
334
+ user['avatar'] = $(data).find('.real_avatar img').attr('src');
335
+
336
+ user['links'] = {
337
+ profile: '/u' + character.split('&u=')[1],
338
+ mp: '/privmsg?mode=post&u=' + character.split('&u=')[1],
339
+ };
340
+
341
+ user['messages'] = {
342
+ public: parseInt($(data).find('span:contains("Mensajes")').parent().parent().find('dd > div').text()) || 0,
343
+ private: parseInt($(data).find('dt:contains("Mensajes privados")').parent().find('dd').text()) || 0
344
+ };
345
+
346
+ user['fields'] = {};
347
+
348
+ $(data).find('dl[id^="field_id"]').each(function() {
349
+ if ($(this).find('dt span').text() !== '') {
350
+ if ($(this).find('dt span').text() === 'Mensajes') return;
351
+
352
+ user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
353
+ name: $(this).find('dt span').text(),
354
+ content: processData($(this).find('dd .field_uneditable'))
355
+ }
356
+ }
357
+ });
358
+
359
+ $(data).find('.ipbform2 > dl').each(function() {
360
+ if ($(this).find('dt span').length && $(this).find('dt span').text() !== '') {
361
+ if ($(this).find('dt span').text() === 'Mensajes') return;
362
+
363
+ user.fields[FNR.utility.genSlug($(this).find('dt span').text())] = {
364
+ name: $(this).find('dt span').text(),
365
+ content: processData($(this).find('dd'))
366
+ }
367
+ }
368
+ });
369
+
370
+ user.fields['rango'] = {
371
+ name: 'Rango',
372
+ content: $(data).find('dt:contains("Rango:")').parent().find('dd').text()
373
+ }
374
+
375
+ resolve(user);
376
+ });
377
+ });
378
+ };
379
+
380
+ const readUserCache = (id) => {
381
+ const userId = `userInfo${id}`;
382
+
383
+ return new Promise((resolve, reject) => {
384
+ FNR.cache.useData(userId, cache).then(
385
+ (result) => {
386
+ resolve(result);
387
+ },
388
+ (err) => {
389
+ getData().then((data) => {
390
+ FNR.cache.setData(userId, data);
391
+
392
+ resolve(data);
393
+ });
394
+ }
395
+ );
396
+ });
397
+ };
398
+
399
+ return readUserCache(name);
400
+ },
401
+ changeAccount: async (out, username, password) => {
402
+ try {
403
+ await fetch(out);
404
+ await fetch('/login', {
405
+ method: 'POST',
406
+ headers: {
407
+ 'Content-Type': 'application/x-www-form-urlencoded',
408
+ },
409
+ body: `username=${encodeURIComponent(username)}&password=${encodeURIComponent(password)}&autologin=1&login=1`
410
+ })
411
+
412
+ return true;
413
+ } catch (error) {
414
+ console.error('Error inesperado', error);
415
+ return false;
416
+ }
417
+ },
418
+ followed: {
419
+ getPages: async () => {
420
+ try {
421
+ const followedPage = await fetch('/search?search_id=watchsearch&change_version=invision');
422
+ const bodyFollowedPage = await followedPage.text();
423
+ const htmlFollowedPage = document.createElement('html');
424
+
425
+ htmlFollowedPage.innerHTML = bodyFollowedPage;
426
+
427
+ const total = htmlFollowedPage.querySelectorAll('.pagination a');
428
+ let arrayItems = [];
429
+
430
+ if (total.length) {
431
+ const finalPage = total[total.length - 2];
432
+ const finalPageUrl = finalPage.href.split(finalPage.origin)[1];
433
+ const finalPageNumberArray = finalPageUrl.match(/[0-9]/g) || [];
434
+ const finalPageNumber = parseInt(finalPageNumberArray.join('')) || 0;
435
+
436
+ const firstPage = total[1];
437
+ const firstPageUrl = firstPage.href.split(firstPage.origin)[1];
438
+ const firstPageNumberArray = firstPageUrl.match(/[0-9]/g) || [];
439
+ const firstPageNumber = parseInt(firstPageNumberArray.join('')) || 0;
440
+
441
+ const arrayPages = typeof finalPageNumber === 'undefined' ? 0 : finalPageNumber / firstPageNumber;
442
+ arrayItems = Array(arrayPages).fill(null).map((page, index) => `/search?search_id=watchsearch&start=${firstPageNumber * (index + 1)}&change_version=invision`);
443
+ }
444
+
445
+ return {
446
+ items: htmlFollowedPage.querySelectorAll('.ipbtable tbody tr td').length === 1 ? 0 : htmlFollowedPage.querySelectorAll('.ipbtable tbody tr').length,
447
+ pages: ['/search?search_id=watchsearch&change_version=invision', ...arrayItems],
448
+ }
449
+ } catch (error) {
450
+ console.error('Error inesperado', error);
451
+ return false;
452
+ }
453
+ },
454
+ getFollowed: async (page) => {
455
+ try {
456
+ const followedPage = await fetch(page);
457
+ const bodyFollowedPage = await followedPage.text();
458
+ const htmlFollowedPage = document.createElement('html');
459
+
460
+ htmlFollowedPage.innerHTML = bodyFollowedPage;
461
+
462
+ return Array.from(htmlFollowedPage.querySelectorAll('.ipbtable tbody tr')).map(row => {
463
+ const cells = row.children;
464
+
465
+ return {
466
+ id: parseInt(cells[7].children[0].value),
467
+ name: cells[1].querySelector('.topictitle').textContent.trim(),
468
+ url: Vue.filter('url-to-normal')(cells[1].querySelector('.topictitle').href),
469
+ views: parseInt(cells[5].textContent),
470
+ replies: parseInt(cells[3].textContent),
471
+ type: FNR.content.topic.getType(cells[0].querySelector('img').src).join(' '),
472
+ }
473
+ });
474
+ } catch (error) {
475
+ console.error('Error inesperado', error);
476
+ return false;
477
+ }
478
+ },
479
+ delFollowed: async (topics) => {
480
+ try {
481
+ await fetch('/search?search_id=watchsearch', {
482
+ method: 'POST',
483
+ headers: {
484
+ 'Content-Type': 'application/x-www-form-urlencoded',
485
+ },
486
+ body: `confirm=confirm${topics.map(topic => `&mark${encodeURIComponent(`[]`)}2=${topic}`)}`
487
+ })
488
+
489
+ return true;
490
+ } catch (error) {
491
+ console.error('Error inesperado', error);
492
+ return false;
493
+ }
494
+ },
495
+ },
496
+ drafts: {
497
+ delDrafts: async (type, drafts) => {
498
+ try {
499
+ const deleteType = type === 'draft' ? 'draft' : 'topic_draft';
500
+
501
+ await fetch(`/search?search_id=${type}search`, {
502
+ method: 'POST',
503
+ headers: {
504
+ 'Content-Type': 'application/x-www-form-urlencoded',
505
+ },
506
+ body: `confirm=confirm${drafts.map(draft => `&delete_${deleteType}${encodeURIComponent(`[${draft}]`)}=on`)}`
507
+ })
508
+
509
+ return true;
510
+ } catch (error) {
511
+ console.error('Error inesperado', error);
512
+ return false;
513
+ }
514
+ },
515
+ messages: {
516
+ getPages: async () => {
517
+ try {
518
+ const draftsPage = await fetch('/search?search_id=draftsearch&change_version=invision');
519
+ const bodyDraftsPage = await draftsPage.text();
520
+ const htmlDraftsPage = document.createElement('html');
521
+
522
+ htmlDraftsPage.innerHTML = bodyDraftsPage;
523
+
524
+ const total = htmlDraftsPage.querySelectorAll('.pagination a');
525
+ let arrayItems = [];
526
+
527
+ if (total.length) {
528
+ const finalPage = total[total.length - 2];
529
+ const finalPageUrl = finalPage.href.split(finalPage.origin)[1];
530
+ const finalPageNumberArray = finalPageUrl.match(/[0-9]/g) || [];
531
+ const finalPageNumber = parseInt(finalPageNumberArray.join('')) || 0;
532
+
533
+ const firstPage = total[1];
534
+ const firstPageUrl = firstPage.href.split(firstPage.origin)[1];
535
+ const firstPageNumberArray = firstPageUrl.match(/[0-9]/g) || [];
536
+ const firstPageNumber = parseInt(firstPageNumberArray.join('')) || 0;
537
+
538
+ const arrayPages = typeof finalPageNumber === 'undefined' ? 0 : finalPageNumber / firstPageNumber;
539
+ arrayItems = Array(arrayPages).fill(null).map((page, index) => `/search?search_id=draftsearch&start=${firstPageNumber * (index + 1)}&change_version=invision`);
540
+ }
541
+
542
+ return {
543
+ items: htmlDraftsPage.querySelectorAll('.ipbtable tbody tr td').length === 1 ? 0 : htmlDraftsPage.querySelectorAll('.ipbtable tbody tr').length,
544
+ pages: ['/search?search_id=draftsearch&change_version=invision', ...arrayItems],
545
+ }
546
+ } catch (error) {
547
+ console.error('Error inesperado', error);
548
+ return false;
549
+ }
550
+ },
551
+ getDrafts: async (page) => {
552
+ try {
553
+ const draftsPage = await fetch(page);
554
+ const bodyDraftsPage = await draftsPage.text();
555
+ const htmlDraftsPage = document.createElement('html');
556
+
557
+ htmlDraftsPage.innerHTML = bodyDraftsPage;
558
+
559
+ return Array.from(htmlDraftsPage.querySelectorAll('.ipbtable tbody tr')).map(row => {
560
+ const cells = row.children;
561
+
562
+ return {
563
+ topic: {
564
+ name: cells[1].textContent.trim(),
565
+ url: Vue.filter('url-to-normal')(cells[1].querySelector('a').href)
566
+ },
567
+ info: {
568
+ location: cells[2].textContent.trim(),
569
+ date: cells[3].textContent.trim()
570
+ },
571
+ modify: Vue.filter('url-to-normal')(cells[4].querySelector('a').href)
572
+ }
573
+ });
574
+ } catch (error) {
575
+ console.error('Error inesperado', error);
576
+ return false;
577
+ }
578
+ },
579
+ },
580
+ topics: {
581
+ getPages: async () => {
582
+ try {
583
+ const draftsPage = await fetch('/search?search_id=topicdraftsearch&change_version=invision');
584
+ const bodyDraftsPage = await draftsPage.text();
585
+ const htmlDraftsPage = document.createElement('html');
586
+
587
+ htmlDraftsPage.innerHTML = bodyDraftsPage;
588
+
589
+ const total = htmlDraftsPage.querySelectorAll('.pagination a');
590
+ let arrayItems = [];
591
+
592
+ if (total.length) {
593
+ const finalPage = total[total.length - 2];
594
+ const finalPageUrl = finalPage.href.split(finalPage.origin)[1];
595
+ const finalPageNumberArray = finalPageUrl.match(/[0-9]/g) || [];
596
+ const finalPageNumber = parseInt(finalPageNumberArray.join('')) || 0;
597
+
598
+ const firstPage = total[1];
599
+ const firstPageUrl = firstPage.href.split(firstPage.origin)[1];
600
+ const firstPageNumberArray = firstPageUrl.match(/[0-9]/g) || [];
601
+ const firstPageNumber = parseInt(firstPageNumberArray.join('')) || 0;
602
+
603
+ const arrayPages = typeof finalPageNumber === 'undefined' ? 0 : finalPageNumber / firstPageNumber;
604
+ arrayItems = Array(arrayPages).fill(null).map((page, index) => `/search?search_id=topicdraftsearch&start=${firstPageNumber * (index + 1)}&change_version=invision`);
605
+ }
606
+
607
+ return {
608
+ items: htmlDraftsPage.querySelectorAll('.ipbtable tbody tr td').length === 1 ? 0 : htmlDraftsPage.querySelectorAll('.ipbtable tbody tr').length,
609
+ pages: ['/search?search_id=topicdraftsearch&change_version=invision', ...arrayItems],
610
+ }
611
+ } catch (error) {
612
+ console.error('Error inesperado', error);
613
+ return false;
614
+ }
615
+ },
616
+ getDrafts: async (page) => {
617
+ try {
618
+ const draftsPage = await fetch(page);
619
+ const bodyDraftsPage = await draftsPage.text();
620
+ const htmlDraftsPage = document.createElement('html');
621
+
622
+ htmlDraftsPage.innerHTML = bodyDraftsPage;
623
+
624
+ return Array.from(htmlDraftsPage.querySelectorAll('.ipbtable tbody tr')).map(row => {
625
+ const cells = row.children;
626
+
627
+ return {
628
+ topic: {
629
+ name: cells[0].textContent.trim(),
630
+ url: Vue.filter('url-to-normal')(cells[0].querySelector('a').href)
631
+ },
632
+ info: {
633
+ location: cells[1].textContent.trim(),
634
+ date: cells[2].textContent.trim()
635
+ },
636
+ modify: Vue.filter('url-to-normal')(cells[3].querySelector('a').href)
637
+ }
638
+ });
639
+ } catch (error) {
640
+ console.error('Error inesperado', error);
641
+ return false;
642
+ }
643
+ },
644
+ }
645
+ },
646
+ profile: {
647
+ getData: (array) => {
648
+ return new Promise((resolve, reject) => {
649
+ $.get('/profile?change_version=invision&mode=editprofile', (data) => {
650
+ const fields = data;
651
+
652
+ $.get('/profile?change_version=invision&mode=editprofile&page_profil=avatars', (data) => {
653
+ const avatar = data;
654
+
655
+ let result = [];
656
+
657
+ [].forEach.call(array, (item) => {
658
+ let value = '',
659
+ options = [];
660
+
661
+ switch (item.type) {
662
+ case 'input':
663
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('input').val();
664
+ break;
665
+
666
+ case 'textarea':
667
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('textarea').val();
668
+ break;
669
+
670
+ case 'select':
671
+ value = $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option:selected').attr('value');
672
+
673
+ $(fields).find('dl:contains("' + item.name + '")').find('dd').find('select option').each(function() {
674
+ if ($(this).attr('value') === '') return;
675
+
676
+ options.push({
677
+ name: $(this).text(),
678
+ value: $(this).attr('value')
679
+ });
680
+ });
681
+ break;
682
+
683
+ case 'avatar':
684
+ value = $(avatar).find('.box-content img').attr('src');
685
+ break;
686
+ }
687
+
688
+ if (item.type === 'select' && value === undefined || item.type === 'select' && value === '') return;
689
+
690
+ let final = {
691
+ type: item.type,
692
+ name: item.name,
693
+ value: value
694
+ };
695
+
696
+ if (item.validation) {
697
+ final.validation = item.validation;
698
+ }
699
+
700
+ if (options.length) {
701
+ final.options = options;
702
+ }
703
+
704
+ result.push(final);
705
+ });
706
+
707
+ resolve(result);
708
+ });
709
+ });
710
+ });
711
+ },
712
+ setData: (array) => {
713
+ return new Promise((resolve, reject) => {
714
+ const resolveSetter = () => {
715
+ $('#forum-save').remove();
716
+
717
+ console.clear();
718
+
719
+ resolve(true);
720
+ };
721
+
722
+ let save = document.createElement('iframe');
723
+
724
+ save.id = 'forum-save';
725
+ save.src = '/profile?change_version=invision&mode=editprofile';
726
+ save.width = 0;
727
+ save.height = 0;
728
+ save.onload = () => {
729
+ let avatar = false;
730
+
731
+ [].forEach.call(array, (item) => {
732
+ switch (item.type) {
733
+ case 'input':
734
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('input').first().val(item.value);
735
+ break;
736
+
737
+ case 'textarea':
738
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('textarea').val(item.value);
739
+ break;
740
+
741
+ case 'select':
742
+ $('#forum-save').contents().find('dl:contains("' + item.name + '")').find('dd').find('select option[value="' + item.value + '"]').attr('selected', 'selected');
743
+ break;
744
+
745
+ case 'avatar':
746
+ avatar = item.value;
747
+ break;
748
+ }
749
+ });
750
+
751
+ saveDOM.onload = () => {
752
+ if (!avatar) {
753
+ resolveSetter();
754
+ } else {
755
+ saveDOM.onload = () => {
756
+ saveDOM.onload = () => {
757
+ resolveSetter();
758
+ }
759
+
760
+ $('#forum-save').contents().find('input[name="avatarremoteurl"]').val(avatar);
761
+ $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
762
+ }
763
+
764
+ saveDOM.src = '/profile?change_version=invision&mode=editprofile&page_profil=avatars';
765
+ }
766
+ };
767
+
768
+ $('#forum-save').contents().find('input[type="submit"][value="Registrar"]').click();
769
+ };
770
+
771
+ document.querySelector('body > header').prepend(save);
772
+
773
+ const saveDOM = document.getElementById('forum-save');
774
+ });
775
+ }
776
+ }
777
+ },
778
+ cache: {
779
+ getData: (id) => {
780
+ if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
781
+ else return JSON.parse(localStorage.getItem(forumData.prefix + '_' + id)).content;
782
+ },
783
+ setData: (id, data, time) => {
784
+ let cur_date = time === -1 ? 'undefined' : new Date().getTime();
785
+
786
+ localStorage.setItem(
787
+ forumData.prefix + '_' + id,
788
+ JSON.stringify({
789
+ cached_at: cur_date,
790
+ content: data,
791
+ })
792
+ );
793
+ },
794
+ delData: (id) => {
795
+ if (localStorage.getItem(forumData.prefix + '_' + id) === null) return false;
796
+ else return localStorage.removeItem(forumData.prefix + '_' + id);
797
+ },
798
+ useData: async (id, time) => {
799
+ const item = localStorage.getItem(forumData.prefix + '_' + id);
800
+ const cur_date = new Date();
801
+ const timeMil = time == -1 ? 'undefined' : time * 86400000;
802
+
803
+ if ((item != null && time == -1) || (item != null && parseInt(JSON.parse(item).cached_at) + timeMil > cur_date.getTime())) {
804
+ return JSON.parse(item).content;
805
+ } else {
806
+ return Promise.reject(false);
807
+ }
808
+ },
809
+ },
810
+ utility: {
811
+ genSlug: (text, alt) => {
812
+ const slug = (Q) => {
813
+ 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/_,:;';
814
+ Q = Q.trim().toLowerCase();
815
+ for (var T = 0, U = R.length; T < U; T++) Q = Q.replace(new RegExp(R.charAt(T), 'g'), 'aaaaeeeeiiiioooouuuunc------'.charAt(T));
816
+ return Q.replace(/[^a-z0-9 -]/g, '').replace(/\s+/g, '-').replace(/-+/g, '-');
817
+ };
818
+
819
+ const replace = alt || '_';
820
+
821
+ return slug(text).replace(/-/g, replace);
822
+ },
823
+ genArray: (string) => {
824
+ return JSON.parse(string.replace(/`/g, '"'));
825
+ },
826
+ genValidation: (array) => {
827
+ let final = '';
828
+
829
+ [].forEach.call(array, (item) => {
830
+ switch (item.validation) {
831
+ case 'hex':
832
+ if (!item.value.match(/^#[a-f0-9]{6}$/i)) {
833
+ final += '<li>El campo de ' + item.name.toLowerCase() + ' debe incluir un código de color hexadecimal.</li>';
834
+ }
835
+ break;
836
+
837
+ case 'img':
838
+ if (!item.value.match(/(jpg|jpeg|png)$/i)) {
839
+ final += '<li>El campo de ' + item.name.toLowerCase() + ' debe ser el enlace a una imagen (formato png, jpg o jpeg).</li>';
840
+ }
841
+ break;
842
+ }
843
+ });
844
+
845
+ return final;
846
+ },
847
+ getGroup: (color) => {
848
+ const returnHexVer = (code) => {
849
+ let status = 'unknown';
850
+
851
+ Object.values(forumColours).map((item) => {
852
+ if (item.hex === code.toLowerCase()) status = FNR.utility.genSlug(item.code);
853
+ });
854
+
855
+ return status;
856
+ };
857
+
858
+ const returnIdVer = (code) => {
859
+ let status = 'unknown';
860
+
861
+ Object.values(forumColours).map((item) => {
862
+ if (item.id === code) status = FNR.utility.genSlug(item.code);
863
+ });
864
+
865
+ return status;
866
+ };
867
+
868
+ if (color === undefined) return 'unknown';
869
+ else if (color.indexOf('#') > -1) return returnHexVer(color);
870
+ else if (color.indexOf('id_') > -1) return returnIdVer(parseFloat(color.split('_')[1]));
871
+ else if (forumColours[color] === undefined) return 'unknown';
872
+ else return FNR.utility.genSlug(forumColours[color].code);
873
+ }
874
+ },
875
+ html: {
876
+ genModal: (title, content, buttons) => {
877
+ if (title === '' || title === undefined || title === null) return;
878
+ if (content === '' || content === undefined || content === null) return;
879
+
880
+ let modal = document.createElement('div');
881
+
882
+ modal.id = 'forum-modal';
883
+
884
+ document.body.appendChild(modal);
885
+
886
+ let final = '';
887
+
888
+ final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="modal-element">';
889
+ final += '<div class="modal-title">';
890
+ final += '<h3>' + title + '</h3>';
891
+ final += '<a onclick="document.getElementById(`forum-modal`).remove()">';
892
+ final += '<i class="fas fa-times"></i>';
893
+ final += '</a>';
894
+ final += '</div>';
895
+ final += '<div class="modal-content">';
896
+ final += '<div class="is-content">';
897
+ final += content.replace(/\n/g, '<br>');
898
+ final += '</div>';
899
+
900
+ if (buttons !== '' && buttons !== undefined && buttons !== null) {
901
+ final += '<div class="modal-buttons">';
902
+ final += buttons;
903
+ final += '</div>';
904
+ }
905
+
906
+ final += '</div>';
907
+ final += '</div>';
908
+
909
+ final += '<div class="is-bgmodal bg-active" onclick="document.getElementById(`forum-modal`).remove()"></div>';
910
+
911
+ document.getElementById('forum-modal').innerHTML = final;
912
+ },
913
+ genPrompt: (title, content, placeholder, text) => {
914
+ if (title === '' || title === undefined || title === null) return;
915
+ if (content === '' || content === undefined || content === null) return;
916
+
917
+ return new Promise((resolve, reject) => {
918
+ 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>');
919
+
920
+ document.querySelector('#modal-button-enter').onclick = () => {
921
+ const result = document.querySelector('#modal-prompt').value;
922
+
923
+ if (result === '') {
924
+ resolve(false);
925
+ } else {
926
+ resolve(result);
927
+ }
928
+
929
+ document.getElementById(`forum-modal`).remove();
930
+ };
931
+
932
+ document.querySelector('#modal-button-cancel').onclick = () => {
933
+ reject(false);
934
+ document.getElementById(`forum-modal`).remove();
935
+ };
936
+
937
+ document.querySelector('.modal-title a').onclick = () => {
938
+ reject(false);
939
+ document.getElementById(`forum-modal`).remove();
940
+ };
941
+
942
+ document.querySelector('.is-bgmodal.bg-active').onclick = () => {
943
+ reject(false);
944
+ document.getElementById(`forum-modal`).remove();
945
+ };
946
+ });
947
+ },
948
+ genNotification: (title, content, icon, url) => {
949
+ if (title === '' || title === undefined || title === null) return;
950
+ if (content === '' || content === undefined || content === null) return;
951
+ if (content.length > 50) return;
952
+ if (icon === '' || icon === undefined || icon === null) return;
953
+
954
+ if (document.querySelectorAll('forum-notification').length) {
955
+ document.getElementById('forum-notification').remove();
956
+ clearTimeout();
957
+ }
958
+
959
+ let notification = document.createElement('div');
960
+
961
+ notification.id = 'forum-notification';
962
+
963
+ document.body.appendChild(notification);
964
+
965
+ let final = '';
966
+
967
+ if (url === '' || url === undefined || url === null) {
968
+ final += '<div id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
969
+ } else {
970
+ final += '<a href="' + url + '" target="_blank" id="' + FNR.utility.genSlug(title, '-') + '" class="notification-element" onclick="document.querySelector(`#forum-notification`).classList.remove(`notification-show`)" >';
971
+ }
972
+
973
+ final += '<div class="notification-icon">';
974
+ final += '<i class="' + icon + '"></i>';
975
+ final += '</div>';
976
+ final += '<div class="notification-content">';
977
+ final += '<h3>' + title + '</h3>';
978
+ final += '<p>' + content + '</p>';
979
+ final += '</div>';
980
+ final += '<div class="notification-controls">';
981
+ final += '<i class="fas fa-times"></i>';
982
+ final += '</div>';
983
+
984
+ if (url === '' || url === undefined || url === null) {
985
+ final += '</div>';
986
+ } else {
987
+ final += '</a>';
988
+ }
989
+
990
+ document.getElementById('forum-notification').innerHTML = final;
991
+
992
+ setTimeout(() => {
993
+ document.getElementById(`forum-notification`).classList.add('notification-show');
994
+ }, 250);
995
+
996
+ setTimeout(() => {
997
+ document.getElementById(`forum-notification`).classList.remove('notification-show');
998
+ }, 8000);
999
+
1000
+ setTimeout(() => {
1001
+ document.getElementById(`forum-notification`).remove();
1002
+ }, 10000);
1003
+ }
1004
+ },
1005
+ behaviour: {
1006
+ genWiki: () => {
1007
+ if (document.querySelector('.wiki-cascade')) {
1008
+ [].forEach.call(document.getElementsByClassName('wiki-cascade'), (item) => {
1009
+ item.onclick = () => {
1010
+ const element = item.parentElement.parentElement;
1011
+
1012
+ if (element.classList.contains('is-active')) {
1013
+ element.classList.remove('is-active');
1014
+ } else {
1015
+ element.classList.add('is-active');
1016
+ }
1017
+ };
1018
+ });
1019
+ }
1020
+
1021
+ if (document.querySelector('.wiki-controls .router-link-active')) {
1022
+ [].forEach.call(document.querySelectorAll('.wiki-controls .router-link-active'), (item) => {
1023
+ if (!item.parentElement.parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
1024
+ const setActive = (element, isFirst) => {
1025
+ let parentElement = element.parentElement.parentElement;
1026
+
1027
+ if (isFirst) {
1028
+ parentElement = parentElement.parentElement.parentElement;
1029
+ }
1030
+
1031
+ parentElement.classList.add('is-active');
1032
+ parentElement.classList.add('is-selected');
1033
+
1034
+ if (!parentElement.parentElement.parentElement.parentElement.classList.contains('wiki-index')) {
1035
+ setActive(parentElement, false);
1036
+ }
1037
+ };
1038
+
1039
+ setActive(item, true);
1040
+ }
1041
+ });
1042
+ }
1043
+
1044
+ if (document.querySelector('aside.wiki-index > .select-container > select')) {
1045
+ document.querySelector('aside.wiki-index > .select-container > select').onchange = () => {
1046
+ router.push(document.querySelector('aside.wiki-index > .select-container > select').value);
1047
+ };
1048
+ }
1049
+ },
1050
+ genDropeable: () => {
1051
+ if (document.querySelector('.is-dropeable')) {
1052
+ [].forEach.call(document.getElementsByClassName('is-dropeable'), (item) => {
1053
+ item.onclick = () => {
1054
+ if (!item.classList.contains('is-active')) {
1055
+ [].forEach.call(document.getElementsByClassName('is-dropeable'), (drops) => {
1056
+ drops.classList.remove('is-active');
1057
+ });
1058
+
1059
+ item.classList.add('is-active');
1060
+ } else {
1061
+ item.classList.remove('is-active');
1062
+ }
1063
+ };
1064
+ });
1065
+ }
1066
+ },
1067
+ genControls: () => {
1068
+ if (document.querySelector('.forum-controls')) {
1069
+ [].forEach.call(document.querySelectorAll('.forum-controls'), (control) => {
1070
+ let children = 0;
1071
+
1072
+ [].forEach.call(control.children, (item) => {
1073
+ if (window.getComputedStyle(item, null).display === 'none') {
1074
+ return;
1075
+ }
1076
+
1077
+ children += item.children.length;
1078
+ });
1079
+
1080
+ if (children === 0 && control.classList.contains('not-show') === false) {
1081
+ control.classList.add('not-show');
1082
+ }
1083
+ });
1084
+ }
1085
+ },
1086
+ genPagelist: (total, current) => {
1087
+ if (total.length < 5) {
1088
+ return total;
1089
+ }
1090
+
1091
+ switch (current) {
1092
+ case 0:
1093
+ return [
1094
+ total[current],
1095
+ total[current + 1],
1096
+ total[current + 2],
1097
+ total[current + 3],
1098
+ total[current + 4]
1099
+ ];
1100
+
1101
+ case 1:
1102
+ return [
1103
+ total[current - 1],
1104
+ total[current],
1105
+ total[current + 1],
1106
+ total[current + 2],
1107
+ total[current + 3]
1108
+ ];
1109
+
1110
+ case current.length - 1:
1111
+ return [
1112
+ total[current - 4],
1113
+ total[current - 3],
1114
+ total[current - 2],
1115
+ total[current - 1],
1116
+ total[current]
1117
+ ];
1118
+
1119
+ case current.length - 2:
1120
+ return [
1121
+ total[current - 3],
1122
+ total[current - 2],
1123
+ total[current - 1],
1124
+ total[current],
1125
+ total[current + 1]
1126
+ ];
1127
+
1128
+ default:
1129
+ return [
1130
+ total[current - 2],
1131
+ total[current - 1],
1132
+ total[current],
1133
+ total[current + 1],
1134
+ total[current + 2]
1135
+ ];
1136
+ }
1137
+ },
1138
+ genDebounce: (func, timeout = 300) => {
1139
+ let timer;
1140
+
1141
+ return (...args) => {
1142
+ clearTimeout(timer);
1143
+ timer = setTimeout(() => { func.apply(this, args); }, timeout);
1144
+ };
1145
+ },
1146
+ }
862
1147
  };