Enterselects the first element in the dropdown.Ctrl-Enteradds the selected card to the maybeboard.Shift-Enteradds the selected card to the sideboard.
Card Overlay - keyboard shortcuts (next, previous, toggle foil, etc.)
| // ==UserScript== | |
| // @name Archidekt Enhancements | |
| // @namespace http://tampermonkey.net/ | |
| // @version 0.1 | |
| // @description Add some convenience functionality to Archidekt | |
| // @author You | |
| // @match https://www.archidekt.com/decks/* | |
| // @icon https://www.google.com/s2/favicons?sz=64&domain=archidekt.com | |
| // @grant GM_log | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| const debug = (...args) => GM_log('enchance', ...args); | |
| const getQuickAdd = () => document.querySelector('input[placeholder^="Quick Add"]'); | |
| // https://developer.mozilla.org/en-US/docs/Web/API/XPathResult#constants | |
| const FIRST_ORDERED_NODE_TYPE = 9; | |
| const xpath = (expression, resultType = FIRST_ORDERED_NODE_TYPE) => document.evaluate(expression, document.body, null, resultType, null); | |
| // finds a card by name and moves it to the maybeboard/sideboard | |
| const moveCard = (name, destination) => { | |
| // find card in decklist | |
| const result = xpath(`//div[starts-with(@id, "stack_")]//*[text()="${name}"]`); | |
| if (!result) { | |
| debug(`Couldn't find "${name}" in decklist`); | |
| return; | |
| } | |
| const element = result.singleNodeValue; | |
| // outermost div for the card/row | |
| // const wrapper = element.closest('div[id^="stack_"] > div'); | |
| const eventOptions = { | |
| bubbles: true, | |
| cancelable: true, | |
| view: unsafeWindow, | |
| }; | |
| // dont' rush React. take it slow | |
| setTimeout(() => { | |
| element.dispatchEvent(new MouseEvent('mouseover', eventOptions)); | |
| setTimeout(() => { | |
| const input = getQuickAdd(); | |
| // if we dispatch the mouse event with the input element in focus, it will be ignored | |
| input.blur(); | |
| // the first letter should 's' (sideboard) or 'm' (maybeboard) | |
| element.dispatchEvent(new KeyboardEvent('keydown', { key: destination[0], ...eventOptions })); | |
| // retore focus | |
| input.focus() | |
| setTimeout(() => { | |
| element.dispatchEvent(new MouseEvent('mouseleave', eventOptions)); | |
| }); | |
| }, 100); | |
| }, 100); | |
| }; | |
| let shouldIgnore = false; | |
| const arrows = [ | |
| 'ArrowDown', | |
| 'ArrowUp', | |
| 'Down', | |
| 'Up', | |
| ]; | |
| // When enter is pressed, select the first result in the list | |
| // even if the first element isn't selected, move it to the appropriate column | |
| // based on the modifier key | |
| // | |
| // ctrl+enter -> Maybeboard | |
| // shift+enter -> Sideboard | |
| const onEnterPressed = e => { | |
| if (e.key !== 'Enter') { | |
| if (arrows.includes(e.key)) { | |
| shouldIgnore = true; | |
| } | |
| return; | |
| } | |
| const firstResult = e.target.closest('span').querySelector('div.result'); | |
| const cardName = firstResult.textContent; | |
| // the user is arrowing around so let the plugin handle it | |
| if (!shouldIgnore) { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| firstResult.click(); | |
| } | |
| shouldIgnore = false; | |
| // move the card to appropriate column | |
| if (e.ctrlKey || e.shiftKey) { | |
| setTimeout(moveCard, 500, cardName, e.ctrlKey ? 'maybeboard' : 'sideboard'); | |
| } | |
| }; | |
| const MAX_COUNT = 10; | |
| let count = 0; | |
| const enhance = () => { | |
| const input = getQuickAdd(); | |
| if (!input) { | |
| if (count++ > MAX_COUNT) { | |
| debug('ran out of time waiting for input element to render. bailing...'); | |
| } | |
| else { | |
| setTimeout(enhance, 500); | |
| } | |
| } | |
| else { | |
| input.addEventListener('keydown', onEnterPressed, true); | |
| } | |
| } | |
| setTimeout(enhance); | |
| })(); |