Luogu Tasks

在洛谷侧边栏显示题单与自己存的题

当前为 2021-04-02 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Luogu Tasks
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.2
  5. // @run-at document-start
  6. // @description 在洛谷侧边栏显示题单与自己存的题
  7. // @author __OwO__
  8. // @match https://www.luogu.com.cn/*
  9. // @grant GM_setValue
  10. // @grant GM_getValue
  11. // @grant unsafeWindow
  12. // @require https://cdn.staticfile.org/jquery/3.5.1/jquery.min.js
  13. // @require https://cdn.staticfile.org/sweetalert/2.1.2/sweetalert.min.js
  14. // ==/UserScript==
  15.  
  16. window.onload = async () => {
  17. const inject_lantency = 500;
  18.  
  19. let configs = {
  20. set train(v) {
  21. GM_setValue("problem-helper-local-train-list", v);
  22. },
  23. get train() {
  24. return GM_getValue("problem-helper-local-train-list");
  25. },
  26. set local(v) {
  27. GM_setValue("problem-helper-local-id", v);
  28. },
  29. get local() {
  30. return GM_getValue("problem-helper-local-id");
  31. },
  32. set hideac(v) {
  33. GM_setValue("problem-helper-hide-aced", v);
  34. },
  35. get hideac() {
  36. return GM_getValue("problem-helper-hide-aced");
  37. },
  38. };
  39.  
  40. let local_problems;
  41. let geticon = (pid, uid, scr, fscr, stat = null) => {
  42. let res;
  43. let ua = (uid, pid) =>
  44. `<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352 512" class="icon svg-inline--fa fa-times fa-w-11" data-v-303bbf52="" style="transform: scale(1.2); color: rgb(231, 76, 60);"><path data-v-1b44b3e6="" fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" class=""></path></svg></a>`;
  45. let ac = (uid, pid) =>
  46. `<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="check" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" class="icon svg-inline--fa fa-check fa-w-16" data-v-303bbf52="" style="color: rgb(82, 196, 26);"><path data-v-1b44b3e6="" fill="currentColor" d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z" class=""></path></svg></a>`;
  47. let nt = (uid, pid) =>
  48. `<a data-v-303bbf52="" data-v-357e29e4="" href="/record/list?pid=${pid}&amp;user=${uid}" target="_blank" colorscheme="default" class="color-default" data-v-83961efe="" style="color: inherit; float:left; padding-right: 0.5em;"><svg data-v-1b44b3e6="" data-v-357e29e4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="minus" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="icon svg-inline--fa fa-minus fa-w-14" data-v-303bbf52="" style="opacity: 0.7;"><path data-v-1b44b3e6="" fill="currentColor" d="M416 208H32c-17.67 0-32 14.33-32 32v32c0 17.67 14.33 32 32 32h384c17.67 0 32-14.33 32-32v-32c0-17.67-14.33-32-32-32z" class=""></path></svg></a>`;
  49. if (scr == fscr || stat) res = ac(uid, pid);
  50. else if (scr == null) res = nt(uid, pid);
  51. else res = ua(uid, pid);
  52. return (
  53. `<span data-v-3fb75f36="" style="font-weight: bold;">` + res + `</span>`
  54. );
  55. };
  56. let renderList = (title, content, float) =>
  57. `
  58. <div
  59. data-v-796309f8=""
  60. data-v-3fb75f36=""
  61. class="card padding-default"
  62. data-v-6febb0e8=""
  63. id="problem-helper-container"
  64. >
  65. ${float}
  66. <h4 data-v-3fb75f36="" data-v-796309f8="" class="lfe-h4">${title}</h4>
  67. <div class="problem-helper-inner" style="display:none;">
  68. ${content}
  69. </div>
  70. <div data-v-e4b7c2ca="" data-v-3fb75f36="" class="expand-tip lfe-caption" data-v-796309f8="" >
  71. <span class="problem-helper-fold-off" style="display:none;" data-v-e4b7c2ca=""><svg data-v-e4b7c2ca="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="chevron-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-chevron-up fa-w-14" ><path data-v-e4b7c2ca="" fill="currentColor" d="M4.465 366.475l7.07 7.071c4.686 4.686 12.284 4.686 16.971 0L224 178.053l195.494 195.493c4.686 4.686 12.284 4.686 16.971 0l7.07-7.071c4.686-4.686 4.686-12.284 0-16.97l-211.05-211.051c-4.686-4.686-12.284-4.686-16.971 0L4.465 349.505c-4.687 4.686-4.687 12.284 0 16.97z" class=""></path></svg> 隐藏列表</span>
  72. <span class="problem-helper-fold-on" data-v-e4b7c2ca=""><svg data-v-e4b7c2ca="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="chevron-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-chevron-down fa-w-14"><path data-v-e4b7c2ca="" fill="currentColor" d="M443.5 162.6l-7.1-7.1c-4.7-4.7-12.3-4.7-17 0L224 351 28.5 155.5c-4.7-4.7-12.3-4.7-17 0l-7.1 7.1c-4.7 4.7-4.7 12.3 0 17l211 211.1c4.7 4.7 12.3 4.7 17 0l211-211.1c4.8-4.7 4.8-12.3.1-17z" class=""></path></svg> 查看列表</span>
  73. </div>
  74. </div>
  75. `;
  76. let loadProblemList = async (id) => {
  77. return new Promise((res, rej) => {
  78. $.get(`https://www.luogu.com.cn/training/${id}?_contentOnly=any`).then(
  79. (task) => {
  80. task = task.currentData.training;
  81. let getList = (x, is_local) => {
  82. let id = task.problems[x].problem.pid;
  83. if (
  84. configs.hideac &&
  85. task.userScore.status[id] &&
  86. id != configs.local
  87. )
  88. return "";
  89. return `
  90. <div>
  91. <div>
  92. <span data-v-3a151854="">
  93. <a
  94. data-v-303bbf52=""
  95. data-v-3fb75f36=""
  96. href="/record/list?pid=${id}&amp;user=${task.userScore.user.uid}"
  97. class="color-default"
  98. style="text-decoration: none;"
  99. >
  100. ${geticon(
  101. id,
  102. task.userScore.user.uid,
  103. task.userScore.score[id],
  104. task.problems[x].problem.fullScore,
  105. task.userScore.status[id]
  106. )}
  107. </a>
  108. ${
  109. is_local
  110. ? `
  111. <a
  112. data-v-3fb75f36=""
  113. style="float: right;font-weight: light;"
  114. class="problem-helper-delete-from-list"
  115. data="${id}"
  116. >
  117. <svg data-v-4121e124="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-times fa-w-10"><path data-v-4121e124="" fill="currentColor" d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z" class=""></path></svg>
  118. </a>
  119. `
  120. : ""
  121. }
  122. </span>
  123. <a
  124. class="colored problem-helper-text"
  125. style="padding-left: 3px"
  126. href="/problemnew/show/${id}"
  127. target="_blank"
  128. >
  129. <b>${id}</b> ${task.problems[x].problem.title}
  130. </a>
  131. </div>
  132. </div>`;
  133. };
  134. let content = "",
  135. float =
  136. '<a style="float:right;" data="${task.id}" data-v-303bbf52="" data-v-3fb75f36="" href="#" class="problem-helper-train-remove color-default">删除</a>';
  137. if (id == configs.local)
  138. (float = ""),
  139. (local_problems = task.problems.map((u) => u.problem.pid));
  140. for (let i in task.problems)
  141. content += getList(i, id == configs.local);
  142. res(renderList(task.title, content, float));
  143. }
  144. );
  145. });
  146. };
  147. let saveTrain = async (problems) => {
  148. return new Promise((r) => {
  149. $.ajax({
  150. type: "POST",
  151. url: `https://www.luogu.com.cn/api/training/editProblems/${configs.local}`,
  152. beforeSend: function (request) {
  153. request.setRequestHeader(
  154. "x-csrf-token",
  155. $("meta[name='csrf-token']")[0].content
  156. );
  157. },
  158. contentType: "application/json;charset=UTF-8",
  159. data: JSON.stringify({ pids: problems }),
  160. success: () => r(),
  161. });
  162. });
  163. };
  164. let saveConfig = async (config) => {
  165. return new Promise((r) => {
  166. $.ajax({
  167. type: "POST",
  168. url: `https://www.luogu.com.cn/paste/new`,
  169. beforeSend: function (request) {
  170. request.setRequestHeader(
  171. "x-csrf-token",
  172. $("meta[name='csrf-token']")[0].content
  173. );
  174. },
  175. contentType: "application/json;charset=UTF-8",
  176. data: JSON.stringify({
  177. public: false,
  178. data: "#lgtsk" + JSON.stringify(config),
  179. }),
  180. success: () => r(),
  181. });
  182. });
  183. };
  184. let loadConfig = () => {
  185. return new Promise((r) => {
  186. $.get("https://www.luogu.com.cn/paste?_contentOnly").then((u) => {
  187. u = u.currentData.pastes.result;
  188. let nc = null;
  189. for (let i in u) {
  190. try {
  191. if (u[i].data.substr(0, 6) !== "#lgtsk") continue;
  192. let k = u[i].data;
  193. nc = JSON.parse(k.substr(6, k.lentgh));
  194. break;
  195. } catch (e) {}
  196. }
  197. if (!nc) return r(0);
  198. configs.train = nc.train;
  199. configs.local = nc.local;
  200. configs.hideac = nc.hideac;
  201. r(1);
  202. });
  203. });
  204. };
  205. let getScore = async (sett) => {
  206. if (sett.method == "train")
  207. return {
  208. uid: sett.task.userScore.user.uid,
  209. scr: sett.task.userScore.score[sett.id],
  210. fscr: sett.task.problems[sett.id].problem.fullScore,
  211. };
  212. else if (sett.method == "local")
  213. return new Promise((res, rej) => {
  214. $.get(`https://www.luogu.com.cn/problem/${sett.id}?_contentOnly`).then(
  215. (u) => {
  216. res({
  217. uid: u.currentUser.uid,
  218. scr: u.currentData.problem.score,
  219. fscr: u.currentData.problem.fullScore,
  220. });
  221. }
  222. );
  223. });
  224. };
  225. // let loadLocalProblem = async () => {
  226. // let local = GM_getValue("problem-helper-local-list");
  227. // let getList = async (id, opt = 1) => {
  228. // let h = "";
  229. // if (opt) {
  230. // let info = await getScore({ method: "local", id: id });
  231. // h = geticon(info.uid, id, info.scr, info.fscr);
  232. // }
  233. // return `
  234. // <div>
  235. // <div>
  236. // ${h}
  237. // <span data-v-3a151854="">
  238. // <a
  239. // data-v-303bbf52=""
  240. // data-v-3fb75f36=""
  241. // href="#"
  242. // class="color-default"
  243. // style="text-decoration: none;"
  244. // >
  245. // <span
  246. // data-v-3fb75f36=""
  247. // style="float: right;font-weight: light;"
  248. // data="${id}"
  249. // class="problem-helper-delete-from-list"
  250. // >
  251. // 删除
  252. // </span>
  253. // </a>
  254. // </span>
  255. // <a
  256. // class="colored problem-helper-text
  257. // style="padding-left: 3px"
  258. // href="/problemnew/show/${id}"
  259. // target="_blank"
  260. // >
  261. // <b>${id}</b> ${local[id]}
  262. // </a>
  263. // </div>
  264. // </div>`;
  265. // };
  266. // let content = "";
  267. // for (let i in local) content += await getList(i);
  268. // return renderList("本地列表", content, "");
  269. // };
  270. function renderItem(title, id) {
  271. return `
  272. <div>
  273. <div>
  274. <span data-v-3a151854="">
  275. <a
  276. data-v-303bbf52=""
  277. data-v-3fb75f36=""
  278. href="/record/list?pid=${id}&amp;user=${task.userScore.user.uid}"
  279. class="color-default"
  280. style="text-decoration: none;"
  281. >
  282. ${geticon(
  283. id,
  284. task.userScore.user.uid,
  285. task.userScore.score[id],
  286. task.problems[x].problem.fullScore,
  287. task.userScore.status[id]
  288. )}
  289. </a>
  290. </span>
  291. <a
  292. class="colored problem-helper-text
  293. style="padding-left: 3px"
  294. href="/problemnew/show/${id}"
  295. target="_blank"
  296. >
  297. <b>${id}</b> ${task.problems[x].problem.title}
  298. </a>
  299. </div>
  300. </div>
  301. `;
  302. }
  303. async function loaderProblemEntry() {
  304. let lists = "";
  305. let urls = configs.train || [];
  306. // console.log(urls);
  307. if (configs.local && !urls[configs.local]) urls[configs.local] = "本地列表";
  308. for (let i in urls) lists += await loadProblemList(i);
  309. lists += renderList(
  310. "设置",
  311. `<div data-v-59a1d633="" data-v-83961efe="" class="row">
  312. <div data-v-72d91c56="" data-v-59a1d633="" class="checkbox" data-v-83961efe=""><input id="problem-helper-hide-aced" type="checkbox" value="65560" ${
  313. configs.hideac ? 'checked=""' : ""
  314. }"> <lable>
  315. 隐藏已通过题目
  316. </label> </div>
  317. <div>
  318. <label>本地题单</label>
  319. <input data-v-a7f7c968="" type="text" placeholder="题单id" class="lfe-form-sz-middle" style+"width: 30%;" value="${
  320. configs.local || ""
  321. }" id="problem-helper-set-local-list">
  322. </div>
  323. <div>
  324. <a id="problem-helper-save">保存到洛谷云剪贴板</a>
  325. <a id="problem-helper-load">从洛谷云剪贴板加载</a>
  326. </div>
  327. </div>`,
  328. ""
  329. );
  330. $("#problem-helper-entry").html(lists);
  331. $(".problem-helper-fold-on").click((u) => {
  332. u = $(u.target);
  333. u.parent().prev(".problem-helper-inner").removeAttr("style");
  334. u.attr("style", "display:none;");
  335. u.prev(".problem-helper-fold-off").removeAttr("style");
  336. });
  337. $(".problem-helper-fold-off").click((u) => {
  338. u = $(u.target);
  339. u.parent().prev(".problem-helper-inner").attr("style", "display:none;");
  340. u.attr("style", "display:none;");
  341. u.next(".problem-helper-fold-on").removeAttr("style");
  342. });
  343. $("#problem-helper-hide-aced").click((u) => {
  344. u = $(u.target);
  345. configs.hideac = u[0].checked;
  346. unsafeWindow._feInstance.$swalToastSuccess("修改成功");
  347. loaderProblemEntry();
  348. });
  349. $("#problem-helper-save").click((u) => {
  350. saveConfig(configs);
  351. unsafeWindow._feInstance.$swalToastSuccess("保存成功");
  352. loaderProblemEntry();
  353. });
  354. $("#problem-helper-load").click(async (u) => {
  355. if (await loadConfig())
  356. unsafeWindow._feInstance.$swalToastSuccess("加载成功");
  357. else unsafeWindow._feInstance.$swalToastError("加载失败");
  358. loaderProblemEntry();
  359. });
  360. $("#problem-helper-set-local-list").keydown(function (e) {
  361. if (e.keyCode == 13) {
  362. configs.local = $("#problem-helper-set-local-list").val();
  363. unsafeWindow._feInstance.$swalToastSuccess("修改成功");
  364. loaderProblemEntry();
  365. }
  366. });
  367. $("#problem-helper-add-to-list").click((u) => {
  368. let r = unsafeWindow.location.href.split("/");
  369. r = r[r.length - 1];
  370. while (r[r.length - 1] == "#") r = r.slice(0, r.length - 1);
  371. if (!unsafeWindow._feInjection.currentData.problem.title) return;
  372. if (local_problems.indexOf(r) == -1) local_problems.push(r);
  373. saveTrain(local_problems);
  374. unsafeWindow._feInstance.$swalToastSuccess("添加成功");
  375. loaderProblemEntry();
  376. });
  377. $(".problem-helper-delete-from-list").click((u) => {
  378. u = $(u.target).parents(".problem-helper-delete-from-list");
  379. let r = u.attr("data");
  380. let now = local_problems;
  381. let newone = [];
  382. for (let i in now) if (now[i] != r) newone[i] = now[i];
  383. saveTrain(newone);
  384. unsafeWindow._feInstance.$swalToastSuccess("删除成功");
  385. loaderProblemEntry();
  386. });
  387. $(".problem-helper-train-remove").click((u) => {
  388. u = $(u.target);
  389. let r = u.attr("data");
  390. let now = configs.train;
  391. let newone = {};
  392. for (let i in now) if (i != r) newone[i] = now[i];
  393. configs.train = now;
  394. unsafeWindow._feInstance.$swalToastSuccess("删除成功");
  395. loaderProblemEntry();
  396. });
  397. }
  398. let deferredInjectProblemPage = () => {
  399. $("#problem-helper-container").remove();
  400. $(".side").prepend(
  401. renderList(
  402. "做题助手",
  403. '<div id="problem-helper-entry"></div>',
  404. '<a style="float:right;" data-v-303bbf52="" data-v-3fb75f36="" href="#" id="problem-helper-add-to-list" class="color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>添加至列表</a >'
  405. )
  406. );
  407. loaderProblemEntry();
  408. };
  409. let loadTrainList = (id) => {
  410. let local = configs.train;
  411. let getList = (id) => {
  412. return `
  413. <div>
  414. <div>
  415. <span data-v-3a151854="">
  416. <a
  417. style="text-decoration: none;float: right;font-weight: light;"
  418. data="${id}"
  419. class="color-default problem-helper-delete-from-list"
  420. data-v-303bbf52=""
  421. data-v-3fb75f36=""
  422. href="#"
  423. >
  424. <svg data-v-4121e124="" aria-hidden="true" focusable="false" data-prefix="fal" data-icon="times" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" class="svg-inline--fa fa-times fa-w-10"><path data-v-4121e124="" fill="currentColor" d="M193.94 256L296.5 153.44l21.15-21.15c3.12-3.12 3.12-8.19 0-11.31l-22.63-22.63c-3.12-3.12-8.19-3.12-11.31 0L160 222.06 36.29 98.34c-3.12-3.12-8.19-3.12-11.31 0L2.34 120.97c-3.12 3.12-3.12 8.19 0 11.31L126.06 256 2.34 379.71c-3.12 3.12-3.12 8.19 0 11.31l22.63 22.63c3.12 3.12 8.19 3.12 11.31 0L160 289.94 262.56 392.5l21.15 21.15c3.12 3.12 8.19 3.12 11.31 0l22.63-22.63c3.12-3.12 3.12-8.19 0-11.31L193.94 256z" class=""></path></svg>
  425. </a>
  426. </span>
  427. <a
  428. class="colored problem-helper-text"
  429. style="padding-left: 3px"
  430. href="https://www.luogu.com.cn/training/${id}#information"
  431. target="_blank"
  432. >
  433. <b>${id}</b> ${local[id]}
  434. </a>
  435. </div>
  436. </div>`;
  437. };
  438. let lists = "";
  439. for (let i in local) lists += getList(i);
  440. return lists;
  441. };
  442. let loaderTrainEntry = async () => {
  443. let lists = loadTrainList();
  444. $("#problem-helper-entry").html(lists);
  445. $(".problem-helper-fold-on").click((u) => {
  446. u = $(u.target);
  447. u.parent().prev(".problem-helper-inner").removeAttr("style");
  448. u.attr("style", "display:none;");
  449. u.prev(".problem-helper-fold-off").removeAttr("style");
  450. });
  451. $(".problem-helper-fold-off").click((u) => {
  452. u = $(u.target);
  453. u.parent().prev(".problem-helper-inner").attr("style", "display:none;");
  454. u.attr("style", "display:none;");
  455. u.next(".problem-helper-fold-on").removeAttr("style");
  456. });
  457. $("#problem-helper-add-to-list").click((u) => {
  458. let r = unsafeWindow.location.href.split("/");
  459. r = r[r.length - 1].split("#")[0];
  460. if (!unsafeWindow._feInjection.currentData.training.title) return;
  461. let now = configs.train;
  462. if (!now) now = {};
  463. now[r] = unsafeWindow._feInjection.currentData.training.title;
  464. configs.train = now;
  465. unsafeWindow._feInstance.$swalToastSuccess("添加成功");
  466. loaderTrainEntry();
  467. });
  468. $(".problem-helper-delete-from-list").click((u) => {
  469. u = $(u.target).parents(".problem-helper-delete-from-list");
  470. let r = u.attr("data");
  471. let now = configs.train;
  472. let newone = {};
  473. for (let i in now) if (i != r) newone[i] = now[i];
  474. configs.train = newone;
  475. unsafeWindow._feInstance.$swalToastSuccess("删除成功");
  476. loaderProblemEntry();
  477. });
  478. };
  479. let deferredInjectTrainPage = () => {
  480. $("#problem-helper-container").remove();
  481. $(".side").prepend(
  482. renderList(
  483. "做题助手",
  484. '<div id="problem-helper-entry"></div>',
  485. '<a style="float:right;" data-v-303bbf52="" data-v-3fb75f36="" href="#" id="problem-helper-add-to-list" class="color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>添加至列表</a>'
  486. )
  487. );
  488. loaderTrainEntry();
  489. };
  490. let deferredInjectProblemlist = () => {
  491. $(".problem-helper-inlist-adder").remove();
  492. let pid = "",
  493. name = "";
  494. let h = (pid, name) => `
  495. <a style="float:right; padding-right: 2em;" data="${pid}" name="${name}" data-v-303bbf52="" data-v-3fb75f36="" href="#" class="problem-helper-inlist-adder color-default"><svg data-v-b35188f4="" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="plus-square" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="svg-inline--fa fa-plus-square fa-w-14"><path data-v-b35188f4="" fill="currentColor" d="M400 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zm-32 252c0 6.6-5.4 12-12 12h-92v92c0 6.6-5.4 12-12 12h-56c-6.6 0-12-5.4-12-12v-92H92c-6.6 0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h92v-92c0-6.6 5.4-12 12-12h56c6.6 0 12 5.4 12 12v92h92c6.6 0 12 5.4 12 12v56z" class=""></path></svg>
  496. 添加
  497. </a>`;
  498. let rows = $(".row");
  499. let trim = (s) => {
  500. return s.replace(/(^\s*)|(\s*$)/g, "");
  501. };
  502. rows.each((u) => {
  503. u = $(rows[u]);
  504. pid = u.children(".pid").text();
  505. name = u.children(".title").children(".title").text();
  506. name = trim(name);
  507. u.children(".title").prepend(h(pid, name));
  508. });
  509. $(".problem-helper-inlist-adder").click((u) => {
  510. u = $(u.target);
  511. let r = u.attr("data"),
  512. s = u.attr("name");
  513. let now = GM_getValue("problem-helper-local-list");
  514. if (!now) now = {};
  515. now[r] = s;
  516. GM_setValue("problem-helper-local-list", now);
  517. unsafeWindow._feInstance.$swalToastSuccess("添加成功");
  518. });
  519. };
  520.  
  521. /* main controller */
  522. let inject = () => {
  523. if (
  524. unsafeWindow.location.href.includes(
  525. "problem/list"
  526. ) /*deferredInjectProblemlist();*/
  527. );
  528. else if (unsafeWindow.location.href.includes("training"))
  529. deferredInjectTrainPage(), deferredInjectProblemlist();
  530. else if (unsafeWindow.location.href.includes("problem"))
  531. deferredInjectProblemPage();
  532. };
  533. $(".entry").click(() => setTimeout(inject, inject_lantency));
  534. $("a").click(() => setTimeout(inject, inject_lantency));
  535. $("button").click(() => setTimeout(inject, inject_lantency));
  536. setTimeout(inject, 100);
  537. $(document.body).append(
  538. `<style>
  539. .problem-helper-text{
  540. -webkit-line-clamp: 1; overflow: hidden; display: -webkit-box;
  541. -webkit-box-orient: vertical; white-space: normal;
  542. }
  543. .expand-tip > span[data-v-e4b7c2ca] {
  544. -webkit-user-select: none;
  545. -moz-user-select: none;
  546. -ms-user-select: none;
  547. cuser-select: none;
  548. cursor: pointer;
  549. color: rgba(0, 0, 0, .3);
  550. }
  551. .expand-tip[data-v-e4b7c2ca] {
  552. text-align: center;
  553. }
  554. .expand-tip > span[data-v-e4b7c2ca]:hover {
  555. color: inherit;
  556. }
  557. </style>`
  558. );
  559. };