-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathaz_cn_wiki_fleet_tech_tool.user.js
381 lines (350 loc) · 11.3 KB
/
az_cn_wiki_fleet_tech_tool.user.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
// ==UserScript==
// @name 碧航艦隊科技工具
// @namespace https://github.com/x94fujo6rpg/SomeTampermonkeyScripts
// @updateURL https://github.com/x94fujo6rpg/SomeTampermonkeyScripts/raw/master/az_cn_wiki_fleet_tech_tool.user.js
// @downloadURL https://github.com/x94fujo6rpg/SomeTampermonkeyScripts/raw/master/az_cn_wiki_fleet_tech_tool.user.js
// @version 0.05
// @description 海事局的艦隊科技頁面 可以點擊該行來標記已120的船 顯示艦船頭像
// @author x94fujo6
// @match https://wiki.biligame.com/blhx/%E8%88%B0%E9%98%9F%E7%A7%91%E6%8A%80
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
/*
[changelog]
0.05
現在可以關閉/開啟標記功能
0.04
顯示艦船頭像(海事局)
自動更新並快取
0.03
修改標記顏色/等待的selector、正確應用delay參數
因用手機看wiki時部分欄位會被隱藏,標記方式改為整行都能觸發
0.02
自動修復當頁面在背景中載入後標題列的錯位問題 (WIKI本身問題 關掉腳本一樣會)
https://i.imgur.com/kQWlEU1.jpg
*/
(async function () {
'use strict';
const
key = { ship_id: "ship_id", ship_icon: "ship_icon" },
bg_color = "silver",
getValue = (_key) => GM_getValue(_key, []),
setValue = (_key, _list) => GM_setValue(_key, (_list instanceof Array) ? _list : []),
log = (...any) => console.log(`%c[碧航艦隊科技工具]%c`, "color:OrangeRed;", "", ...any),
sleep = (ms = 0) => new Promise(resolve => setTimeout(resolve, ms));
let
waitting_result = false;
await waitTab();
waitting_result = await waitEle({ retry: 30, selector: "#CardSelectTr>thead" });
if (!waitting_result) return;
main();
function waitTab() {
return new Promise(resolve => {
if (document.visibilityState === "visible") return resolve();
log("tab in background, script paused");
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
log("script unpaused");
return resolve();
}
});
});
}
async function waitEle({ retry = 30, selector = "", delay = 500 }) {
let result = false;
for (let i = 0; i < retry; i++) {
result = document.querySelector(selector);
if (result) break;
if (!result) log(`target[${selector}] not found, remaining retries [${retry - i}]`, result);
await sleep(delay);
}
if (result) {
log(`found target[${selector}] continue`);
return true;
} else {
log(`max retries exceeded, target[${selector}] not found`);
return false;
}
}
async function main() {
let
pos = document.querySelector("#CardSelectTr"),
table = pos.querySelector("tbody"),
msg = document.createElement("div"),
changeColor = (eles, color = "") => {
eles.forEach(ele => ele.style.backgroundColor = color);
},
updateList = (list) => {
document.querySelector("#wiki_tool_marked_count").textContent = list.size;
document.querySelector("#wiki_tool_marked_list").value = [...list];
},
addCss = () => {
let css = document.createElement("style");
css.textContent = `
.fleet_tech_tool_ship_icon {
display: inline-block;
border: 1px solid #a2a9b1;
border-radius: 7px;
}
.fleet_tech_tool_ship_name {
display: inline-block;
width: calc(100% - 40px);
/*justify-content: center;*/
word-break: keep-all;
vertical-align: middle;
}
`;
document.head.appendChild(css);
},
data_srcipt = [];
addCss();
fixDataHeader();
table.children.forEach(tr => {
addSwitch([...tr.children], tr);
});
await checkIcon();
msg.innerHTML = `
<div style="display: inline-block;">
<div style="display: inline-block; color: red;">艦隊科技工具</div>作用中,點擊艦船該行任意位置進行標記。
已標記: <div id="wiki_tool_marked_count" style="display: inline-block;">${getValue(key.ship_id).length}</div>
</div>
<div>
<button id="wiki_tool_edit" class="btn btn-default">編輯/查看列表</button>
<div id="wiki_tool_box" style="display: none;">
<textarea id="wiki_tool_marked_list"></textarea>
<button id="wiki_tool_save" class="btn btn-default">儲存並更新</button>
</div>
<button id="wiki_tool_switch" class="btn btn-default" style="width: 12rem;">標記功能: OFF</button>
</div>
`;
pos.insertAdjacentElement("beforebegin", msg);
waitting_result = false;
waitting_result = await waitEle({ retry: 30, selector: "#wiki_tool_switch" });
if (!waitting_result) return;
document.querySelector("#wiki_tool_edit").onclick = () => {
let
box = document.querySelector("#wiki_tool_box"),
display = box.style.display;
box.style.display = (display == "none") ? "" : "none";
document.querySelector("#wiki_tool_marked_list").value = getValue(key.ship_id);
};
document.querySelector("#wiki_tool_save").onclick = () => {
let
_list = new Set(document.querySelector("#wiki_tool_marked_list").value.split(",")),
_table = document.querySelector("#CardSelectTr>tbody");
_list.delete('');
log("載入清單", [..._list]);
setValue(key.ship_id, [..._list]);
_table.children.forEach(tr => {
let
_id = tr.children[0].textContent.trim(),
_isInList = _list.has(_id);
changeColor([...tr.children], _isInList ? bg_color : "");
});
updateList(_list);
};
document.querySelector("#wiki_tool_switch").onclick = function () {
let is_on = this.classList.contains("active");
if (is_on) this.classList.remove("active");
if (!is_on) this.classList.add("active");
this.classList.remove(is_on ? "btn-success" : "btn-default");
this.classList.add(!is_on ? "btn-success" : "btn-default");
this.textContent = `標記功能: ${is_on ? "OFF" : "ON"}`;
};
log("載入清單", getValue(key.ship_id));
loadIcon();
function loadIcon() {
let
_getData = () => {
let
list = getValue(key.ship_icon),
data = {};
list.forEach(o => data[o.id] = o.icon);
return data;
},
_data = _getData();
log(`開始載入icon`);
table.children.forEach(tr => {
let
_id = tr.children[0].textContent.trim(),
_name = tr.children[1],
_img = _name.querySelector("img"),
_div = _name.querySelector("div");
tr.style.padding = "0px";
if (_img) _img.remove(); // remove old img if exist
if (_data[_id]) {
_img = document.createElement("img");
_img.src = _data[_id];
_img.className = "fleet_tech_tool_ship_icon";
_name.insertAdjacentElement("afterbegin", _img);
if (!_div) {
_div = document.createElement("div");
_div.className = "fleet_tech_tool_ship_name";
_div.appendChild(_name.querySelector("a"));
_name.insertAdjacentElement("beforeend", _div);
}
}
});
}
async function checkIcon() {
let icon_length = getValue(key.ship_icon).length;
if (data_srcipt.length != icon_length) {
//add update btn
log(`檢查icon, 本頁${data_srcipt.length} != 已取得${icon_length}, 開始更新`);
await iconHarvester();
} else {
log(`檢查icon, 本頁${data_srcipt.length} == 已取得${icon_length}, 不需更新`);
}
async function iconHarvester() {
let
url = "https://wiki.biligame.com/blhx/%E5%AE%9E%E8%A3%85%E6%97%A5%E6%9C%9F",
parser = new DOMParser(),
page = await fetch(url);
if (page.status !== 200) {
throw Error(`unable to get ${url}`);
} else {
let
html_text = await page.text(),
dom = parser.parseFromString(html_text, "text/html"),
waitParser = new Promise((resolve) => { if (dom.readyState == "complete") resolve(true); }),
data_icon = [],
promise_list = [];
log("wait dom");
await waitParser.then(() => {
log("dom loaded");
let data_wiki = extractData(dom);
data_wiki.forEach(o => {
if (data_srcipt.find(id => id == o.id)) {
data_icon.push({
id: o.id,
icon: o.icon,
});
}
});
log("更新完畢", { data_wiki, data_srcipt, data_icon });
});
log("開始轉換為快取");
data_icon.forEach(data => {
promise_list.push(
fetchImageToDataURI(data.icon)
.then(data_url => data.icon = data_url)
);
});
await Promise.all(promise_list);
log("轉換完畢");
setValue(key.ship_icon, data_icon);
return true;
}
async function fetchImageToDataURI(url = "", test = false) {
let local = window.location.protocol == "file:" ? true : false;
if (test || local) {
return url; // can't fetch in local file
} else {
return fetch(url).then(r => {
return r.blob();
}).then(blob => {
return blobToURL(blob);
});
}
function blobToURL(blob) {
return new Promise((resolve, reject) => {
var fr = new FileReader();
fr.onload = () => { resolve(fr.result); };
fr.onerror = reject;
fr.readAsDataURL(blob);
});
}
}
function extractData(dom) {
let
extractor = (ele) => {
let _data = [],
nor = (node) => node.textContent.trim().replace(/[\s·]/mg, "");
ele.querySelector("tbody")
.children
.forEach((line, i) => {
if (i > 0) {
let img = line.querySelector("img");
if (img) {
_data.push({
id: nor(line.children[0]),
name: nor(line.children[1]),
//date: nor(node.children[2]),
icon: img.src,
});
}
}
});
return _data;
},
list = [],
target = dom.querySelector("#mw-content-text");
//log([target]);
target.querySelector("div[class=row]")
.children
.forEach(ele => list = list.concat(extractor(ele)));
//log(JSON.stringify(list));
//log(list);
return list;
}
}
}
function fixDataHeader() {
let head = document.querySelector("#CardSelectTr>thead");
if (head.children.length == 1) {
let bottom = document.querySelector("#CardSelectTr>tbody>tr");
log("missing head, trying to fix it");
if (!(bottom.innerHTML.match(/dataHeader headerSort/gm))) {
throw Error(`element not found, abort\n${bottom.innerHTML}`);
} else {
head.appendChild(bottom);
log("head fixed");
}
} else {
log("normal datahead");
}
}
function addSwitch(elelist, target) {
target.onclick = () => checkList();
checkList(true); // at start
async function checkList(ini = false) {
let
addToList = async () => {
_list.add(`${_id}`);
setValue(key.ship_id, [..._list]);
},
removeFromList = async () => {
_list.delete(`${_id}`);
setValue(key.ship_id, [..._list]);
},
_list = new Set(getValue(key.ship_id)),
_id = elelist[0].innerText.trim(),
_name = elelist[1].innerText.trim(),
_isInList = _list.has(_id),
_is_on = document.querySelector("#wiki_tool_switch")?.classList.contains("active");
if (!_is_on && !ini) return;
if (ini) data_srcipt.push(_id);
if (_isInList) {
if (!ini) {
await removeFromList(_id);
log(`remove ${_id} ${_name}, list size:${_list.size}`);
changeColor(elelist);
updateList(_list);
} else {
changeColor(elelist, bg_color);
}
} else {
if (!ini) {
await addToList(_id);
log(`add ${_id} ${_name}, list size:${_list.size}`);
changeColor(elelist, bg_color);
updateList(_list);
} else {
changeColor(elelist);
}
}
}
}
}
})();