Deck manager
Från och med
// ==UserScript==
// @name Klatu's Elements script
// @namespace Klatu
// @version 10
// @description Deck manager
// @author Klatu
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js
// @require https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.6.0/clipboard.min.js
// @require https://cdnjs.cloudflare.com/ajax/libs/notify/0.4.2/notify.min.js
// @match http://www.kongregate.com/games/zanzarino/elements*
// @grant none
// @noframes
// ==/UserScript==
jQuery.noConflict();
//main function
window.addEventListener('load', ()=>{
var clipboard,
createDeckPopup,
createDeckButton,
createDeckCodeInput,
createDeckNameInput,
deckBeingModified,
decks,
decksDiv,
div,
modifyDeckButton,
modifyDeckPopup,
modifyDeckCodeInput,
modifyDeckNameInput,
popupContainer,
style,
styleElement,
tab,
tabLink;
function showPopup(popup){
popupContainer.style.display='flex';
for(var child of popupContainer.children) child.style.display='none';
popup.style.display='block';
}
function hidePopups(){
popupContainer.style.display='none';
}
function createCloseCross(){
var cross=document.createElement('span');
cross.className='klatu-close-cross';
cross.addEventListener('click', hidePopups);
return cross;
}
function saveDecks(){
localStorage.setItem('elementsDecks', JSON.stringify(decks));
}
function createDeck(){
var deck={name:createDeckNameInput.value, code:createDeckCodeInput.value};
decks.push(deck);
saveDecks();
hidePopups();
updateDecksDiv();
}
function focusWhenUserPressesTab(e){
if(e.which===9||e.keyCode===9){
e.preventDefault();
this.focus();
}
}
function createForm(submitFunction){
function submit(e){
if(e.which===13||e.keyCode===13){
e.preventDefault();
submitFunction();
}
}
//link the last element with the first one and add the submit listener to it
arguments[arguments.length-1].addEventListener('keydown', focusWhenUserPressesTab.bind(arguments[1]));
arguments[arguments.length-1].addEventListener('keydown', submit);
//link the each of the other elements with the next ones
for(var i=1; arguments[i+1]; i++){
arguments[i].addEventListener('keydown', focusWhenUserPressesTab.bind(arguments[i+1]));
arguments[i].addEventListener('keydown', submit);
}
}
function modifyDeck(){
deckBeingModified.name=modifyDeckNameInput.value;
deckBeingModified.code=modifyDeckCodeInput.value;
saveDecks();
hidePopups();
updateDecksDiv();
}
function deleteDeck(){
if(confirm('Are you sure?')){
var deckDiv=this.parentNode;
decks.splice(deckDiv.getAttribute('data-klatu-index'), 1);
saveDecks();
updateDecksDiv();
}
}
function showCreateDeckPopup(){
createDeckNameInput.value='';
createDeckCodeInput.value='';
showPopup(createDeckPopup);
createDeckNameInput.focus();
}
function copyDeckCode(){
if(!Clipboard.isSupported()){
alert('Wait for the script\'s next version please :(');
}
}
function showModifyDeckPopup(){
var index=this.parentNode.getAttribute('data-klatu-index');
deckBeingModified=decks[index];
modifyDeckNameInput.value=deckBeingModified.name;
modifyDeckCodeInput.value=deckBeingModified.code;
showPopup(modifyDeckPopup);
}
function returnElementWhenItExists(id){
return new Promise((resolve, reject) => {
var element=$(id), interval;
if(element) resolve(element);
interval=setInterval(()=>{
var element=$(id);
if(element){
clearInterval(interval);
resolve(element);
}
}, 1000);
});
}
function updateDecksDiv(){
for(var i=decksDiv.children.length-1; 0<=i; i--) decksDiv.children[i].remove();
for(i=0; i<decks.length; i++){
var deck=decks[i];
var deckDiv=document.createElement('div');
var deckNameSpan=document.createElement('span');
var deckCopySpan=document.createElement('span');
var deckModifySpan=document.createElement('span');
var deckDeleteSpan=document.createElement('span');
deckDiv.setAttribute('data-klatu-index', i);
deckDiv.className='klatu-deck-div';
deckNameSpan.innerText=deck.name;
deckNameSpan.className='klatu-deck-name-span';
deckDiv.appendChild(deckNameSpan);
deckDeleteSpan.className='klatu-deck-delete-span';
deckDeleteSpan.addEventListener('click', deleteDeck);
deckDiv.appendChild(deckDeleteSpan);
deckModifySpan.className='klatu-deck-modify-span';
deckModifySpan.addEventListener('click', showModifyDeckPopup);
deckDiv.appendChild(deckModifySpan);
deckCopySpan.className='klatu-deck-copy-span';
deckCopySpan.setAttribute('data-clipboard-text', deck.code);
deckCopySpan.addEventListener('click', copyDeckCode);
deckDiv.appendChild(deckCopySpan);
if(i%2) deckDiv.className+=' even';
decksDiv.appendChild(deckDiv);
}
}
//add own style
style=
'.klatu-close-cross {'+
' position: absolute;'+
' top: 4px;'+
' left: 4px;'+
' background-color: #E95420;'+
' border-radius: 50%;'+
' width: 18px;'+
' height: 18px;'+
' text-align: center;'+
' line-height: 20px;'+
' cursor: pointer;'+
'}'+
'.klatu-close-cross:before {'+
' content: "×";'+
' font-size: 15px;'+
'}'+
'.klatu-deck-div {'+
' font-size: 18px;'+
' padding: 6px;'+
' background-color: #111;'+
' color: #eee;'+
'}'+
'.klatu-popup {'+
' padding: 26px 26px 8px 26px;'+
' position: relative;'+
' background-color: #333;'+
'}'+
'.klatu-popup>input {'+
' margin: 0 auto;'+
' display: block;'+
' width: 750px;'+
' font-family: monospace;'+
'}'+
'.klatus-elements-script-button {'+
' display: block;'+
' padding: 6px 12px;'+
' margin: 8px auto 0 auto;'+
' font-size: 14px;'+
' font-weight: 400;'+
' line-height: 1.42857143;'+
' text-align: center;'+
' white-space: nowrap;'+
' vertical-align: middle;'+
' -ms-touch-action: manipulation;'+
' touch-action: manipulation;'+
' cursor: pointer;'+
' -webkit-user-select: none;'+
' -moz-user-select: none;'+
' -ms-user-select: none;'+
' user-select: none;'+
' width: 100px;'+
' background-image: none;'+
' border: 1px solid transparent;'+
' border-radius: 4px;'+
' color: #fff;'+
' background-color: #337ab7;'+
' border-color: #2e6da4;'+
'}'+
'.klatu-deck-div>span:not(.klatu-deck-name-span) {'+
' float: right;'+
' font-size: 20px;'+
' font-weight: bold;'+
' padding: 1px 3px 1px 3px;'+
' cursor: pointer;'+
'}'+
'.klatu-deck-div.even {'+
' background-color: #333;'+
'}'+
'.klatu-deck-copy-span, .klatu-deck-modify-span, .klatu-deck-delete-span {'+
' float: right;'+
'}'+
'.klatu-deck-delete-span:before {'+
' content: "×";'+
' color: red;'+
'}'+
'.klatu-deck-copy-span:before {'+
' content: "?";'+
' color: #0275d8'+
'}'+
'.klatu-deck-modify-span:before {'+
' content: "✍";'+
' color: #f0ad4e'+
'}'+
'.tabpane {'+
' height: 489px'+
'}'+
'#klatu-popup-container {'+
' justify-content: center;'+
' align-items: center;'+
' position: fixed;'+
' z-index: 99999;'+
' top: 0;'+
' left: 0;'+
' width: 100vw;'+
' height: 100vh;'+
' background-color: rgba(0, 0, 0, 0.75);'+
'}'+
'.notiyjs-corner {'+
' z-index: 9999;'+
'}';
styleElement=document.createElement('style');
styleElement.innerHTML=style;
document.head.appendChild(styleElement);
//create the popup container
popupContainer=document.createElement('div');
popupContainer.id='klatu-popup-container';
popupContainer.style.display='none';
document.body.appendChild(popupContainer);
//hide visible popups when the user presses escape
window.addEventListener('keyup', (e)=>{
if(e.which===27|| e.keyCode===27) hidePopups();
});
//create the create deck popup
createDeckPopup=document.createElement('div');
createDeckPopup.className='klatu-popup';
createDeckNameInput=document.createElement('input');
createDeckNameInput.placeholder='Enter your deck\'s name';
createDeckPopup.appendChild(createDeckNameInput);
createDeckCodeInput=document.createElement('input');
createDeckCodeInput.placeholder='Enter your deck\'s code';
createDeckPopup.appendChild(createDeckCodeInput);
createDeckButton=document.createElement('button');
createDeckButton.className='klatus-elements-script-button';
createDeckButton.innerText='Add deck';
createDeckButton.addEventListener('click', createDeck);
createDeckPopup.appendChild(createDeckButton);
createDeckPopup.appendChild(createCloseCross());
popupContainer.appendChild(createDeckPopup);
createForm(createDeck, createDeckNameInput, createDeckCodeInput);
//create the modify deck popup
modifyDeckPopup=document.createElement('div');
modifyDeckPopup.className='klatu-popup';
modifyDeckNameInput=document.createElement('input');
modifyDeckNameInput.placeholder='Enter your deck\'s new name';
modifyDeckPopup.appendChild(modifyDeckNameInput);
modifyDeckCodeInput=document.createElement('input');
modifyDeckCodeInput.placeholder='Enter your deck\'s new code';
modifyDeckPopup.appendChild(modifyDeckCodeInput);
modifyDeckButton=document.createElement('button');
modifyDeckButton.className='klatus-elements-script-button';
modifyDeckButton.innerText='Modify deck';
modifyDeckButton.addEventListener('click', modifyDeck);
modifyDeckPopup.appendChild(modifyDeckButton);
modifyDeckPopup.appendChild(createCloseCross());
popupContainer.appendChild(modifyDeckPopup);
createForm(modifyDeck, modifyDeckNameInput, modifyDeckCodeInput);
//create the deck manager div
div=document.createElement('div');
div.id='klatus-elements-script-tab-pane';
div.className='tabpane';
//create the DECKS tab
tab=document.createElement('li');
tab.id='klatus-elements-script-tab';
tab.className='tab';
tabLink=document.createElement('a');
tabLink.innerText='Decks';
tabLink.key=div.id;
tabLink.href='#'+div.id;
tabLink.addEventListener('click', function(e){
holodeck._tabs.setActiveTab(this);
e.preventDefault();
});
tab.appendChild(tabLink);
//create the decks div
decksDiv=document.createElement('div');
div.appendChild(decksDiv);
jQuery(decksDiv).sortable({
update: (event, deckDivObject)=>{
var item=deckDivObject.item;
var deck=decks.splice(item[0].getAttribute('data-klatu-index'), 1)[0];
decks.splice(item.index(), 0, deck);
saveDecks();
updateDecksDiv();
},
axis: 'y'
});
//load saved decks
decks=localStorage.getItem('elementsDecks')?JSON.parse(localStorage.getItem('elementsDecks')):[];
//create the decks div
decksDiv=document.createElement('div');
div.appendChild(decksDiv);
jQuery(decksDiv).sortable({
update: (event, deckDivObject)=>{
var item=deckDivObject.item;
var deck=decks.splice(item[0].getAttribute('data-klatu-index'), 1)[0];
decks.splice(item.index(), 0, deck);
saveDecks();
updateDecksDiv();
},
axis: 'y'
});
updateDecksDiv();
//create the add deck button
var button=document.createElement('button');
button.innerText='Add deck';
button.className='klatus-elements-script-button';
button.addEventListener('click', showCreateDeckPopup);
div.appendChild(button);
//append my elements to the body when the appropriate elements are ready
returnElementWhenItExists('main_tab_set').then((element)=>element.appendChild(tab));
returnElementWhenItExists('kong_game_ui').then((element)=>element.appendChild(div));
//add the tab and the div to the holodeck
new Promise((resolve, reject) => {
var interval;
if(window.holodeck&&window.holodeck._tabs) resolve(window.holodeck._tabs);
interval=setInterval(()=>{
if(window.holodeck&&window.holodeck._tabs){
clearInterval(interval);
resolve(window.holodeck._tabs);
}
}, 1000);
}).then((tabs)=>{
tabs.links.push(tabLink);
tabs.containers._object[div.id]=div;
});
//instantiate Clipboard to allow copying deck codes by clicking the appropriate icons
clipboard=new Clipboard('.klatu-deck-copy-span');
clipboard.on('success', ()=>jQuery.notify("Your code has been copied to your clipboard.", "success"));
clipboard.on('error', ()=>jQuery.notify("There was an error while copying your text to your clipboard.", "error"));
});