Analvids/LegalPorno Enhancer

Adds extra functionality to Analvids (formerly known as LegalPorno) and Pornbox. Easily filter out unwanted categories. Also adds tags on top of every scene.

As of 2021-12-22. See the latest version.

  1. // ==UserScript==
  2. // @name Analvids/LegalPorno Enhancer
  3. // @namespace https://www.analvids.com/forum/viewtopic.php?f=96&t=24238
  4. // @description Adds extra functionality to Analvids (formerly known as LegalPorno) and Pornbox. Easily filter out unwanted categories. Also adds tags on top of every scene.
  5. // @match http*://*.analvids.com/*
  6. // @exclude http*://account.analvids.com/*
  7. // @match http*://*pornbox.com/*
  8. // @exclude http*://forum.pornbox.com/*
  9. // @version 1.2.15
  10. // @grant GM_getValue
  11. // @grant GM_setValue
  12. // @grant GM_addStyle
  13. // @run-at document-start
  14. // ==/UserScript==
  15.  
  16. const is_lp = !!window.location.href.match(/(analvids|pornworld)/);
  17.  
  18. let glo_filters = {
  19. studios: {
  20. 'Giorgio Grandi': true,
  21. 'Gonzo.com': true,
  22. 'NRX-Studio': true,
  23. "Giorgio's Lab": true,
  24. 'Yummy estudio': true,
  25. 'Busted T-Girls': true,
  26. 'VK Studio': true,
  27. 'Black in White': true,
  28. 'N&F studio': true,
  29. XfreaX: true,
  30. 'Interracial Vision': true,
  31. 'Angelo Godshack Original': true,
  32. 'Sineplex SOS': true,
  33. 'Sineplex CZ': true,
  34. 'PISSING E ANAL FANTASY': true,
  35. 'LATIN TEENS productions': true,
  36. 'Natasha Teen Productions': true,
  37. 'Mambo Perv': true,
  38. 'American Anal': true,
  39. 'Rock Corp': true,
  40. 'TheWonderToys Training Studio': true,
  41. 'Vira Gold Films': true,
  42. 'Anal Maniacs by Lady Dee': true,
  43. 'Eden does': true,
  44. 'Pineapples Studio': true,
  45. 'Porn World': false,
  46. 'Show Everything': false,
  47. },
  48. categories: {
  49. Piss: true,
  50. 'Piss Drink': true,
  51. Fisting: true,
  52. Prolapse: true,
  53. Trans: true,
  54. },
  55. };
  56.  
  57. const studio_colors = {
  58. 'Gonzo.com': { bg: '#e9000093', text: '#ffeeee' },
  59. 'Giorgio Grandi': { bg: '#2313d393', text: '#EEE' },
  60. 'Interracial Vision': { bg: '#24242493', text: '#e6e6e6' },
  61. 'American Anal': { bg: '#0C532693', text: '#d1f3e8' },
  62. "Giorgio's Lab": { bg: '#3DB8DC93', text: '#EEEEEE' },
  63. 'NRX-Studio': { bg: '#24f6d093', text: '#424d4b' },
  64. 'N&F studio': { bg: '#1091c493', text: '#EEEEEE' },
  65. 'Yummy estudio': { bg: '#0a11e493', text: '#ffff25' },
  66. 'Busted T-Girls': { bg: '#BDF61993', text: '#3485A6' },
  67. 'VK Studio': { bg: '#d7fbaa93', text: '#3a531b' },
  68. 'Black in White': { bg: '#EEEEEE93', text: '#000000' },
  69. 'N&F studio': { bg: '#8D15CA93', text: '#EEEEEE' },
  70. XfreaX: { bg: '#93076A93', text: '#EEEEEE' },
  71. 'Angelo Godshack Original': { bg: '#6ba2d493', text: '#EEEEEE' },
  72. 'Sineplex SOS': { bg: '#9C44EE93', text: '#EEEEEE' },
  73. 'Sineplex CZ': { bg: '#8A0EB393', text: '#EEEEEE' },
  74. 'PISSING E ANAL FANTASY': { bg: '#ff5e0093', text: '#fbf275' },
  75. 'LATIN TEENS productions': { bg: '#1AFB5493', text: '#555555' },
  76. 'Natasha Teen Productions': { bg: '#EE178893', text: '#EEEEEE' },
  77. 'Mambo Perv': { bg: '#C729A593', text: '#EEEEEE' },
  78. 'Rock Corp': { bg: '#6D164493', text: '#83C650' },
  79. 'TheWonderToys Training Studio': { bg: '#ACEACF93', text: '#5F546A' },
  80. 'Vira Gold Films': { bg: '#F7AF7C93', text: '#662a35' },
  81. 'Anal Maniacs by Lady Dee': { bg: '#4B703993', text: '#EEEEEE' },
  82. 'Eden does': { bg: '#378B0393', text: '#EEEEEE' },
  83. 'Pineapples Studio': { bg: '#674ABA93', text: '#EEEEEE' },
  84. 'Porn World': { bg: '#C1015A93', text: '#E2E316' },
  85. };
  86.  
  87. // Uncomment the following line to reset global filters
  88. // GM_setValue('user_filters', JSON.stringify(glo_filters));
  89.  
  90. validateUserFilters = filters => {
  91. if (!filters.studios || !filters.categories) return false;
  92. if (
  93. Object.keys(filters.studios).length !==
  94. Object.keys(glo_filters.studios).length
  95. )
  96. return false;
  97. if (
  98. Object.keys(filters.categories).length !==
  99. Object.keys(glo_filters.categories).length
  100. )
  101. return false;
  102. if (
  103. Object.keys(filters.categories)
  104. .sort()
  105. .some(
  106. (val, idx) => val !== Object.keys(glo_filters.categories).sort()[idx]
  107. )
  108. )
  109. return false;
  110. if (
  111. Object.keys(filters.studios)
  112. .sort()
  113. .some((val, idx) => val !== Object.keys(glo_filters.studios).sort()[idx])
  114. )
  115. return false;
  116. return true;
  117. };
  118.  
  119. try {
  120. const user_config = GM_getValue('user_filters');
  121. if (!user_config)
  122. throw new Error('No user filters found. Using default ones.');
  123. user_filters = JSON.parse(user_config);
  124. if (!validateUserFilters(user_filters))
  125. throw new Error('Invalid user settings.');
  126. glo_filters = user_filters;
  127. } catch (e) {}
  128.  
  129. const studios = {
  130. Interracial: 'Interracial Vision',
  131. 'Hard Porn World': 'Porn World',
  132. };
  133.  
  134. const icon_categories = {
  135. interracial: 'IR',
  136. 'double anal (DAP)': 'DAP',
  137. fisting: 'Fisting',
  138. prolapse: 'Prolapse',
  139. transsexual: 'Trans',
  140. trans: 'Trans',
  141. 'triple anal (TAP)': 'TAP',
  142. piss: 'Piss',
  143. squirting: 'Squirt',
  144. '3+ on 1': '3+on1',
  145. 'double vaginal (DPP)': 'DPP',
  146. 'first time': '1st',
  147. 'triple penetration': 'TP',
  148. '0% pussy': '0% Pussy',
  149. 'cum swallowing': 'Cum Swallow',
  150. 'piss drinking': 'Piss Drink',
  151. 'anal creampies': 'Anal Creampie',
  152. '1 on 1': '1on1',
  153. milf: 'Milf',
  154. 'facial cumshot': 'Facial',
  155. };
  156.  
  157. GM_addStyle(`
  158. .hiddenScene {
  159. display: none !important;
  160. }
  161.  
  162. .hide_element {
  163. display: none !important;
  164. }
  165.  
  166. .thumbnail-duration {
  167. top: 0 !important;
  168. right: 0 !important;
  169. left: unset !important;
  170. bottom: unset !important;
  171. margin: 5px !important;
  172. }
  173.  
  174. .enhanced_categories_container {
  175. width: 100%;
  176. display: flex;
  177. flex-wrap: wrap-reverse;
  178. position: absolute;
  179. bottom:0; left: 0;
  180. z-index: 3;
  181. padding: 3px 5px;
  182. }
  183.  
  184. .enchanced_icon {
  185. border-radius: 3px;
  186. background-color: #616161;
  187. color: #eee;
  188. opacity: 0.9;
  189. padding: 2px 7px;
  190. margin-right: 2px;
  191. margin-top: 2px;
  192. font-size: 13px;
  193. }
  194.  
  195. .enhanced--studio {
  196. position: absolute;
  197. top: 0;
  198. left: 0;
  199. z-index: 3;
  200. display: flex;
  201. margin: 4px 6px;
  202. font-family: sans-serif;
  203. font-weight: 600;
  204. font-size: 0.98em;
  205. background-color: #a76523c9;
  206. border-radius: 3px;
  207. padding: 2px 7px;
  208. color: white;
  209. // text-shadow: 1px 1px #00000080;
  210. margin-right: 4px;
  211. }
  212.  
  213. .enhanced_views_label {
  214. position: absolute;
  215. top: 28px;
  216. right: 5px;
  217. font-size: 11px;
  218. display: flex;
  219. }
  220.  
  221. .enhanced--views {
  222. background-color: rgba(102,102,102,0.6);
  223. padding: 2px 6px;
  224. border-radius: 3px;
  225. color: #fff;
  226. display: flex;
  227. height: 100%;
  228. align-items: center;
  229. justify-content: center;
  230. }
  231.  
  232. .enhanced--views > i {
  233. margin-right: 5px;
  234. }
  235.  
  236. .item__img:hover > div {
  237. display: none;
  238. }
  239.  
  240. .item__img-labels-bottom {
  241. top: 3px;
  242. right: 3px;
  243. left: unset;
  244. bottom: unset;
  245. display: flex
  246. }
  247.  
  248. .img-label {
  249. margin-top: unset;
  250. margin-left: 2px;
  251. }
  252.  
  253. .item__img-labels {
  254. display: flex;
  255. flex-direction: row-reverse;
  256. left: unset;
  257. right: 3px;
  258. top: 23px;
  259. }
  260.  
  261. /* Filter Css Begin */
  262. .filters_container_lp {
  263. margin-left: -15px;
  264. margin-right: -15px;
  265. }
  266.  
  267. .filters_container--main {
  268. width: 100%;
  269. display: flex;
  270. justify-content: center;
  271. background: linear-gradient(
  272. 0deg,
  273. #babcbc 0%,
  274. #dfe1e1 2%,
  275. #dfe1e1 98%,
  276. #babcbc 100%
  277. );
  278. }
  279.  
  280. .filters_card {
  281. margin: 0 25px;
  282. padding-bottom: 15px;
  283. display: flex;
  284. flex-direction: column;
  285. align-items: center;
  286. position: relative;
  287. }
  288.  
  289. .filters_selections {
  290. display: grid;
  291. grid-template-columns: repeat(3, 1fr);
  292. margin-bottom: 10px;
  293. }
  294.  
  295. .filters--divider {
  296. width: 1px;
  297. background-color: rgb(0, 0, 0, 0.25);
  298. height: 50px;
  299. margin-top: 15px;
  300. align-self: center;
  301. }
  302.  
  303. .filters--selection {
  304. padding: 1px 10px 0 0;
  305. min-width: 140px;
  306. display: flex;
  307. align-items: center;
  308. }
  309.  
  310. .filters--selection > label,
  311. .filters--selection > input[type="checkbox"] {
  312. margin: 0 2px 0 0;
  313. font-weight: bold;
  314. }
  315.  
  316. .fitlers--header {
  317. padding: 5px 0 5px 0;
  318. align-self: center;
  319. font-weight: bold;
  320. }
  321.  
  322. .enhanced_toggle {
  323. background: -webkit-linear-gradient(
  324. top,
  325. #a9a9a9 0%,
  326. #d97575 5%,
  327. #563434 100%
  328. ) !important;
  329. // height: 100%;
  330. border: 1px solid #722424 !important;
  331. color: white;
  332. padding: 7px 11px;
  333. font-weight: 700;
  334. border: none !important;
  335. }
  336.  
  337. .enhanced_toggle_pb {
  338. height: 100%;
  339. padding: 7px 11px;
  340. border-radius: 300px;
  341. position: absolute;
  342. margin-left: 4px;
  343. }
  344.  
  345. .enhanced_toggle_lp {
  346. border-radius: 200px;
  347. margin-left: 4px;
  348. }
  349.  
  350. .enhanced_toggle:hover {
  351. cursor: pointer;
  352. }
  353.  
  354. .enhanced_toggle > i {
  355. font-size: 12px;
  356. }
  357. /* Filter Css End */
  358.  
  359. .enhanced--sort {
  360. display: grid;
  361. grid-template-columns: 1fr 1fr;
  362. justify-items: center;
  363. grid-gap: 2px;
  364. position: absolute;
  365.  
  366. top: -4px;
  367. right: 210px;
  368. }
  369.  
  370. .enhanced--sort--navbar {
  371. right: 25px;
  372. top: 6px;
  373. }
  374.  
  375. .enhanced--sort > span {
  376. grid-column-end: span 2;
  377. color: #fff;
  378. }
  379.  
  380. .enhanced--sort > button {
  381. width: 70px;
  382. height: 23px;
  383. justify-content: center;
  384. align-items: center;
  385. text-align: center;
  386. padding: 0;
  387. margin: 0;
  388. }
  389.  
  390. .page-section {
  391. position: relative !important;
  392. }
  393. `);
  394.  
  395. const getSceneInfo = scene => {
  396. const info = {
  397. studio: null,
  398. categories: null,
  399. date: null,
  400. views: null,
  401. };
  402.  
  403. info.studio = scene.querySelector(
  404. '.rating-studio-name, a[href^="/application/studio/"]'
  405. );
  406. info.studio = info.studio ? info.studio.innerText : null;
  407. if (studios[info.studio]) {
  408. info.studio = studios[info.studio];
  409. }
  410. info.categories = [...scene.querySelectorAll('a[href*="niche/"]')]
  411. .filter(cat => cat.innerText && icon_categories[cat.innerText])
  412. .map(cat => icon_categories[cat.innerText])
  413. .sort();
  414. // info.categories = info.categories.filter(
  415. // cat => !(cat === 'Piss' && info.categories.includes('Piss Drink'))
  416. // );
  417. info.categories = Array.from(new Set(info.categories));
  418.  
  419. const views = scene.querySelector('.rating-views');
  420. const date = scene.querySelector('.glyphicon-calendar');
  421.  
  422. if (views) {
  423. info.views = parseInt(views.innerText.replace('VIEWS:', '').trim(), 10);
  424. }
  425. if (date) {
  426. try {
  427. info.date = new Date(
  428. date.parentElement.innerText.replace('RELEASE:', '').trim()
  429. );
  430. } catch (e) {}
  431. }
  432.  
  433. return info;
  434. };
  435.  
  436. const formatViews = n => {
  437. if (n >= 1e3 && n < 1e6) return +(n / 1e3).toFixed(0) + 'k';
  438. if (n >= 1e6 && n < 1e9) return +(n / 1e6).toFixed(0) + 'm';
  439. if (n >= 1e9 && n < 1e12) return +(n / 1e9).toFixed(0) + 'b';
  440. // if (n >= 1e12) return +(n / 1e12).toFixed(1) + "T";
  441. return n;
  442. };
  443.  
  444. const enhanceScene = scene => {
  445. // Remove icons from thumnail. ("4k" and "new")
  446. const icons = scene.querySelectorAll('.icon, .thumbnail-price');
  447. for (const icon of icons) {
  448. icon.classList.add('hide_element');
  449. }
  450.  
  451. const { studio, categories, views, date } = getSceneInfo(scene);
  452.  
  453. if (studio) {
  454. const studioLabel = document.createElement('div');
  455. studioLabel.classList.add('enhanced--studio');
  456. studioLabel.innerHTML = studio;
  457.  
  458. if (studio_colors[studio]) {
  459. studioLabel.style = `
  460. background-color: ${studio_colors[studio]['bg']}; color: ${studio_colors[studio]['text']};
  461. `;
  462. }
  463.  
  464. if (views) {
  465. const viewsLabel = document.createElement('div');
  466. viewsLabel.innerHTML = `
  467. <div class='enhanced--views'><i class='fa fa-eye'></i>${formatViews(
  468. views
  469. )}</div>`;
  470. viewsLabel.classList.add('enhanced_views_label');
  471. if (scene.querySelector('.thumbnail-image')) {
  472. scene.querySelector('.thumbnail-image').appendChild(viewsLabel);
  473. }
  474. }
  475.  
  476. // studioLabel.classList.add('enhanced_title_tags');
  477. scene
  478. .querySelector('.thumbnail-image, .item__img')
  479. .appendChild(studioLabel);
  480. }
  481. if (categories.length) {
  482. const cat_div = document.createElement('div');
  483. cat_div.classList.add('enhanced_categories_container');
  484. for (const cat of categories) {
  485. const icon = document.createElement('div');
  486. icon.classList.add('enchanced_icon');
  487. icon.innerHTML = cat;
  488. cat_div.appendChild(icon);
  489. }
  490.  
  491. if (scene.querySelector('.thumbnail-image, .item__img')) {
  492. scene.querySelector('.thumbnail-image, .item__img').appendChild(cat_div);
  493. }
  494. }
  495. };
  496.  
  497. const isStudioFiltered = studio => {
  498. for (const key of Object.keys(glo_filters.studios)) {
  499. if (studio && studio.includes(key) && glo_filters.studios[key])
  500. return false;
  501. }
  502. return true;
  503. };
  504.  
  505. const isSceneFiltered = scene => {
  506. const { studio, categories, views, date } = getSceneInfo(scene);
  507.  
  508. if (!glo_filters.studios['Show Everything']) {
  509. if (isStudioFiltered(studio)) return true;
  510. }
  511.  
  512. for (const key of Object.keys(glo_filters.categories)) {
  513. if (categories && categories.includes(key) && !glo_filters.categories[key])
  514. return true;
  515. }
  516.  
  517. return false;
  518. };
  519.  
  520. const filterScene = scene => {
  521. if (isSceneFiltered(scene)) {
  522. scene.classList.add('hiddenScene');
  523. }
  524. };
  525.  
  526. const updateFilters = () => {
  527. GM_setValue('user_filters', JSON.stringify(glo_filters));
  528. const scenes = document.querySelectorAll('.thumbnail, .block-item');
  529. for (const scene of scenes) {
  530. if (scene.classList.contains('hiddenScene'))
  531. scene.classList.remove('hiddenScene');
  532. filterScene(scene);
  533. }
  534. };
  535.  
  536. const getStudiosCheckboxes = () => {
  537. return [
  538. ...document.querySelectorAll(
  539. 'input[name="studios"]:not(input[id="Show Everything"])'
  540. ),
  541. ];
  542. };
  543.  
  544. const createFilterElement = () => {
  545. const { studios, categories } = glo_filters;
  546.  
  547. const studioHtml = Object.keys(studios).reduce(
  548. (acc, studio) =>
  549. (acc += `<div class="filters--selection">
  550. <input type="checkbox" name="studios" id="${studio}"
  551. ${studios[studio] ? 'checked="checked"' : ''}
  552. ${
  553. studios['Show Everything'] && studio !== 'Show Everything'
  554. ? 'disabled=true"'
  555. : ''
  556. }
  557. />
  558. <label for="${studio}"
  559. ${studio == 'Show Everything' ? 'style= "color:#f83600;"' : ''}>
  560. ${studio}</label>
  561. </div>`),
  562. ''
  563. );
  564.  
  565. const categoriesHtml = Object.keys(categories).reduce(
  566. (acc, cat) =>
  567. (acc += `<div class="filters--selection">
  568. <input type="checkbox" name="categories" id="${cat}"
  569. ${categories[cat] ? 'checked="checked"' : ''}
  570. />
  571. <label for="${cat}">${cat}</label>
  572. </div>`),
  573. ''
  574. );
  575.  
  576. const form = document.createElement('form');
  577. form.classList.add('filters_container', 'hide_element');
  578. if (is_lp) form.classList.add('filters_container_lp');
  579. form.innerHTML = `<div class="filters_container--main">
  580. <div class="filters_card">
  581. <div class="fitlers--header">Studios:</div>
  582. <div class="filters_selections">
  583. ${studioHtml}
  584. </div>
  585. <div>
  586. <input type="button" value="Select All">
  587. <input type="button" value="Clear">
  588. </div>
  589. </div>
  590. <!-- -->
  591. <div class="filters--divider"></div>
  592. <!-- -->
  593. <div class="filters_card">
  594. <div class="fitlers--header">Categories:</div>
  595. <div class="filters_selections">
  596. ${categoriesHtml}
  597. </div>
  598. </div>
  599. </div>`;
  600.  
  601. form.addEventListener('click', e => {
  602. if (!e.target.type) return;
  603.  
  604. if (e.target.type == 'button') {
  605. if (e.target.value === 'Select All') {
  606. getStudiosCheckboxes().forEach(n => {
  607. n.checked = true;
  608. });
  609.  
  610. Object.keys(glo_filters.studios).forEach(studio => {
  611. if (studio === 'Show Everything') return;
  612. glo_filters.studios[studio] = true;
  613. });
  614. }
  615. if (e.target.value === 'Clear') {
  616. getStudiosCheckboxes().forEach(n => {
  617. n.checked = false;
  618. });
  619. Object.keys(glo_filters.studios).forEach(studio => {
  620. glo_filters.studios[studio] = false;
  621. });
  622. }
  623. // glo_filters[e.target.name][e.target.id] = e.target.checked;
  624. }
  625.  
  626. if (e.target.type == 'checkbox') {
  627. glo_filters[e.target.name][e.target.id] = e.target.checked;
  628. }
  629.  
  630. if (e.target.id === 'Show Everything') {
  631. getStudiosCheckboxes().forEach(el => {
  632. el.disabled = !el.disabled;
  633. });
  634. }
  635.  
  636. updateFilters();
  637. });
  638.  
  639. const lp_header = document.querySelector('.header');
  640. const pb_header = document.querySelector('#wrap-container');
  641.  
  642. if (lp_header) lp_header.insertBefore(form, lp_header.childNodes[2]);
  643. if (pb_header) pb_header.insertBefore(form, pb_header.childNodes[0]);
  644. createFilterToggle();
  645. };
  646.  
  647. const createFilterToggle = () => {
  648. const toggleFilterBtn = document.createElement('button');
  649. toggleFilterBtn.classList.add('enhanced_toggle');
  650. toggleFilterBtn.classList.add(`enhanced_toggle_${is_lp ? 'lp' : 'pb'}`);
  651.  
  652. toggleFilterBtn.innerHTML = `<i class="fa fa-filter"></i>`;
  653.  
  654. toggleFilterBtn.addEventListener('click', () => {
  655. const filters_container = document.querySelector('.filters_container');
  656. if (filters_container) {
  657. filters_container.classList.toggle('hide_element');
  658. }
  659. });
  660.  
  661. const search_container = document.querySelector(
  662. '.nav-search-container, .header-block:nth-of-type(3)'
  663. );
  664. is_lp ? (search_container.style = 'display: flex;') : null;
  665. search_container.appendChild(toggleFilterBtn);
  666. };
  667.  
  668. const callback = mutationsList => {
  669. for (let mutation of mutationsList) {
  670. for (const node of mutation.addedNodes) {
  671. if (node.nodeType === 1) {
  672. if (node.nodeName === 'DIV') {
  673. if (
  674. node.classList.contains('block-item') ||
  675. node.classList.contains('thumbnail')
  676. ) {
  677. enhanceScene(node);
  678. filterScene(node);
  679. }
  680. }
  681. }
  682. }
  683. }
  684. };
  685.  
  686. const config = { childList: true, subtree: true, attributes: true };
  687. const observer = new MutationObserver(callback);
  688. observer.observe(window.document, config);
  689.  
  690. const sortScenes = ({ date = false, views = false, asc = true } = {}) => {
  691. const node = document.querySelector('.thumbnails');
  692. [...node.children]
  693. .sort((a, b) => {
  694. const infoA = getSceneInfo(a);
  695. const infoB = getSceneInfo(b);
  696.  
  697. let order = -1;
  698.  
  699. if (date) {
  700. order = infoA.date > infoB.date ? -1 : 1;
  701. } else if (views) {
  702. order = infoA.views > infoB.views ? -1 : 1;
  703. } else {
  704. order = 0;
  705. }
  706.  
  707. if (a.classList.contains('button--load-more')) return 0;
  708. if (b.classList.contains('button--load-more')) return 0;
  709.  
  710. return !asc ? order : order * -1;
  711. })
  712. .map(scene => {
  713. node.appendChild(scene);
  714. node.appendChild(document.createTextNode(' '));
  715. });
  716. };
  717.  
  718. const sortBtns = () => {
  719. const sortDiv = document.createElement('div');
  720. sortDiv.classList.add('enhanced--sort');
  721. sortDiv.innerHTML = `
  722. <span>Sort By:</span>
  723. <button asc="false">Date</button>
  724. <button asc="false">Views</button>
  725. `;
  726.  
  727. sortDiv.addEventListener('click', e => {
  728. if (e.target.tagName === 'BUTTON') {
  729. const asc = e.target.getAttribute('asc') === 'true';
  730. e.target.setAttribute('asc', !asc);
  731. const sortObj = { asc };
  732. sortObj[e.target.innerText.toLowerCase()] = true;
  733. sortScenes(sortObj);
  734. }
  735. });
  736.  
  737. const navbar = document.querySelectorAll('.navbar > .container-fluid');
  738. if (navbar.length) {
  739. navbar[navbar.length - 1].appendChild(sortDiv);
  740. sortDiv.classList.add('enhanced--sort--navbar');
  741. return;
  742. }
  743.  
  744. const cont = document.querySelector('.page-section');
  745. if (cont) {
  746. sortDiv.children[0].style = 'color: #000;';
  747. cont.appendChild(sortDiv);
  748. }
  749. };
  750.  
  751. document.addEventListener('DOMContentLoaded', () => {
  752. if (!is_lp && !document.querySelector('.nav-search-container')) return;
  753. createFilterElement();
  754. sortBtns();
  755.  
  756. const nodes = document.querySelectorAll('.block-item, .thumbnail');
  757. [...nodes].map(node => {
  758. enhanceScene(node);
  759. filterScene(node);
  760. });
  761. });