碧蓝航线舰队科技

碧蓝航线 WIKI 舰队科技功能增强(样式修改、全选选中、数据备份)

// ==UserScript==
// @name         碧蓝航线舰队科技
// @version      1
// @namespace    https://fiammanda.github.io
// @description  碧蓝航线 WIKI 舰队科技功能增强(样式修改、全选选中、数据备份)
// @author       fiammanda
// @grant        none
// @match        https://wiki.biligame.com/blhx/%E8%88%B0%E9%98%9F%E7%A7%91%E6%8A%80
// @icon         https://azurlane.netojuu.com/images/thumb/a/a6/Wisdom_Cube.png/35px-Wisdom_Cube.png
// ==/UserScript==

"use strict";

const bt = document.querySelector("#editButton");
const tb = document.querySelector("#CardSelectTr");
const ft = document.querySelector(".resourceLoader + .wikitable tbody");

bt.addEventListener("click", (e) => {
  if (bt.classList.contains("selected")) {
    tb.classList.remove("editable");
    ft.classList.remove("visible");
  } else {
    tb.classList.add("editable");
    ft.classList.add("visible");
  }
});

tb.querySelectorAll("tbody a").forEach(a => {
  a.innerHTML = a.innerHTML.replace("(", "[").replace(")", "]");
  a.target = "_blank";
});

document.querySelector("#CardSelectTabHeader1 th:nth-child(3)").textContent = "满级";
document.querySelector("#CardSelectTabHeader1 th:nth-child(5)").textContent = "获得";
document.querySelector("#CardSelectTabHeader1 th:nth-child(6)").textContent = "满级";

ft.querySelector("tr:last-child th").textContent = "功能";
ft.insertAdjacentHTML("beforeend", `
	<tr id="controls">
		<th>脚本</th>
		<td>
			<span class="btn"></span>
      <a class="btn btn-default" aria-label="select-all-get">全选「获得」</a>
      <a class="btn btn-default" aria-label="select-none-get">全清「获得」</a>
      <a class="btn btn-default" aria-label="select-all-120">全选「120」</a>
      <a class="btn btn-default" aria-label="select-none-120">全清「120」</a>
      <a class="btn btn-default" aria-label="data">数据备份</a>
      <div class="modal-content">
        <div class="modal-body">
          <h3>个人数据备份-复制</h3>
          <textarea placeholder=" "></textarea>
          <a class="btn btn-default" aria-label="data-import">导入数据内容</a>
          <a class="btn btn-default" aria-label="data-export">复制数据内容</a>
          <h3>个人数据备份-文件</h3>
          <label>
            <input type="file">
            <a class="btn btn-default" aria-label="data-upload">上传数据文件</a>
          </label>
          <a class="btn btn-default" aria-label="data-download">下载数据文件</a>
        </div>
        <div class="modal-footer">
          <a class="btn btn-default" aria-label="data-close">关闭</a>
        </div>
      </div>
    </td>
	</tr>
`);

ft.querySelector("a[aria-label=\"select-all-get\"]").addEventListener("click", (e) => {
  if (confirm("是否全选当前舰船的「获得」状态?")) {
    tb.querySelectorAll("tbody tr:not([style=\"display: none;\"]) td:nth-last-child(2):not(.fleetTechSelected)").forEach(cell => {
      cell.click();
    });
  }
});
ft.querySelector("a[aria-label=\"select-none-get\"]").addEventListener("click", (e) => {
  if (confirm("是否全清当前舰船的「获得」状态?")) {
    tb.querySelectorAll("tbody tr:not([style=\"display: none;\"]) td:nth-last-child(2).fleetTechSelected").forEach(cell => {
      cell.click();
    });
  }
});
ft.querySelector("a[aria-label=\"select-all-120\"]").addEventListener("click", (e) => {
  if (confirm("是否全选当前舰船的「120」状态?")) {
    tb.querySelectorAll("tbody tr:not([style=\"display: none;\"]) td:nth-last-child(1):not(.fleetTechSelected)").forEach(cell => {
      cell.click();
    });
  }
});
ft.querySelector("a[aria-label=\"select-none-120\"]").addEventListener("click", (e) => {
  if (confirm("是否全清当前舰船的「120」状态?")) {
    tb.querySelectorAll("tbody tr:not([style=\"display: none;\"]) td:nth-last-child(1).fleetTechSelected").forEach(cell => {
      cell.click();
    });
  }
});
ft.querySelector("a[aria-label=\"data\"]").addEventListener("click", () => {
  ft.querySelector(".modal-content").setAttribute("aria-hidden", "false");
});
ft.querySelector("a[aria-label=\"data-close\"]").addEventListener("click", (e) => {
  ft.querySelector(".modal-content").setAttribute("aria-hidden", "true");
});
ft.querySelector("a[aria-label=\"data-import\"]").addEventListener("click", () => {
  if (ft.querySelector("textarea").value && confirm("是否覆盖当前数据?")) {
    localStorage["userjs-fleettech-data"] = ft.querySelector("textarea").value;
  } else {
    alert("没有找到导入内容?!");
  }
});
ft.querySelector("a[aria-label=\"data-export\"]").addEventListener("click", () => {
  if (localStorage["userjs-fleettech-data"] && confirm("是否复制科技数据?")) {
      navigator.clipboard.writeText(localStorage["userjs-fleettech-data"]);
  } else {
    alert("你又没啥需要导出的!");
  }
});
ft.querySelector("a[aria-label=\"data-download\"]").addEventListener("click", () => {
  if (localStorage["userjs-fleettech-data"]) {
    if (confirm("是否下载科技数据?") == true) {
      let link = document.createElement("a");
      link.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(localStorage["userjs-fleettech-data"]));
      link.setAttribute("download", "碧蓝航线舰队科技." + new Date().toLocaleString("sv-SE").replace(/[-: ]/g, "") + ".txt");
      link.style.display = "none";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  } else {
    alert("你又没啥需要导出的!");
  }
});
ft.querySelector("input").addEventListener("change", () => {
  const [file] = ft.querySelector("input").files;
  const reader = new FileReader();
  reader.addEventListener("load", () => {
    localStorage["userjs-fleettech-data"] = reader.result;
    alert("数据导入成功,即将刷新。");
    setTimeout(() => { location.replace("/blhx/舰队科技#舰队科技列表") }, 2500);
  }, false);
  if (file && confirm("是否覆盖当前数据?")) {
    reader.readAsText(file);
  }
});

document.head.insertAdjacentHTML("beforeend", `<style>
  @media (min-width: 768px) {
    #CardSelectTr tr {
      font-size: 13px;
      line-height: 1.5;
    }
	}

	#controls td {
    pointer-events: none;
	}
	#controls td a {
    opacity: 0;
		transition: .2s ease-in-out;
	}
	#controls td span {
		position: absolute;
    pointer-events: none;
		transition: .2s ease-in-out;
	}
	#controls td span::before {
		content: "请先打开编辑模式";
	}
  .visible #controls td {
    pointer-events: all;
  }
  .visible #controls td a {
    opacity: 1;
    pointer-events: all;
  }
  .visible #controls td span {
    opacity: 0;
  }
	#controls h3 {
		margin: 1em 0 .5em;
	}
	#controls input {
		display: none;
	}
	#controls textarea {
		margin: 0 0 .5em;
		padding: .5em;
		width: 100%;
		height: 150px;
		resize: none;
		overflow: hidden scroll;
	}
	#controls .modal-content {
		position: fixed;
		top: calc(50% - 215px);
		left: calc(50% - 300px);
		width: 600px;
		height: 425px;
    opacity: 0;
    pointer-events: none;
		transition: .2s ease-in-out;
	}
	#controls .modal-content[aria-hidden="false"] {
    opacity: 1;
    pointer-events: all;
	}
	#controls .modal-body {
		margin: 0 0 1em;
		padding: .5em 1em 1em;
	}
	#controls .modal-footer {
		padding: .5em 1em;
	}
	#CardSelectTr a, .btn {
		transition: .2s ease-in-out;
	}
  #CardSelectTr a:hover, #CardSelectTr a:focus {
    text-decoration: none !important;
		opacity: .5;
  }
  #CardSelectTr tr {
    font-size: 14px;
    line-height: 2;
  }
  #CardSelectTr tbody tr {
    border-bottom: 1px solid #0003;
  }
  #CardSelectTr th {
		padding: 0 1.5em 0 .5em;
		font-weight: normal;
		text-align: right;
  }
  #CardSelectTr th[colspan] {
		text-align: center;
  }
  #CardSelectTr td {
		padding: 0 .5em;
		text-align: right;
  }
  #CardSelectTr tr:nth-of-type(2n+1) {
    background-color: #fff;
  }
  #CardSelectTr th[rowspan]:nth-child(2), #CardSelectTr th[rowspan]:nth-child(3), #CardSelectTr th[rowspan]:nth-child(4),
  #CardSelectTr td:nth-child(2), #CardSelectTr td:nth-child(3), #CardSelectTr td:nth-child(4) {
		text-align: left;
  }
  #CardSelectTr td:nth-last-child(1), #CardSelectTr td:nth-last-child(2) {
		opacity: .5;
		transition: .2s ease-in-out;
  }
  #CardSelectTr td:nth-last-child(1)::after, #CardSelectTr td:nth-last-child(2)::after {
		content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3E%3Cpath d='M10.97 4.97a.75.75 0 0 1 1.07 1.05l-3.99 4.99a.75.75 0 0 1-1.08.02L4.324 8.384a.75.75 0 1 1 1.06-1.06l2.094 2.093 3.473-4.425a.267.267 0 0 1 .02-.022z'/%3E%3C/svg%3E");
		display: inline-block;
    height: 1em;
    width: 1em;
		background: #ddd;
		border-radius: 1px;
		transform: translate(2px, 2px);
		transition: .2s ease-in-out;
		color: transparent;
	}
  #CardSelectTr .fleetTechSelected {
		opacity: 1 !important;
    background: #fff0 !important;
  }
  #CardSelectTr td.fleetTechSelected::after {
    background: #58b4f5;
	}
  #CardSelectTr.editable td:nth-last-child(1), .editable td:nth-last-child(2) {
    cursor: pointer;
  }
  #CardSelectTr.editable td:nth-last-child(1):hover::after, #CardSelectTr.editable td:nth-last-child(2):hover::after {
    background: #58b4f5;
  }
  #CardSelectTr.editable td.fleetTechSelected:hover::after {
    background: #b6e0ff;
  }
	table.wikitable.FilterTable th {
		padding: 2px;
		font-weight: normal;
	}
	table.wikitable.FilterTable td {
		padding: 2px;
	}
	.resourceLoader + .wikitable .btn {
		padding: 4px 8px;
	}
</style>`);