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.

La data de 22-12-2021. Vezi ultima versiune.

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