Enter
selects the first element in the dropdown.Ctrl-Enter
adds the selected card to the maybeboard.Shift-Enter
adds 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); | |
})(); |