UNPKG

my-snip

Version:

This tool allows you to quickly prototype and develop a bookmarklet, aggregate snippets, and write user-flow scripts.

235 lines (208 loc) 6.53 kB
let currentEl = null; let defaultCommandTimeout = 4000; function getEl(selector) { let results = []; const parent = currentEl[0]; if (selector.slice(0, 2) === "//") { const XPathResult = 7; //ORDERED_NODE_SNAPSHOT_TYPE let query = document.evaluate( selector, parent || document, null, XPathResult, null ); for (let i = 0, length = query.snapshotLength; i < length; ++i) { results.push(query.snapshotItem(i)); } } else { results = [...parent.querySelectorAll(selector)]; } return results; } const getDefaultApi = function (logger) { const waitElArr = function (methodLog, findElArr, options) { let ms = defaultCommandTimeout; if ((options || {}).timeout) { ms = options.timeout; } return new Promise((resolve, reject) => { let waited = 0; let startTime = Date.now(); let timeOutId = null; logger.log("wait " + methodLog); (function waitElem() { timeOutId = setTimeout(() => { let elArr = findElArr(); const isFind = elArr.length > 0; if (waited >= ms || isFind) { clearTimeout(timeOutId); if (isFind) { logger.log("found " + methodLog); currentEl = elArr; resolve(currentEl); } else { currentEl = []; resolve(currentEl); } } else { waited = Date.now() - startTime; waitElem(); } }, 0); })(); }); }; return { // system initEl: async (el) => { currentEl = [el]; }, then: (resolve) => resolve(currentEl), // queries contains: (selector, content, options) => { return waitElArr( "contains " + selector + " " + content, () => getEl(selector).filter((el) => { const elText = (el.innerText || "").toLowerCase(); const text = (content || "").toLowerCase(); return elText.indexOf(text) > -1; }), options ); }, eq: async (index) => { currentEl = currentEl.slice(index, index + 1); }, find: async (selector) => { const el = [...currentEl[0].querySelectorAll(selector)]; if (el.length > 0) { currentEl = el; } }, focused: async () => { currentEl = [document.activeElement]; }, get: (selector, options) => { return waitElArr("get " + selector, () => getEl(selector), options); }, last: async () => { currentEl = [currentEl[currentEl.length - 1]]; }, parent: async () => { currentEl = [currentEl[0].parentElement]; }, siblings: async (selector) => { currentEl = [currentEl[0].parentElement]; currentEl = [...currentEl[0].querySelectorAll(selector)]; }, // actions click: async () => { const { left: clientX, bottom: clientY } = currentEl[0].getBoundingClientRect(); let evt = new MouseEvent("click", { button: 0, bubbles: true, cancelable: true, clientX, clientY, }); currentEl[0].dispatchEvent(evt); }, rightclick: async () => { const { left: clientX, bottom: clientY } = currentEl[0].getBoundingClientRect(); let evt = new MouseEvent("contextmenu", { bubbles: true, cancelable: false, button: 2, buttons: 0, clientX, clientY, }); currentEl[0].dispatchEvent(evt); }, select: async (valueOrTextorIndex) => { const selectObj = currentEl[0]; [...selectObj.options].forEach((option, index) => { const isMatchValue = option.value == valueOrTextorIndex; const isMatchText = option.text == valueOrTextorIndex; const isMatchIndex = index === valueOrTextorIndex; if (isMatchValue || isMatchText || isMatchIndex) { option.selected = true; selectObj.dispatchEvent( new CustomEvent("change", { bubbles: true, }) ); } }); }, trigger: async (eventName) => { let event = new Event(eventName); if(eventName.indexOf("key") === 0){ event = new KeyboardEvent(eventName, {bubbles: true}); } if(eventName.indexOf("mouse") === 0){ event = new MouseEvent(eventName, {bubbles: true}); } if (eventName.indexOf("touch") === 0){ event = new TouchEvent(eventName, {bubbles: true}); } if (eventName.indexOf("pointer") === 0){ event = new PointerEvent(eventName, {bubbles: true}); } if (eventName.indexOf("wheel") === 0){ event = new WheelEvent(eventName, {bubbles: true}); } if (eventName.indexOf("drag") === 0){ event = new DragEvent(eventName, {bubbles: true}); } if (eventName.indexOf("clipboard") === 0){ event = new ClipboardEvent(eventName, {bubbles: true}); } if (eventName.indexOf("composition") === 0){ event = new CompositionEvent(eventName, {bubbles: true}); } if (eventName.indexOf("input") === 0){ event = new InputEvent(eventName, {bubbles: true}); } if (eventName.indexOf("animation") === 0){ event = new AnimationEvent(eventName, {bubbles: true}); } if (eventName.indexOf("transition") === 0){ event = new TransitionEvent(eventName, {bubbles: true}); } if (eventName.indexOf("message") === 0){ event = new MessageEvent(eventName, {bubbles: true}); } if (eventName.indexOf("storage") === 0){ event = new StorageEvent(eventName, {bubbles: true}); } currentEl[0].dispatchEvent(event); }, type: async (text) => { const value = text.replace( /{backspace}|{del}|{downArrow}|{end}|{enter}|{esc}|{home}|{insert}|{leftArrow}|{moveToEnd}|{moveToStart}|{pageDown}|{pageUp}|{rightArrow}|{selectAll}|{upArrow}|{alt}|{ctrl}|{meta}|{shift}]/g, "" ); currentEl[0].value = value; currentEl[0].dispatchEvent( new CustomEvent("input", { bubbles: true, }) ); }, // other commands focus: async () => { currentEl[0].dispatchEvent(new CustomEvent("focus", { bubbles: true })); }, wait: async (time) => await new Promise((resolve) => setTimeout(resolve, time)), log: async (message) => { logger.log(message); }, }; }; export default getDefaultApi;