Wykop XS 3.0

Wykop XS służy do wspomagania działania stylu "Wykop X Style 3", który jest sugerowany do poprawnego działania niniejszego skryptu. Wykop X Style znajdziesz na http://styl.wykopx.pl

Mint 2025.01.22.. Lásd a legutóbbi verzió

  1. // ==UserScript==
  2. // @name Wykop XS 3.0
  3. // @name:pl Wykop XS 3.0
  4. // @name:en Wykop XS 3.0
  5.  
  6. // @version 3.0.81
  7.  
  8. // @description Wykop XS służy do wspomagania działania stylu "Wykop X Style 3", który jest sugerowany do poprawnego działania niniejszego skryptu. Wykop X Style znajdziesz na http://styl.wykopx.pl
  9. // @description:en Wykop XS is a helper script for userstyle "Wykop X Style 3" which modifies wykop.pl website and make it easier to use adding enhancements and new features. Check it out here: http://styl.wykopx.pl
  10.  
  11.  
  12. // Chcesz wesprzeć projekt Wykop X? Postaw kawkę:
  13. // @contributionURL https://buycoffee.to/wykopx
  14.  
  15. // @author Wykop X <wykopx@gmail.com>
  16.  
  17.  
  18.  
  19.  
  20.  
  21.  
  22.  
  23.  
  24.  
  25. // @match https://wykop.pl/*
  26. // @match https://github.com/wykopx/*
  27.  
  28. // @supportURL http://wykop.pl/tag/wykopx
  29. // @namespace Violentmonkey Scripts
  30. // @compatible chrome, firefox, opera, safari, edge
  31. // @license No License
  32. // @icon https://www.google.com/s2/favicons?sz=64&domain=wykop.pl
  33.  
  34.  
  35. // @require https://unpkg.com/localforage@1.10.0/dist/localforage.min.js
  36. // @require https://cdn.jsdelivr.net/npm/dayjs@1.11.10/dayjs.min.js
  37. // @require https://cdn.jsdelivr.net/npm/dayjs@1.11.10/locale/pl.js
  38. // @require https://cdn.jsdelivr.net/npm/dayjs@1.11.10/plugin/relativeTime.js
  39.  
  40.  
  41.  
  42.  
  43. // ==/UserScript==
  44.  
  45.  
  46. (async function ()
  47. {
  48. 'use strict';
  49.  
  50.  
  51. const currentVersion = "3.0.80";
  52. let dev = false;
  53.  
  54. const promoString = " - Wykop XS / #wykopx";
  55.  
  56. const root = document.documentElement;
  57. const head = document.head;
  58. const body = document.body;
  59. const bodySection = body.querySelector("section");
  60.  
  61. dayjs.locale("pl");
  62. dayjs.extend(window.dayjs_plugin_relativeTime); //dayjs.extend(relativeTime); // https://day.js.org/docs/en/plugin/relative-time // https://www.jsdelivr.com/package/npm/dayjs?tab=files&path=plugin
  63.  
  64.  
  65. // github
  66. if (!bodySection)
  67. {
  68. const openGitHubSidebar = () =>
  69. {
  70. document.querySelector('div#wiki-wrapper div#wiki-content button.js-wiki-more-pages-link')?.click();
  71. };
  72.  
  73. openGitHubSidebar();
  74. window.addEventListener('load', openGitHubSidebar);
  75. window.addEventListener('pageshow', openGitHubSidebar);
  76. // window.addEventListener('popstate', openGitHubSidebar);
  77. // window.addEventListener('hashchange', openGitHubSidebar);
  78. // window.addEventListener('pagehide', openGitHubSidebar);
  79. // window.addEventListener('beforeunload', openGitHubSidebar);
  80. // window.addEventListener('unload', openGitHubSidebar);
  81. if (window.navigation)
  82. {
  83. window.navigation.addEventListener('navigate', function ()
  84. {
  85. openGitHubSidebar();
  86. });
  87. }
  88. }
  89. // wykop
  90. else
  91. {
  92. const wykopxSettings = getComputedStyle(head); // getComputedStyle(document.documentElement) -- nie działa, nie wczytuje właściwości z :root
  93. const settings = {};
  94.  
  95. const styleElement = document.createElement('style');
  96. styleElement.id = "wykopxs";
  97. let CSS = "";
  98.  
  99. function setSettingsValueFromCSSProperty(settingName, defaultValueForWykopXS = true, propertyValueInsteadOfBoolean = false)
  100. {
  101. if (propertyValueInsteadOfBoolean) settings[settingName] = wykopxSettings.getPropertyValue(`--${settingName}`) ? wykopxSettings.getPropertyValue(`--${settingName}`).trim() : defaultValueForWykopXS;
  102. else settings[settingName] = wykopxSettings.getPropertyValue(`--${settingName}`) ? wykopxSettings.getPropertyValue(`--${settingName}`).trim() === '1' : defaultValueForWykopXS;
  103. }
  104.  
  105. setSettingsValueFromCSSProperty("WykopXSEnabled");
  106. if (settings.WykopXSEnabled == false) return;
  107. /* WYKOP XS HEADER */
  108.  
  109.  
  110.  
  111. let loggedUser = {
  112. //data: null,
  113. username: null // loggedUser.username -> nazwa zalogowanego uzytkownika
  114. };
  115. let wxs_modal = null;
  116.  
  117. let loadTime = dayjs();
  118.  
  119. // wykop_xs_mikroczat.user.js -MIKROCZAT/LISTA PLUSUJĄCYCH - settings
  120. setSettingsValueFromCSSProperty("entryVotersListEnable"); // włącza pokazywanie listy plusujących z Wykop X Style
  121. setSettingsValueFromCSSProperty("entryVotersListExpandIfLessThan", 50, true);
  122. setSettingsValueFromCSSProperty("hideAds"); // blokuje wszystkie reklamy na wykopie
  123.  
  124. if (settings.entryVotersListEnable)
  125. {
  126. // entryVotersListExpandIfLessThan - domyślnie Wykop pokazywał 5 osób, które zaplusowały.
  127. // Możesz zmienić tę wartość na np. 10 albo 25. Jeśli wpis ma mniej plusów niż ta liczba, zostaną od razu wyświetleni wszyscy plusujący bez przycisku "+15 INNYCH"
  128. if (!settings.entryVotersListExpandIfLessThan) settings.entryVotersListExpandIfLessThan = 20;
  129. settings.votersFollow = true; // pokazuje 🔔 przed użytkownikami, których obserwujesz
  130. settings.votersBlacklist = true; // pokazuje ⛔ przed użytkownikami, których blokujesz
  131. settings.votersBanned = true; // pokazuje użytkowników z aktywnym banem w kolorze i z ikonką 🍌
  132. settings.votersSuspended = true; // pokazuje ✖ przed kontami, które są w trakcie usuwania
  133. settings.votersRemoved = true; // pokazuje ✖ przed kontami, które są usunięte
  134. settings.votersGenderF = false; // pokazuje różową kropkę przed kobietami
  135. settings.votersGenderM = false; // pokazuje niebieską kropkę przed mężczyznami
  136. settings.votersColorGreen = true; // pokazuje zielonki w kolorze
  137. settings.votersColorOrange = false; // pokazuje pomarańczowych użytkowników w kolorze
  138. settings.votersColorBurgundy = true; // pokazuje użytkowników bordo w kolorze
  139. settings.votersFollowFirst = true; // pokazuje użytkowników, których obserwujesz pierwszych na liście
  140. settings.votersBlackFirst = false; // pokazuje plusy od moderacji pierwsze na liście (konta typu @wykop, @m__b, @a__s itd.)
  141. settings.votersBurgundyFirst = false; // pokazuje użytkowników bordo pierwszych na liście
  142. settings.votersOrangeFirst = false; // pokazuje zielonki pierwszych na liście
  143. settings.votersGreenFirst = false; // pokazuje pomarańczki pierwszych na liście
  144. settings.votersBlacklistLast = false; // pokazuje użytkowników, których zablokowałeś na końcu listy
  145. settings.votersRemovedLast = false; // pokazuje usunięte konta na końcu listy
  146. settings.votersBannedLast = false; // pokazuje zbanowanych na końcu listy
  147. settings.votersSuspendedLast = false; // pokazuje konta w trakcie usuwania na końcu listy
  148. }
  149.  
  150. settings.hideShareButton = true; // ukrywa przycisk "Udostępnij"
  151. settings.showFavouriteButton = true; // pokazuje przycisk "Dodaj do ulubionych" (samą gwiazdkę)
  152. settings.showFavouriteButtonLabel = true; // pokazuje oprócz gwiazdki także tekst "Ulubione"
  153. settings.addCommentPlusWhenVotingOnEntry = false; // gdy plusujesz wpis, dodaje komentarz "+1"
  154. settings.addCommentPlusWhenVotingOnComment = false; // gdy plusujesz komentarz, dodaje komentarz "+1"
  155. settings.showAnimatedAvatars = true; // pokazuje animowane avatary
  156.  
  157.  
  158. settings.version = (getComputedStyle(bodySection).getPropertyValue("--version").trim().slice(1, -1)); // "2.48";
  159. settings.versor = (getComputedStyle(bodySection).getPropertyValue("--versor").trim().slice(1, -1)); // "style", "blank", "block"
  160. settings.xblocker = (getComputedStyle(bodySection).getPropertyValue("--xblocker").trim().slice(1, -1)); // "2.48";
  161.  
  162.  
  163.  
  164. if (!dev) dev = setSettingsValueFromCSSProperty("wxsDev", false);
  165.  
  166.  
  167.  
  168.  
  169.  
  170. setSettingsValueFromCSSProperty("WykopXStyleEnabled", false);
  171. setSettingsValueFromCSSProperty("hitsInTopNavJS");
  172. setSettingsValueFromCSSProperty("quickLinksEnable");
  173. setSettingsValueFromCSSProperty("myWykopInTopNavJS");
  174. setSettingsValueFromCSSProperty("favoritesInTopNavJS");
  175. setSettingsValueFromCSSProperty("imageUploaderEnable", false); // https://github.com/wykopx/WykopX/wiki/X-Wklejanie-obrazkow-ze-schowka
  176. setSettingsValueFromCSSProperty("addNewLinkInTopNavJS");
  177. setSettingsValueFromCSSProperty("disableNewLinkEditorPastedTextLimit");
  178. setSettingsValueFromCSSProperty("autoOpenMoreContentEverywhere");
  179. setSettingsValueFromCSSProperty("autoOpenSpoilersEverywhere");
  180. setSettingsValueFromCSSProperty("observedTagsInRightSidebarEnable");
  181. setSettingsValueFromCSSProperty("linkVoteDownButton");
  182. setSettingsValueFromCSSProperty("infiniteScrollEntriesEnabled");
  183. setSettingsValueFromCSSProperty("infiniteScrollLinksEnabled");
  184. setSettingsValueFromCSSProperty("editorShowMyUsername");
  185. setSettingsValueFromCSSProperty("editorShowMyUsernameOnSendButton");
  186. setSettingsValueFromCSSProperty("haveBanDisableTextarea");
  187.  
  188. // ARCHIWUM X
  189. setSettingsValueFromCSSProperty("wxsArchiveXNewestEntry", false);
  190. if (settings.wxsArchiveXNewestEntry) settings.wxsArchiveXNewestEntryRefresh = wykopxSettings.getPropertyValue("--wxsArchiveXNewestEntryRefresh") ? parseInt(wykopxSettings.getPropertyValue("--wxsArchiveXNewestEntryRefresh")) : 15000;
  191.  
  192. // PRZEŁĄCZNIKI
  193. setSettingsValueFromCSSProperty("wxsSwitchesEnable", false);
  194. if (settings.wxsSwitchesEnable)
  195. {
  196. setSettingsValueFromCSSProperty("wxsSwitchPhotoViewer");
  197. setSettingsValueFromCSSProperty("wxsSwitchImages");
  198. setSettingsValueFromCSSProperty("wxsSwitchYouTube");
  199. setSettingsValueFromCSSProperty("wxsSwitchAdult");
  200. setSettingsValueFromCSSProperty("wxsSwitchNSFW");
  201. setSettingsValueFromCSSProperty("wxsSwitchTags");
  202. setSettingsValueFromCSSProperty("wxsSwitchByUserColor");
  203. setSettingsValueFromCSSProperty("wxsSwitchByUserGender");
  204. }
  205.  
  206.  
  207. setSettingsValueFromCSSProperty("removeAnnoyancesEnable");
  208. if (settings.removeAnnoyancesEnable)
  209. {
  210. setSettingsValueFromCSSProperty("removeAnnoyancesIframes");
  211. setSettingsValueFromCSSProperty("removeAnnoyancesScripts");
  212. setSettingsValueFromCSSProperty("removeAnnoyancesAds");
  213. setSettingsValueFromCSSProperty("removeAnnoyancesGDPR");
  214. }
  215.  
  216.  
  217.  
  218.  
  219.  
  220.  
  221. // WYKOP OBJECTS INTERSECTION OBSERVER
  222. let IntersectionObserverEnabled = false;
  223. setSettingsValueFromCSSProperty("intersectionObserverRootMargin");
  224. setSettingsValueFromCSSProperty("linkToVideoDuration");
  225. setSettingsValueFromCSSProperty("entryWithVideoDuration");
  226.  
  227. if (settings.linkToVideoDuration || settings.entryWithVideoDuration)
  228. {
  229. IntersectionObserverEnabled = true;
  230. }
  231.  
  232. setSettingsValueFromCSSProperty("checkLinkVotesEnable");
  233. if (settings.checkLinkVotesEnable)
  234. {
  235. IntersectionObserverEnabled = true;
  236. setSettingsValueFromCSSProperty("checkLinkVotesPerHour");
  237. setSettingsValueFromCSSProperty("checkLinkCommentsPerHour");
  238. }
  239.  
  240. // voting explosion
  241. setSettingsValueFromCSSProperty("votingExplosionEnable", false);
  242.  
  243. // checkPluses()
  244. let votesFetchingLimitMinimumVotes = 1;
  245. let votesFetchingLimitMaximumHoursOld = 48;
  246. let votesFetchingFirstDelayInSeconds = 1; // seconds
  247. let votesFetchingOngoingDelayInSeconds = 990; // seconds
  248.  
  249. let votesFetchingHigherFrequencyLimitMinimumVotes = 30;
  250. let votesFetchingHigherFrequencyLimitMaximumHoursOld = 24;
  251. let votesFetchingHigherFrequencyDelayInSeconds = 990; // seconds
  252.  
  253. setSettingsValueFromCSSProperty("checkEntryPlusesWhenVoting");
  254. setSettingsValueFromCSSProperty("checkEntryPlusesEnable");
  255. setSettingsValueFromCSSProperty("prefixBeforePlusesCount", "brak", true); // domyslnie puste, dodajemy plus przed liczbą plusów
  256.  
  257.  
  258. const prefixBeforePlusesCountMap = new Map([
  259. ['brak', ''],
  260. ['plus', '+'], // domyslnie
  261. ['emoji_serce', '💚'],
  262. ['emoji_index_pointing_up', '☝'],
  263. ['emoji_thumbs_up', '👍'],
  264. ['emoji_backhand_index_pointing_up', '👆'],
  265. ['emoji_upwards_button', '🔼'],
  266. ['emoji_up_arrow', '⬆'],
  267. ['emoji_up_right_arrow', '↗'],
  268. ['emoji_up_left_arrow', '↖'],
  269. ['emoji_right_arrow_curving_up', '⤴'],
  270. ['emoji_heavy_tick', '✔'],
  271. ['emoji_plus_sign', '➕'],
  272. ['emoji_red_triangle_pointed_up', '🔺']
  273. ]);
  274. settings.prefixBeforePlusesCount = prefixBeforePlusesCountMap.get(settings.prefixBeforePlusesCount);
  275.  
  276. setSettingsValueFromCSSProperty("prefixBeforeMinusesCount", "minus", true); // domyślnie minus i tak zostawiamy
  277. const prefixBeforeMinusesCountMap = new Map([
  278. ['brak', ''],
  279. ['minus', '-'], // domyslnie
  280. ['emoji_cross_mark', '❌'],
  281. ['emoji_backhand_index_pointing_down', '👇'],
  282. ['emoji_thumbs_down', '👎'],
  283. ['emoji_downwards_button', '🔽'],
  284. ['emoji_down_arrow', '⬇'],
  285. ['emoji_down_right_arrow', '↘'],
  286. ['emoji_down_left_arrow', '↙'],
  287. ['emoji_right_arrow_curving_down', '⤵'],
  288. ['emoji_minus_sign', '➖'],
  289. ['emoji_red_triangle_pointed_down', '🔻']
  290. ]);
  291. settings.prefixBeforeMinusesCount = prefixBeforeMinusesCountMap.get(settings.prefixBeforeMinusesCount);
  292.  
  293. if (settings.checkEntryPlusesEnable)
  294. {
  295. IntersectionObserverEnabled = true;
  296. setSettingsValueFromCSSProperty("checkEntryPlusesPerHour");
  297. setSettingsValueFromCSSProperty("checkEntryCommentsPerHour");
  298. setSettingsValueFromCSSProperty("checkEntryPlusesForVotingGame");
  299. }
  300.  
  301.  
  302. // SPRAWDZANIE UZYTKOWNIKOW KTORZY CIE BLOKUJA
  303. settings.authorBlocksYouCheckingEnable = true;
  304.  
  305.  
  306.  
  307.  
  308. // LOCAL STORAGE
  309. let localStorageMirkoukrywacz = null;
  310. let localStorageNotatkowator = null;
  311. let localStorageUserLabels = null;
  312.  
  313.  
  314. // LOCALSTORAGE
  315. const localStorageFirstDailyIDs = localforage.createInstance({
  316. driver: localforage.LOCALSTORAGE,
  317. name: "wykopx",
  318. storeName: "firstDailyIDs",
  319. });
  320.  
  321.  
  322.  
  323.  
  324. setSettingsValueFromCSSProperty("linkThumbnail", "poprawej", true); // "poprawej", "polewej", "niepokazuj"
  325.  
  326. setSettingsValueFromCSSProperty("actionBoxEnable");
  327. if (settings.actionBoxEnable)
  328. {
  329. IntersectionObserverEnabled = true;
  330. setSettingsValueFromCSSProperty("filterUserComments");
  331. setSettingsValueFromCSSProperty("filterUserReplies");
  332. setSettingsValueFromCSSProperty("mirkoukrywaczEnable");
  333. if (settings.mirkoukrywaczEnable)
  334. {
  335. setSettingsValueFromCSSProperty("mirkoukrywaczMinimizedGrayedOut");
  336. setSettingsValueFromCSSProperty("mirkoukrywaczMinimizeEntries");
  337. setSettingsValueFromCSSProperty("mirkoukrywaczMinimizeComments");
  338. setSettingsValueFromCSSProperty("mirkoukrywaczHideEntries");
  339. setSettingsValueFromCSSProperty("mirkoukrywaczHideComments");
  340. setSettingsValueFromCSSProperty("mirkoukrywaczHideLinks");
  341. setSettingsValueFromCSSProperty("mirkoukrywaczSaveEntries");
  342. setSettingsValueFromCSSProperty("mirkoukrywaczSaveComments");
  343. }
  344.  
  345. CSS += `
  346. /* ACTION BOX */
  347. section .wxs_menu_action_box
  348. {
  349. --buttonsBorderRadius: 5px;
  350. width: fit-content;
  351. position: absolute;
  352. height: 30px;
  353. border-style: solid;
  354. border-color: var(--blackOpacity01, rgb(125 125 125 / 1));
  355. color: var(--blackOpacity02, rgb(125 125 125 / 1));
  356. display: flex;
  357. flex-direction: row;
  358. justify-content: space-between;
  359. font-size: 11px;
  360. z-index: 1;
  361. opacity: 1!important;
  362. transition: opacity 0.5s linear!important;
  363. }
  364. section .wxs_menu_action_box:hover
  365. {
  366. background-color: var(--contentBackgroundColor, rgb(0 0 0 / 0.2));
  367. }
  368. @starting-style
  369. {
  370. section .wxs_menu_action_box
  371. {
  372. opacity: 0!important;
  373. }
  374. }
  375. /* WE WPISACH I KOMENTARZACH */
  376. section.entry .wxs_menu_action_box
  377. {
  378. border-radius: 0px 0px var(--buttonsBorderRadius, 4px) var(--buttonsBorderRadius, 4px);
  379. border-width: 0px 1px 1px 1px;
  380. right: 140px;
  381. }
  382.  
  383. section.entry:not(.reply) .wxs_menu_action_box
  384. {
  385. top: 0px;
  386. }
  387.  
  388. /* w znaleziskach */
  389. section.link-block .wxs_menu_action_box
  390. {
  391. border-color: var(--blackOpacity005, rgb(125 125 125 / 1));
  392. border-radius: var(--buttonsBorderRadius, 4px) var(--buttonsBorderRadius, 4px) 0px 0px;
  393. border-width: 1px 1px 0px 1px;
  394. bottom: 0px;
  395. top: unset;
  396.  
  397. /* zmienione gdy linkThumbnail == "polewej" */
  398. right: 18px;
  399. left: unset;
  400. }
  401.  
  402.  
  403.  
  404. /* kolejność przycisków zmienione gdy linkThumbnail == "polewej" */
  405. section.link-block .wxs_menu_action_box .wxs_filter_off { order: 1; }
  406. section.link-block .wxs_menu_action_box .wxs_filter_on_user { order: 2; }
  407. section.link-block .wxs_menu_action_box .wxs_hide { order: 3; }
  408.  
  409. /* MOBILE */
  410. @media (max-width: 640px)
  411. {
  412. /* WXS ACTION MENU BUTTONS */
  413. section.link-block .wxs_menu_action_box
  414. {
  415. right: unset!important;
  416. left: 40%!important;
  417. }
  418. }
  419. `;
  420.  
  421. if (settings.linkThumbnail == "polewej")
  422. {
  423. CSS += `@media (max-width: 640px)
  424. {
  425. section.link-block .wxs_menu_action_box .wxs_filter_on_user { order: 2!important; }
  426. section.link-block .wxs_menu_action_box .wxs_filter_off { order: 3!important; }
  427. section.link-block .wxs_menu_action_box .wxs_hide { order: 1!important; }
  428. }
  429. /* WERSJA PC */
  430. @media (min-width: 641px)
  431. {
  432. /* WXS ACTION MENU BUTTONS */
  433. section.link-block .wxs_menu_action_box
  434. {
  435. right: unset!important;
  436. left: 122px!important;
  437. }
  438. section.link-block .wxs_menu_action_box .wxs_filter_on_user { order: 2!important; }
  439. section.link-block .wxs_menu_action_box .wxs_filter_off { order: 3!important; }
  440. section.link-block .wxs_menu_action_box .wxs_hide { order: 1!important; }
  441. }
  442. `;
  443. };
  444.  
  445.  
  446. CSS += `
  447.  
  448.  
  449. section.link-page section.link-block .wxs_menu_action_box
  450. {
  451. left: unset!important;
  452. right: 155px!important;
  453. }
  454. section.link-page section.entry .wxs_menu_action_box
  455. {
  456. right: 190px;
  457. }
  458.  
  459. /* wpisy w sidebarze */
  460. main.main > section > section.sidebar > section.custom-sidebar > div.content > section.entries > section.entry .wxs_menu_action_box
  461. {
  462. display: none!important;
  463. }
  464.  
  465. section.entry .wxs_menu_action_box:hover
  466. {
  467. box-shadow: 3px 3px 2px 1px rgba(0, 0, 0, 0.1);
  468. border-color: var(--blackOpacity04, rgb(125 125 125 / 1));
  469. }
  470. section.link-block .wxs_menu_action_box:hover
  471. {
  472. box-shadow: 3px -3px 2px 1px rgba(0, 0, 0, 0.1);
  473. border-color: var(--blackOpacity04, rgb(125 125 125 / 1));
  474. }
  475. section .wxs_menu_action_box button
  476. {
  477. display: flex;
  478. justify-content: center;
  479. align-items: center;
  480. font-size: inherit;
  481. min-width: 20px;
  482. width: max-content;
  483. padding: 0px 10px;
  484. height: 100%;
  485. color: inherit;
  486. }
  487. section .wxs_menu_action_box button:first-child
  488. {
  489. border-radius: 0px 0px 0px var(--buttonsBorderRadius, 4px)!important;
  490. }
  491. section .wxs_menu_action_box button:last-child
  492. {
  493. border-radius: 0px 0px var(--buttonsBorderRadius, 4px) 0px!important;
  494. }
  495. section .wxs_menu_action_box button span
  496. {
  497. font-size: inherit;
  498. padding: 0px 3px;
  499. }
  500. @media (max-width: 1350px)
  501. {
  502. section.entry .wxs_menu_action_box button span
  503. {
  504. display: none;
  505. }
  506. }
  507.  
  508.  
  509.  
  510.  
  511. /* ukrycie niepotrzebnych przycisków */
  512. section.wxs_minimized > article > div.wxs_menu_action_box > button.wxs_minimize,
  513. section:not(.wxs_minimized) > article > div.wxs_menu_action_box > button.wxs_maximize,
  514. section.own > article > .wxs_menu_action_box > .wxs_hide
  515. {
  516. display: none;
  517. }
  518.  
  519. /* ukrycie filtrowania pod wpisem bez komentarzy */
  520. section.entry-page > section.entry > section.stream > div.content > section.entry.detailed:not(:has(div.comments)) .wxs_menu_action_box > button:is(.wxs_filter_on_user, .wxs_filter_off, .wxs_filter_on_replies)
  521. section.entry-page > section.entry > section.stream > div.content > section.entry.detailed:not(:has(div.comments)) > article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button.wxs_filter_on_replies
  522. {
  523. display: none!important;
  524. }
  525.  
  526. section.link-block .wxs_menu_action_box > button.wxs_minimize,
  527. section.link-block .wxs_menu_action_box > button.wxs_save,
  528. section.link-block .wxs_menu_action_box > button.wxs_filter_on_replies
  529. {
  530. display: none;
  531. }
  532.  
  533.  
  534. section.entry article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button.wxs_filter_on_replies
  535. {
  536. display: inline-block;
  537. margin: 1px 2px 1px 3px;
  538. padding: 2px 4px 2px 4px;
  539. }
  540.  
  541.  
  542.  
  543. section.entry article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button.wxs_filter_on_replies > span
  544. {
  545. display: none;
  546. font-size: 11px;
  547. margin: 0px 4px;
  548. }
  549. section.entry article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button.wxs_filter_on_replies:hover > span
  550. {
  551. display: inline;
  552. }
  553.  
  554. section.entry article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button
  555. {
  556. border: 1px solid var(--athensGray);
  557. }
  558. section.entry article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > button:hover
  559. {
  560. background-color: var(--whitish)
  561. }
  562.  
  563. /* --- filtrowanie komentarzy użytkownika --- */
  564. section .wxs_menu_action_box button:hover,
  565. body[data-wxs_filter="userComments"] .wxs_menu_action_box button.wxs_filter_on_user:hover
  566. body[data-wxs_filter="userReplies"] .wxs_menu_action_box button.wxs_filter_on_replies:hover
  567. {
  568. background-color: var(--blackOpacity005, rgb(0 0 0 / 0.05));
  569. color: var(--blackOpacity1, rgb(125 125 125 / 1));
  570. }
  571. body[data-wxs_filter="userComments"] .wxs_menu_action_box button.wxs_filter_on_user,
  572. body[data-wxs_filter="userReplies"] .wxs_menu_action_box button.wxs_filter_on_replies
  573. {
  574. color: var(--blackOpacity05, rgb(125 125 125 / 1));
  575. background-color: var(--blackOpacity002, rgb(0 0 0 / 0.02));
  576. border-bottom: 1px solid var(--blackOpacity05, rgb(125 125 125 / 1));
  577. }
  578.  
  579.  
  580. /* przyciski filtrowania komentarzy użytkownika */
  581. /* wpisy na stronie glownej */
  582. main.main > section > div.content > section.home-page > section.home > section.stream > div.content > section.entry .wxs_menu_action_box > [class="wxs_filter_on_replies"],
  583. /* wpisy z 1 lub 2 komentarzami */
  584. section.entry[wxs_first_load_comments_count="1"] .wxs_menu_action_box > [class^="wxs_filter"],
  585. section.entry[wxs_first_load_comments_count="2"] .wxs_menu_action_box > [class^="wxs_filter"],
  586. /* wpisy bez komentarzy */
  587. /* main.main > section > div.content > section:not(.link-page) > section section.stream > div.content > section.entry:not(.reply):not(:has(div.comments)) .wxs_menu_action_box > .wxs_filter_on, */
  588. /* main.main > section > div.content > section:not(.link-page) > section section.stream > div.content > section.entry:not(.reply):not(:has(div.comments)) .wxs_menu_action_box > .wxs_filter_off */
  589. {
  590. display: none;
  591. }
  592.  
  593. .wxs_menu_action_box > .wxs_filter_off
  594. {
  595. display: none;
  596. }
  597.  
  598. /* ----- ZMINIMALIZOWANE WPISY I KOMENTARZE */
  599. /* wpisy */
  600. section.entry.wxs_minimized > article
  601. {
  602. padding: 0rem var(--entryLeftPadding, 16px;) 0rem 0rem!important;
  603. }`;
  604. if (settings.mirkoukrywaczMinimizedGrayedOut)
  605. {
  606. CSS += `section.entry.wxs_minimized > article
  607. {
  608. filter: grayscale(100%);
  609. }`;
  610. }
  611.  
  612. CSS += `
  613. /* STRONA ZNALEZISKA - ZWINIĘTE KOMENTARZE */
  614. section.link-page section.entry.wxs_minimized
  615. {
  616. height: 35px;
  617. padding: 0px!important;
  618. }
  619. section.link-page section.entry.wxs_minimized > article
  620. {
  621. padding: 0px!important;
  622. height: 35px;
  623. padding-right: var(--entriesAndCommentsHorizontalPadding, 16px)!important;
  624. margin: 0px!important;
  625. }
  626. section.link-page section.entry.wxs_minimized > div.comments
  627. {
  628. display: none!important;
  629. }
  630. section.link-page section.entry.wxs_minimized > article > header,
  631. section.link-page section.entry.wxs_minimized > article > header > div
  632. {
  633. height: 100%!important;
  634. }
  635.  
  636.  
  637.  
  638. /* czas dodania */
  639. section.entry.wxs_minimized > article > header > div.right > div > span
  640. {
  641. display: none!important;
  642. }
  643.  
  644.  
  645. /* avatar */
  646. section.entry.wxs_minimized > article > header > div.left
  647. {
  648. transform: translate(0px, 0px);
  649. --avatarSize: 17px;
  650. }
  651.  
  652.  
  653. /* div.right */
  654. section.entry.wxs_minimized > article > header
  655. {
  656. min-height: unset!important;
  657. }
  658.  
  659. section.entry.wxs_minimized > article > header > div.right
  660. {
  661. height: 35px!important;
  662. align-items: center!important;
  663. }
  664.  
  665. section.entry.wxs_minimized > article > header > div.right > div
  666. {
  667. display: flex!important;
  668. align-items: center!important;
  669. }
  670.  
  671. /* treść */
  672. section.entry.wxs_minimized > article > div.edit-wrapper
  673. {
  674. display: none!important;
  675. }
  676.  
  677.  
  678. /* ukrycie 2 najlepszych komentarzy pod wpisem w streamie */
  679. main.main > section > div.content > section:is(.bucket-page, .category-page, .favourites-page, .home-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry.wxs_minimized > div.comments
  680. {
  681. display: none!important;
  682. }`;
  683.  
  684. if (settings.mirkoukrywaczEnable)
  685. {
  686. /* WPISY UKRYWANE PRZEZ MIRKOUKRYWACZ .wxs_hidden should be removed most of the times, but still... */
  687. CSS += ` /* TODO LINK */
  688. main.main > section > div.content > section:is(.category-page, .favourites-page, .home-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry.wxs_hidden
  689. main.main > section > div.content > section.search-page > section section.stream > div.content section.entry.wxs_hidden
  690. {
  691. display: none!important;
  692. }`
  693. }
  694. }
  695. else
  696. {
  697. settings.mirkoukrywaczEnable = false;
  698. }
  699.  
  700. if (settings.mirkoukrywaczEnable)
  701. {
  702. // LOCALSTORAGE
  703. localStorageMirkoukrywacz = localforage.createInstance({
  704. driver: localforage.LOCALSTORAGE,
  705. name: "wykopx",
  706. storeName: "mirkoukrywacz",
  707. });
  708.  
  709.  
  710. }
  711.  
  712. setSettingsValueFromCSSProperty("notatkowatorEnable", true);
  713.  
  714.  
  715. if (settings.notatkowatorEnable)
  716. {
  717. IntersectionObserverEnabled = true;
  718. localStorageNotatkowator = localforage.createInstance({
  719. driver: localforage.LOCALSTORAGE,
  720. name: "wykopx",
  721. storeName: "notatkowator",
  722. });
  723.  
  724. //settings.notatkowatorUpdateInterval = parseFloat(wykopxSettings.getPropertyValue("--notatkowatorUpdateInterval")); // number 0 ... 120
  725. setSettingsValueFromCSSProperty("notatkowatorVerticalBar");
  726. setSettingsValueFromCSSProperty("notatkowatorWebsiteURL");
  727. setSettingsValueFromCSSProperty("notatkowatorStyle", "obok_nicka", true); // obok_nicka, obok_nicka_druga_linia, pod_avatarem
  728. }
  729.  
  730.  
  731. let falszyweRozoweArray = null;
  732. let falszyweNiebieskieArray = null;
  733. let mapaTrolli = null;
  734.  
  735. setSettingsValueFromCSSProperty("wxsUserLabelsEnable", true);
  736.  
  737. if (settings.wxsUserLabelsEnable)
  738. {
  739.  
  740. IntersectionObserverEnabled = true;
  741. localStorageUserLabels = localforage.createInstance({
  742. driver: localforage.LOCALSTORAGE,
  743. name: "wykopx",
  744. storeName: "userlabels",
  745. });
  746. setSettingsValueFromCSSProperty("wxsUserLabelsFakeFemales", true);
  747. setSettingsValueFromCSSProperty("wxsUserLabelsTrolls", true);
  748.  
  749. if (settings.wxsUserLabelsFakeFemales)
  750. {
  751. // LISTA FAŁSZYWYCH RÓŻOWYCH PASKÓW fałszywe różowe
  752. const listafalszywychrozowych = [];
  753.  
  754. listafalszywychrozowych.push('washington');
  755. listafalszywychrozowych.push('Obrzydzenie');
  756. listafalszywychrozowych.push('Blueweb');
  757. listafalszywychrozowych.push('conamirko');
  758. listafalszywychrozowych.push('i_took_a_pill_in_remiza');
  759. listafalszywychrozowych.push('Riolet');
  760. listafalszywychrozowych.push('ChwilowaPomaranczka');
  761. listafalszywychrozowych.push('RobieZdrowaZupke');
  762. listafalszywychrozowych.push('IlllIlIIIIIIIIIlllllIlIlIlIlIlIlIII');
  763. listafalszywychrozowych.push('Banderoza');
  764. listafalszywychrozowych.push('deiceberg');
  765. listafalszywychrozowych.push('Chodtok');
  766. listafalszywychrozowych.push('kierowcaautobusuofficial');
  767. listafalszywychrozowych.push('ToJestNiepojete');
  768. listafalszywychrozowych.push('model_wygenerowany_na_wykoppl');
  769. listafalszywychrozowych.push('chwilowypaczelok');
  770. listafalszywychrozowych.push('sinls');
  771. listafalszywychrozowych.push('KRZYSZTOF_DZONG_UN');
  772. listafalszywychrozowych.push('miszczu90');
  773. listafalszywychrozowych.push('nenq123');
  774. listafalszywychrozowych.push('domek_drewniany');
  775. listafalszywychrozowych.push('konserwix');
  776. listafalszywychrozowych.push('Diamond');
  777. listafalszywychrozowych.push('BlackBl-kunack');
  778. listafalszywychrozowych.push('Mantusabra');
  779. listafalszywychrozowych.push('ElCidX');
  780. listafalszywychrozowych.push('cword');
  781. listafalszywychrozowych.push('ToJestNiepojete');
  782. listafalszywychrozowych.push('powodzenia');
  783. listafalszywychrozowych.push('washington');
  784. listafalszywychrozowych.push('sipson204');
  785. listafalszywychrozowych.push('36873');
  786. listafalszywychrozowych.push('Defined');
  787. listafalszywychrozowych.push('toniemojebuty');
  788. listafalszywychrozowych.push('DigitalPasztet');
  789. listafalszywychrozowych.push('wcaleniepchamsiewmultikonto');
  790. listafalszywychrozowych.push('Wieczny_Prawiczek');
  791. listafalszywychrozowych.push('Bpnn');
  792. listafalszywychrozowych.push('AndrzejBabinicz');
  793. listafalszywychrozowych.push('bruhmomentow');
  794. listafalszywychrozowych.push('iforgotmypass_');
  795. listafalszywychrozowych.push('kwiat_pustyni626');
  796. listafalszywychrozowych.push('powodzenia');
  797. listafalszywychrozowych.push('simsakPL');
  798. listafalszywychrozowych.push('ramotka');
  799. listafalszywychrozowych.push('bruhmomentow');
  800.  
  801.  
  802.  
  803.  
  804. // LISTA FAŁSZYWYCH NIEBIESKICH PASKÓW fałszywe niebieskie
  805. const listafalszywychniebieskich = [];
  806. listafalszywychniebieskich.push("Kantor_wymiany_mysli_i_wrazen");
  807. listafalszywychniebieskich.push("DragonTattoo2404");
  808. listafalszywychniebieskich.push("qksgh");
  809. listafalszywychniebieskich.push("mariusz9922");
  810. listafalszywychniebieskich.push("xoxo900");
  811. listafalszywychniebieskich.push("jutronaobiadznowuryz");
  812.  
  813.  
  814.  
  815. localStorageUserLabels.setItem('falszyweRozowe', listafalszywychrozowych).then(() => { });
  816. localStorageUserLabels.setItem('falszyweNiebieskie', listafalszywychniebieskich).then(() => { });
  817.  
  818.  
  819. // get from localstorage
  820. falszyweRozoweArray = await localStorageUserLabels.getItem("falszyweRozowe");
  821. falszyweNiebieskieArray = await localStorageUserLabels.getItem("falszyweNiebieskie");
  822. }
  823.  
  824.  
  825. if (settings.wxsUserLabelsTrolls)
  826. {
  827. const trollsMap = new Map();
  828. trollsMap.set("WykopX", { "url": "https://github.com/wykopx/WykopX/wiki/X-Notatkowator" });
  829. trollsMap.set("wykop", { "label": "Oficjalne konto", });
  830. trollsMap.set("bakehaus", { "label": "Wypiek", "url": "https://nimble.li/vdr4ajlm" });
  831. trollsMap.set("m__b", { "label": "Michał B.", "url": "https://pl.linkedin.com/in/michalbialek" });
  832. trollsMap.set("paliwoda", { "url": "https://sjp.pwn.pl/sjp/chomato;2448428.html" });
  833. trollsMap.set("autotldr", { "label": "Bot AI", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#auto-tldr" });
  834. trollsMap.set("wykop-gpt", { "label": "Bot AI", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#wykop-gpt" });
  835. trollsMap.set("Przypomnienie", { "label": "Bot AI", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#przypomnienie" });
  836. trollsMap.set("DwieLinieBOTv3", { "label": "Bot AI", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#dwie-linie-bot" });
  837. trollsMap.set("ISSTrackerPL", { "label": "Bot", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#iss-tracker" });
  838. trollsMap.set("januszowybot", { "label": "Bot", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Boty-na-Wykopie#januszowy-bot" });
  839. trollsMap.set("mirko_anonim", { "label": "Anonim", "url": "https://github.com/wykopx/Aplikacje-wykopowe/wiki/Aplikacje#mirkoanonim" });
  840. // #wykopaka sciana wstydu
  841. trollsMap.set("Barneyeos", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  842. trollsMap.set("zzbkk", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  843. trollsMap.set("ZarejestrowanyMimoWoli", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  844. trollsMap.set("idainadenshigijutsusha", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  845. trollsMap.set("birus", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  846. trollsMap.set("anthonysoprano", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  847. trollsMap.set("ferigone", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  848. trollsMap.set("DerMirker", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  849. trollsMap.set("viciu03", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  850. trollsMap.set("kriss2005r", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  851. trollsMap.set("Kalinke01", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  852. trollsMap.set("maestroPijanyRolnik", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  853. trollsMap.set("Davidvia0", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  854. trollsMap.set("Nefree", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  855. trollsMap.set("Architekt_Chaosu", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  856. trollsMap.set("kogut_20", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  857. trollsMap.set("mkeeey", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  858. trollsMap.set("Mirkosoft", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  859. trollsMap.set("WodkaGrejfrut", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  860. trollsMap.set("notavailable", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  861. trollsMap.set("spoko_spoko_na_chillku", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  862. trollsMap.set("Repcakos", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  863. trollsMap.set("3dnow", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  864. trollsMap.set("ToChybaJakisZart", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  865. trollsMap.set("vrraaaz", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  866. trollsMap.set("Skura_tak_przezU", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  867. trollsMap.set("Lutekcjusz", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  868. trollsMap.set("ile-prawdy-jest-w-jednym-slowie", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  869. trollsMap.set("kutmen2", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  870. trollsMap.set("michal_misiek", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  871. trollsMap.set("kartofel322", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  872. trollsMap.set("ten_co_uciekl", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  873. trollsMap.set("NaczelnyHejterWykopu", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  874. trollsMap.set("wykopowa_ona", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  875. trollsMap.set("s-o-s", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  876. trollsMap.set("Samowski", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  877. trollsMap.set("CynicznySkurczybyk", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  878. trollsMap.set("qmox", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  879. trollsMap.set("pawel_je", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  880. trollsMap.set("PrawdziwyRealista", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  881. trollsMap.set("beniu89", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  882. trollsMap.set("cranberry250", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  883. trollsMap.set("bimbadil", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  884. trollsMap.set("PanKajak", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  885. trollsMap.set("Qontrol", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  886. trollsMap.set("RobaUrs", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  887. trollsMap.set("PAST", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  888. trollsMap.set("Szychasekk", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  889. trollsMap.set("Szatanski_werset", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  890. trollsMap.set("matess", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  891. trollsMap.set("SSKW", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  892. trollsMap.set("silver1", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  893. trollsMap.set("CioseK", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  894. trollsMap.set("wojt4ss", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  895. trollsMap.set("Ponta", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  896. trollsMap.set("kspr", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  897. trollsMap.set("korporacion", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  898. trollsMap.set("ogrod87", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  899. trollsMap.set("Tomek3322", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  900. trollsMap.set("dgjkasgr8yl3q", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  901. trollsMap.set("dese", { "label": "🤬 #wykopaka", "url": "https://wykopaka.pl/wall-of-shame" });
  902.  
  903.  
  904. trollsMap.set("ChwilowaPomaranczka", { "label": "Wykopowy Troll" });
  905. localStorageUserLabels.setItem('mapaTrolli', Object.fromEntries(trollsMap)).then(() => { });
  906.  
  907. // get from localstorage
  908. localStorageUserLabels.getItem('mapaTrolli').then(val => { mapaTrolli = new Map(Object.entries(val)); })
  909. }
  910. }
  911.  
  912. // wykop_xs_banned.user.js - START - 1
  913. setSettingsValueFromCSSProperty("infoboxUserBannedInfoOnProfilePage");
  914. // wykop_xs_banned.user.js - END - 1
  915.  
  916.  
  917.  
  918.  
  919. setSettingsValueFromCSSProperty("infoboxEnable", false);
  920.  
  921. if (settings.infoboxEnable)
  922. {
  923. IntersectionObserverEnabled = true;
  924. setSettingsValueFromCSSProperty("infoboxUserBannedEmoji");
  925. setSettingsValueFromCSSProperty("infoboxUserBannedInfo");
  926. setSettingsValueFromCSSProperty("infoboxUserMemberSince");
  927. setSettingsValueFromCSSProperty("infoboxUserMemberSinceYear");
  928. setSettingsValueFromCSSProperty("infoboxUserSummaryFollowers");
  929. setSettingsValueFromCSSProperty("infoboxUserSummaryActivity");
  930. }
  931.  
  932.  
  933. setSettingsValueFromCSSProperty("tabChangeEnabled", false);
  934. if (settings.tabChangeEnabled)
  935. {
  936. setSettingsValueFromCSSProperty("tabChangeOnlyOnHiddenState", false);
  937. setSettingsValueFromCSSProperty("tabChangeFaviconEnabled", false);
  938.  
  939. if (settings.tabChangeFaviconEnabled)
  940. {
  941. setSettingsValueFromCSSProperty("tabChangeFaviconSelect", "wykop", true);
  942. }
  943.  
  944. setSettingsValueFromCSSProperty("tabChangeTitleEnabled", false);
  945. if (settings.tabChangeTitleEnabled)
  946. {
  947. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsEnabled", false);
  948. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsCountPM", false);
  949. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsCountEntries", false);
  950. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsCountSeparated", false);
  951. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsCountTagsNewLink", false);
  952. setSettingsValueFromCSSProperty("tabChangeTitleShowNotificationsCountTagsNewEntry", false);
  953. setSettingsValueFromCSSProperty("tabChangeTitlePrefix", false);
  954. setSettingsValueFromCSSProperty("tabChangeTitleSelect", "domyslny", true);
  955. setSettingsValueFromCSSProperty("tabChangeTitleCustom", "Wykop X", true);
  956. setSettingsValueFromCSSProperty("tabChangeTitleSuffix", "domyslny", true);
  957. }
  958. }
  959.  
  960.  
  961.  
  962. // DOMYŚLNIE WYŁĄCZONE BEZ WYKOP X STYLE
  963. setSettingsValueFromCSSProperty("votePlusMinusOnHover", false);
  964. setSettingsValueFromCSSProperty("observedTagsInRightSidebarSortAlphabetically", false);
  965. setSettingsValueFromCSSProperty("topNavHomeButtonClickRefreshOrRedirect", false);
  966. setSettingsValueFromCSSProperty("topNavMicroblogButtonClickRefreshOrRedirect", false);
  967. setSettingsValueFromCSSProperty("quickLinksEnable", false);
  968.  
  969. // DODATKOWE PRZYCISKI NA GORNEJ BELCE
  970. setSettingsValueFromCSSProperty("topNavNightSwitchButton", true);
  971.  
  972. setSettingsValueFromCSSProperty("topNavMyWykopButton", false);
  973. setSettingsValueFromCSSProperty("topNavMicroblogButton", false);
  974. setSettingsValueFromCSSProperty("topNavMessagesButton", false);
  975. setSettingsValueFromCSSProperty("topNavProfileButton", false);
  976. setSettingsValueFromCSSProperty("topNavNotificationsButton", false);
  977.  
  978. // DODATKOWE PRZYCISKI NA BELCE MOBILNEJ
  979. setSettingsValueFromCSSProperty("mobileNavBarHide", false);
  980. if (settings.mobileNavBarHide == false)
  981. {
  982. setSettingsValueFromCSSProperty("mobileNavBarMyWykopButton", false);
  983. setSettingsValueFromCSSProperty("mobileNavBarMessagesButton", false);
  984. setSettingsValueFromCSSProperty("mobileNavBarProfileButton", false);
  985. setSettingsValueFromCSSProperty("mobileNavBarNotificationsButton", false);
  986. }
  987.  
  988.  
  989. // default numbers
  990. settings.observedTagsInRightSidebarUpdateInterval = 12;
  991. if (wykopxSettings.getPropertyValue("--observedTagsInRightSidebarUpdateInterval")) settings.observedTagsInRightSidebarUpdateInterval = parseFloat(wykopxSettings.getPropertyValue("--observedTagsInRightSidebarUpdateInterval")); // number
  992.  
  993.  
  994.  
  995.  
  996.  
  997. // variables from Wykop X Style
  998. // TODO stare Wykop X Style "true"
  999. settings.wxsDownloadImageButton = (wykopxSettings.getPropertyValue("--wxsDownloadImageButton").trim() == `"true"`); // boolean, default off
  1000. settings.topNavHamburgerHoverMinimize = (wykopxSettings.getPropertyValue("--topNavHamburgerHoverMinimize").trim() == `"true"`); // boolean
  1001. settings.tagHeaderEditable = (wykopxSettings.getPropertyValue("--tagHeaderEditable").trim() == `"true"`); // boolean
  1002. settings.linksAnalyzerEnable = (wykopxSettings.getPropertyValue("--linksAnalyzerEnable").trim() == `"true"`); // boolean
  1003. settings.fixCaseSensitiveTagsRedirection = (wykopxSettings.getPropertyValue("--fixCaseSensitiveTagsRedirection").trim() == `"true"`); // boolean
  1004. settings.categoryRedirectToMicroblogButtonEnable = (wykopxSettings.getPropertyValue("--categoryRedirectToMicroblogButtonEnable").trim() == `"true"`); // boolean
  1005.  
  1006.  
  1007.  
  1008. settings.homepagePinnedEntriesHideBelowLimit = parseFloat(wykopxSettings.getPropertyValue("--homepagePinnedEntriesHideBelowLimit")); // number
  1009.  
  1010.  
  1011. // boolean — domyslnie WŁĄCZONE bez Wykop X Style
  1012. setSettingsValueFromCSSProperty("hitsInTopNavJS");
  1013. setSettingsValueFromCSSProperty("myWykopInTopNavJS");
  1014. setSettingsValueFromCSSProperty("favoritesInTopNavJS");
  1015. setSettingsValueFromCSSProperty("addNewLinkInTopNavJS");
  1016. setSettingsValueFromCSSProperty("addNewEntryInTopNavJS");
  1017. setSettingsValueFromCSSProperty("disableNewLinkEditorPastedTextLimit");
  1018.  
  1019.  
  1020. // strings
  1021. setSettingsValueFromCSSProperty("linksAnalyzerSortBy", "domyslnie", true);
  1022. setSettingsValueFromCSSProperty("topNavLogoClick", "glowna", true);
  1023. setSettingsValueFromCSSProperty("editorSendHotkey", "ctrl_enter", true); // "domyslnie", "enter", "ctrl_enter", "ctrl_s"
  1024.  
  1025. if (settings.editorSendHotkey != "domyslnie") setSettingsValueFromCSSProperty("editorSendHotkeyShowOnSendButton");
  1026.  
  1027. settings.categoryRedirectToMicroblogButtonFilter = wykopxSettings.getPropertyValue("--categoryRedirectToMicroblogButtonFilter").replaceAll("_", "/").replaceAll(" ", "");
  1028.  
  1029.  
  1030.  
  1031. /* mouseClickOpensImageInNewTab 💻❎🐁 Otwórz obrazek w nowej karcie kliknięciem "nie_otwieraj"-domyslnie "lewy_przycisk_myszy""srodkowy_przycisk_myszy" "prawy_przycisk_myszy" */
  1032. settings.mouseClickOpensImageInNewTab = wykopxSettings.getPropertyValue("--mouseClickOpensImageInNewTab") ? wykopxSettings.getPropertyValue("--mouseClickOpensImageInNewTab").replaceAll(" ", "") : "srodkowy_przycisk_myszy";
  1033.  
  1034.  
  1035.  
  1036. let localStorageObserved = localforage.createInstance({
  1037. driver: localforage.LOCALSTORAGE,
  1038. name: "wykopx",
  1039. storeName: "observed",
  1040. });
  1041.  
  1042. const topNavHeaderRightElement = document.querySelector('header.header > .right > nav > ul');
  1043.  
  1044. if (dev) consoleX("Settings: ", 1);
  1045. if (dev) console.log(settings);
  1046.  
  1047. // przenoszenie na tagi: wykop.pl/#heheszki
  1048. // i na profile użytkownikow: wykop.pl/@m__b
  1049. // wyszukiwanie wpisów danej osoby w konkretnym tagu wykop.pl/@m__b/#internet albo wykop.pl/#internet/@m__b/
  1050.  
  1051.  
  1052. let currentPageURL = undefined;
  1053.  
  1054. let pageType = "";
  1055. let pageSubtype = "";
  1056. let pageObjects = []; // ["znaleziska", "wpisy", "komentarze"]
  1057.  
  1058. let currentPageTotalVotesUpCount = 0;
  1059.  
  1060. let hash = new URL(document.URL).hash;
  1061. let pathname = new URL(document.URL).pathname;
  1062. let pathnameArray = pathname.split("/"); // ['', 'wpis', '74111643', 'dobranoc-panstwu'] ['', 'wykopalisko'] ['', 'link', '7303053', 'braun-gasi-chanuke-gasnica-mem']
  1063.  
  1064.  
  1065. isURLChanged();
  1066. newPageURL();
  1067.  
  1068. // setInterval(() =>
  1069. // {
  1070. // if (isURLChanged()) newPageURL()
  1071. // }, 5000);
  1072.  
  1073. function isURLChanged()
  1074. {
  1075. const newURL = window.location.href;
  1076. consoleX(`isURLChanged() -> ${newURL}`, 1);
  1077. //const newURL2 = document.URL;
  1078.  
  1079. if (newURL != currentPageURL)
  1080. {
  1081. consoleX(`isURLChanged() -> URL Changed from ${currentPageURL} to ${newURL}`)
  1082. currentPageURL = newURL;
  1083. return true;
  1084. }
  1085. else return false;
  1086. }
  1087.  
  1088.  
  1089. function newPageURL()
  1090. {
  1091. consoleX("newPageURL()", 1);
  1092.  
  1093. hash = new URL(document.URL).hash;
  1094. pathname = new URL(document.URL).pathname;
  1095. pathnameArray = pathname.split("/");
  1096. consoleX(`newPageURL() -> document.URL: ${document.URL} hash: ${hash}, pathname: ${pathname}, pathnameArray: `, 1)
  1097. if (dev) console.log(pathnameArray)
  1098.  
  1099. currentPageTotalVotesUpCount = 0;
  1100.  
  1101. if (pathnameArray[1] == "" || pathnameArray[1] == "aktywne" || pathnameArray[1] == "najnowsze" || pathnameArray[1] == "strona")
  1102. {
  1103. pageType = "glowna";
  1104. pageSubtype = "glowna";
  1105. pageObjects = ["wpisy", "znaleziska"];
  1106.  
  1107. if (pathnameArray[2] && pathnameArray[2] != "strona")
  1108. {
  1109. pageSubtype = pathnameArray[2]; // "aktywne", "najnowsze"
  1110. }
  1111. }
  1112.  
  1113. else if (pathnameArray[1] == "wykopalisko")
  1114. {
  1115. pageType = "wykopalisko";
  1116. pageSubtype = "wykopalisko";
  1117. pageObjects = ["znaleziska"];
  1118.  
  1119. if (pathnameArray[2] && pathnameArray[2] != "strona")
  1120. {
  1121. pageSubtype = pathnameArray[2]; // "najnowszego", "aktywne", "wykopywane", "komentowane"
  1122. }
  1123. }
  1124.  
  1125. else if (pathnameArray[1] == "ludzie") // profil jakiegoś użytkownika wykop.pl/ludzie/NadiaFrance
  1126. {
  1127. pageType = "profil";
  1128. pageSubtype = "profil";
  1129. pageObjects = ["znaleziska", "wpisy", "komentarze"];
  1130. }
  1131. else if (pathnameArray[1] == "link")
  1132. {
  1133. pageType = "znalezisko";
  1134. pageSubtype = "znalezisko";
  1135. pageObjects = ["komentarze"];
  1136. }
  1137. else if (pathnameArray[1] == "wpis")
  1138. {
  1139. pageType = "wpis";
  1140. pageSubtype = "wpis";
  1141. pageObjects = ["komentarze"];
  1142. }
  1143.  
  1144. else if (pathnameArray[1] == "mikroblog")
  1145. {
  1146. pageType = "mikroblog";
  1147. pageSubtype = "mikroblog";
  1148. pageObjects = ["wpisy", "komentarze"];
  1149. }
  1150.  
  1151. else if (pathnameArray[1] == "tag")
  1152. {
  1153. pageType = "tag";
  1154. pageSubtype = pathnameArray[2]; // nazwatagu
  1155. pageObjects = ["znaleziska", "wpisy", "komentarze"];
  1156. }
  1157. consoleX(`Typ strony: ${pageType} ${pageType != pageSubtype ? pageSubtype : ""}`, 1)
  1158. // if(dev) console.log(`pageObjects:`, pageObjects)
  1159. }
  1160.  
  1161.  
  1162.  
  1163.  
  1164. function removeAllDataWXSAttributes()
  1165. {
  1166. consoleX(`removeAllDataWXSAttributes()`, 1);
  1167.  
  1168. document.querySelectorAll(`section[data-wxs_username]`).forEach((el) =>
  1169. {
  1170. removeWXSAttributes(el)
  1171. });
  1172. }
  1173.  
  1174. function removeWXSAttributes(sectionObjectElement)
  1175. {
  1176. if (dev) console.log(`removeWXSAttributes() from id: ${sectionObjectElement.__vue__.item.id}`, + sectionObjectElement);
  1177.  
  1178. sectionObjectElement.removeAttribute('style'); // custom css properties removed
  1179.  
  1180. Object.keys(sectionObjectElement.dataset).forEach(dataKey =>
  1181. {
  1182. if (dataKey.startsWith('wxs_'))
  1183. {
  1184. delete sectionObjectElement.dataset[dataKey];
  1185. }
  1186. });
  1187. }
  1188.  
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194. (async () =>
  1195. {
  1196. let at, tag;
  1197. if (settings.fixCaseSensitiveTagsRedirection)
  1198. {
  1199. /* fixing case sensitive tags https://github.com/wykopx/WykopX/issues/21 */
  1200. if (pathnameArray[1] == "tag" && /[A-Z]/.test(pathnameArray[2]))
  1201. {
  1202. consoleX(`Błędny tag "${pathnameArray[2]}"`);
  1203. pathnameArray[2] = pathnameArray[2].toLowerCase();
  1204. let newPathname = "https://wykop.pl" + pathnameArray.join("/");
  1205. consoleX(`Otwieram poprawny adres: ${newPathname}`);
  1206. window.location.replace(newPathname);
  1207. }
  1208. }
  1209.  
  1210. let excludedPaths = ["szukaj", "wpis", "link", "artykul", "k", "wykopalisko", "mikroblog", "osberwowane", "hity", "powiadomienia", "ustawienia"];
  1211.  
  1212. // # przekierowanie URL http://wykop.pl/#heheszki albo http://wykop.pl/#wykop/@m__b ale nie https://wykop.pl/wpis/213123/tresc#123456
  1213. if (!excludedPaths.includes(pathnameArray[1]) && hash.length > 0)
  1214. {
  1215. let tagWithHash = hash.split("/")[0];
  1216. let tagWithoutHash = tagWithHash.slice(1);
  1217. let tagNumber = Number.parseInt(tagWithoutHash);
  1218.  
  1219. if (tagWithoutHash.length > 1 && (tagNumber == "NaN" || tagWithoutHash.length < 9) && tagWithoutHash != "dodaj")
  1220. {
  1221. if ((tag = getTagFromUrl(tagWithHash))) { }
  1222. if ((at = getUserFromUrl(hash))) { }
  1223. }
  1224. }
  1225.  
  1226. // @ przekierowanie URL http://wykop.pl/@NadiaFrance albo http://wykop.pl/#wykop/@m__b
  1227. if (!excludedPaths.includes(pathnameArray[1]) && pathname.length > 2)
  1228. {
  1229. if (at || (at = getUserFromUrl(pathname))) { }
  1230. }
  1231.  
  1232. if (at || tag) smartRedirectBasedOnUserAndTag(at, tag);
  1233.  
  1234. })();
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243. function redirectToSearchUserEntriesInTag(user, tag)
  1244. {
  1245. window.location.replace(`https://wykop.pl/szukaj/wszystkie/@${user}?tags=${tag}`);
  1246. }
  1247.  
  1248. function redirectToTag(tag)
  1249. {
  1250. window.location.replace(`https://go.wykopx.pl/#${tag}`);
  1251. }
  1252.  
  1253. function redirectToUser(user)
  1254. {
  1255. window.location.replace(`https://wykopx.pl/@${user}`);
  1256. }
  1257.  
  1258. function smartRedirectBasedOnUserAndTag(user, tag)
  1259. {
  1260. consoleX(`smartRedirectBasedOnUserAndTag(user @${user}, tag #${tag})`, 1);
  1261.  
  1262. if (tag && user) redirectToSearchUserEntriesInTag(user, tag)
  1263. else if (tag) redirectToTag(tag)
  1264. else if (user) redirectToUser(user)
  1265. }
  1266. // returns 'tag' from /#tag in string
  1267. function getTagFromUrl(url, splitSeparator = "/", tagSymbol = "#")
  1268. {
  1269. consoleX(`getTagFromUrl(url: ${url}, splitSeparator: #${splitSeparator}), tagSymbol: ${tagSymbol}`, 1);
  1270.  
  1271. let tagArray = url.split(splitSeparator);
  1272. for (let element of tagArray)
  1273. {
  1274. if (element.charAt(0) == "#" || element.charAt(0) == tagSymbol)
  1275. {
  1276. element = element.slice(1);
  1277. return element;
  1278. } else if (tagSymbol == "" && (/^[0-9a-zA-Z]/i.test(element.charAt(0))))
  1279. {
  1280. return element;
  1281. } else
  1282. {
  1283. continue;
  1284. }
  1285. }
  1286. return false;
  1287. }
  1288.  
  1289. function getUserFromUrl(url, splitSeparator = "/", userSymbol = "@")
  1290. {
  1291. consoleX(`getUserFromUrl(url: ${url}, splitSeparator: #${splitSeparator}), userSymbol: ${userSymbol}`, 1);
  1292.  
  1293. let atArray = url.split(splitSeparator);
  1294. for (let element of atArray)
  1295. {
  1296. if (element.charAt(0) == userSymbol)
  1297. {
  1298. return element.slice(1);
  1299. }
  1300. }
  1301. return false;
  1302. }
  1303.  
  1304.  
  1305.  
  1306.  
  1307.  
  1308.  
  1309.  
  1310. let consoleData =
  1311. {
  1312. mirkoukrywacz_hidden:
  1313. {
  1314. count: 0,
  1315. text: "Ukrytych",
  1316. title: "Mirkoukrywacz ukryte",
  1317. },
  1318.  
  1319. mirkoukrywacz_minimized: {
  1320. count: 0,
  1321. text: "Zwiniętych",
  1322. title: "Mirkoukrywacz zwinął",
  1323. },
  1324.  
  1325. annoyances: {
  1326. count: 0,
  1327. text: "Uciążliwych obiektów",
  1328. title: "Annoyances title",
  1329.  
  1330. ads: {
  1331. count: 0,
  1332. text: "Usuniętych reklam",
  1333.  
  1334. },
  1335.  
  1336. iframe: {
  1337. count: 0,
  1338. text: "ads iframes",
  1339. title: "Annoyances iframes with ads",
  1340. },
  1341.  
  1342. script: {
  1343. count: 0,
  1344. text: "ads scripts",
  1345. title: "Annoyances scripts",
  1346. },
  1347.  
  1348. other: {
  1349. count: 0,
  1350. text: "inne",
  1351. title: "Annoyances other",
  1352.  
  1353. },
  1354.  
  1355. div: {
  1356. count: 0,
  1357. text: "inne",
  1358. title: "Annoyances div",
  1359. },
  1360. },
  1361.  
  1362.  
  1363.  
  1364. notatkowator: {
  1365. count: 0,
  1366. text: "Dodanych Notatek",
  1367. title: "Notatki do użytkowników",
  1368. },
  1369. }
  1370.  
  1371. function buildConsole(jNodeHeaderStreamTop = null)
  1372. {
  1373.  
  1374. if (!dev) return;
  1375.  
  1376. consoleX("buildConsole()", 1)
  1377.  
  1378. let headerStreamTopElement;
  1379.  
  1380. if (!jNodeHeaderStreamTop)
  1381. {
  1382. headerStreamTopElement = document.getElementById("main.main > section > div.content section.stream > header.stream-top");
  1383. }
  1384. else
  1385. {
  1386. headerStreamTopElement = jNodeHeaderStreamTop;
  1387. }
  1388.  
  1389. if (headerStreamTopElement)
  1390. {
  1391. //return;
  1392. const wxs_console = document.getElementById("wxs_console");
  1393. if (!wxs_console)
  1394. {
  1395. const wxs_console_container = document.createElement("aside"); // <aside id="wxs_console_container">
  1396. wxs_console_container.id = "wxs_console_container";
  1397. wxs_console_container.innerHTML = `<header><span>𝗪𝘆𝗸𝗼𝗽 𝗫</span> <button>▼</button></header>`;
  1398. wxs_console_container.title = `𝗪𝘆𝗸𝗼𝗽 𝗫`;
  1399. headerStreamTopElement.appendChild(wxs_console_container);
  1400.  
  1401. let wxs_console_section = document.createElement("section");
  1402. wxs_console_section.id = "wxs_console";
  1403.  
  1404. headerStreamTopElement.insertAdjacentElement('afterend', wxs_console_section);
  1405. }
  1406. refreshConsole();
  1407. }
  1408. }
  1409.  
  1410.  
  1411. let wxs_console;
  1412.  
  1413. function refreshConsole()
  1414. {
  1415. consoleX("refresh console()", 1)
  1416.  
  1417. return; // temp
  1418.  
  1419. if (!wxs_console) wxs_console = document.getElementById("wxs_console");
  1420.  
  1421. if (wxs_console)
  1422. {
  1423. wxs_console.innerHTML = "";
  1424.  
  1425. for (let field in consoleData)
  1426. {
  1427. if (consoleData[field].count > 0)
  1428. {
  1429. let div = document.createElement("div");
  1430. div.classList.add(`wcs_console_${field}`)
  1431. div.title = consoleData[field].title;
  1432. div.innerHTML = `<span class="wxs_console_count">
  1433. ${consoleData[field].count}
  1434. </span>
  1435. <span class="wxs_console_text">
  1436. ${consoleData[field].text}
  1437. </span>`;
  1438. wxs_console.appendChild(div);
  1439. }
  1440. }
  1441. for (let field in consoleData.annoyances)
  1442. {
  1443. if (consoleData.annoyances[field].count > 0)
  1444. {
  1445. let div = document.createElement("div");
  1446. div.title = consoleData.annoyances[field].title;
  1447. div.classList.add(`wcs_console_${field}`)
  1448. div.innerHTML = `<span class="wxs_console_count">
  1449. ${consoleData.annoyances[field].count}
  1450. </span>
  1451. <span class="wxs_console_text">
  1452. ${consoleData.annoyances[field].text}
  1453. </span>`;
  1454. wxs_console.appendChild(div);
  1455. }
  1456. }
  1457. }
  1458.  
  1459. }
  1460.  
  1461.  
  1462.  
  1463. /* LENNY FACE
  1464. let lennyArray =
  1465. [
  1466. `( ͡° ͜ʖ ͡°)`,
  1467. `( ͡° ʖ̯ ͡°)`,
  1468. `( ͡º ͜ʖ͡º)`,
  1469. `( ͡°( ͡° ͜ʖ( ͡° ͜ʖ ͡°)ʖ ͡°) ͡°)`,
  1470. `(⌐ ͡■ ͜ʖ ͡■)`,
  1471. `(╥﹏╥)`,
  1472. `(╯︵╰,)`,
  1473. `(ʘ‿ʘ)`,
  1474. `(。◕‿‿◕。)`,
  1475. `ᕙ(⇀‸↼‶)ᕗ`,
  1476. `ᕦ(òóˇ)ᕤ`,
  1477. `(✌ ゚ ∀ ゚)☞`,
  1478. `ʕ•ᴥ•ʔ`,
  1479. `ᶘᵒᴥᵒᶅ`,
  1480. `(⌒(oo)⌒)`
  1481. ]
  1482. }
  1483. */
  1484.  
  1485.  
  1486.  
  1487.  
  1488.  
  1489.  
  1490.  
  1491.  
  1492.  
  1493.  
  1494. // <body data-wxs_category_menu_minimized="false">
  1495. if (settings.topNavHamburgerHoverMinimize)
  1496. {
  1497. waitForKeyElements("body > section > header.header > div.left > button", topNavHamburgerHoverMinimize, true);
  1498. }
  1499. function topNavHamburgerHoverMinimize(hamburgerButton)
  1500. {
  1501. consoleX(`topNavHamburgerHoverMinimize()`, 1);
  1502. body.dataset.wxs_category_menu_minimized = 'true';
  1503. hamburgerButton.addEventListener("mouseover", () =>
  1504. {
  1505. if (body.dataset.wxs_category_menu_minimized === 'true')
  1506. {
  1507. //delete body.dataset.wxs_category_menu_minimized;
  1508. body.dataset.wxs_category_menu_minimized = 'false';
  1509. }
  1510. else
  1511. {
  1512. body.dataset.wxs_category_menu_minimized = 'true';
  1513. }
  1514. });
  1515. }
  1516.  
  1517.  
  1518.  
  1519. /* QUICK SEARCH */
  1520.  
  1521. /* Edytuj nagłówek tagu, aby przejść na inny tag */
  1522.  
  1523. function tagHeaderEditableWatcher()
  1524. {
  1525. consoleX(`tagHeaderEditableWatcher()`, 1);
  1526.  
  1527. if (settings.tagHeaderEditable)
  1528. {
  1529. waitForKeyElements(".main-content .main aside.tag-top .content header h1", tagHeaderEditable, false);
  1530. }
  1531. }
  1532.  
  1533. function tagHeaderEditable(tagHeaderEditable)
  1534. {
  1535. consoleX(`tagHeaderEditable()`, 1);
  1536. let originalValue = tagHeaderEditable.textContent.toLowerCase();
  1537. tagHeaderEditable.className = "wykopx_quick_search";
  1538. tagHeaderEditable.setAttribute("data-wykopx-original-value", originalValue); //todo dataset
  1539. tagHeaderEditable.setAttribute("tabindex", 1);
  1540. tagHeaderEditable.setAttribute("spellcheck", false);
  1541. tagHeaderEditable.contentEditable = "true";
  1542. tagHeaderEditable.role = "textbox";
  1543.  
  1544.  
  1545. let wykopx_quick_search = document.querySelector(".wykopx_quick_search");
  1546. if (originalValue != "")
  1547. {
  1548. wykopx_quick_search.value = originalValue;
  1549. wykopx_quick_search.dispatchEvent(new Event('change'));
  1550. wykopx_quick_search.setAttribute("data-wykopx-original-value", originalValue);
  1551. }
  1552. wykopx_quick_search.addEventListener("blur", eventInsertedTagOrUser);
  1553. wykopx_quick_search.addEventListener("keydown", eventInsertedTagOrUser);
  1554. }
  1555.  
  1556. waitForKeyElements("input.wykopx_quick_search", wykopx_quick_search, false);
  1557.  
  1558. function wykopx_quick_search(wykopxQuickSearch)
  1559. {
  1560. consoleX(`wykopx_quick_search()`, 1);
  1561. wykopxQuickSearch.addEventListener("blur", eventInsertedTagOrUser);
  1562. wykopxQuickSearch.addEventListener("keydown", eventInsertedTagOrUser);
  1563. }
  1564.  
  1565. function eventInsertedTagOrUser(e)
  1566. {
  1567. consoleX("eventInsertedTagOrUser(e)", 1);
  1568.  
  1569. if (e.type === "blur" || (e.type === "keydown" && e.keyCode == 13)) // out of focus or enter
  1570. {
  1571. consoleX("eventInsertedTagOrUser() -- event blur || eydown .wykopx_quick_search", 1);
  1572. e.preventDefault();
  1573.  
  1574. if (dev) console.log("Type of the element: " + e.target.tagName);
  1575. let editedValue;
  1576. if (e.target.tagName == "INPUT") editedValue = e.target.value.toLowerCase();
  1577. else if (e.target.tagName == "H1") editedValue = e.target.textContent.toLowerCase();
  1578.  
  1579. if (editedValue != e.target.getAttribute("data-wykopx-original-value"))
  1580. {
  1581. smartRedirectBasedOnUserAndTag(getUserFromUrl(editedValue, " "), getTagFromUrl(editedValue, " ", ""));
  1582. }
  1583. }
  1584. }
  1585.  
  1586.  
  1587.  
  1588.  
  1589.  
  1590. /* RIGHT SIDEBAR — DODAJ LISTE OBSERWOWANYCH TAGÓW */
  1591. function addObservedTagsToRightSidebar()
  1592. {
  1593. consoleX("addObservedTagsToRightSidebar()", 1)
  1594.  
  1595. let fetchedValuesArray = [];
  1596.  
  1597. if (settings.observedTagsInRightSidebarEnable)
  1598. {
  1599. // consoleX("addObservedTagsToRightSidebar()", 1)
  1600.  
  1601. checkLocalForageupdatedDate(localStorageObserved, getObservedTags, settings.observedTagsInRightSidebarUpdateInterval * 3600);
  1602.  
  1603. // VUE SENSITIVE
  1604. /*
  1605. data-v-d5500d78
  1606. data-v-38d5cf90
  1607. data-v-7befdafc
  1608. */
  1609. let section_html = `
  1610. <section class="wykopx_your_observed_tags custom-sidebar tags-sidebar" data-v-d5500d78 data-v-38d5cf90 data-v-0a0cb29b>
  1611. <header class="" data-v-d5500d78>
  1612. <h4 data-v-d5500d78>Przejdź na #tag lub @profil</h4>
  1613. </header>
  1614. <div class="content wykopx_quick_search_container" data-v-d5500d78>
  1615. <input type="text" class="wykopx_quick_search" placeholder="#wykopx" title="${promoString}" />
  1616. </div>
  1617. <header data-v-d5500d78>
  1618. <h4 data-v-d5500d78>Twoje obserwowane tagi</h4>
  1619. </header>
  1620. <div class="content" data-v-d5500d78>
  1621. <section class="tags" data-v-7befdafc data-v-d5500d78>
  1622. <ul data-v-7befdafc data-v-d5500d78>
  1623. `;
  1624.  
  1625. localStorageObserved.getItem('observedTags').then(function (tagsArray)
  1626. {
  1627. fetchedValuesArray = tagsArray;
  1628. if (settings.observedTagsInRightSidebarSortAlphabetically)
  1629. {
  1630. fetchedValuesArray.sort(); // sortowanie alfabetyczne tagów
  1631. }
  1632. fetchedValuesArray.forEach(function (tag)
  1633. {
  1634. section_html += `
  1635. <li data-v-7befdafc data-v-d5500d78 title="Przejdź na tag #${tag} ${promoString}">
  1636. <span data-v-7befdafc data-v-d5500d78>#</span><a data-v-7befdafc href="https://go.wykopx.pl/#${tag}" class="hybrid" data-v-d5500d78>${tag}</a>
  1637. </li>`;
  1638. });
  1639. section_html += `</ul></section></div></section>`;
  1640. document.querySelector(`section.sidebar`).insertAdjacentHTML('beforeend', section_html);
  1641. }).catch(function (err) { });
  1642.  
  1643. }
  1644. }
  1645.  
  1646.  
  1647. async function checkLocalForageupdatedDate(wykopxStorageName, updateStorageFunction, updateIntervalSeconds)
  1648. {
  1649. consoleX("checkLocalForageupdatedDate()", 1)
  1650.  
  1651. try
  1652. {
  1653. let storageUpdatedDate = await wykopxStorageName.getItem("storageUpdatedDate");
  1654. if (storageUpdatedDate == null)
  1655. {
  1656. consoleX("Selected info wasn't downloaded. Updating now...", 1)
  1657. updateStorageFunction();
  1658. } else
  1659. {
  1660. const date2 = dayjs(storageUpdatedDate)
  1661. if (loadTime.diff(date2, "second") > parseFloat(updateIntervalSeconds))
  1662. {
  1663. consoleX(`Update interval: ${loadTime.diff(date2, "second")}s > ${updateIntervalSeconds}s`, 1)
  1664. updateStorageFunction();
  1665. }
  1666. }
  1667. } catch (err)
  1668. {
  1669. if (dev) console.log(err);
  1670. }
  1671. }
  1672.  
  1673.  
  1674. async function getObservedTags()
  1675. {
  1676. consoleX(`getObservedTags()`, 1);
  1677.  
  1678. const apiGetObservedTags = `https://wykop.pl/api/v3/profile/users/${loggedUser.username}/observed/tags`;
  1679. consoleX(`async function getObservedTags(${loggedUser.username}`, 1);
  1680.  
  1681. await fetch(apiGetObservedTags, {
  1682. method: "GET", // or 'PUT'
  1683. headers: {
  1684. "Content-Type": "application/json",
  1685. Authorization: "Bearer " + window.localStorage.token,
  1686. },
  1687. })
  1688. .then((response) => response.json())
  1689. .then((responseJSON) =>
  1690. {
  1691. if (dev) console.log("🟢🟢🟢responseJSON")
  1692. if (dev) console.log(responseJSON)
  1693. const responseJSONData = responseJSON.data; // data = [{name: 'wykopwnowymstylu'}, {name: 'wykop'}, {name: 'wykopx'}]
  1694. const fetchedValuesArray = responseJSONData.map(function (item)
  1695. { return item.name; });
  1696.  
  1697. localStorageObserved.setItem("storageUpdatedDate", loadTime)
  1698. localStorageObserved.setItem("observedTags", fetchedValuesArray)
  1699.  
  1700. return true;
  1701. });
  1702. }
  1703.  
  1704.  
  1705.  
  1706.  
  1707.  
  1708.  
  1709.  
  1710.  
  1711. async function POSTDATATOWYKOPX()
  1712. {
  1713. if (dev) console.log(" 🍌🍌🍌🍌 POSTDATATOWYKOPX() ")
  1714.  
  1715.  
  1716. await getSettingsList("blacklists", "tags");
  1717. await getSettingsList("blacklists", "domains");
  1718. await getSettingsList("blacklists", "users");
  1719. await getSettingsList("observed", "tags");
  1720.  
  1721. let settings_list_observed_tags = await localStorageObserved.getItem("settings_list_observed_tags");
  1722. let settings_list_blacklists_domains = await localStorageObserved.getItem("settings_list_blacklists_domains");
  1723. let settings_list_blacklists_users = await localStorageObserved.getItem("settings_list_blacklists_users");
  1724. let settings_list_blacklists_tags = await localStorageObserved.getItem("settings_list_blacklists_tags");
  1725.  
  1726.  
  1727. // await getSettingsList("observed", "users", "following");
  1728. // await getSettingsList("observed", "users", "followers");
  1729. // let settings_list_observed_users_followers = await localStorageObserved.getItem("settings_list_observed_users_followers");
  1730. // let settings_list_observed_users_following = await localStorageObserved.getItem("settings_list_observed_users_following");
  1731.  
  1732. let dataPOST = {};
  1733.  
  1734. // let settings_list_SHA256 = await localStorageObserved.getItem("settings_list_SHA256");
  1735. let settings_list_SHA256 = null;
  1736.  
  1737. if (settings_list_blacklists_tags?.length > 0)
  1738. {
  1739. dataPOST.settings_list_blacklists_tags = settings_list_blacklists_tags;
  1740. dataPOST.sha256 = await SHA256(loggedUser.username + settings_list_blacklists_tags[settings_list_blacklists_tags.length - 1].created_at + settings_list_blacklists_tags[settings_list_blacklists_tags.length - 1].name); // WykopX2023-01-01 23:59:59famemma
  1741. }
  1742. if (settings_list_observed_tags?.length > 0)
  1743. {
  1744. dataPOST.settings_list_observed_tags = settings_list_observed_tags;
  1745. if (settings_list_SHA256 == null) dataPOST.sha256 = await SHA256(loggedUser.username + settings_list_observed_tags[settings_list_observed_tags.length - 1].created_at + settings_list_observed_tags[settings_list_observed_tags.length - 1].name);
  1746. }
  1747. if (settings_list_blacklists_domains?.length > 0)
  1748. {
  1749. dataPOST.settings_list_blacklists_domains = settings_list_blacklists_domains;
  1750. if (settings_list_SHA256 == null) dataPOST.sha256 = await SHA256(loggedUser.username + settings_list_blacklists_domains[settings_list_blacklists_domains.length - 1].created_at + settings_list_blacklists_domains[settings_list_blacklists_domains.length - 1].domain);
  1751. }
  1752. if (settings_list_blacklists_users?.length > 0)
  1753. {
  1754. dataPOST.settings_list_blacklists_users = settings_list_blacklists_users;
  1755. if (settings_list_SHA256 == null) dataPOST.sha256 = await SHA256(loggedUser.username + settings_list_blacklists_users[settings_list_blacklists_users.length - 1].created_at + settings_list_blacklists_users[settings_list_blacklists_users.length - 1].username);
  1756. }
  1757.  
  1758.  
  1759.  
  1760.  
  1761. if (Object.keys(dataPOST).length >= 2)
  1762. {
  1763. if (dev) console.log(" 🍌🍌🍌🍌 Sending this data to api.wykopx.pl: ", dataPOST)
  1764.  
  1765. // TODO
  1766. // fetch('https://api.wykopx.pl/api/v3/', {
  1767. // method: 'POST',
  1768. // headers: {
  1769. // 'Content-Type': 'application/json'
  1770. // },
  1771. // body: JSON.stringify(dataPOST)
  1772. // })
  1773. // .then(response => response.text())
  1774. // .then(data =>
  1775. // {
  1776. // localStorageObserved.setItem(`settings_list_update`, loadTime);
  1777.  
  1778. // if(dev) console.log(" 🍌🍌🍌🍌 response from api.wykopx.pl: ")
  1779. // if(dev) console.log(data)
  1780. // })
  1781. // .catch(error => console.error('Error:', error));
  1782. }
  1783. }
  1784.  
  1785. /*
  1786. getSettingsList("blacklists", "tags");
  1787. getSettingsList("blacklists", "domains");
  1788. getSettingsList("blacklists", "users");
  1789. getSettingsList("observed", "tags");
  1790. getSettingsList("observed", "users", "following");
  1791. getSettingsList("observed", "users", "followers");
  1792. */
  1793.  
  1794. let lastBlacklistTagCreatedAt = null;
  1795. let lastBlacklistTagCreatedAtSHA256 = null;
  1796.  
  1797.  
  1798. async function getSettingsList(blacklistsOrObserved, type, subtype)
  1799. {
  1800. consoleX(`getSettingsList(blacklistsOrObserved: ${blacklistsOrObserved}, type: ${type}, subtype: ${subtype})`, 1);
  1801.  
  1802. let page = 1;
  1803. let totalFetched = 0;
  1804. let totalRecords = null;
  1805. let fetchedValuesArray = [];
  1806.  
  1807.  
  1808. while (totalRecords === null || totalFetched < totalRecords)
  1809. {
  1810. let apiGetPaginatedURL = null;
  1811. if (blacklistsOrObserved == "blacklists") apiGetPaginatedURL = `https://wykop.pl/api/v3/settings/blacklists/${type}?page=${page}`;
  1812. else if (blacklistsOrObserved == "observed")
  1813. {
  1814. if (type == "tags") apiGetPaginatedURL = `https://wykop.pl/api/v3/profile/users/${loggedUser.username}/observed/${type}?page=${page}`;
  1815. else if (type == "users" && subtype) apiGetPaginatedURL = `https://wykop.pl/api/v3/profile/users/${loggedUser.username}/observed/${type}/${subtype}?page=${page}`
  1816. }
  1817. const response = await fetch(apiGetPaginatedURL, {
  1818. method: "GET",
  1819. headers: {
  1820. "Content-Type": "application/json",
  1821. Authorization: "Bearer " + window.localStorage.token,
  1822. },
  1823. });
  1824.  
  1825. const responseJSON = await response.json();
  1826. const responseJSONData = responseJSON.data;
  1827.  
  1828. // if (blacklistsOrObserved == "blacklists" && type == "tags")
  1829. // {
  1830. // lastBlacklistTagCreatedAt = loggedUser.username + responseJSONData[responseJSONData.length - 1].created_at + responseJSONData[responseJSONData.length - 1].name; // WykopX2023-01-01 23:59:59famemma
  1831. // lastBlacklistTagCreatedAtSHA256 = await SHA256(lastBlacklistTagCreatedAt);
  1832. // localStorageObserved.setItem(`settings_list_SHA256`, lastBlacklistTagCreatedAtSHA256);
  1833. // }
  1834.  
  1835. let valueName = "name";
  1836. if (type == "users") valueName = "username"
  1837. if (type == "domains") valueName = "domain"
  1838. fetchedValuesArray = fetchedValuesArray.concat(responseJSONData.map(item => item[valueName])); // data = [{ name: 'wykopwnowymstylu' }, { name: 'wykop' }, { name: 'wykopx' }]
  1839. totalFetched += responseJSONData.length;
  1840. totalRecords = responseJSON.pagination.total;
  1841. page++;
  1842. }
  1843.  
  1844. if (dev) console.log(`🔻fetchedValuesArray ${blacklistsOrObserved}/${type} FINISHED`)
  1845. if (dev) console.log(fetchedValuesArray)
  1846.  
  1847. // localforage
  1848. localStorageObserved.setItem(`settings_list_${blacklistsOrObserved}_${type}${subtype ? "_" + subtype : ""}`, fetchedValuesArray); // zapisuje jako Array: ["tag1", "tag2", "tag3"]
  1849.  
  1850. // localstorage
  1851. //localStorage.setItem(`settings_list_${blacklistsOrObserved}_${type}${subtype ? "_" + subtype : ""}`, JSON.stringify(fetchedValuesArray)); // zapisuje jako Array: ["tag1", "tag2", "tag3"]
  1852. //localStorage.setItem("blacklisted_tags", fetchedValuesArray); // zapisuje jako string: tag1,tag2,tag3
  1853. return true;
  1854. }
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862. function switchChanged(PointerEvent, cssFilterName)
  1863. {
  1864. consoleX(`switchChanged(cssFilterName: ${cssFilterName})`, 1);
  1865.  
  1866. /*
  1867. this -> clicked element == event.target
  1868. PointerEvent — even object
  1869. */
  1870. //body.dataset[cssFilterName] = this.value; // <body data-wxs_switch_nsfw="1"]
  1871. if (this.value == 0) body.dataset[cssFilterName] = "OFF_0"; // <body data-wxs_switch_nsfw="OFF"]
  1872. else if (this.value > 0) body.dataset[cssFilterName] = `ON_PLUS_${this.value}`; // <body data-wxs_switch_nsfw="ON_PLUS_1"] // "ON_PLUS_1", "ON_PLUS_2", "ON_PLUS_3"
  1873. else body.dataset[cssFilterName] = `ON_MINUS_${Math.abs(this.value)}`; // <body data-wxs_switch_nsfw="ON_MINUS_1"] <body data-wxs_switch_nsfw="-1"]
  1874.  
  1875. if (cssFilterName == "wxs_switch_entries_photo_viewer")
  1876. {
  1877. const switchImagesInput = document.getElementById("switchImages");
  1878. if (this.value > 0 && switchImagesInput.value != 1)
  1879. {
  1880. switchImagesInput.value = 1;
  1881. switchChanged.call(switchImagesInput, null, "wxs_switch_entries_images")
  1882. }
  1883. else if (this.value == 0 && switchImagesInput.value != 0)
  1884. {
  1885. switchImagesInput.value = 0;
  1886. switchChanged.call(switchImagesInput, null, "wxs_switch_entries_images")
  1887. }
  1888.  
  1889. }
  1890. if (cssFilterName == "wxs_switch_entries_images" && this.value <= 0)
  1891. {
  1892. const switchPhotoViewerInput = document.getElementById("switchPhotoViewer");
  1893. if (switchPhotoViewerInput.value != 0)
  1894. {
  1895. switchPhotoViewerInput.value = 0;
  1896. switchChanged.call(switchPhotoViewerInput, null, "wxs_switch_entries_photo_viewer")
  1897. }
  1898. }
  1899. }
  1900. if (settings.wxsSwitchesEnable)
  1901. {
  1902. document.addEventListener("input", (event) =>
  1903. {
  1904. if (settings.wxsSwitchNSFW && event.target.closest("input#switchNSFW")) switchChanged.call(event.target, event, "wxs_switch_entries_nsfw");
  1905. else if (settings.wxsSwitchAdult && event.target.closest("input#switchAdult")) switchChanged.call(event.target, event, "wxs_switch_entries_adult");
  1906. else if (settings.wxsSwitchPhotoViewer && event.target.closest("input#switchPhotoViewer")) switchChanged.call(event.target, event, "wxs_switch_entries_photo_viewer");
  1907. else if (settings.wxsSwitchImages && event.target.closest("input#switchImages")) switchChanged.call(event.target, event, "wxs_switch_entries_images");
  1908. else if (settings.wxsSwitchYouTube && event.target.closest("input#switchYouTube")) switchChanged.call(event.target, event, "wxs_switch_entries_youtube");
  1909. else if (settings.wxsSwitchTags && event.target.closest("input#switchTags")) switchChanged.call(event.target, event, "wxs_switch_entries_tags");
  1910. else if (settings.wxsSwitchByUserColor && event.target.closest("input#switchByUserColor")) switchChanged.call(event.target, event, "wxs_switch_by_user_color");
  1911. else if (settings.wxsSwitchByUserGender && event.target.closest("input#switchByUserGender")) switchChanged.call(event.target, event, "wxs_switch_by_user_gender");
  1912. });
  1913. }
  1914.  
  1915.  
  1916. function addSwitchButtons()
  1917. {
  1918. consoleX("addSwitchButtons()", 1)
  1919.  
  1920. let buttonsWrapper = document.createElement("section");
  1921. buttonsWrapper.classList.add("wxs_switches_container");
  1922.  
  1923. buttonsWrapper.innerHTML = `<datalist id="markers">
  1924. <option value="-1" label="OFF"></option>
  1925. <option value="0" label=""></option>
  1926. <option value="1" label="ON">ON</option>
  1927. </datalist>`;
  1928.  
  1929. if (settings.wxsSwitchNSFW)
  1930. {
  1931. buttonsWrapper.innerHTML += `<div class="wxs_switch switchNSFW showOnLinksStream showOnEntriesStream showOnEntryPage">
  1932. <div>
  1933. <label class="label_ON_MINUS_1" title=" Wpisy z tagiem #nsfw są ukryte">Bez #nsfw</label>
  1934. <label class="label_OFF_0">#nsfw</label>
  1935. <label class="label_ON_PLUS_1" title=" Wyświetlane są tylko wpisy z tagiem #nsfw">Tylko #nsfw</label>
  1936. </div>
  1937. <div>
  1938. <input type="range" id="switchNSFW" list="markers" name="switchNSFW" min="-1" max="1" step="1" value="0" />
  1939. </div>
  1940. </div>`;
  1941. }
  1942. if (settings.wxsSwitchAdult)
  1943. {
  1944. buttonsWrapper.innerHTML += `<div class="wxs_switch switchAdult showOnLinksStream showOnEntriesStream showOnEntryPage">
  1945. <div>
  1946. <label class="label_ON_MINUS_1" title=" Treści oznaczne jako materiały 18+ są ukryte">Bez 18+</label>
  1947. <label class="label_OFF_0">18+</label>
  1948. <label class="label_ON_PLUS_1" title=" Wyświetlane są tylko treści oznaczone jako 18+ ">Tylko 18+</label>
  1949. </div>
  1950. <div>
  1951. <input type="range" id="switchAdult" list="markers" name="switchAdult" min="-1" max="1" step="1" value="0" />
  1952. </div>
  1953. </div>`;
  1954. }
  1955.  
  1956. if (settings.wxsSwitchByUserColor)
  1957. {
  1958. buttonsWrapper.innerHTML += `<div class="wxs_switch switchByUserColor showOnLinksStream showOnEntriesStream showOnLinkPage showOnEntriesStream showOnEntryPage">
  1959. <div>
  1960. <label class="label_OFF_0">Kolory</label>
  1961. <label class="label_ON_PLUS_1">Bez zielonek</label>
  1962. <label class="label_ON_PLUS_2">Tylko bordo</label>
  1963. </div>
  1964. <div>
  1965. <input type="range" id="switchByUserColor" list="markers" name="switchByUserColor" min="0" max="2" step="1" value="0" />
  1966. </div>
  1967. </div>`;
  1968. }
  1969. if (settings.wxsSwitchByUserGender)
  1970. {
  1971. buttonsWrapper.innerHTML += `<div class="wxs_switch switchByUserGender showOnLinkPage showOnEntriesStream showOnEntryPage">
  1972. <div>
  1973. <label class="label_ON_MINUS_1" title="">Bez różowych</label>
  1974. <label class="label_OFF_0">Różowe</label>
  1975. <label class="label_ON_PLUS_1" title="">Tylko różowe </label>
  1976. </div>
  1977. <div>
  1978. <input type="range" id="switchByUserGender" list="markers" name="switchByUserGender" min="-1" max="1" step="1" value="0" />
  1979. </div>
  1980. </div>`;
  1981. }
  1982.  
  1983. if (settings.wxsSwitchYouTube)
  1984. {
  1985. buttonsWrapper.innerHTML += `<div class="wxs_switch switchYouTube showOnLinksStream showOnEntriesStream showOnEntriesStream showOnEntryPage">
  1986. <div>
  1987. <label class="label_ON_MINUS_1" title=" Treści bez filmików YouTube">Bez YT</label>
  1988. <label class="label_OFF_0">YouTube</label>
  1989. <label class="label_ON_PLUS_1" title=" Tylko YouTube ">Tylko YT</label>
  1990. </div>
  1991. <div>
  1992. <input type="range" id="switchYouTube" list="markers" name="switchYouTube" min="-1" max="1" step="1" value="0" />
  1993. </div>
  1994. </div>`;
  1995. }
  1996. if (settings.wxsSwitchTags)
  1997. {
  1998. buttonsWrapper.innerHTML += `<div class="wxs_switch switchTags showOnEntriesStream">
  1999. <div>
  2000. <label class="label_ON_MINUS_1" title=" Wyświetlane są tylko wpisy nie zawierające w treści żadnych #tagów.\n Wpisy zawierające jakiekolwiek #tagi są ukryte">Tylko nocna 🌙</label>
  2001. <label class="label_OFF_0">#tagi</label>
  2002. <label class="label_ON_PLUS_1" title=" Wyświetlane są tylko wpisy zawierające minimum jeden #tag.\n Wpisy bez żadnego #tagu są ukryte.">Tylko #tagi #️⃣</label>
  2003. </div>
  2004. <div>
  2005. <input type="range" id="switchTags" list="markers" name="switchTags" min="-1" max="1" step="1" value="0" />
  2006. </div>
  2007. </div>`;
  2008. }
  2009.  
  2010. if (settings.wxsSwitchImages)
  2011. {
  2012. buttonsWrapper.innerHTML += `<div class="wxs_switch switchImages showOnLinkPage showOnEntriesStream showOnEntryPage">
  2013. <div>
  2014. <label class="label_ON_MINUS_2" title=" Pokazuje tylko wpisy, które nie mają obrazków. Ukrywa wszystkie wpisy z obrazkami lub GIF-ami">Bez obr. 🚫</label>
  2015. <label class="label_ON_MINUS_1" title=" Ukrywa obrazki we wpisach i komentarzach pozostawiając tekst">Ukryj obr.</label>
  2016. <label class="label_OFF_0">Obrazki</label>
  2017. <label class="label_ON_PLUS_1" title=" Pokazuje tylko wpisy, które zawierają obrazki">Tylko obr.</label>
  2018. </div>
  2019. <div>
  2020. <input type="range" id="switchImages" list="markers" name="switchImages" min="-2" max="1" step="1" value="0" />
  2021. </div>
  2022. </div>`;
  2023. }
  2024.  
  2025. if (settings.wxsSwitchPhotoViewer)
  2026. {
  2027. buttonsWrapper.innerHTML += `<div class="wxs_switch switchPhotoViewer showOnEntriesStream">
  2028. <div>
  2029. <label class="label_OFF_0">PhotoViewer</label>
  2030. <label class="label_ON_PLUS_1">PhotoViewer ✔</label>
  2031. <label class="label_ON_PLUS_2">PhotoViewer ✅</label>
  2032. </div>
  2033. <div>
  2034. <input type="range" id="switchPhotoViewer" list="markers" name="switchPhotoViewer" min="0" max="2" step="1" value="0" />
  2035. </div>
  2036. </div>`;
  2037. }
  2038.  
  2039.  
  2040.  
  2041. const nav = document.querySelector("body header div.right nav");
  2042. nav.parentNode.insertBefore(buttonsWrapper, nav);
  2043. }
  2044.  
  2045.  
  2046.  
  2047.  
  2048. // ACTION BOX BUTTONS
  2049. document.addEventListener("click", (event) =>
  2050. {
  2051. //if (event.target.closest("button.wxsDownVote")) downVoteLink.call(event.target, event); // zakopywanie znaleziska na głównej
  2052. if (settings.actionBoxEnable)
  2053. {
  2054. if (settings.filterUserComments || settings.filterUserReplies)
  2055. {
  2056. if (event.target.closest("button.wxs_filter_off")) filterUserOff.call(event.target, event, event.target.closest("button.wxs_filter_off"));
  2057.  
  2058. if (settings.filterUserComments)
  2059. {
  2060. if (event.target.closest("button.wxs_filter_on_user")) filterUserComments.call(event.target, event, event.target.closest("button.wxs_filter_on_user"), "userComments");
  2061. }
  2062. if (settings.filterUserReplies)
  2063. {
  2064. if (event.target.closest("button.wxs_filter_on_replies")) filterUserComments.call(event.target, event, event.target.closest("button.wxs_filter_on_replies"), "userReplies");
  2065. }
  2066. }
  2067.  
  2068. if (settings.mirkoukrywaczEnable)
  2069. {
  2070. if (event.target.closest("button.wxs_minimize")) minimizeThisEntry.call(event.target, event);
  2071. if (event.target.closest("button.wxs_maximize")) maximizeThisEntry.call(event.target, event);
  2072.  
  2073. if (event.target.closest("button.wxs_hide")) hideThisEntry.call(event.target, event, event.target.closest("button.wxs_hide")); // > (this, arg1, arg2)
  2074.  
  2075.  
  2076. if (event.target.closest(".wykopx_mirkoukrywacz_unhide")) maximizeThisEntry.call(event.target, event, event.target.dataset.wxs_object_id);
  2077.  
  2078. }
  2079. }
  2080.  
  2081. if (settings.mirkoukrywaczEnable)
  2082. {
  2083. if (event.target.closest("#wxs_mirkoukrywacz_delete_all")) mirkoukrywaczRemoveTooOld.call(event.target, event,
  2084. {
  2085. days: 0,
  2086. blockingType: "all",
  2087. resource: "all",
  2088. });
  2089.  
  2090. if (event.target.closest("#wxs_mirkoukrywacz_delete_older_than_7_days"))
  2091. {
  2092. mirkoukrywaczRemoveTooOld.call(event.target, event, {
  2093. days: document.getElementById("wxs_mirkoukrywacz_delete_timespan").value,
  2094. blockingType: document.getElementById("wxs_mirkoukrywacz_delete_block_type").value,
  2095. resource: document.getElementById("wxs_mirkoukrywacz_delete_resource").value,
  2096. });
  2097. }
  2098. }
  2099. });
  2100.  
  2101.  
  2102.  
  2103.  
  2104.  
  2105.  
  2106.  
  2107.  
  2108.  
  2109. /* ---------------- MIRKOUKRYWACZ MENU ----------------- */
  2110. function saveThisEntryContent(PointerEvent)
  2111. {
  2112. consoleX("saveThisEntryContent()", 1)
  2113. let resource = "unknown";
  2114. let entry_stream = this?.closest(".stream");
  2115. if (entry_stream)
  2116. {
  2117. if (entry_stream.classList.contains("microblog")) resource = "entry";
  2118. else if (entry_stream.classList.contains("entry-comments")) resource = "entry";
  2119. else if (entry_stream.classList.contains("entry-subcomments")) resource = "entry-subcomments";
  2120. else if (entry_stream.classList.contains("link-comments")) resource = "link-comments";
  2121.  
  2122. let entry = this.closest(".entry");
  2123. let comment_id = entry.id.split("-")[1];
  2124. let username = entry.querySelector("a.username span").innerText;
  2125. let text = entry.querySelector("div.content div.wrapper").innerText.replace(/\n/g, " ");
  2126.  
  2127. let grandcomment_id = comment_id; /* id nad-komentarza */
  2128. if (resource == "entry-subcomments")
  2129. {
  2130. let entry_grandparent = entry.parentNode.closest(".entry");
  2131. grandcomment_id = entry_grandparent.id.split("-")[1];
  2132. }
  2133. mirkoukrywaczBlockNewElement(entry.id, grandcomment_id, username, text, resource, "saved");
  2134. }
  2135. }
  2136.  
  2137. function filterUserOff(event, buttonElement)
  2138. {
  2139. consoleX(`filterUserOff()`, 1);
  2140.  
  2141. if (body.dataset.wxs_filter) delete body.dataset.wxs_filter // <body data-wxs_filter>
  2142. if (body.dataset.wxs_filter_style) delete body.dataset.wxs_filter_style
  2143. if (body.dataset.wxs_filter_username) delete body.dataset.wxs_filter_username
  2144.  
  2145. // TODO check -> document.getElementById('wxs_css_filter_user_comments')?.parentNode?.removeChild(styleElement);
  2146.  
  2147. let wxs_css_style_filter_user_comments = head.querySelector("#wxs_css_filter_user_comments");
  2148. if (wxs_css_style_filter_user_comments)
  2149. {
  2150. wxs_css_style_filter_user_comments.remove();
  2151. }
  2152. }
  2153.  
  2154.  
  2155. function filterUserComments(event, buttonElement, filterType)
  2156. {
  2157. consoleX(`filterUserComments()`, 1);
  2158.  
  2159. // filterUserComments
  2160. // filterType => "userComments" / "userReplies"
  2161. /*
  2162. this -> clicked element == event.target
  2163. event — PointerEvent object
  2164. */
  2165.  
  2166.  
  2167.  
  2168. const css_id = "wxs_css_filter_user_comments";
  2169.  
  2170. const filterUsername = buttonElement.dataset.wxs_author_username;
  2171. const filterUserGender = buttonElement.dataset.wxs_author_gender ? buttonElement.dataset.wxs_author_gender : "m";
  2172.  
  2173. let filterStyles =
  2174. [
  2175. `border: 3px solid gray!important; opacity: 0.3!important; `,
  2176. `filter: grayscale(1); `,
  2177. `display: none!important; `,
  2178. ]
  2179.  
  2180. let filterStyleIndex = 0;
  2181. let wxs_css_style_filter_user_comments = document.getElementById(css_id);
  2182.  
  2183. if (wxs_css_style_filter_user_comments) // jest już nałożony jakiś filtr
  2184. {
  2185. if (body.dataset.wxs_filter == filterType && body.dataset.wxs_filter_username == filterUsername) // ten sam typ filtra i uzytkownik - zmiana stylu
  2186. {
  2187. let currentFilterStyleIndex = parseInt(body.dataset.wxs_filter_style);
  2188.  
  2189. filterStyleIndex = currentFilterStyleIndex + 1;
  2190. if (filterStyleIndex == filterStyles.length)
  2191. {
  2192. filterUserOff();
  2193. return false;
  2194. }
  2195. }
  2196. else // zachowujemy ten sam styl bo zmienil sie typ filtra lub filtrowany uzytkownik
  2197. {
  2198. filterStyleIndex = parseInt(body.dataset.wxs_filter_style);
  2199. }
  2200. }
  2201.  
  2202. body.dataset.wxs_filter_style = filterStyleIndex.toString()
  2203.  
  2204. body.dataset.wxs_filter_username = filterUsername;
  2205.  
  2206. let css = "";
  2207.  
  2208. if (filterType == "userComments")
  2209. {
  2210. body.dataset.wxs_filter = "userComments"; // <body data-wxs_filter="userComments">
  2211.  
  2212. css = `.wxs_menu_action_box > .wxs_filter_off
  2213. {
  2214. display: flex!important;
  2215. }
  2216.  
  2217. /* odstęp pomiędzy komentarzami */
  2218. div.comments > section.stream > div.content
  2219. {
  2220. display: flex;
  2221. flex-direction: column;
  2222. row-gap: 20px;
  2223. padding: 20px;
  2224. }
  2225. /* odfiltrowane znaleziska */
  2226. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .home-page, .observed-page, .profile-page, .tag-page, .hits-page, .upcoming-page) > section section.stream > div.content > section.link-block:has(article > div.content > section.info a.username[href="/ludzie/${filterUsername}"])
  2227. {
  2228. border: 1px solid ${filterUserGender == "f" ? "var(--rozowyPasek1, rgba(192, 72, 167, 1))" : "var(--niebieskiPasek1, rgba(67, 131, 175, 1))"} !important;
  2229. }
  2230.  
  2231.  
  2232. /* strona wpisu - filtrowane komentarze */
  2233. body > section > div.main-content > main.main > section > div.content > section.entry-page > section.entry > section.entry-comments > div.content > section.entry.detailed > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2234.  
  2235. /* strona streamu wpisów - wpisy filtrowanego użytkownika */
  2236. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2237.  
  2238. /* strona streamu wpisów - komentarze filtrowanego użytkownika */
  2239. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2240.  
  2241. /* strona znaleziska - komentarze i subkomentarze filtrowanego użytkownika */
  2242. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content section.entry:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])
  2243.  
  2244. {
  2245. border: 1px solid ${filterUserGender == "f" ? "var(--rozowyPasek1, rgba(192, 72, 167, 1))" : "var(--niebieskiPasek1, rgba(67, 131, 175, 1))"} !important;
  2246. }
  2247.  
  2248.  
  2249. /* strony ze znaleziskami oprócz głównej - znaleziska autora, odfiltrowwanie znalezisk innych użytkowników */
  2250. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .home-page, .observed-page, .profile-page, .tag-page, .hits-page, .upcoming-page) > section section.stream > div.content > section.link-block:not(:has(article > div.content > section.info a.username[href="/ludzie/${filterUsername}"])),
  2251.  
  2252. /* strona główna - znaleziska autora, odfiltrowwanie znalezisk innych użytkowników a takze wpisow przypietych przez moderacje */
  2253. .pub-slot-wrapper:has(section.premium-pub.link-block),
  2254. body > section > div.main-content > main.main > section > div.content > section.home-page > section section.stream > div.content > section:is(.link-block:not(:has(article > div.content > section.info a.username[href="/ludzie/${filterUsername}"])),
  2255. .entry:not(:has(> article > header > div.right > div > div.tooltip-slot > span > a.username[href="/ludzie/${filterUsername}"]))),
  2256.  
  2257. /* strona wpisu-ukrycie komentarzy nie-filtrowanych użytkowników */
  2258. body > section > div.main-content > main.main > section > div.content > section.entry-page > section.entry > section.entry-comments > div.content > section.entry.detailed > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])),
  2259.  
  2260. /* strona streamu wpisów-ukrycie wpisów w ktorych nie ma wypowiedzi filtrowanego uzytkownika-ani wpis, ani komentarz*/
  2261. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:not(:has(article > header > div.right a.username[href="/ludzie/${filterUsername}"])),
  2262.  
  2263. /* strona streamu wpisów-komentarze pod wpisami na streamach które zawierają komentarz filtrowanego użytkownika */
  2264. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:has(article > header > div.right a.username[href="/ludzie/${filterUsername}"]) > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])),
  2265.  
  2266. /* strona streamu wpisów-komentarze pod wpisami na streamach które zawierają komentarz filtrowanego użytkownika */
  2267. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:has(article > header > div.right a.username[href="/ludzie/${filterUsername}"]) > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])),
  2268.  
  2269. /* strona znaleziska-komentarze bez subkomentarzy filtrowanego użytkownika */
  2270. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content > section.entry:not(:has(div.right > div a.username[href="/ludzie/${filterUsername}"])),
  2271.  
  2272. /* strona znaleziska-subkomentarze nie-filtrowanego użytkownika */
  2273. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content > section.entry > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(> article > header > div.right > div a.username[href="/ludzie/${filterUsername}"]))
  2274. {
  2275. ${filterStyles[filterStyleIndex]}
  2276. }`;
  2277. }
  2278. else if (filterType == "userReplies")
  2279. {
  2280. body.dataset.wxs_filter = "userReplies"; // <body data-wxs_filter="userReplies">
  2281.  
  2282. css = `.wxs_menu_action_box > .wxs_filter_off
  2283. {
  2284. display: flex!important;
  2285. }
  2286.  
  2287. /* odstęp pomiędzy komentarzami */
  2288. div.comments > section.stream > div.content
  2289. {
  2290. display: flex;
  2291. flex-direction: column;
  2292. row-gap: 20px;
  2293. padding: 20px;
  2294. }
  2295.  
  2296. /* WYRÓŻNIENIE KOMENTARZY FILTROWANEGO UŻYTKOWNIKA */
  2297. /* strona wpisu-filtrowane komentarze */
  2298. body > section > div.main-content > main.main > section > div.content > section.entry-page > section.entry > section.entry-comments > div.content > section.entry.detailed > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2299.  
  2300. /* strona streamu wpisów-wpisy filtrowanego użytkownika */
  2301. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2302.  
  2303. /* strona streamu wpisów-komentarze filtrowanego użytkownika */
  2304. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"]),
  2305.  
  2306. /* strona znaleziska-komentarze i subkomentarze filtrowanego użytkownika */
  2307. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content section.entry:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])
  2308. {
  2309. border: 2px solid ${filterUserGender == "f" ? "var(--rozowyPasek1, rgba(192, 72, 167, 1))" : "var(--niebieskiPasek1, rgba(67, 131, 175, 1))"} !important;
  2310. }
  2311.  
  2312.  
  2313. /* WYRÓŻNIENIE ODPOWIEDZI Z OZNACZONYM FILTROWANYM UŻYTKOWNIKIEM */
  2314. /* strona wpisu - filtrowane komentarze */
  2315. body > section > div.main-content > main.main > section > div.content > section.entry-page > section.entry > section.entry-comments > div.content > section.entry.detailed > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > a[href="/ludzie/${filterUsername}"]),
  2316.  
  2317. /* strona streamu wpisów-komentarze z oznaczonym wołaniem filtrowanego użytkownika */
  2318. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:has(> article > div.edit-wrapper > div.content > section.entry-content > div.wrapper a[href="/ludzie/${filterUsername}"]),
  2319.  
  2320. /* strona znaleziska - komentarze i subkomentarze filtrowanego użytkownika */
  2321. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content section.entry:has(> article > header > div.right a.username[href="/ludzie/${filterUsername}"])
  2322. {
  2323. border: 2px solid var(--nicknameOrange1, rgba(255, 89, 23, 1))!important;
  2324. }
  2325.  
  2326. /* wyróżnienie tagowanego w odpowiedzi */
  2327. section.entry.reply > article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > a[href="/ludzie/${filterUsername}"]
  2328. {
  2329. background-color: var(--whiteOpacity1);
  2330. padding: 0px 5px 0px 5px;
  2331. margin-right: 5px;
  2332. border-bottom: 1px solid;
  2333. font-weight: bolder!important;
  2334. }
  2335.  
  2336. /* UKRYCIE KOMENTARZY, KTÓRE NIE SĄ FILTROWANEGO UŻYTKOWNIKA ANI NIE WOŁAJĄ FILTROWANEGO UŻYTKOWNIKA */
  2337.  
  2338. /* strona wpisu - ukrycie komentarzy nie-filtrowanych użytkowników */
  2339. body > section > div.main-content > main.main > section > div.content > section.entry-page > section.entry > section.entry-comments > div.content > section.entry.detailed > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(> article > header a.username[href="/ludzie/${filterUsername}"], > article > div.edit-wrapper > div.content > section.entry-content > div.wrapper a[href="/ludzie/${filterUsername}"])),
  2340.  
  2341. /* strona streamu wpisów - ukrycie wpisów i komentarzy które nie są wypowiedziami filtrowanego uzytkownika ani nie zawierają w treści otagowanego filtrowanego użytkownika */
  2342. body > section > div.main-content > main.main > section > div.content > section:is(.bucket-page, .search-page, .category-page, .favourites-page, .observed-page, .profile-page, .tag-page, .microblog-page) > section section.stream > div.content > section.entry:not(:has(div > a[href="/ludzie/${filterUsername}"])),
  2343.  
  2344. /* strona znaleziska - komentarze bez subkomentarzy filtrowanego użytkownika */
  2345. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content > section.entry:not(:has(a.username[href="/ludzie/${filterUsername}"])),
  2346.  
  2347. /* strona znaleziska-subkomentarze nie-filtrowanego użytkownika */
  2348. body > section > div.main-content > main.main > section > div.content > section.link-page > section.link > section.comments > section.stream.link-comments > div.content > section.entry > div.comments > section.stream.entry-subcomments > div.content > section.entry.reply:not(:has(a.username[href="/ludzie/${filterUsername}"]))
  2349. {
  2350. ${filterStyles[filterStyleIndex]}
  2351. }`;
  2352. }
  2353.  
  2354. if (dev) console.log("css");
  2355. if (dev) console.log(css);
  2356.  
  2357. if (wxs_css_style_filter_user_comments)
  2358. {
  2359. wxs_css_style_filter_user_comments.textContent = css;
  2360. }
  2361. else
  2362. {
  2363. wxs_css_style_filter_user_comments = document.createElement('style');
  2364. wxs_css_style_filter_user_comments.id = css_id;
  2365. wxs_css_style_filter_user_comments.dataset.wxs_filter_type = filterStyleIndex;
  2366.  
  2367. wxs_css_style_filter_user_comments.appendChild(document.createTextNode(css));
  2368. head.appendChild(wxs_css_style_filter_user_comments);
  2369. }
  2370.  
  2371. }
  2372.  
  2373. function minimizeThisEntry(PointerEvent) // PointerEvent.altKey, .ctrlKey, .shiftKey, .target (Element)
  2374. {
  2375. consoleX("minimizeThisEntry()", 1)
  2376.  
  2377. let sectionEntry = this?.closest('.entry');
  2378. if (sectionEntry)
  2379. {
  2380. mirkoukrywaczBlockNewElement(sectionEntry, undefined, "minimized");
  2381. }
  2382. }
  2383.  
  2384. function maximizeThisEntry(PointerEvent, object_id)
  2385. {
  2386. consoleX("maximizeThisEntry()", 1)
  2387.  
  2388. let sectionEntry = this?.closest('.entry');
  2389.  
  2390. if (sectionEntry)
  2391. {
  2392. mirkoukrywaczUnblockElement(sectionEntry);
  2393. }
  2394. else if (object_id)
  2395. {
  2396. mirkoukrywaczUnblockElement(undefined, object_id);
  2397. }
  2398. }
  2399.  
  2400. // UKRYWANIE WPISU I KOMENTARZY-DODAWANIE DO MIRKOUKRYWACZA
  2401. function hideThisEntry(event, buttonElement)
  2402. {
  2403. consoleX(`hideThisEntry()`, 1);
  2404.  
  2405. // console.log("hideThisEntry - event", event);
  2406. // console.log("hideThisEntry - button", button);
  2407. // console.log("hideThisEntry - button.dataset.wxs_resource", button.dataset.wxs_resource);
  2408. // console.log("hideThisEntry - this", this); // this > span
  2409.  
  2410. let resource = buttonElement.dataset.wxs_resource;
  2411. let entry_stream = buttonElement?.closest(".stream");
  2412.  
  2413. if (entry_stream)
  2414. {
  2415. let sectionObject;
  2416.  
  2417. if (resource == "entry" || resource == "entry_comment" || resource == "link_comment")
  2418. {
  2419. sectionObject = buttonElement.closest(".entry");
  2420. }
  2421. else if (resource == "link")
  2422. {
  2423. sectionObject = buttonElement.closest('.link-block');
  2424. }
  2425. if (dev) console.log("sectionObject");
  2426. if (dev) console.log(sectionObject);
  2427.  
  2428. if (sectionObjectIntersectionObserver) sectionObjectIntersectionObserver.unobserve(sectionObject);
  2429. mirkoukrywaczBlockNewElement(sectionObject, null, "hidden");
  2430. sectionObject.remove();
  2431. }
  2432. }
  2433.  
  2434.  
  2435.  
  2436.  
  2437.  
  2438.  
  2439. // getWykopXAPIData("entry", "first-by-date") -> https://archiwum.wykopx.pl/api/entry/first-by-date
  2440. async function getWykopXAPIData(...pathAPIargs)
  2441. {
  2442. if (dev) console.log("❎ getWykopXAPIData", pathAPIargs)
  2443. try
  2444. {
  2445. let apiURL = `https://archiwum.wykopx.pl/api/${pathAPIargs.join('/')}`;
  2446. if (dev) console.log("❎ getWykopXAPIData apiURL: ", apiURL)
  2447.  
  2448. const response = await fetch(apiURL,
  2449. {
  2450. method: "GET",
  2451. headers: {
  2452. "Content-Type": "application/json"
  2453. },
  2454. });
  2455.  
  2456. if (dev) console.log("❎ getWykopXAPIData response:", response)
  2457. let data;
  2458. try
  2459. {
  2460. data = await response.json();
  2461. if (dev) console.log("❎ getWykopXAPIData data: ", data)
  2462. }
  2463. catch (error)
  2464. {
  2465. data = response.status; // 204
  2466. if (dev) console.log("❎ getWykopXAPIData-response.status")
  2467. }
  2468. return data;
  2469. }
  2470. catch (error)
  2471. {
  2472. console.error(`❎ call to WykopX API failed: ${error}`);
  2473. throw error;
  2474. }
  2475. }
  2476.  
  2477. // calls Wykop API url: getWykopAPIData("profile") -> https://wykop.pl/api/v3/profile
  2478. // getWykopAPIData("profile", "users", username } -> https://wykop.pl/api/v3/profile/users/NadiaFrance
  2479. // getWykopAPIData("profile"} -> https://wykop.pl/api/v3/profile
  2480. async function getWykopAPIData(...pathAPIargs)
  2481. {
  2482. if (dev) console.log("getWykopAPIData(), pathAPIargs: ", pathAPIargs)
  2483.  
  2484. try
  2485. {
  2486. let data = await callWykopAPI("GET", ...pathAPIargs);
  2487. return data;
  2488.  
  2489. }
  2490. catch (error)
  2491. {
  2492. console.error(`Fetch failed: ${error}`);
  2493. throw error;
  2494. }
  2495. }
  2496. async function postWykopAPIData(...pathAPIargs)
  2497. {
  2498. if (dev) console.log("postWykopAPIData(), pathAPIargs: ", pathAPIargs);
  2499.  
  2500. try
  2501. {
  2502. let data = await callWykopAPI("POST", ...pathAPIargs);
  2503. return data;
  2504. }
  2505. catch (error)
  2506. {
  2507. console.error(`Fetch failed: ${error}`);
  2508. throw error;
  2509. }
  2510. }
  2511.  
  2512. async function deleteWykopAPIData(...pathAPIargs)
  2513. {
  2514. if (dev) console.log("deleteWykopAPIData(), pathAPIargs: ", pathAPIargs)
  2515. try
  2516. {
  2517. let data = await callWykopAPI("DELETE", ...pathAPIargs);
  2518. return data;
  2519. }
  2520. catch (error)
  2521. {
  2522. console.error(`Fetch failed: ${error}`);
  2523. throw error;
  2524. }
  2525. }
  2526.  
  2527.  
  2528. async function callWykopAPI(method, ...pathAPIargs)
  2529. {
  2530. if (dev) console.log(`callWykopAPI() -> method: ${method}, pathAPIargs: `, pathAPIargs)
  2531. try
  2532. {
  2533. const response = await fetch(`https://wykop.pl/api/v3/${pathAPIargs.join('/')}`, {
  2534. method: method, // "GET", "POST", or 'PUT'
  2535. headers: {
  2536. "Content-Type": "application/json",
  2537. Authorization: "Bearer " + window.localStorage.token,
  2538. },
  2539. });
  2540.  
  2541. if (dev) console.log("callWykopAPI() -> URL: " + `https://wykop.pl/api/v3/${pathAPIargs.join('/')}`)
  2542. if (dev) console.log(response)
  2543.  
  2544. // if (!response.ok)
  2545. // {
  2546. // throw new Error(`HTTP error! status: ${response.status}`);
  2547. // }
  2548.  
  2549. let data;
  2550. try
  2551. {
  2552. data = await response.json();
  2553. if (dev) console.log("callWykopAPI() -> data", data)
  2554. }
  2555. catch (error)
  2556. {
  2557. // if(dev) console.log('No body or not a JSON body:', error);
  2558. data = response.status; // 204
  2559. if (dev) console.log("callWykopAPI() -> response.status", response.status)
  2560. }
  2561. return data;
  2562. }
  2563. catch (error)
  2564. {
  2565. console.error(`call to Wykop API failed: ${error}`);
  2566. throw error;
  2567. }
  2568. }
  2569.  
  2570.  
  2571.  
  2572.  
  2573.  
  2574.  
  2575.  
  2576.  
  2577.  
  2578.  
  2579.  
  2580.  
  2581.  
  2582.  
  2583.  
  2584.  
  2585.  
  2586.  
  2587.  
  2588.  
  2589.  
  2590.  
  2591.  
  2592.  
  2593. /* INTERSECTION OBSERVER */
  2594.  
  2595. // dla każdego wpisu i komentarza
  2596. // strona wpisu, caly wpis: section:is(.entry:has(> article), .link-block:has(> section > article)):not(.deleted)
  2597. // tylko czesc wpisu bez komentarzy "section.entry:not(.deleted):has(> article), section.link-block:not(.deleted) > section > article)
  2598. /// :not(.deleted)
  2599. if (IntersectionObserverEnabled == true) waitForKeyElements("section.entry:has(> article), section.link-block:not(.premium-pub, .market-pub):has(> section > article)", sectionObjectDetected, false);
  2600.  
  2601. function sectionObjectDetected(sectionObjectElement)
  2602. {
  2603. // consoleX(`sectionObjectDetected()`, 1)
  2604. sectionObjectIntersectionObserver.observe(sectionObjectElement);
  2605. }
  2606.  
  2607.  
  2608.  
  2609. if (settings.linkToVideoDuration || settings.entryWithVideoDuration)
  2610. {
  2611. CSS += `
  2612. /* WYKOP XS CODE - START */
  2613. section.link-block > section > article > figure::before,
  2614. section.link-page section.link-block[data-wxs_video_duration] > section::before, /* WYKOP XS ONLY */
  2615. section.entry[data-wxs_video_duration] > article > div.edit-wrapper > section.embed > section.embed-ghost::before /* WYKOP XS ONLY */
  2616. {
  2617. content: var(--wxs_video_duration); /* WYKOP XS ONLY */
  2618.  
  2619. z-index: 1;
  2620. max-width: 80px;
  2621. animation-name: fadeIn;
  2622. animation-duration: 0.4s;
  2623. animation-delay: 1s;
  2624. animation-fill-mode: both;
  2625. animation-timing-function: ease-in-out;
  2626. position: absolute;
  2627. bottom: 10%;
  2628. padding: 4px 25px 4px 25px;
  2629. display: flex;
  2630. border-bottom: 1px solid var(--alto);
  2631. border-radius: 0 var(--borderRadius) var(--borderRadius) 0!important;
  2632. justify-content: center;
  2633. align-items: center;
  2634. color: rgba(180, 180, 180, 1);
  2635. background-color: rgba(0, 0, 0, 1);
  2636. opacity: 1;
  2637.  
  2638. @starting-style {
  2639. opacity: 0; scale: 0.9; translate: -40px;
  2640. }
  2641. }
  2642. /* WYKOP XS CODE - END */
  2643. section.link-page section.link-block[data-wxs_video_duration] > section,
  2644. section.entry[data-wxs_video_duration] > article > div.edit-wrapper > section.embed > section.embed-ghost
  2645. {
  2646. position: relative;
  2647. }
  2648. section.link-page section.link-block[data-wxs_video_duration] > section::before
  2649. {
  2650. bottom: unset;
  2651. top: -15px;
  2652. border-bottom: none;
  2653. border-radius: 0!important;
  2654. }
  2655. section.link-page section.link-block[data-wxs_video_duration] > section { margin-top: 15px; }
  2656. @keyframes fadeIn { 0% { opacity: 0; scale: 0.8; translate: -40px; } 100% { opacity: 1; scale: 1; translate: 0px; }}
  2657. `;
  2658. }
  2659.  
  2660.  
  2661. // INTERSECTION OBSERVED
  2662. const sectionObjectsAreIntersecting = async (intersectingObject, observer) =>
  2663. {
  2664. intersectingObject.forEach(async (IntersectionObserverEntry) => // InterIntersectionObserverEntry
  2665. {
  2666.  
  2667.  
  2668. // ----- ANY INTERSECTION CHANGED
  2669. let sectionObjectElement = IntersectionObserverEntry.target; // element <section class="entry">
  2670. let resource = null; // resource="link", "entry", "entry_comment"
  2671. // if(dev) console.log(`intersectingObject: `, sectionObjectElement)
  2672. if (!sectionObjectElement?.__vue__?.item) return false;
  2673.  
  2674.  
  2675. // ----- ONLY ONCE: INTERSECTION CHANGED FOR THE FIRST TIME:
  2676. if (!sectionObjectElement.dataset.wxs_first_load_time)
  2677. {
  2678. // if(dev) console.log("intersectingObject-sectionObjectElement.__vue__.item")
  2679. // if(dev) console.log(sectionObjectElement)
  2680. // if(dev) console.log("intersectingObject-sectionObjectElement.__vue__.item")
  2681. // if(dev) console.log(sectionObjectElement.__vue__)
  2682. // if(dev) console.log("intersectingObject-sectionObjectElement.__vue__.item")
  2683. // if(dev) console.log(sectionObjectElement.__vue__.item)
  2684. // data-wxs_first_load_time="2024-12-12..."
  2685. sectionObjectElement.dataset.wxs_first_load_time = dayjs().valueOf(); // data unix kiedy przybyly ostatnio odswiezone plusy-tutaj czas załadowania strony
  2686. resource = sectionObjectElement.__vue__.item.resource;
  2687.  
  2688. let wxs_votes_up = sectionObjectElement.__vue__.item.votes.up; // liczba wykopów/plusów 10
  2689. let wxs_votes_down = sectionObjectElement.__vue__.item.votes.down; // liczba zakopów/minusów 20
  2690. let wxs_votes_count = wxs_votes_up - wxs_votes_down; // suma plusów i minusów/ suma wykopów i zakopów -10
  2691. let wxs_votes_all = wxs_votes_up - wxs_votes_down; // łączna liczba oddanych głosów 30
  2692. let wxs_votes_up_percent = 0;
  2693. let wxs_votes_down_percent = 0;
  2694. if (wxs_votes_all > 0)
  2695. {
  2696. wxs_votes_down_percent = Math.ceil(wxs_votes_down * 100 / wxs_votes_all);
  2697. wxs_votes_up_percent = Math.ceil(wxs_votes_up * 100 / wxs_votes_all);
  2698. }
  2699.  
  2700. // wpisy i komentarze
  2701. if (resource != "link")
  2702. {
  2703. if (settings.checkEntryPlusesEnable || settings.votingExplosionEnable)
  2704. {
  2705. sectionObjectElement.style.setProperty('--votesAll', `"👨${wxs_votes_all}"`); // var(--votesAll)
  2706. sectionObjectElement.dataset.wxs_votes_all = wxs_votes_all; // data-wxs_votes_all="-10"
  2707. sectionObjectElement.style.setProperty('--votesUp', `"${wxs_votes_up > 0 ? settings.prefixBeforePlusesCount : ""}${wxs_votes_up}"`); // var(--votesUp);
  2708.  
  2709.  
  2710.  
  2711. sectionObjectElement.dataset.wxs_votes_up = wxs_votes_up; // data-wxs_votes_all="10"
  2712. sectionObjectElement.style.setProperty('--votesDown', `"${wxs_votes_down > 0 ? settings.prefixBeforeMinusesCount : ""}${wxs_votes_down}"`); //var(--votesDown)
  2713. sectionObjectElement.dataset.wxs_votes_down = wxs_votes_down; // data-wxs_votes_all="20"
  2714. sectionObjectElement.style.setProperty('--votesCount', `"${wxs_votes_up > 0 ? settings.prefixBeforePlusesCount : wxs_votes_up < 0 ? settings.prefixBeforeMinusesCount : ""}${wxs_votes_count}"`); // var(--votesCount)
  2715. sectionObjectElement.dataset.wxs_votes_count = wxs_votes_count; // data-wxs_votes_all="30"
  2716.  
  2717. sectionObjectElement.dataset.wxs_voted = sectionObjectElement.__vue__.item.voted; // data-wxs_voted=1 data-wxs_voted=0
  2718.  
  2719. if (settings.votingExplosionEnable || settings.checkEntryPlusesPerHour && !sectionObjectElement.dataset.wxs_first_load_votes_count)
  2720. {
  2721. // liczba plusow podczas zaladowania strony
  2722. sectionObjectElement.dataset.wxs_first_load_votes_count = sectionObjectElement.__vue__.item.votes.up - sectionObjectElement.__vue__.item.votes.down;
  2723. }
  2724. }
  2725.  
  2726. if (settings.entryWithVideoDuration && sectionObjectElement?.__vue__?.item?.media?.embed?.video_metadata?.duration_in_seconds)
  2727. {
  2728. let wxs_video_duration = timeDurationFromSeconds(sectionObjectElement?.__vue__?.item?.media?.embed?.video_metadata?.duration_in_seconds);
  2729. sectionObjectElement.dataset.wxs_video_duration = wxs_video_duration; // data-wxs_video_duration="02:34"
  2730. sectionObjectElement.style.setProperty("--wxs_video_duration", `"${wxs_video_duration}"`); // var(--wxs_video_duration) -> "02:34"
  2731. }
  2732.  
  2733. if (settings.filterUserReplies)
  2734. {
  2735. sectionObjectElement.querySelectorAll(`article > div.edit-wrapper > div.content > section.entry-content > div.wrapper > a[href^="/ludzie/"]:not([data-wxs_mention_username])`).forEach((a_mention) =>
  2736. {
  2737. const a_mentions_filter_button = document.createElement("button");
  2738. a_mentions_filter_button.classList = "wxs_filter_on_replies";
  2739. a_mentions_filter_button.innerHTML = `🔰<span>FILTRUJ</span>`
  2740. a_mentions_filter_button.type = "button";
  2741.  
  2742. const wxs_mention_username = a_mention.href.replace("https://wykop.pl/ludzie/", "")
  2743. a_mention.dataset.wxs_mention_username = wxs_mention_username; // każdy @mention uzytkownika zmieniamy na <a href="/ludzie/NadiaFrance" data-wxs_author_username="NadiaFrance">
  2744.  
  2745. a_mentions_filter_button.dataset.wxs_author_username = wxs_mention_username;
  2746. a_mentions_filter_button.title = `𝗪𝘆𝗸𝗼𝗽 𝗫 𝗳𝗶𝗹𝘁𝗿𝗼𝘄𝗮𝗻𝗶𝗲 𝗱𝘆𝘀𝗸𝘂𝘀𝗷𝗶 𝗶 𝗼𝗱𝗽𝗼𝘄𝗶𝗲𝗱𝘇𝗶 \n \n Pokaż całą dyskusję z użytkownikiem '${wxs_mention_username}'.\n \n Pokazuje: \n wszystkie komentarze '${wxs_mention_username}' \n odpowiedzi, które wołają '@${wxs_mention_username}' \n \n Klikając przełączasz tryb filtrowania: \n Filtr 1: odfiltrowane komentarze półprzezroczyste\n Filtr 2: odfiltrowane komentarze czarno białe\n Filtr 3: całkowicie ukrywa odfiltrowane komentarze\n \n "`
  2747.  
  2748. a_mention.insertAdjacentElement("afterend", a_mentions_filter_button);
  2749.  
  2750. // if(dev) console.log("=== BUTTON ADDED: a_mentions_filter_button")
  2751. // if(dev) console.log(a_mentions_filter_button)
  2752. })
  2753. }
  2754.  
  2755.  
  2756. if (resource == "entry") // TODO komentarze w znaleziskach
  2757. {
  2758.  
  2759. if (settings.authorBlocksYouCheckingEnable && loggedUser?.status == "active")
  2760. {
  2761. // nie sprawdzamy, gdy ktoś ma bana, bo wtedy nigdzie nie można dodać wpisu
  2762.  
  2763. // <section data-status="400"> jeśli autor cie blokuje i nie mozna dodac wpisu
  2764.  
  2765. let blockingStatus = await checkIfYouCanPostCommentInEntry(sectionObjectElement.__vue__.item.id);
  2766. if (blockingStatus == 400)
  2767. {
  2768. sectionObjectElement.dataset.status = blockingStatus;
  2769. let blockDetectorTitle = `Wykop X: 𝗕𝗹𝗼𝗰𝗸 𝗗𝗲𝘁𝗲𝗰𝘁𝗼𝗿❗\n\n`;
  2770. if (sectionObjectElement.__vue__.item.author.gender == "f") blockDetectorTitle += `Użytkowniczka @${sectionObjectElement.__vue__.item.author.username} dodała Cię na czarną listę.`
  2771. else blockDetectorTitle += `Użytkownik @${sectionObjectElement.__vue__.item.author.username} dodał Cię na czarną listę.`;
  2772. blockDetectorTitle += `\n\nNie możesz dodawać komentarzy w tym wpisie.`
  2773. sectionObjectElement.title = blockDetectorTitle;
  2774.  
  2775. // TODO - dodanie autora do listy blokujących
  2776. }
  2777. }
  2778.  
  2779. // sectionObjectElement.title = `Wykop X: 𝗕𝗹𝗼𝗰𝗸 𝗗𝗲𝘁𝗲𝗰𝘁𝗼𝗿❗\n\nUżytkownik @m__b dodał Cię na czarną listę\n\nNie możesz dodawać komentarzy w tym wpisie.`;
  2780.  
  2781. // sprawdzenie czy wpis zawiera grę w plusowanie
  2782. if (settings.checkEntryPlusesForVotingGame)
  2783. {
  2784. var substrings = ["z plusów", "tnia cyfra", "cyfra powie", "siaj jesteś", "siaj jestes", "niej cyfry", "iczba po zaplus", "yfra po zaplus"];
  2785. var containsSubstring = substrings.some(substring => sectionObjectElement.__vue__.item.content.includes(substring));
  2786.  
  2787. if (containsSubstring)
  2788. {
  2789. sectionObjectElement.dataset.wxs_voting_game = "true";
  2790.  
  2791. // string pokazujący zakrytą liczbę plusow - zamiast "1234" -> "12--"
  2792. //sectionObjectElement.style.setProperty('--votesUpHidden', `"+${replaceDigitsWithDot(sectionObjectElement.__vue__.item.votes.up)}"`);
  2793. sectionObjectElement.style.setProperty('--votesUpHidden', `"${settings.prefixBeforePlusesCount}` + replaceDigitsWithDot(wxs_votes_up) + `"`);
  2794. sectionObjectElement.style.wxs_votes_up_hidden = replaceDigitsWithDot(wxs_votes_up); // data-wxs_votes_up_hidden
  2795.  
  2796. let votingGameLastDigit = wxs_votes_up + 1; // liczba po zaplusowaniu
  2797. votingGameLastDigit = votingGameLastDigit.toString().slice(-1); // ostatnia cyfra po zaplusowaniu
  2798.  
  2799. sectionObjectElement.style.setProperty('--votingGameLastDigit', `"` + votingGameLastDigit + `"`);
  2800. sectionObjectElement.dataset.wxs_voting_game_last_digit = votingGameLastDigit; // data-wxs_voting_game_last_digit="9"
  2801. }
  2802. }
  2803.  
  2804. if (settings.checkEntryCommentsPerHour && !sectionObjectElement.dataset.wxs_first_load_comments_count)
  2805. {
  2806. sectionObjectElement.dataset.wxs_first_load_comments_count = sectionObjectElement.__vue__.item.comments.count;
  2807. }
  2808. }
  2809. }
  2810. // znalezisko
  2811. else if (resource == "link")
  2812. {
  2813. if (settings.linkToVideoDuration && sectionObjectElement?.__vue__?.item?.media?.embed?.video_metadata?.duration_in_seconds)
  2814. {
  2815. let wxs_video_duration = timeDurationFromSeconds(sectionObjectElement?.__vue__?.item?.media?.embed?.video_metadata?.duration_in_seconds);
  2816. sectionObjectElement.dataset.wxs_video_duration = wxs_video_duration; // data-wxs_video_duration="02:34"
  2817. sectionObjectElement.style.setProperty("--wxs_video_duration", `"${wxs_video_duration}"`); // var(--wxs_video_duration) -> "02:34"
  2818. }
  2819.  
  2820. if (settings.checkLinkVotesEnable && settings.checkLinkVotesPerHour && !sectionObjectElement.dataset.wxs_first_load_votes_count)
  2821. {
  2822. //sectionObjectElement.style.setProperty('--votesUp', `"${sectionObjectElement.__vue__.item.votes.up}"`);
  2823. //sectionObjectElement.style.setProperty('--votesDown', `"${sectionObjectElement.__vue__.item.votes.down}"`);
  2824. sectionObjectElement.dataset.wxs_votes_up = sectionObjectElement.__vue__.item.votes.up;
  2825. sectionObjectElement.dataset.wxs_votes_down = sectionObjectElement.__vue__.item.votes.down;
  2826. sectionObjectElement.dataset.wxs_voted = sectionObjectElement.__vue__.item.voted;
  2827. sectionObjectElement.dataset.wxs_first_load_votes_count = sectionObjectElement.__vue__.item.votes.up - sectionObjectElement.__vue__.item.votes.down;
  2828. sectionObjectElement.dataset.wxs_votes_count = sectionObjectElement.__vue__.item.votes.up - sectionObjectElement.__vue__.item.votes.down;
  2829. sectionObjectElement.dataset.wxs_votes_all = sectionObjectElement.__vue__.item.votes.up + sectionObjectElement.__vue__.item.votes.down;
  2830. }
  2831. if (settings.checkLinkCommentsPerHour && !sectionObjectElement.dataset.wxs_first_load_comments_count)
  2832. {
  2833. if (!sectionObjectElement.dataset.wxs_first_load_time) sectionObjectElement.dataset.wxs_first_load_time = dayjs().valueOf(); // data unix kiedy przybyly ostatnio odswiezone plusy-tutaj czas załadowania strony
  2834. sectionObjectElement.dataset.wxs_first_load_comments_count = sectionObjectElement.__vue__.item.comments.count;
  2835. }
  2836. }
  2837. currentPageTotalVotesUpCount += sectionObjectElement.__vue__.item.votes.up;
  2838. }
  2839.  
  2840.  
  2841. // ----- OBJECT IS VISIBLE -- IS INTERSECTING!
  2842. if (IntersectionObserverEntry.isIntersecting)
  2843. {
  2844. if (!resource) resource = sectionObjectElement.__vue__.item.resource;
  2845.  
  2846. let object_id = sectionObjectElement.id; // object_id > id="comment-1234567"
  2847. let id = sectionObjectElement.__vue__.item.id; // id > 1234567
  2848. let parent_resource, parent_id;
  2849.  
  2850. // ZA KAŻDYM RAZEM GDY POJAWIA SIE NA EKRANIE:
  2851. sectionObjectElement.classList.add("isIntersecting");
  2852. sectionObjectElement.classList.remove("notIntersecting");
  2853.  
  2854.  
  2855. // ZNALEZISKO WIĘC WŁĄCZAMY ANALIZĘ ZNALEZISKA
  2856. if (resource == "link")
  2857. {
  2858. if (settings.checkLinkVotesEnable)
  2859. {
  2860. if ((sectionObjectElement.__vue__.item.votes.up > votesFetchingLimitMinimumVotes || sectionObjectElement.__vue__.item.votes.down > votesFetchingLimitMinimumVotes) && loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'hour') < votesFetchingLimitMaximumHoursOld)
  2861. {
  2862. let i = 1;
  2863. let timeoutId = null
  2864. timeoutId = setTimeout(function checkPlusesAgain()
  2865. {
  2866. if (sectionObjectElement?.__vue__?.item)
  2867. {
  2868. checkPluses(sectionObjectElement, undefined, true);
  2869.  
  2870. if (sectionObjectElement.classList.contains("isIntersecting"))
  2871. {
  2872. if ((sectionObjectElement.dataset.wxs_votes_fetch_high_frequency)
  2873. || ((loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'hour') < votesFetchingHigherFrequencyLimitMaximumHoursOld)
  2874. && sectionObjectElement.__vue__.item.votes.up > votesFetchingHigherFrequencyLimitMinimumVotes))
  2875. {
  2876. if (!sectionObjectElement.dataset.wxs_votes_fetch_high_frequency) sectionObjectElement.dataset.wxs_votes_fetch_high_frequency = "true";
  2877. setTimeout(checkPlusesAgain, votesFetchingHigherFrequencyDelayInSeconds * 1000)
  2878. }
  2879. else
  2880. {
  2881. setTimeout(checkPlusesAgain, votesFetchingOngoingDelayInSeconds * 1000)
  2882. }
  2883. }
  2884. }
  2885. }, votesFetchingFirstDelayInSeconds * 1000);
  2886. }
  2887. }
  2888. }
  2889. // WPISY I KOMENTARZE
  2890. else
  2891. {
  2892. if (settings.checkEntryPlusesEnable)
  2893. {
  2894. // tylko wpisy i komentarze, które mają minimum X plusów i nie są starsze niż Y dni
  2895. if ((sectionObjectElement.__vue__.item.votes.up > votesFetchingLimitMinimumVotes || sectionObjectElement.__vue__.item.votes.down > votesFetchingLimitMinimumVotes) && loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'hour') < votesFetchingLimitMaximumHoursOld)
  2896. {
  2897. let timeoutId = null
  2898. let i = 1;
  2899. let timeoudId = setTimeout(function checkPlusesAgain()
  2900. {
  2901. if (sectionObjectElement?.__vue__?.item)
  2902. {
  2903. checkPluses(sectionObjectElement, undefined, true);
  2904.  
  2905. if (sectionObjectElement.classList.contains("isIntersecting"))
  2906. {
  2907. if ((sectionObjectElement.dataset.wxs_votes_fetch_high_frequency)
  2908. || ((loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'hour') < votesFetchingHigherFrequencyLimitMaximumHoursOld)
  2909. && sectionObjectElement.__vue__.item.votes.up > votesFetchingHigherFrequencyLimitMinimumVotes))
  2910. {
  2911. if (!sectionObjectElement.dataset.wxs_votes_fetch_high_frequency) sectionObjectElement.dataset.wxs_votes_fetch_high_frequency = "true";
  2912. setTimeout(checkPlusesAgain, votesFetchingHigherFrequencyDelayInSeconds * 1000)
  2913. }
  2914. else
  2915. {
  2916. setTimeout(checkPlusesAgain, votesFetchingOngoingDelayInSeconds * 1000)
  2917. }
  2918. }
  2919. }
  2920. }, votesFetchingFirstDelayInSeconds * 1000);
  2921.  
  2922. // ZABAWA W PLUSY
  2923. if (resource == "entry" && settings.checkEntryPlusesForVotingGame)
  2924. {
  2925.  
  2926. }
  2927. }
  2928.  
  2929. }
  2930. }
  2931.  
  2932.  
  2933. // ----- IS VISIBLE FOR THE FIRST TIME
  2934.  
  2935. // GDY PIERWSZY RAZ WIDZIMY WPIS/KOMENTARZ/ZNALEZISKO
  2936. if (!sectionObjectElement.classList.contains("wasIntersecting"))
  2937. {
  2938. sectionObjectElement.classList.add("wasIntersecting");
  2939.  
  2940. // ZNALEZISKO WIĘC WŁĄCZAMY ANALIZĘ ZNALEZISKA
  2941. if (resource == "link")
  2942. {
  2943. if (settings.linksAnalyzerEnable || settings.linkVoteDownButton)
  2944. {
  2945. linkSectionIntersected(sectionObjectElement) // waitForKeyElements(`section.link-block[id^="link-"]`, , false); // GM_wrench.waitForKeyElements(`section.link-block[id^="link-"]`, linkSectionIntersected, false);
  2946. }
  2947.  
  2948. if (settings.checkLinkVotesEnable && settings.checkLinkVotesPerHour)
  2949. {
  2950. const ratingBoxSection = sectionObjectElement.querySelector(".vote-box")
  2951.  
  2952. if ((sectionObjectElement.__vue__.item.votes.up > votesFetchingLimitMinimumVotes || sectionObjectElement.__vue__.item.votes.down > votesFetchingLimitMinimumVotes) && loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'day') < votesFetchingLimitMaximumHoursOld)
  2953. {
  2954. let wxs_votes_per_hourDivElement = document.createElement("div");
  2955. wxs_votes_per_hourDivElement.title = "Wykop X: Liczba wykopów na godzinę";
  2956. wxs_votes_per_hourDivElement.classList = "wxs_votes_per_hour";
  2957. ratingBoxSection.appendChild(wxs_votes_per_hourDivElement);
  2958. }
  2959. }
  2960. }
  2961. // WPISY, KOMENTARZE POD WPISAMI, KOMENTARZE POD ZNALEZISKAMI,
  2962. else
  2963. {
  2964.  
  2965. const ratingBoxSection = sectionObjectElement.querySelector(".rating-box")
  2966. if (settings.votingExplosionEnable || settings.checkEntryPlusesWhenVoting)
  2967. {
  2968. votingEventListener(sectionObjectElement, ratingBoxSection);
  2969. }
  2970.  
  2971. if (ratingBoxSection && settings.checkEntryPlusesEnable && settings.checkEntryPlusesPerHour)
  2972. {
  2973. if ((sectionObjectElement.__vue__.item.votes.up > votesFetchingLimitMinimumVotes || sectionObjectElement.__vue__.item.votes.down > votesFetchingLimitMinimumVotes) && loadTime.diff(dayjs(sectionObjectElement.__vue__.item.created_at), 'day') < votesFetchingLimitMaximumHoursOld)
  2974. {
  2975. let wxs_votes_per_hourDivElement = document.createElement("div");
  2976. wxs_votes_per_hourDivElement.title = "Wykop X: Liczba plusów na godzinę";
  2977. wxs_votes_per_hourDivElement.classList = "wxs_votes_per_hour";
  2978. ratingBoxSection.appendChild(wxs_votes_per_hourDivElement);
  2979. }
  2980.  
  2981. }
  2982. }
  2983.  
  2984.  
  2985. // podkomentarz
  2986. if (sectionObjectElement.__vue__.item.parent)
  2987. {
  2988. parent_resource = sectionObjectElement.__vue__.item.parent.resource; // data-wxs_parent_resource="entry"
  2989. parent_id = sectionObjectElement.__vue__.item.parent.id; // data-wxs_parent_id="1234567"
  2990. }
  2991.  
  2992.  
  2993.  
  2994. // INFOBOX, NOTATKOWATOR, USER LABELS
  2995. let userDataObject = sectionObjectElement.__vue__?.item?.author;
  2996. if (settings.infoboxEnable || settings.notatkowatorEnable || settings.wxsUserLabelsEnable)
  2997. {
  2998. // TWORZYMY USERINFOBOX do wszystkich nicków autora tego wpisu/komentarza/linka
  2999. // pierwszy raz widzimy ten wpis / komentarz użytkownika i nie były do niego dodawane userdata więc dodajemy data-wxs_username="NadiaFrance"
  3000. if (!sectionObjectElement.dataset.wxs_username && userDataObject.username)
  3001. {
  3002. // POBIERAMY INFORMACJE O UŻYTKOWNIKU Z FETCH API
  3003. if (settings.infoboxEnable)
  3004. {
  3005. userDataObject = await getUserDetailsForUsername(userDataObject, undefined, true); // userDataObject, username, forceAPICheck
  3006. }
  3007. if (settings.wxsUserLabelsEnable)
  3008. {
  3009. if (settings.wxsUserLabelsFakeFemales)
  3010. {
  3011. if (falszyweRozoweArray && falszyweRozoweArray.includes(userDataObject.username))
  3012. {
  3013. userDataObject.gender = "m";
  3014. sectionObjectElement.__vue__.item.author.gender = "m";
  3015. userDataObject.changeSexTo = "male";
  3016. }
  3017. else if (falszyweNiebieskieArray && falszyweNiebieskieArray.includes(userDataObject.username))
  3018. {
  3019. userDataObject.gender = "f";
  3020. sectionObjectElement.__vue__.item.author.gender = "f";
  3021. userDataObject.changeSexTo = "female";
  3022. }
  3023. }
  3024.  
  3025.  
  3026. if (settings.wxsUserLabelsTrolls && mapaTrolli)
  3027. {
  3028. let wxsUserLabelObject = null;
  3029. // if(dev) console.log(mapaTrolli.get(userDataObject.username));
  3030. if ((wxsUserLabelObject = mapaTrolli.get(userDataObject.username)))
  3031. {
  3032. userDataObject.wxsUserLabel = wxsUserLabelObject.label;
  3033. userDataObject.wxsUserURL = wxsUserLabelObject.url;
  3034. }
  3035. }
  3036. }
  3037.  
  3038. // SPRAWDZENIE I DODANIE NOTATKI ORAZ DANYCH UZYTKOWNIKA
  3039. let userNoteObject = null;
  3040. if (settings.notatkowatorEnable)
  3041. {
  3042.  
  3043.  
  3044. // jeszcze nie dodawaliśmy notatki
  3045. if (userDataObject?.note == true && sectionObjectElement?.dataset?.wxs_note_loaded != true)
  3046. {
  3047. // potencjalna zmiana plci przez +m lub +f
  3048. userNoteObject = await getUserNoteObjectByUsername(sectionObjectElement, undefined, true); // username, forceAPICheck
  3049. sectionObjectElement.dataset.wxs_note_loaded = "true"; // todo nazwa uzytkownika zamiast true zeby potem sprawdzac <section data-wxs_note_loaded="true" data-wxs_username="NadiaFrance" data-wxs_user_note="true">
  3050.  
  3051. if (userNoteObject?.changeSexTo)
  3052. {
  3053. userDataObject.changeSexTo = userNoteObject.changeSexTo;
  3054. userDataObject.gender = userNoteObject.gender;
  3055. sectionObjectElement.__vue__.item.author.gender = userNoteObject.gender;
  3056. }
  3057. }
  3058. }
  3059.  
  3060. createInfoboxDivsForUserEverywhere(userDataObject, userNoteObject, undefined);
  3061. }
  3062. }
  3063.  
  3064.  
  3065.  
  3066.  
  3067. // TWORZYMY ACTION BOX
  3068. if (settings.actionBoxEnable)
  3069. {
  3070. const wxs_author_username = sectionObjectElement.__vue__.item.author.username;
  3071. const wxs_author_gender = sectionObjectElement.__vue__.item.author.gender;
  3072. let wxs_menu_action_box = document.createElement("div");
  3073. wxs_menu_action_box.classList.add("wxs_menu_action_box", "wykopxs"); // 📰📑 🔖 ⎀⎊👁 🖾 🗙 ⌧ ⮽ 🗳 ☒ 🗵 🗷- ‐ ‑ – ‒ — ― _ ﹏🗖 ⎀ ⎊
  3074. let wxs_menu_action_box_html = ``;
  3075.  
  3076. if (settings.filterUserComments || settings.filterUserReplies)
  3077. {
  3078. wxs_menu_action_box_html += `<button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_filter_off" title=" Wykop X — wyłącz filtrowanie \n \n Pokaż normalnie wszystkie odfiltrowane komentarze / znaleziska \n \n ">❌<span>Wyłącz filtr</span></button>`;
  3079. if (settings.filterUserComments)
  3080. {
  3081. wxs_menu_action_box_html += `<button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_filter_on_user" title=" 𝗪𝘆𝗸𝗼𝗽 𝗫 — 𝗳𝗶𝗹𝘁𝗿𝗼𝘄𝗮𝗻𝗶𝗲 𝗸𝗼𝗺𝗲𝗻𝘁𝗮𝗿𝘇𝘆/𝘇𝗻𝗮𝗹𝗲𝘇𝗶𝘀𝗸 \n \n Na stronach zawierających 𝗸𝗼𝗺𝗲𝗻𝘁𝗮𝗿𝘇𝗲 (pod wpisami i pod znaleziskami) \n odfiltrowuje 𝗸𝗼𝗺𝗲𝗻𝘁𝗮𝗿𝘇𝗲 innych użytkowników. \n Pozostawia widoczne wyłącznie 𝗸𝗼𝗺𝗲𝗻𝘁𝗮𝗿𝘇𝗲 tego użytkownika. \n \n Na stronach zawierających 𝘇𝗻𝗮𝗹𝗲𝘇𝗶𝘀𝗸𝗮 (np. główna, wykopalisko) \n odfiltrowuje 𝘇𝗻𝗮𝗹𝗲𝘇𝗶𝘀𝗸𝗮 innych użytkowników. \n Pozostawia widoczne wyłącznie 𝘇𝗻𝗮𝗹𝗲𝘇𝗶𝘀𝗸𝗮 tego użytkownika. \n \n \n Klikając przełączasz tryb filtrowania: \n — Filtr 1: całkowicie ukrywa odfiltrowane komentarze \n — Filtr 2: odfiltrowane komentarze półprzezroczyste \n — Filtr 3: odfiltrowane komentarze czarno białe \n \n ">⚜<span>Filtruj</span></button>`;
  3082. }
  3083. if (settings.filterUserReplies)
  3084. {
  3085. wxs_menu_action_box_html += `<button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_filter_on_replies" title=" 𝗪𝘆𝗸𝗼𝗽 𝗫 — 𝗳𝗶𝗹𝘁𝗿𝗼𝘄𝗮𝗻𝗶𝗲 𝗱𝘆𝘀𝗸𝘂𝘀𝗷𝗶 𝗶 𝗼𝗱𝗽𝗼𝘄𝗶𝗲𝗱𝘇𝗶 \n \n Odfiltrowuje 𝗸𝗼𝗺𝗲𝗻𝘁𝗮𝗿𝘇𝗲, które nie dotyczą tego użytkownika. \n \n Nie ukrywa: \n — komentarzy tego użytkownika \n — odpowiedzi, które zawierają @wołanie tego użytkownika \n \n Klikając przełączasz tryb filtrowania: \n — Filtr 1: całkowicie ukrywa odfiltrowane komentarze \n — Filtr 2: odfiltrowane komentarze półprzezroczyste \n — Filtr 3: odfiltrowane komentarze czarno białe \n \n ">🔰<span>Filtruj</span></button>`;
  3086. }
  3087. }
  3088.  
  3089. if (settings.mirkoukrywaczEnable)
  3090. {
  3091. if (settings.mirkoukrywaczHideComments || settings.mirkoukrywaczHideEntries || settings.mirkoukrywaczHideLinks)
  3092. {
  3093. wxs_menu_action_box_html += `<button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_minimize" title="Wykop X Krawężnik — zwiń"><span>[ </span>—<span> ]</span></button>
  3094. <button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_maximize" title="Wykop X Krawężnik — pokaż cały"><span>[ </span>+<span> ]</span></button>
  3095. <button data-wxs_object_id="${object_id}" data-wxs_id="${id}" data-wxs_resource="${resource}" data-wxs_parent_id="${parent_id}" data-wxs_parent_resource="${parent_resource}" data-wxs_author_username="${wxs_author_username}" data-wxs_author_gender="${wxs_author_gender}" class="wxs_hide" title="Wykop X Mirkoukrywacz — ukryj"><span>Ukryj </span>🗙</button> `;
  3096. }
  3097. }
  3098.  
  3099. // DODAJEMY KRAWĘŻNIK
  3100. wxs_menu_action_box.innerHTML = wxs_menu_action_box_html;
  3101. const sectionEntryHeaderElement = sectionObjectElement.querySelector("article > header");
  3102. sectionEntryHeaderElement.parentNode.insertBefore(wxs_menu_action_box, sectionEntryHeaderElement);
  3103. }
  3104.  
  3105.  
  3106.  
  3107. // TODO
  3108. // liczba komentarzy autora wpisu
  3109. if (resource == "entry" && sectionObjectElement.classList.contains("detailed")) // jestesmy na stronie wpisu i ta sekcja to glowny wpis
  3110. {
  3111. const wxs_comments_count = sectionObjectElement.__vue__.item.comments.count;
  3112. sectionObjectElement.dataset.wxs_comments_count = wxs_comments_count; // <section class="entry detailed" data-wxs_comments-count="99" data-wxs_comments_author_count="12" data-comments-author-percent="10%">
  3113.  
  3114. if (wxs_comments_count > 0)
  3115. {
  3116. const wxs_comments_author_count = sectionObjectElement.__vue__.item.comments.items.filter(comment => comment.author.username === sectionObjectElement.__vue__.item.author.username).length;
  3117. const wxs_comments_author_percent = Math.round(wxs_comments_author_count / wxs_comments_count * 100);
  3118. sectionObjectElement.dataset.wxs_comments_author_count = wxs_comments_author_count;
  3119. sectionObjectElement.dataset.wxs_comments_author_percent = wxs_comments_author_percent;
  3120. }
  3121. }
  3122. }
  3123. }
  3124. // ----- OBJECT IS NOT VISIBLE -- SEKCJA ZNIKNĘŁA Z EKRANU
  3125. else if (sectionObjectElement.classList.contains("isIntersecting"))
  3126. {
  3127. // consoleX(`section.entry NOT intersecting: ${id}`, 1)
  3128. sectionObjectElement.classList.remove("isIntersecting", "plusesAdded", "plusesRemoved", "minusesAdded", "minusesRemoved");
  3129. sectionObjectElement.classList.add("notIntersecting");
  3130. }
  3131. });
  3132. };
  3133.  
  3134.  
  3135. const sectionObjectIntersectionObserverOptions =
  3136. {
  3137. root: null,
  3138. rootMargin: "0px 0px -50px 0px", // rootMargin: "0px 0px -100px 0px",
  3139. threshold: 0,
  3140. };
  3141. // powiekszenie wczytywania ponizej viewportu
  3142. if (settings.intersectionObserverRootMargin) sectionObjectIntersectionObserverOptions.rootMargin = "0px 0px 700px 0px";
  3143. const sectionObjectIntersectionObserver = new IntersectionObserver(sectionObjectsAreIntersecting, sectionObjectIntersectionObserverOptions)
  3144.  
  3145.  
  3146. /*
  3147. __vue__.item.
  3148. .actions. [create/create_favourite/delete/delete_favourite/report/undo_vote/update/vote_up]
  3149. .adult
  3150. .atchive
  3151. .author
  3152. .comments [count: int, items: Array]
  3153. .content: "tresc"
  3154. .created_at: "2023-12..."
  3155. .deletable: false
  3156. .device: ""
  3157. .editable: false
  3158. .favourite: false
  3159. .id: 1234567
  3160. .media [embed/photo/survey]
  3161. .parent
  3162. .resource: "entry"
  3163. .slug: "wykop-to-portal"
  3164. .status: "visible"
  3165. ,tags: Array
  3166. .voted: 0
  3167. .votes [.down: 1 / .up: 2 / .users: Array[]]
  3168. __vue__.item. author.
  3169. .avatar (url jpg)
  3170. .blacklist: false
  3171. .color: "orange"
  3172. .company: false
  3173. .follow: false
  3174. .gender: "m"
  3175. .note: true
  3176. .online: true
  3177. .rank [trend/position]
  3178. .status: ["active"/"banned"/"suspended"]
  3179. .username: "nick"
  3180. .verified: false
  3181. */
  3182.  
  3183.  
  3184. async function createInfoboxDivsForUserEverywhere(userDataObject, userNoteObject, username = userDataObject.username)
  3185. {
  3186. consoleX(`createInfoboxDivsForUserEverywhere(username: ${username})`, 1);
  3187.  
  3188. let userInfoElementTitle = "";
  3189. const a_usernameAll = document.querySelectorAll(`div.right div.tooltip-slot > span > a.username[href="/ludzie/${username}"]:not(:has([data-wxs_username]))`);
  3190. let changeSexTo = false;
  3191. if (userDataObject.changeSexTo) changeSexTo = userDataObject.changeSexTo;
  3192.  
  3193.  
  3194. // informacja o użytkowniku pobrana z __vue__ lub fetch z API
  3195. // DIV Z INFOBOXEM i NOTATKAMI
  3196. let div = document.createElement('div');
  3197. {
  3198. div.classList = `wykopxs wxs_user_info wxs_user_info_year`; // <div class="wykopxs wxs_user_info wxs_user_info_year"
  3199.  
  3200. let noteVarElement = null;
  3201. let noteURLsElement = null;
  3202. let infoboxInnerHTML = "";
  3203.  
  3204. // XLABEL
  3205. if (settings.wxsUserLabelsEnable)
  3206. {
  3207. if (userDataObject.changeSexTo == "male")
  3208. {
  3209. infoboxInnerHTML += `<span class="wxs_user_label wxs_user_label_fake_gender wxs_user_label_fake_female"><span>#falszywyrozowypasek</span></span>`;
  3210. }
  3211. else if (userDataObject.changeSexTo == "female")
  3212. {
  3213. infoboxInnerHTML += `<span class="wxs_user_label wxs_user_label_fake_gender wxs_user_label_fake_male"><span>#falszywyniebieskipasek</span></span>`;
  3214. }
  3215. if (userDataObject.wxsUserLabel)
  3216. {
  3217. infoboxInnerHTML += `<span class="wxs_user_label wxs_user_label_name"><span>${userDataObject.wxsUserLabel}</span></span>`;
  3218. }
  3219. if (userDataObject.wxsUserURL)
  3220. {
  3221. infoboxInnerHTML += `<span class="wxs_user_label wxs_user_label_url"><a href="${userDataObject.wxsUserURL}" target="_blank">www</a></span> `;
  3222. }
  3223. }
  3224.  
  3225.  
  3226. // NOTATKI
  3227. if (settings.notatkowatorEnable && userDataObject.note == true && userNoteObject)
  3228. {
  3229. // if(dev) console.log("NOTATKI 222: ")
  3230. // if(dev) console.log("userDataObject.note")
  3231. // if(dev) console.log(userDataObject.note);
  3232. // if(dev) console.log("userNoteObject");
  3233. // if(dev) console.log(userNoteObject);
  3234. /*
  3235. Notes from API:
  3236. user.data = { username: 'NadiaFrance', content: 'Treść notatki' }
  3237. user.data = { username: 'NadiaFrance', content: '' }
  3238. Notes from LocalStorage:
  3239. userNoteObject -> wykopx/notatkowator/tomek123456789 =
  3240. {
  3241. username: "Zenek",
  3242. usernote: "Notatka | +r",
  3243. lastUpdate: "2024-01-07T15:55:37.210Z"
  3244. }
  3245. */
  3246. let usernoteParsedToDisplay = removePlusWords(userNoteObject.usernote);
  3247. // if(dev) console.log("usernoteParsedToDisplay");
  3248. // if(dev) console.log(usernoteParsedToDisplay);
  3249.  
  3250. if (settings.notatkowatorVerticalBar)
  3251. {
  3252. let sepIndex = userNoteObject.usernote.indexOf("|");
  3253. if (sepIndex != -1)
  3254. {
  3255. usernoteParsedToDisplay = `${usernoteParsedToDisplay.substring(0, sepIndex).trim()}...`;
  3256. //let remainingPart = usernote.substring(sepIndex + 1).trim();
  3257. }
  3258. }
  3259.  
  3260. noteVarElement = document.createElement('var');
  3261. // <span class="wxs_user_info_usernote wxs_notatkowator_normal">
  3262. // <span class="wxs_user_info_usernote wxs_notatkowator_r">
  3263. noteVarElement.classList = `wxs_user_info_usernote`;
  3264.  
  3265. if (userNoteObject.changeSexTo) changeSexTo = userNoteObject.changeSexTo;
  3266.  
  3267. const plusWordsArray = getPlusWords(userNoteObject.usernote);
  3268. plusWordsArray.forEach(plusWord =>
  3269. {
  3270. noteVarElement.classList.add(`wxs_notatkowator_${plusWord}`); // class="wxs_notatkowator_r"
  3271. });
  3272.  
  3273.  
  3274. if (settings.notatkowatorWebsiteURL)
  3275. {
  3276. const noteURLsArray = getURLsFromString(usernoteParsedToDisplay, false, false);
  3277. if (noteURLsArray)
  3278. {
  3279. noteURLsElement = document.createElement('span');
  3280. noteURLsElement.classList = `wxs_user_label wxs_user_info_usernote_url`;
  3281.  
  3282. noteURLsArray.forEach((url) =>
  3283. {
  3284. noteURLsElement.innerHTML += `<a href="${url.startsWith('www.') ? 'https://' + url : url}" target="_blank">www</a>`;
  3285. usernoteParsedToDisplay = usernoteParsedToDisplay.replace(url, "");
  3286. })
  3287. }
  3288. }
  3289.  
  3290. noteVarElement.innerHTML = `${usernoteParsedToDisplay}`;
  3291. userInfoElementTitle += ` \n 𝗪𝘆𝗸𝗼𝗽 𝗫 𝗡𝗼𝘁𝗮𝘁𝗸𝗼𝘄𝗮𝘁𝗼𝗿 \n \n ${userNoteObject.usernote} \n \n`;
  3292. }
  3293.  
  3294.  
  3295.  
  3296. // INFOBOX
  3297. if (settings.infoboxEnable)
  3298. {
  3299. userInfoElementTitle += ` \n 𝗪𝘆𝗸𝗼𝗽 𝗫 InfoBox \n Informacje o użytkowniku @${userDataObject.username} \n \n `
  3300.  
  3301. if (changeSexTo == "male") userInfoElementTitle += ` FAŁSZYWY RÓŻOWY PASEK \n \n `;
  3302. else if (changeSexTo == "female") userInfoElementTitle += ` FAŁSZYWY NIEBIESKI PASEK \n \n `;
  3303.  
  3304.  
  3305. if (userDataObject.wxsUserLabel) userInfoElementTitle += ` XLabel: ${userDataObject.wxsUserLabel} \n \n `;
  3306.  
  3307. // basic data without fetch
  3308. if (userDataObject.blacklist == true) // basic
  3309. {
  3310. infoboxInnerHTML += `<var class="wxs_user_blacklist" title="@${userDataObject.username} jest na Twojej czarnej liście">🚯</var>`
  3311. }
  3312. if (userDataObject.follow == true) // basic
  3313. {
  3314. infoboxInnerHTML += `<var class="wxs_user_follow" title="Obserwujesz użytkownika @${userDataObject.username}">🔔</var>`
  3315. }
  3316.  
  3317. if (userDataObject.status == "banned" || userDataObject.status == "suspended") // basic
  3318. {
  3319. if (userDataObject.banned?.wxs_info_text_1) // DETAILS from API
  3320. {
  3321. if (settings.infoboxUserBannedEmoji) infoboxInnerHTML += `<var class="wxs_user_banned" title=" 🍌 ${userDataObject.banned.wxs_info_text_1}. \n \n ${userDataObject.banned.wxs_info_text_2} \n \n ${userDataObject.banned.wxs_info_text_3} \n \n">🍌</var>`;
  3322. userInfoElementTitle += ` 🍌 ${userDataObject.banned.wxs_info_text_1}. \n \n ${userDataObject.banned.wxs_info_text_2} \n \n ${userDataObject.banned.wxs_info_text_3} \n \n`;
  3323. }
  3324. }
  3325.  
  3326. let memberSinceDate = null;
  3327. let membersSinceInYears = null;
  3328. let membersSinceInMonths = null;
  3329. let membersSinceInDays = null;
  3330. memberSinceDate = dayjs(userDataObject.member_since);
  3331. membersSinceInYears = loadTime.diff(memberSinceDate, 'year');
  3332. membersSinceInMonths = loadTime.diff(memberSinceDate, 'month');
  3333. membersSinceInDays = loadTime.diff(memberSinceDate, 'day');
  3334.  
  3335. if (settings.infoboxUserMemberSince)
  3336. {
  3337. if (userDataObject.member_since) // DETAILS from API
  3338. {
  3339.  
  3340. // wyświetlony obok nazwy użytkownika rok założenia konta
  3341. if (membersSinceInDays < 32)
  3342. {
  3343. // konto zalozone dzisiaj
  3344. if (membersSinceInDays == 0)
  3345. {
  3346. let membersSinceInHours = loadTime.diff(memberSinceDate, 'hour');
  3347. let membersSinceInMinutes = loadTime.diff(memberSinceDate, 'minute');
  3348. if (membersSinceInHours == 0)
  3349. {
  3350. infoboxInnerHTML += `<var class="wxs_user_member_since">Konto od ${membersSinceInMinutes} minut </var>`;
  3351. }
  3352. else
  3353. {
  3354. infoboxInnerHTML += `<var class="wxs_user_member_since">Konto od ${membersSinceInHours} h </var>`;
  3355. }
  3356. }
  3357. // wczoraj
  3358. else if (membersSinceInDays == 1)
  3359. {
  3360. infoboxInnerHTML += `<var class="wxs_user_member_since">Konto od wczoraj</var>`;
  3361. }
  3362. else
  3363. {
  3364. infoboxInnerHTML += `<var class="wxs_user_member_since">${membersSinceInDays} dni </var>`;
  3365. }
  3366. }
  3367. // mniej niz 12 miesiecy
  3368. else if (membersSinceInMonths < 12)
  3369. {
  3370. infoboxInnerHTML += `<var class="wxs_user_member_since">${membersSinceInMonths} mies. </var>`;
  3371. }
  3372. // ponad 11 miesiecy
  3373. else
  3374. {
  3375. if (settings.infoboxUserMemberSinceYear) infoboxInnerHTML += `<var class="wxs_user_member_since">${memberSinceDate.year()}</var>`; // 2011
  3376. else
  3377. {
  3378. if (membersSinceInYears >= 5) infoboxInnerHTML += `<var class="wxs_user_member_since">${membersSinceInYears} lat</var>`; // 5 lat
  3379. else if (membersSinceInYears >= 2) infoboxInnerHTML += `<var class="wxs_user_member_since">${membersSinceInYears} lata</var>`; // 2 lata
  3380. else if (membersSinceInYears == 1) infoboxInnerHTML += `<var class="wxs_user_member_since">1 rok</var>`; // 1 rok
  3381. }
  3382.  
  3383. }
  3384. }
  3385. }
  3386. else
  3387. {
  3388. infoboxInnerHTML += `<var class="wxs_user_member_since"> </var>`; // · { i }
  3389. }
  3390.  
  3391.  
  3392. userInfoElementTitle += userDataObject.online ? ` \n @${userDataObject.username} jest teraz online 🟢 \n ` : "";
  3393.  
  3394. if (userDataObject.name) userInfoElementTitle += userDataObject.name != "" ? `Nazwa: ${userDataObject.name} \n ` : "";
  3395. if (userDataObject.city) userInfoElementTitle += userDataObject.city != "" ? `Miasto: ${userDataObject.city} \n ` : "";
  3396. if (userDataObject.public_email) userInfoElementTitle += userDataObject.public_email != "" ? `\n E-mail: ${userDataObject.public_email} \n ` : "";
  3397. userInfoElementTitle += `\n`;
  3398.  
  3399. if (userDataObject.gender == "f")
  3400. {
  3401. userInfoElementTitle += userDataObject.follow ? `🔔 Obserwujesz tę Mirabelkę. \n ` : "";
  3402. userInfoElementTitle += userDataObject.blacklist ? `🚯 Ta Mirabelka jest na Twojej czarnej liście. \n ` : "";
  3403.  
  3404. if (userDataObject.summary) // DETAILS from API
  3405. {
  3406. userInfoElementTitle += userDataObject.summary.followers > 0 ? ` Jest obserwowana przez ${userDataObject.summary.followers} osób` : "Nikt jej nie obserwuje";
  3407. userInfoElementTitle += userDataObject.summary.following_users > 0 ? `, a ona sama obserwuje ${userDataObject.summary.following_users} innych osób oraz ` : `. Nie obserwuje żadnych użytkowników i `;
  3408. userInfoElementTitle += userDataObject.summary.following_tags > 0 ? `${userDataObject.summary.following_tags} #tagów \n ` : `nie obserwuje żadnych #tagów \n `;
  3409. }
  3410.  
  3411. }
  3412. else
  3413. {
  3414. userInfoElementTitle += userDataObject.follow ? `🔔 Obserwujesz tego Mireczka \n ` : "";
  3415. userInfoElementTitle += userDataObject.blacklist ? `🚯 Ten Mireczek jest na Twojej czarnej liście \n ` : "";
  3416.  
  3417. if (userDataObject.summary) // DETAILS from API
  3418. {
  3419. userInfoElementTitle += userDataObject.summary.followers > 0 ? ` Jest obserwowany przez ${userDataObject.summary.followers} osób \n ` : "Nikt go nie obserwuje";
  3420. userInfoElementTitle += `\n On sam obserwuje`;
  3421. userInfoElementTitle += `\n ${userDataObject.summary.following_users} osób `;
  3422. userInfoElementTitle += userDataObject.summary.following_tags > 0 ? `\n ${userDataObject.summary.following_tags} #tagów \n ` : `i nie obserwuje żadnych #tagów \n `;
  3423. }
  3424. }
  3425.  
  3426. if (userDataObject.member_since)
  3427. {
  3428. userInfoElementTitle += `\n Na Wykopie od: ${userDataObject.member_since} \n \n `;
  3429. userInfoElementTitle += `Przez ${membersSinceInYears > 1 ? membersSinceInYears + " lat(a)" : membersSinceInMonths > 1 ? membersSinceInMonths + " miesiące(ęcy)" : membersSinceInDays + " dni"} na Wykopie ${userDataObject.gender == "f" ? "dodała" : "dodał"}: \n `; // Rzeczownik
  3430. }
  3431.  
  3432. if (userDataObject.summary)
  3433. {
  3434. userInfoElementTitle += `\n Na mikroblogu: \n `;
  3435. userInfoElementTitle += `- ${userDataObject.summary.entries_details.added} wpisów\n `;
  3436. userInfoElementTitle += `- ${userDataObject.summary.entries_details.commented} komentarzy pod wpisami \n `;
  3437. userInfoElementTitle += `- ${userDataObject.summary.entries_details.voted} zaplusowanych wpisów \n `;
  3438.  
  3439. userInfoElementTitle += `\n Na głównej: \n `;
  3440. userInfoElementTitle += `- ${userDataObject.summary.links_details.up} wykopanych znalezisk \n `;
  3441.  
  3442. userInfoElementTitle += `- ${userDataObject.summary.links_details.published} znalezisk na głównej \n `;
  3443. userInfoElementTitle += `- ${userDataObject.summary.links_details.added} znalezisk \n `;
  3444. userInfoElementTitle += `- ${userDataObject.summary.links_details.commented} komentarzy pod znaleziskami \n `;
  3445. userInfoElementTitle += `- ${userDataObject.summary.links_details.related} powiązanych do znalezisk \n `;
  3446. }
  3447.  
  3448. if (userDataObject.about) userInfoElementTitle += userDataObject.about != "" ? ` \n \n O sobie: \n ${userDataObject.about} \n \n ` : "";
  3449. }
  3450.  
  3451.  
  3452.  
  3453.  
  3454. if (infoboxInnerHTML !== "") div.innerHTML = infoboxInnerHTML;
  3455. if (noteVarElement !== null) div.appendChild(noteVarElement);
  3456. if (noteURLsElement !== null) div.appendChild(noteURLsElement);
  3457.  
  3458. div.title = `${userInfoElementTitle} \n.`;
  3459. }
  3460.  
  3461. // if(dev) console.log("gotowy user infobox div:")
  3462. // if(dev) console.log(div)
  3463.  
  3464. // dołączenie info o użytkowniku do każdego wystąpienia jego nicka na stronie
  3465. a_usernameAll.forEach((a_username) =>
  3466. {
  3467. // if(dev) console.log(`Dodaję infobox przy każdym linku a.username:`);
  3468. // if(dev) console.log(a_username);
  3469. // if(dev) console.log(a_username.parentNode.nodeName);
  3470. if (a_username.dataset.wxs_username == undefined)
  3471. {
  3472. a_username.dataset.wxs_username = userDataObject.username;
  3473.  
  3474. let a_username_type;
  3475. if (a_username.parentNode.nodeName == "SPAN") a_username_type = "section_entry_header";
  3476. if (a_username.parentNode.nodeName == "LI") a_username_type = "section_entry_voters_li";
  3477.  
  3478.  
  3479. // tylko dla section.entry, nie dla listy plusujących
  3480. if (a_username_type == "section_entry_header")
  3481. {
  3482. if (changeSexTo != false)
  3483. {
  3484. const figureElement = a_username.parentNode.parentNode.parentNode.parentNode.parentNode.querySelector("div.left > a.avatar > figure"); // header
  3485. if (changeSexTo == "male")
  3486. {
  3487. figureElement.classList.remove("female");
  3488. figureElement.classList.add("male");
  3489. }
  3490. else if (changeSexTo == "female")
  3491. {
  3492. figureElement.classList.add("female");
  3493. figureElement.classList.remove("male");
  3494. }
  3495. }
  3496. let sectionObjectElement = a_username.closest('section.entry, section.link-block, aside.profile-top'); // section.entry, section.link-block a w profilu <aside class="profile-top wide-top">
  3497.  
  3498. if (sectionObjectElement && (!sectionObjectElement.dataset.wxs_username || sectionObjectElement.dataset.wxs_username != userDataObject.username))
  3499. {
  3500.  
  3501. // USER DATA BASIC
  3502. sectionObjectElement.dataset.wxs_username = userDataObject.username; // <section data-wxs-username="NadiaFrance">
  3503. sectionObjectElement.dataset.wxs_user_note = userDataObject.note; // data-wxs_user_note="true"
  3504. sectionObjectElement.dataset.wxs_user_company = userDataObject.company; //
  3505. sectionObjectElement.dataset.wxs_user_status = userDataObject.status; // data-wxs_user_status="banned" / "suspended"
  3506. sectionObjectElement.dataset.wxs_user_color = userDataObject.color; // data-wxs_user_color="orange"
  3507. sectionObjectElement.dataset.wxs_user_verified = userDataObject.verified; // data-wxs_user_verified="true"
  3508. sectionObjectElement.dataset.wxs_user_blacklist = userDataObject.blacklist; // data-wxs_user_blacklist="true"
  3509. sectionObjectElement.dataset.wxs_user_follow = userDataObject.follow; // data-wxs_user_follow="true"
  3510. sectionObjectElement.dataset.wxs_user_gender = userDataObject.gender; // data-wxs_user_gender="m"
  3511. sectionObjectElement.dataset.wxs_user_online = userDataObject.online; // data-wxs_user_online="true"
  3512. sectionObjectElement.dataset.wxs_user_rank_position = userDataObject.rank?.position; // data-wxs_user_rank_position=34 // "null"
  3513. sectionObjectElement.dataset.wxs_user_rank_trend = userDataObject.rank?.trend; // data-wxs_user_rank_trend=0
  3514.  
  3515. if (settings.wxsUserLabelsEnable && userDataObject.wxsUserLabel)
  3516. {
  3517. sectionObjectElement.dataset.wxs_user_label = userDataObject.wxsUserLabel; // XLabel
  3518. }
  3519.  
  3520. if (userDataObject.summary)
  3521. {
  3522. sectionObjectElement.dataset.wxs_user_entries_added = userDataObject.summary.entries_details.added; // <section data-wxs-user-entries-added="12">
  3523. sectionObjectElement.dataset.wxs_user_entries_commented = userDataObject.summary.entries_details.commented; // <section data-wxs-user-entries-commented="12">
  3524. sectionObjectElement.dataset.wxs_user_entries_voted = userDataObject.summary.entries_details.voted; // <section data-wxs-user-entries-voted="12">
  3525. sectionObjectElement.dataset.wxs_user_links_up = userDataObject.summary.links_details.up; // <section data-wxs-user-links-up="12">
  3526. sectionObjectElement.dataset.wxs_user_links_published = userDataObject.summary.links_details.published; // <section data-wxs-user-links-published="12">
  3527. sectionObjectElement.dataset.wxs_user_links_added = userDataObject.summary.links_details.added; // <section data-wxs-user-links-added="12">
  3528. sectionObjectElement.dataset.wxs_user_links_commented = userDataObject.summary.links_details.commented; // <section data-wxs-user-links-commented="12">
  3529. sectionObjectElement.dataset.wxs_user_links_related = userDataObject.summary.links_details.related; // <section data-wxs-user-links-related="12">
  3530. }
  3531.  
  3532.  
  3533.  
  3534. // WykopObject
  3535. // to juz jest dodawane wczesniej
  3536.  
  3537. //sectionObjectElement.dataset.wxs_id = sectionObjectElement.__vue__.item.id; // <section data-wxs_id="1234567">
  3538. //sectionObjectElement.dataset.wxs_resource = sectionObjectElement.__vue__.item.resource; // <section data-wxs_resource="entry_comment">
  3539. // if (sectionObjectElement.__vue__.item.parent)
  3540. // {
  3541. // sectionObjectElement.dataset.wxs_parent_resource = sectionObjectElement.__vue__.item.parent.resource; // data-wxs_parent_resource="entry"
  3542. // sectionObjectElement.dataset.wxs_parent_id = sectionObjectElement.__vue__.item.parent.id; // data-wxs_parent_id="1234567"
  3543. // }
  3544. // if (sectionObjectElement.__vue__.item.created_at) sectionObjectElement.dataset.wxs_created_at = sectionObjectElement.__vue__.item.created_at; // data-wxs_created_at="2023-12-31 2359"
  3545. // if (sectionObjectElement.__vue__.item.favourite) sectionObjectElement.dataset.wxs_favourite = sectionObjectElement.__vue__.item.author.favourite; // data-wxs_favourite="true"
  3546. // if (sectionObjectElement.__vue__.item.voted)
  3547. // {
  3548. // sectionObjectElement.dataset.wxs_voted = sectionObjectElement.__vue__.item.voted; // data-wxs_voted="0" / "1"
  3549. // sectionObjectElement.dataset.wxs_votes_up = sectionObjectElement.__vue__.item.votes.up; // data-wxs_votes-up="23"
  3550. // sectionObjectElement.dataset.wxs_votes_down = sectionObjectElement.__vue__.item.votes.down; // data-wxs_votes-up="23"
  3551. // }
  3552. }
  3553. }
  3554.  
  3555.  
  3556. //let div_tooltipSlot = a_username.closest("div.tooltip-slot");
  3557. let userInfoboxDiv = div.cloneNode(true);
  3558. // if(dev) console.log(`userInfoboxDiv`, userInfoboxDiv);
  3559. // if(dev) console.log(`a_username`, a_username);
  3560. // if(dev) console.log(`a_username.closest("div.right > div:has(a.username)")`, a_username.closest("div.right > div:has(a.username)"));
  3561.  
  3562.  
  3563. a_username.closest("div.right > div:has(a.username)").appendChild(userInfoboxDiv);
  3564.  
  3565. // if (div_tooltipSlot)
  3566. // {
  3567. // div_tooltipSlot.insertAdjacentElement('afterend', userInfoboxDiv);
  3568. // }
  3569. // else
  3570. // {
  3571. // a_username.title = userInfoElementTitle;
  3572. // a_username.insertAdjacentElement('afterend', userInfoboxDiv);
  3573. // }
  3574. }
  3575.  
  3576.  
  3577. // elementToInsertUserInfo.appendChild(div);
  3578. // elementToInsertUserInfo.parentNode.insertBefore(div, elementToInsertUserInfo.nextSibling);
  3579.  
  3580. // -- strona wpisu
  3581. // — wpis:
  3582. // section.entry.detailed > article > header > div.right > div > div.tooltip-slot > span > a.username > span
  3583. // section.entry.detailed > article > header > div.right > div > span > a.current.active > time
  3584. // — komentarze:
  3585. // section.entry.detailed > div.comments > section.stream > div.content > section.entry.reply > article > header > div.right > div > div.tooltip-slot > span > a.username > span
  3586. // section.entry.detailed > div.comments > section.stream > div.content > section.entry.reply > article > header > div.right > div > span > a > time
  3587.  
  3588.  
  3589. // -- mikroblog wpisy i komentarze:
  3590. // — wpis:
  3591. // section.entry > article > header > div.right > div > div.tooltip.slot > span > a.username > span
  3592. // section.entry > article > header > div.right > div > span > a > time
  3593. // — komentarze:
  3594. // section.entry > div.comments > section.stream > div.content > section.entry.reply > article > header > div.right > div > div.tooltip-slot > span > a.username > span
  3595. // section.entry > div.comments > section.stream > div.content > section.entry.reply > article > header > div.right > div > span > a > time
  3596.  
  3597. // główna (brak header div.right)
  3598. // section.link-block > section > article > header > div.content > section.info > span > div.tooltip-slot > span > a.username > span
  3599. // section.link-block > section > article > header > div.content > section.info > span > div.tooltip-slot (drugi) > span > a.external // domena linku
  3600. // section.link-block > section > article > header > div.content > section.info > span > time
  3601.  
  3602. // strona znaleziska (brak header div.right)
  3603. // main.main > section > div.content > section.link-page > section.link > section.link-block.detailed > section > article > div.content > section.info > span > div.tooltip-slot > span > a.username > span
  3604. // main.main > section > div.content > section.link-page > section.link > section.link-block.detailed > section > article > div.content > section.info > span > div.tooltip-slot (drugi) > span > a.external
  3605. // main.main > section > div.content > section.link-page > section.link > section.link-block.detailed > section > article > div.content > section.info > span > time
  3606.  
  3607. // wpisy na stronie profilu
  3608. // main.main > section > div.content > section.profile-page > section.profile > section.stream.link-entries > div.content > section.entry > article > header > div.right > div > div.tooltip-slot > span > a.username > span
  3609. // main.main > section > div.content > section.profile-page > section.profile > section.stream.link-entries > div.content > section.entry > article > header > div.right > div > span > a > time
  3610.  
  3611. // prawy sidebar (brak .tooltip-slot)
  3612. //main.main > section > section.sidebar > section > div.content > section.entries > section.entry > header > div.right > div > a.username > span
  3613. //main.main > section > section.sidebar > section > div.content > section.entries > section.entry > header > div.right > div > span.plus // +16 liczba plusów
  3614. //main.main > section > section.sidebar > section > div.content > section.entries > section.entry > header > div.right > a > time
  3615.  
  3616. // strona PROFILU — naglowek profilu uzytkownika (brak .tooltip-slot)
  3617. // main.main > aside.profile-top > section > header > div > h1 > a.username > span
  3618. // main.main > aside.profile-top > section > header > div > time
  3619. });
  3620. div.remove();
  3621. }
  3622.  
  3623.  
  3624.  
  3625.  
  3626.  
  3627.  
  3628.  
  3629.  
  3630.  
  3631. /* ------------- NOTATKOWATOR ------------ */
  3632. async function getUserNoteObjectByUsername(sectionObjectElement, username = sectionObjectElement.__vue__.item.author.username, forceAPICheck = false)
  3633. {
  3634. consoleX(`getUserNoteObjectByUsername(username: ${username}, forceAPICheck: ${forceAPICheck})`, 1)
  3635.  
  3636. if (settings.notatkowatorEnable && (forceAPICheck || (sectionObjectElement && sectionObjectElement.__vue__.item.author.note)))
  3637. {
  3638. // consoleX(`getUserNoteObjectByUsername()`, 1);
  3639.  
  3640. if (username)
  3641. {
  3642. let usernote = "";
  3643. let userNoteObject = await localStorageNotatkowator.getItem(username);
  3644.  
  3645. // consoleX(`getUserNoteObjectByUsername()`, 1);
  3646. // if(dev) console.log(username);
  3647.  
  3648. if (forceAPICheck == false)
  3649. {
  3650. // TODO check this
  3651.  
  3652. if (userNoteObject == null || userNoteObject == "")
  3653. {
  3654. // if(dev) console.log("typeof userNoteObject", typeof userNoteObject)
  3655. // if(dev) console.log(userNoteObject);
  3656.  
  3657. const date2 = dayjs(userNoteObject.lastUpdate);
  3658.  
  3659. //if (loadTime.diff(date2, "second") > parseFloat(settings.notatkowatorUpdateInterval * 3600))
  3660. //{
  3661. // userNoteObject = null; /* notatka jest zbyt stara */
  3662. //}
  3663. //else
  3664. //{
  3665. // mamy aktualną notatkę z localforage
  3666. // consoleX(`Notatkowator wczytał notatkę z LocalStorage. Użytkownik: @${username}`);
  3667. // if(dev) console.log("userNoteObject")
  3668. // if(dev) console.log(userNoteObject)
  3669. // if(dev) console.log("userNoteObject.usernote")
  3670. // if(dev) console.log(userNoteObject.usernote)
  3671. usernote = userNoteObject.usernote;
  3672.  
  3673. return userNoteObject;
  3674. //}
  3675. }
  3676. }
  3677.  
  3678. if (usernote != "")
  3679. {
  3680. return userNoteObject;
  3681. }
  3682.  
  3683. else // Notatka z API — brak notatki o tym użytkowniku w localforage lub była zbyt stara lub forceAPICheck = true
  3684. {
  3685. try
  3686. {
  3687. let jsonResponse = await getWykopAPIData("notes", username);
  3688. usernote = jsonResponse?.data?.content;
  3689.  
  3690. /*
  3691. Notes from API:
  3692. user.data = { username: 'NadiaFrance', content: 'Treść notatki' }
  3693. user.data = { username: 'NadiaFrance', content: '' }
  3694. Notes from LocalStorage:
  3695. userNoteObject -> wykopx/notatkowator/tomek123456789 =
  3696. {
  3697. username: "Zenek",
  3698. usernote: "Notatka | +r",
  3699. lastUpdate: "2024-01-07T15:55:37.210Z"
  3700. gender: "f" / "m" / null
  3701. changeSexTo: "female" / "male"
  3702. }
  3703. */
  3704.  
  3705. userNoteObject =
  3706. {
  3707. username: jsonResponse?.data?.username,
  3708. usernote: jsonResponse?.data?.content,
  3709. gender: sectionObjectElement.__vue__.item.author,
  3710. lastUpdate: dayjs()
  3711. }
  3712.  
  3713. const plusWordsArray = getPlusWords(userNoteObject.usernote);
  3714. // if(dev) console.log("plusWordsArray")
  3715. // if(dev) console.log(plusWordsArray)
  3716.  
  3717. // dodane jakies +przełączniki
  3718. if (plusWordsArray[0] != "normal")
  3719. {
  3720. const femaleChecklistArray = ["k", "f", "female", "kobieta", "dziewczyna", "dziewczynka", "girl", "baba", "różowa", "rozowa", "rózowa", "rożowa"];
  3721. const maleChecklistArray = ["m", "mezczyzna", "mężczyzna", "męzczyzna", "meżczyzna", "male", "facet", "boy", "chlopak", "chłopak", "chłopiec", "chłop", "chlop", "niebieski"];
  3722. const isFemale = plusWordsArray.filter(item => femaleChecklistArray.includes(item));
  3723. const isMale = plusWordsArray.filter(item => maleChecklistArray.includes(item));
  3724.  
  3725. if (isFemale.length >= 1) // różowy pasek // +k lub +f
  3726. {
  3727. userNoteObject.changeSexTo = "female";
  3728. userNoteObject.gender = "f";
  3729. //userDataObject.gender="f";
  3730. }
  3731. else if (isMale.length >= 1) // niebieski pasek // +m
  3732. {
  3733. userNoteObject.changeSexTo = "male";
  3734. userNoteObject.gender = "m";
  3735. //userDataObject.gender="m";
  3736. }
  3737. }
  3738.  
  3739.  
  3740. // if(dev) console.log(jsonResponse);
  3741. // if(dev) console.log("userNoteObject");
  3742. // if(dev) console.log(userNoteObject);
  3743.  
  3744.  
  3745.  
  3746.  
  3747. if (usernote != "" && userNoteObject.usernote != null && userNoteObject.usernote != "")
  3748. {
  3749. // if(dev) console.log(`API zwróciło ${userNoteObject.username} notatkę: ${userNoteObject.usernote}`);
  3750. consoleData.notatkowator.count++;
  3751. refreshConsole();
  3752.  
  3753. // await displayUserNote(sectionObjectElement, usernote, username)
  3754.  
  3755. if (localStorageNotatkowator)
  3756. {
  3757. localStorageNotatkowator.setItem(username, userNoteObject)
  3758. .then(function (value)
  3759. {
  3760. consoleX(`Notatkowator zapisał notatkę o użytkowniku @${userNoteObject.username}: "${userNoteObject.usernote}"`, 1);
  3761. })
  3762. .catch(function (err)
  3763. {
  3764. consoleX(`Notatkowator = error: ` + err, 1);
  3765. });
  3766. // return usernote;
  3767. return userNoteObject
  3768. }
  3769. }
  3770. else
  3771. {
  3772. // consoleX(`Użytkownik ${username} nie ma żadnej notatki`)
  3773. }
  3774. }
  3775. catch (error)
  3776. {
  3777. console.error(`Failed to get data: ${error}`);
  3778. }
  3779. }
  3780. }
  3781.  
  3782. }
  3783.  
  3784. }
  3785.  
  3786.  
  3787.  
  3788.  
  3789.  
  3790.  
  3791.  
  3792. /* wyświetlenie danych o autorze z __vue__ lub pobranie z API*/
  3793. async function getUserDetailsForUsername(userDataObject = null, username = userDataObject.username, forceAPICheck = false)
  3794. {
  3795.  
  3796. consoleX(`getUserDetailsForUsername(username: ${username}, forceAPICheck: ${forceAPICheck})`, 1)
  3797.  
  3798. if (settings.infoboxEnable && username)
  3799. {
  3800. // consoleX(`getUserDetailsForUsername() ${username}`, 1);
  3801.  
  3802. // if(dev) console.log(`user: ${username}: `)
  3803.  
  3804. // jesli jest zbanowany lub chcemy wszystkie dane (np. followersi — wysylamy zapytanie do API)
  3805. if (userDataObject.status == "banned" || userDataObject.status == "suspended" || forceAPICheck == true)
  3806. {
  3807. // if(dev) console.log("---- getUserDetailsForUsername — sprawdzanie użytkownika w API: " + username)
  3808. try
  3809. {
  3810. // profile/users/{username}
  3811. // profile/users/{username}/short
  3812. // let jsonResponse = await getWykopAPIData("profile", "users", username, "short");
  3813. let jsonResponse = await getWykopAPIData("profile", "users", username);
  3814. if (jsonResponse.data)
  3815. {
  3816. let userDataObject = jsonResponse.data;
  3817.  
  3818. // if(dev) console.log("userData fetched from API");
  3819. // if(dev) console.log(userDataObject);
  3820. return userDataObject; // return the data
  3821. }
  3822.  
  3823. }
  3824. catch (error)
  3825. {
  3826. console.error(`Failed to get data: ${error}`);
  3827. }
  3828. }
  3829. // jeśli wystarczą nam podstawowe informacje z __vue__
  3830. else
  3831. {
  3832. // if(dev) console.log("---- getUserDetailsForUsername — zwracam danej użytkownika z vue: " + username)
  3833. return userDataObject;
  3834. }
  3835. }
  3836. }
  3837.  
  3838.  
  3839.  
  3840.  
  3841. // wykop_xs_banned.user.js - START - 2
  3842. if (settings.infoboxUserBannedInfoOnProfilePage)
  3843. {
  3844. waitForKeyElements("aside.profile-top:has(aside.info-box.red)", bannedUserProfileAside, false);
  3845.  
  3846. // DODAJEMY INFO NA STRONIE PROFILOWEJ O SZCZEGÓŁACH BANA
  3847. function bannedUserProfileAside(element)
  3848. {
  3849. const bannedUserObject = element?.__vue__?.user;
  3850.  
  3851. if (!bannedUserObject) return;
  3852.  
  3853. if (bannedUserObject.status == "banned" || bannedUserObject.status == "suspended")
  3854. {
  3855. bannedUserObject.banned.wxs_reason_lowercase = bannedUserObject.banned.reason.toLowerCase();
  3856.  
  3857. bannedUserObject.banned.wxs_ban_end_date_string = bannedUserObject.banned.expired; // "2024-01-04 17:22:31" / null
  3858. if (bannedUserObject.banned.wxs_ban_end_date_string != null)
  3859. {
  3860. bannedUserObject.banned.wxs_ban_end_date_object = dayjs(bannedUserObject.banned.wxs_ban_end_date_string);
  3861. bannedUserObject.banned.wxs_ban_end_in_years = bannedUserObject.banned.wxs_ban_end_date_object.diff(loadTime, 'year'); // 5 > koniec bana za "5" lat
  3862. bannedUserObject.banned.wxs_ban_end_in_months = bannedUserObject.banned.wxs_ban_end_date_object.diff(loadTime, 'month'); // 3 > koniec bana za: "3" miesiące
  3863. bannedUserObject.banned.wxs_ban_end_in_days = bannedUserObject.banned.wxs_ban_end_date_object.diff(loadTime, 'day'); // 31 > koniec bana za 31 dni
  3864. bannedUserObject.banned.wxs_ban_end_in_days = bannedUserObject.banned.wxs_ban_end_date_object.diff(loadTime, 'day'); // 31 > koniec bana za 31 dni
  3865. // banEndDateDuration = banEndDateObject.toNow()
  3866.  
  3867. }
  3868.  
  3869.  
  3870.  
  3871. const bannedRedBox = element.querySelector("aside.info-box.red p");
  3872. let bannedRedBoxInnerHTML = `To konto jest ${bannedUserObject.status == "suspended" ? "w trakcie usuwania" : "zbanowane"}. <br/><br/><strong>Informacja z Wykop X - Ban Info:</strong> <br/>`;
  3873.  
  3874. // Ban permanentny
  3875. if (bannedUserObject.status == "banned" && (bannedUserObject.banned.wxs_ban_end_date_string == null || bannedUserObject.banned.wxs_ban_end_in_years > 100))
  3876. {
  3877. bannedRedBoxInnerHTML = `To konto jest zbanowane permanentnie. <br/><br/><strong>Wykop XS Ban Info:</strong> <br/>`;
  3878. }
  3879.  
  3880.  
  3881. // "Użytkowniczka @NadiaFrance dsotała bana za naruszenie regulaminu"
  3882. if (bannedUserObject.status == "suspended")
  3883. {
  3884. bannedRedBoxInnerHTML += `${bannedUserObject.gender == "f" ? "Użytkowniczka @" + bannedUserObject.username + " rozpoczęła usuwanie konta" : "Użytkownik @" + bannedUserObject.username + " rozpoczął usuwanie konta"}`;
  3885. }
  3886. else
  3887. {
  3888. bannedRedBoxInnerHTML += `${bannedUserObject.gender == "f" ? "Użytkowniczka @" + bannedUserObject.username + " dostała" : "Użytkownik @" + bannedUserObject.username + " dostał"} bana za <strong>${bannedUserObject.banned.wxs_reason_lowercase}</strong>`;
  3889. }
  3890.  
  3891. // Ban permanentny
  3892. if (bannedUserObject.banned.wxs_ban_end_date_string == null || bannedUserObject.banned.wxs_ban_end_in_years > 100)
  3893. {
  3894. // Ban permanentny na 999 lat
  3895. bannedRedBoxInnerHTML += `<br/><small>Ban permanentny. Śpij słodko aniołku [*] </small>`;
  3896. }
  3897. else
  3898. {
  3899. // "Koniec bana za 14 dni"
  3900. bannedRedBoxInnerHTML += `<br/><small title="Czas końca bana dotyczy czasu letniego. \nWykop posiada błąd i nie rozpoznaje czasu zimowego, \ndlatego zimą i jesienią ban trwa o godzinę dłużej niż podany">
  3901. Koniec bana ${bannedUserObject.banned.wxs_ban_end_in_years > 1 ? "za <strong>" + bannedUserObject.banned.wxs_ban_end_in_years + " lat(a)" : bannedUserObject.banned.wxs_ban_end_in_months > 1 ? "za <strong>" + bannedUserObject.banned.wxs_ban_end_in_months + " miesiące(ęcy)" : bannedUserObject.banned.wxs_ban_end_in_days > 1 ? "za <strong>" + bannedUserObject.banned.wxs_ban_end_in_days + " dni" : bannedUserObject.banned.wxs_ban_end_date_object.isSame(loadTime, 'day') == true ? " <strong>już dzisiaj! " : " jutro"}</strong><br/>`;
  3902. // "Ban trwa do 2024-12-12 23:59:59"
  3903. bannedRedBoxInnerHTML += `Ban trwa do ${bannedUserObject.banned.wxs_ban_end_date_string}<span style="cursor: help; padding: 0px 7px">ℹ</span></small>`;
  3904. }
  3905.  
  3906. bannedRedBox.innerHTML = bannedRedBoxInnerHTML;
  3907. }
  3908. }
  3909. }
  3910. // wykop_xs_banned.user.js - END - 2
  3911.  
  3912.  
  3913.  
  3914.  
  3915. // DOPISUJE NOTATKĘ DO UZYTKOWNIKA
  3916. /*async function displayUserNote(sectionObjectElement = null, usernote, username = sectionObjectElement.__vue__.item.author.username)
  3917. {
  3918. if (usernote?.length > 0 && username)
  3919. {
  3920. // "⭐ Obok nicka (Notatkowator2000)":"obok_nicka",
  3921. // "Wyraźna, pod avatarem (Wykop X Style)":"pod_avatarem",
  3922. let elementToInsertNoteAfter;
  3923. const sectionObjectElementsAll = document.querySelectorAll(`section[data-wxs_username="${username}"]`)
  3924. sectionObjectElementsAll.forEach((section) =>
  3925. {
  3926. if (!section.dataset.wxs_note || section.dataset.wxs_username != username)
  3927. {
  3928. section.dataset.wxs_note="true"; // <section data-wxs-note="true" wxs_username="NadiaFrance">
  3929. // if(dev) console.log(`Notatkowator — dodaje notatkę: ${ username } / ${usernote}`);
  3930. let resource = section.__vue__.item.resource;
  3931. if (resource == "entry" || resource == "entry_comment" || resource == "link_comment")
  3932. {
  3933. switch (settings.notatkowatorStyle)
  3934. {
  3935. case "pod_avatarem":
  3936. elementToInsertNoteAfter = section.querySelector(`article > header`);
  3937. break;
  3938. case "obok_nicka":
  3939. elementToInsertNoteAfter = section.querySelector(`article > header > div.right > div > div.tooltip-slot`);
  3940. break;
  3941. default:
  3942. null;
  3943. }
  3944. }
  3945. else if (resource == "link")
  3946. {
  3947. elementToInsertNoteAfter = section.querySelector("section > article > div.content > section.info > span > div.tooltip-slot");
  3948. }
  3949. */
  3950.  
  3951.  
  3952.  
  3953.  
  3954.  
  3955.  
  3956.  
  3957.  
  3958.  
  3959. // returns objecct-id "comment-1234567", "link-12345678"
  3960. function getObjectIdFromSectionObjectElement(sectionObjectElement)
  3961. {
  3962. consoleX(`getObjectIdFromSectionObjectElement()`, 1);
  3963.  
  3964. if (sectionObjectElement && sectionObjectElement.__vue__?.item?.resource)
  3965. {
  3966. let resource = sectionObjectElement.__vue__.item.resource;
  3967.  
  3968. if (resource == "link")
  3969. {
  3970. return `link-${sectionObjectElement.__vue__.item.id}`;
  3971. }
  3972. else if (resource == "entry" || resource == "entry_comment" || resource == "link_comment")
  3973. {
  3974. return `comment-${sectionObjectElement.__vue__.item.id}`;
  3975. }
  3976. }
  3977. else
  3978. {
  3979. return null;
  3980. }
  3981. }
  3982. // zwraca tytul znaleziska lub fragment poczatku wpisu/komentarza. Maks tytul znaleziska to 80 znakow
  3983. function getTitleTextFromSectionObjectElement(sectionObjectElement, charLimit = 80)
  3984. {
  3985. consoleX(`getTitleTextFromSectionObjectElement(charLimit: ${charLimit})`, 1);
  3986.  
  3987. if (sectionObjectElement && sectionObjectElement.__vue__?.item?.resource)
  3988. {
  3989. let resource = sectionObjectElement.__vue__.item.resource;
  3990.  
  3991. if (resource == "link" && sectionObjectElement.__vue__?.item?.title)
  3992. {
  3993. return sectionObjectElement.__vue__.item.title.substring(0, charLimit);
  3994. }
  3995. else if (sectionObjectElement.__vue__?.item?.content && (resource == "entry" || resource == "entry_comment" || resource == "link_comment"))
  3996. {
  3997. return sectionObjectElement.__vue__.item.content.replace(/\n/g, " ").substring(0, charLimit);
  3998. }
  3999. }
  4000. else
  4001. {
  4002. return null;
  4003. }
  4004. }
  4005.  
  4006.  
  4007.  
  4008. /* MIRKOUKRYWA */
  4009.  
  4010. // mirkoukrywaczBlockNewElement(sectionObjectElement, null, "minimized")
  4011. // mirkoukrywaczBlockNewElement(null, "comment-123456", "hidden")
  4012. function mirkoukrywaczBlockNewElement(sectionObjectElement = null, object_id = getObjectIdFromSectionObjectElement(sectionObjectElement), blockingType = "hidden")
  4013. {
  4014. // console.clear();
  4015. consoleX(`mirkoukrywaczBlockNewElement(blockingType: ${blockingType})`, 1);
  4016.  
  4017.  
  4018. if (localStorageMirkoukrywacz && (sectionObjectElement || object_id))
  4019. {
  4020. if (!sectionObjectElement)
  4021. {
  4022. sectionObjectElement = document.getElementById(object_id);
  4023. }
  4024.  
  4025. if (blockingType == "minimized")
  4026. {
  4027. sectionObjectElement.classList.add('wxs_minimized');
  4028. consoleData.mirkoukrywacz_minimized.count++;
  4029. refreshConsole();
  4030. }
  4031. else if (blockingType == "hidden")
  4032. {
  4033. sectionObjectElement.classList.add('wxs_hidden');
  4034. consoleData.mirkoukrywacz_hidden.count++;
  4035. refreshConsole();
  4036. }
  4037.  
  4038. const resource = sectionObjectElement.__vue__.item.resource;
  4039. const text = getTitleTextFromSectionObjectElement(sectionObjectElement);
  4040. if (!object_id) object_id = getObjectIdFromSectionObjectElement(sectionObjectElement);
  4041.  
  4042. // if(dev) console.log("sectionObjectElement")
  4043. // if(dev) console.log(sectionObjectElement);
  4044.  
  4045. localStorageMirkoukrywacz
  4046. .setItem(object_id,
  4047. {
  4048. object_id,
  4049. grandcomment_id: sectionObjectElement.__vue__.item.parent?.id,
  4050. resource,
  4051. username: sectionObjectElement.__vue__.item.author?.username,
  4052. text,
  4053. blockingType, // "hidden" / "minimized"
  4054. date: dayjs()
  4055. })
  4056. .then(function (value)
  4057. {
  4058. // if(dev) console.log(value);
  4059. })
  4060. .catch(function (err)
  4061. {
  4062. if (dev) console.log(`mirkoukrywaczBlockNewElement = error: ` + err);
  4063. });
  4064. // mirkoukrywaczHideAllBlockedElements();
  4065. }
  4066. }
  4067.  
  4068. function mirkoukrywaczUnblockElement(sectionObjectElement = null, object_id = getObjectIdFromSectionObjectElement(sectionObjectElement))
  4069. {
  4070. // console.clear();
  4071. if (dev) console.log(`mirkoukrywaczUnblockElement(${object_id})`)
  4072.  
  4073. if (localStorageMirkoukrywacz)
  4074. {
  4075. localStorageMirkoukrywacz
  4076. .getItem(object_id)
  4077. .then(function (value)
  4078. {
  4079. if (dev) console.log("getItem: " + object_id)
  4080. if (dev) console.log(value)
  4081.  
  4082. localStorageMirkoukrywacz
  4083. .removeItem(object_id)
  4084. .then(function ()
  4085. {
  4086. if (value.blockingType == "minimized")
  4087. {
  4088. if (!sectionObjectElement) sectionObjectElement = document.getElementById(object_id);
  4089. if (sectionObjectElement)
  4090. {
  4091. sectionObjectElement.classList.remove(`wxs_minimized`);
  4092. consoleData.mirkoukrywacz_hidden.count--;
  4093. refreshConsole();
  4094. }
  4095. }
  4096. document.getElementById(`wykopx_mirkoukrywacz_element_${object_id}`)?.remove();
  4097. })
  4098. .catch(function (err)
  4099. {
  4100. if (dev) console.log(err);
  4101. });
  4102. })
  4103. }
  4104. }
  4105.  
  4106. function mirkoukrywaczHideAllBlockedElements()
  4107. {
  4108. consoleX(`mirkoukrywaczHideAllBlockedElements()`, 1)
  4109. if (localStorageMirkoukrywacz)
  4110. {
  4111. //consoleX(`mirkoukrywaczHideAllBlockedElements()`, 1);
  4112.  
  4113. let hiddenElements = 0;
  4114. let minimizedElements = 0;
  4115.  
  4116. localStorageMirkoukrywacz.iterate(function (value, key, iterationNumber)
  4117. {
  4118. // if(dev) console.log("value");
  4119. // if(dev) console.log(value);
  4120. // if(dev) console.log("key");
  4121. // if(dev) console.log(key);
  4122.  
  4123. let foundElementToHide = document.getElementById(`${key}`); // comment-1234 link-12345
  4124. if (foundElementToHide)
  4125. {
  4126.  
  4127. if (value.blockingType == "hidden")
  4128. {
  4129. if (sectionObjectIntersectionObserver) sectionObjectIntersectionObserver.unobserve(foundElementToHide);
  4130. foundElementToHide.remove();
  4131. hiddenElements++;
  4132. }
  4133. else if (value.blockingType == "minimized")
  4134. {
  4135. foundElementToHide.classList.add(`wxs_minimized`); // class="wxs_minimized"
  4136. minimizedElements++;
  4137. }
  4138. }
  4139. }).then(function ()
  4140. {
  4141.  
  4142. if (hiddenElements + minimizedElements == 0)
  4143. {
  4144. consoleData.mirkoukrywacz_hidden.count = 0;
  4145. consoleData.mirkoukrywacz_minimized.count = 0;
  4146. refreshConsole();
  4147. }
  4148. else
  4149. {
  4150. consoleData.mirkoukrywacz_hidden.count = hiddenElements;
  4151. consoleData.mirkoukrywacz_minimized.count = minimizedElements;
  4152. refreshConsole();
  4153. }
  4154.  
  4155.  
  4156. }).catch(function (err)
  4157. {
  4158. if (dev) console.log(err);
  4159. });
  4160.  
  4161. }
  4162. /*
  4163. value = {
  4164. "id": "74301447",
  4165. "grandcomment_id": "74301447",
  4166. "resource": "entry",
  4167. "username": "Jadowityssak",
  4168. "text": "Zawsze jak widzę tego typa z Afromental to mi gość",
  4169. "date": "2023-12-26T02:44:23.039Z"
  4170. "blockingType": "minimize"/"hide" }*/
  4171. }
  4172.  
  4173. function mirkoukrywaczAppendOneElementToHideList(value, key, iterationNumber = "⭐")
  4174. {
  4175. consoleX(`mirkoukrywaczAppendOneElementToHideList(value: ${value}, key: ${key})`);
  4176.  
  4177. if (!document.querySelector(`#wxs_modal .wykopx_mirkoukrywacz_list_of_hidden_items #wykopx_mirkoukrywacz_element_${key}`))
  4178. {
  4179. let hidden_element_html = `
  4180. <div class="wykopx_mirkoukrywacz_element" id="wykopx_mirkoukrywacz_element_${key}">
  4181. <div class="wykopx_mirkoukrywacz_unhide" data-object_id="${key}" title="Przestań ukrywać ten element">❌</div>
  4182. <div class="wykopx_mirkoukrywacz_lp">${iterationNumber}</div>
  4183. <div class="wykopx_mirkoukrywacz_text">${value.text}</div>
  4184. <div class="wykopx_mirkoukrywacz_id">${key}</div>
  4185. <div class="wykopx_mirkoukrywacz_resource">${value.resource}</div>
  4186. <div class="wykopx_mirkoukrywacz_date">${dayjs(value.date).format("YYYY-MM-DD HH:mm")}</div>
  4187. <div class="wykopx_mirkoukrywacz_blocking_type">${value.blockingType}</div>
  4188. </div>`;
  4189. document.querySelector("#wxs_modal .wykopx_mirkoukrywacz_list_of_hidden_items").innerHTML += hidden_element_html;
  4190. }
  4191. }
  4192.  
  4193. function mirkoukrywaczRefreshHideList()
  4194. {
  4195. if (localStorageMirkoukrywacz)
  4196. {
  4197. consoleX(`mirkoukrywaczRefreshHideList()`, 1);
  4198.  
  4199. localStorageMirkoukrywacz
  4200. .iterate(function (value, key, iterationNumber)
  4201. {
  4202. mirkoukrywaczAppendOneElementToHideList(value, key, iterationNumber);
  4203. })
  4204. .then(function () { })
  4205. .catch(function (err) { });
  4206. }
  4207.  
  4208. }
  4209.  
  4210. function createMenuItemForMirkoukrywacz()
  4211. {
  4212. if (settings.mirkoukrywaczEnable)
  4213. {
  4214. consoleX(`createMenuItemForMirkoukrywacz()`, 1)
  4215.  
  4216. if (document.getElementById("wxs_open_modal_mirkoukrywacz_button") == null)
  4217. {
  4218. createProfileDropdownMenuItem(
  4219. {
  4220. text: `Mirkoukrywacz: Wykop X`,
  4221. title: "Wykop X — lista elementów ukrytych przez Mirkoukrywacz",
  4222. className: `mirkoukrywacz`,
  4223. id: "wxs_open_modal_mirkoukrywacz_button",
  4224. url: null,
  4225. target: null,
  4226. icon: null,
  4227. number: null
  4228. });
  4229. document.getElementById("wxs_open_modal_mirkoukrywacz_button").onclick = function (event)
  4230. {
  4231. event.preventDefault();
  4232. if (wxs_modal == null)
  4233. {
  4234. createModalBox();
  4235. }
  4236. mirkoukrywaczRefreshHideList();
  4237. wxs_modal.style.display = "block";
  4238. };
  4239. }
  4240. }
  4241. }
  4242. function createMenuItemForNotatkowator()
  4243. {
  4244. if (settings.notatkowatorEnable)
  4245. {
  4246. consoleX(`createMenuItemForNotatkowator()`, 1)
  4247.  
  4248. createProfileDropdownMenuItem(
  4249. {
  4250. text: `Notatki: Wykop X`,
  4251. title: "Wykop X — Notatkowator — Twoje notatki do innych użytkowników",
  4252. className: `notatkowator`,
  4253. id: "wxs_open_modal_notatkowator_button",
  4254. url: null,
  4255. target: null,
  4256. icon: null,
  4257. number: null
  4258. });
  4259. document.getElementById("wxs_open_modal_notatkowator_button").onclick = function (event)
  4260. {
  4261. //mirkoukrywaczRefreshHideList();
  4262. event.preventDefault();
  4263. if (wxs_modal == null) createModalBox();
  4264. wxs_modal.style.display = "block";
  4265. };
  4266. }
  4267. }
  4268.  
  4269. function createModalBox()
  4270. {
  4271. if (wxs_modal == null)
  4272. {
  4273. consoleX(`createModalBox()`, 1)
  4274.  
  4275. let html = `
  4276. <div class="wykopxs wykopx_modal" id="wxs_modal">
  4277. <div class="wykopx_modal-content">
  4278. <aside class="wykopxs_info_bar wykopx_hide_this_if_stylus_is_installed">
  4279. Masz już działający skrypt Wykop XS. Aby Mirkoukrywacz działał, musisz zainstalować i włączyć w Stylusie <a href="http://wiki.wykopx.pl" target="_blank">Wykop X</a>
  4280. </aside>
  4281. <aside class="wxs_modal_is_turned_off wykopx_hide_this_if_mirkoukrywanie_is_turned_on">
  4282. Wykop XS oraz Wykop X są zainstalowane poprawnie, ale Mirkoukrywacz jest wyłączony. Aby Mirkoukrywacz działał, włącz go w ustawieniach Stylusa. <a href="https://github.com/wykopx/WykopX/wiki/Extra#mirkoukrywacz" target="_blank">Zobacz instrukcję obsługi Mirkoukrywacza</a>
  4283. </aside>
  4284. <header class="wykopxs">
  4285. <span>Mirkoukrywacz:</span>
  4286. <span>Lista ukrytych elementów</span>
  4287. </header>
  4288. <section class="wykopxs wykopx_mirkoukrywacz_list_of_hidden_items">
  4289. <span class="wykopx_mirkoukrywacz_hidden_list_is_empty">
  4290. Żadne treści nie zostały jeszcze zaznaczone do ukrycia
  4291. </span>
  4292. </section>
  4293. <footer>
  4294. <span>Usuń z Mirkoukrywacza</span>
  4295. <section>
  4296. <select id="wxs_mirkoukrywacz_delete_block_type">
  4297. <option value="all" selected>wszystkie</option>
  4298. <option value="minimized">zwinięte (Krawężnik)</option>
  4299. <option value="hidden">ukryte (Mirkoukrywacz)</option>
  4300. </select>
  4301. <select id="wxs_mirkoukrywacz_delete_resource">
  4302. <option value="all" selected>znaleziska, wpisy i komentarze</option>
  4303. <option value="links">znaleziska</option>
  4304. <option value="entries">wpisy</option>
  4305. <option value="comments">komentarze</option>
  4306. </select>
  4307. <select id="wxs_mirkoukrywacz_delete_timespan">
  4308. <option value="30">starsze niż miesiąc</option>
  4309. <option value="14">starsze niż 2 tygodnie</option>
  4310. <option value="7">starsze niż 7 dni</option>
  4311. <option value="3" selected>starsze niż 3 dni</option>
  4312. <option value="1">starsze niż 1 dzień</option>
  4313. <option value="0">wszystkie</option>
  4314. </select>
  4315. </section>
  4316. <button id="wxs_mirkoukrywacz_delete_older_than_7_days">Usuń</button>
  4317. <button id="wxs_mirkoukrywacz_delete_all" style="color: rgb(255, 60, 60); margin-left: auto;">Usuń wszystkie</button>
  4318. </footer>
  4319. </div>
  4320. </div>`;
  4321.  
  4322. body.insertAdjacentHTML('afterbegin', html);
  4323. wxs_modal = document.getElementById("wxs_modal");
  4324.  
  4325. window.onclick = function (event)
  4326. {
  4327. if (event.target == wxs_modal)
  4328. {
  4329. wxs_modal.style.display = "none";
  4330. }
  4331. };
  4332. }
  4333. }
  4334.  
  4335.  
  4336. function mirkoukrywaczRemoveTooOld(PointerEvent, options)
  4337. {
  4338. if (localStorageMirkoukrywacz && options)
  4339. {
  4340. consoleX(`mirkoukrywaczRemoveTooOld()`, 1);
  4341.  
  4342. let numberOfRemovedItems = 0;
  4343.  
  4344. localStorageMirkoukrywacz.iterate(function (value, id, iterationNumber)
  4345. {
  4346. if (value.blockingType == options.blockingType || options.blockingType == "all") // "hidden", "minimized"
  4347. {
  4348. const itemDate = dayjs(value.date);
  4349. const diffInDays = loadTime.diff(itemDate, 'day', true); // true — floating point
  4350.  
  4351. if (diffInDays >= options.days)
  4352. {
  4353. numberOfRemovedItems++;
  4354.  
  4355. localStorageMirkoukrywacz.removeItem(id).then(function ()
  4356. {
  4357. document.getElementById(`wykopx_mirkoukrywacz_element_${id}`).remove();
  4358. }).catch(function (err) { console.log(err); });
  4359. }
  4360. }
  4361. }).then(function ()
  4362. {
  4363. if (numberOfRemovedItems > 0)
  4364. {
  4365. if (options.days == 0) alert(`Wykop X Mirkowołacz:
  4366.  
  4367. Usunięto wszystkie elementy z listy.
  4368. Od teraz będą się one znów wyświetlać na Wykopie`);
  4369. else alert(`Wykop X Mirkowołacz:
  4370.  
  4371. ${numberOfRemovedItems} ukrytych elementów starszych niż ${options.days} dni
  4372. zostało usuniętych z listy Mirkoukrywacza.
  4373.  
  4374. Od teraz będą się one znów wyświetlać na Wykopie`);
  4375. }
  4376. }).catch(function (err)
  4377. {
  4378. if (dev) console.log(err);
  4379. });
  4380. }
  4381. }
  4382.  
  4383.  
  4384.  
  4385.  
  4386.  
  4387.  
  4388.  
  4389.  
  4390.  
  4391.  
  4392.  
  4393. /* AUTOMATYCZNIE POKAŻ CAŁOŚĆ DŁUGICH TREŚCI */
  4394. function autoOpenMoreContentEverywhere()
  4395. {
  4396. if (settings.autoOpenMoreContentEverywhere)
  4397. {
  4398. consoleX("autoOpenMoreContentEverywhere()", 1)
  4399.  
  4400. let showMoreButtons = document.querySelectorAll("div.wrapper button.more");
  4401. if (showMoreButtons?.length > 0)
  4402. {
  4403. showMoreButtons.forEach(button =>
  4404. {
  4405. button.click()
  4406. });
  4407. consoleX(`Automatycznie rozwinięto ${showMoreButtons.length} długich wpisów i komentarzy`);
  4408. }
  4409. }
  4410. }
  4411. /* AUTOMATYCZNIE ROZWIJAJ SPOILERY */
  4412. function autoOpenSpoilersEverywhere()
  4413. {
  4414. if (settings.autoOpenSpoilersEverywhere)
  4415. {
  4416. consoleX("autoOpenMoreContentEverywhere()", 1)
  4417.  
  4418. let showSpoilerButtons = document.querySelectorAll("div.wrapper section.content-spoiler button");
  4419. if (showSpoilerButtons?.length > 0)
  4420. {
  4421. showSpoilerButtons.forEach(button =>
  4422. {
  4423. button.click()
  4424. });
  4425. consoleX(`Automatycznie rozwinięto ${showSpoilerButtons.length} spoilerów`);
  4426. }
  4427. }
  4428. }
  4429.  
  4430.  
  4431. /* Kliknięcie w stronę główną odświeża stronę główną */
  4432. function topNavLogoClick()
  4433. {
  4434. if (settings.topNavLogoClick == "mikroblog")
  4435. {
  4436. consoleX(`topNavLogoClick()`, 1);
  4437.  
  4438. refreshOrRedirectOnButtonClick(`body > section > header.header > div.left > a`, `/mikroblog`);
  4439. }
  4440. else if (settings.topNavLogoClick == "mikroblog_dodaj")
  4441. {
  4442. refreshOrRedirectOnButtonClick(`body > section > header.header > div.left > a`, `/mikroblog#dodaj`);
  4443. }
  4444. }
  4445. /* Kliknięcie w stronę główną odświeża stronę główną */
  4446. function topNavHomeButtonClickRefreshOrRedirect()
  4447. {
  4448. if (settings.topNavHomeButtonClickRefreshOrRedirect)
  4449. {
  4450. consoleX(`topNavHomeButtonClickRefreshOrRedirect()`, 1);
  4451. refreshOrRedirectOnButtonClick(`body > section > header.header > div.left > nav.main > ul > li > a[href="/"]`, `/`);
  4452. }
  4453. }
  4454. /* Kliknięcie w Mikroblog odświeża stronę */
  4455. function topNavMicroblogButtonClickRefreshOrRedirect()
  4456. {
  4457. if (settings.topNavMicroblogButtonClickRefreshOrRedirect)
  4458. {
  4459. consoleX(`topNavMicroblogButtonClickRefreshOrRedirect()`, 1);
  4460.  
  4461. refreshOrRedirectOnButtonClick(`body > section > header.header > div.left > nav.main > ul > li > a[href="/mikroblog"]`, `/mikroblog`);
  4462. }
  4463. }
  4464.  
  4465. function refreshOrRedirectOnButtonClick(selector, pathToRefresh = "/")
  4466. {
  4467. consoleX(`refreshOrRedirectOnButtonClick(selector: ${selector}, pathToRefresh: ${pathToRefresh})`, 1)
  4468. document.querySelectorAll(selector).forEach(function (element)
  4469. {
  4470. element.addEventListener('click', function (event)
  4471. {
  4472. event.preventDefault();
  4473. let pathname = new URL(document.URL).pathname;
  4474. if (pathname == pathToRefresh) window.location.reload();
  4475. else window.location.href = pathToRefresh;
  4476. });
  4477. });
  4478. }
  4479.  
  4480.  
  4481.  
  4482. if (settings.categoryRedirectToMicroblogButtonEnable)
  4483. {
  4484. waitForKeyElements(`ul.categories`, categoryRedirectToMicroblogButton, false); // waitForKeyElements sends jNode object, not DOM object
  4485. }
  4486.  
  4487. // przyciski MIRKO w kategoriach
  4488. function categoryRedirectToMicroblogButton(ul_category_element)
  4489. {
  4490. consoleX("categoryRedirectToMicroblogButton()", 1);
  4491.  
  4492. /*
  4493. "Najnowsze":"_mikroblog_najnowsze",
  4494. "Ostatnio wybrane":"_mikroblog",
  4495. "Aktywne":"_mikroblog_aktywne",
  4496. "Gorące (2h)":"_mikroblog_gorace_2",
  4497. "Gorące (6h)":"_mikroblog_gorace_6",
  4498. "Gorące (12h)":"_mikroblog_gorace_12",
  4499. "Gorące (24h)":"_mikroblog_gorace_24"
  4500. */
  4501. if (document.querySelectorAll('section.links div.content ul.categories .wykopx_categories_microblog_a').length == 0)
  4502. {
  4503. let listItems = document.querySelectorAll('section.links div.content ul.categories li');
  4504. listItems.forEach(function (item)
  4505. {
  4506. let kategoria = item.outerText;
  4507. let href = "";
  4508. switch (kategoria)
  4509. {
  4510. case "Ciekawostki":
  4511. href = "/k/ciekawostki";
  4512. break;
  4513. case "Informacje":
  4514. href = "/k/informacje";
  4515. break;
  4516. case "Rozrywka":
  4517. href = "/k/rozrywka";
  4518. break;
  4519. case "Sport":
  4520. href = "/k/sport";
  4521. break;
  4522. case "Motoryzacja":
  4523. href = "/k/motoryzacja";
  4524. break;
  4525. case "Technologia":
  4526. href = "/k/technologia";
  4527. break;
  4528. case "Ukraina":
  4529. href = "/k/ukraina";
  4530. break;
  4531. case "Gospodarka":
  4532. href = "/k/gospodarka";
  4533. break;
  4534. case "Podróże":
  4535. href = "/k/podroze";
  4536. break;
  4537. default:
  4538. null;
  4539. }
  4540. href += settings.categoryRedirectToMicroblogButtonFilter;
  4541. const microblogButtonHtml = `<li class="wykopxs wykopx_categories_microblog_li"><a class="wykopx_categories_microblog_a" href="${href}">M</a></li>`;
  4542. item.insertAdjacentHTML('afterend', microblogButtonHtml);
  4543. });
  4544.  
  4545. }
  4546.  
  4547. if (document.querySelectorAll('section.links div.content ul.buckets .wykopx_categories_microblog_a').length == 0)
  4548. {
  4549. document.querySelectorAll('section.links div.content ul.buckets li').forEach(function (item)
  4550. {
  4551. let href = item.querySelector("a").getAttribute("href");
  4552. href = href.replaceAll("/mikroblog", "");
  4553. href += settings.categoryRedirectToMicroblogButtonFilter;
  4554. const microblogButtonHtml = `<li class="wykopxs wykopx_categories_microblog_li"><a class="wykopxs wykopx_categories_microblog_a" href="${href}"></a></li>`;
  4555. item.insertAdjacentHTML('afterend', microblogButtonHtml);
  4556. });
  4557. }
  4558.  
  4559. }
  4560.  
  4561.  
  4562.  
  4563.  
  4564.  
  4565.  
  4566.  
  4567. // otwieranie powiadomienia SPM w nowej karcie
  4568. // REMOVED in WykopXS 3.0
  4569. /* if (wykopxSettings.getPropertyValue("--middleClickOpensNotificationsInNewTab"))
  4570. {
  4571. // środkowy przycisk na powiadomieniu otwiera je w nowej karcie
  4572. body.addEventListener('mousedown', function(e1) {
  4573. if (e1.target.closest('section.notifications-stream section.notify') && e1.which === 2) {
  4574. let target = e1.target;
  4575. target.addEventListener('mouseup', function(e2) {
  4576. if (e1.target === e2.target) {
  4577. let url_to_open = target.querySelector('a[href^="/wpis/"]').getAttribute('href');
  4578. let tab_handle = window.open(url_to_open, '_blank');
  4579. // tab_handle.blur(); //window.focus();
  4580. if (window.CustomEvent) {
  4581. var e3 = new CustomEvent('middleclick', {bubbles: true, cancelable: true});
  4582. e2.target.dispatchEvent(e3);
  4583. } else if (document.createEvent) {
  4584. var e3 = document.createEvent('HTMLEvents');
  4585. e3.initEvent('middleclick', true, true);
  4586. e2.target.dispatchEvent(e3);
  4587. }
  4588. }
  4589. }, {once: true});
  4590. }
  4591. });
  4592. }
  4593. */
  4594.  
  4595.  
  4596.  
  4597. // otwieranie obrazka w nowej karcie klikając wybrany przycisk myszy
  4598. if (settings.mouseClickOpensImageInNewTab != "nie_otwieraj")
  4599. {
  4600. let detected_event_click;
  4601. let event_trigger_type;
  4602.  
  4603. if (settings.mouseClickOpensImageInNewTab == "lewy_przycisk_myszy")
  4604. {
  4605. detected_event_click = 1;
  4606. event_trigger_type = "wykopx_leftclick";
  4607. }
  4608. if (settings.mouseClickOpensImageInNewTab == "srodkowy_przycisk_myszy")
  4609. {
  4610. detected_event_click = 2;
  4611. event_trigger_type = "wykopx_middleclick";
  4612. }
  4613. if (settings.mouseClickOpensImageInNewTab == "prawy_przycisk_myszy")
  4614. {
  4615. detected_event_click = 3;
  4616. event_trigger_type = "wykopx_rightclick";
  4617. }
  4618. body.addEventListener('mousedown', function (e1)
  4619. {
  4620. if (e1.which === detected_event_click && e1.target?.tagName === 'IMG' && e1.target?.src?.startsWith('https://wykop.pl/cdn/'))
  4621. {
  4622. const sectionEntryPhoto = e1.target.closest('section.entry section.entry-photo');
  4623.  
  4624. if (sectionEntryPhoto)
  4625. {
  4626. e1.preventDefault();
  4627. consoleX("Kliknięto przycisk myszy: " + e1.which, 1);
  4628.  
  4629. e1.target.addEventListener('mouseup', function (e2)
  4630. {
  4631. e2.preventDefault();
  4632. if (e1.target === e2.target)
  4633. {
  4634. let url_to_open = sectionEntryPhoto.querySelector('a[href^="https://wykop.pl/cdn/"]').getAttribute('href');
  4635. window.open(url_to_open, '_blank');
  4636.  
  4637. if (window.CustomEvent)
  4638. {
  4639. var e3 = new CustomEvent(event_trigger_type, { bubbles: true, cancelable: true });
  4640. e2.target.dispatchEvent(e3);
  4641. }
  4642. else if (document.createEvent)
  4643. {
  4644. var e3 = document.createEvent('HTMLEvents');
  4645. e3.initEvent(event_trigger_type, true, true);
  4646. e2.target.dispatchEvent(e3);
  4647. }
  4648. }
  4649. }, { once: true });
  4650. }
  4651.  
  4652.  
  4653. }
  4654.  
  4655.  
  4656.  
  4657. });
  4658.  
  4659. }
  4660.  
  4661.  
  4662.  
  4663.  
  4664.  
  4665.  
  4666.  
  4667.  
  4668.  
  4669.  
  4670.  
  4671.  
  4672. /* checking for new versions */
  4673. // getIntegerVersionNumber("2.50.3") -> 2503
  4674. function getIntegerVersionNumber(versionString)
  4675. {
  4676. let arr = versionString.split(".");
  4677. let result = arr[0] * 1000 + arr[1] * 10 + arr[2] * 1;
  4678. return result;
  4679. }
  4680.  
  4681.  
  4682. async function checkVersionForUpdates()
  4683. {
  4684. // if (!dev) console.clear();
  4685. consoleX("Sprawdzanie aktualizacji Wykop X Style i Wykop XS...");
  4686.  
  4687. try
  4688. {
  4689. const response = await fetch(`https://update.wykopx.pl/xs/wykopxs?${currentVersion}`); // wykopxs?3.0.0
  4690. const newestWykopXSVersion = await response.text();
  4691.  
  4692.  
  4693. if (getIntegerVersionNumber(currentVersion) >= getIntegerVersionNumber(newestWykopXSVersion))
  4694. {
  4695. consoleX(`✅ Masz najnowszą wersję skryptu Wykop XS v.${currentVersion}`);
  4696. }
  4697. else
  4698. {
  4699. addWykopXSNewVersionAvailableToast();
  4700. consoleX(`🆕 Dostępna jest nowa wersja Wykop XS v. ${newestWykopXSVersion} Możesz wejść na http://script.wykopx.pl i zaktualizować skrypt. Wersja, którą masz u siebie to Wykop XS v.${currentVersion}`);
  4701. }
  4702. }
  4703. catch (error)
  4704. {
  4705. }
  4706.  
  4707. if (settings.versor == "style" || settings.versor == "blank")
  4708. {
  4709. try
  4710. {
  4711. const response = await fetch(`https://update.wykopx.pl/xs/wykopx${settings.versor}?${settings.version}`); // wykopxstyle?3.0.0 | wykopxblank?3.0.0
  4712. const newestWykopXStyleVersion = await response.text();
  4713.  
  4714. if (getIntegerVersionNumber(settings.version) >= getIntegerVersionNumber(newestWykopXStyleVersion))
  4715. {
  4716. consoleX(`✅ Masz najnowszą wersję styli Wykop X ${capitalizeFirstLetter(settings.versor)} v.${settings.version}`);
  4717. }
  4718. else
  4719. {
  4720. addWykopXStyleNewVersionAvailableToast();
  4721. consoleX(`🆕 Dostępna jest nowa wersja styli Wykop X ${capitalizeFirstLetter(settings.versor)} v.${newestWykopXStyleVersion} Możesz wejść na http://${settings.versor}.wykopx.pl i zaktualizować je. Wersja, którą masz u siebie to Wykop X ${capitalizeFirstLetter(settings.versor)} v.${settings.version}`);
  4722. }
  4723. }
  4724. catch (error)
  4725. {
  4726. }
  4727. }
  4728. }
  4729.  
  4730.  
  4731.  
  4732. function hideWykopXSPromo()
  4733. {
  4734. consoleX("hideWykopXSPromo()", 1)
  4735.  
  4736. let style = document.createElement('style');
  4737. style.innerHTML = `body div.main-content section > section.sidebar::after { display: none !important; }`;
  4738. head.appendChild(style);
  4739. }
  4740.  
  4741. function addWykopXPromoBanner()
  4742. {
  4743. consoleX("addWykopXPromoBanner()", 1)
  4744.  
  4745. let targetElement = document.querySelector('section.sidebar > footer');
  4746. if (targetElement)
  4747. {
  4748. const wykopxpromo = document.createElement('section');
  4749. const wykopxpromolink = document.createElement('a');
  4750. wykopxpromolink.href = "http://xstyle.wykopx.pl/"
  4751. wykopxpromolink.target = "wykopx"
  4752. wykopxpromo.appendChild(wykopxpromolink);
  4753. wykopxpromo.classList.add("wykopx_promo", "wykopx_promo_banner");
  4754. targetElement.parentNode.insertBefore(wykopxpromo, targetElement);
  4755. }
  4756. }
  4757.  
  4758. function addWykopXSNewVersionAvailableToast()
  4759. {
  4760. consoleX("addWykopXSNewVersionAvailableToast()", 1)
  4761.  
  4762.  
  4763. // <a href="http://script.wykopx.pl" target="_blank" style="color: #fff!important;">
  4764. let wykopxsnewversionavailabletoast = `
  4765. <aside class="wykopxs_new_version wykopxs_info_bar">
  4766. <span class="wykopxs_new_version_first">
  4767. Dostępna jest nowa wersja skryptu Wykop XS.
  4768. </span>
  4769. <a href="https://greasyfork.org/scripts/458860-wykop-xs/code/Wykop%20XS.user.js" target="_blank" style="color: #fff!important;">
  4770. Zaktualizuj Wykop XS
  4771. </a>
  4772. <span class="wykopxs_new_version_second">
  4773. do najnowszej wersji
  4774. </span>
  4775. <footer>
  4776. Twoja wersja Wykop XS to v.${currentVersion}
  4777. </footer>
  4778. </aside>`;
  4779. document.querySelector('body > section > header.header').insertAdjacentHTML('afterend', wykopxsnewversionavailabletoast);
  4780. }
  4781.  
  4782. function addWykopXStyleNewVersionAvailableToast()
  4783. {
  4784. consoleX("addWykopXStyleNewVersionAvailableToast()", 1)
  4785.  
  4786. let wykopxstylenewversionavailabletoast = "";
  4787.  
  4788. if (settings.versor == "style")
  4789. {
  4790. wykopxstylenewversionavailabletoast = `
  4791. <aside class="wykopxs_new_version wykopxs_info_bar">
  4792. <span class="wykopxs_new_version_first">Dostępna jest nowa wersja styli Wykop X Style</strong>.
  4793. </span>
  4794. <a href="https://userstyles.world/style/8174/wykop-x-style" target="_blank" style="color: #fff!important;">
  4795. Zaktualizuj Wykop X Style
  4796. </a>
  4797. <span class="wykopxs_new_version_second">do najnowszej wersji</span>
  4798. <footer>Twoja wersja Wykop X Style to v.${settings.version}</footer>
  4799. </aside>`;
  4800. }
  4801. else if (settings.versor == "blank")
  4802. {
  4803. wykopxstylenewversionavailabletoast = `
  4804. <aside class="wykopxs_new_version wykopxs_info_bar">
  4805. <span class="wykopxs_new_version_first">Dostępna jest nowa wersja styli Wykop X Blank</strong>.</span>
  4806. <a href="https://userstyles.world/style/8174/wykop-x-style" target="_blank" style="color: #fff!important;">
  4807. Zaktualizuj Wykop X Blank
  4808. </a>
  4809. <span class="wykopxs_new_version_second">do najnowszej wersji</span>
  4810. <footer>Twoja wersja Wykop X Style to v.${settings.version}</footer>
  4811. </aside>`;
  4812. }
  4813.  
  4814. let div = document.createElement('div');
  4815. div.innerHTML = wykopxstylenewversionavailabletoast;
  4816. let newElement = div.firstChild;
  4817. let header = document.querySelector('body > section > header.header');
  4818. header.parentNode.insertBefore(newElement, header.nextSibling);
  4819. }
  4820. function addWykopXBlockerNewVersionAvailableToast()
  4821. {
  4822. consoleX("addWykopXBlockerNewVersionAvailableToast()", 1)
  4823.  
  4824. let wykopxblockernewversionavailabletoast = `
  4825. <aside class="wykopxs_new_version wykopxs_info_bar">
  4826. <span class="wykopxs_new_version_first">Dostępna jest nowa wersja styli Wykop X Blocker</strong>.
  4827. </span>
  4828. <a href="https://userstyles.world/style/" target="_blank" style="color: #fff!important;">
  4829. Zaktualizuj Wykop X Blocker
  4830. </a>
  4831. <span class="wykopxs_new_version_second">do najnowszej wersji</span>
  4832. <footer>Twoja wersja Wykop X Blocker to v.${settings.xblocker}</footer>
  4833. </aside>`;
  4834. let div = document.createElement('div');
  4835. div.innerHTML = wykopxblockernewversionavailabletoast;
  4836. let newElement = div.firstChild;
  4837. let header = document.querySelector('body > section > header.header');
  4838. header.parentNode.insertBefore(newElement, header.nextSibling);
  4839. }
  4840.  
  4841.  
  4842.  
  4843.  
  4844.  
  4845.  
  4846.  
  4847.  
  4848. const unreadNotifications = {
  4849. tags: 0,
  4850. tags_new_entry_with_observed_tag: 0,
  4851. tags_new_link_with_observed_tag: 0,
  4852. entries: 0,
  4853. pm: 0,
  4854. total: 0,
  4855. };
  4856.  
  4857. // ZLICZA NOWE POWIADOMIENIA Z MENU OD 1 DO 5+
  4858. function countNumberOfNotificationsOnDesktop()
  4859. {
  4860. consoleX(`countNumberOfNotificationsOnDesktop()`, 1)
  4861.  
  4862. unreadNotifications.tags = unreadNotifications.tags_new_entry_with_observed_tag = unreadNotifications.tags_new_link_with_observed_tag = unreadNotifications.entries = unreadNotifications.pm = unreadNotifications.total = 0;
  4863.  
  4864. let elements = document.querySelectorAll('header .right ul li.dropdown');
  4865. elements.forEach(function (element)
  4866. {
  4867. element.classList.remove('unread_5', 'unread_4', 'unread_3', 'unread_2', 'unread_1');
  4868. });
  4869.  
  4870.  
  4871.  
  4872. let li_dropdown = document.querySelectorAll("header .right ul li.dropdown:has(a.new)");
  4873. li_dropdown.forEach(function (dropdown)
  4874. {
  4875.  
  4876. const lastWord = dropdown.className.split(" ").pop();
  4877. let numberOfNotifications = 0;
  4878. let notifies = dropdown.querySelectorAll(".notify:not(.read)");
  4879. notifies.forEach(function (notify)
  4880. {
  4881. ++numberOfNotifications;
  4882. notify.classList.add(`unread_${numberOfNotifications}`);
  4883. if (lastWord == "tags")
  4884. {
  4885. ++unreadNotifications["total"];
  4886. if (notify.querySelector(`div.content p.new-entry-with-observed-tag`))
  4887. {
  4888. ++unreadNotifications["tags_new_entry_with_observed_tag"];
  4889. ++unreadNotifications["tags"];
  4890. ++unreadNotifications["total"];
  4891. } else if (notify.querySelector(`div.content p.new-link-with-observed-tag`))
  4892. {
  4893. ++unreadNotifications["tags_new_link_with_observed_tag"];
  4894. ++unreadNotifications["tags"];
  4895. ++unreadNotifications["total"];
  4896. }
  4897. } else if (lastWord == "entries")
  4898. {
  4899. ++unreadNotifications["entries"];
  4900. ++unreadNotifications["total"];
  4901. }
  4902. });
  4903. let parentNotification = dropdown.closest(`.notifications.dropdown`);
  4904. if (parentNotification)
  4905. {
  4906. parentNotification.classList.add(`unread_${numberOfNotifications}`);
  4907. }
  4908. });
  4909.  
  4910.  
  4911. if (unreadNotifications["tags"] > 0)
  4912. {
  4913. consoleX(`Liczba nowych powiadomień z obserwowanych tagów: ${unreadNotifications["tags"]} (w tym ${unreadNotifications["tags_new_entry_with_observed_tag"]} z wpisów i ${unreadNotifications["tags_new_link_with_observed_tag"]} ze znalezisk)`, 1);
  4914. }
  4915. if (unreadNotifications["entries"] > 0)
  4916. {
  4917. consoleX(`Liczba nowych zawołań: ${unreadNotifications["entries"]}`, 1);
  4918. }
  4919.  
  4920.  
  4921.  
  4922. let li_pm_dropdown = document.querySelectorAll("header .right ul li.pm.dropdown");
  4923. li_pm_dropdown.forEach(function (dropdown)
  4924. {
  4925. if (dropdown.querySelector('a.new'))
  4926. {
  4927. let numberOfNotifications = 0; // liczba powiadomień o wiadomościach PM
  4928. let unreadItems = dropdown.querySelectorAll(".item.unread");
  4929. unreadItems.forEach(function (item, index)
  4930. {
  4931. ++numberOfNotifications;
  4932. ++unreadNotifications["total"];
  4933. item.classList.add(`unread_${numberOfNotifications}`);
  4934. });
  4935. let parentDropdown = dropdown.closest(`.pm.dropdown`);
  4936. if (parentDropdown)
  4937. {
  4938. parentDropdown.classList.add(`unread_${numberOfNotifications}`);
  4939. }
  4940. unreadNotifications["pm"] = numberOfNotifications;
  4941. // if(dev) console.log(`Liczba nowych wiadomości: ${unreadNotifications["pm"]}`);
  4942. }
  4943. });
  4944.  
  4945.  
  4946. if (unreadNotifications.tags > 0)
  4947. {
  4948. createProfileDropdownMenuItem(
  4949. {
  4950. text: `Powiadomienia z #tagów: (${unreadNotifications.tags < 25 ? unreadNotifications.tags : "25+"})`,
  4951. title: "Masz nowe powiadomienia z obserwowanych #tagów",
  4952. className: `wykopx_notifications_tags`,
  4953. id: undefined,
  4954. url: "/powiadomienia/tagi",
  4955. target: "_self",
  4956. icon: null,
  4957. number: unreadNotifications.tags < 25 ? unreadNotifications.tags : "25+"
  4958. })
  4959. }
  4960. if (unreadNotifications.entries > 0)
  4961. {
  4962. createProfileDropdownMenuItem(
  4963. {
  4964. text: `Zawołania w komentarzach: (${unreadNotifications.entries < 25 ? unreadNotifications.entries : "25+"})`,
  4965. title: "Zawołano Cię w komentarzu",
  4966. className: `wykopx_notifications_entries`,
  4967. id: undefined,
  4968. url: "/powiadomienia/moje",
  4969. target: "_self",
  4970. icon: null,
  4971. number: unreadNotifications.entries < 25 ? unreadNotifications.entries : "25+"
  4972. })
  4973. }
  4974. if (unreadNotifications.pm > 0)
  4975. {
  4976. createProfileDropdownMenuItem(
  4977. {
  4978. text: `Nowe wiadomości: (${unreadNotifications.pm < 25 ? unreadNotifications.pm : "25+"})`,
  4979. title: "Masz nowe, nieprzeczytane wiadomości prywatne",
  4980. className: `wykopx_notifications_pm`,
  4981. id: undefined,
  4982. url: "/wiadomosci",
  4983. target: "_self",
  4984. icon: null,
  4985. number: unreadNotifications.pm < 25 ? unreadNotifications.pm : "25+"
  4986. })
  4987. }
  4988.  
  4989. if (settings.tabChangeEnabled) executeTabAndFaviconChanges();
  4990. }
  4991.  
  4992.  
  4993.  
  4994. function addWykopXButtonsToNavBar()
  4995. {
  4996. consoleX("addWykopXButtonsToNavBar()", 1)
  4997.  
  4998. // createNewNavBarButton({
  4999. // position: "left",
  5000. // text: "Czat",
  5001. // title: `Otwórz mikroczat.pl ${promoString}`,
  5002. // class: "open_mikroczat", // wykopx_open_mikroczat_li
  5003. // hideWithoutXStyle: false,
  5004. // url: mikroczatDomain,
  5005. // target: "mikroczat",
  5006. // icon: "https://i.imgur.com/9PvHlaA.png",
  5007. // number: null,
  5008. // })
  5009.  
  5010.  
  5011. if (settings.myWykopInTopNavJS)
  5012. {
  5013. createNewNavBarButton({
  5014. position: "left",
  5015. text: "Mój Wykop",
  5016. title: `Mój Wykop ${promoString}`,
  5017. class: "mywykop", // wykopx_mywykop_li
  5018. hideWithoutXStyle: false,
  5019. url: "/obserwowane",
  5020. target: "_self",
  5021. icon: null,
  5022. number: null,
  5023. data: "data-v-5182b5f6",
  5024. })
  5025. }
  5026. if (settings.hitsInTopNavJS)
  5027. {
  5028. createNewNavBarButton({
  5029. position: "left",
  5030. text: "Hity",
  5031. title: `Hity ${promoString}`,
  5032. class: "hits",
  5033. hideWithoutXStyle: false,
  5034. url: "/hity",
  5035. target: "_self",
  5036. icon: null,
  5037. number: null,
  5038. data: "data-v-5182b5f6",
  5039. })
  5040. }
  5041. if (settings.favoritesInTopNavJS)
  5042. {
  5043. createNewNavBarButton({
  5044. position: "left",
  5045. text: "Ulubione",
  5046. title: `Ulubione ${promoString}`,
  5047. class: "favorites",
  5048. hideWithoutXStyle: false,
  5049. url: "/ulubione",
  5050. target: "_self",
  5051. icon: null,
  5052. number: null,
  5053. data: "data-v-5182b5f6",
  5054. })
  5055. }
  5056. if (settings.addNewLinkInTopNavJS)
  5057. {
  5058. createNewNavBarButton({
  5059. position: "left",
  5060. text: "+",
  5061. title: `Dodaj nowe Znalezisko ${promoString}`,
  5062. class: ["add_new_link", "plus"], // wykopx_add_new_link_li wykopx_plus_li // a > wykopx_add_new_link wykopx_plus_button
  5063. hideWithoutXStyle: false,
  5064. url: "/dodaj-link",
  5065. target: "_self",
  5066. icon: null,
  5067. number: null,
  5068. data: "data-v-5182b5f6",
  5069. insertAfter: `li:has(a[href="/wykopalisko"])`
  5070. })
  5071. }
  5072.  
  5073. if (settings.addNewEntryInTopNavJS)
  5074. {
  5075. createNewNavBarButton({
  5076. position: "left",
  5077. text: "+",
  5078. title: `Dodaj nowy wpis na Mirko ${promoString}`,
  5079. class: ["add_new_entry", "plus"], // wykopx_add_new_entry_li wykopx_plus_li // a > wykopx_add_new_entry wykopx_plus_button
  5080. hideWithoutXStyle: false,
  5081. url: "/mikroblog/#dodaj",
  5082. target: "_self",
  5083. icon: null,
  5084. number: null,
  5085. data: "data-v-5182b5f6",
  5086. insertAfter: `li:has(a[href="/mikroblog"])`
  5087. })
  5088. }
  5089.  
  5090. // TODO IF
  5091. /* createNewNavBarButton({
  5092. position: "left",
  5093. text: "Wykop X Style",
  5094. title: `Zainstaluj style CSS "𝗪𝘆𝗸𝗼𝗽 𝗫 𝗦𝘁𝘆𝗹𝗲" w rozszerzeniu Stylus i odkryj setki dodatkowych funkcji zmieniających i naprawiających Wykop`,
  5095. class: ["promo", "install_wykopx"], // wykopx_promo (ukrywane przez X Style) wykopx_install_wykopx_li hybrid" | a > wykopx_promo wykopx_install_wykopx_button hybrid
  5096. hideWithoutXStyle: false,
  5097. url: "https://userstyles.world/search?q=Wykop+X+Style+3&category=&sort=mostinstalls",
  5098. target: "_blank",
  5099. icon: null,
  5100. number: null,
  5101. data: "data-v-5182b5f6",
  5102. }) */
  5103.  
  5104. addQuickLinksToNavBar();
  5105.  
  5106. }
  5107.  
  5108.  
  5109. // QUICK LINKS
  5110. function addQuickLinksToNavBar()
  5111. {
  5112. consoleX("addQuickLinksToNavBar()", 1)
  5113.  
  5114. if (settings.quickLinksEnable == true)
  5115. {
  5116. let wxs_quick_links = document.getElementById("wxs_quick_links");
  5117. if (wxs_quick_links == null)
  5118. {
  5119. wxs_quick_links = document.createElement('div');
  5120. wxs_quick_links.id = "wxs_quick_links";
  5121. // wxs_quick_links.classList.add("wykopxs"); // nie dodajemy bo domyslnie wlaczone
  5122.  
  5123. wxs_quick_links.innerHTML = `
  5124.  
  5125. <nav class="home">
  5126. <section>
  5127. <span>
  5128. <a href="/" target="_self" title="Wykop X: Przejdź na stronę główną Wykopu">Główna</a>
  5129. </span>
  5130. <div>
  5131. <a href="/najnowsze" target="_self" title="Wykop X: Najnowsze znaleziska, które dostały się na główną">Najnowsze</a>
  5132. <a href="/aktywne" target="_self" title="Wykop X: Najpopularniejsze znaleziska na stronie głównej z ostatnich 24 godzin">Aktywne</a>
  5133. </div>
  5134. </section>
  5135.  
  5136. <section>
  5137. <span>
  5138. <a href="/hity" target="_self">Hity</a>
  5139. </span>
  5140. <div>
  5141. <a href="/hity/dnia" target="_self">Dnia</a>
  5142. <a href="/hity/tygodnia" target="_self">Tygodnia</a>
  5143. <a href="/hity/miesiaca" target="_self">Miesiąca</a>
  5144. <a href="/hity/roku" target="_self">Roku</a>
  5145. </div>
  5146. </section>
  5147.  
  5148. <section>
  5149. <span>Ulubione</span>
  5150. <div>
  5151. <a href="/ulubione/znaleziska" target="_self" title="Wykop X: Znaleziska dodane przez Ciebie do Ulubionych">Znaleziska</a>
  5152. <a href="/ulubione/komentarze-znaleziska" target="_self" title="Wykop X: Komentarze pod znaleziskami dodane przez Ciebie do Ulubionych">Komentarze do znalezisk</a>
  5153. </div>
  5154. </section>
  5155. </nav>
  5156. <nav class="upcoming">
  5157. <section>
  5158. <span>Dodaj</span>
  5159. <div>
  5160. <a href="/dodaj-link" target="_self" title="Wykop X: Dodaj nowe znalezisko (link do strony internetowej)">Nowe znalezisko</a>
  5161. </div>
  5162. </section>
  5163. <section>
  5164. <span>Wykopalisko</span>
  5165. <div>
  5166. <a href="/wykopalisko/najnowsze" target="_self">Najnowsze</a>
  5167. <a href="/wykopalisko/aktywne" target="_self">Aktywne</a>
  5168. <a href="/wykopalisko/wykopywane" target="_self">Wykopywane</a>
  5169. <a href="/wykopalisko/komentowane" target="_self">Komentowane</a>
  5170. </div>
  5171. <span>Moja aktywność</span>
  5172. <div>
  5173. <a href="/ludzie/${loggedUser.username}/znaleziska/dodane" target="_self">Moje znaleziska</a>
  5174. <a href="/ludzie/${loggedUser.username}/znaleziska/komentowane" target="_self">Komentowane</a>
  5175. <a href="/ludzie/${loggedUser.username}/znaleziska/wykopane" target="_self">Wykopane</a>
  5176. <a href="/ludzie/${loggedUser.username}/znaleziska/zakopane" target="_self">Zakopane</a>
  5177. </div>
  5178. </section>
  5179.  
  5180. <section>
  5181. <span>Ulubione</span>
  5182. <div>
  5183. <a href="/ulubione/znaleziska" target="_self" title="Wykop X: Znaleziska dodane przez Ciebie do Ulubionych">Znaleziska</a>
  5184. <a href="/ulubione/komentarze-znaleziska" target="_self" title="Wykop X: Komentarze pod znaleziskami dodane przez Ciebie do Ulubionych">Komentarze do znalezisk</a>
  5185. </div>
  5186. </section>
  5187. </nav>
  5188.  
  5189. <nav class="hits">
  5190. <section>
  5191. <span>Hity</span>
  5192. <div>
  5193. <a href="/hity/dnia" target="_self">Dnia</a>
  5194. <a href="/hity/tygodnia" target="_self">Tygodnia</a>
  5195. <a href="/hity/miesiaca" target="_self">Miesiąca</a>
  5196. <a href="/hity/roku" target="_self">Roku</a>
  5197. </div>
  5198. </section>
  5199.  
  5200. <section>
  5201. <span>Archiwum</span>
  5202. <div>
  5203. <a href="/hity/2020" target="_self">2020</a>
  5204. <a href="/hity/2021" target="_self">2021</a>
  5205. <a href="/hity/2022" target="_self">2022</a>
  5206. <a href="/hity/2023" target="_self">2023</a>
  5207. </div>
  5208. </section>
  5209. </nav>
  5210.  
  5211.  
  5212. <nav class="microblog">
  5213. <section>
  5214. <span>Dodaj</span>
  5215. <div>
  5216. <a href="/mikroblog/#dodaj" target="_self" title="Wykop X: Dodaj nowy wpis na Mikroblogu">Nowy wpis na Mirko</a>
  5217. </div>
  5218. </section>
  5219.  
  5220. <section>
  5221. <span>Mikroblog</span>
  5222. <div>
  5223. <a href="/mikroblog/najnowsze" target="_self" title="Wykop X: Najnowsze wpisy na Mikroblogu">Najnowsze</a>
  5224. <a href="/mikroblog/aktywne" target="_self" title="Wykop X: Nowe, angażujące wpisy na Mikroblogu">Aktywne</a>
  5225. </div>
  5226. </section>
  5227.  
  5228. <section>
  5229. <span>
  5230. <a href="/mikroblog/gorace" target="_self" title="Wykop X: Przejdź na ostatnio wybrane gorące">Gorące</a>
  5231. </span>
  5232. <div>
  5233. <a href="/mikroblog/gorace/2" class="wxs_quicklink_short" target="_self" title="Wykop X: Najbardziej gorące wpisy z ostatnich 2 godzin">2h</a>
  5234. <a href="/mikroblog/gorace/6" class="wxs_quicklink_short" target="_self" title="Wykop X: Najbardziej gorące wpisy z ostatnich 6 godzin">6h</a>
  5235. <a href="/mikroblog/gorace/12" class="wxs_quicklink_short" target="_self" title="Wykop X: Najbardziej gorące wpisy z ostatnich 12 godzin">12h</a>
  5236. <a href="/mikroblog/gorace/24" class="wxs_quicklink_short" target="_self" title="Wykop X: Najbardziej gorące wpisy z ostatnich 24 godzin">24h</a>
  5237. </div>
  5238. </section>
  5239.  
  5240. <section>
  5241. <span>
  5242. Moje Mirko
  5243. </span>
  5244. <div>
  5245. <a href="/ludzie/${loggedUser.username}/wpisy/dodane" target="_self">Moje wpisy</a>
  5246. <a href="/ludzie/${loggedUser.username}/wpisy/komentowane" target="_self">Komentowane</a>
  5247. <a href="/ludzie/${loggedUser.username}/wpisy/plusowane" target="_self">Zaplusowane</a>
  5248. </div>
  5249. </section>
  5250.  
  5251. <section>
  5252. <span>Ulubione</span>
  5253. <div>
  5254. <a href="/ulubione/wpisy" target="_self">Wpisy</a>
  5255. <a href="/ulubione/komentarze-wpisy" target="_self">Komentarze do wpisów</a>
  5256. </div>
  5257. </section>
  5258. </nav>
  5259.  
  5260. <nav class="mywykop">
  5261. <section>
  5262. <span>Mój Wykop</span>
  5263. <div>
  5264. <a href="/obserwowane/" target="_self">Wszystko</a>
  5265. <a href="/obserwowane/tagi" target="_self">#Tagi</a>
  5266. <a href="/obserwowane/profile" target="_self">@Profile</a>
  5267. </div>
  5268. </section>
  5269.  
  5270. <section>
  5271. <span>Moja aktywność</span>
  5272. <span>Mikroblog</span>
  5273. <div>
  5274. <a href="/ludzie/${loggedUser.username}/wpisy/dodane" target="_self">Moje wpisy</a>
  5275. <a href="/ludzie/${loggedUser.username}/wpisy/komentowane" target="_self">Moje komentarze</a>
  5276. <a href="/ludzie/${loggedUser.username}/wpisy/plusowane" target="_self">Moje plusy</a>
  5277. </div>
  5278. </section>
  5279. <section>
  5280. <span>Znaleziska</span>
  5281. <div>
  5282. <a href="/ludzie/${loggedUser.username}/znaleziska/dodane" target="_self">Moje znaleziska</a>
  5283. <a href="/ludzie/${loggedUser.username}/znaleziska/komentowane" target="_self">Moje komentarze</a>
  5284. <a href="/ludzie/${loggedUser.username}/znaleziska/wykopane" target="_self">Wykopane</a>
  5285. <a href="/ludzie/${loggedUser.username}/znaleziska/zakopane" target="_self">Zakopane</a>
  5286. </div>
  5287. </section>
  5288. </nav>
  5289.  
  5290. <nav class="favorites">
  5291. <section>
  5292. <span>Ulubione</span>
  5293. <div>
  5294. <a href="/ulubione" target="_self">Wszystko</a>
  5295. <a href="/ulubione/znaleziska" target="_self">Znaleziska</a>
  5296. <a href="/ulubione/komentarze-znaleziska" target="_self">Komentarze do znalezisk</a>
  5297. <a href="/ulubione/wpisy" target="_self">Wpisy</a>
  5298. <a href="/ulubione/komentarze-wpisy" target="_self">Komentarze do wpisów</a>
  5299. </div>
  5300. </section>
  5301. </nav>
  5302.  
  5303. <nav class="profile_links">
  5304. <section>
  5305. <span>Mój profil</span>
  5306. <div>
  5307. <a href="/ludzie/${loggedUser.username}" target="_self">Profil</a>
  5308. <a href="/ludzie/${loggedUser.username}/znaleziska/dodane" target="_self">Dodane znaleziska</a>
  5309. <a href="/ludzie/${loggedUser.username}/znaleziska/komentowane" target="_self">Komentowane znaleziska</a>
  5310. <a href="/ludzie/${loggedUser.username}/znaleziska/wykopane" target="_self">Wykopane</a>
  5311. <a href="/ludzie/${loggedUser.username}/znaleziska/zakopane" target="_self">Zakopane</a>
  5312. </div>
  5313. </section>
  5314. </nav>
  5315.  
  5316. <nav class="profile_entries">
  5317. <section>
  5318. <span>Mój profil</span>
  5319. <div>
  5320. <a href="/ludzie/${loggedUser.username}/wpisy/dodane" target="_self">Dodane wpisy</a>
  5321. <a href="/ludzie/${loggedUser.username}/wpisy/komentowane" target="_self">Komentowane wpisy</a>
  5322. <a href="/ludzie/${loggedUser.username}/wpisy/plusowane" target="_self">Zaplusowane</a>
  5323. </div>
  5324. </section>
  5325. </nav>
  5326.  
  5327. <nav class="profile_observed">
  5328. <section>
  5329. <span>Mój profil</span>
  5330. <div>
  5331. <a href="/ludzie/${loggedUser.username}/obserwowane/profile" target="_self">Obserwowani @użytkownicy</a>
  5332. <a href="/ludzie/${loggedUser.username}/obserwowane/tagi" target="_self">Obserwowane #tagi</a>
  5333. </div>
  5334. </section>
  5335. </nav>
  5336.  
  5337. <nav class="add_new">
  5338. <section>
  5339. <span>Dodaj</span>
  5340. <div>
  5341. <a href="/dodaj-link" target="_self" title="Wykop X: Dodaj nowe znalezisko (link do strony internetowej)">Nowe znalezisko</a>
  5342. <a href="/mikroblog/#dodaj" target="_self" title="Wykop X: Dodaj nowy wpis na Mikroblogu">Nowy wpis na Mirko</a>
  5343. </div>
  5344. </section>
  5345. </nav>
  5346.  
  5347. `;
  5348. document.querySelector('body > section > header.header > div.left').appendChild(wxs_quick_links);
  5349. }
  5350. }
  5351.  
  5352. }
  5353.  
  5354.  
  5355.  
  5356. // options: { position: "left", "right", "center",
  5357. // text: ``, title: ``, : ``, id: null, url: null,
  5358. // target: "_blank", icon: null, number: null,
  5359. // insertAfter: selectorQuery, showWithoutXStyle: true
  5360. // data: "data-v-5182b5f6" // data-v-5182b5f6
  5361. // number-nieuzwane
  5362. function createNewNavBarButton(options)
  5363. {
  5364. consoleX(`createNewNavBarButton()`, 1)
  5365.  
  5366. let nav_ul;
  5367.  
  5368. if (options.position == "left") nav_ul = document.querySelector("body header div.left nav.main ul");
  5369. else if (options.position == "center") nav_ul = document.querySelector("body header div.right nav aside"); // doodle
  5370. /*<aside title="Komentuj ważne wydarzenia" class="doodle">
  5371. <div class="v-portal"></div>
  5372. <a href="/tag/sejm/wpisy">
  5373. <div class="vue-portal-target">
  5374. <img src="/static/img/svg/doodles/gov.svg" alt="">
  5375. Komentuj ważne wydarzenia
  5376. </div>
  5377. </a>
  5378. </aside>*/
  5379. else nav_ul = document.querySelector("body header div.right nav ul"); // brak na wersji mobilnej
  5380.  
  5381. if (nav_ul)
  5382. {
  5383. let nav_ul_li = nav_ul.querySelector(`li.wykopx_${options.class}_li`);
  5384.  
  5385. if (!nav_ul_li)
  5386. {
  5387. nav_ul_li = document.createElement("li");
  5388. if (options.data) nav_ul_li.setAttribute(options.data, null);
  5389. if (options.hideWithoutXStyle == true) nav_ul_li.classList.add("wykopxs");
  5390. addWykopXSClassesToElement(nav_ul_li, options.class, "li") // class="wykopx_aaaaaa_li"
  5391.  
  5392. let nav_ul_li_a = document.createElement("a");
  5393.  
  5394. nav_ul_li.dataset["v-6c2d0fdd"] = "";
  5395. nav_ul_li_a.dataset["v-6c2d0fdd"] = "";
  5396.  
  5397. if (options.url) nav_ul_li_a.setAttribute("href", options.url);
  5398. if (options.href) nav_ul_li_a.setAttribute("href", options.href);
  5399. if (options.target) nav_ul_li_a.setAttribute("target", options.target);
  5400. if (options.title) nav_ul_li_a.setAttribute("title", options.title);
  5401. if (options.data) nav_ul_li_a.setAttribute(options.data, null);
  5402.  
  5403. nav_ul_li_a.classList.add("hybrid");
  5404. if (options.class) addWykopXSClassesToElement(nav_ul_li_a, options.class);
  5405.  
  5406.  
  5407. let nav_ul_li_a_span = document.createElement("span");
  5408. nav_ul_li_a_span.innerHTML = options.text;
  5409.  
  5410. nav_ul_li_a.appendChild(nav_ul_li_a_span);
  5411. nav_ul_li.appendChild(nav_ul_li_a);
  5412.  
  5413. if (options.insertAfter != null)
  5414. {
  5415. let section = nav_ul.querySelector(options.insertAfter);
  5416. section.insertAdjacentElement('afterend', nav_ul_li);
  5417. }
  5418. else
  5419. {
  5420. nav_ul.appendChild(nav_ul_li);
  5421. }
  5422. }
  5423. }
  5424. }
  5425.  
  5426.  
  5427.  
  5428.  
  5429. // returnWykopXSClassesString("klasa", "li") >> class="wykopx_klasa_li"
  5430. // returnWykopXSClassesString(["klasa1", "klasa2"]) class="wykopx_klasa1 wykopx_klasa2"
  5431. function addWykopXSClassesToElement(element, inputClassOrArray, suffix = null)
  5432. {
  5433. consoleX("addWykopXSClassesToElement()", 1)
  5434.  
  5435. if (inputClassOrArray)
  5436. {
  5437. if (typeof inputClassOrArray === 'string')
  5438. {
  5439. element.classList.add(`wykopx_${inputClassOrArray}${suffix != null ? "_" + suffix : ""}`);
  5440. }
  5441. else if (Array.isArray(inputClassOrArray) && inputClassOrArray.every(item => typeof item === 'string'))
  5442. {
  5443. inputClassOrArray.map(item =>
  5444. {
  5445. element.classList.add(`wykopx_${item}${suffix != null ? "_" + suffix : ""}`);
  5446. });
  5447. }
  5448. }
  5449. }
  5450.  
  5451. // options: { text: null, title: null, className: ``, id: null, url: null, target: "_blank", icon: null, number: null
  5452. function createProfileDropdownMenuItem(options)
  5453. {
  5454. consoleX(`createProfileDropdownMenuItem()`, 1)
  5455.  
  5456. let dropdownBody = document.querySelector("body header div.right nav ul li.account.dropdown ul.dropdown-body");
  5457.  
  5458. if (dropdownBody)
  5459. {
  5460. let dropdownItem = dropdownBody.querySelector(`li.${options.className}_li`);
  5461.  
  5462. if (!dropdownItem)
  5463. {
  5464. // dropdownItem.remove();
  5465. let clonedDropdownItem = dropdownBody.querySelector("li.settings").cloneNode(true);
  5466. if (options.className)
  5467. {
  5468. clonedDropdownItem.setAttribute("class", `${options.className}_li`);
  5469.  
  5470. let clonedDropdownItemLink = clonedDropdownItem.querySelector("a");
  5471. clonedDropdownItemLink.setAttribute("class", `${options.className}_button`);
  5472.  
  5473. if (options.url) clonedDropdownItemLink.setAttribute("href", options.url);
  5474. else if (options.href) clonedDropdownItemLink.setAttribute("href", options.href);
  5475. else clonedDropdownItemLink.removeAttribute("href");
  5476.  
  5477. if (options.target) clonedDropdownItemLink.setAttribute("target", options.target);
  5478. if (options.id) clonedDropdownItemLink.setAttribute("id", options.id);
  5479. if (options.title) clonedDropdownItemLink.setAttribute("title", options.title);
  5480. if (options.text) clonedDropdownItemLink.textContent = options.text;
  5481. dropdownBody.appendChild(clonedDropdownItem);
  5482. }
  5483. }
  5484. }
  5485. else // niezalogowany brak menu, zamiast tego przyciski Zaloguj/Zarejestruj
  5486. {
  5487. createNewNavBarButton({
  5488. position: "left",
  5489. text: options.text,
  5490. title: options.title,
  5491. class: options.className,
  5492. hideWithoutXStyle: options.hideWithoutXStyle,
  5493. url: options.url,
  5494. target: options.target,
  5495. icon: options.icon,
  5496. number: options.number
  5497. })
  5498. }
  5499. }
  5500.  
  5501.  
  5502. // wyswietla sie tylko 25 powiadomien, wiec powinno byc 25+
  5503. function addNotificationSummaryButtonToNavBar()
  5504. {
  5505. consoleX("addNotificationSummaryButtonToNavBar()", 1)
  5506.  
  5507. let mojeLubTagi = document.querySelector('header .right ul li.account.dropdown ul.dropdown-body li.notifications.new a')?.getAttribute('href');
  5508.  
  5509. let wykopx_notification_summary_url = "/powiadomienia/";
  5510. if (typeof mojeLubTagi == "string")
  5511. {
  5512. mojeLubTagi = mojeLubTagi.split("/").pop();
  5513.  
  5514. if (mojeLubTagi == "tagi")
  5515. {
  5516. createProfileDropdownMenuItem(
  5517. {
  5518. text: `Powiadomienia z #tagów`,
  5519. title: "Masz nowe powiadomienia z obserwowanych #tagów",
  5520. className: `wykopx_notifications_tags`,
  5521. id: undefined,
  5522. url: "/powiadomienia/tagi",
  5523. target: "_self",
  5524. icon: null,
  5525. number: null
  5526. })
  5527. }
  5528. if (mojeLubTagi == "moje")
  5529. {
  5530. createProfileDropdownMenuItem(
  5531. {
  5532. text: `Powiadomienia z #tagów`,
  5533. title: "Masz nowe powiadomienia z obserwowanych #tagów",
  5534. className: `wykopx_notifications_tags`,
  5535. id: undefined,
  5536. url: "/powiadomienia/tagi",
  5537. target: "_self",
  5538. icon: null,
  5539. number: null
  5540. })
  5541. createProfileDropdownMenuItem(
  5542. {
  5543. text: `Zawołania w komentarzach`,
  5544. title: "Zawołano Cię w komentarzu",
  5545. className: `wykopx_notifications_entries`,
  5546. id: undefined,
  5547. url: "/powiadomienia/moje",
  5548. target: "_self",
  5549. icon: null,
  5550. number: null
  5551. })
  5552. }
  5553. wykopx_notification_summary_url += mojeLubTagi;
  5554. }
  5555.  
  5556. let li = document.createElement("li");
  5557. li.setAttribute("class", "wykopxs wykopx_notification_summary notifications dropdown");
  5558. li.setAttribute("title", `Nowe powiadomienia ${promoString}`);
  5559. let a = document.createElement("a");
  5560. a.setAttribute("href", wykopx_notification_summary_url);
  5561. let figure = document.createElement("figure");
  5562. a.appendChild(figure);
  5563. li.appendChild(a);
  5564. topNavHeaderRightElement.insertAdjacentElement("afterbegin", li);
  5565. }
  5566.  
  5567.  
  5568.  
  5569.  
  5570.  
  5571. // TRYB NOCNY W BELCE NAWIGACYJNEJ
  5572. function addNightModeButtonToNavBar()
  5573. {
  5574. if (settings.topNavNightSwitchButton)
  5575. {
  5576. consoleX("addNightModeButtonToNavBar()", 1)
  5577.  
  5578. const wykopx_night_mode = `<li class="wykopxs wykopx_night_mode notifications dropdown" title="Przełącz pomiędzy trybem nocnym/dziennym ${promoString}"><a href="#"><figure></figure></a></li>`;
  5579. topNavHeaderRightElement.insertAdjacentHTML('afterbegin', wykopx_night_mode);
  5580.  
  5581. document.querySelector('.wykopx_night_mode').addEventListener('click', function ()
  5582. {
  5583. const currentMode = localStorage.getItem('nightMode');
  5584. if (currentMode === null || currentMode === '0')
  5585. {
  5586. body.setAttribute('data-night-mode', 'true');
  5587. localStorage.setItem('nightMode', 1);
  5588. if (mikroczatWindow && mikroczatDomain) mikroczatWindow.postMessage({ type: "nightMode", value: 1 }, mikroczatDomain);
  5589. }
  5590. else
  5591. {
  5592. body.removeAttribute('data-night-mode');
  5593. localStorage.setItem('nightMode', 0);
  5594. if (mikroczatWindow && mikroczatDomain) mikroczatWindow.postMessage({ type: "nightMode", value: 0 }, mikroczatDomain);
  5595. }
  5596. });
  5597. }
  5598. }
  5599.  
  5600.  
  5601.  
  5602.  
  5603.  
  5604.  
  5605. function addExtraButtons()
  5606. {
  5607. consoleX("addExtraButtons()", 1)
  5608.  
  5609. /* Przyciski dodawane tylko na górną belkę nawigacyjną */
  5610. const wykopx_wykopwnowymstylu_li = `<li class="wykopx_wykopwnowymstylu_li dropdown"><a href="/tag/wykopx" class="wykopx_wykopwnowymstylu_button" title="Przejdź na #wykopx"><span>#</span></a></li>`;
  5611. const wykopx_microblog_mobile_li = `<li class="wykopx_microblog_mobile_li dropdown"><a href="/mikroblog" class="wykopx_microblog_mobile_button" title="Mikroblog ${promoString}"><figure> </figure></a></li>`;
  5612. /* Te przyciski także na belce mobilnej */
  5613. const wykopx_mywykop_mobile_li = `<li data-v-1adb6cc8 class="wykopx_mywykop_mobile_li dropdown"><a data-v-1adb6cc8 href="/obserwowane" class="wykopx_mywykop_mobile_button" title="Mój Wykop ${promoString}"><span data-v-1adb6cc8><i data-v-1adb6cc8>Mój Wykop</i></span></a></li>`;
  5614. const wykopx_profile_mobile_li = `<li data-v-1adb6cc8 class="wykopx_profile_mobile_li dropdown ${loggedUser.username}"><a data-v-1adb6cc8 href="/ludzie/${loggedUser.username}" class="wykopx wykopx_profile_button" title="Przejdź na swój profil ${loggedUser.username} ${promoString}"><span data-v-1adb6cc8><i data-v-1adb6cc8>Profil</i></span></a></li>`;
  5615. const wykopx_messages_mobile_li = `<li data-v-1adb6cc8 class="wykopx_messages_mobile_li dropdown"><a data-v-1adb6cc8 href="/wiadomosci" class="wykopx wykopx_messages_button" title="Wiadomości ${promoString}"><span data-v-1adb6cc8><i data-v-1adb6cc8>Wiadomości</i></span></a></li>`;
  5616. const wykopx_notifications_mobile_li = `<li data-v-1adb6cc8 class="wykopx_notifications_mobile_li dropdown"><a data-v-1adb6cc8 href="/powiadomienia" class="wykopx wykopx_notifications_button" title="Powiadomienia ${promoString}"><span data-v-1adb6cc8><i data-v-1adb6cc8>Powiadomienia</i></span></a></li>`;
  5617.  
  5618. if (topNavHeaderRightElement)
  5619. {
  5620. topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_wykopwnowymstylu_li);
  5621.  
  5622. if (settings.topNavMicroblogButton) topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_microblog_mobile_li);
  5623.  
  5624. if (loggedUser !== null)
  5625. {
  5626. if (settings.topNavMyWykopButton) topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_mywykop_mobile_li);
  5627. if (settings.topNavMessagesButton) topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_messages_mobile_li);
  5628. if (settings.topNavNotificationsButton) topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_notifications_mobile_li);
  5629. if (settings.topNavProfileButton) topNavHeaderRightElement.insertAdjacentHTML('beforeend', wykopx_profile_mobile_li);
  5630. }
  5631. }
  5632.  
  5633. /* dolna belka mobilna */
  5634. if (settings.mobileNavBarHide == false)
  5635. {
  5636. const mobileNavbarUlElement = document.querySelector('body > section > nav.mobile-navbar > ul')
  5637. if (mobileNavbarUlElement)
  5638. {
  5639. if (loggedUser !== null)
  5640. {
  5641. if (settings.mobileNavBarMyWykopButton) mobileNavbarUlElement.insertAdjacentHTML('beforeend', wykopx_mywykop_mobile_li);
  5642. if (settings.mobileNavBarNotificationsButton) mobileNavbarUlElement.insertAdjacentHTML('beforeend', wykopx_notifications_mobile_li);
  5643. if (settings.mobileNavBarMessagesButton) mobileNavbarUlElement.insertAdjacentHTML('beforeend', wykopx_messages_mobile_li);
  5644. if (settings.mobileNavBarProfileButton) mobileNavbarUlElement.insertAdjacentHTML('beforeend', wykopx_profile_mobile_li);
  5645. }
  5646. }
  5647. }
  5648. }
  5649.  
  5650. CSS += `
  5651. /* ikona extra MW Mój Wykop w panelu powiadomień */
  5652.  
  5653. header.header > .right > nav > ul > li
  5654. {
  5655. display: flex!important;
  5656. height: 100%!important;
  5657. justify-content: center;
  5658. align-items: center;
  5659. }
  5660.  
  5661. ul > li.wykopx_microblog_mobile_li > a > figure,
  5662.  
  5663. ul > li.wykopx_mywykop_mobile_li > a > span,
  5664. ul > li.wykopx_profile_mobile_li > a > span,
  5665. ul > li.wykopx_notifications_mobile_li > a > span,
  5666. ul > li.wykopx_messages_mobile_li > a > span
  5667. {
  5668. display: flex!important;
  5669. background-repeat: no-repeat;
  5670. background-position: 0 10px;
  5671. width: 20px;
  5672. height: 100%;
  5673. }
  5674. ul > li.wykopx_microblog_mobile_li > a > figure
  5675. {
  5676. background-image: url('https://i.imgur.com/F8BqeCx.png');
  5677. }
  5678. /* mój wykop */
  5679. ul > li.wykopx_mywykop_mobile_li > a > span
  5680. {
  5681. background-image: url('https://i.imgur.com/4oQuftz.png'); /* 20p */
  5682. background-image: url('https://i.imgur.com/qtGPe78.png'); /* 20p */
  5683. /*background-image: url('https://i.imgur.com/GoTmF0m.png');
  5684. background-image: url('https://i.imgur.com/7DArcw6.png'); */
  5685. }
  5686. [data-night-mode] ul > li.wykopx_mywykop_mobile_li > a > span
  5687. {
  5688. background-image: url('https://i.imgur.com/qtGPe78.png');
  5689. }
  5690. /* profile */
  5691. ul > li.wykopx_profile_mobile_li > a > span
  5692. {
  5693. background-image: url('https://i.imgur.com/XD7q4hY.png'); /* black*/
  5694. background-image: url('https://i.imgur.com/EpytPvb.png'); /* white*/
  5695. }
  5696. [data-night-mode] ul > li.wykopx_profile_mobile_li > a > span
  5697. {
  5698. background-image: url('https://i.imgur.com/EpytPvb.png');
  5699. }
  5700. /* wiadomosci */
  5701. ul > li.wykopx_messages_mobile_li > a > span
  5702. {
  5703. background-image: url('https://i.imgur.com/Yx1ZAYt.png'); /* black*/
  5704. background-image: url('https://i.imgur.com/dE4f85B.png'); /* white*/
  5705. }
  5706. [data-night-mode] ul > li.wykopx_messages_mobile_li > a > figure
  5707. {
  5708. background-image: url('https://i.imgur.com/dE4f85B.png');
  5709. }
  5710.  
  5711. /* powiadomienia */
  5712. ul > li.wykopx_notifications_mobile_li > a > span
  5713. {
  5714. background-image: url('https://i.imgur.com/UpYMDtr.png');
  5715. }
  5716. header.header > .right > nav > ul > li > a > span > i
  5717. {
  5718. display: none;
  5719. }
  5720.  
  5721.  
  5722. /* wykopwnowymstylu */
  5723. header.header > .right > nav > ul > li.wykopx_wykopwnowymstylu_li > a > span
  5724. {
  5725. font-size: 1.2em;
  5726. color: var(--x-inactive-button, rgba(255,255,255,0.3));
  5727. }
  5728. header.header > .right > nav > ul > li.wykopx_wykopwnowymstylu_li > a:hover > span
  5729. {
  5730. color: white;
  5731. }
  5732.  
  5733. header.header > .right > nav > ul > li.wykopx_wykopwnowymstylu_li
  5734. {
  5735. display: none!important;
  5736. }`;
  5737.  
  5738. if (settings.topNavNightSwitchButton)
  5739. {
  5740. CSS += `
  5741. /* PRZYCISK TRYB NOCNY W BELCE NAWIGACYJNEJ */
  5742.  
  5743. header.header > .right > nav > ul > li.wykopx_night_mode figure
  5744. {
  5745. width: 20px!important;
  5746. height: 20px!important;
  5747. background: url("/static/img/svg/night-mode.svg") no-repeat center;
  5748. }
  5749.  
  5750. [data-night-mode] header.header > .right > nav > ul > li.wykopx_night_mode figure
  5751. {
  5752. background: url("/static/img/svg/day-mode.svg") no-repeat center;
  5753. }
  5754. `;
  5755. }
  5756.  
  5757.  
  5758.  
  5759. // DODAJ NOWY WPIS NA MIRKO /mikroblog/#dodaj
  5760. function focusOnAddingNewMicroblogEntry()
  5761. {
  5762. consoleX(`focusOnAddingNewMicroblogEntry()`, 1)
  5763. let wykop_url = new URL(document.URL);
  5764. if (wykop_url.hash == "#dodaj")
  5765. {
  5766. // consoleX(`focusOnAddingNewMicroblogEntry()`, 1);
  5767. document.querySelector(`section.microblog-page section.microblog section.editor div.content textarea`).focus();
  5768. }
  5769. }
  5770.  
  5771.  
  5772.  
  5773.  
  5774.  
  5775.  
  5776.  
  5777. /* ------ TAB TITLE AND WEBSITE FAVICON CHANGES --------- */
  5778. let pageTabTitleOriginal = document.title;
  5779. let pageTabTitleProcessed = pageTabTitleOriginal;
  5780. let tabTitles = new Map([
  5781. ["domyslny", " "],
  5782. ["adres_url", " "],
  5783. ["pusty_tytul", "ᅟᅟ"],
  5784. ["wlasny", settings.tabChangeTitleCustom],
  5785. ["wykop", "Wykop"],
  5786. ["wykopx", "Wykop X"],
  5787. ["digg", "News and Trending Stories Around the Internet | Digg"],
  5788. ["google", "Google"],
  5789. ["interia", "Interia — Polska i świat: informacje, sport, gwiazdy."],
  5790. ["onet", "Onet – Jesteś na bieżąco"],
  5791. ["reddit", "Reddit — Dive into anything"],
  5792. ["wp", "Wirtualna Polska — Wszystko co ważne"],
  5793. ["x", "Home / X"],
  5794. ["youtube", "YouTube"],
  5795. ])
  5796.  
  5797. const defaultWykopFaviconURL = "https://wykop.pl/static/img/favicons/favicon.png";
  5798. let tabFaviconsMap = new Map([
  5799. ["wykop", defaultWykopFaviconURL],
  5800. ["wykop_white", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/W_white.png"],
  5801. ["wykop_gray", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/W_black.png"],
  5802.  
  5803. ["digg", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/digg.png"],
  5804. ["google", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/google.svg"],
  5805. ["interia", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/interia.ico"],
  5806. ["onet", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/onet.png"],
  5807. ["reddit", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/reddit.png"],
  5808. ["wp", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/wp.png"],
  5809. ["x", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/x.png"],
  5810. ["youtube", "https://raw.githubusercontent.com/wykopx/wykopx-png/main/icons/favicons/youtube.ico"],
  5811. ])
  5812. let tabSuffixesMap = new Map([
  5813. ["domyslny", ":: Wykop.pl"],
  5814. ["dashwykoppl", "- Wykop.pl"],
  5815. ["dashwykop", "- Wykop"],
  5816. ["dashwykopx", "- Wykop X"],
  5817. ["", ""],
  5818. ])
  5819.  
  5820.  
  5821. /* TAB TITLE
  5822. changeDocumentTitle()
  5823. changeDocumentTitle("youtube")
  5824. changeDocumentTitle("Example new title")
  5825. */
  5826.  
  5827.  
  5828. function changeDocumentTitle(new_document_title)
  5829. {
  5830. consoleX(`changeDocumentTitle(${new_document_title})`, 1)
  5831.  
  5832. // if(dev) console.log(`changeDocumentTitle() > start: document.title:`);
  5833. // if(dev) console.log(document.title);
  5834. // if(dev) console.log(`changeDocumentTitle() > start: pageTabTitleOriginal`);
  5835. // if(dev) console.log(pageTabTitleOriginal);
  5836.  
  5837. pageTabTitleProcessed = pageTabTitleOriginal;
  5838.  
  5839. // sufix :: Wykop.pl
  5840. if (settings.tabChangeTitleSuffix) pageTabTitleProcessed = pageTabTitleProcessed.replace(":: Wykop.pl", tabSuffixesMap.get(settings.tabChangeTitleSuffix));
  5841. // prefix
  5842. if (settings.tabChangeTitlePrefix) pageTabTitleProcessed = `Wykop X - ${pageTabTitleProcessed}`;
  5843.  
  5844.  
  5845.  
  5846.  
  5847. let tabTitleNotifications = "";
  5848.  
  5849. if (settings.tabChangeTitleShowNotificationsEnabled == true)
  5850. {
  5851. let notificationsTotalCount = 0;
  5852.  
  5853. let tabNotificationsSeparated = "";
  5854.  
  5855. if (unreadNotifications["total"] > 0)
  5856. {
  5857. if (settings.tabChangeTitleShowNotificationsCountPM && unreadNotifications["pm"] > 0
  5858. || settings.tabChangeTitleShowNotificationsCountTagsNewLink && unreadNotifications["tags_new_link_with_observed_tag"] > 0
  5859. || settings.tabChangeTitleShowNotificationsCountTagsNewEntry && unreadNotifications["tags_new_entry_with_observed_tag"] > 0
  5860. || settings.tabChangeTitleShowNotificationsCountEntries && unreadNotifications["entries"] > 0)
  5861. {
  5862. let notificationsEmoji = "";
  5863.  
  5864. if (settings.tabChangeTitleShowNotificationsCountPM && unreadNotifications["pm"] > 0)
  5865. {
  5866. notificationsTotalCount += unreadNotifications["pm"];
  5867. notificationsEmoji = "✉"; // 🔗✉📧📩✉ 🖂 🖃 🖄 🖅 🖆
  5868. tabNotificationsSeparated += `${notificationsEmoji}${unreadNotifications["pm"]} `;
  5869. }
  5870.  
  5871. if (settings.tabChangeTitleShowNotificationsCountEntries && unreadNotifications["entries"] > 0)
  5872. {
  5873. notificationsTotalCount += unreadNotifications["entries"];
  5874. notificationsEmoji = "🕭"; // 🕭🔔
  5875. tabNotificationsSeparated += `${notificationsEmoji}${unreadNotifications["entries"]} `;
  5876. }
  5877.  
  5878. if (unreadNotifications["tags"] && settings.tabChangeTitleShowNotificationsCountTagsNewLink || settings.tabChangeTitleShowNotificationsCountTagsNewEntry)
  5879. {
  5880. notificationsEmoji = "#"; // #🏷
  5881. if (settings.tabChangeTitleShowNotificationsCountTagsNewLink && unreadNotifications["tags_new_link_with_observed_tag"] > 0)
  5882. {
  5883. notificationsTotalCount += unreadNotifications["tags_new_link_with_observed_tag"];
  5884. }
  5885. if (settings.tabChangeTitleShowNotificationsCountTagsNewEntry && unreadNotifications["tags_new_entry_with_observed_tag"] > 0)
  5886. {
  5887. notificationsTotalCount += unreadNotifications["tags_new_entry_with_observed_tag"];
  5888. }
  5889. tabNotificationsSeparated += `${notificationsEmoji}${unreadNotifications["tags"]} `;
  5890. }
  5891.  
  5892. if (settings.tabChangeTitleShowNotificationsCountSeparated)
  5893. {
  5894. tabTitleNotifications = tabNotificationsSeparated; // 📧 2 🔔 3 # 14
  5895. }
  5896. else
  5897. {
  5898. tabTitleNotifications = notificationsTotalCount; // 19
  5899. }
  5900.  
  5901. if (new_document_title == "pusty_tytul") // jesli pusty tytul — ikonki powiadomien bez nawiasow
  5902. {
  5903. tabTitleNotifications = `${tabTitleNotifications} ` // 📧 2 🔔 3 # 14 albo 19
  5904. }
  5905. else
  5906. {
  5907. tabTitleNotifications = `${tabTitleNotifications} | ` // 📧 2 🔔 3 # 14 | albo 19 |
  5908. }
  5909. }
  5910. }
  5911.  
  5912. }
  5913.  
  5914. let documentTitle = tabTitleNotifications;
  5915.  
  5916. if (new_document_title != "domyslny")
  5917. {
  5918. if (tabTitles.has(new_document_title)) // selected title from Map
  5919. {
  5920. documentTitle += `${tabTitles.get(new_document_title)}`;
  5921. }
  5922. else
  5923. {
  5924. documentTitle += `${new_document_title}`;
  5925. }
  5926. }
  5927. else
  5928. {
  5929. documentTitle += pageTabTitleProcessed;
  5930. }
  5931. document.title = documentTitle;
  5932. // if(dev) console.log("changeDocumentTitle() > zmieniam document.title na: " + documentTitle);
  5933. }
  5934.  
  5935.  
  5936. // FAVICON ICO
  5937. function changeDocumentFavicon(new_favicon = defaultWykopFaviconURL)
  5938. {
  5939. consoleX(`changeDocumentFavicon(new_favicon: "${new_favicon}")`, 1)
  5940. let selectedFaviconURL = new_favicon;
  5941. if (tabFaviconsMap.has(new_favicon)) selectedFaviconURL = tabFaviconsMap.get(new_favicon);
  5942.  
  5943. // <link rel="icon" type="image/svg+xml" href="/static/img/favicons/favicon.svg">
  5944. // <link rel="alternate icon" type="image/png" href="/static/img/favicons/favicon.png">
  5945. const oldFaviconElement = head.querySelector('link[rel="icon"]');
  5946.  
  5947. if (oldFaviconElement && !oldFaviconElement.href.startsWith(selectedFaviconURL))
  5948. {
  5949. head.removeChild(oldFaviconElement);
  5950. const faviconLinkElement = document.createElement('link');
  5951. faviconLinkElement.rel = 'icon';
  5952. faviconLinkElement.type = 'image/x-icon'; // "image/svg+xml" "image/png"
  5953. faviconLinkElement.href = selectedFaviconURL + '?=' + Math.random();
  5954. head.appendChild(faviconLinkElement);
  5955. }
  5956.  
  5957. const alternateFaviconElement = head.querySelector('link[rel="alternate icon"]');
  5958. if (alternateFaviconElement)
  5959. {
  5960. head.removeChild(alternateFaviconElement);
  5961. }
  5962. }
  5963.  
  5964.  
  5965.  
  5966. function executeTabAndFaviconChanges()
  5967. {
  5968. consoleX(`executeTabAndFaviconChanges()`, 1);
  5969.  
  5970. if (document.hidden || !settings.tabChangeOnlyOnHiddenState)
  5971. {
  5972. if (settings.tabChangeFaviconEnabled) changeDocumentFavicon(settings.tabChangeFaviconSelect);
  5973. if (settings.tabChangeTitleEnabled) changeDocumentTitle(settings.tabChangeTitleSelect);
  5974. }
  5975. }
  5976.  
  5977.  
  5978.  
  5979. // EVENT: KARTA JEST W TLE document.hidden == true
  5980. // https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API
  5981. // https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event
  5982. function browserTabVisibilityChanged()
  5983. {
  5984. consoleX(`browserTabVisibilityChanged() -> ${document.visibilityState}`, 1);
  5985.  
  5986. // if(dev) console.log("browserTabVisibilityChanged(): " + document.visibilityState)
  5987. // document.visibilityState > "visible"/"hidden"
  5988. // document.hidden > true/false
  5989. if (document.hidden == false)
  5990. {
  5991. if (settings.wxsArchiveXNewestEntry && (wxs_newest_entry == 1 || wxs_newest_entry == 3)) runWithDelay(3000, getNewestEntryFromAPI);
  5992. }
  5993.  
  5994. if (settings.tabChangeEnabled)
  5995. {
  5996. if (document.hidden)
  5997. {
  5998. executeTabAndFaviconChanges();
  5999. // if(dev) console.log(`document.hidden -> true > document.visibilityState: ${document.visibilityState}`);
  6000. }
  6001. else
  6002. {
  6003. if (settings.tabChangeOnlyOnHiddenState)
  6004. {
  6005. if (settings.tabChangeTitleEnabled) changeDocumentTitle(pageTabTitleOriginal);
  6006. if (settings.tabChangeFaviconEnabled) changeDocumentFavicon();
  6007. }
  6008. }
  6009. }
  6010.  
  6011. }
  6012. // EVENT LISTENER
  6013. document.addEventListener("visibilitychange", browserTabVisibilityChanged, false); // ICO PNG GIF JPEG SVG
  6014.  
  6015.  
  6016.  
  6017.  
  6018. // TITLE MUTATION
  6019. let titleMutationObserver = new MutationObserver(mutationsList =>
  6020. {
  6021. if (dev) console.log("titleMutationObserver ->")
  6022. if (dev) console.log(mutationsList);
  6023.  
  6024. for (let mutation of mutationsList)
  6025. {
  6026. if (mutation.type === 'childList')
  6027. {
  6028. let mutatedTitle = mutation.addedNodes[0].textContent;
  6029. consoleX(`titleMutationObserver -> Nowy tytuł strony: ${mutatedTitle}`, 1);
  6030.  
  6031. // if (mutatedTitle.endsWith(":: Wykop.pl"))
  6032. // {
  6033. // pageTabTitleOriginal = mutatedTitle;
  6034. // if(dev) console.log(`mutatedTitle.endsWith(":: Wykop.pl")`);
  6035. // }
  6036.  
  6037. // if (!mutatedTitle.includes(specialCharacter)) // tytul nie zostal jeszcze zmieniony i dodane są liczby powiadomien zeby sie nie powtarzalo (1)(1)
  6038. // {
  6039. // pageTabTitleProcessed = mutatedTitle;
  6040. // // if(dev) console.log(`!mutatedTitle.includes("specialCharacter")`);
  6041. // }
  6042.  
  6043. // titleMutationObserver.disconnect();
  6044. // executeTabAndFaviconChanges();
  6045. // titleMutationObserver.observe(document.querySelector('title'), { childList: true, })
  6046. // if(dev) console.log("pageTabTitleProcessed: " + pageTabTitleProcessed)
  6047. }
  6048. }
  6049. });
  6050. // MUTATION OBSERVER
  6051. titleMutationObserver.observe(document.querySelector('title'), { childList: true, })
  6052.  
  6053.  
  6054.  
  6055.  
  6056.  
  6057. // PLUSES OBSERVER
  6058. function getVotesObject(sectionObjectElement, ratingBoxSection)
  6059. {
  6060. consoleX(`getVotesObject()`, 1);
  6061.  
  6062. /* returns:
  6063. {
  6064. separated: false,
  6065. votesUp: 50,
  6066. votesUpPercent: 100,
  6067. votesDown: 5,
  6068. votesDownPercent: 0,
  6069. votesCount: 45,
  6070. votesAll: 55,
  6071. voted: 0
  6072. votesUpPrevious: 49
  6073. votesDownPrevious: 4,
  6074. plusesDelta: 1
  6075. minusesDelta: 1
  6076. commentsCount: 100, // liczba komentarzy dla znalezisk, wpisów i main-comments pod znaleziskami
  6077. commentsHot: true // dla gorących znalezisk
  6078. }
  6079. {
  6080. resource: "link"
  6081. sectionObjectElement: <DOMElement>,
  6082. ratingBox: <DOMElement>,
  6083. link: <DOMElement>,
  6084. id: 123456,
  6085. link_id: 123456,
  6086. }
  6087. {
  6088. resource: "entry"
  6089. sectionObjectElement: <DOMElement>,
  6090. ratingBox: <DOMElement>,
  6091. entry: <DOMElement>,
  6092. id: 123456,
  6093. entry_id: 123456,
  6094. }
  6095. or
  6096. {
  6097. resource: "entry_comment"
  6098. sectionObjectElement: <DOMElement>
  6099. ratingBox: <DOMElement>,
  6100. entry: <DOMElement>, // parent
  6101. comment: DOMElement,
  6102. id: 12345678,
  6103. entry_id: 123456, // parent
  6104. comment_id: 12345678,
  6105. }
  6106. or
  6107. {
  6108. resource: "link_subcomment"
  6109. sectionObjectElement: DOMElement
  6110. ratingBox: <DOMElement>,
  6111. entry: <DOMElement>,
  6112. id: 12345678,
  6113. entry_id: 123456,
  6114. link_id: 12345678,
  6115. comment_id: 12345678123
  6116. parent_id: 1234567 // znalezisko
  6117. parent_comment_id: 123456 // komentarz pod znaleziskiem
  6118. parent_element: <DOMElement>, // komentarz
  6119. fetchURL: 'https://wykop.pl/api/v3...'
  6120. }
  6121. ratingBoxSection.__vue__
  6122. {
  6123. voted: 0 // czy zaglosowane
  6124. down: 0
  6125. up: 278
  6126. value: 278
  6127. formattedValue: "278",
  6128. separated: false
  6129. id: 23456789
  6130. idParent: 1234567
  6131. linkId: 1234567
  6132. users: [{}, {}...],
  6133. type: "entryComment" / "???"
  6134. deleted: null
  6135. author: "NadiaFrance"
  6136. showBtn: true / false
  6137. }
  6138. */
  6139.  
  6140. let votesObject =
  6141. {
  6142. separated: false,
  6143.  
  6144. votesUp: 0,
  6145. votesDown: 0,
  6146. votesCount: 0,
  6147. votesAll: 0,
  6148. votesCount: 0,
  6149. votesAll: 0,
  6150. votesDownPercent: 0,
  6151. votesUpPercent: 100,
  6152. voted: 0,
  6153.  
  6154. commentsCount: 0,
  6155. commentsHot: false,
  6156. };
  6157.  
  6158.  
  6159. votesObject.sectionObjectElement = sectionObjectElement; // returns the section element above .rating-box
  6160. votesObject.ratingBoxSection = ratingBoxSection; // returns .rating-box section
  6161.  
  6162. //blocks.id = blocks.sectionObjectElement.__vue__.item.id;
  6163. votesObject.id = ratingBoxSection.__vue__.id;
  6164. votesObject.separated = ratingBoxSection.__vue__.separated;
  6165. votesObject.votesUp = ratingBoxSection.__vue__.up;
  6166.  
  6167. if (dev) console.log(votesObject.votesUp)
  6168. votesObject.votesDown = ratingBoxSection.__vue__.down;
  6169.  
  6170. votesObject.votesCount = votesObject.votesUp - votesObject.votesDown; // -10 (suma plusów i minusów nie dotyczy entry, entry_comment)
  6171. votesObject.votesAll = votesObject.votesUp + votesObject.votesDown; // 30 (łączna liczba głosów nie dotyczy entry, entry_comment)
  6172.  
  6173. votesObject.votesDownPercent = Math.ceil(votesObject.votesDown * 100 / votesObject.votesAll); // nie dotyczy entry, entry_comment
  6174. votesObject.votesUpPercent = Math.ceil(votesObject.votesUp * 100 / votesObject.votesAll); // nie dotyczy entry, entry_comment zawsze 100%
  6175.  
  6176. votesObject.voted = ratingBoxSection.__vue__.voted;
  6177.  
  6178.  
  6179. /*
  6180. block.commentsCount
  6181. __vue__.item.comments =
  6182. - znalezisko na stronie głównej i stronie znaleziska
  6183. comments = { count: 42, hot: false }
  6184. - na stronie mikrobloga i wpisie (na stronie Mikrobloga Array[2])
  6185. comments = { count: 142, items: Array[50] }
  6186. komentarze nie mają "comments"
  6187. */
  6188.  
  6189. if (votesObject?.sectionObjectElement?.__vue__?.item?.comments?.count) votesObject.commentsCount = votesObject.sectionObjectElement.__vue__.item.comments.count;
  6190. if (votesObject?.sectionObjectElement?.__vue__?.item?.comments?.hot) votesObject.commentsHot = votesObject.sectionObjectElement.__vue__.item.comments.hot;
  6191.  
  6192.  
  6193. if (votesObject.sectionObjectElement.__vue__.item.resource == "link") // znalezisko
  6194. {
  6195. votesObject.resource = "link";
  6196. votesObject.fetchURL = `https://wykop.pl/api/v3/links/${votesObject.id}`; // TODO
  6197.  
  6198. votesObject.link_id = votesObject.id;
  6199. votesObject.link = votesObject.sectionObjectElement; // parent = this
  6200. votesObject.parent_element = votesObject.sectionObjectElement; // parent = this
  6201. votesObject.parent_id = votesObject.id;
  6202. votesObject.sectionObjectElement.dataset.wxs_resource = "link";
  6203. }
  6204. else
  6205. {
  6206. if (votesObject.sectionObjectElement.__vue__.item.resource == "link_comment")
  6207. {
  6208. votesObject.comment_element = votesObject.sectionObjectElement;
  6209.  
  6210. if (votesObject.comment_element.__vue__.item.parent.resource == "link_comment") // subkomentarz
  6211. {
  6212. votesObject.resource = "link_subcomment";
  6213. votesObject.comment_element.dataset.wxs_resource = "link_subcomment";
  6214.  
  6215. votesObject.comment_id = votesObject.comment_element.__vue__.item.id;
  6216. votesObject.parent_id = votesObject.comment_element.__vue__.item.parent.link.id; // id znaleziska
  6217. votesObject.parent_comment_id = votesObject.comment_element.__vue__.item.parent.id; // id nadkomentarza
  6218. votesObject.parent_element = document.getElementById(`comment-${votesObject.parent_comment_id}`) // nadkomentarz
  6219. votesObject.fetchURL = `https://wykop.pl/api/v3/links/${votesObject.parent_id}/comments/${votesObject.parent_comment_id}/comments`; // TODO
  6220. }
  6221. else
  6222. {
  6223. votesObject.resource = "link_comment";
  6224. votesObject.comment_element.dataset.wxs_resource = "link_comment";
  6225. votesObject.comment_id = votesObject.comment_element.__vue__.item.id;
  6226. votesObject.parent_id = votesObject.comment_element.__vue__.item.parent.id;
  6227. votesObject.parent_element = document.getElementById(`link-${votesObject.parent_id}`) // section.link-block
  6228. votesObject.fetchURL = `https://wykop.pl/api/v3/links/${votesObject.parent_id}/comments/${votesObject.comment_id}`;
  6229.  
  6230. }
  6231. }
  6232. // KOMENTARZ POD WPISEM
  6233. else if (votesObject.sectionObjectElement.__vue__.item.resource == "entry_comment")
  6234. {
  6235. votesObject.comment_element = votesObject.sectionObjectElement;
  6236.  
  6237. if (votesObject.comment_element.parentNode)
  6238. {
  6239. votesObject.resource = "entry_comment"; // komentarz pod wpisem
  6240. votesObject.comment_element.dataset.wxs_resource = "entry_comment";
  6241. votesObject.parent_element = votesObject.comment_element.parentNode.closest('section.entry');
  6242. votesObject.parent_id = votesObject.parent_element.__vue__.item.id;
  6243. votesObject.comment_id = votesObject.comment_element.__vue__.item.id;
  6244. votesObject.fetchURL = `https://wykop.pl/api/v3/entries/${votesObject.parent_id}/comments/${votesObject.comment_id}`;
  6245. }
  6246. else
  6247. {
  6248. return null;
  6249. }
  6250. }
  6251. // WPIS NA MIKROBLOGU
  6252. else if (votesObject.sectionObjectElement.__vue__.item.resource == "entry")
  6253. {
  6254. votesObject.parent_element = votesObject.sectionObjectElement; // parent = this
  6255. votesObject.parent_id = votesObject.id;
  6256. votesObject.resource = "entry";
  6257. votesObject.fetchURL = `https://wykop.pl/api/v3/entries/${votesObject.id}`;
  6258. votesObject.parent_element.dataset.wxs_resource = "entry";
  6259. }
  6260. }
  6261.  
  6262.  
  6263. // votesObject.sectionObjectElement.dataset.wxs_votes_up = votesObject.votesUp; // <section data-wxs_votes_up="1" data_wxs_votes_down="8">
  6264. // votesObject.sectionObjectElement.dataset.wxs_votes_down = votesObject.votesDown;
  6265.  
  6266. if (dev) console.log("votesObject");
  6267. if (dev) console.log(votesObject);
  6268.  
  6269. return votesObject;
  6270. }
  6271.  
  6272.  
  6273.  
  6274.  
  6275.  
  6276.  
  6277.  
  6278.  
  6279. function checkPluses(sectionObjectElement, ratingBoxSection, showUpdatedValues = true)
  6280. {
  6281. // console.clear();
  6282. consoleX(`checkPluses(showUpdatedValues: ${showUpdatedValues})`, 0);
  6283.  
  6284. if (sectionObjectElement == null && ratingBoxSection?.__vue__?.$parent)
  6285. {
  6286. if (ratingBoxSection?.__vue__?.$parent.item.resource == "link")
  6287. {
  6288. sectionObjectElement = ratingBoxSection.closest("section.link-block")
  6289. }
  6290. else
  6291. {
  6292. sectionObjectElement = ratingBoxSection.closest("section.entry")
  6293. }
  6294. }
  6295.  
  6296.  
  6297. if (sectionObjectElement && sectionObjectElement.__vue__ && sectionObjectElement.__vue__.item.deleted == null)
  6298. {
  6299. if (!ratingBoxSection)
  6300. {
  6301. if (sectionObjectElement.__vue__.item.resource == "link")
  6302. {
  6303. ratingBoxSection = sectionObjectElement.querySelector("section.vote-box");
  6304. }
  6305. else
  6306. {
  6307. ratingBoxSection = sectionObjectElement.querySelector("section.rating-box");
  6308. }
  6309. }
  6310.  
  6311. if (dev) console.log("checkPluses() -> sectionObjectElement: ", sectionObjectElement)
  6312. if (dev) console.log("checkPluses() -> ratingBoxSection: ", ratingBoxSection)
  6313.  
  6314. const votesObject = getVotesObject(sectionObjectElement, ratingBoxSection);
  6315.  
  6316. if (votesObject) // TODO subkomentarze
  6317. {
  6318. if (dev) console.log("checkPluses() -> votesObject", votesObject);
  6319.  
  6320. // let sectionObjectElement = votesObject.sectionObjectElement;
  6321. sectionObjectElement.classList.remove("plusesAdded", "plusesRemoved", "minusesAdded", "minusesRemoved");
  6322.  
  6323. sectionObjectElement.style.removeProperty('--plusesAdded');
  6324. sectionObjectElement.style.removeProperty('--plusesRemoved');
  6325. sectionObjectElement.style.removeProperty('--minusesAdded');
  6326. sectionObjectElement.style.removeProperty('--minusesRemoved');
  6327.  
  6328. fetch(votesObject.fetchURL,
  6329. {
  6330. method: "GET",
  6331. headers: {
  6332. "Content-Type": "application/json",
  6333. Authorization: "Bearer " + window.localStorage.token,
  6334. },
  6335. })
  6336. .then(x => x.json())
  6337. .then(data =>
  6338. {
  6339. if (!data.data) return false;
  6340.  
  6341. let data_fetched;
  6342. if (Array.isArray(data.data) && data.data.length > 0) data_fetched = data.data.find(item => item.id === votesObject.id); // array from subcomments /api/v3/links/a/comments/b/comments => [array of subcomment objects]
  6343. else if (data.data && data.data.id === votesObject.id) data_fetched = data.data;
  6344. else { return false; }
  6345.  
  6346. if (dev) console.log(`checkPluses() -> data_fetched from ${votesObject.fetchURL}`, data_fetched);
  6347.  
  6348. votesObject.votesUpPrevious = votesObject.votesUp; // sectionObjectElement.dataset.wxs_votes_up;
  6349. votesObject.votesDownPrevious = votesObject.votesDown; // sectionObjectElement.dataset.wxs_votes_down;
  6350.  
  6351. votesObject.votesUp = data_fetched.votes.up;
  6352. votesObject.votesDown = data_fetched.votes.down;
  6353. votesObject.votesCount = data_fetched.votes.up - data_fetched.votes.down; // -10 (suma plusów i minusów nie dotyczy entry, entry_comment)
  6354. votesObject.votesAll = data_fetched.votes.up + data_fetched.votes.down; // 30 (liczba głosów nie dotyczy entry, entry_comment)
  6355. votesObject.votesUpPercent = 0; // nie dotyczy entry, entry_comment zawsze 100%
  6356. votesObject.votesDownPercent = 0; // nie dotyczy entry, entry_comment
  6357.  
  6358. if (data_fetched?.comments?.count) votesObject.commentsCount = data_fetched.comments.count;
  6359. if (data_fetched?.comments?.hot) votesObject.commentsHot = data_fetched.comments.hot;
  6360.  
  6361. // ile plusów przybyło/ubyło od ostatniego sprawdzenia
  6362. votesObject.plusesDelta = votesObject.votesUp - votesObject.votesUpPrevious;
  6363. votesObject.minusesDelta = votesObject.votesDown - votesObject.votesDownPrevious;
  6364. votesObject.votesCountChanged = (votesObject.plusesDelta != 0 || votesObject.minusesDelta != 0);
  6365.  
  6366.  
  6367. // if(dev) console.log("dataset.votesup: " + sectionObjectElement.dataset.wxs_votes_up + " / votesObject.plusesDelta: " + votesObject.plusesDelta)
  6368. // if(dev) console.log("sectionObjectElement.dataset")
  6369. // if(dev) console.log(sectionObjectElement.dataset)
  6370. // if(dev) console.log(sectionObjectElement)
  6371.  
  6372. // ZMIENIŁA SIĘ LICZBA PLUSÓW / WYKOPÓW
  6373. if (votesObject.votesCountChanged)
  6374. {
  6375. //alert("votesCountChanged")
  6376. if (dev) console.log("checkPluses() -> --------------------");
  6377. if (dev) console.log("checkPluses() -> VOTES COUNT CHANGED", sectionObjectElement)
  6378.  
  6379.  
  6380. sectionObjectElement.dataset.wxs_votes_up = votesObject.votesUp; // 10
  6381. sectionObjectElement.dataset.wxs_votes_down = votesObject.votesDown; // 20 — dodatnia nie dotyczy entry, entry_comment
  6382. sectionObjectElement.dataset.wxs_votes_count = votesObject.votesCount; // -10 (suma plusów i minusów nie dotyczy entry, entry_comment)
  6383. sectionObjectElement.dataset.wxs_votes_all = votesObject.votesAll; // 30 (łączna liczba głosów nie dotyczy entry, entry_comment)
  6384. sectionObjectElement.dataset.wxs_voted = votesObject.voted; // czy zaglosowano
  6385. sectionObjectElement.dataset.wxs_votes_separated = votesObject.separated || true;
  6386.  
  6387. updateFetchedVotesData(sectionObjectElement, votesObject, showUpdatedValues);
  6388. }
  6389. });
  6390. }
  6391. }
  6392. }
  6393.  
  6394. function updateFetchedVotesData(sectionObjectElement, votesObject, showUpdatedValues = true, onlyPluses = false)
  6395. {
  6396. consoleX(`updateFetchedVotesData() -> updateVisibleLinkVotesCount(showUpdatedValues: ${showUpdatedValues}, onlyPluses: ${onlyPluses})`, 1);
  6397.  
  6398. let ratingBoxSection;
  6399. let ratingBoxVotesUpCountElement;
  6400. let ratingBoxVotesDownCountElement;
  6401. let ratingBoxVotesDownPercentElement;
  6402. let ratingBoxVotesPerHourElement;
  6403.  
  6404. if (sectionObjectElement.__vue__.item.resource == "link")
  6405. {
  6406. ratingBoxSection = sectionObjectElement.querySelector("section.vote-box");
  6407.  
  6408. ratingBoxVotesUpCountElement = ratingBoxSection.querySelector("div.dig > p > span");
  6409. ratingBoxVotesDownCountElement = ratingBoxSection.querySelector(".wykopx_votesDownCount");
  6410. ratingBoxVotesDownPercentElement = ratingBoxSection.querySelector(".wykopx_votesDownPercent");
  6411. ratingBoxVotesPerHourElement = ratingBoxSection.querySelector(".wxs_votes_per_hour");
  6412. }
  6413. else
  6414. {
  6415. ratingBoxSection = sectionObjectElement.querySelector("section.rating-box");
  6416. sectionObjectElement.dataset.wxs_votes_separated = ratingBoxSection.__vue__.separated;
  6417.  
  6418. if (ratingBoxSection.__vue__.separated)
  6419. {
  6420. ratingBoxVotesUpCountElement = ratingBoxSection.querySelector("li.plus"); // li.plus.zero
  6421. ratingBoxVotesDownCountElement = ratingBoxSection.querySelector("li.minus"); // tylko przy komentarzach pod znaleziskiem
  6422. }
  6423. else
  6424. {
  6425. ratingBoxVotesUpCountElement = ratingBoxSection.querySelector("ul > li");
  6426. }
  6427.  
  6428. ratingBoxVotesPerHourElement = ratingBoxSection.querySelector(".wxs_votes_per_hour");
  6429. }
  6430.  
  6431.  
  6432.  
  6433. if (!votesObject && ratingBoxSection)
  6434. {
  6435. votesObject = getVotesObject(sectionObjectElement, ratingBoxSection);
  6436. }
  6437.  
  6438.  
  6439.  
  6440. // VOTES PER HOUR CALCULATION
  6441. if ((votesObject.resource == "link" && settings.checkLinkVotesEnable && settings.checkLinkVotesPerHour)
  6442. || (votesObject.resource != "link" && settings.checkEntryPlusesEnable && settings.checkEntryPlusesPerHour))
  6443. {
  6444. const timeSinceFirtsLoad = (dayjs().valueOf() - sectionObjectElement.dataset.wxs_first_load_time) / 1000; // liczba sekund od zaladowania strony
  6445.  
  6446. if (timeSinceFirtsLoad > votesFetchingFirstDelayInSeconds + 5)
  6447. {
  6448. let votesPerHour = (votesObject.votesCount - sectionObjectElement.dataset.wxs_first_load_votes_count) * 3600 / timeSinceFirtsLoad;
  6449. let votesPerHourString;
  6450.  
  6451. // PLUSÓW NA GODZINE
  6452. if (votesPerHour == 0)
  6453. {
  6454. votesPerHourString = "0";
  6455. }
  6456. else if (votesPerHour > 0 && votesPerHour < 0.9)
  6457. {
  6458. votesPerHourString = "< 1";
  6459. }
  6460. else
  6461. {
  6462. let suffix_text;
  6463.  
  6464. if (votesObject.resource == "link")
  6465. {
  6466. suffix_text = "/h";
  6467. votesPerHour = votesPerHour.toFixed(0);
  6468. }
  6469. else
  6470. {
  6471. suffix_text = " plusa / h";
  6472. votesPerHour = votesPerHour.toFixed(1);
  6473. }
  6474.  
  6475. //votesPerHour = Math.round(votesPerHour)
  6476. votesPerHourString = `${votesPerHour}${suffix_text}`;
  6477. }
  6478.  
  6479. if (ratingBoxVotesPerHourElement) ratingBoxVotesPerHourElement.dataset.wxs_votes_per_hour = votesPerHourString; // data-wxs_votes_per_hour
  6480. }
  6481. }
  6482.  
  6483. // VOTES DOWN PERCENT
  6484. if (votesObject.votesAll > 0)
  6485. {
  6486. votesObject.votesDownPercent = Math.ceil(votesObject.votesDown * 100 / votesObject.votesAll);
  6487.  
  6488. sectionObjectElement.dataset.wxs_votes_down_percent = votesObject.votesDownPercent;
  6489.  
  6490.  
  6491. if (ratingBoxVotesDownPercentElement)
  6492. {
  6493. ratingBoxVotesDownPercentElement.dataset.wxs_votes_down_percent = votesObject.votesDownPercent;
  6494. ratingBoxVotesDownPercentElement.textContent = `(${votesObject.votesDownPercent}%)`;
  6495. }
  6496. }
  6497.  
  6498. // COMMENTS COUNT
  6499. // if (votesObject.resource == "link" || votesObject.resource == "entry" || votesObject.resource == "link_comment")
  6500. // {
  6501. // sectionObjectElement.dataset.wxs_comment_count = votesObject.commentsCount;
  6502. // }
  6503.  
  6504. // if(dev) console.log("votesObject:");
  6505. // if(dev) console.log(votesObject);
  6506. // if(dev) console.log("sectionObjectElement.dataset:");
  6507. // if(dev) console.log(sectionObjectElement.dataset);
  6508.  
  6509.  
  6510.  
  6511.  
  6512. if (onlyPluses == false)
  6513. {
  6514. const votesDown = sectionObjectElement.dataset.wxs_votes_down;
  6515. sectionObjectElement.style.setProperty('--votesDown', `"${settings.prefixBeforeMinusesCount}` + votesDown + `"`);
  6516. // zbytek
  6517. let minusLi = sectionObjectElement.querySelector("section.rating-box > ul > li.minus");
  6518. if (minusLi) minusLi.textContent = votesDown;
  6519. }
  6520.  
  6521.  
  6522.  
  6523. // PRZYBYŁY PLUSY
  6524. if (votesObject.plusesDelta != 0)
  6525. {
  6526. ratingBoxVotesUpCountElement.dataset.wxs_votes_up = votesObject.votesUp;
  6527.  
  6528. if (votesObject.resource == "link")
  6529. {
  6530. ratingBoxVotesUpCountElement.textContent = votesObject.votesUp;
  6531. }
  6532. else
  6533. {
  6534. const separated = sectionObjectElement.dataset.wxs_votes_separated || true;
  6535. let votesCountDisplayValue = ((separated === "true" || separated === true) ? votesObject.votesCount : votesObject.votesUp);
  6536. if (votesCountDisplayValue > 0) votesCountDisplayValue = `${settings.prefixBeforePlusesCount}${votesCountDisplayValue}`
  6537. else if (votesCountDisplayValue < 0) votesCountDisplayValue = `${settings.prefixBeforeMinusesCount}${votesCountDisplayValue}`;
  6538.  
  6539.  
  6540. }
  6541.  
  6542. if (votesObject.plusesDelta > 0)
  6543. {
  6544. sectionObjectElement.classList.add("plusesAdded");
  6545. ratingBoxSection.dataset.wxs_pluses_delta = `+${votesObject.plusesDelta}`;
  6546. //sectionObjectElement.style.setProperty('--plusesAdded', `"+${votesObject.plusesDelta}"`);
  6547. }
  6548. else
  6549. {
  6550. sectionObjectElement.classList.add("plusesRemoved");
  6551. ratingBoxSection.dataset.wxs_pluses_delta = `${votesObject.plusesDelta}`;
  6552. //sectionObjectElement.style.setProperty('--plusesRemoved', `"${votesObject.plusesDelta}"`); // jest z minusem
  6553. }
  6554. }
  6555.  
  6556. // PRZYBYŁY MINUSY POD KOMENTARZEM W ZNALEZISKU
  6557. if (votesObject.minusesDelta != 0 && ratingBoxVotesDownCountElement)
  6558. {
  6559. ratingBoxVotesDownCountElement.dataset.wxs_votes_down = votesObject.votesDown;
  6560.  
  6561. if (votesObject.resource == "link")
  6562. {
  6563. ratingBoxVotesDownCountElement.textContent = votesObject.votesDown;
  6564. }
  6565. else
  6566. {
  6567. const separated = sectionObjectElement.dataset.wxs_votes_separated || true;
  6568. if (separated) // minusy i plusy są osobno, więc zmieniamy minusy
  6569. {
  6570. let votesCountDisplayValue = votesObject.votesDown;
  6571. if (votesCountDisplayValue < 0) votesCountDisplayValue = `${settings.prefixBeforeMinusesCount}${votesCountDisplayValue}`;
  6572. ratingBoxVotesDownCountElement.textContent = votesCountDisplayValue;
  6573. }
  6574. else // minusy i plusy są razem, więc zmieniamy plusy
  6575. {
  6576. let votesCountDisplayValue = votesObject.votesCount;
  6577. if (votesCountDisplayValue > 0) votesCountDisplayValue = `${settings.prefixBeforePlusesCount}${votesCountDisplayValue}`
  6578. else if (votesCountDisplayValue < 0) votesCountDisplayValue = `${settings.prefixBeforeMinusesCount}${votesCountDisplayValue}`;
  6579. ratingBoxVotesUpCountElement.textContent = votesCountDisplayValue;
  6580. }
  6581.  
  6582. }
  6583.  
  6584.  
  6585. if (votesObject.minusesDelta > 0)
  6586. {
  6587. sectionObjectElement.classList.add("minusesAdded");
  6588. ratingBoxSection.dataset.wxs_minuses_delta = `-${votesObject.minusesDelta}`;
  6589. //sectionObjectElement.style.setProperty('--minusesAdded', `"-${votesObject.minusesDelta}"`);
  6590. }
  6591. else
  6592. {
  6593. sectionObjectElement.classList.add("minusesRemoved");
  6594. ratingBoxSection.dataset.wxs_minuses_delta = `+${votesObject.minusesDelta}`;
  6595. //sectionObjectElement.style.setProperty('--minusesRemoved', `"+${votesObject.minusesDelta}"`);
  6596. }
  6597. }
  6598. }
  6599.  
  6600.  
  6601.  
  6602.  
  6603.  
  6604.  
  6605.  
  6606. // <section class="rating-box" data-wxs_pluses="269" data-wxs_minuses="0" data-wxs_pluses_minuses_total="269" data-wxs_pluses_below_limit="true">
  6607. function parseRatingBoxCurrentContentAndCreateDataValues(ratingBoxSection)
  6608. {
  6609. // dodanie data-wxs_pluses na podstawie aktualnych wartosci plusow w HTML
  6610. // if(dev) console.log("parseRatingBoxCurrentContentAndCreateDataValues(ratingBoxSection)")
  6611. consoleX(`parseRatingBoxCurrentContentAndCreateDataValues()`, 1);
  6612.  
  6613. const minusLi = ratingBoxSection.querySelector('li.minus');
  6614. let plusLi = ratingBoxSection.querySelector('li.plus');
  6615. if (!plusLi) plusLi = ratingBoxSection.querySelector('li.zero')
  6616. let votesUp = plusLi ? plusLi.textContent : 0; // 5liczba plusów
  6617. let votesDown = minusLi ? -1 * minusLi.textContent : 0; // 15 liczba minusów (dodatnia)
  6618. let votesCount = votesUp - votesDown; // -10 suma plusów i minusów
  6619. let votesAll = votesUp + votesDown; // 20 liczba glosow
  6620.  
  6621.  
  6622. ratingBoxSection.dataset.wxs_votes_up = votesUp;
  6623. ratingBoxSection.dataset.wxs_votes_down = votesDown;
  6624. ratingBoxSection.dataset.wxs_votes_count = votesCount;
  6625. ratingBoxSection.dataset.wxs_votes_all = votesAll;
  6626.  
  6627. // limit ukrywania wpisow przypietych na glownej
  6628. const homepagePinnedEntriesPlusesLimit = settings.homepagePinnedEntriesHideBelowLimit;
  6629. if (homepagePinnedEntriesPlusesLimit > 0)
  6630. {
  6631. // czy wpis jest poniżej limitu ukrywania wpisow przypietych na glownej
  6632. let plusesBelowLimit = (votesCount < homepagePinnedEntriesPlusesLimit ? true : false);
  6633. ratingBoxSection.dataset.wxs_pluses_below_limit = plusesBelowLimit;
  6634. }
  6635. }
  6636.  
  6637.  
  6638.  
  6639. // VOTING REAL UPDATE, VOTING EXPLOSION
  6640. function votingEventListener(sectionObjectElement, ratingBoxSection)
  6641. {
  6642. consoleX(`votingEventListener()`, 1);
  6643.  
  6644. if (sectionObjectElement && ratingBoxSection)
  6645. {
  6646. if (settings.checkEntryPlusesWhenVoting)
  6647. {
  6648. ratingBoxSection.addEventListener('mouseenter', function (event)
  6649. {
  6650. //var clickedButton = event.target;
  6651. if (dev) console.log("mouseenter rating box")
  6652. checkPluses(sectionObjectElement, ratingBoxSection, false);
  6653. });
  6654. }
  6655.  
  6656.  
  6657. /*
  6658. ratingBoxSection.__vue__
  6659. {
  6660. voted: 0 // czy zaglosowane
  6661. down: 0
  6662. up: 278
  6663. value: 278
  6664. formattedValue: "278",
  6665. separated: false
  6666. id: 23456789
  6667. idParent: 1234567
  6668. linkId: 1234567
  6669. users: [{}, {}...],
  6670. type: "entryComment" / "???"
  6671. deleted: null
  6672. author: "NadiaFrance"
  6673. showBtn: true / false
  6674. }
  6675. */
  6676.  
  6677. if (settings.votePlusMinusOnHover)
  6678. {
  6679. ratingBoxSection.addEventListener('mouseover', function (event)
  6680. {
  6681.  
  6682. if (event.target.matches('button:not(.voted)'))
  6683. {
  6684. event.target.click();
  6685. }
  6686. });
  6687. }
  6688.  
  6689.  
  6690. ratingBoxSection.addEventListener('click', function (event)
  6691. {
  6692. var clickedButton = event.target;
  6693.  
  6694. let up = 0;
  6695. let down = 0;
  6696. let count = 0;
  6697. let all = 0;
  6698.  
  6699. let vote = "voted"; // "voted", "unvoted"
  6700. let action = "plused"; // "plused", "minused"
  6701. let sign = "+";
  6702.  
  6703. // let votesUp = ratingBoxSection.__vue__.up;
  6704. // let votesDown = ratingBoxSection.__vue__.down;
  6705.  
  6706. //let votesUp = sectionObjectElement.dataset.wxs_votes_up;
  6707. //let votesDown = sectionObjectElement.dataset.wxs_votes_down;
  6708.  
  6709.  
  6710. if (clickedButton.matches('button.plus.voted')) // dodano plusa
  6711. {
  6712. action = "plused";
  6713. vote = "voted";
  6714. // count = votesUp;
  6715. up = Number(sectionObjectElement.dataset.wxs_votes_up) + 1;
  6716. count = Number(sectionObjectElement.dataset.wxs_votes_count) + 1;
  6717. all = Number(sectionObjectElement.dataset.wxs_votes_all) + 1;
  6718.  
  6719. }
  6720. else if (clickedButton.matches('button.plus:not(.voted)')) // usunieto plusa
  6721. {
  6722. action = "plused";
  6723. vote = "unvoted";
  6724. //count = votesUp;
  6725. up = Number(sectionObjectElement.dataset.wxs_votes_up) - 1;
  6726. count = Number(sectionObjectElement.dataset.wxs_votes_count) - 1;
  6727. all = Number(sectionObjectElement.dataset.wxs_votes_all) - 1;
  6728. }
  6729. else if (clickedButton.matches('button.minus.voted')) // dodano minusa
  6730. {
  6731. action = "minused";
  6732. vote = "voted";
  6733. sign = "-";
  6734. down = Number(sectionObjectElement.dataset.wxs_votes_down) - 1;
  6735. count = Number(sectionObjectElement.dataset.wxs_votes_count) - 1;
  6736. all = Number(sectionObjectElement.dataset.wxs_votes_all) + 1; // liczba głosów
  6737. }
  6738. else if (clickedButton.matches('button.minus:not(.voted)')) // usunięto minusa
  6739. {
  6740. action = "minused";
  6741. vote = "unvoted";
  6742. sign = "-";
  6743. //count = votesDown;
  6744. down = Number(sectionObjectElement.dataset.wxs_votes_down) + 1;
  6745. count = Number(sectionObjectElement.dataset.wxs_votes_count) + 1;
  6746. all = Number(sectionObjectElement.dataset.wxs_votes_all) - 1; // liczba głosów
  6747. }
  6748.  
  6749. sectionObjectElement.dataset.wxs_votes_up = up;
  6750. sectionObjectElement.dataset.wxs_votes_down = down;
  6751. sectionObjectElement.dataset.wxs_votes_all = all;
  6752. sectionObjectElement.dataset.wxs_votes_count = count;
  6753.  
  6754. updateFetchedVotesData(sectionObjectElement);
  6755.  
  6756. // voting explosion
  6757. if (settings.votingExplosionEnable && vote == "voted")
  6758. {
  6759. let maximumExpliosionTime = 1300; // default 0 delay, 1300 duration
  6760.  
  6761. let min_x = -60;
  6762. let max_x = 60;
  6763. let min_y = -60;
  6764. let max_y = -20;
  6765.  
  6766. if (count > 30) max_y = 60;
  6767. if (count > 300) { min_x = -90; max_x = 90; }
  6768.  
  6769. // let particlesCount = (count > 110 ? Math.ceil(count / 10) : count);
  6770. let particlesCount = count;
  6771. if (particlesCount > 2000) particlesCount = 200;
  6772. else if (particlesCount > 690) particlesCount = particlesCount / 10;
  6773. else if (particlesCount > 345) particlesCount = particlesCount / 5;
  6774. else if (particlesCount > 39) particlesCount = 39;
  6775.  
  6776.  
  6777. var newDivs = [];
  6778.  
  6779. for (var i = 0; i < particlesCount; i++)
  6780. {
  6781. var newDiv = document.createElement('div');
  6782. newDiv.textContent = sign;
  6783. newDiv.classList.add(`wykopxs_vote_animation`, `wykopxs_${vote}`, `wykopxs_${action}`); // class="wykopxs_vote_animation wykopxs_voted wykopxs_plused"
  6784.  
  6785. let color = (sign === "+" ? "green" : "red");
  6786. if (sign === "+")
  6787. {
  6788. if (count >= 666 && getRandomInt(1, 10) == 1) color = "golden";
  6789. if (count > 100 && count < 666 && getRandomInt(1, 80) == 1) newDiv.textContent = "💚";;
  6790. }
  6791. if (count > 100 && getRandomInt(1, 30) == 1)
  6792. {
  6793. min_x += getRandomInt(-30, 30); max_x += getRandomInt(-30, 30)
  6794. min_y -= getRandomInt(-30, 30); max_y -= getRandomInt(-30, 30);
  6795. }
  6796.  
  6797. newDiv.classList.add(`wykopxs_${color}`);
  6798.  
  6799. newDiv.style.setProperty('--position_x', getRandomInt(min_x, max_x, "px"));
  6800. newDiv.style.setProperty('--position_y', getRandomInt(min_y, max_y, "px"));
  6801. newDiv.style.setProperty('--position_z', 0);
  6802.  
  6803.  
  6804. if (count > 30)
  6805. {
  6806. newDiv.style.setProperty('--explosionTiming', getRandomString("linear", "ease", "ease-in-out", "ease-in", "ease-out")); // "cubic-bezier(0.1, 0.7, 1, 0.1)"
  6807. newDiv.style.setProperty('--explosionDelay', getRandomInt(0, getRandomInt(0, Math.max(800, count)), "ms"));
  6808. newDiv.style.setProperty('--explosionDuration', getRandomInt(900, 1300), "ms");
  6809.  
  6810. maximumExpliosionTime = Math.max(800, count) + 1300;
  6811. }
  6812.  
  6813. clickedButton.after(newDiv);
  6814. newDivs.push(newDiv);
  6815. }
  6816.  
  6817. parseRatingBoxCurrentContentAndCreateDataValues(ratingBoxSection); // TODO
  6818.  
  6819. setTimeout(function ()
  6820. {
  6821. for (var i = 0; i < newDivs.length; i++)
  6822. {
  6823. newDivs[i].parentNode.removeChild(newDivs[i]);
  6824. }
  6825.  
  6826. }, maximumExpliosionTime);
  6827. }
  6828. });
  6829. }
  6830.  
  6831. }
  6832.  
  6833.  
  6834.  
  6835.  
  6836.  
  6837.  
  6838.  
  6839.  
  6840.  
  6841.  
  6842.  
  6843. const apiGetLink = "https://wykop.pl/api/v3/links/";
  6844. /*
  6845. <section id="link-7288349" class="link-block"
  6846. data-wxs_votes_up="183" data-wxs_votes_down="5" data-wxs_votes_count="178" data-voted="0" data-comments-count="10" data-comments-hot="false" data-hot="false" data-adult="false" data-wxs_created_at="2023-11-27 21:12:49" data-published-at="2023-11-28 15:22:38" data-title="Dwie awarie..." data-slug="dwie-awarie-w-ec-bedzin-wznowienie-dostaw-ciepla-w-koncu-tygodnia-rmf-24" data-wxs_description="Dwie awarie w (...)" data-wxs_source_label="www.rmf24.pl" data-source-u-r-l="https://www.rmf24.pl/regiony/slaskie/news..." data-wxs_source_type="anchor" data-tags="slaskie,bedzin,awaria,wydarzenia">
  6847. */
  6848.  
  6849. function linkSectionIntersected(linkBlock)
  6850. {
  6851. if (dev) console.log("linkSectionIntersected(linkBlock)", linkBlock)
  6852.  
  6853. // const linkBlock = jNodeLinkBlock[0]; // jNode => DOMElement
  6854. //const link_id = linkBlock.id.replace("link-", ""); // 78643212
  6855. const link_id = linkBlock.__vue__.item.id;
  6856. const fetchURL = apiGetLink + link_id;
  6857. if (dev) console.log(fetchURL);
  6858.  
  6859. let link_data;
  6860.  
  6861. let sectionVoteBox = linkBlock.querySelector('section.vote-box');
  6862.  
  6863. if (sectionVoteBox)
  6864. {
  6865.  
  6866. if (settings.linksAnalyzerEnable)
  6867. {
  6868.  
  6869. fetch(fetchURL,
  6870. {
  6871. method: "GET", // or 'PUT'
  6872. headers: {
  6873. "Content-Type": "application/json",
  6874. Authorization: "Bearer " + window.localStorage.token,
  6875. },
  6876. })
  6877. .then(x => x.json())
  6878. .then(data =>
  6879. {
  6880. link_data = data.data;
  6881. if (dev) console.log("link_data");
  6882. if (dev) console.log(link_data);
  6883.  
  6884. linkBlock.dataset.wxs_votes_up = link_data.votes.up; // liczba wykopów/plusów 10
  6885. linkBlock.dataset.wxs_votes_down = link_data.votes.down; // liczba zakopów/minusów 20
  6886. linkBlock.dataset.wxs_votes_count = link_data.votes.count; // suma plusów i minusów/ suma wykopów i zakopów -10
  6887. linkBlock.dataset.wxs_votes_all = link_data.votes.up + link_data.votes.down; // łączna liczba oddanych głosów 30
  6888.  
  6889. link_data.votes.votesDownPercent = 0;
  6890. link_data.votes.votesUpPercent = 0;
  6891.  
  6892. if (linkBlock.dataset.wxs_votes_all > 0)
  6893. {
  6894. link_data.votes.votesDownPercent = Math.ceil(link_data.votes.down * 100 / linkBlock.dataset.wxs_votes_all);
  6895. link_data.votes.votesUpPercent = Math.ceil(link_data.votes.up * 100 / linkBlock.dataset.wxs_votes_all);
  6896. }
  6897.  
  6898. linkBlock.dataset.wxs_hot = link_data.hot;
  6899. linkBlock.dataset.wxs_slug = link_data.slug;
  6900. linkBlock.dataset.wxs_adult = link_data.adult;
  6901. linkBlock.dataset.wxs_tags = link_data.tags;
  6902. linkBlock.dataset.wxs_title = link_data.title;
  6903. linkBlock.dataset.wxs_voted = link_data.voted;
  6904. linkBlock.dataset.wxs_source_url = link_data.source.url;
  6905. linkBlock.dataset.wxs_source_type = link_data.source.type;
  6906. linkBlock.dataset.wxs_comments_hot = link_data.comments.hot;
  6907. linkBlock.dataset.wxs_description = link_data.description;
  6908. linkBlock.dataset.wxs_source_label = link_data.source.label;
  6909. linkBlock.dataset.wxs_comment_count = link_data.comments.count;
  6910. const linkBlockInfoSpan = linkBlock.querySelector("section > article > div.content > section.info > span");
  6911. if (link_data.created_at)
  6912. {
  6913. linkBlock.dataset.wxs_created_at = link_data.created_at;
  6914. const timeCreatedAt = document.createElement("time");
  6915. // timeCreatedAt.setAttribute("data-v-441f7cc5", null);
  6916. timeCreatedAt.innerHTML = `Dodane: ${link_data.created_at}`;
  6917. linkBlockInfoSpan.appendChild(timeCreatedAt);
  6918. }
  6919.  
  6920. if (link_data.published_at)
  6921. {
  6922. linkBlock.dataset.wxs_published_at = link_data.published_at;
  6923. const timePublishedAt = document.createElement("time");
  6924. // timePublishedAt.setAttribute("data-v-441f7cc5", null);
  6925. timePublishedAt.innerHTML = `Na głównej od: ${link_data.published_at}`;
  6926. linkBlockInfoSpan.appendChild(timePublishedAt);
  6927. }
  6928.  
  6929.  
  6930.  
  6931.  
  6932. // SORTOWANIE ZNALEZISK NA GŁÓWNEJ WEDŁUG
  6933. if (typeof settings.linksAnalyzerSortBy === "string" && settings.linksAnalyzerSortBy != "" && settings.linksAnalyzerSortBy != "domyslnie")
  6934. {
  6935. if (settings.linksAnalyzerSortBy == "by_votes_count") linkBlock.style.order = -1 * link_data.votes.count; // 🔽 Sortuj wg liczby wykopów style="order: -321"
  6936. else if (settings.linksAnalyzerSortBy == "by_comments_count") linkBlock.style.order = -1 * link_data.comments.count; // 🔽 Sortuj wg liczby komentarzy
  6937. else if (settings.linksAnalyzerSortBy == "by_created_oldest")
  6938. {
  6939. linkBlock.style.order = Math.floor(new Date(link_data.created_at).getTime() / 1000); // ⏬ Sortuj wg daty dodania (od najstarszego)
  6940. }
  6941. else if (settings.linksAnalyzerSortBy == "by_created_newest")
  6942. {
  6943. linkBlock.style.order = -1 * Math.floor(new Date(link_data.created_at).getTime() / 1000); // ⏫ Sortuj wg daty dodania (od najnowszego)
  6944. }
  6945. else if (link_data.published_at != null && settings.linksAnalyzerSortBy == "by_published_oldest")
  6946. {
  6947. linkBlock.style.order = Math.floor(new Date(link_data.published_at).getTime() / 1000); // ⏬ Sortuj wg czasu na głównej (od najstarszego)
  6948. }
  6949. else if (link_data.published_at != null && settings.linksAnalyzerSortBy == "by_published_newest")
  6950. {
  6951. linkBlock.style.order = -1 * Math.floor(new Date(link_data.published_at).getTime() / 1000); // ⏫ Sortuj wg czasu na głównej (od najnowszego)
  6952. }
  6953. }
  6954.  
  6955.  
  6956. const votesMeter = document.createElement('progress');
  6957. votesMeter.className = "wykopxs wykopx_votesMeter";
  6958. votesMeter.setAttribute('value', link_data.votes.up);
  6959. votesMeter.setAttribute('max', link_data.votes.up + link_data.votes.down);
  6960.  
  6961. const votesDownInfo = document.createElement('div');
  6962. votesDownInfo.className = "burry active wykopxVotesDownInfo";
  6963.  
  6964. const span = document.createElement('span');
  6965. span.className = "wykopxs wykopx_votesDown";
  6966. // VUE SENSITIVE data-v-5bb34f93
  6967. span.setAttribute('data-v-5bb34f93', '');
  6968. span.setAttribute('data-dropdown', `buried-${link_id}`);
  6969. span.setAttribute('title', `Statystyki Wykop X:
  6970.  
  6971. Liczba wykopujących: ${link_data.votes.up}
  6972. Liczba zakopujących: ${link_data.votes.down} (${link_data.votes.votesDownPercent}%)`);
  6973.  
  6974. const spanVotesDownCount = document.createElement('span');
  6975. spanVotesDownCount.className = "wykopxs wykopx_votesDownCount";
  6976. spanVotesDownCount.textContent = `${link_data.votes.down}`;
  6977.  
  6978. const spanVotesDownPercent = document.createElement('span');
  6979. spanVotesDownPercent.className = "wykopxs wykopx_votesDownPercent";
  6980. spanVotesDownPercent.textContent = `(${link_data.votes.votesDownPercent}%)`;
  6981.  
  6982. span.appendChild(spanVotesDownCount);
  6983. span.appendChild(spanVotesDownPercent);
  6984. votesDownInfo.appendChild(span);
  6985.  
  6986. sectionVoteBox.appendChild(votesDownInfo);
  6987. if (linkBlock.dataset.wxs_votes_all > 0)
  6988. {
  6989. sectionVoteBox.appendChild(votesMeter);
  6990. }
  6991.  
  6992. });
  6993. }
  6994.  
  6995. // if (settings.linkVoteDownButton && pageType != "wykopalisko")
  6996. if (settings.linkVoteDownButton && !sectionVoteBox.querySelector("div.burry"))
  6997. {
  6998. const downVoteElement = document.createElement("div");
  6999. downVoteElement.classList = "wxsDownVoteWrapper";
  7000. downVoteElement.style = "justify-content: center; display: flex; margin-top: 5px;"
  7001. let downVoteButtonHtml = `<button class="wxsDownVote" data-id="${link_id}" data-vote="down" data-reason="5" style="color: var(--blackish); font-size: 11px;">ZAKOP</button>`; //1-duplikat, 2-spam, 3-informacja nieprawidłowa, 4-treść nieodpowiednia, 5-nie nadaje się
  7002. downVoteElement.innerHTML = downVoteButtonHtml;
  7003. sectionVoteBox.appendChild(downVoteElement);
  7004.  
  7005.  
  7006. downVoteElement.addEventListener("click", async function ()
  7007. {
  7008. const downVoteButton = downVoteElement.children[0];
  7009. if (dev) console.log(downVoteButton);
  7010. let data = null;
  7011. if (downVoteButton.dataset.vote == "down")
  7012. {
  7013. data = await postWykopAPIData("links", downVoteButton.dataset.id, "votes", "down", downVoteButton.dataset.reason) // "/api/v3/links/1234567/votes/down/5"
  7014. // znalezisko zakopano
  7015. if (data == 204)
  7016. {
  7017. downVoteButton.dataset.vote = "undo";
  7018. downVoteButton.innerText = "odkop";
  7019. linkBlock.classList.add("wxsVotedDown");
  7020. sectionVoteBox.classList.add("voted", "buried");
  7021. }
  7022. }
  7023. else if (downVoteButton.dataset.vote == "undo")
  7024. {
  7025. data = await deleteWykopAPIData("links", downVoteButton.dataset.id, "votes") // "/api/v3/links/1234567/votes" -- cofniecie wykopu/zakopu
  7026. // cofnięto wykop/zakop
  7027. if (data == 204)
  7028. {
  7029. downVoteButton.dataset.vote = "down";
  7030. downVoteButton.innerText = "ZAKOP";
  7031. linkBlock.classList.remove("wxsVotedDown");
  7032. sectionVoteBox.classList.remove("voted", "buried");
  7033. }
  7034. }
  7035.  
  7036. if (dev) console.log("downVoteLink data:");
  7037. if (dev) console.log(data);
  7038. })
  7039. }
  7040. }
  7041. }
  7042.  
  7043.  
  7044.  
  7045.  
  7046.  
  7047.  
  7048.  
  7049.  
  7050.  
  7051.  
  7052.  
  7053.  
  7054.  
  7055.  
  7056.  
  7057.  
  7058.  
  7059. /* ------ ZNIESIENIE LIMITÓW W TEXTAREA I INPUT PODCZAS WKLEJANIA TEKSTU ------ */
  7060.  
  7061. // <input data-v-6486857b="" data-v-99298700="" type="text" placeholder="Wpisz tytuł Znaleziska..." maxlength="80" class="">
  7062. // <textarea data-v-8f9e192e="" data-v-99298700="" placeholder="Wpisz opis Znaleziska..." maxlength="300" class=""></textarea>
  7063. // <input data-v-714efcd5="" id="title" type="text" placeholder="Wpisz tytuł..." maxlength="80" class="highlight">
  7064. if (settings.disableNewLinkEditorPastedTextLimit)
  7065. {
  7066. waitForKeyElements("[maxlength]", disableNewLinkEditorPastedTextLimit, false);
  7067. }
  7068.  
  7069. function disableNewLinkEditorPastedTextLimit(input)
  7070. {
  7071. consoleX(`disableNewLinkEditorPastedTextLimit()`, 1)
  7072. const maxLength = input.getAttribute('maxlength');
  7073. input.removeAttribute('maxlength');
  7074.  
  7075. let divElement = document.createElement('div');
  7076.  
  7077. divElement.className = 'wykopxs_textinput_limit_info';
  7078. divElement.style.color = 'rgba(120, 120, 120, 1)';
  7079. divElement.style.fontSize = '14px';
  7080. divElement.style.margin = '10px 0px 10px 0px';
  7081.  
  7082. input.parentNode.appendChild(divElement, input);
  7083.  
  7084. function handleInputEvent()
  7085. {
  7086. let charCount = input.value.length;
  7087. divElement.innerHTML = `
  7088. Wykop X: wprowadzono:
  7089. <span class="${charCount > maxLength ? 'overLimit' : 'withinLimit'}" style="color: ${charCount > maxLength ? 'red' : 'inherit'}">
  7090. <strong>${charCount}</strong> /
  7091. <strong>${maxLength}</strong>
  7092. </span>
  7093. znaków`;
  7094. }
  7095.  
  7096. input.addEventListener('change', handleInputEvent);
  7097. input.addEventListener('focus', handleInputEvent);
  7098. input.addEventListener('paste', handleInputEvent);
  7099.  
  7100.  
  7101. let timeout = null;
  7102. input.addEventListener('keyup', function (e)
  7103. {
  7104. if (e.key === ' ' || e.key === '.')
  7105. {
  7106. handleInputEvent(e);
  7107. }
  7108. else
  7109. {
  7110. clearTimeout(timeout);
  7111. timeout = setTimeout(function ()
  7112. {
  7113. handleInputEvent(e);
  7114. }, 2000);
  7115. }
  7116. });
  7117.  
  7118. }
  7119.  
  7120.  
  7121.  
  7122.  
  7123.  
  7124.  
  7125.  
  7126.  
  7127.  
  7128.  
  7129.  
  7130.  
  7131.  
  7132. /* ------ HELPER FUNCTIONS --------- */
  7133.  
  7134. // consoleX("TEXT")
  7135. // consoleX("TEXT", false)
  7136. // consoleX("TEXT", 1) -- wyświetla tylko w trybie dev
  7137. function consoleX(text, only_on_dev_mode = false)
  7138. {
  7139. if (only_on_dev_mode == false || dev == true)
  7140. {
  7141. let tpl = `background-color:black; border:1px solid rgba(244, 244, 244, 0.4); font-weight: bolder; padding: 0px 9px; font-family: "Segoe UI", "Open Sans", sans-serif; margin-right: 10px;`;
  7142. if (only_on_dev_mode) tpl += `color:rgba(43, 255, 75, 1);`;
  7143. else tpl += `color:rgba(255, 255, 255, 0.8);`;
  7144.  
  7145. if (dev) console.log(`%cWykop X%c` + text, `${tpl}`, `font-family: "Segoe UI", "Open Sans"`);
  7146. }
  7147.  
  7148. }
  7149.  
  7150.  
  7151. // DEV RUN WITH DELAY
  7152. function runWithDelay(time, f)
  7153. {
  7154. // consoleX(`runWithDelay(f , ${time})`, 1);
  7155. setTimeout(function ()
  7156. {
  7157. f();
  7158. }, time);
  7159. }
  7160.  
  7161.  
  7162.  
  7163. function replaceDigitsWithDot(num)
  7164. {
  7165. if (num < 100)
  7166. {
  7167. return num.toString().slice(0, -1) + " ·";
  7168. } else
  7169. {
  7170. return num.toString().slice(0, -2) + " · ·";
  7171. }
  7172. }
  7173.  
  7174. // SHA256("WykopX") => "f5583a1d5d6044951722fe4b08d534af2b571efc065c8b73d07689d25d8a6175"
  7175. async function SHA256(message)
  7176. {
  7177. const encoder = new TextEncoder();
  7178. const data = encoder.encode(message); // 8,87,121,107,111,112,88
  7179. const hashBuffer = await crypto.subtle.digest("SHA-256", data);
  7180. const hashArray = Array.from(new Uint8Array(hashBuffer)); // convert buffer to byte array
  7181. const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join(''); // convert bytes to hex string f5583a1d5d6044951722fe4b08d534af2b571efc065c8b73d07689d25d8a6175
  7182. consoleX(`SHA256 hash: ${hashHex}`, 1);
  7183. return hashHex;
  7184. }
  7185.  
  7186.  
  7187.  
  7188. // getRandomInt(-30, 20, "px")
  7189. function getRandomInt(min, max, unit)
  7190. {
  7191. min = Math.ceil(min);
  7192. max = Math.floor(max);
  7193. let randomValue = Math.floor(Math.random() * (max - min + 1)) + min;
  7194. if (unit != null) randomValue = randomValue + unit;
  7195. return randomValue;
  7196. }
  7197.  
  7198.  
  7199. // getRandomString("string1", "string2", "string3", "string4", "string5");
  7200. function getRandomString(...stringsArray)
  7201. {
  7202. let randomString = stringsArray[Math.floor(Math.random() * stringsArray.length)];
  7203. return randomString;
  7204. }
  7205.  
  7206.  
  7207.  
  7208. // FUNKCJA SKOPIOWANA DO TS W WykopX Drop
  7209. function isValidURL(string)
  7210. {
  7211. try
  7212. {
  7213. new URL(string);
  7214. return true;
  7215. } catch (err)
  7216. {
  7217. return false;
  7218. }
  7219. }
  7220. // FUNKCJA SKOPIOWANA DO TS W WykopX Drop
  7221. function isValidImageURL(string)
  7222. {
  7223. if (isValidURL(string))
  7224. {
  7225. let lowerCaseString = string.toLowerCase();
  7226. if (lowerCaseString.endsWith(".png") || lowerCaseString.endsWith(".jpeg") || lowerCaseString.endsWith(".jpg") || lowerCaseString.endsWith(".webp"))
  7227. {
  7228. return true;
  7229. }
  7230. }
  7231. return false;
  7232. }
  7233. // FUNKCJA SKOPIOWANA DO TS W WykopX Drop
  7234. // returns array of valid URL's from a given string
  7235. // returns ["http://onet.pl", "https://www.wp.pl"]
  7236. // returns null
  7237. // getURLsFromString("string")
  7238. // getURLsFromString("string with img urls", true)
  7239. function getURLsFromString(string, onlyImagesURLs = false, appendHttpsForBeforeWww = true)
  7240. {
  7241. let urlRegex = /(https?:\/\/[^\s]+)|(www\.[^\s]+)/g;
  7242. let urlImagesRegex = /(https?:\/\/[^\s]+(\.png|\.jpg|\.jpeg|\.webp))|(www\.[^\s]+(\.png|\.jpg|\.jpeg|\.webp))/g;
  7243.  
  7244. let urls = string.match(onlyImagesURLs ? urlImagesRegex : urlRegex);
  7245. if (urls && appendHttpsForBeforeWww)
  7246. {
  7247. urls = urls.map(url => url.startsWith('www.') ? 'https://' + url : url);
  7248. }
  7249. return urls;
  7250. }
  7251. // FUNKCJA SKOPIOWANA DO TS W WykopX Drop
  7252. function bytesToKB(bytes, decimalDigits = 2)
  7253. {
  7254. return (bytes / 1024).toFixed(decimalDigits) + ' KB';
  7255. }
  7256. // FUNKCJA SKOPIOWANA DO TS W WykopX Drop
  7257. function bytesToMB(bytes, decimalDigits = 2)
  7258. {
  7259. return (bytes / (1024 * 1024)).toFixed(decimalDigits) + ' MB';
  7260. }
  7261.  
  7262. // returns array of words prefixed with + in string
  7263. // Output: ["r", "b", "f"]
  7264. // Output: ["normal"]
  7265. function getPlusWords(str)
  7266. {
  7267. // if(dev) console.log("getPlusWords(string): " + str)
  7268.  
  7269. let matches = str.match(/\+\p{L}+/gu); // diacritics characters, nie działa dla: str.match(/\+\w+/g);
  7270. if (matches)
  7271. {
  7272. return matches.map(word => word.slice(1)); //
  7273. }
  7274. else
  7275. {
  7276. return ["normal"];
  7277. }
  7278. }
  7279. function removePlusWords(str)
  7280. {
  7281. let words = str.split(' ');
  7282. let filteredWords = words.filter(word => word[0] !== '+');
  7283. let stringWithout = filteredWords.join(' ');
  7284. return stringWithout;
  7285. }
  7286.  
  7287. function capitalizeFirstLetter(str)
  7288. {
  7289. return str.charAt(0).toUpperCase() + str.slice(1);
  7290. }
  7291.  
  7292. function timeDurationFromSeconds(seconds)
  7293. {
  7294. const hours = Math.floor(seconds / 3600);
  7295. seconds %= 3600;
  7296. const minutes = String(Math.floor(seconds / 60)).padStart(2, '0');
  7297. seconds = String(Math.floor(seconds % 60)).padStart(2, '0');
  7298. return `${hours > 0 ? hours + ":" : ""}${minutes}:${seconds}`;
  7299. }
  7300.  
  7301.  
  7302.  
  7303.  
  7304.  
  7305.  
  7306.  
  7307.  
  7308.  
  7309. /* ARCHIWUM X */
  7310. let newestEntrySection = null;
  7311. let newestEntryID = null;
  7312. let wxs_newest_entry = 1;
  7313.  
  7314. async function archiveXNewestEntry()
  7315. {
  7316. let newestEntrySectionElem = document.createElement("div");
  7317. newestEntrySectionElem.id = "wxs_newest_entry";
  7318. newestEntrySectionElem.classList.add("hidden"); // .hidden
  7319.  
  7320. newestEntrySectionElem.innerHTML = `
  7321. <section data-v-2aacfeb5="" data-v-7693ae52="" class="entry" data-v-0a84d0a4=""><!-- id="comment-75364841" -->
  7322. <article data-v-2aacfeb5="">
  7323. <header data-v-2aacfeb5="">
  7324. <div data-v-2aacfeb5="" class="left">
  7325. <a data-v-fb64f4be="" data-v-2aacfeb5="" class="avatar active" style="width: 40px; height: 40px;"> <!-- href="/ludzie/NICK" -->
  7326. <figure data-v-fb64f4be="" class="male orange-profile wxs_newest_entry_author_color wxs_newest_entry_author_gender">
  7327. <img class="wxs_newest_entry_author_avatar" data-v-ecb5ea3e="" data-v-fb64f4be="" loading="lazy" src="https://wykop.pl/cdn/c0834752/3f55ec16859056965fb5ef04e080527497a9abce924d2edb171680c11e34ce1c,q80.png" alt="NICK">
  7328. </figure>
  7329. </a>
  7330. </div>
  7331.  
  7332. <div data-v-2aacfeb5="" class="right">
  7333. <div data-v-2aacfeb5="">
  7334. <div data-v-0908378b="" data-v-2aacfeb5="" class="tooltip-slot">
  7335. <span data-v-0908378b="">
  7336. <a class="wxs_newest_entry_author_username_ahref wxs_newest_entry_author_color username orange-profile active" href="/ludzie/WykopX" data-v-ed9f6c56="" data-v-2aacfeb5="">
  7337. <span class="wxs_newest_entry_author_username" data-v-ed9f6c56="">WykopX</span>
  7338. </a>
  7339. </span>
  7340. </div>
  7341. <span data-v-0908378b="">
  7342. <span data-v-2aacfeb5="">
  7343. <a class="wxs_newest_entry_ahref" data-v-2aacfeb5="" href="">
  7344. <time class="date wxs_newest_entry_created_at" data-v-0132bb98="" data-v-2aacfeb5="" title="2024-03-09 18:42:19" datetime="2024-03-09 18:42:19">przed chwilą</time>
  7345. </a>
  7346. </span>
  7347. </a>
  7348. </span>
  7349. </div>
  7350. <div data-v-2aacfeb5="">
  7351. <section data-v-76790450="" data-v-2aacfeb5="" class="rating-box">
  7352. <ul data-v-76790450="" class="">
  7353. <li data-v-76790450="" class="zero">0</li>
  7354. </ul>
  7355. <div data-v-76790450="" class="buttons">
  7356. <button data-v-76790450="" data-no-bubble="" class="plus">+</button>
  7357. </div>
  7358. </section>
  7359. </div>
  7360. </div>
  7361. </header>
  7362. <div data-v-2aacfeb5="" class="edit-wrapper">
  7363. <div data-v-2aacfeb5="" data-selectable="" class="content">
  7364. <section data-v-725caa02="" data-v-2aacfeb5="" class="entry-content">
  7365. <div data-v-725caa02="" class="wxs_newest_entry_content wrapper"adowanie...</div>
  7366. </section>
  7367. </div>
  7368. </div>
  7369. </article>
  7370. <div class="timer">
  7371. <div class="mask"></div>
  7372. </div>
  7373. </section>
  7374. `;
  7375.  
  7376. bodySection.appendChild(newestEntrySectionElem);
  7377. newestEntrySection = bodySection.querySelector("#wxs_newest_entry");
  7378.  
  7379. if (wxs_newest_entry && wxs_newest_entry != 0) getNewestEntryFromAPI(newestEntrySection);
  7380. }
  7381.  
  7382.  
  7383.  
  7384.  
  7385. let firstInDayID = {
  7386. entry: null,
  7387. link: null
  7388. }
  7389.  
  7390. // getEntryDailyNumber(wykopObjectData, "2023-01-01") -> 678 - zwraca który wpis tego dnia
  7391. async function getEntryDailyNumber(objectData) // "2024-03-14 21:34:51",
  7392. {
  7393. // if(dev) console.log(`getEntryDailyNumber(objectData.id: ${objectData.id}, createdAtDate: ${objectData.created_at})`);
  7394. // if(dev) console.log(`getEntryDailyNumber() - firstInDayID[${objectData.resource}]: `, firstInDayID[objectData.resource]);
  7395.  
  7396. const dateToCheck = dayjs(objectData.created_at).format("YYYY-MM-DD");
  7397.  
  7398. if (firstInDayID[objectData.resource] != null)
  7399. {
  7400. // if(dev) console.log(`mapa firstInDayID[${objectData.resource}] = null, sprawdzamy localstorage`);
  7401.  
  7402. await localStorageFirstDailyIDs.getItem(`${objectData.resource}FirstInDayIDsMap`).then(val => // localstorage: entryFirstInDayIDsMap / linkFirstInDayIDsMap
  7403. {
  7404. if (val !== null)
  7405. {
  7406. firstInDayID[objectData.resource] = new Map(Object.entries(val));
  7407. // if(dev) console.log("znaleziono w localstorage val=", val);
  7408. // if(dev) console.log("znaleziono w localstorage firstInDayID[objectData.resource]=", firstInDayID[objectData.resource]);
  7409. }
  7410. else
  7411. {
  7412. // if(dev) console.log('Mapa nie istniała, a w localstorage nie było zapisanych danych');
  7413. firstInDayID[objectData.resource] = new Map();
  7414. }
  7415. }).catch(err =>
  7416. {
  7417. console.error(err);
  7418. });
  7419. }
  7420.  
  7421. if (firstInDayID[objectData.resource])
  7422. {
  7423. // if(dev) console.log('Mapa już istnieje: firstInDayID[objectData.resource]', firstInDayID[objectData.resource]);
  7424.  
  7425. if (firstInDayID[objectData.resource].has(dateToCheck))
  7426. {
  7427. // if(dev) console.log(`Mapa posiada dla daty ${dateToCheck}, wartość: ${firstInDayID[objectData.resource].get(dateToCheck)}`);
  7428. // if(dev) console.log("firstInDayID[objectData.resource]", firstInDayID[objectData.resource])
  7429.  
  7430. return (objectData.id - firstInDayID[objectData.resource].get(dateToCheck)) / 2;
  7431. }
  7432. else
  7433. {
  7434. // if(dev) console.log(`Mapa istnieje, ale dla daty ${dateToCheck} nie posiada jeszcze wartości`);
  7435. }
  7436. }
  7437. else
  7438. {
  7439. firstInDayID[objectData.resource] = new Map();
  7440. }
  7441.  
  7442.  
  7443. // if(dev) console.log('Mapa przed wyslaniem zapytania do API WykopX: firstInDayID[objectData.resource]', firstInDayID[objectData.resource]);
  7444.  
  7445. const firstEntryData = await getWykopXAPIData(objectData.resource, "first-by-date") // https://archiwum.wykopx.pl/api/entry/first-by-date // https://archiwum.wykopx.pl/api/link/first-by-date
  7446. // if(dev) console.log('Pobrano z Archiwum Wykop X: firstEntryData, ', firstEntryData);
  7447.  
  7448. if (firstEntryData && firstEntryData.id != null)
  7449. {
  7450. firstInDayID[objectData.resource].set(dateToCheck, firstEntryData.id);
  7451. localStorageFirstDailyIDs.setItem(`${objectData.resource}FirstInDayIDsMap`, Object.fromEntries(firstInDayID[objectData.resource]));//.then(() => { });
  7452. // if(dev) console.log("firstInDayID[objectData.resource]", firstInDayID[objectData.resource])
  7453.  
  7454. return (objectData.id - firstEntryData.id) / 2;
  7455. }
  7456.  
  7457. return false;
  7458. }
  7459.  
  7460.  
  7461.  
  7462.  
  7463.  
  7464.  
  7465. // zmodyfikowana funkcja z mikroczatu
  7466. // zwraca 400 jesli autor cię blokuje, 409 jeśli nie
  7467. async function checkIfYouCanPostCommentInEntry(entry_id)
  7468. {
  7469. if (dev) console.log(`checkIfYouCanPostCommentInEntry() entry_id: ${entry_id}`);
  7470.  
  7471. let newMessageBody = {
  7472. resource: "entry_comment",
  7473. entry_id: entry_id,
  7474. content: ""
  7475. }
  7476.  
  7477. if (dev) console.log(`checkIfYouCanPostCommentInEntry() newMessageBody:`, newMessageBody);
  7478.  
  7479. //try
  7480. //{
  7481. if (dev) console.log(`try > postNewMessageToChannel, entry_id: ${entry_id}`);
  7482. return await postNewMessageToChannel(newMessageBody)
  7483. //}
  7484. // catch (error)
  7485. // {
  7486. // let httpError = error;
  7487.  
  7488. // switch (httpError.status)
  7489. // {
  7490. // case 400:
  7491. // // UZYTKOWNIK CIĘ BLOKUJE
  7492. // return false;
  7493. // break;
  7494. // case 409:
  7495. // // MOZED ODPISYWAĆ - WSZYSTKO OK (po prostu za krotka wiadomosc)
  7496. // return true;
  7497. // break;
  7498. // case 429:
  7499. // // INNY BLAD - ZA DUZO REQUESTOW
  7500. // break;
  7501. // default:
  7502. // // Other status codes
  7503. // }
  7504. // }
  7505. }
  7506.  
  7507.  
  7508.  
  7509.  
  7510.  
  7511. /* POST */
  7512. // funkcja z mikroczatu
  7513. async function postNewMessageToChannel(message)
  7514. {
  7515. if (dev) console.log(`postNewMessageToChannel: message: `, message);
  7516. /*
  7517. {
  7518. "data":
  7519. {
  7520. "content": "**foobar** __foobar__ [lorem](https://www.wykop.pl) impsum!!! #nsfw #wykop",
  7521. "photo": "e07843ss3fbe9cb4saeed0asdfsdfc64b9a4df6084199b39d2",
  7522. "embed": "1fde707843ss3fbe9cb4eed0asdfsdfc64ab9a4df6084199b39d2",
  7523. "survey": "qErgdjp5K0xz",
  7524. "adult": false
  7525. }
  7526. }
  7527. */
  7528.  
  7529. // nowy wpis (domyślnie)
  7530. let apiURL = "https://wykop.pl/api/v3/entries";
  7531.  
  7532. // nowy komentarz pod wpisem
  7533. if (message.resource && message.resource == "entry_comment" && message.entry_id)
  7534. {
  7535. apiURL = `https://wykop.pl/api/v3/entries/${message.entry_id}/comments`;
  7536. }
  7537.  
  7538. let bodyData = {};
  7539. message.content ? bodyData.content = message.content : "";
  7540. message.photo ? bodyData.photo = message.photo : "";
  7541. message.embed ? bodyData.embed = message.embed : "";
  7542. message.survey ? bodyData.survey = message.survey : "";
  7543. message.adult ? bodyData.adult = message.adult : "";
  7544.  
  7545. if (dev) console.log("bodyData to send: ", bodyData);
  7546. if (dev) console.log("apiURL: ", apiURL);
  7547.  
  7548. return new Promise(async (resolve, reject) =>
  7549. {
  7550. try
  7551. {
  7552. await fetch(apiURL,
  7553. {
  7554. method: "POST",
  7555. headers:
  7556. {
  7557. "Content-Type": "application/json",
  7558. Authorization: "Bearer " + window.localStorage.getItem("token"),
  7559. },
  7560. body: JSON.stringify(
  7561. {
  7562. "data": bodyData
  7563. })
  7564. })
  7565. .then((response) =>
  7566. {
  7567. if (dev) console.log("response", response)
  7568.  
  7569. if (!response.ok)
  7570. {
  7571. // zwraca error.status = 400 (jestes blokowany) albo error.status = 409 (pusta tresc)
  7572. if (dev) console.log(`HTTP error! status: ${response.status}`);
  7573. resolve(response.status);
  7574. // throw new T.HTTPError(`HTTP error! status: ${response.status}`, response.status);
  7575. }
  7576. })
  7577. .then(async (responseJSON) =>
  7578. {
  7579. if (dev) console.log("responseJSON")
  7580. if (dev) console.log(responseJSON)
  7581.  
  7582. resolve(responseJSON.data);
  7583.  
  7584. }).catch((error) =>
  7585. {
  7586. if (error instanceof TypeError)
  7587. {
  7588. //console.error('xxx Network error:', error); // AWARIA SERWERA
  7589. } else
  7590. {
  7591. //console.error('Other error:', error);
  7592. }
  7593. reject(error);
  7594. });
  7595. }
  7596. catch (error)
  7597. {
  7598. //console.error('Other catched error:', error);
  7599. reject(error);
  7600. }
  7601. });
  7602. }
  7603.  
  7604.  
  7605.  
  7606.  
  7607.  
  7608.  
  7609. async function getNewestEntryFromAPI(sectionElement = newestEntrySection)
  7610. {
  7611. sectionElement.classList.remove("animationRunning");
  7612.  
  7613. let newestEntryObject = await getWykopAPIData(`entries?sort=newest&limit=1`); // https://wykop.pl/api/v3/entries?sort=newest&limit=1
  7614. newestEntryObject = newestEntryObject.data[0]
  7615.  
  7616. if (newestEntryObject.id != newestEntryID)
  7617. {
  7618. newestEntryID = newestEntryObject.id
  7619. sectionElement.classList.add("animationRunning");
  7620.  
  7621. let entries_today_count = await getEntryDailyNumber(newestEntryObject);
  7622.  
  7623. if (entries_today_count)
  7624. {
  7625. sectionElement.querySelectorAll(".entry").forEach((el) =>
  7626. {
  7627. el.dataset.entries_today_count = entries_today_count;
  7628. });
  7629. }
  7630.  
  7631. sectionElement.querySelectorAll(".wxs_newest_entry_author_username_ahref").forEach((el) =>
  7632. {
  7633. el.href = `/ludzie/${newestEntryObject.author.username}`;
  7634. });
  7635. sectionElement.querySelectorAll(".wxs_newest_entry_author_gender").forEach((el) =>
  7636. {
  7637. el.classList.remove("male", "female");
  7638. if (newestEntryObject.author.gender == "m") el.classList.add(`male`);
  7639. else if (newestEntryObject.author.gender == "f") el.classList.add(`female`);
  7640. });
  7641. sectionElement.querySelectorAll(".wxs_newest_entry_author_color").forEach((el) =>
  7642. {
  7643. el.classList.remove("orange-profile", "green-profile", "burgundy-progile");
  7644. el.classList.add(`${newestEntryObject.author.color}-profile`);
  7645. });
  7646. sectionElement.querySelectorAll(".wxs_newest_entry_author_username").forEach((el) =>
  7647. {
  7648. el.innerHTML = newestEntryObject.author.username;
  7649. });
  7650. sectionElement.querySelectorAll(".wxs_newest_entry_author_avatar").forEach((el) =>
  7651. {
  7652. if (newestEntryObject.author.avatar) el.src = newestEntryObject.author.avatar;
  7653. else el.src = "/static/img/svg/avatar-default.svg";
  7654.  
  7655. el.alt = newestEntryObject.author.username;
  7656. });
  7657.  
  7658. sectionElement.querySelectorAll(".wxs_newest_entry_ahref").forEach((el) =>
  7659. {
  7660. el.href = `https://wykop.pl/wpis/${newestEntryObject.id}/wykopx`;
  7661. });
  7662. sectionElement.querySelectorAll(".wxs_newest_entry_created_at").forEach((el) =>
  7663. {
  7664. el.title = newestEntryObject.created_at;
  7665. el.datetime = newestEntryObject.created_at;
  7666. });
  7667.  
  7668. sectionElement.querySelectorAll(".wxs_newest_entry_content").forEach((el) =>
  7669. {
  7670. el.innerHTML = newestEntryObject.content;
  7671. });
  7672.  
  7673. }
  7674.  
  7675. sectionElement.classList.remove("hidden");
  7676.  
  7677. if (document.hidden == false) runWithDelay(2000 + (settings.wxsArchiveXNewestEntryRefresh * 1000), getNewestEntryFromAPI);
  7678. }
  7679.  
  7680.  
  7681. if (settings.wxsArchiveXNewestEntry)
  7682. {
  7683. CSS += `
  7684. body[data-wxs_newest_entry="0"] #wxs_newest_entry { display: none!important; }
  7685. body[data-wxs_newest_entry="1"] .wykopx_newest_entry_switcher { background: linear-gradient(to bottom right, transparent 0%, transparent 50%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.1) 100%); }
  7686. body[data-wxs_newest_entry="2"] .wykopx_newest_entry_switcher { background: linear-gradient(to top left, transparent 0%, transparent 50%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, 0.1) 100%); }
  7687. body[data-wxs_newest_entry="3"] .wykopx_newest_entry_switcher { background: rgba(255, 255, 255, 0.1); }
  7688.  
  7689. #wxs_newest_entry
  7690. {
  7691. right: 40px;
  7692. width: 400px;
  7693. height: auto;
  7694. max-height: 50%;
  7695.  
  7696. --border-radius: 0px;
  7697. border-radius: var(--border-radius)!important;
  7698. position: fixed;
  7699. bottom: 15px;
  7700. z-index: 9999;
  7701. display: grid;
  7702. color: var(--blackish);
  7703. background-color: var(--alta);
  7704. background: linear-gradient(145deg, var(--whitish), var(--alta));
  7705. box-shadow: 5px 5px 10px var(--porcelain), -5px -5px 10px var(--porcelain);
  7706. }
  7707. #wxs_newest_entry > .entry
  7708. {
  7709. border-radius: var(--border-radius)!important;
  7710. }
  7711.  
  7712. #wxs_newest_entry > .entry::after
  7713. {
  7714. bottom: 10px;
  7715. left: 20px;
  7716. content: attr(data-entries_today_count);
  7717. position: absolute;
  7718. font-size: 15px;
  7719. opacity: 0.2;
  7720. }`;
  7721. }
  7722.  
  7723.  
  7724. // TRYB NOCNY W BELCE NAWIGACYJNEJ
  7725. function addNewestEntryTopNavButton()
  7726. {
  7727. if (settings.wxsArchiveXNewestEntry)
  7728. {
  7729. wxs_newest_entry = localStorage.getItem('wxs_newest_entry');
  7730. if (!wxs_newest_entry) wxs_newest_entry = 1;
  7731. body.dataset.wxs_newest_entry = wxs_newest_entry;
  7732. // wykopx_newest_entry_switcher_status_0 - wylaczone
  7733. // wykopx_newest_entry_switcher_status_1 - wpisy
  7734. // wykopx_newest_entry_switcher_status_2 - linki
  7735. // wykopx_newest_entry_switcher_status_3 - oba
  7736. const wykopx_newest_entry_switcher_button = document.createElement("li");
  7737. wykopx_newest_entry_switcher_button.insertAdjacentHTML('afterbegin', `<a href="#"><figure>🤍</figure></a>`);
  7738. wykopx_newest_entry_switcher_button.classList.add("wykopx_newest_entry_switcher", "notifications", "dropdown");
  7739. wykopx_newest_entry_switcher_button.title = `Włącz/wyłącz powiadomienia o najnowszych wpisach na Mikroblogu ${promoString}`;
  7740. wykopx_newest_entry_switcher_button.addEventListener('click', function ()
  7741. {
  7742. wxs_newest_entry = localStorage.getItem('wxs_newest_entry');
  7743. // 0 - wylaczone
  7744. // 1 - wpisy
  7745. // 2 - linki
  7746. // 3 - wpisy + linki
  7747. if (wxs_newest_entry === null)
  7748. {
  7749. wxs_newest_entry = 1;
  7750. }
  7751. else if (wxs_newest_entry == 1) // przy linkach zmienić na == 3
  7752. {
  7753. wxs_newest_entry = 0;
  7754. }
  7755. else
  7756. {
  7757. wxs_newest_entry++;
  7758. }
  7759.  
  7760. if (wxs_newest_entry > 0) getNewestEntryFromAPI();
  7761.  
  7762. localStorage.setItem('wxs_newest_entry', wxs_newest_entry);
  7763.  
  7764. body.dataset.wxs_newest_entry = wxs_newest_entry;
  7765. });
  7766. topNavHeaderRightElement.appendChild(wykopx_newest_entry_switcher_button);
  7767. }
  7768. }
  7769.  
  7770.  
  7771.  
  7772.  
  7773.  
  7774.  
  7775.  
  7776.  
  7777.  
  7778.  
  7779.  
  7780. /* ------ PRZYCISK DO POBIERANIA OBRAZKÓW --------- */
  7781. if (settings.wxsDownloadImageButton)
  7782. {
  7783. waitForKeyElements("section.entry section.entry-photo figure", wxsDownloadImageButton, false);
  7784.  
  7785. function wxsDownloadImageButton(entryPhotoFigureElement)
  7786. {
  7787. consoleX(`wxsDownloadImageButton()`, 1);
  7788. let html = `<div class="wykopxs wxs_download_image_button"><a title="Pobierz ten obrazek w pełnej rozdzielczości ${promoString}" href="${entryPhotoFigureElement.querySelector('figcaption a').getAttribute('href')} " download>Pobierz ten obrazek</a></div>`;
  7789. entryPhotoFigureElement.insertAdjacentHTML('beforeend', html);
  7790. }
  7791. }
  7792.  
  7793.  
  7794.  
  7795.  
  7796.  
  7797. /* ------ IMAGE UPLOADER CTRL+V --------- */
  7798. waitForKeyElements("section.editor", sectionEditor, false);
  7799.  
  7800. function sectionEditor(sectionEditorElement)
  7801. {
  7802. consoleX("sectionEditor", 1)
  7803. const textareaEditorElement = sectionEditorElement.querySelector("textarea");
  7804.  
  7805. if (settings.editorSendHotkey != "domyslnie")
  7806. {
  7807. sendOnCTRL_ENTER(sectionEditorElement);
  7808. }
  7809.  
  7810. if (settings.imageUploaderEnable)
  7811. {
  7812. imagePasteFromClipboardListener(sectionEditorElement);
  7813. }
  7814.  
  7815. }
  7816.  
  7817.  
  7818. function sendOnCTRL_ENTER(sectionEditorElement)
  7819. {
  7820. consoleX("sendOnCTRL_ENTER", 1)
  7821.  
  7822. const textareaEditorElement = sectionEditorElement.querySelector("textarea");
  7823. const buttonSendElement = sectionEditorElement.querySelector("div.button.send > button");
  7824.  
  7825. if (settings.editorSendHotkey == "ctrl_enter")
  7826. {
  7827. sectionEditorElement.style.setProperty('--editorSendHotkey', `"CTRL+ENTER"`);
  7828. buttonSendElement.title = "Wykop X: Wciśnij CTRL + ENTER, aby wysłać "
  7829. }
  7830. else if (settings.editorSendHotkey == "enter")
  7831. {
  7832. sectionEditorElement.style.setProperty('--editorSendHotkey', `"ENTER"`);
  7833. buttonSendElement.title = "Wykop X: Wciśnij ENTER, aby wysłać "
  7834. }
  7835. else if (settings.editorSendHotkey == "ctrl_s")
  7836. {
  7837. sectionEditorElement.style.setProperty('--editorSendHotkey', `"CTRL+S"`);
  7838. buttonSendElement.title = "Wykop X: Wciśnij CTRL + S, aby wysłać ";
  7839. }
  7840.  
  7841. textareaEditorElement.addEventListener('keydown', function (e)
  7842. {
  7843. if (settings.editorSendHotkey == "ctrl_enter" && e.ctrlKey && e.key === 'Enter')
  7844. {
  7845. e.preventDefault();
  7846. buttonSendElement.dispatchEvent(new Event('click'));
  7847. }
  7848. else if (settings.editorSendHotkey == "enter" && e.key === 'Enter')
  7849. {
  7850. e.preventDefault();
  7851. buttonSendElement.dispatchEvent(new Event('click'));
  7852. }
  7853. else if (settings.editorSendHotkey == "ctrl_s" && e.ctrlKey && e.key === 's')
  7854. {
  7855. e.preventDefault();
  7856. buttonSendElement.dispatchEvent(new Event('click'));
  7857. }
  7858. });
  7859. }
  7860.  
  7861.  
  7862.  
  7863. function imagePasteFromClipboardListener(sectionEditorElement)
  7864. {
  7865. consoleX(`imagePasteFromClipboardListener()`, 1);
  7866. const textarea = sectionEditorElement.querySelector("textarea");
  7867. // if(dev) console.log(textarea);
  7868. const imageUploadPreview = document.createElement('figure');
  7869. imageUploadPreview.classList.add("wxs_uploaded_image_placeholder");
  7870. textarea.parentNode.appendChild(imageUploadPreview);
  7871.  
  7872. const imageUploaderCaption = document.createElement('div');
  7873. imageUploaderCaption.classList.add("wxs_uploader_caption");
  7874. imageUploaderCaption.innerHTML = `<span class="wxs_upload_first_image">CTRL + V - wklej obrazek ze schowka</span><span class="wxs_upload_and_replace_current_image">CTRL + V - wklej kolejny obrazek, aby zastąpić aktualnie dodany</span>`;
  7875. textarea.parentNode.appendChild(imageUploaderCaption);
  7876.  
  7877.  
  7878.  
  7879. // PASTE EVENT
  7880. document.addEventListener('paste', async (e) =>
  7881. {
  7882. // e.preventDefault();
  7883. // e.stopPropagation();
  7884. console.clear();
  7885. // if(dev) console.log("e.clipboardData.items") // object DataTransferItemList {0: DataTransferItem, 1: DataTransferItem, ...}
  7886. // if(dev) console.log(e.clipboardData.items)
  7887. // if(dev) console.log("clipboardData.types")
  7888. // if(dev) console.log(e.clipboardData.types) //  Array: ['Files', 'text/plain', 'text/html', 'application/vnd.code.copymetadata', 'vscode-editor-data']
  7889. // if(dev) console.log("clipboardData.files")
  7890. // if(dev) console.log(e.clipboardData.files)
  7891. /*
  7892. FileList = { 0: File, length: 1 }
  7893. FileList = { 0:
  7894. {
  7895. lastModified: timestamp // 1702989703658
  7896. lastModifiedDate: DateTime
  7897. name: "image.png";
  7898. size: 1230133
  7899. type: "image/png"
  7900. webkitRelativePath: ""
  7901. },
  7902. length: 1
  7903. }
  7904. */
  7905. // items ->text files -> pliki png
  7906.  
  7907. const uploadModal = document.querySelector('#modals-container div[data-modal="entryPhoto"] section.modal.entryPhoto');
  7908. let fileInput, urlInput;
  7909. if (uploadModal)
  7910. {
  7911. fileInput = uploadModal.querySelector('form div.upload section.file div.upload input');
  7912. urlInput = uploadModal.querySelector('form div.field input[inputmode="url"]');
  7913. }
  7914.  
  7915. // W SCHOWKU BYŁ OBRAZEK
  7916. if (e.clipboardData.files.length > 0)
  7917. {
  7918. if (dev) console.log(e.clipboardData.files[0]);
  7919. let imageFile = e.clipboardData.files[0];
  7920. if (dev) console.log("imageFile (original)");
  7921. if (dev) console.log(imageFile);
  7922.  
  7923. // próba konwersji z WEBP na PNG
  7924. // if (imageFile.type == "image/webp") // image/gif // image/png // image/jpeg // image/webp
  7925. // {
  7926. // let reader = new FileReader();
  7927. // reader.onload = function (event)
  7928. // {
  7929. // let img = new Image();
  7930. // img.onload = function ()
  7931. // {
  7932. // let canvas = document.createElement('canvas');
  7933. // canvas.width = this.width;
  7934. // canvas.height = this.height;
  7935. // let ctx = canvas.getContext('2d');
  7936. // ctx.drawImage(this, 0, 0);
  7937. // canvas.toBlob(function (blob)
  7938. // {
  7939. // imageFile = new File([blob], "test.png", { type: "image/png" });
  7940. // if(dev) console.log(imageFile);
  7941. // }, 'image/png');
  7942. // };
  7943. // img.src = event.target.result;
  7944. // };
  7945. // reader.readAsDataURL(imageFile);
  7946. // }
  7947.  
  7948. if (imageFile.name === "image.png")
  7949. {
  7950. imageFile = new File([imageFile], "WykopX", { type: imageFile.type });
  7951. }
  7952.  
  7953. if (dev) console.log("imageFile");
  7954. if (dev) console.log(imageFile);
  7955.  
  7956. const bitmap = await createImageBitmap(imageFile)
  7957. let canvas = document.createElement('canvas');
  7958. canvas.width = bitmap.width;
  7959. canvas.height = bitmap.height;
  7960. canvas.style.width = "100%";
  7961. canvas.style.maxWidth = "400px";
  7962. canvas.classList.add("wxs_uploaded_image_preview", `wxs_uploaded_image_${imageFile.type.split("/")[1]}`); // class="wxs_uploaded_image_png", class="wxs_uploaded_image_jpeg"
  7963. canvas.title = `WykopX: Plik ${imageFile.type.split("/")[1].toUpperCase()} o wielkości ${imageFile.size < 1048576 ? bytesToKB(imageFile.size, 2) : bytesToMB(imageFile.size)} i rozmiarach ${bitmap.width} x ${bitmap.height}`
  7964.  
  7965.  
  7966. canvas.getContext('2d').drawImage(bitmap, 0, 0, bitmap.width, bitmap.height);
  7967. imageUploadPreview.appendChild(canvas);
  7968.  
  7969. if (dev) console.log("bitmap");
  7970. if (dev) console.log(bitmap);
  7971.  
  7972. if (!fileInput)
  7973. {
  7974. let fakeDropEvent = new DragEvent('drop');
  7975.  
  7976. Object.defineProperty(fakeDropEvent, 'dataTransfer',
  7977. {
  7978. value: {
  7979. files: [imageFile], // 'file' is the File object you want to drop
  7980. types: ['Files'],
  7981. effectAllowed: 'all',
  7982. dropEffect: 'move',
  7983. items: [
  7984. {
  7985. kind: 'file',
  7986. type: imageFile.type,
  7987. getAsFile: function () { return imageFile; }
  7988. }
  7989. ],
  7990. getData: function () { return ''; },
  7991. setData: function () { },
  7992. clearData: function () { },
  7993. setDragImage: function () { }
  7994. }
  7995. });
  7996.  
  7997. // Dispatch the fake drop event
  7998. sectionEditorElement.dispatchEvent(fakeDropEvent);
  7999. }
  8000. else
  8001. {
  8002.  
  8003. }
  8004. }
  8005. // wklejono tekst
  8006. else if (e.clipboardData.files.length == 0 && e.clipboardData.items.length > 0)
  8007. {
  8008. if (dev) console.log("e.clipboardData.items.length > 0");
  8009. let textPlainFromClipboard = e.clipboardData.getData('text/plain');
  8010. if (dev) console.log("Clipboard text/plain: " + textPlainFromClipboard);
  8011.  
  8012. let urlsArray = getURLsFromString(textPlainFromClipboard, true);
  8013. if (urlsArray && urlsArray.length > 0)
  8014. {
  8015. urlsArray.forEach((urlFromClipboard) =>
  8016. {
  8017.  
  8018. if (urlFromClipboard.endsWith(".webp"))
  8019. {
  8020.  
  8021. }
  8022.  
  8023.  
  8024. if (dev) console.log("probuje pobrać plik: " + urlFromClipboard);
  8025.  
  8026. let img = new Image();
  8027. img.src = urlFromClipboard;
  8028.  
  8029. img.onload = function ()
  8030. {
  8031. let canvas = document.createElement('canvas');
  8032. canvas.width = this.width;
  8033. canvas.height = this.height;
  8034. canvas.style.width = "100%";
  8035. let ctx = canvas.getContext('2d');
  8036. ctx.drawImage(this, 0, 0);
  8037. imageUploadPreview.appendChild(canvas);
  8038.  
  8039. /* CORS POLICY ERROR:
  8040. canvas.toBlob(function (blob)
  8041. {
  8042. let imageFile = new File([blob], "test.png", { type: "image/png" });
  8043. // You now have a PNG File object, 'newFile', with image data from the original WebP file
  8044. }, 'image/png'); */
  8045. };
  8046. // img.crossOrigin = 'anonymous'; CORS
  8047. });
  8048.  
  8049. // e.preventDefault();
  8050.  
  8051. }
  8052. else
  8053. {
  8054. // wklejono tekst bez okna modalnego (wiekszosc wypadkow)
  8055. }
  8056. }
  8057. });
  8058. }
  8059. // IMAGE UPLOADER END
  8060.  
  8061.  
  8062.  
  8063.  
  8064.  
  8065.  
  8066.  
  8067.  
  8068.  
  8069. /* ------------- EVENTS ------------ */
  8070.  
  8071. // LOADED PAGE
  8072. window.onload = function (event)
  8073. {
  8074. consoleX("windows.onload", 1)
  8075. loadTime = dayjs();
  8076. browserExecuteOnPageLoad();
  8077. browserExecuteOnPageLoadAndPageChange();
  8078. };
  8079.  
  8080.  
  8081. /* NEW WYKOP PAGE REDIRECTION */
  8082. if (window?.navigation != null) /* Firefox nadal tego nie obsluguje */
  8083. {
  8084. navigation.addEventListener("navigate", (event) =>
  8085. {
  8086. consoleX(`🎈 Event: "navigate"`)
  8087. loadTime = dayjs();
  8088. browserExecuteOnPageChange(event);
  8089. browserExecuteOnPageLoadAndPageChange();
  8090. });
  8091. }
  8092.  
  8093.  
  8094.  
  8095. function handleWindowEvent(event)
  8096. {
  8097. if (dev) console.log(`handleWindowEvent() -> event.type: ${event.type} was fired`);
  8098. // if(dev) console.log(event);
  8099. }
  8100. // window.addEventListener('load', handleWindowEvent); // 1.
  8101. // window.addEventListener('pageshow', handleWindowEvent); // 2.
  8102. // window.addEventListener('popstate', handleWindowEvent);
  8103. // window.addEventListener('hashchange', handleWindowEvent);
  8104. // window.addEventListener('pagehide', handleWindowEvent);
  8105. // window.addEventListener('beforeunload', handleWindowEvent);
  8106. // window.addEventListener('unload', handleWindowEvent);
  8107.  
  8108. /* events in Wykop podczas ladowania strony:
  8109. 1. window.addEventListener('load', callback); (Event) event.srcElement.URL > "https://wykop.pl/wpis/74180083/pytanie#comment-261404235"
  8110. 2. window.addEventListener('pageshow', callback); (PageTransitionEvent)
  8111. firefox:
  8112. - load, pageshow - OK
  8113. - brak wykrytych eventów podczas przechodzenia miedzy stronami
  8114. - brak obiektu window.navigator
  8115. przejscie na nowa strone, do innego #anchora po kliknieciu w permalink komentarza we wpisie
  8116. 3. navigation.addEventListener("navigate", callback) (NavigateEvent)
  8117. “popstate”: This event is fired when the active history entry changes, either by the user navigating to a different state, or by the code calling the history.pushState() or history.replaceState() methods. This event can be used to update the page content according to the new state.
  8118. “hashchange”: This event is fired when the fragment identifier of the URL (the part after the “#”) changes. This event can be used to implement single-page applications that use different hash values to load different views.
  8119. “pushstate”: This event is fired when the history.pushState() method is called, which adds a new state to the history stack. This event can be used to perform some actions when a new state is created.
  8120. “replacestate”: This event is fired when the history.replaceState() method is called, which modifies the current state in the history stack. This event can be used to perform some actions when the current state is changed.
  8121. */
  8122.  
  8123.  
  8124. // ---- PAGE OPENED 1st TIME
  8125. async function browserExecuteOnPageLoad()
  8126. {
  8127. // awariaSerwera();
  8128. // consoleX(`browserExecuteOnPageLoad`, 1);
  8129. if (isURLChanged()) newPageURL()
  8130.  
  8131. const loggedUserJSON = await getWykopAPIData("profile") // -> https://wykop.pl/api/v3/profile
  8132.  
  8133. loggedUser = loggedUserJSON.data;
  8134. //ser.username = user.data.username;
  8135.  
  8136. if (!(loggedUser?.username))
  8137. {
  8138. const topHeaderProfileButton = document.querySelector("body header > div.right > nav > ul > li.account a.avatar");
  8139. if (topHeaderProfileButton)
  8140. {
  8141. loggedUser.username = topHeaderProfileButton.getAttribute("href").split('/')[2];
  8142. }
  8143. }
  8144.  
  8145. if (loggedUser?.username)
  8146. {
  8147. if (settings.editorShowMyUsername)
  8148. {
  8149. bodySection.style.setProperty('--myUsername', `"${loggedUser.username}"`);
  8150. bodySection.style.setProperty('--myUsernameAs', `"jako ${loggedUser.username}"`);
  8151. bodySection.style.setProperty('--myUsernameAS', `"JAKO ${loggedUser.username}"`);
  8152. bodySection.style.setProperty('--myUsernameAddingAs', `"Dodajesz z konta ${loggedUser.username}"`);
  8153. }
  8154. // UŻYTKOWNIK MA BANA
  8155. if (loggedUser?.status && loggedUser.status == "banned")
  8156. {
  8157. settings.authorBlocksYouCheckingEnable = false; // BlockDetector off for banned user
  8158. settings.editorSendHotkey = "domyslnie";
  8159. settings.editorSendHotkeyShowOnSendButton = false;
  8160.  
  8161. body.dataset.userBanned = "true"; // <body data-user-banned="true">
  8162.  
  8163. if (settings.haveBanDisableTextarea)
  8164. {
  8165. // 🍌 Pokaż informację o banie w edytorze nowego wpisu/komentarza
  8166. bodySection.style.setProperty('--myUsernameAddingAs', `"🍌 ${loggedUser.username}, masz bana. Nie możesz dodawać wpisów i komentarzy"`);
  8167. }
  8168. }
  8169. }
  8170. else
  8171. {
  8172. // niezalogowany
  8173. }
  8174.  
  8175.  
  8176. // if (loggedUser.username == null) consoleX(`Cześć Anon.Nie jesteś zalogowany na Wykopie(⌐ ͡■ ͜ʖ ͡■)`);
  8177. // else consoleX(`Cześć ${ loggedUser.username }(⌐ ͡■ ͜ʖ ͡■)`);
  8178.  
  8179. focusOnAddingNewMicroblogEntry();
  8180. addWykopXButtonsToNavBar();
  8181.  
  8182. if (settings.wxsSwitchesEnable)
  8183. {
  8184. runWithDelay(200, function ()
  8185. {
  8186. addSwitchButtons();
  8187. });
  8188. }
  8189. if (settings.observedTagsInRightSidebarEnable)
  8190. {
  8191. runWithDelay(500, function ()
  8192. {
  8193. addObservedTagsToRightSidebar();
  8194. });
  8195. }
  8196.  
  8197. runWithDelay(400, function ()
  8198. {
  8199. addExtraButtons();
  8200. });
  8201.  
  8202. // 8s
  8203. runWithDelay(8000, function ()
  8204. {
  8205. if (settings.topNavNightSwitchButton) addNightModeButtonToNavBar();
  8206. hideWykopXSPromo();
  8207. topNavLogoClick();
  8208. topNavHomeButtonClickRefreshOrRedirect();
  8209. addNotificationSummaryButtonToNavBar();
  8210. topNavMicroblogButtonClickRefreshOrRedirect();
  8211. });
  8212.  
  8213.  
  8214. if (settings.notatkowatorEnable)
  8215. {
  8216. runWithDelay(17000, function ()
  8217. {
  8218. createMenuItemForNotatkowator();
  8219. });
  8220. }
  8221. if (settings.mirkoukrywaczEnable)
  8222. {
  8223. runWithDelay(17000, function ()
  8224. {
  8225. createMenuItemForMirkoukrywacz();
  8226. });
  8227. }
  8228.  
  8229. // 20s
  8230. //runWithDelay(25000, function ()
  8231. runWithDelay(1000, function ()
  8232. {
  8233. checkVersionForUpdates();
  8234. createProfileDropdownMenuItem(
  8235. {
  8236. text: `Pomoc: Wykop X`,
  8237. title: "Otwórz stronę Wiki z informacjami o dodatku Wykop X",
  8238. className: `wykopx_wiki`,
  8239. id: undefined,
  8240. url: "http://wiki.wykopx.pl/",
  8241. target: "wykopx",
  8242. icon: null,
  8243. number: null
  8244. });
  8245.  
  8246. addWykopXPromoBanner();
  8247. });
  8248.  
  8249. runWithDelay(30000, async function ()
  8250. {
  8251. if (loggedUser?.username)
  8252. {
  8253. try
  8254. {
  8255. let settings_list_update = await localStorageObserved.getItem("settings_list_update");
  8256. if (settings_list_update == null)
  8257. {
  8258. POSTDATATOWYKOPX();
  8259. }
  8260. else
  8261. {
  8262. if (loadTime.diff(dayjs(settings_list_update), "days") > 1)
  8263. {
  8264. POSTDATATOWYKOPX();
  8265. }
  8266. else
  8267. {
  8268. return true;
  8269. }
  8270. }
  8271. }
  8272. catch (err)
  8273. {
  8274. if (dev) console.log(err);
  8275. }
  8276. }
  8277. });
  8278.  
  8279. if (settings.wxsArchiveXNewestEntry)
  8280. {
  8281. addNewestEntryTopNavButton();
  8282. archiveXNewestEntry();
  8283. }
  8284. }
  8285. // ----- PAGE NAVIGATION
  8286. async function browserExecuteOnPageChange(event)
  8287. {
  8288. consoleX(`browserExecuteOnPageChange() -> navigation -> navigate event ${event.type}`, 1);
  8289. consoleX(`browserExecuteOnPageChange() -> document.title: ${document.title}`, 1);
  8290. // if(dev) console.log(event);
  8291.  
  8292. pageTabTitleOriginal = document.title;
  8293. pageTabTitleProcessed = pageTabTitleOriginal;
  8294.  
  8295. //visiblePlusesObserver.disconnect();
  8296. //if (sectionObjectIntersectionObserver) sectionObjectIntersectionObserver.disconnect();
  8297. //if (settings.actionBoxEnable && (settings.filterUserComments || settings.filterUserReplies)) filterUserOff(); // usuniecie filtra komentarzy
  8298.  
  8299. runWithDelay(500, function ()
  8300. {
  8301. if (isURLChanged())
  8302. {
  8303. const previousPageSubtype = pageSubtype;
  8304. newPageURL();
  8305. if (pageSubtype == previousPageSubtype) removeAllDataWXSAttributes();
  8306. }
  8307. });
  8308.  
  8309. // 7s
  8310. if (!settings.tabChangeOnlyOnHiddenState) runWithDelay(7000, () => { executeTabAndFaviconChanges() })
  8311. }
  8312. // ---- PAGE OPENED 1st TIME + PAGE NAVIGATION
  8313. async function browserExecuteOnPageLoadAndPageChange()
  8314. {
  8315. consoleX(`browserExecuteOnPageLoadAndPageChange()`, 1);
  8316.  
  8317. runWithDelay(100, function ()
  8318. {
  8319. countNumberOfNotificationsOnDesktop();
  8320. });
  8321.  
  8322. if (settings.mirkoukrywaczEnable)
  8323. {
  8324. runWithDelay(3000, function ()
  8325. {
  8326. mirkoukrywaczHideAllBlockedElements(); // ukrycie elementow blokowanych przez Mirkowolacz oraz actionBox
  8327. });
  8328. }
  8329.  
  8330. if (pageType == "tag" && settings.tagHeaderEditable)
  8331. {
  8332. runWithDelay(2200, function ()
  8333. {
  8334. tagHeaderEditableWatcher();
  8335. })
  8336. }
  8337.  
  8338. if (pageType == "profil") // info o blokadzie
  8339. {
  8340. // runWithDelay(100, function ()
  8341. // {
  8342.  
  8343. // })
  8344. }
  8345.  
  8346. if (settings.autoOpenMoreContentEverywhere)
  8347. {
  8348. runWithDelay(6000, function ()
  8349. {
  8350. autoOpenMoreContentEverywhere();
  8351. })
  8352. }
  8353.  
  8354.  
  8355. // 10s
  8356. if (settings.autoOpenSpoilersEverywhere)
  8357. {
  8358. runWithDelay(10000, function ()
  8359. {
  8360. autoOpenSpoilersEverywhere();
  8361. });
  8362. }
  8363.  
  8364. if (settings.removeAnnoyancesEnable)
  8365. {
  8366. runWithDelay(18000, function ()
  8367. {
  8368. if (settings.removeAnnoyancesIframes) waitForKeyElements(`html > iframe, html > body > iframe`, removeFromDOM, false);
  8369. if (settings.removeAnnoyancesScripts) waitForKeyElements(`html > head > script[src^="https://"]`, removeFromDOM, false);
  8370. })
  8371.  
  8372. runWithDelay(3000, function ()
  8373. {
  8374. removeAnnoyances()
  8375. })
  8376. }
  8377.  
  8378. // waitForKeyElements("main.main > section > div.content section.stream > header.stream-top", buildConsole, false)
  8379. // buildConsole();
  8380. // refreshConsole();
  8381. }
  8382.  
  8383.  
  8384.  
  8385.  
  8386.  
  8387.  
  8388.  
  8389.  
  8390.  
  8391.  
  8392.  
  8393.  
  8394.  
  8395.  
  8396. // async function awariaSerwera()
  8397. // {
  8398. // let awaria = document.querySelector(`body > section > footer > a[onclick="window.location.href = reloadURL"`);
  8399. // if (awaria) alert("AWARIA");
  8400. // }
  8401.  
  8402. // XHR BLOCKER
  8403.  
  8404.  
  8405.  
  8406. // Wykop XS-XHR Blocker
  8407. // https://greasyfork.org/en/scripts/486722-wykop-xs-xhr-blocker
  8408. setSettingsValueFromCSSProperty("wxsBlockXHREnable");
  8409. if (settings.wxsBlockXHREnable)
  8410. {
  8411. setSettingsValueFromCSSProperty("wxsBlockXHRExternal");
  8412. setSettingsValueFromCSSProperty("wxsBlockXHRInternalAds");
  8413. setSettingsValueFromCSSProperty("wxsBlockXHRConsoleLogAllowed", false);
  8414. setSettingsValueFromCSSProperty("wxsBlockXHRConsoleLogBlocked", false);
  8415. setSettingsValueFromCSSProperty("rightSidebarHidePopularTags", false);
  8416. setSettingsValueFromCSSProperty("rightSidebarHideRelatedTags", false);
  8417. setSettingsValueFromCSSProperty("rightSidebarHideHits", false);
  8418. setSettingsValueFromCSSProperty("rightSidebarHideEntriesHot", false);
  8419. setSettingsValueFromCSSProperty("rightSidebarHideEntriesActive", false);
  8420. setSettingsValueFromCSSProperty("rightSidebarHideEntriesPopular", false);
  8421. setSettingsValueFromCSSProperty("rightSidebarHideUpcomingActive", false);
  8422. setSettingsValueFromCSSProperty("rightSidebarHideLinksNewest", false);
  8423. setSettingsValueFromCSSProperty("rightSidebarHideLinksActive", false);
  8424. setSettingsValueFromCSSProperty("rightSidebarHideLinksPopular", false);
  8425. }
  8426.  
  8427. let xhook = null;
  8428. if (settings.infiniteScrollEntriesEnabled || settings.infiniteScrollLinksEnabled || settings.wxsBlockXHREnable)
  8429. {
  8430. //XHook-v1.6.2-https://github.com/jpillora/xhook
  8431. //Jaime Pillora <dev@jpillora.com>-MIT Copyright 2023
  8432. xhook = function () { "use strict"; const e = (e, t) => Array.prototype.slice.call(e, t); let t = null; "undefined" != typeof WorkerGlobalScope && self instanceof WorkerGlobalScope ? t = self : "undefined" != typeof global ? t = global : window && (t = window); const n = t, o = t.document, r = ["load", "loadend", "loadstart"], s = ["progress", "abort", "error", "timeout"], a = e => ["returnValue", "totalSize", "position"].includes(e), i = function (e, t) { for (let n in e) { if (a(n)) continue; const o = e[n]; try { t[n] = o } catch (e) { } } return t }, c = function (e, t, n) { const o = e => function (o) { const r = {}; for (let e in o) { if (a(e)) continue; const s = o[e]; r[e] = s === t ? n : s } return n.dispatchEvent(e, r) }; for (let r of Array.from(e)) n._has(r) && (t[`on${r}`] = o(r)) }, u = function (e) { if (o && null != o.createEventObject) { const t = o.createEventObject(); return t.type = e, t } try { return new Event(e) } catch (t) { return { type: e } } }, l = function (t) { let n = {}; const o = e => n[e] || [], r = { addEventListener: function (e, t, r) { n[e] = o(e), n[e].indexOf(t) >= 0 || (r = void 0 === r ? n[e].length : r, n[e].splice(r, 0, t)) }, removeEventListener: function (e, t) { if (void 0 === e) return void (n = {}); void 0 === t && (n[e] = []); const r = o(e).indexOf(t); -1 !== r && o(e).splice(r, 1) }, dispatchEvent: function () { const n = e(arguments), s = n.shift(); t || (n[0] = i(n[0], u(s)), Object.defineProperty(n[0], "target", { writable: !1, value: this })); const a = r[`on${s}`]; a && a.apply(r, n); const c = o(s).concat(o("*")); for (let e = 0; e < c.length; e++) { c[e].apply(r, n) } }, _has: e => !(!n[e] && !r[`on${e}`]) }; return t && (r.listeners = t => e(o(t)), r.on = r.addEventListener, r.off = r.removeEventListener, r.fire = r.dispatchEvent, r.once = function (e, t) { var n = function () { return r.off(e, n), t.apply(null, arguments) }; return r.on(e, n) }, r.destroy = () => n = {}), r }; var f = function (e, t) { switch (typeof e) { case "object": return n = e, Object.entries(n).map((([e, t]) => `${e.toLowerCase()}: ${t}`)).join("\r\n"); case "string": return function (e, t) { const n = e.split("\r\n"); null == t && (t = {}); for (let e of n) if (/([^:]+):\s*(.+)/.test(e)) { const e = null != RegExp.$1 ? RegExp.$1.toLowerCase() : void 0, n = RegExp.$2; null == t[e] && (t[e] = n) } return t }(e, t) }var n; return [] }; const d = l(!0), p = e => void 0 === e ? null : e, h = n.XMLHttpRequest, y = function () { const e = new h, t = {}; let n, o, a, u = null; var y = 0; const v = function () { if (a.status = u || e.status, -1 !== u && (a.statusText = e.statusText), -1 === u); else { const t = f(e.getAllResponseHeaders()); for (let e in t) { const n = t[e]; if (!a.headers[e]) { const t = e.toLowerCase(); a.headers[t] = n } } } }, b = function () { x.status = a.status, x.statusText = a.statusText }, g = function () { n || x.dispatchEvent("load", {}), x.dispatchEvent("loadend", {}), n && (x.readyState = 0) }, E = function (e) { for (; e > y && y < 4;)x.readyState = ++y, 1 === y && x.dispatchEvent("loadstart", {}), 2 === y && b(), 4 === y && (b(), "text" in a && (x.responseText = a.text), "xml" in a && (x.responseXML = a.xml), "data" in a && (x.response = a.data), "finalUrl" in a && (x.responseURL = a.finalUrl)), x.dispatchEvent("readystatechange", {}), 4 === y && (!1 === t.async ? g() : setTimeout(g, 0)) }, m = function (e) { if (4 !== e) return void E(e); const n = d.listeners("after"); var o = function () { if (n.length > 0) { const e = n.shift(); 2 === e.length ? (e(t, a), o()) : 3 === e.length && t.async ? e(t, a, o) : o() } else E(4) }; o() }; var x = l(); t.xhr = x, e.onreadystatechange = function (t) { try { 2 === e.readyState && v() } catch (e) { } 4 === e.readyState && (o = !1, v(), function () { if (e.responseType && "text" !== e.responseType) "document" === e.responseType ? (a.xml = e.responseXML, a.data = e.responseXML) : a.data = e.response; else { a.text = e.responseText, a.data = e.responseText; try { a.xml = e.responseXML } catch (e) { } } "responseURL" in e && (a.finalUrl = e.responseURL) }()), m(e.readyState) }; const w = function () { n = !0 }; x.addEventListener("error", w), x.addEventListener("timeout", w), x.addEventListener("abort", w), x.addEventListener("progress", (function (t) { y < 3 ? m(3) : e.readyState <= 3 && x.dispatchEvent("readystatechange", {}) })), "withCredentials" in e && (x.withCredentials = !1), x.status = 0; for (let e of Array.from(s.concat(r))) x[`on${e}`] = null; if (x.open = function (e, r, s, i, c) { y = 0, n = !1, o = !1, t.headers = {}, t.headerNames = {}, t.status = 0, t.method = e, t.url = r, t.async = !1 !== s, t.user = i, t.pass = c, a = {}, a.headers = {}, m(1) }, x.send = function (n) { let u, l; for (u of ["type", "timeout", "withCredentials"]) l = "type" === u ? "responseType" : u, l in x && (t[u] = x[l]); t.body = n; const f = d.listeners("before"); var p = function () { if (!f.length) return function () { for (u of (c(s, e, x), x.upload && c(s.concat(r), e.upload, x.upload), o = !0, e.open(t.method, t.url, t.async, t.user, t.pass), ["type", "timeout", "withCredentials"])) l = "type" === u ? "responseType" : u, u in t && (e[l] = t[u]); for (let n in t.headers) { const o = t.headers[n]; n && e.setRequestHeader(n, o) } e.send(t.body) }(); const n = function (e) { if ("object" == typeof e && ("number" == typeof e.status || "number" == typeof a.status)) return i(e, a), "data" in e || (e.data = e.response || e.text), void m(4); p() }; n.head = function (e) { i(e, a), m(2) }, n.progress = function (e) { i(e, a), m(3) }; const d = f.shift(); 1 === d.length ? n(d(t)) : 2 === d.length && t.async ? d(t, n) : n() }; p() }, x.abort = function () { u = -1, o ? e.abort() : x.dispatchEvent("abort", {}) }, x.setRequestHeader = function (e, n) { const o = null != e ? e.toLowerCase() : void 0, r = t.headerNames[o] = t.headerNames[o] || e; t.headers[r] && (n = t.headers[r] + ", " + n), t.headers[r] = n }, x.getResponseHeader = e => p(a.headers[e ? e.toLowerCase() : void 0]), x.getAllResponseHeaders = () => p(f(a.headers)), e.overrideMimeType && (x.overrideMimeType = function () { e.overrideMimeType.apply(e, arguments) }), e.upload) { let e = l(); x.upload = e, t.upload = e } return x.UNSENT = 0, x.OPENED = 1, x.HEADERS_RECEIVED = 2, x.LOADING = 3, x.DONE = 4, x.response = "", x.responseText = "", x.responseXML = null, x.readyState = 0, x.statusText = "", x }; y.UNSENT = 0, y.OPENED = 1, y.HEADERS_RECEIVED = 2, y.LOADING = 3, y.DONE = 4; var v = { patch() { h && (n.XMLHttpRequest = y) }, unpatch() { h && (n.XMLHttpRequest = h) }, Native: h, Xhook: y }; function b(e, t, n, o) { return new (n || (n = Promise))((function (r, s) { function a(e) { try { c(o.next(e)) } catch (e) { s(e) } } function i(e) { try { c(o.throw(e)) } catch (e) { s(e) } } function c(e) { var t; e.done ? r(e.value) : (t = e.value, t instanceof n ? t : new n((function (e) { e(t) }))).then(a, i) } c((o = o.apply(e, t || [])).next()) })) } const g = n.fetch; function E(e) { return e instanceof Headers ? m([...e.entries()]) : Array.isArray(e) ? m(e) : e } function m(e) { return e.reduce(((e, [t, n]) => (e[t] = n, e)), {}) } const x = function (e, t = { headers: {} }) { let n = Object.assign(Object.assign({}, t), { isFetch: !0 }); if (e instanceof Request) { const o = function (e) { let t = {}; return ["method", "headers", "body", "mode", "credentials", "cache", "redirect", "referrer", "referrerPolicy", "integrity", "keepalive", "signal", "url"].forEach((n => t[n] = e[n])), t }(e), r = Object.assign(Object.assign({}, E(o.headers)), E(n.headers)); n = Object.assign(Object.assign(Object.assign({}, o), t), { headers: r, acceptedRequest: !0 }) } else n.url = e; const o = d.listeners("before"), r = d.listeners("after"); return new Promise((function (t, s) { let a = t; const i = function (e) { if (!r.length) return a(e); const t = r.shift(); return 2 === t.length ? (t(n, e), i(e)) : 3 === t.length ? t(n, e, i) : i(e) }, c = function (e) { if (void 0 !== e) { const n = new Response(e.body || e.text, e); return t(n), void i(n) } u() }, u = function () { if (!o.length) return void l(); const e = o.shift(); return 1 === e.length ? c(e(n)) : 2 === e.length ? e(n, c) : void 0 }, l = () => b(this, void 0, void 0, (function* () { const { url: t, isFetch: o, acceptedRequest: r } = n, c = function (e, t) { var n = {}; for (var o in e) Object.prototype.hasOwnProperty.call(e, o) && t.indexOf(o) < 0 && (n[o] = e[o]); if (null != e && "function" == typeof Object.getOwnPropertySymbols) { var r = 0; for (o = Object.getOwnPropertySymbols(e); r < o.length; r++)t.indexOf(o[r]) < 0 && Object.prototype.propertyIsEnumerable.call(e, o[r]) && (n[o[r]] = e[o[r]]) } return n }(n, ["url", "isFetch", "acceptedRequest"]); return e instanceof Request && c.body instanceof ReadableStream && (c.body = yield new Response(c.body).text()), g(t, c).then((e => i(e))).catch((function (e) { return a = s, i(e), s(e) })) })); u() })) }; var w = { patch() { g && (n.fetch = x) }, unpatch() { g && (n.fetch = g) }, Native: g, Xhook: x }; const O = d; return O.EventEmitter = l, O.before = function (e, t) { if (e.length < 1 || e.length > 2) throw "invalid hook"; return O.on("before", e, t) }, O.after = function (e, t) { if (e.length < 2 || e.length > 3) throw "invalid hook"; return O.on("after", e, t) }, O.enable = function () { v.patch(), w.patch() }, O.disable = function () { v.unpatch(), w.unpatch() }, O.XMLHttpRequest = v.Native, O.fetch = w.Native, O.headers = f, O.enable(), O }();
  8433. }
  8434.  
  8435.  
  8436. if (xhook != null && settings.wxsBlockXHREnable)
  8437. {
  8438. if (!dev) dev = wykopxSettings.getPropertyValue("--wxsDev") ? wykopxSettings.getPropertyValue("--wxsDev") === '1' : false;
  8439.  
  8440. const allowed = ['https://wykop.pl/api/', 'https://raw.githubusercontent.com/wykopx/', 'wykopx.pl']; // allowed.push();
  8441. if (settings.wxsBlockXHRExternal)
  8442. {
  8443.  
  8444. }
  8445.  
  8446. const prohibited = [];
  8447. if (settings.wxsBlockXHRInternalAds) prohibited.push("https://wykop.pl/api/v3/ads");
  8448.  
  8449. if (settings.rightSidebarHidePopularTags) prohibited.push("https://wykop.pl/api/v3/tags/popular?sidebar=true");
  8450. if (settings.rightSidebarHideRelatedTags) prohibited.push("/related?sidebar=true");
  8451.  
  8452. //if (settings.rightSidebarHideEntriesHot) prohibited.push("https://wykop.pl/api/v3/entries?sort=hot&last_update=6");
  8453. if (settings.rightSidebarHideEntriesActive) prohibited.push("https://wykop.pl/api/v3/entries?sort=active&sidebar=true");
  8454. if (settings.rightSidebarHideEntriesPopular) prohibited.push("https://wykop.pl/api/v3/entries?sort=hot&last_update=12&sidebar=true");
  8455. if (settings.rightSidebarHideUpcomingActive) prohibited.push("https://wykop.pl/api/v3/links?type=upcoming&sort=active&sidebar=true");
  8456. if (settings.rightSidebarHideHits) prohibited.push("https://wykop.pl/api/v3/hits/links?sort=day&sidebar=true");
  8457. if (settings.rightSidebarHideLinksNewest) prohibited.push("&sort=newest&sidebar=true");
  8458. if (settings.rightSidebarHideLinksActive) prohibited.push("&sort=active&sidebar=true");
  8459. // if (settings.rightSidebarHideLinksPopular) prohibited.push(""); // popularne w kategorii https://wykop.pl/api/v3/search/links?sort=popular&category=rozrywka&date_from=2024-02-16+24:30:06&sidebar=true
  8460.  
  8461. // https://wykop.pl/api/v3/entries?sort=active&sidebar=true
  8462. // https://wykop.pl/api/v3/entries?sort=hot&last_update=24&sidebar=true
  8463. // https://wykop.pl/api/v3/entries?sort=hot&last_update=12&sidebar=true
  8464.  
  8465.  
  8466. // https://wykop.pl/api/v3/hits/links?sort=day&sidebar=true
  8467. // https://wykop.pl/api/v3/hits/links?sort=week&sidebar=true
  8468.  
  8469. // https://wykop.pl/api/v3/links?type=homepage&sort=newest&sidebar=true
  8470. // https://wykop.pl/api/v3/links?type=upcoming&sort=newest&sidebar=true
  8471. // https://wykop.pl/api/v3/links?type=upcoming&sort=active&sidebar=true
  8472. // https://wykop.pl/api/v3/links?type=homepage&sort=active&sidebar=true
  8473. // https://wykop.pl/api/v3/links/stats/upcoming
  8474.  
  8475.  
  8476. // https://wykop.pl/api/v3/search/links?sort=popular&bucket=17c344d6871fcac52893&sidebar=true
  8477. // https://wykop.pl/api/v3/search/entries?sort=popular&bucket=17c344d6871fcac52893&sidebar=true
  8478. // https://wykop.pl/api/v3/search/links?sort=popular&category=rozrywka&date_from=2024-02-16+24:30:06&sidebar=true
  8479.  
  8480. // https://wykop.pl/api/v3/tags/polska/related?sidebar=true
  8481. // https://wykop.pl/api/v3/tags/popular?sidebar=true
  8482.  
  8483. // https://wykop.pl/api/v3/buckets/status
  8484. // https://wykop.pl/api/v3/notifications/status
  8485. // https://wykop.pl/api/v3/notifications/tags?page=1
  8486. // https://wykop.pl/api/v3/notifications/entries?page=1
  8487. // https://wykop.pl/api/v3/pm/conversations
  8488.  
  8489. xhook.before((request, callback) =>
  8490. {
  8491. if (allowed.some(str => request.url.includes(str)) && !prohibited.some(str => request.url.includes(str)))
  8492. {
  8493. if (settings.wxsBlockXHRConsoleLogAllowed) console.log("Wykop XS: XHR Blocker | XHR: 🌍 " + request.url);
  8494. callback();
  8495. }
  8496. else
  8497. {
  8498. if (settings.wxsBlockXHRConsoleLogBlocked) console.log("Wykop XS: XHR Blocker | XHR: ⛔ " + request.url + " (BLOCKED)");
  8499. }
  8500. });
  8501. }
  8502.  
  8503. if (xhook != null && (settings.infiniteScrollEntriesEnabled || settings.infiniteScrollLinksEnabled))
  8504. {
  8505. xhook.after((request, response) =>
  8506. {
  8507. // if(dev) console.log("✔ xhook.after-request: " + request.url);
  8508. // if(dev) console.log(request);
  8509. // if(dev) console.log("✔ xhook.after-response");
  8510. // if(dev) console.log(response);
  8511.  
  8512. if (response.status == 200 && request.url.endsWith("page=1"))
  8513. {
  8514. // if(dev) console.log("request.url.endsWith(page = 1)")
  8515. if ((settings.infiniteScrollEntriesEnabled && pageType == "wpis") || (settings.infiniteScrollLinksEnabled && pageType == "znalezisko"))
  8516. {
  8517. let url = null;
  8518.  
  8519. try
  8520. {
  8521. url = new URL(request.url);
  8522. }
  8523. catch
  8524. {
  8525. return
  8526. }
  8527.  
  8528. // if(dev) console.log("xhook.after-request.url");
  8529. // if(dev) console.log(request.url);
  8530. // if(dev) console.log(url);
  8531.  
  8532. //if (url.host == "wykop.pl")
  8533. if (1)
  8534. {
  8535. let searchParams = new URLSearchParams(url.searchParams)
  8536.  
  8537. // if(dev) console.log("✔ xhook.after-url.href");
  8538. // if(dev) console.log(url.href);
  8539. // if(dev) console.log("✔ xhook.after-searchParams");
  8540. // if(dev) console.log(searchParams);
  8541. // if(dev) console.log(`✔ xhook.after-${url.href} searchParams.has('page'): ` + searchParams.has('page'))
  8542. // if(dev) console.log(`✔ xhook.after-${url.href} searchParams.get('page'): ` + searchParams.get('page'))
  8543.  
  8544. if (searchParams.has('page') && searchParams.get('page') == 1)
  8545. {
  8546. // if(dev) console.log("✔ xhook.after-INFINITE SCROLL");
  8547.  
  8548. let regex = /\/api\/v3\/entries\/\d+\/comments$/;
  8549. if (pageType == "znalezisko") regex = /\/api\/v3\/links\/\d+\/comments$/;
  8550.  
  8551. // if(dev) console.log("url.pathname");
  8552. // if(dev) console.log(url.pathname);
  8553.  
  8554. if (regex.test(url.pathname))
  8555. {
  8556. let json = JSON.parse(response.text)
  8557. // if(dev) console.log("json")
  8558. // if(dev) console.log(json)
  8559.  
  8560. for (let page = 2; page <= Math.ceil(json['pagination']['total'] / json['pagination']['per_page']); ++page)
  8561. {
  8562. searchParams.set('page', page.toString())
  8563.  
  8564. let req = new XMLHttpRequest();
  8565. req.open('GET', `${url.pathname} ? ${searchParams.toString()}`, false)
  8566.  
  8567. for (let key of Object.keys(request.headers))
  8568. {
  8569. req.setRequestHeader(key, request.headers[key])
  8570. }
  8571.  
  8572. req.send(null)
  8573.  
  8574. if (req.status !== 200)
  8575. {
  8576. break
  8577. }
  8578.  
  8579. let data = JSON.parse(req.responseText)['data']
  8580. if (data.length === 0)
  8581. {
  8582. break
  8583. }
  8584.  
  8585. json['data'] = json['data'].concat(data)
  8586. }
  8587.  
  8588. // Hide pagination
  8589. json['pagination']['total'] = 0
  8590.  
  8591. // Override response text
  8592. response.text = JSON.stringify(json)
  8593. }
  8594. }
  8595. }
  8596. }
  8597. }
  8598. });
  8599. }
  8600.  
  8601.  
  8602.  
  8603.  
  8604.  
  8605.  
  8606.  
  8607.  
  8608.  
  8609.  
  8610.  
  8611.  
  8612.  
  8613.  
  8614.  
  8615. // USUWANIE NATARCZYWYCH IFRAME, REKLAM I GDPR
  8616. function removeAnnoyances()
  8617. {
  8618. consoleX("removeAnnoyances()", 1)
  8619.  
  8620. if (settings.removeAnnoyancesIframes)
  8621. {
  8622. document.querySelectorAll("html > iframe, html > body > iframe").forEach((el) =>
  8623. {
  8624. removeFromDOM(el)
  8625. });
  8626. }
  8627.  
  8628. if (settings.removeAnnoyancesAds)
  8629. {
  8630.  
  8631. /* removing .pub-slot-wrapper without .top .sidebar-1 oraz .screening - causes Node not found error when loading further pages */
  8632. /* .pub.slot-wrapper classes: .stream-bottom`.stream-1 .stream-2 .stream-3 .stream-4 .stream-5 .stream-6 .stream-7 .stream-8 .market-1 .sidebar-2 .sidebar-3 .sponsored-1 .sponsored-2 */
  8633.  
  8634. /* removing .pub-slot-wrapper without .top oraz .screening - causes Node not found error when loading further pages */
  8635. document.querySelectorAll(`.pub-slot-wrapper:not(.sidebar-1):not(.screening):not(.top):not(:has(section.premium-pub.link-block))`).forEach((el) =>
  8636. {
  8637. if (dev) console.log(`🧧 removeAnnoyancesAds - `, el)
  8638. consoleData.annoyances.ads.count++;
  8639. removeFromDOM(el);
  8640. });
  8641. }
  8642.  
  8643. if (settings.removeAnnoyancesGDPR)
  8644. {
  8645. document.querySelectorAll(`div[class^="app_gdpr"]`).forEach((el) =>
  8646. {
  8647. document.querySelector("body").style = "overflow: initial!important;";
  8648. consoleData.annoyances.other.count++;
  8649. removeFromDOM(el);
  8650. });
  8651. }
  8652.  
  8653. if (settings.removeAnnoyancesScripts)
  8654. {
  8655. document.querySelectorAll(`html > head > script[src^="https://"]`).forEach((el) =>
  8656. {
  8657. removeFromDOM(el);
  8658. });
  8659. document.querySelectorAll(`html > head > script[src^="//"]`).forEach((el) =>
  8660. {
  8661. removeFromDOM(el);
  8662. });
  8663. }
  8664.  
  8665. }
  8666.  
  8667.  
  8668.  
  8669.  
  8670. function removeFromDOM(Node)
  8671. {
  8672. if (Node)
  8673. {
  8674. consoleX(`removeFromDOM()`, 1);
  8675.  
  8676. if (Node instanceof Element)
  8677. {
  8678. consoleX("removeFromDOM(): REMOVING DOM Node", 1);
  8679. // if(dev) console.log(Node)
  8680. let nodeName = Node.nodeName;
  8681. nodeName = nodeName.toLowerCase()
  8682. // if(dev) console.log("nodeName:" + nodeName)
  8683. if (!consoleData.annoyances[nodeName])
  8684. {
  8685. consoleData.annoyances[nodeName] = { count: 0 };
  8686. }
  8687. consoleData.annoyances[nodeName].count++;
  8688. Node.remove();
  8689. }
  8690.  
  8691. consoleData.annoyances.count++;
  8692. // if(dev) console.log("removeFromDOM(): REMOVED TOTAL: ", consoleData.annoyances.count)
  8693. // if(dev) console.log("removeFromDOM(): consoleData:");
  8694. // if(dev) console.log(consoleData);
  8695.  
  8696. refreshConsole();
  8697. }
  8698. }
  8699.  
  8700.  
  8701.  
  8702.  
  8703.  
  8704.  
  8705. /* CSS STYLES */
  8706. CSS += `
  8707. body small { font-size: 0.8em; line-height: 0.9em; }
  8708. .hidden { display: none!important; }
  8709.  
  8710. section.editor>header>ul>li>i, /* napisy przy ikonkach edytora */
  8711. aside.profile-top>section>header>ul li, /* ikonki "Zgłoś", "Zablokuj" */
  8712. aside.profile-top>section>header>ul li a, /* ikonka "Napisz do użytkownika"*/
  8713. section.editor div.enter label, /* przycisk wysyłania enterem */
  8714. aside.tag-top aside ul > li.edit > a, /* edycja tagu autorskiego */
  8715. section.popper > section.tooltip > footer > ul.icons > li, /* ikonki w menu kontekstowym */
  8716. section.popper > section.tooltip > footer > ul.icons > li > a, /* ikonki w menu kontekstowym */
  8717. section.link-page > section.link > section.link-block > section > article > section.actions > ul > li > ul > li > a /* action menu znaleziska nadpisane przez a, span { font-size: 14px; } */
  8718. {
  8719. font-size: 0;
  8720. }
  8721.  
  8722.  
  8723.  
  8724. aside.profile-top > section > header > div h1 /* nazwa nicku na profilu */
  8725. {
  8726. display: flex;
  8727. align-items: center;
  8728. }
  8729. `;
  8730.  
  8731. if (settings.editorSendHotkey != "domyslnie")
  8732. {
  8733. if (settings.editorSendHotkeyShowOnSendButton)
  8734. {
  8735. CSS += `
  8736. section.editor > footer > div.buttons > div.button.send > button.target
  8737. {
  8738. display: flex;
  8739. flex-wrap: nowrap;
  8740. flex-direction: row;
  8741. column-gap: 4px;
  8742. text-transform: capitalize;
  8743. }
  8744. section.editor > footer > div.buttons > div.button.send > button.target::before
  8745. {
  8746. content: var(--editorSendHotkey);
  8747. text-transform: initial;
  8748. border-right: 1px solid var(--gullGray);
  8749. padding-right: 4px;
  8750. }`;
  8751. }
  8752. }
  8753.  
  8754. if (settings.imageUploaderEnable)
  8755. {
  8756. CSS += `
  8757. /* IMAGE UPLOADER */
  8758. section.editor figure.wxs_uploaded_image_placeholder
  8759. {
  8760. display: flex;
  8761. position: relative;
  8762. }
  8763. section.editor div.wxs_uploader_caption > span
  8764. {
  8765. display: none;
  8766. font-size: 15px;
  8767. color: var(--gullGray);
  8768. text-transform: initial;
  8769. position: relative;
  8770. margin-top: 15px;
  8771. padding-top: 15px;
  8772. margin-bottom: 15px;
  8773. border-top: 1px dotted rgba(120, 120, 120, 0.3);
  8774. }
  8775. section.editor:has(aside li.photo) div.wxs_uploader_caption > span.wxs_upload_and_replace_current_image,
  8776. section.editor:not(:has(aside li.photo)) div.wxs_uploader_caption > span.wxs_upload_first_image
  8777. {
  8778. display: flex;
  8779. }
  8780. section.editor figure.wxs_uploaded_image_placeholder:has(canvas)
  8781. {
  8782. margin: 20px 0px;
  8783. border-radius: 4px!important;
  8784. display: flex;
  8785. flex-direction: row-reverse;
  8786. flex-wrap: wrap-reverse;
  8787. justify-content: start;
  8788. align-content: start;
  8789. gap: 10px;
  8790. }
  8791. section.editor figure.wxs_uploaded_image_placeholder > canvas
  8792. {
  8793. display: none;
  8794. }
  8795. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder > canvas
  8796. {
  8797. display: flex;
  8798. max-width: 400px!important;
  8799. border: 1px solid var(--whiteOpacity07, rgba(128, 128, 128, 0.7))!important;
  8800. border-radius: 4px!important;
  8801. box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.3), -3px -3px 12px rgba(0, 0, 0, 0.3), 0px 0px 22px rgba(0, 0, 0, 0.3);
  8802. opacity: 0.7;
  8803. filter: brightness(0.8) grayscale(0.6);
  8804. }
  8805. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder > canvas:hover
  8806. {
  8807. max-width: 400px!important;
  8808. opacity: 1;
  8809. filter: brightness(1.3) grayscale(0)!important;
  8810. border: 1px solid var(--whiteOpacity07, rgba(128, 128, 128, 0.7))!important;
  8811. }
  8812. /* ten plik zostanie wysłany (ostatni na liscie) */
  8813. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder > canvas:nth-last-child(1 of canvas)
  8814. {
  8815. opacity: 1;
  8816. filter: brightness(1.1) grayscale(0);
  8817. border-color: rgba(21, 138, 255, .89)!important;
  8818. border: 20px solid red;
  8819. }
  8820.  
  8821.  
  8822.  
  8823. /* lista wgranych plików wraz z nazwami */
  8824. section.editor > aside > ul > li.photo > span
  8825. {
  8826. line-height: 24px;
  8827. }
  8828.  
  8829. section.editor > aside > ul > li.photo::before
  8830. {
  8831. top: unset!important;
  8832. left: unset!important;
  8833. }
  8834. section.editor > aside > ul > li.photo
  8835. {
  8836. padding: 8px 0px 8px 10px;
  8837. border-radius: 4px;
  8838. background-color: rgba(255, 0, 0, 0.1);
  8839. opacity: 0.6;
  8840. }
  8841. section.editor > aside > ul > li:nth-last-child(1 of li.photo)
  8842. {
  8843. opacity: 1;
  8844. background-color: rgba(21, 138, 255, .01);
  8845. }
  8846.  
  8847.  
  8848. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_preview::after
  8849. {
  8850. display: flex;
  8851. font-size: 14px;
  8852. color: rgba(254, 255, 255, 0.3);
  8853. background-color: rgba(0, 0, 0, 0.7);
  8854. border: 1px solid rgba(0, 0, 0, 1);
  8855. position: absolute;
  8856. left: 10px;
  8857. bottom: 10rem;
  8858. padding: 4px 11px;
  8859. border-radius: 3px;
  8860. }
  8861. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_png::after
  8862. {
  8863. content: "PNG";
  8864. }
  8865. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_jpeg::after,
  8866. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_jpeg::after
  8867. {
  8868. content: "JPEG";
  8869. }
  8870. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_gif::after
  8871. {
  8872. content: "GIF";
  8873. }
  8874. section.editor:has(aside li.photo) figure.wxs_uploaded_image_placeholder canvas.wxs_uploaded_image_webp::after
  8875. {
  8876. content: "WEBP";
  8877. }
  8878.  
  8879. /* IMAGE UPLOADER - END */
  8880. `;
  8881. }
  8882.  
  8883. if (settings.haveBanDisableTextarea)
  8884. {
  8885. CSS += `
  8886. section.editor > div.content::before
  8887. {
  8888. content: var(--myUsernameAddingAs);
  8889. display: flex;
  8890. position: relative;
  8891. color: var(--gullGray);
  8892. font-size: 15px;
  8893. text-transform: initial;
  8894. margin-top: 15px;
  8895. margin-bottom: 15px;
  8896. padding-bottom: 15px;
  8897. border-bottom: 1px dotted rgba(120, 120, 120, 0.3);
  8898. }
  8899. `;
  8900. }
  8901.  
  8902. if (settings.editorShowMyUsername)
  8903. {
  8904. CSS += `
  8905. header.stream-top:has(+ section.editor) > h1::after
  8906. {
  8907. margin-left: 5px;
  8908. content: var(--myUsernameAS);
  8909. text-transform: initial;
  8910. }
  8911. section.editor > div.content::before
  8912. {
  8913. content: var(--myUsernameAddingAs);
  8914. display: flex;
  8915. position: relative;
  8916. color: var(--gullGray);
  8917. font-size: 15px;
  8918. text-transform: initial;
  8919. margin-top: 15px;
  8920. margin-bottom: 15px;
  8921. padding-bottom: 15px;
  8922. border-bottom: 1px dotted rgba(120, 120, 120, 0.3);
  8923. }
  8924. `;
  8925.  
  8926. if (settings.editorShowMyUsernameOnSendButton)
  8927. {
  8928. CSS += `
  8929. section.editor > footer > div.buttons > div.button.send > button.target
  8930. {
  8931. display: flex;
  8932. flex-wrap: nowrap;
  8933. flex-direction: row;
  8934. column-gap: 4px;
  8935. text-transform: capitalize;
  8936. }
  8937. section.editor > footer > div.buttons > div.button.send > button.target::after
  8938. {
  8939. content: var(--myUsernameAs);
  8940. text-transform: initial;
  8941. }
  8942. `;
  8943. }
  8944. }
  8945.  
  8946. if (settings.observedTagsInRightSidebarEnable)
  8947. {
  8948. CSS += `
  8949. main.main > section > section.sidebar
  8950. {
  8951. display: flex;
  8952. flex-direction: column;
  8953. }
  8954. section.wykopx_your_observed_tags
  8955. {
  8956. order: -9999;
  8957. display: flex!important;
  8958. flex-direction: column;
  8959. gap: 16px;
  8960. }
  8961.  
  8962. section.wykopx_your_observed_tags div.wykopx_quick_search_container
  8963. {
  8964. display: flex!important;
  8965. width: 100%;
  8966. position: relative;
  8967. }
  8968. section.wykopx_your_observed_tags .wykopx_quick_search_container,
  8969. section.wykopx_your_observed_tags > div.content
  8970. {
  8971. margin-top: 0px!important;
  8972. }
  8973.  
  8974. section.wykopx_your_observed_tags .wykopx_quick_search_container input.wykopx_quick_search
  8975. {
  8976. box-sizing: border-box;
  8977. width: 100%;
  8978. height: 25px; /*25px;*/
  8979. font-size: 15px; /* 15px; */
  8980. padding: 17px 10px 17px 34px;
  8981. opacity: 0.5;
  8982.  
  8983. color: var(--colorLinkTag, rgba(47, 174, 255, 1));
  8984. border: 1px solid var(--blackOpacity05, rgba(175, 175, 175, 0.5));
  8985. background-color: var(--whiteOpacity01, rgba(175, 175, 175, 0.1));
  8986. }
  8987.  
  8988. section.wykopx_your_observed_tags .wykopx_quick_search_container:hover input.wykopx_quick_search,
  8989. section.wykopx_your_observed_tags .wykopx_quick_search_container input.wykopx_quick_search:focus,
  8990. section.wykopx_your_observed_tags .wykopx_quick_search_container input.wykopx_quick_search:not(:placeholder-shown)
  8991. {
  8992. opacity: 1;
  8993. background-color: var(--whiteOpacity03, rgba(175, 175, 175, 0.1));
  8994. }
  8995.  
  8996. section.wykopx_your_observed_tags .wykopx_quick_search_container::before
  8997. {
  8998. content: "🔍";
  8999. font-size: 16px;
  9000. display: block;
  9001. position: absolute;
  9002. left: 8px;
  9003. top: 6px;
  9004. min-width: 20px;
  9005. min-height: 20px;
  9006. max-height: 20px;
  9007. max-width: 20px;
  9008. }`;
  9009. }
  9010.  
  9011. if (settings.quickLinksEnable)
  9012. {
  9013. CSS += `:root
  9014. {
  9015. --quickLinksAFontSize: var(--textFontSize13, 13px);
  9016. --quickLinksSpanFontSize: var(--textFontSize11, 11px);
  9017. }
  9018. header.header > div.left > #wxs_quick_links > nav
  9019. {
  9020. font-size: var(--quickLinksAFontSize, 13px);
  9021. }
  9022. header.header > div.left > #wxs_quick_links > nav > section span
  9023. {
  9024. font-size: var(--quickLinksSpanFontSize, 11px);
  9025. }
  9026. header.header > div.left > #wxs_quick_links
  9027. {
  9028. display: flex;
  9029. top: calc(var(--topNavHeigh, 48px) - 1px);
  9030. position: absolute;
  9031. left: -1px;
  9032. width: 100vw;
  9033. height: 1px;
  9034. z-index: -100;
  9035. }
  9036. @keyframes quickLinksAnimationOn
  9037. {
  9038. 0% { display: none; top: -20px; opacity: 1; }
  9039. 1% { display: flex; top: -20px; opacity: 0; }
  9040. 99% { display: flex; top: -20px; opacity: 0; }
  9041. 100% { display: flex; top: 0px; opacity: 1; }
  9042. }
  9043. @keyframes quickLinksAnimationOff
  9044. {
  9045. 0% { display: flex; top: 0px; opacity: 1; }
  9046. 50% { display: flex; top: 0px; opacity: 0; }
  9047. 99% { display: flex; top: -20px; opacity: 0; }
  9048. 100% { display: none; top: -20px; opacity: 0; }
  9049. }
  9050. header.header > div.left > #wxs_quick_links > nav
  9051. {
  9052. z-index: -999;
  9053. column-gap: 0px;
  9054. flex-wrap: nowrap;
  9055. position: absolute;
  9056. left: 0px;
  9057. width: 100%;
  9058. }
  9059. @starting-style
  9060. {
  9061. header.header > div.left > #wxs_quick_links > nav:hover
  9062. {
  9063.  
  9064. }
  9065. }
  9066. header.header > div.left > #wxs_quick_links > nav:not(:hover)
  9067. {
  9068. z-index: -1000!important;
  9069. display: none;
  9070. transition: display 1s ease-out allow-discrete;
  9071. /* animation-name: quickLinksAnimationOff!important;
  9072. animation-duration: 0s;
  9073. animation-delay: 0.4s;
  9074. animation-iteration-count: 1;
  9075. animation-direction: normal;
  9076. animation-fill-mode: forwards;*/
  9077. }
  9078. header.header > div.left > #wxs_quick_links > nav:hover
  9079. {
  9080. z-index: 999!important;
  9081. display: flex!important;
  9082. animation-name: quickLinksAnimationOn!important;
  9083. animation-duration: 0s!important;
  9084. animation-delay: 0s!important;
  9085. animation-direction: normal!important;
  9086. animation-fill-mode: forwards!important;
  9087. }
  9088.  
  9089. header.header > div.left > #wxs_quick_links > nav > section
  9090. {
  9091. display: flex;
  9092. flex-wrap: nowrap;
  9093. align-items: center;
  9094. }
  9095. header.header > div.left > #wxs_quick_links > nav > section div
  9096. {
  9097. display: flex;
  9098. height: 100%;
  9099. }
  9100. header.header > div.left > #wxs_quick_links > nav > section a,
  9101. header.header > div.left > #wxs_quick_links > nav > section span
  9102. {
  9103. display: flex;
  9104. align-items: center;
  9105. justify-content: center;
  9106. }
  9107. header.header > div.left:has(a[href="/"]:hover) > #wxs_quick_links > nav.home,
  9108. header.header > div.left:has(> nav.main > ul > li:hover a[href="/"]) > #wxs_quick_links > nav.home,
  9109. header.header > div.left:has(> nav.main > ul > li a[href="/"]:hover) > #wxs_quick_links > nav.home,
  9110. header.header > div.left:has(> nav.main > ul > li:hover a[href="/wykopalisko"]) > #wxs_quick_links > nav.upcoming,
  9111. header.header > div.left:has(> nav.main > ul > li:hover a[href="/mikroblog"]) > #wxs_quick_links > nav.microblog,
  9112. header.header > div.left:has(> nav.main > ul > li:hover a[href="/obserwowane"]) > #wxs_quick_links > nav.mywykop,
  9113. header.header > div.left:has(> nav.main > ul > li:hover a[href="/hity"]) > #wxs_quick_links > nav.hits,
  9114. header.header > div.left:has(> nav.main > ul > li:hover a[href="/ulubione"]) > #wxs_quick_links > nav.favorites,
  9115. header.header > div.left:has(> nav.main > ul > li:hover a[href="/dodaj-link"]) > #wxs_quick_links > nav.add_new,
  9116. header.header > div.left:has(> nav.main > ul > li:hover a[href="/mikroblog/#dodaj"]) > #wxs_quick_links > nav.add_new
  9117. {
  9118. z-index: 999;
  9119. display: flex!important;
  9120. animation-name: quickLinksAnimationOn!important;
  9121. animation-duration: 2s;
  9122. animation-delay: 0s;
  9123. animation-direction: normal;
  9124. animation-fill-mode: forwards;
  9125. }
  9126. /* colors */
  9127. header.header > div.left > #wxs_quick_links > nav
  9128. {
  9129. height: 37px;
  9130. color: var(--blackOpacity07, rgba(255, 255, 255, 0.7));
  9131. border-bottom: 1px solid var(--blackOpacity03, rgba(255, 255, 255, 0.3));
  9132. box-shadow: 0px 4px 4px var(--whiteOpacity04, rgba(0, 0, 0, 0.4));
  9133. }
  9134. header.header > div.left > #wxs_quick_links > nav:hover
  9135. {
  9136.  
  9137. }
  9138. header.header > div.left > #wxs_quick_links > nav > section
  9139. {
  9140. background-color: var(--whiteOpacity1, rgba(18, 18, 20, 1));
  9141. column-gap: 5px;
  9142. padding-left: 20px;
  9143. padding-right: 0px;
  9144. border-left: 1px solid rgba(120, 120, 120, 0.2);
  9145. }
  9146.  
  9147. header.header > div.left > #wxs_quick_links > nav > section:hover
  9148. {
  9149. background-color: var(--whiteOpacity1, rgba(18, 18, 20, 1));
  9150. }
  9151. header.header > div.left > #wxs_quick_links > nav > section:hover span
  9152. {
  9153. color: var(--blackOpacity1, rgba(255, 255, 255, 1));
  9154. }
  9155.  
  9156. header.header > div.left > #wxs_quick_links > nav > section span
  9157. {
  9158. padding-right: 10px;
  9159. text-transform: uppercase;
  9160. font-weight: bolder;
  9161. cursor: default ;
  9162. width: max-content;
  9163. }
  9164.  
  9165. header.header > div.left > #wxs_quick_links > nav > section a,
  9166. header.header > div.left > #wxs_quick_links > nav > section span
  9167. {
  9168. height: 100%;
  9169. min-width: 70px;
  9170. width: max-content;
  9171. }
  9172.  
  9173. header.header > div.left > #wxs_quick_links > nav > section.wxs_quicklink_short
  9174. {
  9175. min-width: 20px;
  9176. }
  9177.  
  9178. header.header > div.left > #wxs_quick_links > nav > section a
  9179. {
  9180. text-decoration: none;
  9181. padding: 0px 14px 0px 14px;
  9182. }
  9183.  
  9184. header.header > div.left > #wxs_quick_links > nav > section a:hover
  9185. {
  9186. color: var(--blackOpacity09, rgba(255, 255, 255, 1));
  9187. background-color: var(--blackOpacity01, rgba(255, 255, 255, 0.2));
  9188. }
  9189.  
  9190. /* MOBILE */
  9191. @media(max-width: 600px)
  9192. {
  9193. header.header > div.left > #wxs_quick_links > nav:not(:hover)
  9194. {
  9195.  
  9196. animation-name: quickLinksAnimationOff!important;
  9197. animation-delay: 4s;
  9198. }
  9199.  
  9200. header.header > div.left > #wxs_quick_links > nav,
  9201. header.header > div.left > #wxs_quick_links > nav > section,
  9202. header.header > div.left > #wxs_quick_links > nav > section > div
  9203. {
  9204. flex-direction: column!important;
  9205. align-items: start!important;
  9206. }
  9207. header.header > div.left > #wxs_quick_links > nav,
  9208. header.header > div.left > #wxs_quick_links > nav > section,
  9209. header.header > div.left > #wxs_quick_links > nav > section > div,
  9210. header.header > div.left > #wxs_quick_links > nav > section > span,
  9211. header.header > div.left > #wxs_quick_links > nav > section a
  9212. {
  9213. width: 100%;
  9214. justify-content: start;
  9215. }
  9216. header.header > div.left > #wxs_quick_links > nav > section
  9217. {
  9218. border-top: 1px solid rgba(120, 120, 120, 0.3);
  9219. }
  9220. header.header > div.left > #wxs_quick_links > nav > section,
  9221. header.header > div.left > #wxs_quick_links > nav > section > div,
  9222. header.header > div.left > #wxs_quick_links > nav > section > span,
  9223. header.header > div.left > #wxs_quick_links > nav > section a
  9224. {
  9225. padding: 10px;
  9226. }
  9227. }
  9228. } `;
  9229. }
  9230.  
  9231. /* HIDE ADS ALWAYS */
  9232. CSS += `
  9233. .pub-slot-wrapper
  9234. {
  9235. display: none!important;
  9236. }
  9237. .pub-slot-wrapper:has(section.premium-pub.link-block)
  9238. {
  9239. display: flex!important;
  9240. border: 1px solid rgba(255, 0, 0, 0.3)!important;
  9241. }
  9242. .pub-slot-wrapper:has(section.premium-pub.link-block)::before
  9243. {
  9244. display: flex!important;
  9245. content: "Aby ukryć Wykopy Sponsorowane i Reklamowane zainstaluj 𝗪𝘆𝗸𝗼𝗽 𝗫 𝗦𝘁𝘆𝗹𝗲 lub 𝗪𝘆𝗸𝗼𝗽 𝗫 𝗕𝗹𝗼𝗰𝗸𝗲𝗿";
  9246. font-size: 13px;
  9247. color: var(--blackish);
  9248. margin: 9px 14px;
  9249. align-self: self-start;
  9250. }`;
  9251.  
  9252.  
  9253. /* HIDE WYKOP XS PROMO FROM STYLUS */
  9254. CSS += `body div.main-content[class] section > section.sidebar::after { display: none!important; }`;
  9255.  
  9256.  
  9257. /* ----- Wykop X Style promo banners ON */
  9258. CSS += `.wykopx_promo_banner a
  9259. { width: 100%; display: block!important; height: 300px!important; background: url('https://raw.githubusercontent.com/wykopx/wykopx-png/main/promo-images/wykopx-install-sidebar-day.png'); }
  9260. [data-night-mode] .wykopx_promo_banner a
  9261. { background: url('https://raw.githubusercontent.com/wykopx/wykopx-png/main/promo-images/wykopx-install-sidebar-night.png'); }
  9262. .wykopx_promo_banner:hover { filter: brightness(0.98) drop-shadow(0px 0px 3px rgba(0, 0, 0, 0.2)); }
  9263. [data-night-mode] .wykopx_promo_banner:hover { filter: brightness(1.2); }
  9264.  
  9265. body > section > header.header > div.left > nav.main > ul > li
  9266. {
  9267. white-space: nowrap!important;
  9268. height: calc(100%-12px)!important;
  9269. position: relative!important;
  9270. }
  9271.  
  9272. body > section > header.header > div.left > nav.main > ul > li > a
  9273. {
  9274. text-decoration: none!important;
  9275. height: 100% !important;
  9276. display: flex!important;
  9277. flex-direction: column!important;
  9278. justify-content: center!important;
  9279. position: relative!important;
  9280. font-weight: 400!important;
  9281. padding: 0 12px!important;
  9282. }
  9283. body > section > header.header > div.left > nav.main > ul > li:hover a
  9284. {
  9285. background: rgba(255, 255, 255, 0.2)!important;
  9286. }
  9287. body > section > header.header > div.left > nav.main > ul > li > a > span
  9288. {
  9289. white-space: nowrap!important;
  9290. }
  9291. body > section > header.header > div.left > nav.main > ul > li.wykopx_promo_li > a > span
  9292. {
  9293. color: rgba(255, 255, 255, 1)!important;
  9294. font-size: 14px;
  9295. }
  9296.  
  9297.  
  9298.  
  9299.  
  9300. section.editor.expand section.inline-autocomplete section.inline-autocomplete-stream div.content::after,
  9301. header.header div.right section.search-input section.inline-autocomplete section.inline-autocomplete-stream div.content::after
  9302. { display: none!important; }
  9303.  
  9304. /* ----- WykopXS new version available */
  9305. .wykopxs_info_bar
  9306. { display: flex; align-items: center; border-bottom: 1px solid rgba(128, 128, 128, 0.2); color: rgba(128, 128, 128, 1); padding: 8px 20px; font-size: 14px; }
  9307.  
  9308. aside.wykopxs_info_bar a
  9309. { display: inline-block; background: rgb(0, 85, 0); color: white; display: inline-block; background-color: #005200; padding: .3em 0.7em; margin: 0 10px; }
  9310.  
  9311. aside.wykopxs_info_bar a:hover
  9312. { background: rgba(0, 85, 0, 0.7); text-decoration: none!important; }
  9313.  
  9314. aside.wykopxs_info_bar footer
  9315. { opacity: 0.6; margin-left: auto; }
  9316.  
  9317. @media(max-width: 640px)
  9318. {
  9319. body > section > aside.wykopxs_info_bar { flex-direction: column; padding-top: 30px; }
  9320. body > section > aside.wykopxs_info_bar a { margin: 11px; padding: 14px; width: 100%; text-align: center; }
  9321. body > section > aside.wykopxs_info_bar span.wykopxs_new_version_second,
  9322. body > section > aside.wykopxs_info_bar > footer { display: none; }
  9323. }
  9324. `;
  9325.  
  9326.  
  9327.  
  9328.  
  9329.  
  9330.  
  9331.  
  9332.  
  9333.  
  9334.  
  9335.  
  9336.  
  9337.  
  9338. // XS MIKROCZAT -- START
  9339. let wykopDomain = "https://wykop.pl";
  9340. let wxDomain = "https://wykopx.pl";
  9341. const mikroczatDomain = "https://mikroczat.pl";
  9342. const mikroczatPath = "/"; /* /czat */
  9343. // let mikroczatChannel="/";
  9344. let mikroczatWindow = null;
  9345. const mikroczatButtonOpenTitle = "Otwórz wykopowy MikroCzat";
  9346. const mikroczatButtonOpenLabel = "Czat";
  9347.  
  9348.  
  9349. function openMikroczat(channel, windowOptions, target = "mikroczat")
  9350. {
  9351. if (bodySection.dataset.key_shift) delete bodySection.dataset.key_shift;
  9352. if (bodySection.dataset.key_ctrl) delete bodySection.dataset.key_ctrl;
  9353. if (bodySection.dataset.key_alt) delete bodySection.dataset.key_alt;
  9354.  
  9355. let mikroczatURL = `${mikroczatDomain}`;
  9356. mikroczatURL += `${mikroczatPath}${channel}`;
  9357.  
  9358. mikroczatWindow = window.open(mikroczatURL, target, windowOptions);
  9359. }
  9360.  
  9361. // OTWIERANIE MIKROCZATU Z PRZYCISKU
  9362. document.addEventListener("mousedown", wykopx_open_mikroczat_event_listener);
  9363.  
  9364. function wykopx_open_mikroczat_event_listener(e)
  9365. {
  9366. if (!e.target.closest(".wykopx_open_mikroczat")) return;
  9367. e.preventDefault();
  9368. let windowOptions = "";
  9369. let channel = "";
  9370.  
  9371. if (e.shiftKey || e.ctrlKey || e.altKey || e.button === 2)
  9372. {
  9373. windowOptions = "popup";
  9374. }
  9375.  
  9376. // WykopXS unique
  9377. const pathnameArray = new URL(document.URL).pathname.split("/");
  9378. if (pathnameArray[1] == "tag")
  9379. {
  9380. channel = "/" + pathnameArray[2]; // nazwatagu
  9381. }
  9382.  
  9383. openMikroczat(channel, windowOptions);
  9384. }
  9385.  
  9386.  
  9387.  
  9388. // PREVENT DEFAULT EVENT
  9389. function preventDefaultEvent(e)
  9390. {
  9391. e.preventDefault();
  9392. }
  9393. document.addEventListener("click", (e) =>
  9394. {
  9395. if (!e.target.closest(".wykopx_open_mikroczat")) return;
  9396. e.preventDefault();
  9397. });
  9398.  
  9399. let keys = {};
  9400. document.addEventListener("keydown", (e) =>
  9401. {
  9402. if (e.target.tagName.toLowerCase() === 'textarea') return;
  9403.  
  9404. if (!keys["SHIFT"] && e.key == "Shift")
  9405. {
  9406. keys["SHIFT"] = true;
  9407. bodySection.dataset.key_shift = "true";
  9408. }
  9409. else if (!keys["ALT"] && (e.key == "Alt" || e.key == "AltGraph"))
  9410. {
  9411. keys["ALT"] = true;
  9412. bodySection.dataset.key_alt = "true";
  9413. }
  9414. });
  9415. document.addEventListener("keyup", (e) =>
  9416. {
  9417. if (e.target.tagName.toLowerCase() === 'textarea') return;
  9418.  
  9419. if (keys["SHIFT"] && e.key == "Shift")
  9420. {
  9421. keys["SHIFT"] = false;
  9422. delete bodySection.dataset.key_shift;
  9423. }
  9424. else if (keys["ALT"] && (e.key == "Alt" || e.key == "AltGraph"))
  9425. {
  9426. keys["ALT"] = false;
  9427. delete bodySection.dataset.key_alt;
  9428. }
  9429. });
  9430.  
  9431.  
  9432.  
  9433.  
  9434. document.addEventListener("mouseover", (e) =>
  9435. {
  9436. if (e.target.matches(`a[href^="/tag/"]`))
  9437. {
  9438. e.target.title = `Wciśnij klawisz 𝗦𝗛𝗜𝗙𝗧 lub 𝗔𝗟𝗧 (⌥ 𝗢𝗽𝘁𝗶𝗼𝗻 na Mac) klikając na tag,\naby otworzyć kanał #${e.target.innerText} na 🗯 Mikroczacie\n\n 𝗔𝗟𝗧 - mikroczat w nowej karcie\n 𝗦𝗛𝗜𝗙𝗧 - mikroczat w nowym oknie`;
  9439.  
  9440. e.target.addEventListener("click", preventDefaultEvent, true);
  9441. e.target.addEventListener("mousedown", tagHrefEventListenerWithShift, true);
  9442. e.target.addEventListener("mouseup", preventDefaultEvent, true);
  9443. }
  9444. });
  9445.  
  9446. document.addEventListener("mouseout", (e) =>
  9447. {
  9448. if (e.target.matches(`a[href^="/tag/"]`))
  9449. {
  9450. e.target.removeEventListener("click", preventDefaultEvent, true);
  9451. e.target.removeEventListener("mousedown", tagHrefEventListenerWithShift, true);
  9452. e.target.removeEventListener("mouseup", preventDefaultEvent, true);
  9453. }
  9454. });
  9455.  
  9456. function tagHrefEventListenerWithShift(e)
  9457. {
  9458. const channel = e.target.href.split("tag/").pop();
  9459.  
  9460. if (e.ctrlKey || e.altKey) // || e.button === 2)
  9461. {
  9462. e.preventDefault();
  9463. openMikroczat(channel, null, "_blank");
  9464. }
  9465. else if (e.shiftKey)
  9466. {
  9467. e.preventDefault();
  9468. openMikroczat(channel, "popup");
  9469. }
  9470. else if (e.button === 2) // PPM
  9471. {
  9472.  
  9473. }
  9474. else if (e.button === 1) // ŚPM
  9475. {
  9476.  
  9477. }
  9478. else if (e.button === 0) // LPM
  9479. {
  9480. window.location.href = e.target.href;
  9481. }
  9482. }
  9483.  
  9484.  
  9485. // WIADOMOŚCI OD MIKROCZAT.PL
  9486. window.addEventListener('message', function (event)
  9487. {
  9488. if (event.origin !== mikroczatDomain) return;
  9489. if (dev) console.log('Wiadomość z mikroczat.pl', event.data);
  9490.  
  9491. //if (event.data == "MikroCzatOpened") mikroczatWindow.postMessage({ type: "token", token: window.localStorage.getItem("token") }, mikroczatDomain);
  9492.  
  9493. if (event.data == "MikroCzatOpened")
  9494. {
  9495. mikroczatWindow.postMessage({ type: "TokensObject", token: window.localStorage.getItem("token"), userKeep: window.localStorage.getItem("userKeep") }, mikroczatDomain);
  9496. }
  9497.  
  9498.  
  9499. if (event.data == "MikroCzatLoggedIn")
  9500. {
  9501. if (dev) console.log("event.data", event.data)
  9502. bodySection.dataset.mikroczatLogged = true;
  9503. }
  9504.  
  9505. if (event.data == "MikroCzatClosed")
  9506. {
  9507. bodySection.dataset.mikroczatLogged = false;
  9508. mikroczatWindow = null;
  9509. }
  9510. }, false);
  9511.  
  9512.  
  9513. function createLeftPanelButton()
  9514. {
  9515. if (dev) console.log("createLeftPanelButton");
  9516.  
  9517. const aside_section_div_ul = document.querySelector("body aside.left-panel > section.buttons ul");
  9518. if (!aside_section_div_ul) return;
  9519.  
  9520. let aside_section_div_ul_li = aside_section_div_ul.querySelector("li.mikroczat");
  9521. if (aside_section_div_ul_li) return;
  9522.  
  9523. aside_section_div_ul_li = document.createElement('li');
  9524. aside_section_div_ul_li.classList.add('wykopx_open_mikroczat', 'mikroczat');
  9525. aside_section_div_ul_li.title = mikroczatButtonOpenTitle;
  9526.  
  9527. aside_section_div_ul_li.innerHTML = `
  9528. <div class="popper-button">
  9529. <span>
  9530. <span class="button">
  9531. <a target="_mikroczat" class="hybrid">
  9532. <span>${mikroczatButtonOpenLabel}</span>
  9533. </a>
  9534. </span>
  9535. </span>
  9536. </div>`;
  9537.  
  9538. aside_section_div_ul.appendChild(aside_section_div_ul_li);
  9539. }
  9540.  
  9541.  
  9542. {
  9543. CSS += `
  9544. /* LEFT MENU MIKROCZAT BUTTON - START */
  9545. body aside.left-panel:not(.mini) > section.buttons > div.content > ul
  9546. {
  9547. display: flex;
  9548. flex-wrap: wrap;
  9549. justify-content: space-around;
  9550. column-gap: 0px;
  9551. }
  9552. body aside.left-panel:not(.mini) > section.buttons > div.content > ul > li
  9553. {
  9554. flex-basis: 47%;
  9555. box-sizing: border-box;
  9556. padding: 0px;
  9557. margin-top: 7px;
  9558. }
  9559.  
  9560. body aside.left-panel > section > div.content > ul > li
  9561. {
  9562. position: relative;
  9563. cursor: pointer;
  9564. }
  9565.  
  9566. body aside.left-panel.mini > section > div.content > ul > li:hover,
  9567. body aside.left-panel:not(.mini) > section.buttons > div.content > ul > li:hover a::before
  9568. {
  9569. background: var(--squeeze);
  9570. }
  9571.  
  9572. aside.left-panel>section.links>.content ul li a /* [data-v-5687662b] */
  9573. {
  9574. padding: 0 6px;
  9575. display: block;
  9576. -webkit-box-sizing: border-box;
  9577. box-sizing: border-box;
  9578. font-weight: 400;
  9579. text-decoration: none;
  9580. font-size: 16px;
  9581. line-height: 36px;
  9582. height: 36px;
  9583. }
  9584.  
  9585.  
  9586. aside.left-panel>section.buttons>.content ul li a /* [data-v-5687662b] */
  9587. {
  9588. display: block;
  9589. position: relative;
  9590. color: var(--steelBluish);
  9591. font-size: 0;
  9592. }
  9593.  
  9594. aside.left-panel>section.buttons>.content ul li.active a, /* [data-v-5687662b] */
  9595. aside.left-panel>section.buttons>.content ul li:hover a /* [data-v-5687662b] */
  9596. {
  9597. color: var(--tuna);
  9598. font-weight: 600;
  9599. }
  9600.  
  9601. aside.left-panel>section.buttons>.content ul li a:before /* [data-v-5687662b] */
  9602. {
  9603. content: '';
  9604. display: block;
  9605. width: 100%;
  9606. height: 36px;
  9607. border: 1px solid var(--porcelain);
  9608. border-radius: 6px;
  9609. box-sizing: border-box;
  9610. transition: background .2s ease, border .2s ease;
  9611. }
  9612. [data-night-mode] aside.left-panel>section.buttons>.content ul li a:before /* [data-v-5687662b] */
  9613. {
  9614. border-color: #303032;
  9615. }
  9616.  
  9617. aside.left-panel:not(.mini)>section.buttons>.content ul li:hover a:before,
  9618. [data-night-mode] aside.left-panel:not(.mini)>section.buttons>.content ul li:hover a:before
  9619. {
  9620. border-color: var(--tuna);
  9621. }
  9622.  
  9623. aside.left-panel:not(.mini)>section.buttons>.content ul li a:after /* [data-v-5687662b] */
  9624. {
  9625. content: '';
  9626. display: block;
  9627. position: absolute;
  9628. -webkit-mask-repeat: no-repeat;
  9629. mask-repeat: no-repeat;
  9630. -webkit-mask-position: center;
  9631. mask-position: center;
  9632. background: var(--gullGray);
  9633. height: 34px;
  9634. width: 100%;
  9635. top: 0;
  9636. left: 0;
  9637. -webkit-transition: background .2s ease;
  9638. transition: background .2s ease;
  9639. }
  9640.  
  9641. aside.left-panel:not(.mini)>section.buttons>.content ul li.mikroczat a:after /* [data-v-5687662b] */
  9642. {
  9643. -webkit-mask-image: url(https://i.imgur.com/82a9CyK.png);
  9644. mask-image: url(https://i.imgur.com/82a9CyK.png);
  9645. -webkit-mask-size: 22px 22px;
  9646. mask-size: 22px 22px;
  9647. }
  9648.  
  9649. /* ZWINIETE MENU PO LEWEJ */
  9650. aside.left-panel>section.links>.content ul li a:before /* [data-v-5687662b] */
  9651. {
  9652. content: '';
  9653. display: block;
  9654. position: absolute;
  9655. -webkit-mask-repeat: no-repeat;
  9656. mask-repeat: no-repeat;
  9657. -webkit-mask-position: center;
  9658. mask-position: center;
  9659. -webkit-mask-size: cover;
  9660. mask-size: cover;
  9661. background: var(--gullGray);
  9662. -webkit-transform: translateX(-50%) translateY(-50%);
  9663. transform: translateX(-50%) translateY(-50%);
  9664. top: 50%;
  9665. left: 24px;
  9666. -webkit-transition: background .2s ease;
  9667. transition: background .2s ease;
  9668. z-index: 1;
  9669. }
  9670.  
  9671.  
  9672. aside.left-panel.mini > section.links > .content ul li.mikroczat a:before
  9673. {
  9674. -webkit-mask-image: url(https://i.imgur.com/82a9CyK.png);
  9675. mask-image: url(https://i.imgur.com/82a9CyK.png);
  9676. -webkit-mask-size: 22px 22px;
  9677. mask-size: 22px 22px;
  9678.  
  9679. mask-size: 22px 22px;
  9680. width: 22px;
  9681. height: 22px;
  9682. margin-top: 0px;
  9683. }
  9684.  
  9685.  
  9686. aside.left-panel:not(.mini)>section.buttons>.content ul li a>span /*[data-v-5687662b] */
  9687. {
  9688. position: relative;
  9689. display: inline-block;
  9690. font-size: 11px;
  9691. left: 50%;
  9692. -webkit-transform: translateX(-50%);
  9693. transform: translateX(-50%);
  9694. white-space: nowrap;
  9695. margin-top: 2px;
  9696. line-height: 16px;
  9697. height: 16px;
  9698. }
  9699. aside.left-panel.mini > section.links > .content ul li a > span
  9700. {
  9701. display: none;
  9702. }
  9703. /* LEFT MENU MIKROCZAT BUTTON - END */
  9704.  
  9705.  
  9706.  
  9707.  
  9708. /* MIKROCZAT TAG LINKS */
  9709. section:is(.entry-content, .link-block)[class] { overflow: visible!important; }
  9710.  
  9711. section:is(.entry-content, .link-block) a[href^="/tag/"]
  9712. {
  9713. padding-right: 2px !important;
  9714. margin-right: 1px;
  9715. transition: none!important;
  9716. }
  9717. section:is(.entry-content, .link-block) a[href^="https://mikroczat.pl/"]
  9718. {
  9719. padding-right: 2px!important;
  9720. padding-left: 2px!important;
  9721. }
  9722. section:is(.entry-content, .link-block) a[href^="/tag/"],
  9723. section.entry-content .wrapper a[href^="https://mikroczat.pl/"]
  9724. {
  9725. border: 1px solid transparent!important;
  9726. position: relative!important;
  9727. }
  9728.  
  9729. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9730. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9731. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9732. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"] *,
  9733. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"] *,
  9734. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"] *,
  9735. body > section[data-key_shift="true"] section.entry-content a[href^="https://mikroczat.pl/"],
  9736. body > section[data-key_alt="true"] section.entry-content a[href^="https://mikroczat.pl/"],
  9737. body > section[data-key_ctrl="true"] section.entry-content a[href^="https://mikroczat.pl/"],
  9738. body > section[data-key_shift="true"] section.entry-content a[href^="https://mikroczat.pl/"] *,
  9739. body > section[data-key_alt="true"] section.entry-content a[href^="https://mikroczat.pl/"] *,
  9740. body > section[data-key_ctrl="true"] section.entry-content a[href^="https://mikroczat.pl/"] *
  9741. {
  9742. color: var(--tagChannelColor)!important;
  9743. }
  9744.  
  9745. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9746. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9747. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9748. body > section[data-key_shift="true"] section.entry-content a[href^="https://mikroczat.pl/"],
  9749. body > section[data-key_alt="true"] section.entry-content a[href^="https://mikroczat.pl/"],
  9750. body > section[data-key_ctrl="true"] section.entry-content a[href^="https://mikroczat.pl/"]
  9751. {
  9752. border-color: var(--tagChannelColor)!important;
  9753. background-color: color-mix(in srgb, var(--whitish) 90%, var(--tagChannelColor))!important;
  9754. border-radius: var(--smallBorderRadius)!important;
  9755. }
  9756. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover,
  9757. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover,
  9758. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover,
  9759. body > section[data-key_shift="true"] section.entry-content a[href^="https://mikroczat.pl/"]:hover,
  9760. body > section[data-key_alt="true"] section.entry-content a[href^="https://mikroczat.pl/"]:hover,
  9761. body > section[data-key_ctrl="true"] section.entry-content a[href^="https://mikroczat.pl/"]:hover
  9762. {
  9763. background-color: color-mix(in srgb, var(--whitish) 60%, var(--tagChannelColor))!important;
  9764. }
  9765.  
  9766. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9767. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"],
  9768. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]
  9769. {
  9770.  
  9771. padding-left: 3px !important;
  9772. margin-left: -12px !important;
  9773.  
  9774. }
  9775. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover,
  9776. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover,
  9777. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]:hover
  9778. {
  9779. text-decoration: none!important;
  9780. }
  9781. body > section[data-key_shift="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]::before,
  9782. body > section[data-key_alt="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]::before,
  9783. body > section[data-key_ctrl="true"] section:is(.entry-content, .link-block) a[href^="/tag/"]::before
  9784. {
  9785. content: "#";
  9786. }
  9787. body > section[data-key_shift="true"] section.entry-content a[href^="/tag/"]::after,
  9788. body > section[data-key_alt="true"] section.entry-content a[href^="/tag/"]::after,
  9789. body > section[data-key_ctrl="true"] section.entry-content a[href^="/tag/"]::after,
  9790. body > section[data-key_shift="true"] section.entry-content a[href^="https://mikroczat.pl/"]::after,
  9791. body > section[data-key_alt="true"] section.entry-content a[href^="https://mikroczat.pl/"]::after,
  9792. body > section[data-key_ctrl="true"] section.entry-content a[href^="https://mikroczat.pl/"]::after
  9793. {
  9794. color: white;
  9795. content: "🗯";
  9796. position: absolute;
  9797. top: -1em;
  9798. right: -0.5em;
  9799. }
  9800. body > section[data-mikroczat-logged="true"] li.wykopx_open_mikroczat_li span:after
  9801. {
  9802. content: "•";
  9803. color: white;
  9804. position: absolute;
  9805. top: 4px;
  9806. right: 5px;
  9807. }
  9808. body > section[data-mikroczat-logged="false"] li.wykopx_open_mikroczat_li span:after
  9809. {
  9810. content: "•";
  9811. color: rgb(255, 255, 255, 0.3);
  9812. position: absolute;
  9813. top: 4px;
  9814. right: 5px;
  9815. }`;
  9816. }
  9817.  
  9818.  
  9819. createLeftPanelButton();
  9820.  
  9821. createNewNavBarButton({
  9822. position: "left",
  9823. // text: "Mikro<strong>czat</strong>",
  9824. text: mikroczatButtonOpenLabel,
  9825. title: mikroczatButtonOpenTitle,
  9826. class: "open_mikroczat", // wykopx_open_mikroczat_li
  9827. hideWithoutXStyle: false,
  9828. url: mikroczatDomain,
  9829. target: "_mikroczat",
  9830. number: null,
  9831. });
  9832.  
  9833.  
  9834.  
  9835. function throttle(func, delay)
  9836. {
  9837. let promise = Promise.resolve();
  9838. return function (...args)
  9839. {
  9840. promise = promise.then(() =>
  9841. {
  9842. return new Promise((resolve) =>
  9843. {
  9844. setTimeout(() =>
  9845. {
  9846. func(...args);
  9847. resolve();
  9848. }, delay);
  9849. });
  9850. });
  9851. };
  9852. }
  9853.  
  9854. const throttledAddVotersList = throttle(addVotersList, 200);
  9855.  
  9856. let observer = new MutationObserver((mutations) =>
  9857. {
  9858. if (dev) console.log(`--- ${mutations.length} mutations`, mutations);
  9859.  
  9860. mutations.forEach((mutation) =>
  9861. {
  9862. if (dev)
  9863. {
  9864. console.log("---------- new mutation -----");
  9865. console.log(mutation);
  9866.  
  9867. if (mutation.type)
  9868. {
  9869. console.log(`⭐ mutation.type: `, mutation.type)
  9870. }
  9871. if (mutation.attributeName)
  9872. {
  9873. console.log(`⭐ mutation.attributeName: ${mutation.attributeName}`, mutation.attributeName)
  9874. }
  9875. if (mutation.addedNodes.length > 0 && mutation.addedNodes[0] && mutation.addedNodes[0] instanceof Element)
  9876. {
  9877. console.log(`⭐ mutation.addedNodes.length: ${mutation.addedNodes.length}`, mutation.addedNodes[0])
  9878. }
  9879.  
  9880. if (mutation.target)
  9881. {
  9882. console.log(`⭐ mutation.target: ${mutation.target.tagName}`, mutation.target)
  9883.  
  9884. if (mutation.target.tagName === "SECTION")
  9885. {
  9886.  
  9887. }
  9888. }
  9889. }
  9890.  
  9891. // ADDED NODES
  9892. if (mutation.addedNodes.length > 0 && mutation.addedNodes[0] && mutation.addedNodes[0] instanceof Element)
  9893. {
  9894. if (mutation.addedNodes[0].matches("section.entry[id]"))
  9895. {
  9896. const sectionEntry = mutation.addedNodes[0];
  9897.  
  9898. if (dev) console.log("mutation 1", sectionEntry);
  9899.  
  9900. processSectionEntry(sectionEntry)
  9901.  
  9902. const sectionCommentsArray = sectionEntry.querySelectorAll("section.entry[id]");
  9903. if (dev) console.log("mutation 1 - forEach: sectionEntryArray", sectionCommentsArray);
  9904. sectionCommentsArray.forEach((sectionComment) =>
  9905. {
  9906. processSectionEntry(sectionComment)
  9907. })
  9908. }
  9909. else if (mutation.addedNodes[0].matches("div.content:has(>section.entry[id])"))
  9910. {
  9911. const sectionEntriesArray = mutation.addedNodes[0].querySelectorAll("section.entry[id]");
  9912. if (dev) console.log("mutation 2 - forEach: sectionEntriesArray", sectionEntriesArray);
  9913. sectionEntriesArray.forEach((sectionEntry) =>
  9914. {
  9915. processSectionEntry(sectionEntry)
  9916. })
  9917. }
  9918. else if (mutation.target.tagName === "SECTION" && mutation.target.matches("section.entry.detailed[id]"))
  9919. {
  9920. const sectionEntry = mutation.target;
  9921. if (dev) console.log("mutation 3", sectionEntry)
  9922. if (dev) console.log("mutation 3: mutation.target", mutation.target);
  9923.  
  9924. processSectionEntry(sectionEntry);
  9925.  
  9926. const sectionCommentsArray = sectionEntry.querySelectorAll("section.entry[id]");
  9927. if (dev) console.log("mutation 3 - forEach: sectionEntryArray", sectionCommentsArray);
  9928. sectionCommentsArray.forEach((sectionComment) =>
  9929. {
  9930. processSectionEntry(sectionComment)
  9931. })
  9932. }
  9933. else if (settings.showAnimatedAvatars && mutation.addedNodes[0].matches("aside.profile-top"))
  9934. {
  9935. animatedAvatar(mutation.addedNodes[0]);
  9936. }
  9937. // LEFT SIDE CATEGORY MENU OPENED
  9938. else if (mutation.addedNodes[0].matches("aside.left-panel.thin-scrollbar"))
  9939. {
  9940. createLeftPanelButton();
  9941. }
  9942. }
  9943.  
  9944.  
  9945. });
  9946. });
  9947.  
  9948.  
  9949.  
  9950. // CONTENT LOADED
  9951. let mainSection;
  9952. document.addEventListener('readystatechange', (event) =>
  9953. {
  9954. if (dev) console.log('readyState:' + document.readyState);
  9955. mainSection = document.querySelector('body > section');
  9956.  
  9957. if (mainSection)
  9958. {
  9959.  
  9960. const sectionEntryArray = mainSection.querySelectorAll("section.entry[id]");
  9961. // if (dev) console.log("sectionEntryArray", sectionEntryArray);
  9962. sectionEntryArray.forEach((sectionEntry) =>
  9963. {
  9964. processSectionEntry(sectionEntry)
  9965. })
  9966. const config = {
  9967. childList: true,
  9968. subtree: true,
  9969. };
  9970.  
  9971. observer.observe(mainSection, config);
  9972.  
  9973. if (settings.showAnimatedAvatars)
  9974. {
  9975. const asideProfileTop = mainSection.querySelector("aside.profile-top");
  9976. if (asideProfileTop) animatedAvatar(asideProfileTop);
  9977. }
  9978. }
  9979.  
  9980. });
  9981.  
  9982.  
  9983.  
  9984. function processSectionEntry(sectionEntry)
  9985. {
  9986. if (dev) console.log("processSectionEntry()", sectionEntry)
  9987.  
  9988. if (!sectionEntry) return;
  9989.  
  9990. if (settings.showAnimatedAvatars) animatedAvatar(sectionEntry);
  9991.  
  9992. if (settings.showFavouriteButton) addFavouriteButton(sectionEntry);
  9993.  
  9994. if (settings.entryVotersListEnable && sectionEntry?.__vue__?.item)
  9995. {
  9996. if (dev) console.log("sectionEntry?.__vue__.item.id", sectionEntry?.__vue__.item.id);
  9997. if (dev) console.log("sectionEntry.dataset?.votersLoaded", sectionEntry.dataset?.votersLoaded);
  9998.  
  9999. if (sectionEntry.dataset?.votersLoaded == sectionEntry?.__vue__.item.id) return;
  10000. if (sectionEntry?.__vue__.item.votes.up == 0)
  10001. {
  10002. removeVotersListWhenNoVoters(sectionEntry);
  10003. return;
  10004. }
  10005.  
  10006. if (settings.entryVotersListExpandIfLessThan > 5 && sectionEntry?.__vue__.item.votes.up <= settings.entryVotersListExpandIfLessThan && sectionEntry?.__vue__.item.votes.up > 5)
  10007. {
  10008. if (dev) console.log(`processSectionEntry() wybrano 💛throttledAddVotersList ${sectionEntry.__vue__.item.id} | plusow: ${sectionEntry.__vue__.item.votes.up}`,)
  10009. throttledAddVotersList(sectionEntry);
  10010. }
  10011. else
  10012. {
  10013. if (dev) console.log(`processSectionEntry() wybrano 🤎addVotersList ${sectionEntry.__vue__.item.id} | plusow: ${sectionEntry.__vue__.item.votes.up}`,)
  10014. addVotersList(sectionEntry)
  10015. }
  10016. }
  10017. }
  10018.  
  10019.  
  10020. function animatedAvatar(sectionEntry)
  10021. {
  10022. const image = sectionEntry.querySelector('a.avatar figure img'); // Replace with your actual selector
  10023. if (image)
  10024. {
  10025. if (dev) console.log("image", image)
  10026. const currentSrc = image.getAttribute('src');
  10027. if (dev) console.log("currentSrc", currentSrc)
  10028. if (currentSrc.endsWith('.gif'))
  10029. {
  10030. const modifiedSrc = currentSrc.replace(/,.*?\./, '.');
  10031. image.setAttribute('src', modifiedSrc);
  10032. if (dev) console.log("image.src", image.src)
  10033. }
  10034. }
  10035. }
  10036.  
  10037. function removeVotersListWhenNoVoters(sectionEntry)
  10038. {
  10039. if (sectionEntry)
  10040. {
  10041. delete sectionEntry.dataset?.votersLoaded;
  10042. sectionEntry.querySelector("section.entry-voters")?.remove();
  10043. }
  10044.  
  10045. }
  10046.  
  10047. async function addVotersList(sectionEntry)
  10048. {
  10049. if (dev) console.log(`addVotersList precheck: `, sectionEntry)
  10050.  
  10051. if (!sectionEntry || !sectionEntry.__vue__) return;
  10052.  
  10053. if (sectionEntry.dataset?.votersLoaded == sectionEntry?.__vue__.item.id) return;
  10054.  
  10055. if (dev) console.log(`addVotersList execute: `, sectionEntry)
  10056.  
  10057. if (sectionEntry?.__vue__ && sectionEntry?.__vue__.item.votes.up > 0)
  10058. {
  10059. if (sectionEntry?.__vue__ && settings.entryVotersListExpandIfLessThan > 5 && sectionEntry?.__vue__.item.votes.up <= settings.entryVotersListExpandIfLessThan && sectionEntry?.__vue__.item.votes.up > 5)
  10060. {
  10061. let entryId, commentId;
  10062. if (sectionEntry?.__vue__?.item.resource == "entry")
  10063. {
  10064. entryId = sectionEntry?.__vue__?.item.id;
  10065. }
  10066. else if (sectionEntry?.__vue__?.item.resource == "entry_comment")
  10067. {
  10068. entryId = sectionEntry?.__vue__?.item.parent.id;
  10069. commentId = sectionEntry?.__vue__?.item.id;
  10070. }
  10071. let voters = await fetchAllVotersFromAPI(entryId, commentId);
  10072.  
  10073. appendVotersToEntry(sectionEntry, voters);
  10074.  
  10075. }
  10076. else
  10077. {
  10078. appendVotersToEntry(sectionEntry, sectionEntry?.__vue__?.item?.votes?.users);
  10079. }
  10080. }
  10081. }
  10082.  
  10083. function addFavouriteButton(sectionEntry)
  10084. {
  10085. if (sectionEntry && sectionEntry?.__vue__)
  10086. {
  10087. const sectionActionsUL = sectionEntry.querySelector("section.actions:not(:has(li.favourite)) > ul");
  10088. if (!sectionActionsUL) return;
  10089.  
  10090. let entryId, commentId;
  10091.  
  10092. let isFavourite = sectionEntry?.__vue__?.item.favourite;
  10093.  
  10094. if (sectionEntry?.__vue__?.item.resource == "entry")
  10095. {
  10096. entryId = sectionEntry?.__vue__?.item.id;
  10097. }
  10098. else if (sectionEntry?.__vue__?.item.resource == "entry_comment")
  10099. {
  10100. entryId = sectionEntry?.__vue__?.item.parent.id;
  10101. commentId = sectionEntry?.__vue__?.item.id;
  10102. }
  10103.  
  10104. const favButtonLI = document.createElement("li");
  10105. favButtonLI.classList.add("favourite", "icon", "icon-favourite");
  10106.  
  10107.  
  10108. if (isFavourite) { favButtonLI.classList.add("active"); }
  10109. const favButtonSpan = document.createElement("span");
  10110. favButtonSpan.classList.add("favouriteButton");
  10111.  
  10112. // VUE SENSITIVE
  10113. /*
  10114. data-v-90179052
  10115. */
  10116. favButtonLI.setAttribute('data-v-90179052', '');
  10117. favButtonSpan.setAttribute('data-v-90179052', '');
  10118.  
  10119. favButtonSpan.dataset.isFavourite = isFavourite;
  10120. favButtonSpan.dataset.entryId = entryId;
  10121. if (commentId) favButtonSpan.dataset.commentId = commentId;
  10122. if (settings.showFavouriteButtonLabel) favButtonSpan.innerText = `Ulubione`;
  10123. favButtonLI.appendChild(favButtonSpan);
  10124.  
  10125. const sharingElement = sectionActionsUL.querySelector(".sharing");
  10126. if (sharingElement) sharingElement.insertAdjacentElement("afterend", favButtonLI);
  10127.  
  10128. }
  10129.  
  10130. }
  10131.  
  10132.  
  10133.  
  10134.  
  10135. function appendVotersToEntry(sectionEntry, voters)
  10136. {
  10137.  
  10138.  
  10139. if (!sectionEntry) return;
  10140. const divEditWrapperElement = sectionEntry.querySelector('article > div.edit-wrapper');
  10141. if (!divEditWrapperElement) return;
  10142.  
  10143. if (dev) console.log(`💚 appendVotersToEntry start`, sectionEntry)
  10144.  
  10145. sectionEntry.dataset.votersLoaded = sectionEntry?.__vue__?.item.id;
  10146.  
  10147. if (dev) console.log(`appendVotersToEntry: ${sectionEntry?.__vue__?.item.id}`, voters)
  10148.  
  10149.  
  10150. const fiveVoters = voters;
  10151.  
  10152. if (!fiveVoters || fiveVoters.length < 1) return false;
  10153.  
  10154. let sectionEntryVotersHTML = `<ul>`;
  10155.  
  10156. fiveVoters.forEach(voter =>
  10157. {
  10158. sectionEntryVotersHTML += getListItemForUser(voter);
  10159. });
  10160.  
  10161. // <li class="more">
  10162. if (sectionEntry?.__vue__?.item?.votes.up > settings.entryVotersListExpandIfLessThan && voters.length <= settings.entryVotersListExpandIfLessThan)
  10163. {
  10164. sectionEntryVotersHTML += `
  10165. <li data-no-bubble="" class="more">
  10166. <span data-votes-up="${sectionEntry?.__vue__?.item?.votes.up}"`;
  10167.  
  10168. if (sectionEntry?.__vue__?.item.resource == "entry")
  10169. {
  10170. sectionEntryVotersHTML += `data-entry-id="${sectionEntry?.__vue__?.item.id}"`;
  10171. }
  10172. else if (sectionEntry?.__vue__?.item.resource == "entry_comment")
  10173. {
  10174. sectionEntryVotersHTML += `data-entry-id="${sectionEntry?.__vue__?.item.parent.id}"`;
  10175. sectionEntryVotersHTML += `data-comment-id="${sectionEntry?.__vue__?.item.id}"`;
  10176. }
  10177.  
  10178. sectionEntryVotersHTML += `>+${sectionEntry?.__vue__?.item?.votes.up - 5} innych</span></li>`;
  10179. }
  10180. sectionEntryVotersHTML += `</ul>`;
  10181.  
  10182. const sectionEntryVoters = document.createElement("section");
  10183. sectionEntryVoters.classList.add("entry-voters");
  10184. // sectionEntryVoters.setAttribute('data-v-6e6ed6ee', '');
  10185. // sectionEntryVoters.setAttribute('data-v-2aacfeb5', '');
  10186. sectionEntryVoters.innerHTML = sectionEntryVotersHTML;
  10187.  
  10188. const sectionEntryVotersElement = divEditWrapperElement.querySelector('section.entry-voters');
  10189.  
  10190. if (sectionEntryVotersElement)
  10191. {
  10192. let parentElement = sectionEntryVotersElement.parentNode;
  10193. parentElement.replaceChild(sectionEntryVoters, sectionEntryVotersElement);
  10194. }
  10195. else
  10196. {
  10197. const editWrapper = sectionEntry.querySelector(".edit-wrapper");
  10198. if (editWrapper) editWrapper.appendChild(sectionEntryVoters);
  10199. }
  10200. }
  10201.  
  10202. function getListItemForUser(voter)
  10203. {
  10204. let userHTML = `<li>
  10205. <a href="/ludzie/${voter.username}" class="username`;
  10206.  
  10207. userHTML += ` ${voter.color}-profile`; // orange-profile green-profile burgundy-profile
  10208. userHTML += ` ${voter.status}`; // active banned suspended removed
  10209. userHTML += ` follow-${voter.follow}`; // follow-true follow-false
  10210. userHTML += ` verified-${voter.verified}`; // verified-false
  10211. userHTML += ` blacklist-${voter.blacklist}`;// blacklist-true blacklist-false
  10212. userHTML += ` online-${voter.online}`; // online-true online-false
  10213.  
  10214. userHTML += ` ${voter.gender}-gender`; // m-gender, f-gender, null-gender
  10215. if (voter.gender == "m") userHTML += ` male`;
  10216. else if (voter.gender == "f") userHTML += ` female`;
  10217. userHTML += `">`;
  10218.  
  10219.  
  10220. if (settings?.votersFollow && voter.follow) userHTML += `<i class="follow-true" title="Obserwujesz tego użytkownika"></i>`;
  10221. if (settings?.votersVerified && voter.verified) userHTML += `<i class="verified-true" title="Ten użytkownik jest zweryfikowany"></i>`;
  10222. if (settings?.votersBlacklist && voter.blacklist) userHTML += `<i class="blacklist-true" title="Ten użytkownik jest na Twojej czarnej liście"></i>`;
  10223. if (settings?.votersOffline && !voter.online) userHTML += `<i class="online-false" title="Ten uzytkownik jest teraz offline"></i>`;
  10224. if (settings?.votersOnline && voter.online) userHTML += `<i class="online-true" title="Ten uzytkownik jest teraz online"></i>`;
  10225. if (settings?.votersBanned && voter.status == "banned") userHTML += `<i class="banned" title="Użytkownik dostał bana. Z dodatkiem Wykop XS - Ban Info możesz szybko sprawdzić przyczynę i długość trwania bana."></i>`;
  10226. if (settings?.votersSuspended && voter.status == "suspended") userHTML += `<i class="suspended" title="To konto jest w trakcie usuwania."></i>`;
  10227. if (settings?.votersRemoved && voter.status == "removed") userHTML += `<i class="removed" title="Konto usunięte"></i>`;
  10228. if (settings?.votersGenderM && voter.gender == "m") userHTML += `<i class="${voter.gender}-gender" title="Wpis od niebieskiego"></i>`;
  10229. if (settings?.votersGenderF && voter.gender == "f") userHTML += `<i class="${voter.gender}-gender" title="Plus od różowej"></i>`;
  10230.  
  10231. userHTML += `<span>${voter.username}</span>
  10232. </a>
  10233. </li>`;
  10234.  
  10235. return userHTML;
  10236. }
  10237.  
  10238.  
  10239. /*
  10240. <section data-v-6e6ed6ee="" data-v-2aacfeb5="" class="entry-voters">
  10241. <ul data-v-6e6ed6ee="">
  10242. <li data-v-6e6ed6ee="" class="">
  10243. <a data-v-ed9f6c56="" data-v-6e6ed6ee="" href="/ludzie/NaczelnyAgnostyk" class="username orange-profile active">
  10244. <span data-v-ed9f6c56="">
  10245. NaczelnyAgnostyk<!---->
  10246. </span>
  10247. </a>
  10248. </li>
  10249. <li data-v-6e6ed6ee="" data-no-bubble="" class="more">
  10250. <span data-v-6e6ed6ee="">+5 innych</span>
  10251. </li>
  10252. </ul>
  10253. </section>
  10254. */
  10255.  
  10256. function fetchAllVotersFromAPI(entryId, commentId)
  10257. {
  10258. if (dev) console.log(`fetchAllVotersFromAPI: ${entryId}, ${commentId}`)
  10259. let apiURL = `https://wykop.pl/api/v3/entries/${entryId}/votes?page=1`
  10260. if (commentId) apiURL = `https://wykop.pl/api/v3/entries/${entryId}/comments/${commentId}/votes`;
  10261.  
  10262. return new Promise(async (resolve, reject) =>
  10263. {
  10264. await fetch(apiURL, {
  10265. method: "GET",
  10266. headers: {
  10267. "Content-Type": "application/json",
  10268. Authorization: "Bearer " + window.localStorage.getItem("token"),
  10269. },
  10270. })
  10271. .then((response) =>
  10272. {
  10273. if (!response.ok)
  10274. {
  10275. if (dev) console.log("HTTP error! status: ${response.status}");
  10276. // throw new Error(`HTTP error! status: ${response.status}`);
  10277. }
  10278. return response.json();
  10279. })
  10280. .then(async (responseJSON) =>
  10281. {
  10282. resolve(responseJSON.data);
  10283.  
  10284. }).catch((error) =>
  10285. {
  10286. if (error instanceof TypeError)
  10287. {
  10288. console.error('Network error:', error); // AWARIA SERWERA WYPOKU
  10289. } else
  10290. {
  10291. console.error('Other error:', error);
  10292. }
  10293. reject(error);
  10294. });
  10295. });
  10296. }
  10297.  
  10298. function postFavouriteToAPI(favourite, resource, id)
  10299. {
  10300. let apiURL = `https://wykop.pl/api/v3/favourites`;
  10301. const method = favourite ? "POST" : "DELETE";
  10302. const body = {
  10303. data: {
  10304. type: resource,
  10305. source_id: id
  10306. }
  10307. }
  10308.  
  10309. return new Promise(async (resolve, reject) =>
  10310. {
  10311. await fetch(apiURL, {
  10312. method: method,
  10313. headers: {
  10314. "Content-Type": "application/json",
  10315. Authorization: "Bearer " + window.localStorage.getItem("token"),
  10316. },
  10317. body: JSON.stringify(body)
  10318. })
  10319. .then((response) =>
  10320. {
  10321. if (!response.ok)
  10322. {
  10323. if (dev) console.log("HTTP error! status: ${response.status}");
  10324. // throw new Error(`HTTP error! status: ${response.status}`);
  10325. }
  10326. return response.json();
  10327. })
  10328. .then(async (responseJSON) =>
  10329. {
  10330. resolve(responseJSON.data);
  10331.  
  10332. }).catch((error) =>
  10333. {
  10334. if (error instanceof TypeError)
  10335. {
  10336. console.error('Network error:', error); // AWARIA SERWERA WYPOKU
  10337. } else
  10338. {
  10339. console.error('Other error:', error);
  10340. }
  10341. reject(error);
  10342. });
  10343.  
  10344. });
  10345. }
  10346.  
  10347. function postCommentPlus1ToAPI(sectionEntry)
  10348. {
  10349. if (!sectionEntry || !sectionEntry.__vue__) return;
  10350.  
  10351. const resource = sectionEntry.__vue__.item.resource;
  10352. let entryId;
  10353. let authorUsername = sectionEntry.__vue__.item.author.username;
  10354. if (resource === "entry")
  10355. entryId = sectionEntry.__vue__.item.id;
  10356.  
  10357. else if (resource === "entry_comment")
  10358. entryId = sectionEntry.__vue__.item.parent.id;
  10359.  
  10360. // TODO ZNALEZISKA
  10361.  
  10362. let apiURL = `https://wykop.pl/api/v3/entries/${entryId}/comments`;
  10363. const method = "POST";
  10364. const body = {
  10365. data: {
  10366. "content": `@${authorUsername} [+](https://greasyfork.org/en/scripts/489949)1`,
  10367. "adult": false
  10368. }
  10369. }
  10370. /*
  10371. "data":
  10372. {
  10373. "content": "**foobar** __foobar__ [lorem](https://www.wykop.pl) impsum!!! #nsfw #wykop",
  10374. "embed": "1fde707843ss3fbe9cb4eed0asdfsdfc64ab9a4df6084199b39d2",
  10375. "photo": "e07843ss3fbe9cb4saeed0asdfsdfc64b9a4df6084199b39d2",
  10376. "adult": false
  10377. }
  10378. }
  10379. */
  10380.  
  10381. return new Promise(async (resolve, reject) =>
  10382. {
  10383. await fetch(apiURL, {
  10384. method: method,
  10385. headers: {
  10386. "Content-Type": "application/json",
  10387. Authorization: "Bearer " + window.localStorage.getItem("token"),
  10388. },
  10389. body: JSON.stringify(body)
  10390. })
  10391. .then((response) =>
  10392. {
  10393. if (!response.ok)
  10394. {
  10395. if (dev) console.log("HTTP error! status: ${response.status}");
  10396. // throw new Error(`HTTP error! status: ${response.status}`);
  10397. }
  10398. return response.json();
  10399. })
  10400. .then(async (responseJSON) =>
  10401. {
  10402. resolve(responseJSON.data);
  10403.  
  10404. }).catch((error) =>
  10405. {
  10406. if (error instanceof TypeError)
  10407. {
  10408. console.error('Network error:', error); // AWARIA SERWERA WYPOKU
  10409. } else
  10410. {
  10411. console.error('Other error:', error);
  10412. }
  10413. reject(error);
  10414. });
  10415.  
  10416. });
  10417. }
  10418.  
  10419.  
  10420.  
  10421.  
  10422.  
  10423. // li.more click
  10424. document.addEventListener("click", async function (e)
  10425. {
  10426. if (e.target.closest("div.buttons button.plus"))
  10427. {
  10428. const sectionEntry = e.target.closest("section.entry[id]");
  10429. if (sectionEntry.__vue__?.item?.voted == 1)
  10430. {
  10431. if (settings.addCommentPlusWhenVotingOnEntry && sectionEntry && sectionEntry.__vue__?.item?.resource == "entry")
  10432. {
  10433. postCommentPlus1ToAPI(sectionEntry);
  10434. }
  10435. else if (settings.addCommentPlusWhenVotingOnComment && sectionEntry && sectionEntry.__vue__?.item?.resource == "entry_comment")
  10436. {
  10437. postCommentPlus1ToAPI(sectionEntry);
  10438. }
  10439. }
  10440. }
  10441.  
  10442. if (e.target.matches("li.more span"))
  10443. {
  10444. e.preventDefault();
  10445.  
  10446. let sectionEntry = e.target.closest("section.entry");
  10447. const entryId = e.target.dataset.entryId;
  10448. const commentId = e.target.dataset.commentId;
  10449. if (dev) console.log(`Wykop XS pobiera listę ${e.target.dataset.votesUp} plusujących`);
  10450. e.target.closest("section.entry-voters").innerHTML = `<span>(Wykop X: wczytywanie ${e.target.dataset.votesUp} plusujących...)</span>`;
  10451.  
  10452. let voters = await fetchAllVotersFromAPI(entryId, commentId);
  10453.  
  10454. appendVotersToEntry(sectionEntry, voters);
  10455. return;
  10456. }
  10457.  
  10458. if (e.target.matches("span.favouriteButton"))
  10459. {
  10460. e.preventDefault();
  10461. if (e.target.dataset.isFavourite == "true")
  10462. {
  10463. if (e.target.dataset.commentId) postFavouriteToAPI(false, "entry_comment", e.target.dataset.commentId);
  10464. else postFavouriteToAPI(false, "entry", e.target.dataset.entryId);
  10465. e.target.parentElement.classList.remove("active");
  10466. e.target.dataset.isFavourite = "false";
  10467.  
  10468. }
  10469. else if (e.target.dataset.isFavourite == "false")
  10470. {
  10471. if (e.target.dataset.commentId) postFavouriteToAPI(true, "entry_comment", e.target.dataset.commentId);
  10472. else postFavouriteToAPI(true, "entry", e.target.dataset.entryId);
  10473. e.target.parentElement.classList.add("active");
  10474. e.target.dataset.isFavourite = "true";
  10475. }
  10476. return;
  10477. }
  10478. }, false);
  10479.  
  10480.  
  10481.  
  10482.  
  10483.  
  10484. /* CSS WYKOP XS MIKROCZAT */
  10485. if (settings?.hideShareButton) CSS += `section.actions ul li.sharing { display: none!important; }`;
  10486.  
  10487.  
  10488. /* Wykop X Style 3.0 */
  10489. CSS += `
  10490. :root
  10491. {
  10492. --kolorBananowy1: rgba(255, 185, 0, 1);
  10493. --tagChannelColor: rgba(0, 183, 255, 1);
  10494. --smallBorderRadius: 4px;
  10495. }
  10496. div[data-modal="entryVoters"] section.entry-voters::after {content: none!important;} /* Wykop X Style PROMO */
  10497. `;
  10498.  
  10499. /* LISTA PLUSUJĄCYCH CSS, PRZYCISK DODAJ DO ULUBIONYCH */
  10500. if (settings?.entryVotersListEnable)
  10501. {
  10502. CSS += `
  10503. /* Chrome 109, Firefox 115 */
  10504. @supports not (display: block flex)
  10505. {
  10506. section.entry-voters ul
  10507. {
  10508. display: flex;
  10509. }
  10510. }
  10511.  
  10512. section.entry-voters ul
  10513. {
  10514. display: block flex;
  10515. row-gap: 0px;
  10516. flex-wrap: wrap;
  10517. align-items: baseline;
  10518. padding: 0 0 0 0;
  10519. margin: 0;
  10520. margin-top: 8px;
  10521. list-style-type: none;
  10522. position: relative;
  10523. }
  10524.  
  10525. section.entry-voters ul,
  10526. section.entry-voters > span
  10527. {
  10528. font-size: var(--entryVotersTextFontSize, 12px);
  10529. color: var(--gullGray);
  10530. }
  10531.  
  10532. section.entry-voters ul::before
  10533. {
  10534. content: "Plusujący: ";
  10535. margin-right: 0.2em;
  10536. }
  10537.  
  10538. section.entry-voters ul li.more
  10539. {
  10540. cursor: pointer;
  10541. font-weight: 700;
  10542. text-transform: uppercase;
  10543. }
  10544.  
  10545. section.entry-voters ul li::after
  10546. {
  10547. content: " • ";
  10548. margin: 0px 0.2em 0px 0em;
  10549. }
  10550.  
  10551. section.entry-voters ul li.more::after,
  10552. section.entry-voters ul li:only-child::after
  10553. { content: none; }
  10554.  
  10555. section.entry-voters ul li a.username span
  10556. {
  10557. font-weight: normal;
  10558. }
  10559.  
  10560. section.entry-voters ul li a.username i { display: none; font-size: 0.8em; font-style: normal; bottom: 0px; position: relative; }
  10561. section.entry-voters ul li a.username i:has(+span) { margin-right: 1px; }
  10562. section.entry-voters ul li a.username i.follow-true,
  10563. section.entry-voters ul li a.username i.blacklist-true,
  10564. section.entry-voters ul li a.username i.banned ,
  10565. section.entry-voters ul li a.username i.suspended,
  10566. section.entry-voters ul li a.username i.removed,
  10567. section.entry-voters ul li a.username i.f-gender,
  10568. section.entry-voters ul li a.username i.m-gender
  10569. { display: inline flex;}
  10570. section.entry-voters ul li a.username i.follow-true::before { content: '🔔'; }
  10571. section.entry-voters ul li a.username i.blacklist-true::before { content: '⛔'; }
  10572. section.entry-voters ul li a.username i.banned::before { content: '🍌'; }
  10573. section.entry-voters ul li a.username i.suspended::before { content: '✖'; }
  10574. section.entry-voters ul li a.username i.removed::before { content: '❌'; }
  10575. section.entry-voters ul li a.username i.f-gender::before { content: '🟣'; font-size: 0.7em; bottom: 3px; }
  10576. section.entry-voters ul li:has(a.username) { order: 6; }
  10577. section.entry-voters ul li.more { order: 100; }
  10578. `;
  10579.  
  10580. if (settings?.votersFollowFirst) CSS += `section.entry-voters ul li:has(a.username.follow-true) { order: 1; }`;
  10581. if (settings?.votersBlackFirst) CSS += `section.entry-voters ul li:has(a.username.burgundy-profile) { order: 3; }`;
  10582. if (settings?.votersOrangeFirst) CSS += `section.entry-voters ul li:has(a.username.orange-profile) { order: 4; }`;
  10583. if (settings?.votersGreenFirst) CSS += `section.entry-voters ul li:has(a.username.green-profile) { order: 5; }`;
  10584.  
  10585. if (settings?.votersBlacklistLast) CSS += `section.entry-voters ul li:has(a.username.blacklist-true) { order: 7; }`;
  10586. if (settings?.votersBannedLast) CSS += `section.entry-voters ul li:has(a.username.banned) { order: 8; }`;
  10587. if (settings?.votersSuspendedLast) CSS += `section.entry-voters ul li:has(a.username.banned) { order: 9; }`;
  10588. if (settings?.votersRemovedLast) CSS += `section.entry-voters ul li:has(a.username.removed) { order: 10; }`;
  10589.  
  10590. if (!settings?.votersColorOrange) CSS += `section.entry-voters ul li a.username.orange-profile { color: var(--gullGray); }`;
  10591. if (!settings?.votersColorGreen) CSS += `section.entry-voters ul li a.username.green-profile { color: var(--gullGray); }`;
  10592. if (!settings?.votersColorBurgundy) CSS += `section.entry-voters ul li a.username.burgundy-profile { color: var(--gullGray); }`;
  10593.  
  10594. CSS += `
  10595. section.entry-voters ul li a.username.banned:not(.removed) span { color: var(--kolorBananowy1); };
  10596. section.entry-voters ul li a.username.suspended:not(.removed) span { color: var(--heather); }
  10597. section.entry-voters ul li a.username.removed span { color: var(--heather); }
  10598. [data-night-mode] section.entry-voters ul li a.username.removed span { background-color: rgba(255, 255, 255, 0.1); padding-left: 5px; padding-right: 5px; }
  10599. `;
  10600. }
  10601.  
  10602.  
  10603.  
  10604. /* ULUBIONE */
  10605. CSS += `
  10606. section.actions > ul > li.favourite
  10607. {
  10608. cursor: pointer;
  10609. user-select: none;
  10610. color: var(--gullGray);
  10611. font-size: 14px;
  10612. padding-left: 26px;
  10613. transition: color .2s ease, opacity .2s ease;
  10614. }
  10615.  
  10616. .actions li.favourite span::before
  10617. {
  10618. content: '';
  10619. width: 18px;
  10620. height: 18px;
  10621. display: block;
  10622. position: absolute;
  10623. left: 0;
  10624. background: var(--gullGray);
  10625. transition: background .2s ease;
  10626.  
  10627. -webkit-mask-size: 18px 18px;
  10628. mask-size: 18px 18px;
  10629. -webkit-mask: url(/static/img/svg/favourite.svg) no-repeat center;
  10630. mask-image: url(/static/img/svg/favourite.svg);
  10631. }
  10632. .actions li.favourite.active span::before
  10633. {
  10634. background: var(--orange);
  10635. -webkit-mask: url(/static/img/svg/favourite-filled.svg) no-repeat center;
  10636. mask-image: url(/static/img/svg/favourite-filled.svg);
  10637. }
  10638. `;
  10639.  
  10640. /* fixNotificationBadgeBug */
  10641. // if (settings.fixNotificationBadgeBug)
  10642. // {
  10643. // CSS += `
  10644. // :root
  10645. // {
  10646. // /* brak nowych powiadomień */
  10647. // --notificationIconWithoutUnreadNotificationsColor: rgba(255, 255, 255, 0.2); /* ikonka powiadomienia ✉ 🕭 #, jesli nie ma nowych powiadomien */
  10648. // --notificationIconWithoutUnreadNotificationsBackgroundColor: rgba(0, 0, 0, 0); /* tło powiadomienia ✉ 🕭 #, jesli nie ma nowych powiadomien */
  10649. // --notificationIconWithoutUnreadNotificationsHoverColor: rgba(255, 255, 255, 0.8);
  10650. // --notificationIconWithoutUnreadNotificationsHoverBackgroundColor: rgba(255, 255, 255, 0.3);
  10651. // --notificationIconWithoutUnreadNotificationsActiveColor: rgba(255, 255, 255, 0.4);
  10652. // --notificationIconWithoutUnreadNotificationsActiveBackgroundColor: rgba(255, 255, 255, 0.2);
  10653. // }
  10654. // `;
  10655. // }
  10656.  
  10657.  
  10658.  
  10659.  
  10660. /* ------------- NOTATKOWATOR + INFOBOX + USER LABELS ----------------- */
  10661. if (settings.infoboxEnable || settings.notatkowatorEnable || settings.wxsUserLabelsEnable)
  10662. {
  10663. CSS += `
  10664. /* infobox wrapper */
  10665. .wxs_user_info
  10666. {
  10667. display: flex!important;
  10668. align-items: baseline!important;
  10669. gap: 6px!important;
  10670. font-size: 11px!important;
  10671. cursor: help!important;
  10672. }
  10673.  
  10674.  
  10675. /* wpisy {} */
  10676. section.entry > article.wxs_user_info
  10677. {
  10678. }
  10679. /* znaleziska {} */
  10680. section.link-block article.wxs_user_info
  10681. {
  10682. margin-right: 5px;
  10683. }
  10684.  
  10685. /* kropka online w naglowku profilu uzytkownika */
  10686. aside.profile-top > section > header > div > h1 > a.online > span > i
  10687. {
  10688. display: block;
  10689. top: 0px;
  10690. left: -18px;
  10691. }
  10692. /* 🟢 zielona ikonka statusu online */
  10693. section header div.wxs_user_info.wxs_user_online
  10694. {
  10695. order: 1;
  10696. font-size: 5px;
  10697. }
  10698.  
  10699. /* notatka na profilu użytkownika */
  10700. aside.profile-top > section > header > div > h1
  10701. {
  10702. align-items: baseline!important;
  10703. }
  10704. aside.profile-top > section > header > div > h1 > div.wxs_user_info
  10705. {
  10706. margin-left: 8px;
  10707. position: relative;
  10708. bottom: 2px;
  10709. }
  10710. .wxs_user_info var
  10711. {
  10712. font-style: normal;
  10713. font-size: 12px;
  10714. opacity: 1;
  10715. }
  10716. .wxs_user_label
  10717. {
  10718. border-radius: 4px;
  10719. }
  10720. .wxs_user_label: hover
  10721. {
  10722. filter: brightness(1.2);
  10723. }
  10724. .wxs_user_label > *,
  10725. .wxs_user_member_since
  10726. {
  10727. border-radius: 4px;
  10728. padding: 1px 9px;
  10729. font-size: 12px;
  10730. font-weight: bolder;
  10731. background-color: var(--alto);
  10732. }
  10733. .wxs_user_label
  10734. {
  10735. order: 10;
  10736. }
  10737. .wxs_user_label_fake_gender
  10738. {
  10739. order: 1;
  10740. }
  10741. .wxs_user_label_fake_female
  10742. {
  10743. color: var(--rozowyPasek1, rgba(192, 72, 167, 1));
  10744. }
  10745. .wxs_user_label_fake_male
  10746. {
  10747. color: var(--niebieskiPasek1, rgba(67, 131, 175, 1));
  10748. }
  10749. /* XLabel troll/bot */
  10750. .wxs_user_label_name
  10751. {
  10752. order: 2;
  10753. color: var(--persianRed);
  10754. }
  10755.  
  10756. /* LINKI-adresy URL w notatce */
  10757. .wxs_user_label_url,
  10758. .wxs_user_info_usernote_url
  10759. {
  10760. order: 3;
  10761. }
  10762. .wxs_user_label_url > a
  10763. {
  10764. background-color: var(--alto);
  10765. color: var(--userCustomColorLinkExternal, rgb(52, 125, 219));
  10766. }
  10767. .wxs_user_info_usernote_url > a
  10768. {
  10769. background-color: var(--alto);
  10770. color: var(--userCustomColorLinkInternal, rgb(23, 71, 140));
  10771. }
  10772. .wxs_user_info_usernote_url
  10773. {
  10774. order: 4;
  10775. display: flex;
  10776. gap: 4px;
  10777. }
  10778.  
  10779. /* ban */
  10780. .wxs_user_banned
  10781. {
  10782. order: 9;
  10783. }
  10784. /* 🔔 obserwujesz użytkownika */
  10785. .wxs_user_follow,
  10786. .wxs_user_blacklist
  10787. {
  10788. order: 10;
  10789. }
  10790. .wxs_user_member_since
  10791. {
  10792. order: 20;
  10793. background-color: var(--alto);
  10794. }
  10795. .wxs_user_info_usernote
  10796. {
  10797. order: 40;
  10798. border-radius: 4px;
  10799. padding: 1px 9px;
  10800. font-size: 12px;
  10801. background-color: rgba(196, 183, 123, .2);
  10802. background-color: var(--alto);
  10803. }
  10804.  
  10805. /* ukrycie dodanego roku oraz notatki do nazwy uzytkownika na liście plusujących */
  10806. section.entry-voters > ul > li > div.wxs_user_info > .wxs_user_info_usernote,
  10807. section.entry-voters > ul > li > div.wxs_user_info > .wxs_user_member_since
  10808. {
  10809. display: none!important;
  10810. }
  10811.  
  10812. /* NOTATKA DO UŻYTKOWNIKA */
  10813. .wxs_user_info
  10814. {
  10815. --notatkowator_color_red: rgb(255, 0, 0);
  10816. --notatkowator_color_green: rgb(14, 137, 39);
  10817. --notatkowator_color_blue: rgb(66, 141, 255);
  10818. --notatkowator_color_orange: rgb(179, 89, 30);
  10819. --notatkowator_color_pink: rgb(219, 14, 191);
  10820. --notatkowator_color_yellow: rgb(253, 246, 50);
  10821. }
  10822.  
  10823. .wxs_user_info_usernote.wxs_notatkowator_c { color: var(--notatkowator_color_red); }
  10824. .wxs_user_info_usernote.wxs_notatkowator_z { color: var(--notatkowator_color_green); }
  10825. .wxs_user_info_usernote.wxs_notatkowator_n { color: var(--notatkowator_color_blue); }
  10826. .wxs_user_info_usernote.wxs_notatkowator_p { color: var(--notatkowator_color_orange); }
  10827. .wxs_user_info_usernote.wxs_notatkowator_r { color: var(--notatkowator_color_pink); }
  10828. .wxs_user_info_usernote.wxs_notatkowator_ż { color: var(--notatkowator_color_yellow); }
  10829.  
  10830. /* notatka pod avatarem */
  10831. section.entry > article > header + .wxs_user_info_usernote
  10832. {
  10833. display: flex!important;
  10834. border-bottom: 1px solid rgba(128, 128, 128, 0.1);
  10835. background-color: var(--whiteOpacity06);
  10836. border-radius: 4px;
  10837. padding: 10px;
  10838. margin-top: 16px;
  10839. margin-bottom: 4px;
  10840. font-size: 13px;
  10841. color: var(--blackOpacity09, rgba(255, 255, 255, 1));
  10842. }
  10843.  
  10844. section.entry > article > header + .wxs_user_info_usernote
  10845. {
  10846. color: var(--blackOpacity07, rgba(255, 255, 255, 1));
  10847. }`;
  10848. }
  10849.  
  10850.  
  10851. /* HIDE ADS ALWAYS */
  10852. if (settings.hideAds) { CSS += `.pub-slot-wrapper { display: none!important; }`; }
  10853.  
  10854.  
  10855.  
  10856.  
  10857. styleElement.textContent = CSS;
  10858. document.head.appendChild(styleElement);
  10859. }
  10860.  
  10861. })();
  10862.  
  10863.  
  10864.  
  10865.  
  10866.  
  10867.  
  10868.  
  10869.  
  10870.  
  10871.  
  10872.  
  10873.  
  10874.  
  10875.  
  10876.  
  10877.  
  10878. // https://cdn.jsdelivr.net/gh/CoeJoder/waitForKeyElements.js@latest/waitForKeyElements.js
  10879. /**
  10880. * A utility function for userscripts that detects and handles AJAXed content.
  10881. *
  10882. * @example
  10883. * waitForKeyElements("div.comments", (element) => {
  10884. * element.innerHTML ="This text inserted by waitForKeyElements().";
  10885. * });
  10886. *
  10887. * waitForKeyElements(() => {
  10888. * const iframe = document.querySelector('iframe');
  10889. * if (iframe) {
  10890. * const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
  10891. * return iframeDoc.querySelectorAll("div.comments");
  10892. * }
  10893. * return null;
  10894. * }, callbackFunc);
  10895. *
  10896. * @param {(string|function)} selectorOrFunction - The selector string or function.
  10897. * @param {function} callback - The callback function; takes a single DOM element as parameter.
  10898. * If returns true, element will be processed again on subsequent iterations.
  10899. * @param {boolean} [waitOnce=true] - Whether to stop after the first elements are found.
  10900. * @param {number} [interval=300] - The time (ms) to wait between iterations.
  10901. * @param {number} [maxIntervals=-1] - The max number of intervals to run (negative number for unlimited).
  10902. */
  10903. function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals)
  10904. {
  10905. if (typeof waitOnce === "undefined")
  10906. {
  10907. waitOnce = true;
  10908. }
  10909. if (typeof interval === "undefined")
  10910. {
  10911. interval = 300;
  10912. }
  10913. if (typeof maxIntervals === "undefined")
  10914. {
  10915. maxIntervals = -1;
  10916. }
  10917. if (typeof waitForKeyElements.namespace === "undefined")
  10918. {
  10919. waitForKeyElements.namespace = Date.now().toString();
  10920. }
  10921. var targetNodes = (typeof selectorOrFunction === "function")
  10922. ? selectorOrFunction()
  10923. : document.querySelectorAll(selectorOrFunction);
  10924.  
  10925. var targetsFound = targetNodes && targetNodes.length > 0;
  10926. if (targetsFound)
  10927. {
  10928. targetNodes.forEach(function (targetNode)
  10929. {
  10930. var attrAlreadyFound = `data-userscript-${waitForKeyElements.namespace}-alreadyFound`;
  10931. var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false;
  10932. if (!alreadyFound)
  10933. {
  10934. var cancelFound = callback(targetNode);
  10935. if (cancelFound)
  10936. {
  10937. targetsFound = false;
  10938. }
  10939. else
  10940. {
  10941. targetNode.setAttribute(attrAlreadyFound, true);
  10942. }
  10943. }
  10944. });
  10945. }
  10946.  
  10947. if (maxIntervals !== 0 && !(targetsFound && waitOnce))
  10948. {
  10949. maxIntervals -= 1;
  10950. setTimeout(function ()
  10951. {
  10952. waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals);
  10953. }, interval);
  10954. }
  10955. }