PageAutomator

Automate the actions on the page

目前為 2023-01-27 提交的版本,檢視 最新版本

此腳本不應該直接安裝,它是一個供其他腳本使用的函式庫。欲使用本函式庫,請在腳本 metadata 寫上: // @require https://update.cn-greasyfork.org/scripts/458951/1142583/PageAutomator.js

  1. // ==UserScript==
  2. // @name PageAutomator
  3. // @description Automate the actions on the page
  4. // @version 1.0.4
  5. // @author aolko
  6. // @match *
  7. // @namespace https://greasyfork.org/ru/users/5008-aolko
  8. // @grant none
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/mousetrap/1.6.5/mousetrap.min.js
  10. // ==/UserScript==
  11.  
  12. function PageAutomator() {
  13. // Animate the cursor movement
  14. function animateCursor(x, y) {
  15. var startX = cursorX;
  16. var startY = cursorY;
  17. var distanceX = x - startX;
  18. var distanceY = y - startY;
  19. var startTime = null;
  20. function step(timeStamp) {
  21. if (!startTime) startTime = timeStamp;
  22. var progress = timeStamp - startTime;
  23. cursorX = startX + (distanceX * progress) / 200;
  24. cursorY = startY + (distanceY * progress) / 200;
  25. updateCursor(cursorX, cursorY);
  26. if (progress < 200) {
  27. requestAnimationFrame(step);
  28. }
  29. }
  30. requestAnimationFrame(step);
  31. }
  32.  
  33. // Mouse events
  34. mouse: {
  35. this.hover = function (selector) {
  36. var element = document.querySelector(selector);
  37. element.dispatchEvent(new MouseEvent("mouseover"));
  38. return this;
  39. };
  40. this.click = function (selector, button = "left") {
  41. var element = document.querySelector(selector);
  42. if (!element) {
  43. console.log("Error: element not found");
  44. return this;
  45. }
  46. if (button === "left") {
  47. element.dispatchEvent(new MouseEvent("click"));
  48. } else if (button === "right") {
  49. element.dispatchEvent(new MouseEvent("contextmenu"));
  50. }
  51. return this;
  52. };
  53. this.scroll = function (amount) {
  54. window.scrollBy(0, amount);
  55. return this;
  56. };
  57. this.scrollTo = function (element) {
  58. element.scrollIntoView({
  59. behavior: "smooth",
  60. block: "start",
  61. inline: "nearest",
  62. });
  63. return this;
  64. };
  65. this.hold = function (selector, button) {
  66. var element = document.querySelector(selector);
  67. if (button === "left") {
  68. element.dispatchEvent(new MouseEvent("mousedown"));
  69. } else if (button === "right") {
  70. element.dispatchEvent(
  71. new MouseEvent("mousedown", {
  72. button: 2,
  73. })
  74. );
  75. }
  76. return this;
  77. };
  78. this.moveToPosition = function (x, y) {
  79. window.dispatchEvent(
  80. new MouseEvent("mousemove", {
  81. clientX: x,
  82. clientY: y,
  83. })
  84. );
  85. return this;
  86. };
  87. this.moveToElement = function (selector) {
  88. var element = document.querySelector(selector);
  89. if(!element) {
  90. console.log("Error: element not found");
  91. return this;
  92. }
  93. var rect = element.getBoundingClientRect();
  94. var x = rect.left + window.pageXOffset + rect.width / 2;
  95. var y = rect.top + window.pageYOffset + rect.height / 2;
  96. window.dispatchEvent(
  97. new MouseEvent("mousemove", {
  98. clientX: x,
  99. clientY: y,
  100. })
  101. );
  102. return this;
  103. };
  104. this.getPosition = function () {
  105. var position = {
  106. x: 0,
  107. y: 0,
  108. };
  109. document.addEventListener("mousemove", function (event) {
  110. position.x = event.clientX;
  111. position.y = event.clientY;
  112. });
  113. return position;
  114. return this;
  115. };
  116. }
  117. // Keyboard events
  118. keyboard: {
  119. this.keyPress = function (key) {
  120. var event = new KeyboardEvent("keypress", {
  121. key: key,
  122. });
  123. document.dispatchEvent(event);
  124. return this;
  125. };
  126. this.keyUp = function (key) {
  127. var event = new KeyboardEvent("keyup", {
  128. key: key,
  129. });
  130. document.dispatchEvent(event);
  131. return this;
  132. };
  133. this.keyDown = function (key) {
  134. var event = new KeyboardEvent("keydown", {
  135. key: key,
  136. });
  137. document.dispatchEvent(event);
  138. return this;
  139. };
  140. this.holdKey = function (key, action) {
  141. var keys = {
  142. ctrl: 17,
  143. shift: 16,
  144. alt: 18,
  145. win: 91,
  146. };
  147. var event = new KeyboardEvent("keydown", {
  148. keyCode: keys[key],
  149. which: keys[key],
  150. });
  151. document.dispatchEvent(event);
  152. action();
  153. var event = new KeyboardEvent("keyup", {
  154. keyCode: keys[key],
  155. which: keys[key],
  156. });
  157. document.dispatchEvent(event);
  158. return this;
  159. };
  160. this.holdKeySequence = function (sequence, action) {
  161. Mousetrap.bind(
  162. sequence,
  163. function () {
  164. action();
  165. Mousetrap.unbind(sequence);
  166. },
  167. "keydown"
  168. );
  169. return this;
  170. };
  171. this.setKeyState = function (key, state) {
  172. if (key === "numlock") {
  173. var event = new KeyboardEvent("keydown", {
  174. key: "NumLock",
  175. code: "NumLock",
  176. });
  177. document.dispatchEvent(event);
  178. } else if (key === "scrolllock") {
  179. var event = new KeyboardEvent("keydown", {
  180. key: "ScrollLock",
  181. code: "ScrollLock",
  182. });
  183. document.dispatchEvent(event);
  184. } else if (key === "capslock") {
  185. var event = new KeyboardEvent("keydown", {
  186. key: "CapsLock",
  187. code: "CapsLock",
  188. });
  189. document.dispatchEvent(event);
  190. }
  191. return this;
  192. };
  193. }
  194. input: {
  195. // Block input
  196. this.blockInput = function () {
  197. document.addEventListener("keydown", function (event) {
  198. event.preventDefault();
  199. });
  200. document.addEventListener("mousedown", function (event) {
  201. event.preventDefault();
  202. });
  203. return this;
  204. };
  205. }
  206. timer: {
  207. // Timer events
  208. this.wait = function (ms) {
  209. var start = new Date().getTime();
  210. var end = start;
  211. while (end < start + ms) {
  212. end = new Date().getTime();
  213. }
  214. return this;
  215. };
  216. this.waitForElement = function (selector) {
  217. var element = document.querySelector(selector);
  218. while (!element) {
  219. element = document.querySelector(selector);
  220. }
  221. return this;
  222. };
  223. this.waitForMouse = function (cursor) {
  224. var currentCursor = document.body.style.cursor;
  225. while (currentCursor !== cursor) {
  226. currentCursor = document.body.style.cursor;
  227. }
  228. return this;
  229. };
  230. }
  231. // Conditionals
  232. this.ifElement = function (selector, condition, value) {
  233. var element = document.querySelector(selector);
  234. if (condition === "contains") {
  235. if (element.innerHTML.includes(value)) {
  236. return true;
  237. } else {
  238. return false;
  239. }
  240. } else if (condition === "does not contain") {
  241. if (!element.innerHTML.includes(value)) {
  242. return true;
  243. } else {
  244. return false;
  245. }
  246. } else if (condition === "is") {
  247. if (element.innerHTML === value) {
  248. return true;
  249. } else {
  250. return false;
  251. }
  252. } else if (condition === "is not") {
  253. if (element.innerHTML !== value) {
  254. return true;
  255. } else {
  256. return false;
  257. }
  258. }
  259. return this;
  260. };
  261. this.onElement = function(selector, callback) {
  262. var observer = new MutationObserver(function(mutations) {
  263. mutations.forEach(function(mutation) {
  264. if (mutation.addedNodes && mutation.addedNodes.length > 0) {
  265. for (var i = 0; i < mutation.addedNodes.length; i++) {
  266. var node = mutation.addedNodes[i];
  267. if (node.matches && node.matches(selector)) {
  268. observer.disconnect();
  269. callback(node);
  270. }
  271. }
  272. }
  273. });
  274. });
  275. observer.observe(document.documentElement, {
  276. childList: true,
  277. subtree: true
  278. });
  279. };
  280.  
  281. dialogs: {
  282. // Dialogs/Message Boxes
  283. this.showNotification = function (title, text) {
  284. var notification = new Notification(title, {
  285. body: text,
  286. });
  287. return this;
  288. };
  289. this.showDialog = function (title, text) {
  290. var dialog = document.createElement("dialog");
  291. var titleElement = document.createElement("strong");
  292. titleElement.innerHTML = title;
  293. var textElement = document.createElement("p");
  294. textElement.innerHTML = text;
  295. dialog.appendChild(titleElement);
  296. dialog.appendChild(textElement);
  297. document.body.appendChild(dialog);
  298. dialog.show();
  299. return this;
  300. };
  301. this.showCustomDialog = function (html) {
  302. var dialog = document.createElement("dialog");
  303. dialog.innerHTML = html;
  304. document.body.appendChild(dialog);
  305. dialog.show();
  306. return this;
  307. };
  308. }
  309. clipboard: {
  310. // Clipboard
  311. this.getClipboardText = function () {
  312. return navigator.clipboard.readText().then((text) => {
  313. return text;
  314. });
  315. return this;
  316. };
  317. this.setClipboardText = function (text) {
  318. navigator.clipboard.writeText(text);
  319. return this;
  320. };
  321. this.clearClipboard = function () {
  322. navigator.clipboard.writeText("");
  323. return this;
  324. };
  325. }
  326. router: {
  327. // function to handle different actions based on URL
  328. this.ifUrl = function(url, action) {
  329. if (url.startsWith("/") && window.location.pathname === url) {
  330. action();
  331. }else if (url === '/' && window.location.pathname === '/') {
  332. action();
  333. } else if (window.location.href === url) {
  334. action();
  335. }
  336. };
  337. // function to navigate to a specified URL
  338. this.navigate = function(url) {
  339. window.location.href = url;
  340. };
  341. // function to expose current URL
  342. currentUrl: {
  343. this.get_domain = function get_domain() {
  344. return window.location.hostname;
  345. };
  346. this.get_protocol =function get_protocol() {
  347. return window.location.protocol;
  348. };
  349. this.get_page = function get_page() {
  350. return window.location.pathname;
  351. };
  352. this.get_query = function get_query() {
  353. return window.location.search;
  354. };
  355. }
  356. }
  357.  
  358. }