pervert-monkey 1.0.7 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ // ==UserScript==
2
+ // @name Xhamster Improved
3
+ // @namespace pervertmonkey
4
+ // @version 5.0.1
5
+ // @author violent-orangutan
6
+ // @description Infinite scroll [optional], Filter by Title and Duration
7
+ // @license MIT
8
+ // @icon https://www.google.com/s2/favicons?sz=64&domain=xhamster.com
9
+ // @homepage https://github.com/smartacephale/sleazy-fork
10
+ // @homepageURL https://github.com/smartacephale/sleazy-fork
11
+ // @source github:smartacephale/sleazy-fork
12
+ // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
+ // @match https://*.xhamster.com/*
14
+ // @match https://*.xhamster.*/*
15
+ // @exclude https://*.xhamster.com/embed*
16
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.8/dist/core/pervertmonkey.core.umd.js
17
+ // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
18
+ // @grant GM_addStyle
19
+ // @grant unsafeWindow
20
+ // @run-at document-idle
21
+ // ==/UserScript==
22
+
23
+ (function (core, utils) {
24
+ 'use strict';
25
+
26
+ var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : undefined)();
27
+
28
+ const IS_VIDEO_PAGE = /^\/videos|moments\//.test(location.pathname);
29
+ const IS_PLAYLIST = /^\/my\/favorites\/videos\/\w+/.test(location.pathname);
30
+ function createThumb(data) {
31
+ const attrsToReplace = {
32
+ href: data.pageURL,
33
+ "data-previewvideo": data.trailerURL,
34
+ "data-previewvideo-fallback": data.trailerFallbackUrl,
35
+ "data-sprite": data.spriteURL,
36
+ title: data.title,
37
+ "data-video-id": data.id,
38
+ srcset: data.thumbURL,
39
+ src: data.imageURL
40
+ };
41
+ const text = {
42
+ ".video-thumb-views": data.views,
43
+ "[title]": data.title,
44
+ '[data-role="video-duration"] div': data.duration
45
+ };
46
+ return utils.instantiateTemplate(".video-thumb", attrsToReplace, text);
47
+ }
48
+ const getPaginationData = !IS_PLAYLIST ? void 0 : async (url) => {
49
+ const data = await utils.fetchJson(url);
50
+ const thumbsHtml = data.list.map((e) => createThumb(e)).join("\n");
51
+ return utils.parseHtml(`<div>${thumbsHtml}</div>`);
52
+ };
53
+ function createPlaylistPaginationStrategy() {
54
+ const collectionId = location.pathname.split("/my/favorites/videos/")[1].split("-")[0];
55
+ const data = _unsafeWindow.initials;
56
+ const paginationLast = data.favoritesVideoPaging.maxPages;
57
+ const paginationOffset = data.favoritesVideoPaging.active;
58
+ const playlistPaginationStrategy = {
59
+ paginationSelector: 'nav[class *= "pagination"]',
60
+ getPaginationLast: () => paginationLast,
61
+ getPaginationOffset: () => paginationOffset,
62
+ getPaginationUrlGenerator: () => (offset) => {
63
+ return `https://xhamster.com/api/front/favorite/get-playlist?id=${collectionId}&perPage=60&page=${offset}`;
64
+ }
65
+ };
66
+ return playlistPaginationStrategy;
67
+ }
68
+ const paginationStrategyOptionsDefault = {
69
+ paginationSelector: ".prev-next-list, .test-pager"
70
+ };
71
+ const paginationStrategyOptions = IS_PLAYLIST ? createPlaylistPaginationStrategy() : paginationStrategyOptionsDefault;
72
+ const rules = new core.RulesGlobal({
73
+ paginationStrategyOptions,
74
+ getPaginationData,
75
+ containerSelectorLast: ".thumb-list",
76
+ thumbsSelector: ".video-thumb",
77
+ titleSelector: ".video-thumb-info__name,.video-thumb-info>a",
78
+ durationSelector: ".thumb-image-container__duration",
79
+ gropeStrategy: "all-in-all",
80
+ getThumbImgDataStrategy: "auto",
81
+ getThumbImgDataAttrDelete: "[loading]",
82
+ customThumbDataSelectors: {
83
+ watched: {
84
+ type: "boolean",
85
+ selector: '[data-role="video-watched'
86
+ }
87
+ },
88
+ customDataSelectorFns: [
89
+ "filterInclude",
90
+ "filterExclude",
91
+ "filterDuration",
92
+ {
93
+ filterWatched: (el, state) => !!(state.filterWatched && el.watched)
94
+ },
95
+ {
96
+ filterUnwatched: (el, state) => !!(state.filterUnwatched && !el.watched)
97
+ }
98
+ ],
99
+ schemeOptions: [
100
+ "Text Filter",
101
+ "Badge",
102
+ {
103
+ title: "Filter Watched",
104
+ content: [
105
+ { filterWatched: false, label: "watched" },
106
+ { filterUnwatched: false, label: "unwatched" }
107
+ ]
108
+ },
109
+ "Duration Filter",
110
+ "Advanced"
111
+ ],
112
+ animatePreview
113
+ });
114
+ function animatePreview() {
115
+ function createPreviewVideoElement(src, mount) {
116
+ const video = document.createElement("video");
117
+ video.playsInline = true;
118
+ video.autoplay = true;
119
+ video.loop = true;
120
+ video.classList.add("thumb-image-container__video");
121
+ video.src = src;
122
+ video.addEventListener(
123
+ "loadeddata",
124
+ () => {
125
+ mount.before(video);
126
+ },
127
+ false
128
+ );
129
+ return () => utils.exterminateVideo(video);
130
+ }
131
+ utils.OnHover.create(
132
+ document.body,
133
+ (e) => e.classList.contains("thumb-image-container__image"),
134
+ (e) => {
135
+ const videoSrc = e.parentElement?.getAttribute("data-previewvideo");
136
+ const onOverCallback = createPreviewVideoElement(videoSrc, e);
137
+ const leaveTarget = e.parentElement?.parentElement;
138
+ return { leaveTarget, onOverCallback };
139
+ }
140
+ );
141
+ }
142
+ function expandMoreVideoPage() {
143
+ utils.watchElementChildrenCount(rules.container, () => setTimeout(parseThumbs, 1800));
144
+ utils.waitForElementToAppear(document.body, 'button[data-role="show-more-next"]', (el) => {
145
+ const observer = new utils.Observer((target) => {
146
+ target.click();
147
+ });
148
+ observer.observe(el);
149
+ });
150
+ }
151
+ function parseThumbs() {
152
+ const containers = utils.getCommonParents(rules.getThumbs(document.body));
153
+ containers.forEach((c) => {
154
+ rules.dataManager.parseData(c, c);
155
+ });
156
+ }
157
+ if (IS_VIDEO_PAGE) {
158
+ expandMoreVideoPage();
159
+ }
160
+
161
+ })(core, utils);
@@ -0,0 +1,87 @@
1
+ // ==UserScript==
2
+ // @name XVideos Improved
3
+ // @namespace pervertmonkey
4
+ // @version 4.0.1
5
+ // @author violent-orangutan
6
+ // @description Infinite scroll [optional], Filter by Title and Duration
7
+ // @license MIT
8
+ // @icon https://www.google.com/s2/favicons?sz=64&domain=xvideos.com
9
+ // @homepage https://github.com/smartacephale/sleazy-fork
10
+ // @homepageURL https://github.com/smartacephale/sleazy-fork
11
+ // @source github:smartacephale/sleazy-fork
12
+ // @supportURL https://github.com/smartacephale/sleazy-fork/issues
13
+ // @match https://*.xvideos.com/*
14
+ // @require https://cdn.jsdelivr.net/npm/pervert-monkey@1.0.8/dist/core/pervertmonkey.core.umd.js
15
+ // @require data:application/javascript,var core = window.pervertmonkey.core || pervertmonkey.core; var utils = core;
16
+ // @grant GM_addStyle
17
+ // @grant unsafeWindow
18
+ // @run-at document-idle
19
+ // ==/UserScript==
20
+
21
+ (function (core, utils) {
22
+ 'use strict';
23
+
24
+ var _unsafeWindow = (() => typeof unsafeWindow != "undefined" ? unsafeWindow : undefined)();
25
+
26
+ const xv = _unsafeWindow.xv;
27
+ new core.RulesGlobal({
28
+ paginationStrategyOptions: {
29
+ paginationSelector: "#main .pagination:last-child",
30
+ searchParamSelector: "p"
31
+ },
32
+ containerSelector: "#content > div",
33
+ thumbsSelector: "div.thumb-block[id^=video_]:not(.thumb-ad)",
34
+ titleSelector: "[class*=title]",
35
+ uploaderSelector: "[class*=name]",
36
+ durationSelector: "[class*=duration]",
37
+ gropeStrategy: "all-in-one",
38
+ customDataSelectorFns: ["filterInclude", "filterExclude"],
39
+ schemeOptions: ["Text Filter", "Duration Filter", "Badge", "Advanced"],
40
+ animatePreview,
41
+ getThumbDataCallback(thumb) {
42
+ setTimeout(() => {
43
+ const id = parseInt(thumb.getAttribute("data-id"));
44
+ xv.thumbs.prepareVideo(id);
45
+ }, 200);
46
+ }
47
+ });
48
+ function animatePreview(container) {
49
+ function createPreviewElement(src, mount) {
50
+ const elem = utils.parseHtml(`
51
+ <div class="videopv" style="display: none;">
52
+ <video autoplay="autoplay" playsinline="playsinline" muted="muted"></video>
53
+ </div>`);
54
+ mount.after(elem);
55
+ const video = elem.querySelector("video");
56
+ video.src = src;
57
+ video.addEventListener(
58
+ "loadeddata",
59
+ () => {
60
+ mount.style.opacity = "0";
61
+ elem.style.display = "block";
62
+ elem.style.background = "#000";
63
+ },
64
+ false
65
+ );
66
+ return () => {
67
+ utils.exterminateVideo(video);
68
+ elem.remove();
69
+ mount.style.opacity = "1";
70
+ };
71
+ }
72
+ function getVideoURL(src) {
73
+ return src.replace(/\w+\.\w+$/, () => "preview.mp4");
74
+ }
75
+ utils.OnHover.create(
76
+ container,
77
+ (target) => target.tagName === "IMG" && target.id.includes("pic_"),
78
+ (target) => {
79
+ const videoSrc = getVideoURL(target.src);
80
+ const onOverCallback = createPreviewElement(videoSrc, target);
81
+ const leaveTarget = target.closest(".thumb-inside");
82
+ return { leaveTarget, onOverCallback };
83
+ }
84
+ );
85
+ }
86
+
87
+ })(core, utils);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pervert-monkey",
3
3
  "description": "daddy told us not to be ashamed of our userscripts",
4
- "version": "1.0.7",
4
+ "version": "1.0.8",
5
5
  "license": "MIT",
6
6
  "keywords": [
7
7
  "userscript",