您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Add item group feature
当前为
// ==UserScript== // @name WOD 道具分组 // @icon http://info.world-of-dungeons.org/wod/css/WOD.gif // @namespace ttang.tw // @grant none // @author Taylor Tang // @description Add item group feature // @include *://*.world-of-dungeons.org/wod/spiel/hero/items.php* // @modifier Christophero // @version 2022.08.21.2 // ==/UserScript== (function(){ const LANGUAGE = Object.freeze({ COIN: '金币', ITEM: '物品', GROUP_ITEM: '团队物品', SELL: '出售', POSITION: '位置', WAREHOUSE: '仓库', GROUP_WAREHOUSE2: '团队仓库', GROUP_WAREHOUSE: '宝库', STORAGE_ROOM: '贮藏室', OWNER: '所有者', STORAGE_DATE: '入库时间', DROP_DATE: '掉落', MARKET: '市集', LOWEST_PRIZE: '最低价格', SELLER_COMMENT: '卖家注释', TRANSFER_TO: '移交给', }); function insertCss() { var style = document.createElement('style'); var row0 = document.querySelector('tr.row0'); var row1 = document.querySelector('tr.row1'); if(row0) { document.head.appendChild(style); var row0_color = getComputedStyle(row0).getPropertyValue('background-color'); var row1_color = getComputedStyle(row1).getPropertyValue('background-color'); style.sheet.insertRule('table.content_table .hidden_row { display: none; }', 0); style.sheet.insertRule('table.content_table .group_child > td:nth-child(1):before { content: "\u21D2"; }', 0); style.sheet.insertRule('table.content_table > tbody > :nth-child(2n) { background-color: ' + row1_color + '; }', 0); style.sheet.insertRule('table.content_table > tbody > :nth-child(2n+1) { background-color: ' + row0_color + '; }', 0); } } function setSelectValue(select, value) { if(select.querySelector('[value="' + value + '"]')) { select.value = value; return true; } return false; } function chomp(str) { var regex = new RegExp('[ ' + String.fromCharCode(8593) + String.fromCharCode(8595) + '\xA0\t\n\r]|&\w+;', 'g'); return str.replace(regex, ''); } function findTable() { function findSiblings(el) { if(!el) { return false; } var next = el.nextElementSibling; if(!next) { return null; } if(next.tagName.toLowerCase() === 'table' && next.classList.contains('content_table')) { return next; } else { return findSiblings(next); } } var search = document.querySelector('.search_container'); return findSiblings(search); } function Item(row, table_map) { var head = row.parentNode.parentNode.tHead.querySelector('.header'); var name = row.cells[1]; var use = name.textContent.match(/\((\d+)\/\d+\)$/); this.el = row; for(var i = 0; i < table_map.length; i++) { if( table_map[i] in this.parser) { this.parser[table_map[i]].call(this, i); } } } Item.prototype.parser = Object.freeze({ sell: function(idx) { var price = this.el.cells[idx]; if(!price) { return false; } this.price = Number(price.textContent || 0); this.sell_checkbox = price.querySelector('input'); }, item: function(idx) { var item = this.el.cells[idx]; var use = item.textContent.match(/\((\d+)\/\d+\)$/); item = item.querySelector('a'); this.item = item.textContent.replace(/!$/, ''); this.use = use ? Number(use[1]) : 1; this.item_useability = item.className; this.href = item.href; }, owner: function(idx) { var owner = this.el.cells[idx]; this.owner = owner.textContent; }, group_item: function(idx) { var el = this.el.cells[idx]; this.group_item_checkbox = el.querySelector('input[name^="SetGrpItem"]'); }, position: function(idx) { var el = this.el.cells[idx]; this.item_position_select = el.querySelector('select'); }, storage_date: function(idx) { var storage_date = this.el.cells[idx]; this.storage_date = storage_date.textContent; }, drop_date: function(idx) { var drop_date = this.el.cells[idx]; this.drop_date = drop_date.textContent; } }); function ItemGroup(table, prime_key) { function useGetter() { var use = this.child.map((k) => (k.use)); return use.reduce((sum, value) => (sum + value)); } function priceGetter() { return this.child.map((k) => (k.price)).reduce((sum, value) => (sum + value)); } function rowGetter() { if(!row) { row = this.createContainer(); } return row; } var row; this.pk = prime_key; this.tbody = table.tBodies[0]; this.thead = table.tHead.rows[1]; this.child = []; Object.defineProperty(this, 'row', { get: rowGetter.bind(this), writeable: false }); Object.defineProperty(this, 'use', { get: useGetter.bind(this), writeable: false }); Object.defineProperty(this, 'price', { get: priceGetter.bind(this), writeable: false }); } ItemGroup.prototype.add = function(item) { this.child.push(item); function setupSyncEvent(key) { if(!item[key]) { return false; } if(item[key].tagName.toLowerCase() === 'select') { item[key].addEventListener('change', (function(){ this.syncSelect(key); }).bind(this)); } else { item[key].addEventListener('change', (function(){ this.syncCheckbox(key); }).bind(this)); } } setupSyncEvent.call(this, 'sell_checkbox'); setupSyncEvent.call(this, 'group_item_checkbox'); setupSyncEvent.call(this, 'item_position_select'); }; ItemGroup.prototype.renderDefault = function(cell, idx, align) { var div = document.createElement('div'); div.textContent = this.child[0].el.cells[idx].textContent; cell.style.textAlign = align || 'center'; cell.appendChild(div); }; ItemGroup.prototype.syncSelect = function(key) { var el = this[key]; var prev, now, select; if(!el) { return false; } for(var i = 0; i < this.child.length; i++) { select = this.child[i][key]; now = select.options[select.selectedIndex].value; if(typeof prev === 'undefined') { prev = now; } else if(prev != now){ el.value = '0'; return false; } } if(!setSelectValue(el, now.replace(/^-/, ''))) { el.value = '0'; } }; ItemGroup.prototype.syncCheckbox = function(key) { var el = this[key]; var prev, now, check; if(!el) { return false; } for(var i = 0; i < this.child.length; i++) { check = this.child[i][key]; if(!check) { return false; } now = check.checked; if(typeof prev === 'undefined') { prev = now; } else if(prev != now){ return false; } } el.checked = now; }; ItemGroup.prototype.renderDropDate = function(cell, idx) { this.renderDefault(cell, idx); if(this.pk != 'drop_date') { cell.children[0].style.visibility = 'hidden'; } }; ItemGroup.prototype.renderItemPosition = function(position, idx) { function newOps(txt, value) { var opt = document.createElement('option'); opt.textContent = txt; opt.value = value; return opt; } var select = document.createElement('select'); var head_cell = this.thead.cells[idx]; var head_select = head_cell.querySelector('select'); if(head_select) { position.style.textAlign = 'right'; position.style.paddingRight = '23px'; select.appendChild(newOps('-------', '0')); select.appendChild(newOps(LANGUAGE.WAREHOUSE, 'go_lager')); select.appendChild(newOps(LANGUAGE.GROUP_WAREHOUSE2, 'go_group_2')); select.appendChild(newOps(LANGUAGE.GROUP_WAREHOUSE, 'go_group')); select.appendChild(newOps(LANGUAGE.STORAGE_ROOM, 'go_keller')); select.addEventListener('change', (function(e){ var value = e.target.options[e.target.selectedIndex].value; this.child.forEach(function(c){ if(c.item_position_select) { setSelectValue(c.item_position_select, value); setSelectValue(c.item_position_select, '-' + value); } }); }).bind(this)); position.appendChild(select); this.item_position_select = select; head_select.addEventListener('change', (function() { this.syncSelect('item_position_select'); }).bind(this)); } }; ItemGroup.prototype.renderItemPrice = function(price, idx) { var text = document.createElement('span'); var checkbox = document.createElement('input'); var head_cell = this.thead.cells[idx]; price.style.textAlign = 'right'; price.classList.add('small'); text.textContent = this.price; checkbox.type = 'checkbox'; checkbox.addEventListener('change', (function(e){ var checked = e.target.checked; this.child.forEach(function(c) { if(c.sell_checkbox) { c.sell_checkbox.checked = checked; } }); }).bind(this)); price.appendChild(text); price.appendChild(checkbox); this.sell_checkbox = checkbox; var head_checkbox = head_cell.querySelector('input[type="checkbox"]'); if(head_checkbox){ head_checkbox.addEventListener('change', (function() { this.syncCheckbox('sell_checkbox'); }).bind(this)); } }; ItemGroup.prototype.renderGroupSetter = function(cell, idx) { var setter = document.createElement('input'); var head_cell = this.thead.cells[idx]; cell.style.textAlign = 'center'; setter.type = 'checkbox'; setter.addEventListener('change', (function(e){ var checked = e.target.checked; this.child.forEach(function(c){ if(c.group_item_checkbox) { c.group_item_checkbox.checked = checked; } }); }).bind(this)); cell.appendChild(setter); this.group_item_checkbox = setter; head_cell.querySelector('input[type="checkbox"]').addEventListener('change', (function() { this.syncCheckbox('group_item_checkbox'); }).bind(this)); }; ItemGroup.prototype.renderItemName = function(name) { if(this.pk === 'item') { var a = document.createElement('a'); a.innerHTML = '📂 '; a.textContent += this.child[0].item + ' (' + this.use + ')'; a.className = this.child[0].item_useability; a.addEventListener('click', (e) => { wo(this.child[0].href); e.stopPropagation(); }); name.appendChild(a); } else { name.innerHTML = '📂 ' + this.child.length + ' items'; } }; ItemGroup.prototype.toggleChild = function() { if(this.child.length <= 1) { return false; } if(this.child[0].el.classList.contains('hidden_row')) { this.expand(); } else { this.shrink(); } }; ItemGroup.prototype.createContainer = function() { var row = this.tbody.insertRow(); row.className = 'item_group'; row.style.cursor = 'pointer'; row.addEventListener('click', (function(e) { var tag = e.target.tagName.toLowerCase(); if(tag != 'input' && tag != 'select' && tag != 'option') { this.toggleChild(); } }).bind(this)); return row; }; ItemGroup.prototype.parseCell = function(type, idx) { var cell = this.row.insertCell(); switch(type) { case 'index': this.renderDefault(cell, idx, 'right'); break; case 'item': this.renderItemName(cell); break; case 'sell': this.renderItemPrice(cell, idx); break; case 'position': this.renderItemPosition(cell, idx); break; case 'group_item': this.renderGroupSetter(cell, idx); break; case 'drop_date': this.renderDropDate(cell, idx); break; case 'owner': case 'storage_date': if(this.pk === type) { this.renderDefault(cell, idx); } break; } }; ItemGroup.prototype.render = function(table_map) { if(this.child.length > 1) { this.renderGroup(table_map); } else { this.tbody.appendChild(this.child[0].el); } }; ItemGroup.prototype.renderGroup = function(table_map) { for(var i = 0; i < table_map.length; i++) { this.parseCell(table_map[i], i); } this.syncSelect('item_position_select'); this.syncCheckbox('group_item_checkbox'); this.syncCheckbox('sell_checkbox'); this.child.reverse(); }; ItemGroup.prototype.shrink = function() { var table_body = this.row.parentNode; if(this.child.length > 1) { this.child.forEach((c) => { c.el.remove(); table_body.appendChild(c.el); c.el.classList.add('hidden_row'); }); } }; ItemGroup.prototype.expand = function() { var table_body = this.row.parentNode; if(this.child.length > 1) { if(this.row) { this.child.forEach((c) => { c.el.remove(); table_body.insertBefore(c.el, this.row.nextSibling); c.el.classList.remove('hidden_row'); c.el.classList.add('group_child'); }); } } }; function indexOf(obj, value) { var tmp = Object.entries(LANGUAGE); var idx = tmp.findIndex(function(pair){ return pair[1] === value; }); if(idx > 0) { return tmp[idx][0]; } else { return ''; } } function init() { var table = findTable(); if(!(table && table.tHead && table.tBodies[0].rows.length > 1)) { return false; } function parseRow(item_db, table) { var row = table.tBodies[0].rows[0]; var item = new Item(row, table_map); if(!item_db[item[group_by]]) { item_db[item[group_by]] = new ItemGroup(table, group_by); } item_db[item[group_by]].add(item); } function parseTableIndex() { var arr = []; function parseCell(head_cell) { var btn, title = (btn = head_cell.querySelector('input[type="submit"]')) ? btn.value : head_cell.textContent; title = chomp(title); return indexOf(LANGUAGE, title).toLowerCase(); } for(var i = 0; i < head.children.length; i++) { arr.push(parseCell(head.children[i])); } arr[0] = 'index'; return arr; } function parseTable(table) { var item_db = {}; var tbody = table.tBodies[0]; while(tbody.rows[0]) { parseRow(item_db, table); tbody.rows[0].remove(); } return item_db; } function initItemGroup(item_db) { var index = Number(item_db[Object.keys(item_db)[0]].child[0].el.cells[0].textContent); for(var k in item_db) { if(item_db.hasOwnProperty(k)){ item_db[k].child.forEach((c) => (c.el.cells[0].textContent = index++)); item_db[k].render(table_map); } } for(k in item_db) { if(item_db.hasOwnProperty(k)){ item_db[k].toggleChild(); } } } function addToggleBtn(table, db) { var container = document.createElement('span'); var text_expand = document.createElement('a'); var text_shrink = document.createElement('a'); text_expand.textContent = 'Expand All'; text_shrink.textContent = 'Shrink All'; text_expand.style.display = 'inline-block'; text_shrink.style.display = 'none'; container.style.cursor = 'pointer'; container.appendChild(text_expand); container.appendChild(text_shrink); table.tHead.rows[0].cells[0].appendChild(container); text_expand.addEventListener('click', function(e) { text_expand.style.display = 'none'; text_shrink.style.display = 'inline-block'; for(k in item_db) { if(item_db.hasOwnProperty(k)){ item_db[k].expand(); } } }); text_shrink.addEventListener('click', function(e) { text_expand.style.display = 'inline-block'; text_shrink.style.display = 'none'; for(k in item_db) { if(item_db.hasOwnProperty(k)){ item_db[k].shrink(); } } }); } var head = table.tHead.rows[1]; var table_map = parseTableIndex(head); var group_by = indexOf(LANGUAGE, chomp(head.querySelector('.table_hl_sorted').value)).toLowerCase(); if(/item|owner|storage_date|drop_date/.test(group_by)) { insertCss(); var item_db = parseTable(table); initItemGroup(item_db); addToggleBtn(table, item_db); } } init(); })();