您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds missing sort options and amount of shares to buy calculator
// ==UserScript== // @name DeGiro improved filters // @namespace https://yelidmod.com/degiro // @version 0.7 // @description Adds missing sort options and amount of shares to buy calculator // @author DonNadie // @match https://trader.degiro.nl/* // @grant none // ==/UserScript== // jshint esversion: 6 (function() { 'use strict'; const section = { equity: 1, etf: 131 }; let filtersIndex = { volume: 0, isin: null, }; const sortButton = '<i role="img" data-name="icon" data-type="sort" aria-hidden="true" class="ife-sort-icon"><svg viewBox="0 0 24 24"><path d="M16.8 13.2L12 18l-4.8-4.8h9.6zM12 6l4.8 4.8H7.2L12 6z"></path></svg></i>'; const addStyle = (styleString) => { const style = document.createElement('style'); style.textContent = styleString; document.head.append(style); }; const sort = () => { const trList = document.querySelectorAll('[data-name="productTypeSearch"] tr'); new Promise((resolve, reject) => { let list = []; let val; trList.forEach((tr, e) => { tr.querySelectorAll('td').forEach((td, i) => { if (i !== filtersIndex.volume) { return; } val = parseInt(td.innerText.replace(".", "")); list.push({ tr: tr, value : isNaN(val) ? 0 : val }); }); if (e == (trList.length - 1)) { resolve(list); } }); }).then(list => { list.sort((a, b) => (a.value < b.value) ? 1 : -1); list.forEach(entry => { document.querySelector('[data-name="productTypeSearch"] tbody').appendChild(entry.tr); }); }); }; const onLoaded = () => { const url = new URL(location.href.replace("#", '')); if (!url.searchParams.has('productType')) { return; } const currentSection = parseInt(url.searchParams.get('productType')); document.querySelectorAll('[data-name="productTypeSearch"] th').forEach((el, i) => { if (el.innerText == "Volumen") { filtersIndex.volume = i; el.classList.add('ife-container'); el.innerHTML += sortButton; el.addEventListener("click", sort); } else if (el.innerText.includes("ISIN")) { filtersIndex.isin = i; } }); if (filtersIndex.isin == null || ![section.etf, section.equity].includes(currentSection)) { return; } const morningType = currentSection == section.etf ? 'ETF' : 'STOCK'; document.querySelectorAll('[data-name="productTypeSearch"] tr').forEach((tr, e) => { tr.querySelectorAll('td').forEach((td, i) => { if (i !== filtersIndex.isin) { return; } let isin; if (td.innerText.includes("/")) { isin = td.innerText.split(" / ")[1]; } else if (td.innerText.length > 5) { isin = td.innerText; } td.querySelector("span").innerHTML = td.innerText.replace(isin, '<a href="https://www.morningstar.es/es/funds/SecuritySearchResults.aspx?type=' + morningType + '&search=' + isin + '" class="ife-link" target="_blank">' + isin + '</a>'); }); }); }; const showCalculator = (mutationsList) => { let section = document.querySelector('[data-name="orderForm"] section'); if (section == null || document.getElementById('simple-calculator') != null || typeof window.calculatorInjected !== "undefined") { return; } window.calculatorInjected = true; const calculatorContainer = document.createElement("div"); calculatorContainer.id = "simple-calculator"; calculatorContainer.classList.add("ife-calculator-container"); calculatorContainer.innerHTML += '<div class="ife-input-container"><div class="ife-input-label"><input id="calculator-money" type="number" min="0" step="1" placeholder="0" class="ife-input"><span>€</span></div></div>' + "." + '<div class="ife-input-container"><div class="ife-input-label"><input id="calculator-shares" type="text" class="ife-input" placeholder="0" disabled><span>shares</span></div></div>'; const moneyInput = calculatorContainer.querySelector("#calculator-money"); const sharesInput = calculatorContainer.querySelector("#calculator-shares"); moneyInput.addEventListener("input", () => { const sharePrice = parseFloat(document.querySelector('[data-field="CurrentPrice"]').title.replace(".", "").replace(",", ".")); sharesInput.value = Math.floor(moneyInput.value / sharePrice); }); setTimeout(() => { // it seems like section is recreated in just a few secs :S section = document.querySelector('[data-name="orderForm"] section'); section.parentNode.insertBefore(calculatorContainer, section); delete(window.calculatorInjected); }, 1000); }; addStyle(` .ife-container { align-items: center; display: flex; flex-direction: row; padding-right: 12px; position: relative; } .ife-sort-icon { contain: strict; display: inline-block; flex-shrink: 0; font-style: normal; font-weight: 400; line-height: 1; opacity: 1; overflow: hidden; width: 20px; height: 20px; text-align: center; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; vertical-align: middle; position: absolute; right: -8px; top: 50%; transform: translateY(-50%); cursor: pointer; } .ife-link { color: #009fdf; } .ife-calculator-container { align-items: flex-start; display: flex; flex-direction: row; } .ife-input-container { display: flex; flex: 1 1 50%; flex-direction: column; max-width: 50%; margin-top: 10px; margin-bottom: 10px; } .ife-input-label { background-color: #f3f4f5; border: 1px solid transparent; display: inline-block; height: 32px; min-height: 32px; position: relative; } .ife-input { background-color: inherit; border: 0; border-radius: inherit; display: block; font-size: 1rem; height: 100%; line-height: 1.5; min-height: 100%; padding: 0 8px; width: 100%; } .ife-input[disabled], .ife-input[disabled]::placeholder { color: #00a658; } .ife-input-label span { color: #00a658; position: absolute; top: 30%; right: 10px; } `); let observerTimeout = null; const observerCallback = (mutationsList, observer) => { showCalculator(mutationsList); // since we can't track an specific id, we observe any body changes and // check if our classes are present. if (document.querySelectorAll('.ife-container').length > 0) { return; } if (observerTimeout != null) { clearTimeout(observerTimeout); } observerTimeout = setTimeout(onLoaded, 1000 * 2); }; (new MutationObserver(observerCallback)).observe(document.body, {childList: true, subtree: true }); })();