dlsite_rj_code_preview

Make RJ code great again!

  1. // ==UserScript==
  2. // @name dlsite_rj_code_preview
  3. // @author SettingDust
  4. // @description Make RJ code great again!
  5. // @grant GM_xmlhttpRequest
  6. // @grant GM_setValue
  7. // @grant GM_getValue
  8. // @inject-into auto
  9. // @match *://*/*
  10. // @match *://dlsite.com/*
  11. // @name:zh-CN DLSite_RJ_码预览
  12. // @namespace SettingDust
  13. // @run-at document-end
  14. // @version 3.1.0
  15. // ==/UserScript==
  16.  
  17. // src/fetch-rj.ts
  18. var productPage = (rj) => `https://www.dlsite.com/maniax/work/=/product_id/${rj.toUpperCase()}.html`, agings = {
  19. adult: "18 \u7981",
  20. general: "\u5168\u5E74\u9F84"
  21. };
  22. function productInfo(rj) {
  23. return new Promise((resolve, reject) => {
  24. GM_xmlhttpRequest({
  25. url: `https://www.dlsite.com/maniax/api/=/product.json?workno=${rj}`,
  26. responseType: "json",
  27. onload: function(resp) {
  28. resp.readyState === 4 && resp.status === 200 ? (resolve(resp.response[0]), console.debug("[rj-code-preview/product]", resp.response[0])) : reject(resp);
  29. }
  30. });
  31. });
  32. }
  33. function productRatingInfo(rj) {
  34. return new Promise((resolve, reject) => {
  35. GM_xmlhttpRequest({
  36. url: `https://www.dlsite.com/maniax/product/info/ajax?product_id=${rj}`,
  37. responseType: "json",
  38. onload: function(resp) {
  39. resp.readyState === 4 && resp.status === 200 ? (resolve(resp.response[rj]), console.debug("[rj-code-preview/rating]", resp.response[rj])) : reject(resp);
  40. }
  41. });
  42. });
  43. }
  44. function fetch_rj_default(rj) {
  45. return new Promise((resolve, reject) => {
  46. Promise.all([productInfo(rj), productRatingInfo(rj)]).then(
  47. ([product, rating]) => {
  48. var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
  49. return {
  50. name: product.work_name,
  51. image: (_a = product.image_main) == null ? void 0 : _a.url,
  52. type: product.work_type_string,
  53. group: product.maker_name,
  54. date: product.regist_date,
  55. series: product.title_name,
  56. age: (_b = agings[product.age_category_string]) != null ? _b : product.age_category_string,
  57. voices: (_d = (_c = product.creaters) == null ? void 0 : _c.voice_by) == null ? void 0 : _d.map((it) => it.name),
  58. illusts: (_f = (_e = product.creaters) == null ? void 0 : _e.illust_by) == null ? void 0 : _f.map((it) => it.name),
  59. scenarios: (_h = (_g = product.creaters) == null ? void 0 : _g.scenario_by) == null ? void 0 : _h.map((it) => it.name),
  60. creators: (_j = (_i = product.creaters) == null ? void 0 : _i.created_by) == null ? void 0 : _j.map((it) => it.name),
  61. musics: (_l = (_k = product.creaters) == null ? void 0 : _k.music_by) == null ? void 0 : _l.map((it) => it.name),
  62. hasCreators: (_n = (_m = product.creaters) == null ? void 0 : _m.created_by) == null ? void 0 : _n.length,
  63. hasScenarios: (_p = (_o = product.creaters) == null ? void 0 : _o.scenario_by) == null ? void 0 : _p.length,
  64. hasIllusts: (_r = (_q = product.creaters) == null ? void 0 : _q.illust_by) == null ? void 0 : _r.length,
  65. hasVoices: (_t = (_s = product.creaters) == null ? void 0 : _s.voice_by) == null ? void 0 : _t.length,
  66. hasMusics: (_v = (_u = product.creaters) == null ? void 0 : _u.music_by) == null ? void 0 : _v.length,
  67. tags: (_w = product.genres) == null ? void 0 : _w.map((it) => it.name),
  68. hasTags: (_x = product.genres) == null ? void 0 : _x.length,
  69. rating: rating == null ? void 0 : rating.rate_average_2dp,
  70. sale: rating == null ? void 0 : rating.dl_count
  71. };
  72. }
  73. ).then((it) => {
  74. GM_setValue(rj, it), resolve(it);
  75. }).catch(reject);
  76. let cache = GM_getValue(rj);
  77. cache && (console.debug(`[rj-code-preview/cached/${rj}]`), resolve(cache));
  78. });
  79. }
  80.  
  81. // src/hack-rj-code.ts
  82. var RJ_CODE_LINK_CLASS = "rj-code", RJ_CODE_ATTRIBUTE = "rjCode", RJ_REGEX = new RegExp("R[JE][0-9]{6,8}", "gi");
  83. function wrapRJCode(rj) {
  84. let a = document.createElement("a");
  85. return a.classList.add(RJ_CODE_LINK_CLASS), a.href = productPage(rj), a.innerHTML = rj, a.target = "_blank", a.rel = "noreferrer", a.dataset[RJ_CODE_ATTRIBUTE] = rj.toUpperCase(), a;
  86. }
  87. function injectRJCode(node) {
  88. var _a;
  89. let text = node.nodeValue, matches = [], match;
  90. for (; match = RJ_REGEX.exec(text); )
  91. matches.push({
  92. index: match.index,
  93. value: match[0]
  94. });
  95. matches.length && console.debug("[rj-code-preview/matches]", text, matches), node.nodeValue = text.substring(0, matches[0].index);
  96. let prev = null;
  97. for (let i = 0; i < matches.length; i++) {
  98. let match2 = matches[i], a = wrapRJCode(match2.value);
  99. node.parentNode.insertBefore(a, prev ? prev.nextSibling : node.nextSibling);
  100. let nextIndex = (_a = matches[i + 1]) == null ? void 0 : _a.index, afterText = text.substring(
  101. match2.index + match2.value.length,
  102. nextIndex
  103. );
  104. if (afterText) {
  105. let afterNode = document.createTextNode(afterText);
  106. node.parentNode.insertBefore(afterNode, a.nextElementSibling), prev = afterNode;
  107. } else
  108. prev = a;
  109. }
  110. }
  111. function hack_rj_code_default(root) {
  112. let walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, {
  113. acceptNode(node) {
  114. if (node.parentElement.classList.contains(RJ_CODE_LINK_CLASS) || node.nodeValue.match(RJ_REGEX))
  115. return NodeFilter.FILTER_ACCEPT;
  116. }
  117. });
  118. for (; walker.nextNode(); ) {
  119. let node = walker.currentNode;
  120. node.parentElement.classList.contains(RJ_CODE_LINK_CLASS) || injectRJCode(node);
  121. }
  122. }
  123.  
  124. // node_modules/.pnpm/mustache@4.2.0/node_modules/mustache/mustache.mjs
  125. var objectToString = Object.prototype.toString, isArray = Array.isArray || function(object) {
  126. return objectToString.call(object) === "[object Array]";
  127. };
  128. function isFunction(object) {
  129. return typeof object == "function";
  130. }
  131. function typeStr(obj) {
  132. return isArray(obj) ? "array" : typeof obj;
  133. }
  134. function escapeRegExp(string) {
  135. return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
  136. }
  137. function hasProperty(obj, propName) {
  138. return obj != null && typeof obj == "object" && propName in obj;
  139. }
  140. function primitiveHasOwnProperty(primitive, propName) {
  141. return primitive != null && typeof primitive != "object" && primitive.hasOwnProperty && primitive.hasOwnProperty(propName);
  142. }
  143. var regExpTest = RegExp.prototype.test;
  144. function testRegExp(re, string) {
  145. return regExpTest.call(re, string);
  146. }
  147. var nonSpaceRe = /\S/;
  148. function isWhitespace(string) {
  149. return !testRegExp(nonSpaceRe, string);
  150. }
  151. var entityMap = {
  152. "&": "&amp;",
  153. "<": "&lt;",
  154. ">": "&gt;",
  155. '"': "&quot;",
  156. "'": "&#39;",
  157. "/": "&#x2F;",
  158. "`": "&#x60;",
  159. "=": "&#x3D;"
  160. };
  161. function escapeHtml(string) {
  162. return String(string).replace(/[&<>"'`=\/]/g, function(s) {
  163. return entityMap[s];
  164. });
  165. }
  166. var whiteRe = /\s*/, spaceRe = /\s+/, equalsRe = /\s*=/, curlyRe = /\s*\}/, tagRe = /#|\^|\/|>|\{|&|=|!/;
  167. function parseTemplate(template2, tags) {
  168. if (!template2)
  169. return [];
  170. var lineHasNonSpace = !1, sections = [], tokens = [], spaces = [], hasTag = !1, nonSpace = !1, indentation = "", tagIndex = 0;
  171. function stripSpace() {
  172. if (hasTag && !nonSpace)
  173. for (; spaces.length; )
  174. delete tokens[spaces.pop()];
  175. else
  176. spaces = [];
  177. hasTag = !1, nonSpace = !1;
  178. }
  179. var openingTagRe, closingTagRe, closingCurlyRe;
  180. function compileTags(tagsToCompile) {
  181. if (typeof tagsToCompile == "string" && (tagsToCompile = tagsToCompile.split(spaceRe, 2)), !isArray(tagsToCompile) || tagsToCompile.length !== 2)
  182. throw new Error("Invalid tags: " + tagsToCompile);
  183. openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + "\\s*"), closingTagRe = new RegExp("\\s*" + escapeRegExp(tagsToCompile[1])), closingCurlyRe = new RegExp("\\s*" + escapeRegExp("}" + tagsToCompile[1]));
  184. }
  185. compileTags(tags || mustache.tags);
  186. for (var scanner = new Scanner(template2), start, type, value, chr, token, openSection; !scanner.eos(); ) {
  187. if (start = scanner.pos, value = scanner.scanUntil(openingTagRe), value)
  188. for (var i = 0, valueLength = value.length; i < valueLength; ++i)
  189. chr = value.charAt(i), isWhitespace(chr) ? (spaces.push(tokens.length), indentation += chr) : (nonSpace = !0, lineHasNonSpace = !0, indentation += " "), tokens.push(["text", chr, start, start + 1]), start += 1, chr === `
  190. ` && (stripSpace(), indentation = "", tagIndex = 0, lineHasNonSpace = !1);
  191. if (!scanner.scan(openingTagRe))
  192. break;
  193. if (hasTag = !0, type = scanner.scan(tagRe) || "name", scanner.scan(whiteRe), type === "=" ? (value = scanner.scanUntil(equalsRe), scanner.scan(equalsRe), scanner.scanUntil(closingTagRe)) : type === "{" ? (value = scanner.scanUntil(closingCurlyRe), scanner.scan(curlyRe), scanner.scanUntil(closingTagRe), type = "&") : value = scanner.scanUntil(closingTagRe), !scanner.scan(closingTagRe))
  194. throw new Error("Unclosed tag at " + scanner.pos);
  195. if (type == ">" ? token = [type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace] : token = [type, value, start, scanner.pos], tagIndex++, tokens.push(token), type === "#" || type === "^")
  196. sections.push(token);
  197. else if (type === "/") {
  198. if (openSection = sections.pop(), !openSection)
  199. throw new Error('Unopened section "' + value + '" at ' + start);
  200. if (openSection[1] !== value)
  201. throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
  202. } else
  203. type === "name" || type === "{" || type === "&" ? nonSpace = !0 : type === "=" && compileTags(value);
  204. }
  205. if (stripSpace(), openSection = sections.pop(), openSection)
  206. throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
  207. return nestTokens(squashTokens(tokens));
  208. }
  209. function squashTokens(tokens) {
  210. for (var squashedTokens = [], token, lastToken, i = 0, numTokens = tokens.length; i < numTokens; ++i)
  211. token = tokens[i], token && (token[0] === "text" && lastToken && lastToken[0] === "text" ? (lastToken[1] += token[1], lastToken[3] = token[3]) : (squashedTokens.push(token), lastToken = token));
  212. return squashedTokens;
  213. }
  214. function nestTokens(tokens) {
  215. for (var nestedTokens = [], collector = nestedTokens, sections = [], token, section, i = 0, numTokens = tokens.length; i < numTokens; ++i)
  216. switch (token = tokens[i], token[0]) {
  217. case "#":
  218. case "^":
  219. collector.push(token), sections.push(token), collector = token[4] = [];
  220. break;
  221. case "/":
  222. section = sections.pop(), section[5] = token[2], collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
  223. break;
  224. default:
  225. collector.push(token);
  226. }
  227. return nestedTokens;
  228. }
  229. function Scanner(string) {
  230. this.string = string, this.tail = string, this.pos = 0;
  231. }
  232. Scanner.prototype.eos = function() {
  233. return this.tail === "";
  234. };
  235. Scanner.prototype.scan = function(re) {
  236. var match = this.tail.match(re);
  237. if (!match || match.index !== 0)
  238. return "";
  239. var string = match[0];
  240. return this.tail = this.tail.substring(string.length), this.pos += string.length, string;
  241. };
  242. Scanner.prototype.scanUntil = function(re) {
  243. var index = this.tail.search(re), match;
  244. switch (index) {
  245. case -1:
  246. match = this.tail, this.tail = "";
  247. break;
  248. case 0:
  249. match = "";
  250. break;
  251. default:
  252. match = this.tail.substring(0, index), this.tail = this.tail.substring(index);
  253. }
  254. return this.pos += match.length, match;
  255. };
  256. function Context(view, parentContext) {
  257. this.view = view, this.cache = { ".": this.view }, this.parent = parentContext;
  258. }
  259. Context.prototype.push = function(view) {
  260. return new Context(view, this);
  261. };
  262. Context.prototype.lookup = function(name) {
  263. var cache = this.cache, value;
  264. if (cache.hasOwnProperty(name))
  265. value = cache[name];
  266. else {
  267. for (var context = this, intermediateValue, names, index, lookupHit = !1; context; ) {
  268. if (name.indexOf(".") > 0)
  269. for (intermediateValue = context.view, names = name.split("."), index = 0; intermediateValue != null && index < names.length; )
  270. index === names.length - 1 && (lookupHit = hasProperty(intermediateValue, names[index]) || primitiveHasOwnProperty(intermediateValue, names[index])), intermediateValue = intermediateValue[names[index++]];
  271. else
  272. intermediateValue = context.view[name], lookupHit = hasProperty(context.view, name);
  273. if (lookupHit) {
  274. value = intermediateValue;
  275. break;
  276. }
  277. context = context.parent;
  278. }
  279. cache[name] = value;
  280. }
  281. return isFunction(value) && (value = value.call(this.view)), value;
  282. };
  283. function Writer() {
  284. this.templateCache = {
  285. _cache: {},
  286. set: function(key, value) {
  287. this._cache[key] = value;
  288. },
  289. get: function(key) {
  290. return this._cache[key];
  291. },
  292. clear: function() {
  293. this._cache = {};
  294. }
  295. };
  296. }
  297. Writer.prototype.clearCache = function() {
  298. typeof this.templateCache != "undefined" && this.templateCache.clear();
  299. };
  300. Writer.prototype.parse = function(template2, tags) {
  301. var cache = this.templateCache, cacheKey = template2 + ":" + (tags || mustache.tags).join(":"), isCacheEnabled = typeof cache != "undefined", tokens = isCacheEnabled ? cache.get(cacheKey) : void 0;
  302. return tokens == null && (tokens = parseTemplate(template2, tags), isCacheEnabled && cache.set(cacheKey, tokens)), tokens;
  303. };
  304. Writer.prototype.render = function(template2, view, partials, config) {
  305. var tags = this.getConfigTags(config), tokens = this.parse(template2, tags), context = view instanceof Context ? view : new Context(view, void 0);
  306. return this.renderTokens(tokens, context, partials, template2, config);
  307. };
  308. Writer.prototype.renderTokens = function(tokens, context, partials, originalTemplate, config) {
  309. for (var buffer = "", token, symbol, value, i = 0, numTokens = tokens.length; i < numTokens; ++i)
  310. value = void 0, token = tokens[i], symbol = token[0], symbol === "#" ? value = this.renderSection(token, context, partials, originalTemplate, config) : symbol === "^" ? value = this.renderInverted(token, context, partials, originalTemplate, config) : symbol === ">" ? value = this.renderPartial(token, context, partials, config) : symbol === "&" ? value = this.unescapedValue(token, context) : symbol === "name" ? value = this.escapedValue(token, context, config) : symbol === "text" && (value = this.rawValue(token)), value !== void 0 && (buffer += value);
  311. return buffer;
  312. };
  313. Writer.prototype.renderSection = function(token, context, partials, originalTemplate, config) {
  314. var self = this, buffer = "", value = context.lookup(token[1]);
  315. function subRender(template2) {
  316. return self.render(template2, context, partials, config);
  317. }
  318. if (value) {
  319. if (isArray(value))
  320. for (var j = 0, valueLength = value.length; j < valueLength; ++j)
  321. buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);
  322. else if (typeof value == "object" || typeof value == "string" || typeof value == "number")
  323. buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);
  324. else if (isFunction(value)) {
  325. if (typeof originalTemplate != "string")
  326. throw new Error("Cannot use higher-order sections without the original template");
  327. value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender), value != null && (buffer += value);
  328. } else
  329. buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);
  330. return buffer;
  331. }
  332. };
  333. Writer.prototype.renderInverted = function(token, context, partials, originalTemplate, config) {
  334. var value = context.lookup(token[1]);
  335. if (!value || isArray(value) && value.length === 0)
  336. return this.renderTokens(token[4], context, partials, originalTemplate, config);
  337. };
  338. Writer.prototype.indentPartial = function(partial, indentation, lineHasNonSpace) {
  339. for (var filteredIndentation = indentation.replace(/[^ \t]/g, ""), partialByNl = partial.split(`
  340. `), i = 0; i < partialByNl.length; i++)
  341. partialByNl[i].length && (i > 0 || !lineHasNonSpace) && (partialByNl[i] = filteredIndentation + partialByNl[i]);
  342. return partialByNl.join(`
  343. `);
  344. };
  345. Writer.prototype.renderPartial = function(token, context, partials, config) {
  346. if (partials) {
  347. var tags = this.getConfigTags(config), value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
  348. if (value != null) {
  349. var lineHasNonSpace = token[6], tagIndex = token[5], indentation = token[4], indentedValue = value;
  350. tagIndex == 0 && indentation && (indentedValue = this.indentPartial(value, indentation, lineHasNonSpace));
  351. var tokens = this.parse(indentedValue, tags);
  352. return this.renderTokens(tokens, context, partials, indentedValue, config);
  353. }
  354. }
  355. };
  356. Writer.prototype.unescapedValue = function(token, context) {
  357. var value = context.lookup(token[1]);
  358. if (value != null)
  359. return value;
  360. };
  361. Writer.prototype.escapedValue = function(token, context, config) {
  362. var escape = this.getConfigEscape(config) || mustache.escape, value = context.lookup(token[1]);
  363. if (value != null)
  364. return typeof value == "number" && escape === mustache.escape ? String(value) : escape(value);
  365. };
  366. Writer.prototype.rawValue = function(token) {
  367. return token[1];
  368. };
  369. Writer.prototype.getConfigTags = function(config) {
  370. return isArray(config) ? config : config && typeof config == "object" ? config.tags : void 0;
  371. };
  372. Writer.prototype.getConfigEscape = function(config) {
  373. if (config && typeof config == "object" && !isArray(config))
  374. return config.escape;
  375. };
  376. var mustache = {
  377. name: "mustache.js",
  378. version: "4.2.0",
  379. tags: ["{{", "}}"],
  380. clearCache: void 0,
  381. escape: void 0,
  382. parse: void 0,
  383. render: void 0,
  384. Scanner: void 0,
  385. Context: void 0,
  386. Writer: void 0,
  387. /**
  388. * Allows a user to override the default caching strategy, by providing an
  389. * object with set, get and clear methods. This can also be used to disable
  390. * the cache by setting it to the literal `undefined`.
  391. */
  392. set templateCache(cache) {
  393. defaultWriter.templateCache = cache;
  394. },
  395. /**
  396. * Gets the default or overridden caching object from the default writer.
  397. */
  398. get templateCache() {
  399. return defaultWriter.templateCache;
  400. }
  401. }, defaultWriter = new Writer();
  402. mustache.clearCache = function() {
  403. return defaultWriter.clearCache();
  404. };
  405. mustache.parse = function(template2, tags) {
  406. return defaultWriter.parse(template2, tags);
  407. };
  408. mustache.render = function(template2, view, partials, config) {
  409. if (typeof template2 != "string")
  410. throw new TypeError('Invalid template! Template should be a "string" but "' + typeStr(template2) + '" was given as the first argument for mustache#render(template, view, partials)');
  411. return defaultWriter.render(template2, view, partials, config);
  412. };
  413. mustache.escape = escapeHtml;
  414. mustache.Scanner = Scanner;
  415. mustache.Context = Context;
  416. mustache.Writer = Writer;
  417. var mustache_default = mustache;
  418.  
  419. // node_modules/.pnpm/delegate-it@5.0.0/node_modules/delegate-it/index.js
  420. var ledger = /* @__PURE__ */ new WeakMap();
  421. function editLedger(wanted, baseElement, callback, setup) {
  422. var _a, _b;
  423. if (!wanted && !ledger.has(baseElement))
  424. return !1;
  425. let elementMap = (_a = ledger.get(baseElement)) != null ? _a : /* @__PURE__ */ new WeakMap();
  426. if (ledger.set(baseElement, elementMap), !wanted && !ledger.has(baseElement))
  427. return !1;
  428. let setups = (_b = elementMap.get(callback)) != null ? _b : /* @__PURE__ */ new Set();
  429. elementMap.set(callback, setups);
  430. let existed = setups.has(setup);
  431. return wanted ? setups.add(setup) : setups.delete(setup), existed && wanted;
  432. }
  433. function isEventTarget(elements) {
  434. return typeof elements.addEventListener == "function";
  435. }
  436. function safeClosest(event, selector) {
  437. let target = event.target;
  438. if (target instanceof Text && (target = target.parentElement), target instanceof Element && event.currentTarget instanceof Element) {
  439. let closest = target.closest(selector);
  440. if (closest && event.currentTarget.contains(closest))
  441. return closest;
  442. }
  443. }
  444. function delegate(base, selector, type, callback, options) {
  445. let listenerOptions = typeof options == "object" ? options : { capture: options };
  446. delete listenerOptions.once;
  447. let { signal } = listenerOptions;
  448. if (signal != null && signal.aborted)
  449. return;
  450. if (typeof base == "string" && (base = document.querySelectorAll(base)), !isEventTarget(base)) {
  451. for (let element of base)
  452. delegate(element, selector, type, callback, listenerOptions);
  453. return;
  454. }
  455. let baseElement = base instanceof Document ? base.documentElement : base, capture = Boolean(typeof options == "object" ? options.capture : options), listenerFn = (event) => {
  456. let delegateTarget = safeClosest(event, selector);
  457. if (delegateTarget) {
  458. let delegateEvent = Object.assign(event, { delegateTarget });
  459. callback.call(baseElement, delegateEvent);
  460. }
  461. }, setup = JSON.stringify({ selector, type, capture });
  462. editLedger(!0, baseElement, callback, setup) || baseElement.addEventListener(type, listenerFn, listenerOptions), signal == null || signal.addEventListener("abort", () => {
  463. editLedger(!1, baseElement, callback, setup);
  464. });
  465. }
  466. var delegate_it_default = delegate;
  467.  
  468. // src/popup.ts
  469. var linkSelector = `a.${RJ_CODE_LINK_CLASS}`, template = `
  470. <img src="{{ image }}">
  471. <div class="info">
  472. <h3>{{ name }}</h3>
  473. {{ #rating }}<p><span>\u8BC4\u4EF7\uFF1A</span><span>{{ rating }}</span></p>{{ /rating }}
  474. {{ #sale }}<p><span>\u8D29\u5356\u6570\uFF1A</span><span>{{ sale }}</span></p>{{ /sale }}
  475. {{ #group }}<p><span>\u793E\u56E2\u540D\uFF1A</span><span>{{ group }}</span></p>{{ /group }}
  476. {{ #date }}<p><span>\u8D29\u5356\u65E5\uFF1A</span><span>{{ date }}</span></p>{{ /date }}
  477. {{ #series }}<p><span>\u7CFB\u5217\u540D\uFF1A</span><span>{{ series }}</span></p>{{ /series }}
  478. {{ #hasCreators }}<p><span>\u4F5C\u8005\uFF1A</span>{{ #creators }}<span>{{ . }} / </span>{{ /creators }}</p>{{ /hasCreators }}
  479. {{ #hasScenarios }}<p><span>\u5267\u60C5\uFF1A</span>{{ #scenarios }}<span>{{ . }} / </span>{{ /scenarios }}</p>{{ /hasScenarios }}
  480. {{ #hasIllusts }}<p><span>\u63D2\u753B\uFF1A</span>{{ #illusts }}<span>{{ . }} / </span>{{ /illusts }}</p>{{ /hasIllusts }}
  481. {{ #hasVoices }}<p><span>\u58F0\u4F18\uFF1A</span>{{ #voices }}<span>{{ . }} / </span>{{ /voices }}</p>{{ /hasVoices }}
  482. {{ #hasMusics }}<p><span>\u97F3\u4E50\uFF1A</span>{{ #musics }}<span>{{ . }} / </span>{{ /musics }}</p>{{ /hasMusics }}
  483. {{ #age }}<p><span>\u5E74\u9F84\u6307\u5B9A\uFF1A</span><span>{{ age }}</span></p>{{ /age }}
  484. {{ #type }}<p><span>\u4F5C\u54C1\u7C7B\u578B\uFF1A</span><span>{{ type }}</span></p>{{ /type }}
  485. {{ #hasTags }}<p><span>\u5206\u7C7B\uFF1A</span>{{ #tags }}<span>{{ . }} </span>{{ /tags }}</p>{{ /hasTags }}
  486. </div>`, currentWork, currentRj;
  487. async function show(x, y) {
  488. let popup = document.getElementById("rj-popup"), tempRj = currentRj, temp = await fetch_rj_default(tempRj);
  489. if ((currentRj === tempRj || !currentWork) && (currentWork = temp), console.debug("[rj-code-preview/work]", currentWork), !hided && currentWork) {
  490. let rendered = mustache_default.render(template, currentWork, null, {
  491. escape: (it) => it
  492. });
  493. console.debug("[rj-code-preview/rendered]", rendered), popup.innerHTML = rendered, move(x, y);
  494. let img = popup.getElementsByTagName("img").item(0);
  495. img.onload = () => setTimeout(() => move(x, y)), img.onerror = () => setTimeout(() => move(x, y));
  496. }
  497. hided = !1;
  498. }
  499. var hided = !1;
  500. function hide() {
  501. hided = !0, currentRj = void 0, currentWork = void 0, document.getElementById("rj-popup").innerHTML = "";
  502. }
  503. function move(x, y) {
  504. let popup = document.getElementById("rj-popup");
  505. if (x + popup.offsetWidth + 16 < window.innerWidth)
  506. popup.style.left = x + 8 + "px";
  507. else {
  508. let left = x - popup.offsetWidth - 8;
  509. left < 0 ? popup.style.left = "8px" : popup.style.left = left + "px";
  510. }
  511. popup.offsetHeight + y + 16 > window.innerHeight ? popup.style.top = window.innerHeight - popup.offsetHeight - 16 + "px" : popup.style.top = y + 8 + "px";
  512. }
  513. delegate_it_default(document.body, linkSelector, "mouseout", () => hide());
  514. delegate_it_default(document.body, linkSelector, "mouseover", (event) => {
  515. currentRj = event.target.dataset[RJ_CODE_ATTRIBUTE], console.debug("[rj-code-preview/rj]", currentRj), currentRj && (hided = !1, show(event.clientX, event.clientY).then());
  516. });
  517. delegate_it_default(
  518. document.body,
  519. linkSelector,
  520. "mousemove",
  521. (event) => move(event.clientX, event.clientY)
  522. );
  523. function initPopup() {
  524. let popup = document.createElement("div");
  525. popup.id = "rj-popup", document.body.append(popup);
  526. let style2 = document.createElement("style");
  527. style2.innerHTML = `
  528. #rj-popup {
  529. max-width: min(calc(100vw - 16px), 360px);
  530. max-height: calc(100vh - 32px);
  531. position: fixed;
  532. display: flex;
  533. flex-direction: column;
  534. overflow: hidden;
  535. color: #fff;
  536. background-color: #424242;
  537. border-radius: 12px;
  538. z-index: 99999;
  539. }
  540. #rj-popup > img {
  541. width: 100%;
  542. height: auto;
  543. border-radius: 0;
  544. }
  545. #rj-popup > .info {
  546. padding: 12px 16px;
  547. font-size: 0.88rem;
  548. line-height: 1.2;
  549. display: grid;
  550. grid-gap: 6px;
  551. box-sizing: border-box;
  552. }
  553. #rj-popup > .info > * {
  554. margin: 0;
  555. }
  556. #rj-popup > .info > h3 {
  557. color: inherit;
  558. font-size: 1.1rem;
  559. font-weight: bold;
  560. line-height: 1;
  561. }`, document.head.append(style2);
  562. }
  563.  
  564. // src/index.ts
  565. var observer = new MutationObserver((records) => {
  566. for (let { addedNodes } of records)
  567. for (let node of addedNodes)
  568. hack_rj_code_default(node);
  569. });
  570. observer.observe(document.body, { childList: !0, subtree: !0 });
  571. hack_rj_code_default(document.body);
  572. var style = document.createElement("style");
  573. style.innerHTML = `
  574. .${RJ_CODE_LINK_CLASS} {
  575. color: inherit;
  576. -webkit-text-stroke-width: 1px;
  577. /* \u5E7B\u60F3\u6B21\u5143\u9996\u9875\u5217\u8868\u4F1A\u8BA9\u5BBD\u5EA6\u53D8\u6210 70% */
  578. width: fit-content !important;
  579. /* \u5E7B\u60F3\u6B21\u5143\u548C\u7EC5\u58EB\u4E4B\u5EAD\u4F1A\u8BA9 a \u6807\u7B7E\u6362\u884C */
  580. display: inline-flex !important;
  581. line-height: 1;
  582. /* [[\u7EC5\u58EB\u4E4B\u5EAD]] \u9996\u9875\u6807\u9898\u7684 [[RJ \u7801]] \u4F1A\u53D8\u5F97\u5F88\u5927 */
  583. font-size: inherit !important;
  584. /* [[\u5357+]] \u7684\u5E16\u5B50\u5217\u8868\u4F1A\u7ED9 a \u6807\u7B7E\u4E00\u4E2A\u53F3\u4FA7 [[margin]] */
  585. margin: 0;
  586. align-items: center;
  587. }`;
  588. document.head.append(style);
  589. initPopup();
  590. document.addEventListener("securitypolicyviolation", (e) => {
  591. e.blockedURI.includes("img.dlsite.jp") && document.querySelector(`img[src="${e.blockedURI}"]`).remove();
  592. });
  593. /*! Bundled license information:
  594.  
  595. mustache/mustache.mjs:
  596. (*!
  597. * mustache.js - Logic-less {{mustache}} templates with JavaScript
  598. * http://github.com/janl/mustache.js
  599. *)
  600. */