PageSourceSearch

https://ren.pt/js/search.js?v2

js ren.pt collected 2026-09-24 09:23:16 UTC 11,930 bytes, 463 lines download raw bytes

1var loaded = false;
2
3var search_current_page = 1;
4var search_current_news = 1;
5var search_current_multimedia = 1;
6var search_current_document = 1;
7var search_local_storage_prefix = 'RENWEBSITE_';
8var search_local_storage_max = 16;
9var search_local_storage_cols = 4;
10var search_local_storage_col_max = 4;
11
12var divElementTag = "<div>";
13var ulElementTag = "<ul>";
14var liElementTag = "<li>";
15var aElementTag = "<a>";
16
17window.onload = function () {
18 if (document.readyState == 'complete' && !loaded) {
19  readUrlParameterSearch();
20  setPageRecentSearches();
21  handleInputs();
22
23  loaded = true;
24 }
25};
26
27handleInputs();
28
29function handleInputs() {
30 var input_search_global = document.getElementById("ws_txt_search_global");
31 if (input_search_global != null) {
32  input_search_global.addEventListener("keypress", function (event) {
33   if (event.key === "Enter") {
34    event.preventDefault();
35    var headerSearchForm = document.getElementById('header-search-form');
36    if (headerSearchForm != null) {
37     let searchUrl = headerSearchForm.dataset.spUrl;
38     goToSearchPage(searchUrl);
39    }
40   }
41  });
42 }
43
44 var input_search_global_principal = document.getElementById("ws_txt_search_global_principal");
45 if (input_search_global_principal != null) {
46  input_search_global_principal.addEventListener("keypress", function (event) {
47   if (event.key === "Enter") {
48    event.preventDefault();
49    searchMain();
50   }
51  });
52 }
53}
54
55function readUrlParameterSearch() {
56 let searchParams = (new URL(document.location)).searchParams;
57
58 let sParam = searchParams.get("s");
59 if (sParam != null) {
60  document.getElementById('ws_txt_search_global_principal').value = decodeURI(unescapeHtml(sParam));
61 }
62
63 let cParam = searchParams.get("c");
64 if (cParam != null) {
65  var categories = unescapeHtml(cParam).split(';')
66  for (var i = 0; i < categories.length; i++) {
67   if (categories.at(i) !== '') {
68    var _tag = document.getElementById("searchMainCat_" + categories.at(i));
69    if (_tag != null) {
70     _tag.classList.remove('tag-ren');
71     _tag.classList.add('tag-ren_special');
72    }
73   }
74  }
75 }
76
77 let ppParam = searchParams.get("pp");
78 if (ppParam != null) {
79  search_current_page = parseInt(unescapeHtml(ppParam));
80 }
81
82 let piParam = searchParams.get("pi");
83 if (piParam != null) {
84  search_current_news = parseInt(unescapeHtml(piParam));
85 }
86
87 let pvParam = searchParams.get("pv");
88 if (pvParam != null) {
89  search_current_multimedia = parseInt(unescapeHtml(pvParam));
90 }
91
92 let pdParam = searchParams.get("pd");
93 if (pdParam != null) {
94  search_current_document = parseInt(unescapeHtml(pdParam));
95 }
96
97 let pTab = searchParams.get("t");
98 if (pTab != null) {
99  let tabId = '.btn-ren--tabs-slim#';
100  let tabIndex = parseInt(unescapeHtml(pTab));
101
102  switch (tabIndex) {
103   case 1:
104    tabId += 'tab-pages';
105    break;
106   case 2:
107    tabId += 'tab-news';
108    break;
109   case 3:
110    tabId += 'tab-multimedia';
111    break;
112   case 4:
113    tabId += 'tab-documents';
114    break;
115   default:
116    tabId += 'tab-pages';
117    break;
118  }
119
120  $(tabId).click();
121 }
122}
123
124function pageSearchByCat(category) {
125 search_current_page = 1;
126
127 let _category = document.getElementById("searchMainCat_" + category);
128 if (_category.classList.contains('tag-ren_special')) {
129  _category.classList.remove('tag-ren_special');
130  _category.classList.add('tag-ren');
131 }
132 else {
133  _category.classList.add('tag-ren_special');
134 }
135
136 let categories = [];
137 let selectedCategories = document.getElementsByClassName("tag-ren_special");
138 for (var i = 0; i < selectedCategories.length; i++) {
139  categories.push(selectedCategories.item(i).id.replace('searchMainCat_', ''));
140 }
141
142 let searchCategoriesUrl = getSeachBase() + '&c=' + encodeURI(categories.join(';'));
143 setBrowserLocation(searchCategoriesUrl);
144}
145
146function pageSearchByText() {
147 setBrowserLocation(getSeachBase());
148}
149
150function getSeachBase() {
151 let element = document.getElementById('ws_txt_search_global_principal');
152 let textToSearch = "";
153
154 if (element) {
155  textToSearch = escapeSearchTextToHTML(element.value);
156 }
157
158 return encodeURI(__searchPageUrl) + '?s=' + textToSearch + getPagingDetails();
159}
160
161function getPagingDetails() {
162 let tab = $('.btn-ren--tabs-slim.active').attr('id');
163 let _tab = 0;
164
165 switch (tab) {
166  case 'tab-pages':
167   _tab = 1;
168   break;
169  case 'tab-news':
170   _tab = 2;
171   break;
172  case 'tab-multimedia':
173   _tab = 3;
174   break;
175  case 'tab-documents':
176   _tab = 4;
177   break;
178  default:
179   _tab = 1;
180   break;
181 }
182
183 let params = '&pp=' + search_current_page
184  + '&l=' + search_items_per_page
185  + '&t=' + _tab
186  + '&pi=' + search_current_news
187  + '&pv=' + search_current_multimedia
188  + '&pd=' + search_current_document;
189
190 return encodeURI(params);
191}
192
193function searchMain() {
194 search_current_page = 1;
195 search_current_news = 1;
196 search_current_multimedia = 1;
197 search_current_document = 1;
198
199 let element = document.getElementById('ws_txt_search_global_principal');
200 if (element) {
201  let textToSearch = element.value;
202  setOnRecentSearches(textToSearch);
203
204  setBrowserLocation(getSeachBase() + '&c=' + getSearchCategory());
205 }
206}
207
208function getSearchCategory() {
209 let element = document.getElementsByClassName('tag-ren_special')[0];
210
211 if (element === undefined) {
212  return ''
213 }
214
215 return encodeURI(element.getAttribute('id').replace('searchMainCat_', ''));
216}
217
218function searchByRecent(text) {
219 search_current_page = 1;
220
221 setBrowserLocation(encodeURI(__searchPageUrl) + '?s=' + escapeSearchTextToHTML(text) + encodeURI(getPagingDetails()));
222}
223
224function goToSearchPage(searchpage) {
225 let element = document.getElementById('ws_txt_search_global');
226 if (element) {
227  let textToSearch = element.value.trim();
228
229  // Store the search term in recent searches
230  setOnRecentSearches(textToSearch);
231
232  // Validate and sanitize the searchpage URL
233  let safeSearchPage = validateAndSanitizeSearchPage(searchpage);
234  if (safeSearchPage) {
235   // Properly URL-encode the search parameter (not HTML escape)
236   const encodedSearchText = encodeURIComponent(textToSearch);
237
238   // Construct the final URL and redirect
239   setBrowserLocation(safeSearchPage + '?s=' + encodedSearchText);
240  } else {
241   console.error("Invalid or unsafe searchpage URL. Redirection aborted.");
242  }
243 }
244}
245
246function validateAndSanitizeSearchPage(searchpage) {
247 // Ensure the searchpage is a valid relative path
248 if (typeof searchpage !== "string" || searchpage.trim() === "") {
249  console.error("Invalid searchpage URL: Empty or non-string input.");
250  return null;
251 }
252
253 // Must be a relative path starting with /
254 if (!searchpage.startsWith("/")) {
255  console.error("Invalid searchpage URL: Must start with /");
256  return null;
257 }
258
259 // Prevent directory traversal
260 if (searchpage.includes("../") || searchpage.includes("..\\")) {
261  console.error("Invalid searchpage URL: Path traversal detected.");
262  return null;
263 }
264
265 // Ensure there are no protocol handlers or special characters
266 if (/[:?#&=]/.test(searchpage)) {
267  console.error("Invalid searchpage URL: Contains invalid characters.");
268  return null;
269 }
270
271 // Return the validated path
272 return searchpage;
273}
274
275
276function searchNextPage() {
277 search_current_page += 1;
278
279 searchNavigate()
280}
281
282function searchPreviousPage() {
283 search_current_page -= 1;
284
285 searchNavigate()
286}
287
288function searchNextImage() {
289 search_current_news += 1;
290
291 searchNavigate()
292}
293
294function searchPreviousImage() {
295 search_current_news -= 1;
296
297 searchNavigate()
298}
299
300function searchNextVideo() {
301 search_current_multimedia += 1;
302
303 searchNavigate()
304}
305
306function searchPreviousVideo() {
307 search_current_multimedia -= 1;
308
309 searchNavigate()
310}
311
312function searchNextDocument() {
313 search_current_document += 1;
314
315 searchNavigate()
316}
317
318function searchPreviousDocument() {
319 search_current_document -= 1;
320
321 searchNavigate()
322}
323
324function searchNavigate() {
325 setBrowserLocation(getSeachBase() + '&c=' + getSearchCategory());
326}
327
328function setBrowserLocation(location) {
329 // Validate the location is a simple relative path
330 if (!location || typeof location !== 'string') {
331  console.error('Invalid location: empty or not a string');
332  return;
333 }
334
335 // Reject absolute URLs or protocol-relative URLs
336 if (location.match(/^(?:[a-z]+:|\/\/)/i)) {
337  console.error('Invalid location: contains protocol or is protocol-relative');
338  return;
339 }
340
341 // Remove any path traversal attempts
342 const sanitizedLocation = location.replace(/\.\.\//g, '');
343
344 // Construct the full URL safely
345 const baseOrigin = document.location.origin;
346 const safeUrl = new URL(sanitizedLocation, baseOrigin).href;
347
348 // Optional: verify the URL still starts with our origin
349 if (!safeUrl.startsWith(baseOrigin)) {
350  console.error('Security error: URL would redirect outside origin');
351  return;
352 }
353
354 // Perform the redirect
355 window.location.assign(safeUrl);
356}
357
358
359function setPageRecentSearches() {
360 let searchHistoryDivs = document.getElementsByClassName('search-history');
361
362 if (searchHistoryDivs.length == 0)
363  return;
364
365 let searchHistoryDiv = searchHistoryDivs[0];
366 let searchHistoryRowDiv = searchHistoryDiv.childNodes[1];
367 let recentSearches = getRecentSearches();
368 let index = 0;
369
370 const fragment = new DocumentFragment();
371
372 if (recentSearches.length > 0) {
373  for (var i = 0; i < search_local_storage_cols; i++) {
374   addRecentSearchHistoryContainer(i, searchHistoryRowDiv);
375
376   for (var j = 0; j < search_local_storage_col_max; j++) {
377    if (index >= recentSearches.length) break;
378    let searchRecentText = unescapeHtml(recentSearches[parseInt(index)]);
379    addRecentSearchHistoryItem(searchRecentText, j, i);
380
381    index += 1;
382   }
383  }
384
385  document.querySelectorAll('[data-recent-search]').forEach(el => {
386   const linkText = el.getAttribute('data-recent-search');
387
388   el.addEventListener('click', (e) => {
389    e.preventDefault()
390    searchByRecent(linkText)
391   })
392  });
393 }
394}
395
396function addRecentSearchHistoryItem(text, id, parentId) {
397 let parentList = $(`#search-history-list-${parentId}`)
398 $(unescapeHtml(liElementTag), {
399  id: `search-history-list-item-${parentId}-${id}`,
400  appendTo: parentList
401 });
402
403 let parentItem = $(`#search-history-list-item-${parentId}-${id}`)
404 $(unescapeHtml(aElementTag), {
405  id: `search-history-list-item-url-${parentId}-${id}`,
406  href: "#",
407  text: text,
408  appendTo: parentItem
409 }).attr('data-recent-search', text);
410}
411
412function addRecentSearchHistoryContainer(id, parent) {
413 $(unescapeHtml(divElementTag), {
414  id: `search-history-container-${id}`,
415  "class": "col-12 col-sm-6 col-lg",
416  appendTo: parent
417 });
418
419 let parentContainer = $(`#search-history-container-${id}`)
420 $(unescapeHtml(ulElementTag), {
421  id: `search-history-list-${id}`,
422  "class": "history-list d-flex flex-column gap-2 mb-2",
423  appendTo: parentContainer
424 });
425}
426
427function setOnRecentSearches(text) {
428 let recentSearches = getRecentSearches();
429 if (recentSearches.length >= search_local_storage_max) {
430  removeOldestFromLocalStorage(search_local_storage_prefix);
431 }
432 addToLocalStorage(search_local_storage_prefix, unescapeHtml(text));
433}
434
435function getRecentSearches() {
436 return getAllFromLocalStorage(search_local_storage_prefix);
437}
438
439function escapeSearchTextToHTML(str) {
440 let result = str.replace(/[&<>"'\\/]/g, function (char) {
441  switch (char) {
442   case '&':
443    return '&amp;';
444   case '<':
445    return '&lt;';
446   case '>':
447    return '&gt;';
448   case '\\':
449    return '&#39;';
450   case '/':
451    return '&#x2F;';
452   default:
453    return char;
454  }
455 });
456
457 return result.replace('&amp;', "%26");
458}
459
460function unescapeHtml(str) {
461 var doc = new DOMParser().parseFromString(str, "text/html");
462 return doc.documentElement.textContent;
463}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.