🏠 Home 

Greasy Fork is available in English.

知乎修改器移动版-持续更新

知乎修改器的移动版:首页可持续加载内容,回答可以查看全部回答和评论,文章可以查看全部评论,回答内容、文章、评论可直接点赞、反对,去除禁止复制的限制,列表标题类别显示功能设置,收起按钮悬浮设置,列表、问题详情、回答、文章内容置顶创建和修改时间设置,一键获取内容链接设置,问题详情添加查看问题日志按钮,自定义样式,隐藏模块,缓存列表和浏览历史记录等功能。


Installer dette script?
  1. // ==UserScript==
  2. // @name 知乎修改器移动版-持续更新
  3. // @namespace http://tampermonkey.net/
  4. // @version 2.9.2
  5. // @description 知乎修改器的移动版:首页可持续加载内容,回答可以查看全部回答和评论,文章可以查看全部评论,回答内容、文章、评论可直接点赞、反对,去除禁止复制的限制,列表标题类别显示功能设置,收起按钮悬浮设置,列表、问题详情、回答、文章内容置顶创建和修改时间设置,一键获取内容链接设置,问题详情添加查看问题日志按钮,自定义样式,隐藏模块,缓存列表和浏览历史记录等功能。
  6. // @compatible edge Violentmonkey
  7. // @compatible edge Tampermonkey
  8. // @compatible chrome Violentmonkey
  9. // @compatible chrome Tampermonkey
  10. // @compatible firefox Violentmonkey
  11. // @compatible firefox Tampermonkey
  12. // @compatible safari Violentmonkey
  13. // @compatible safari Tampermonkey
  14. // @author liuyubing
  15. // @license MIT
  16. // @match *://*.zhihu.com/*
  17. // @grant GM_setValue
  18. // @grant GM_getValue
  19. // @grant GM.getValue
  20. // @grant GM.setValue
  21. // @grant GM_registerMenuCommand
  22. // @run-at document-start
  23. // ==/UserScript==
  24. "use strict";
  25. (() => {
  26. var dom = (n2) => document.querySelector(n2);
  27. var domById = (id) => document.getElementById(id);
  28. var domA = (n2) => document.querySelectorAll(n2);
  29. var domC = (name, attrObjs) => {
  30. const node = document.createElement(name);
  31. for (let key in attrObjs) {
  32. node[key] = attrObjs[key];
  33. }
  34. return node;
  35. };
  36. var domP = (node, attrName, attrValue) => {
  37. const nodeP = node.parentElement;
  38. if (!nodeP)
  39. return void 0;
  40. if (!attrName || !attrValue)
  41. return nodeP;
  42. if (nodeP === document.body)
  43. return void 0;
  44. const attrValueList = (nodeP.getAttribute(attrName) || "").split(" ");
  45. return attrValueList.includes(attrValue) ? nodeP : domP(nodeP, attrName, attrValue);
  46. };
  47. var insertAfter = (newElement, targetElement) => {
  48. const parent = targetElement.parentNode;
  49. if (parent.lastChild === targetElement) {
  50. parent.appendChild(newElement);
  51. } else {
  52. parent.insertBefore(newElement, targetElement.nextSibling);
  53. }
  54. };
  55. var fnReturnStr = (str, isHave = false, strFalse = "") => isHave ? str : strFalse;
  56. var fnInitDomStyle = (id, innerHTML) => {
  57. const element = domById(id);
  58. element ? element.innerHTML = innerHTML : document.head.appendChild(domC("style", { id, type: "text/css", innerHTML }));
  59. };
  60. function throttle(fn, time = 300) {
  61. let tout = void 0;
  62. return function() {
  63. if (tout)
  64. return;
  65. tout = setTimeout(() => {
  66. tout = void 0;
  67. fn.apply(this, arguments);
  68. }, time);
  69. };
  70. }
  71. var copy = async (value) => {
  72. if (navigator.clipboard && navigator.permissions) {
  73. await navigator.clipboard.writeText(value);
  74. } else {
  75. const domTextarea = domC("textArea", {
  76. value,
  77. style: "width: 0px;position: fixed;left: -999px;top: 10px;"
  78. });
  79. domTextarea.setAttribute("readonly", "readonly");
  80. document.body.appendChild(domTextarea);
  81. domTextarea.select();
  82. document.execCommand("copy");
  83. document.body.removeChild(domTextarea);
  84. }
  85. };
  86. var messageDoms = [];
  87. var message = (value, t2 = 3e3) => {
  88. const time = +/* @__PURE__ */ new Date();
  89. const classTime = `ctz-message-${time}`;
  90. const nDom = domC("div", {
  91. innerHTML: value,
  92. className: `ctz-message ${classTime}`
  93. });
  94. const domBox = domById("CTZ_MESSAGE_BOX");
  95. if (!domBox)
  96. return;
  97. domBox.appendChild(nDom);
  98. messageDoms.push(nDom);
  99. if (messageDoms.length > 3) {
  100. const prevDom = messageDoms.shift();
  101. prevDom && domBox.removeChild(prevDom);
  102. }
  103. setTimeout(() => {
  104. const nPrevDom = dom(`.${classTime}`);
  105. if (nPrevDom) {
  106. domById("CTZ_MESSAGE_BOX").removeChild(nPrevDom);
  107. messageDoms.shift();
  108. }
  109. }, t2);
  110. };
  111. var hexToRgba = (hex, opacity) => {
  112. return "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + opacity + ")";
  113. };
  114. var nodesStopPropagation = (names, fnArr = [], type = "click") => {
  115. let nodeArray = [];
  116. names.forEach((item) => {
  117. nodeArray = nodeArray.concat(Array.prototype.slice.call(domA(item)));
  118. });
  119. for (let i2 = 0, len = nodeArray.length; i2 < len; i2++) {
  120. nodeArray[i2].addEventListener(type, (event) => {
  121. event.stopPropagation();
  122. fnArr.forEach((fn) => {
  123. fn(event);
  124. });
  125. });
  126. }
  127. };
  128. var fnLog = (...str) => console.log("%c「修改器」", "color: green;font-weight: bold;", ...str);
  129. var HTML_HOOTS = ["www.zhihu.com", "zhuanlan.zhihu.com"];
  130. var ID_CTZ_COMMENT = "CTZ_COMMENT";
  131. var ID_CTZ_COMMENT_CHILD = "CTZ_COMMENT_CHILD";
  132. var ID_CTZ_COMMENT_CLOSE = "CTZ_BUTTON_COMMENT_CLOSE";
  133. var ID_CTZ_COMMENT_BACK = "CTZ_BOTTOM_COMMENT_BACK";
  134. var CLASS_INPUT_CLICK = "ctz-i";
  135. var CLASS_INPUT_CHANGE = "ctz-i-change";
  136. var CLASS_TIME_ITEM = "ctz-list-item-time";
  137. var CLASS_COPY_LINK = "ctz-copy-link";
  138. var EXTRA_CLASS_HTML = {
  139. "zhuanlan.zhihu.com": "zhuanlan",
  140. "www.zhihu.com": "zhihu"
  141. };
  142. var HEADER = [
  143. { href: "#CTZ_BASIS", value: "基础设置" },
  144. { href: "#CTZ_HIDDEN", value: "隐藏模块" },
  145. { href: "#CTZ_FILTER", value: "屏蔽内容" },
  146. // { href: '#CTZ_BLOCK_WORD', value: '屏蔽词' },
  147. // { href: '#CTZ_BLACKLIST', value: '黑名单' },
  148. { href: "#CTZ_HISTORY", value: "历史记录" }
  149. // { href: '#CTZ_DEFAULT', value: '默认功能' },
  150. ];
  151. var THEMES = [
  152. { label: "浅色", value: "0" /* 浅色 */, background: "#fff", color: "#000" },
  153. { label: "深色", value: "1" /* 深色 */, background: "#000", color: "#fff" },
  154. { label: "自动", value: "2" /* 自动 */, background: "linear-gradient(to right, #fff, #000)", color: "#000" }
  155. ];
  156. var THEME_CONFIG_LIGHT = {
  157. ["0" /* 默认 */]: { name: "默认", background: "#ffffff", background2: "" },
  158. ["1" /* 红 */]: { name: "红", background: "#ffe4c4", background2: "#fff4e7" },
  159. ["2" /* 黄 */]: { name: "黄", background: "#faf9de", background2: "#fdfdf2" },
  160. ["3" /* 绿 */]: { name: "绿", background: "#cce8cf", background2: "#e5f1e7" },
  161. ["4" /* 灰 */]: { name: "灰", background: "#eaeaef", background2: "#f3f3f5" },
  162. ["5" /* 紫 */]: { name: "紫", background: "#e9ebfe", background2: "#f2f3fb" }
  163. };
  164. var THEME_CONFIG_DARK = {
  165. ["0" /* 默认 */]: { name: "默认", color: "#fff", background: "#121212", background2: "#333333" },
  166. ["1" /* 夜间护眼一 */]: { name: "夜间护眼一", color: "#f7f9f9", background: "#15202b", background2: "#38444d" },
  167. ["2" /* 夜间护眼二 */]: { name: "夜间护眼二", color: "#f7f9f9", background: "#1f1f1f", background2: "#303030" },
  168. ["3" /* 夜间护眼三 */]: { name: "夜间护眼三", color: "#f7f9f9", background: "#272822", background2: "#383932" }
  169. };
  170. var INPUT_NAME_THEME = "theme";
  171. var INPUT_NAME_THEME_DARK = "themeDark";
  172. var INPUT_NAME_ThEME_LIGHT = "themeLight";
  173. var VoteTypeOb = {
  174. [0 /* 赞同 */]: {
  175. ["answers" /* 回答 */]: '{"type":"up"}',
  176. ["articles" /* 文章 */]: '{"voting":1}',
  177. ["zvideos" /* 视频 */]: '{"voting":1}'
  178. },
  179. [1 /* 中立 */]: {
  180. ["answers" /* 回答 */]: '{"type":"neutral"}',
  181. ["articles" /* 文章 */]: '{"voting":0}',
  182. ["zvideos" /* 视频 */]: '{"voting":0}'
  183. },
  184. [2 /* 反对 */]: {
  185. ["answers" /* 回答 */]: '{"type":"down"}',
  186. ["articles" /* 文章 */]: '{"voting":-1}',
  187. ["zvideos" /* 视频 */]: '{"voting":-1}'
  188. }
  189. };
  190. var NAME_CONFIG = "mobileConfig";
  191. var NAME_HISTORY = "mobileHistory";
  192. var HISTORY_DEFAULT = {
  193. view: [],
  194. list: []
  195. };
  196. var CONFIG_HIDDEN_DEFAULT = {
  197. hiddenOpenApp: true,
  198. hiddenReadMoreText: true,
  199. hiddenReward: true,
  200. hiddenAD: true,
  201. hiddenBottomSticky: true
  202. };
  203. var CONFIG_FILTER_DEFAULT = {
  204. removeZhihuOfficial: true,
  205. removeAnonymousAnswer: false,
  206. removeFromYanxuan: true,
  207. removeUnrealAnswer: true,
  208. removeFromEBook: true,
  209. removeStoryAnswer: true,
  210. removeYanxuanAnswer: true,
  211. removeYanxuanRecommend: true,
  212. removeYanxuanCPRecommend: true,
  213. hiddenAnswerYanxuanRecommend: true
  214. };
  215. var CONFIG_DEFAULT = {
  216. ...CONFIG_HIDDEN_DEFAULT,
  217. ...CONFIG_FILTER_DEFAULT,
  218. openButtonTop: 100,
  219. openButtonLeft: 0,
  220. questionTitleTag: true,
  221. releaseTimeForList: true,
  222. releaseTimeForAnswer: true,
  223. releaseTimeForQuestion: true,
  224. releaseTimeForArticle: true,
  225. theme: "2" /* 自动 */,
  226. themeLight: "0" /* 默认 */,
  227. themeDark: "1" /* 夜间护眼一 */,
  228. copyAnswerLink: true,
  229. showQuestionLog: true,
  230. showAllContent: true,
  231. showToAnswer: true,
  232. showIP: true,
  233. haveTopSearch: true
  234. };
  235. var SAVE_HISTORY_NUMBER = 500;
  236. var HIDDEN_ANSWER_TAG = {
  237. removeFromYanxuan: "盐选专栏",
  238. // removeUnrealAnswer: '虚构创作',
  239. removeFromEBook: "电子书"
  240. };
  241. var HIDDEN_ANSWER_ACCOUNT = {
  242. removeStoryAnswer: "故事档案局",
  243. removeYanxuanAnswer: "盐选科普",
  244. removeYanxuanRecommend: "盐选推荐",
  245. removeYanxuanCPRecommend: "盐选测评室"
  246. };
  247. var HIDDEN_ARRAY = [
  248. [{ value: "hiddenAD", label: "广告" }],
  249. [
  250. { value: "hiddenOpenApp", label: "隐藏跳转APP的提示和按钮" },
  251. { value: "hiddenReward", label: "隐藏赞赏按钮" }
  252. ],
  253. [
  254. { value: "hiddenLogo", label: "隐藏LOGO" },
  255. { value: "hiddenHeader", label: "隐藏顶部悬浮模块" },
  256. { value: "hiddenBottomSticky", label: "隐藏进入回答页面时的底部操作栏" },
  257. { value: "hiddenCommitImg", label: "隐藏评论区图片" }
  258. ],
  259. [
  260. { value: "hiddenAnswers", label: "隐藏列表回答内容" },
  261. { value: "hiddenListVideoContent", label: "隐藏列表视频回答的内容" },
  262. { value: "hiddenListImg", label: "隐藏列表图片" }
  263. // { value: 'hiddenReadMoreText', label: '隐藏列表「阅读全文」文字' },
  264. ],
  265. [
  266. { value: "hiddenItemActions", label: "隐藏列表回答操作栏" },
  267. { value: "hiddenAnswerItemActions", label: "隐藏详情回答操作栏" }
  268. ],
  269. [
  270. { value: "hiddenQuestionFollowing", label: "隐藏关注问题按钮" },
  271. { value: "hiddenQuestionAnswer", label: "隐藏问题写回答按钮" }
  272. ],
  273. [
  274. { value: "hiddenAnswerItemTime", label: "隐藏回答底部发布编辑时间和IP" },
  275. { value: "hiddenAnswerItemTimeButHaveIP", label: "隐藏回答底部发布编辑时间(保留IP)" }
  276. ],
  277. [
  278. { value: "hiddenDetailAvatar", label: "隐藏回答人头像" },
  279. { value: "hiddenDetailName", label: "隐藏回答人姓名" },
  280. { value: "hiddenDetailBadge", label: "隐藏回答人简介" },
  281. { value: "hiddenDetailVoters", label: "隐藏回答人下赞同数" },
  282. { value: "hiddenWhoVoters", label: "隐藏回答人下 你赞同过、XXX赞同了 等信息" }
  283. ],
  284. [
  285. { value: "hiddenZhuanlanAvatarWrapper", label: "隐藏文章作者头像" },
  286. { value: "hiddenZhuanlanAuthorInfoHead", label: "隐藏文章作者姓名" },
  287. { value: "hiddenZhuanlanAuthorInfoDetail", label: "隐藏文章作者简介" },
  288. { value: "hiddenZhuanlanFollowButton", label: "隐藏文章作者关注按钮" },
  289. { value: "hiddenZhuanlanTitleImage", label: "隐藏文章标题图片" },
  290. { value: "hiddenZhuanlanImage", label: "隐藏文章内容图片" },
  291. { value: "hiddenZhuanlanActions", label: "隐藏文章底部悬浮操作栏" }
  292. ],
  293. [
  294. { value: "hiddenAnswerYanxuanRecommend", label: "隐藏回答页盐选推荐" },
  295. { value: "hiddenAnswerRelatedRecommend", label: "隐藏回答页相关推荐" },
  296. { value: "hiddenAnswerHotRecommend", label: "隐藏回答页热门推荐" }
  297. ]
  298. ];
  299. var BASIC_SHOW_CONTENT = [
  300. { label: "隐藏修改器唤起按钮,可在脚本菜单<b>⚙️ 设置</b>打开", value: "openButtonInvisible" },
  301. { label: "页面顶部显示搜索框", value: "haveTopSearch" },
  302. { label: "<b>回答、文章</b>显示完整内容和评论", value: "showAllContent" },
  303. {
  304. label: `<b>列表</b>标题类别显示<span class="ctz-label-tag ctz-label-tag-Answer">问答</span><span class="ctz-label-tag ctz-label-tag-Article">文章</span><span class="ctz-label-tag ctz-label-tag-ZVideo">视频</span><span class="ctz-label-tag ctz-label-tag-Pin">想法</span>`,
  305. value: "questionTitleTag",
  306. needFetch: false
  307. },
  308. // { label: '<b>收起</b>按钮悬浮', value: 'suspensionPickup' },
  309. { label: "<b>列表</b>内容置顶创建和修改时间", value: "releaseTimeForList" },
  310. { label: "<b>问题详情</b>置顶创建和修改时间", value: "releaseTimeForQuestion" },
  311. { label: "<b>问题详情回答</b>置顶创建和修改时间", value: "releaseTimeForAnswer" },
  312. { label: "<b>文章</b>置顶创建时间", value: "releaseTimeForArticle" },
  313. { label: "一键获取内容链接", value: "copyAnswerLink" },
  314. { label: "<b>列表</b>显示直达问题按钮", value: "showToAnswer" },
  315. { label: "<b>问题详情</b>显示<b>查看问题日志</b>按钮", value: "showQuestionLog" },
  316. { label: "<b>评论</b>顺序、关闭操作栏置于底部", value: "commentHeaderToBottom" },
  317. { label: "显示用户IP(存在历史回答IP缺失的情况)", value: "showIP" }
  318. ];
  319. var myStorage = {
  320. set: async function(name, value) {
  321. value.t = +/* @__PURE__ */ new Date();
  322. const v = JSON.stringify(value);
  323. localStorage.setItem(name, v);
  324. await GM.setValue(name, v);
  325. },
  326. get: async function(name) {
  327. const config = await GM.getValue(name);
  328. const configLocal = localStorage.getItem(name);
  329. const cParse = config ? JSON.parse(config) : null;
  330. const cLParse = configLocal ? JSON.parse(configLocal) : null;
  331. if (!cParse && !cLParse)
  332. return "";
  333. if (!cParse)
  334. return configLocal;
  335. if (!cLParse)
  336. return config;
  337. if (cParse.t < cLParse.t)
  338. return configLocal;
  339. return config;
  340. },
  341. getConfig: async function() {
  342. const nConfig = await this.get(NAME_CONFIG);
  343. const c2 = nConfig ? JSON.parse(nConfig) : {};
  344. const configSave = { ...CONFIG_DEFAULT, ...c2 };
  345. return Promise.resolve(configSave);
  346. },
  347. getHistory: async function() {
  348. const nHistory = await myStorage.get(NAME_HISTORY);
  349. const h2 = nHistory ? JSON.parse(nHistory) : HISTORY_DEFAULT;
  350. return Promise.resolve(h2);
  351. },
  352. /** 修改配置中的值 */
  353. updateConfig: async function(key, value) {
  354. const config = await this.getConfig();
  355. if (typeof key === "string") {
  356. config[key] = value;
  357. } else {
  358. for (let itemKey in key) {
  359. config[itemKey] = key[itemKey];
  360. }
  361. }
  362. await this.set(NAME_CONFIG, config);
  363. },
  364. /** 更新配置 */
  365. setConfig: async function(params) {
  366. await this.set(NAME_CONFIG, params);
  367. },
  368. setHistoryItem: async function(key, params) {
  369. const pfHistory = await this.getHistory();
  370. pfHistory[key] = params.slice(0, SAVE_HISTORY_NUMBER);
  371. await this.set(NAME_HISTORY, pfHistory);
  372. },
  373. setHistory: async function(value) {
  374. this.set(NAME_HISTORY, value);
  375. }
  376. };
  377. var myBackground = {
  378. init: async function() {
  379. const { themeDark = "1" /* 夜间护眼一 */, themeLight = "0" /* 默认 */ } = await myStorage.getConfig();
  380. const innerHTML = await this.change(themeDark, themeLight);
  381. fnInitDomStyle("CTZ_STYLE_BACKGROUND", innerHTML);
  382. },
  383. change: async function(themeDark, themeLight) {
  384. const getBackground = async () => {
  385. const isD = await this.isUseDark();
  386. if (isD)
  387. return this.dark(themeDark);
  388. if (themeLight === "0" /* 默认 */)
  389. return this.default();
  390. return this.light(themeLight);
  391. };
  392. const strBg = await getBackground();
  393. const strText = await this.text();
  394. return strBg + strText;
  395. },
  396. isUseDark: async () => {
  397. const { theme = "2" /* 自动 */ } = await myStorage.getConfig();
  398. if (theme === "2" /* 自动 */) {
  399. const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");
  400. return prefersDarkScheme.matches;
  401. }
  402. return theme === "1" /* 深色 */;
  403. },
  404. default: () => ".GlobalSideBar-navList{background: #fff}",
  405. dark: function(darkKey) {
  406. const { background, background2, color } = THEME_CONFIG_DARK[darkKey];
  407. const whiteText = `#CTZ_DIALOG,.ctz-message,#CTZ_MAIN input,#CTZ_MAIN textarea,.ctz-footer,#CTZ_CLOSE_DIALOG,.ctz-commit,#CTZ_OPEN_BUTTON,.KfeCollection-VipRecommendCard-content,.KfeCollection-VipRecommendCard-title,#CTZ_DIALOG textarea,#CTZ_DIALOG .ctz-button,.ctz-button.ctz-button-transparent,body,.zu-top-nav-link,.CommentContent,[data-za-detail-view-path-module="CommentList"] div,.CommentsForOia div,.ctz-suspension-pickup,.zm-ac-link,.css-10noe4n,.css-3ny988,.css-hmd01z,.css-z0cc58,.css-7aa3bk,.css-1965tpd,.css-b574el,.css-1jg6wq6,textarea.zg-form-text-input,.zg-form-text-input>textarea,.css-1eglonx,.css-1tip2bd,.css-1symrae,.css-u3vsx3>div,.zm-editable-editor-field-wrap,.zu-question-suggest-topic-input,.zg-form-text-input,.zg-form-select,.css-10u695f,.css-r4op92{color: ${color}!important}`;
  408. const linkText = `.RelevantQuery li,.modal-dialog a,.zhi a,.VoteButton,.ContentItem-more,.QuestionMainAction,a.UserLink-link,.RichContent--unescapable.is-collapsed .ContentItem-rightButton,.ContentItem-title a:hover,.css-b7erz1,.css-1vbwaf6,.css-1jj6qre,.css-jf1cpf,.css-vphnkw,.css-1icigob{color: deepskyblue!important;}`;
  409. const addPrefix = (i2) => {
  410. return i2.split(",").map((i3) => `html[data-theme=dark] ${i3}`).join(",");
  411. };
  412. const darkTransparentBg = `.ColumnHomeTop:before,.ColumnHomeBottom{background: transparent!important;}`;
  413. return addPrefix(this.doSetCSS(background, background2) + whiteText + linkText + darkTransparentBg) + this.doSetCSSInCTZ(background, background2) + `.MobileAppHeader-expandBackdrop{background: ${hexToRgba(background, 0.65)}!important;}`;
  414. },
  415. light: function(lightKey) {
  416. const { background, background2 } = THEME_CONFIG_LIGHT[lightKey];
  417. return this.doSetCSS(background, background2) + this.doSetCSSInCTZ(background, background2);
  418. },
  419. /** 设置字体颜色 */
  420. text: async function() {
  421. const { colorText1 } = await myStorage.getConfig();
  422. const styleColorText1 = `.ContentItem-title, body{color: ${colorText1}!important;}`;
  423. return colorText1 ? styleColorText1 : "";
  424. },
  425. /** 知乎内元素样式设置 */
  426. doSetCSS: function(background, background2) {
  427. const cssBg = `${this.cssNamesBackground1}{background-color: ${background}!important;background:${background}!important;}`;
  428. const cssBg2 = `${this.cssNamesBackground2}{background-color:${background2}!important;background:${background2}!important;}`;
  429. const cssJustBGC2 = `${this.useCSSJustBGC2}{background-color: ${background2}!important;}`;
  430. const cssBgTransparent = `${this.cssNamesBackgroundTransparent}{background-color: transparent!important;background: transparent!important;}`;
  431. const loadingStyle = `.css-w2vj5n{background: ${background}!important;color: ${background2}!important;}`;
  432. const borderBg = `.KfeCollection-VipRecommendCard-article{border-color: ${background}!important;}`;
  433. return cssBg + cssBg2 + cssBgTransparent + loadingStyle + borderBg + cssJustBGC2;
  434. },
  435. /** 修改器样式设置(不需要添加前缀) */
  436. doSetCSSInCTZ: function(background, background2) {
  437. const menuTopBeforeAfter = `.ctz-menu>a.target::after,.ctz-menu>a.target::before{${this.menuBeforeAfter(background2)}}`;
  438. const openButton = `#CTZ_OPEN_BUTTON{background: ${background}!important;}`;
  439. return menuTopBeforeAfter + openButton;
  440. },
  441. /** 使用背景色1的元素名称 */
  442. cssNamesBackground1: `#CTZ_DIALOG,#CTZ_BASIS_SHOW label b,.ctz-suspension-pickup,.ctz-content-top a.target,.ctz-message,#CTZ_DIALOG textarea,#CTZ_DIALOG .ctz-button,body,.App,.MobileAppHeader-searchBox,.Input-wrapper,.VideoAnswerPlayer-stateBar,.ColumnHomeColumnCard,.Toast-root-tU3yo,.AuthorsSection-author-tFZJF,.editable,textarea.zg-form-text-input,.zg-form-text-input>textarea,.ac-active,.PagingButton,[data-tooltip="回到顶部"],.css-d1dtt9,.css-k8i00s,.css-41c1px,.zm-editable-editor-field-wrap,.zu-question-suggest-topic-input,.zg-form-text-input,.zg-form-select,.css-4lspwd,.zu-top`,
  443. /** 使用背景色2的元素名称 */
  444. cssNamesBackground2: `.ctz-content,.ctz-menu>a.target,.Card,.Sticky,.ContentItem-more,.ContentItem-actions,.Popover-content,.Popover-arrow:after,.MobileAppHeader-expand,.CommentsForOia>div,.KfeCollection-VipRecommendCard,.OpenInAppButton>div,.Modal-inner,.MobileSearch-container,.ProfileBar,.MobileAppHeader,.ZVideo-mobile,.Post-content,.sgui-header,.MobileCollectionsHeader-tabs,.MobileModal-title--default,.MobileModal,.List-item,.Login,.Input-wrapper.SignFlow-accountInput,.SignFlowInput .Input-wrapper,.SearchTabs,.MobileEmptyPageWithType,.TopicHot-Header,.Favlists-mobileActions,[data-za-detail-view-path-module="SearchR###ltList"]>div,[data-za-detail-view-path-module="SearchR###ltList"]>div>a,.SearchSubTabs,.KfeCollection-PcCollegeCard-root,.modal-dialog,.ac-renderer,.css-hplpcn,.zh-add-question-form .add-question-splash-page .ac-renderer .ac-row.ac-last,.HeaderInfo-infoCard-orDxs,.Common-content-893LU,.ContentModule-module-9gTaH,.NewBottomBar-root-dVXzD,.AuthorModule-root-rxFMb,.css-w0m1iq,.zu-autocomplete-row-label,.ac-row.zu-autocomplete-row-search-link,.PostItem,.Recommendations-Main,.ErrorPage,.css-1e7fksk,.css-1gfesro,.css-ud510h,.css-vb0amv,.css-t89z5u,.css-u3vsx3>div,.css-5k4zcx,.css-13heq6w,.css-13heq6w>a,.css-1eltcns,.css-yoby3j,.css-l63y2t,.css-173civf,.css-1nalx0p,.css-mn9570,.css-4r7szo,.css-vkey2q,.css-ugzr12,.css-6v1k3,.css-1xj1964,.css-ggid2,.css-rhbxt0,.css-1j23ebo,.css-7wvdjh,.css-kt4t4n,#CTZ_COMMENT,#CTZ_COMMENT_CHILD, #CTZ_TOP_SEARCH,.mobile-top-nav-popup .top-nav-dropdown,.zm-item-tag,.mobile-top-nav-popup .top-nav-dropdown a,.Topbar,.AutoInviteItem-wrapper--mobile`,
  445. useCSSJustBGC2: `.slide-up`,
  446. /** 背景色透明的元素名称 */
  447. cssNamesBackgroundTransparent: `.ContentItem-more:before`,
  448. cssNamesColorUserBackground1: ``,
  449. menuBeforeAfter: (color, size = "12px") => {
  450. return `background: radial-gradient(circle at top left, transparent ${size}, ${color} 0) top left,
  451. radial-gradient(circle at top right, transparent ${size}, ${color} 0) top right,
  452. radial-gradient(circle at bottom right, transparent ${size}, ${color} 0) bottom right,
  453. radial-gradient(circle at bottom left, transparent ${size}, ${color} 0) bottom left;
  454. background-size: 50% 50%;
  455. background-repeat: no-repeat;`;
  456. }
  457. };
  458. var myCustomStyle = {
  459. init: async function() {
  460. const nodeCustomStyle = dom('[name="textStyleCustom"]');
  461. if (!nodeCustomStyle)
  462. return;
  463. const { customizeCss = "" } = await myStorage.getConfig();
  464. nodeCustomStyle.value = customizeCss;
  465. this.change(customizeCss);
  466. },
  467. change: (innerCus) => fnInitDomStyle("CTZ_STYLE_CUSTOM", innerCus)
  468. };
  469. var onUseThemeDark = async () => {
  470. const isD = await isDark();
  471. dom("html").setAttribute("data-theme", isD ? "dark" : "light");
  472. };
  473. var loadFindTheme = () => {
  474. onUseThemeDark();
  475. const elementHTML = dom("html");
  476. const muConfig = { attribute: true, attributeFilter: ["data-theme"] };
  477. if (!elementHTML)
  478. return;
  479. const muCallback = async function() {
  480. const themeName = elementHTML.getAttribute("data-theme");
  481. const isD = await isDark();
  482. if (themeName === "dark" && !isD || themeName === "light" && isD) {
  483. onUseThemeDark();
  484. }
  485. };
  486. const muObserver = new MutationObserver(muCallback);
  487. muObserver.observe(elementHTML, muConfig);
  488. };
  489. var loadBackground = () => myBackground.init();
  490. var isDark = async () => await myBackground.isUseDark();
  491. var createItem = ({ label, value, background, color, inputName }) => `<label><input class="${CLASS_INPUT_CLICK}" name="${inputName}" type="radio" value="${value}"/><div style="background: ${background};color: ${color}">${label}</div></label>`;
  492. var createThemeHTML = (themeConfig, inputName) => {
  493. return Object.keys(themeConfig).map((key) => {
  494. const { background, color, name } = themeConfig[key];
  495. return createItem({ label: name, value: key, background, color, inputName });
  496. }).join("");
  497. };
  498. var addBackgroundElement = () => {
  499. domById("CTZ_BACKGROUND").innerHTML = THEMES.map((item) => createItem({ ...item, inputName: INPUT_NAME_THEME })).join("");
  500. domById("CTZ_BACKGROUND_LIGHT").innerHTML = createThemeHTML(THEME_CONFIG_LIGHT, INPUT_NAME_ThEME_LIGHT);
  501. domById("CTZ_BACKGROUND_DARK").innerHTML = createThemeHTML(THEME_CONFIG_DARK, INPUT_NAME_THEME_DARK);
  502. };
  503. var myMenu = {
  504. init: function() {
  505. const { hash } = location;
  506. const nodeMenuTop = dom(".ctz-menu");
  507. if (!nodeMenuTop)
  508. return;
  509. const chooseId = [...nodeMenuTop.children].map((i2) => i2.hash).find((i2) => i2 === hash || hash.replace(i2, "") !== hash);
  510. this.click({ target: dom(`a[href="${chooseId || HEADER[0].href}"]`) });
  511. },
  512. /** 选择菜单 */
  513. click: function({ target }) {
  514. const targetForA = target.tagName === "A" ? target : target.parentElement;
  515. if (!(targetForA.hash && targetForA.tagName === "A"))
  516. return;
  517. const chooseId = targetForA.hash.replace(/#/, "");
  518. if (!chooseId)
  519. return;
  520. const nodesA = domA(".ctz-menu>a");
  521. for (let i2 = 0, len = nodesA.length; i2 < len; i2++) {
  522. nodesA[i2].classList.remove("target");
  523. }
  524. targetForA.classList.add("target");
  525. const nodesDiv = domA(".ctz-content>div");
  526. for (let i2 = 0, len = nodesDiv.length; i2 < len; i2++) {
  527. const item = nodesDiv[i2];
  528. item.style.display = chooseId === item.id ? "flex" : "none";
  529. }
  530. myMenu2.init(chooseId);
  531. }
  532. };
  533. var myMenu2 = {
  534. init: function(chooseId) {
  535. const domContentTop = dom(`#${chooseId} .ctz-content-top`);
  536. if (!domContentTop || !domContentTop.children || !domContentTop.children.length)
  537. return;
  538. const { hash } = location;
  539. const target = [...domContentTop.children].find((i2) => i2.hash === hash);
  540. this.click({ target: target || domContentTop.children[0] });
  541. },
  542. click: function({ target }) {
  543. const chooseId = target.hash.replace(/#/, "");
  544. if (!chooseId)
  545. return;
  546. const nodesA = target.parentElement.children;
  547. for (let i2 = 0, len = nodesA.length; i2 < len; i2++) {
  548. nodesA[i2].classList.remove("target");
  549. }
  550. target.classList.add("target");
  551. const nodesDiv = target.parentElement.parentElement.querySelectorAll(".ctz-content-center>div");
  552. for (let i2 = 0, len = nodesDiv.length; i2 < len; i2++) {
  553. const item = nodesDiv[i2];
  554. item.style.display = chooseId === item.id ? "block" : "none";
  555. }
  556. }
  557. };
  558. var positionOne = (position, max) => {
  559. if (position < 0)
  560. return 0;
  561. if (position > max)
  562. return max;
  563. return position;
  564. };
  565. var openButtonPosition = async () => {
  566. const { openButtonTop, openButtonLeft } = await myStorage.getConfig();
  567. const domFind = domById("CTZ_OPEN_BUTTON");
  568. if (!domFind)
  569. return;
  570. const maxLeft = window.innerWidth - domFind.offsetWidth;
  571. const maxTop = window.innerHeight - domFind.offsetHeight;
  572. const innerLeft = positionOne(openButtonLeft, maxLeft);
  573. const innerTop = positionOne(openButtonTop, maxTop);
  574. domFind.style.cssText += `top: ${innerTop}px; left: ${innerLeft}px;`;
  575. let startX = 0;
  576. let startY = 0;
  577. let x2 = 0;
  578. let y = 0;
  579. domFind.addEventListener("touchstart", function(e2) {
  580. startX = e2.targetTouches[0].pageX;
  581. startY = e2.targetTouches[0].pageY;
  582. x2 = this.offsetLeft;
  583. y = this.offsetTop;
  584. this.style.transition = "";
  585. });
  586. domFind.addEventListener("touchmove", function(e2) {
  587. let moveX = e2.targetTouches[0].pageX - startX;
  588. let moveY = e2.targetTouches[0].pageY - startY;
  589. const left = x2 + moveX;
  590. const top = y + moveY;
  591. this.style.left = positionOne(left, maxLeft) + "px";
  592. this.style.top = positionOne(top, maxTop) + "px";
  593. e2.preventDefault();
  594. });
  595. domFind.addEventListener("touchend", async function() {
  596. const left = this.offsetLeft > maxLeft / 2 ? maxLeft : 0;
  597. this.style.left = `${left}px`;
  598. this.style.transition = "all 0.5s";
  599. const top = this.offsetTop;
  600. await myStorage.updateConfig({
  601. openButtonTop: top,
  602. openButtonLeft: left
  603. });
  604. });
  605. };
  606. var ID_TOP_SEARCH_BUTTON = "CTZ_TOP_SEARCH_BUTTON";
  607. var ID_TOP_SEARCH_INPUT = "CTZ_TOP_SEARCH_INPUT";
  608. var ID_TOP_SEARCH = "CTZ_TOP_SEARCH";
  609. var fnHaveTopSearch = async () => {
  610. if (location.pathname === "/search")
  611. return;
  612. const { haveTopSearch } = await myStorage.getConfig();
  613. const domFind = domById(ID_TOP_SEARCH);
  614. if (haveTopSearch) {
  615. if (domFind)
  616. return;
  617. const domSearch = domC("div", {
  618. id: ID_TOP_SEARCH,
  619. innerHTML: `<input type="text" placeholder="搜索内容" id="${ID_TOP_SEARCH_INPUT}" /><button id="${ID_TOP_SEARCH_BUTTON}">搜索</button>`
  620. });
  621. const domRoot = domById("root");
  622. if (domRoot) {
  623. document.body.insertBefore(domSearch, domRoot);
  624. domById(ID_TOP_SEARCH_BUTTON).onclick = function() {
  625. const inputValue = domById(ID_TOP_SEARCH_INPUT).value.trim();
  626. if (inputValue) {
  627. window.open(`https://www.zhihu.com/search?q=${encodeURIComponent(inputValue)}&type=content`);
  628. }
  629. };
  630. return;
  631. }
  632. setTimeout(() => {
  633. fnHaveTopSearch();
  634. }, 500);
  635. } else {
  636. domFind && domFind.remove();
  637. return;
  638. }
  639. };
  640. var INNER_HTML = `<div id="CTZ_DIALOG" style="display: none"><div class="ctz-header"><span class="ctz-version"></span><div class="ctz-top-operate"><!-- <span id="CTZ_FETCH_STATUS">状态获取中...</span><button class="ctz-button" id="CTZ_CHANGE_FETCH" size="small">切换接口拦截</button> --></div><button id="CTZ_CLOSE_DIALOG">✕</button></div><div class="ctz-menu"></div><div class="ctz-content"><div id="CTZ_BASIS" style="display: none"><div class="ctz-content-top"><a href="#CTZ_BASIS_SHOW">显示</a><a href="#CTZ_BASIS_BACKGROUND">颜色</a><a href="#CTZ_BASIS_SETTING">配置</a></div><div class="ctz-content-center"><div id="CTZ_BASIS_SHOW" style="display: none"></div><div id="CTZ_BASIS_BACKGROUND" style="display: none"><div class="ctz-set-background"><div class="fwb mt8 ctz-background-title">外观</div><div id="CTZ_BACKGROUND" class="ctz-background-content"></div><div class="fwb mt8 ctz-background-title">浅色设置</div><div id="CTZ_BACKGROUND_LIGHT" class="ctz-background-content"></div><div class="fwb mt8 ctz-background-title">深色设置</div><div id="CTZ_BACKGROUND_DARK" class="ctz-background-content"></div></div></div><div id="CTZ_BASIS_SETTING" style="display: none"><button class="ctz-button" name="configExport" style="margin-right: 8px">获取当前配置</button><button class="ctz-button" name="configReset">恢复默认配置</button><div class="ctz-hidden-item-br"></div><div class="ctz-config-import-box"><div>配置导入</div><textarea name="textConfigImport" placeholder="配置参考获取的格式"></textarea><button class="ctz-button" name="configImport">确 定</button></div><div class="ctz-hidden-item-br"></div><div class="ctz-config-import-box"><div>自定义样式</div><textarea name="textStyleCustom" placeholder="示例: body{background: #ffffff;}"></textarea><div class="ctz-btn-box"><button class="ctz-button" name="styleCustom" style="margin-right: 12px">确 定</button><button class="ctz-button" name="styleCustomReset">清 空</button></div></div></div></div></div><div id="CTZ_HIDDEN" style="display: none"><div class="ctz-content-center"></div></div><div id="CTZ_FILTER" style="display: none"><!-- <div class="ctz-content-top"></div> --><div class="ctz-content-center"><div class="ctz-filter-defail-who"><div class="ctz-label">屏蔽以下官方账号的回答</div><div class="ctz-one"><label><input class="ctz-i" name="removeZhihuOfficial" type="checkbox" value="on" />所有知乎官方账号</label></div><div class="ctz-flex-wrap ctz-one"><label><input class="ctz-i" name="removeStoryAnswer" type="checkbox" value="on" />故事档案局</label><label><input class="ctz-i" name="removeYanxuanAnswer" type="checkbox" value="on" />盐选科普</label><label><input class="ctz-i" name="removeYanxuanRecommend" type="checkbox" value="on" />盐选推荐</label><label><input class="ctz-i" name="removeYanxuanCPRecommend" type="checkbox" value="on" />盐选测评室</label></div></div><div class="ctz-flex-wrap ctz-one"><label><span class="ctz-label">屏蔽「匿名用户」回答</span><input class="ctz-i" name="removeAnonymousAnswer" type="checkbox" value="on" /></label></div><div class="ctz-filter-defail-tag ctz-one"><div class="ctz-label">屏蔽带有以下标签的回答</div><div class="ctz-flex-wrap"><label><input class="ctz-i" name="removeFromYanxuan" type="checkbox" value="on" />选自盐选专栏</label><label><input class="ctz-i" name="removeUnrealAnswer" type="checkbox" value="on" />带有虚构创作</label><label><input class="ctz-i" name="removeFromEBook" type="checkbox" value="on" />选自电子书</label></div></div><label class="ctz-one" style="display: flex; align-items: center"><span class="ctz-label">列表屏蔽视频<span class="ctz-label-tag ctz-label-tag-ZVideo">视频</span></span><input class="ctz-i" name="removeItemAboutVideo" type="checkbox" value="on" /></label><label class="ctz-one" style="display: flex; align-items: center"><span class="ctz-label">列表屏蔽文章<span class="ctz-label-tag ctz-label-tag-Article">文章</span></span><input class="ctz-i" name="removeItemAboutArticle" type="checkbox" value="on" /></label></div></div><div id="CTZ_BLACKLIST" style="display: none"><div class="ctz-content-top"></div><div class="ctz-content-center">CTZ_BLACKLIST</div></div><div id="CTZ_HISTORY" style="display: none"><div class="ctz-content-top"><a href="#CTZ_HISTORY_LIST">推荐列表缓存</a><a href="#CTZ_HISTORY_VIEW">浏览历史记录</a></div><div class="ctz-content-center"><div id="CTZ_HISTORY_LIST" style="display: none"><button class="ctz-button" name="buttonHistoryClear" data-id="list">清空列表缓存</button><div class="ctz-set-content"></div><div class="ctz-commit ta-c mt8">--- 最多缓存500条,包含已过滤项 ---</div></div><div id="CTZ_HISTORY_VIEW" style="display: none"><button class="ctz-button" name="buttonHistoryClear" data-id="view">清空历史记录</button><div class="ctz-set-content"></div><div class="ctz-commit ta-c mt8">--- 最多缓存500条 ---</div></div></div></div></div><div class="ctz-footer"><a href="https://github.com/liuyubing233/zhihu-custom-mobile" target="_blank">Github⭐</a><ahref="https://greasyfork.org/zh-CN/scripts/488508-%E7%9F%A5%E4%B9%8E%E4%BF%AE%E6%94%B9%E5%99%A8%E7%A7%BB%E5%8A%A8%E7%89%88-%E6%8C%81%E7%BB%AD%E6%9B%B4%E6%96%B0"target="_blank">GreasyFork</a></div></div><div id="CTZ_OPEN_BUTTON">⚙︎</div><div id="CTZ_MESSAGE_BOX"></div><div id="CTZ_LOADING_TOAST" style="display: none"><div class="ctz-loading-toast-icon"><span>↻</span></div><div class="ctz-loading-toast-text">加载中...</div></div><div id="CTZ_COMMENT" style="display: none"><div class="ctz-comment-header"><div class="ctz-comment-header-left"><div class="ctz-comment-count"><span>0</span>条评论</div><div class="ctz-comment-sort"><button name="score">默认</button><button name="ts">最新</button></div></div><button class="ctz-comment-btn" id="CTZ_BUTTON_COMMENT_CLOSE">✕</button></div><div class="ctz-comment-content"><div class="ctz-comment-list"></div></div></div><div id="CTZ_COMMENT_CHILD" style="display: none"><div class="ctz-comment-header"><button class="ctz-comment-btn" id="CTZ_BOTTOM_COMMENT_BACK">◀︎ 评论回复</button></div><div class="ctz-comment-content"><div class="ctz-comment-list"></div></div></div><div style="display: none" class="ctz-preview" id="CTZ_PREVIEW_IMAGE"><div><img src="" /></div></div>`;
  641. var INNER_CSS = `@keyframes rotate{from{transform:translate(-50%, -50%) rotate(0deg)}to{transform:translate(-50%, -50%) rotate(360deg)}}.hover-style{cursor:pointer}.hover-style:hover{color:#1677ff !important}.ctz-btn-box{display:flex}.ctz-btn-box button{flex:1;margin-right:12px}.ctz-btn-box button:last-child{margin:0}.ctz-one{margin:4px 0;border-bottom:1px solid #ebebeb;padding-bottom:4px}.ctz-desc,.ctz-commit{font-size:14px;color:#999}.ctz-desc b,.ctz-commit b{color:#e55353}.ctz-desc{padding-left:4px}.dis-if-c{display:inline-flex;align-items:center}.ta-c{text-align:center}.fwb{font-weight:bold}.mt8{margin-top:8px}.bg-ec7259{background:#ec7259}.bg-12c2e9{background:#12c2e9}.bg-00965e{background:#00965e}.bg-9c27b0{background:#9c27b0}.c-ec7259{color:#ec7259}.c-12c2e9{color:#12c2e9}.c-00965e{color:#00965e}.c-9c27b0{color:#9c27b0}.ctz-button{box-sizing:border-box;outline:none;position:relative;display:inline-block;font-weight:400;white-space:nowrap;text-align:center;border:1px solid transparent;cursor:pointer;transition:all .3s;user-select:none;touch-action:manipulation;font-size:14px;padding:4px 15px;border-radius:4px;background-color:#ffffff;border-color:#d9d9d9;color:rgba(0,0,0,0.88);box-shadow:0 2px 0 rgba(0,0,0,0.02)}.ctz-button:hover{color:#1677ff;border-color:#1677ff}.ctz-button:active{background:rgba(0,0,0,0.08) !important}.ctz-button[size='small'],.ctz-button.ctz-button-small{padding:2px 6px;font-size:12px;height:24px}.ctz-button.ctz-button-transparent{background:transparent}.ctz-button-red{color:#e55353 !important;border:1px solid #e55353 !important}.ctz-button-red:hover{color:#ec7259 !important;border:1px solid #ec7259 !important}.ctz-button:disabled{border-color:#d0d0d0;background-color:rgba(0,0,0,0.08);color:#b0b0b0;cursor:not-allowed}[name='buttonHistoryClear']{margin-bottom:12px}#CTZ_BACKGROUND,#CTZ_BACKGROUND_LIGHT,#CTZ_BACKGROUND_DARK{display:grid;gap:8px}#CTZ_BACKGROUND>label,#CTZ_BACKGROUND_LIGHT>label,#CTZ_BACKGROUND_DARK>label{position:relative;cursor:pointer}#CTZ_BACKGROUND>label input,#CTZ_BACKGROUND_LIGHT>label input,#CTZ_BACKGROUND_DARK>label input{position:absolute;pointer-events:none;width:20px;height:20px;top:18px;left:20px}#CTZ_BACKGROUND>label input:checked+div,#CTZ_BACKGROUND_LIGHT>label input:checked+div,#CTZ_BACKGROUND_DARK>label input:checked+div{border:4px solid #1677ff}#CTZ_BACKGROUND>label div,#CTZ_BACKGROUND_LIGHT>label div,#CTZ_BACKGROUND_DARK>label div{pointer-events:none;border:4px double #eee;font-size:14px;border-radius:12px;line-height:56px;padding-left:60px}#CTZ_BACKGROUND_LIGHT{color:#000}.ctz-set-background{margin:-12px}.ctz-set-background .ctz-background-title{padding:12px 12px 0}.ctz-set-background .ctz-background-content{padding:12px;border-bottom:1px solid #d9d9d9}.ctz-set-background .ctz-background-content:last-of-type{border:none}.css-nk32ej{display:none}.TopstoryMain [itemprop='zhihu:question']{display:inline}.RichContent-inner p{margin-bottom:1.4em}a.external,a.internal,a.ztext-link{border-bottom:1px solid #81858f;cursor:pointer;text-decoration:none}.OpenInAppButton,.css-u5ygyp{display:none}.Question-main .ContentItem.AnswerItem .ContentItem-expandButton,.TopstoryMain .ContentItem.AnswerItem .ContentItem-expandButton{position:absolute;height:100%;width:100%}.Question-main .ctz-n-button-close,.TopstoryMain .ctz-n-button-close{margin-left:12px;border:0 !important}.Question-main .ctz-n-button-comment,.TopstoryMain .ctz-n-button-comment{margin-left:12px}.ctz-answer-item .AuthorInfo-avatarWrapper .AuthorInfo-avatar,.ctz-recommend-item .AuthorInfo-avatarWrapper .AuthorInfo-avatar{box-sizing:border-box;margin:0;min-width:0;max-width:100%;background-color:#ffffff;width:38px;height:38px;border-radius:2px}.ctz-answer-item .RichContent-inner img,.ctz-recommend-item .RichContent-inner img{max-width:100%}.Question-mainEntity .ContentItem-actions>.ContentItem-action{display:none}.QuestionAnswer-content .ctz-answer-item{padding:0}#CTZ_COMMENT,#CTZ_COMMENT_CHILD{position:fixed;top:0;left:0;width:100%;height:100%;background:#fff;z-index:2000;font-size:16px;transition:all .2s;flex-direction:column}#CTZ_COMMENT button,#CTZ_COMMENT_CHILD button{padding:0;margin:0;border:0}#CTZ_COMMENT button.ctz-comment-button,#CTZ_COMMENT_CHILD button.ctz-comment-button{display:inline-block;font-size:14px;line-height:32px;text-align:center;cursor:pointer;background:rgba(132,145,165,0.1);border:1px solid transparent;border-radius:3px;margin:10px 0px 10px 54px;padding:0px 6px 0px 12px;height:32px;color:#8491a5;font-weight:500}.ctz-comment-header{height:48px;display:flex;padding:0 24px;align-items:center;border-top:1px solid #ebeced;border-bottom:1px solid #ebeced}.ctz-comment-header-left{flex:1;display:flex;align-items:center}.ctz-comment-content{flex:1;overflow-y:auto}.ctz-ci{display:flex;padding:10px 20px 14px}.ctz-ci-child{padding:10px 20px 14px 54px}.ctz-ci-avatar img{box-sizing:border-box;margin:0px;min-width:0px;max-width:100%;width:24px;height:24px;border-radius:2px;filter:brightness(.95);display:block;position:relative;background-color:#f8f8fa;flex:0 0 auto;text-indent:-9999px;overflow:hidden}.ctz-ci-right{flex:1;padding-left:10px}.ctz-ci-user a,.ctz-ci-user div{display:inline-block}.ctz-ci-user a{font-size:15px;font-weight:bold}.ctz-ci-user .ctz-tag{padding:0px 4px;color:#999;height:16px;line-height:16px;box-sizing:border-box;margin-left:4px;font-size:12px;border-radius:4px}.ctz-ci-user span{margin:0 6px;font-size:16px;color:#9196a1}.ctz-ci-content{margin:4px 0px 0px;min-width:0px;overflow:hidden;overflow-wrap:break-word;font-size:15px;line-height:21px}.ctz-ci-content>p{display:inline}.ctz-ci-info{display:flex;justify-content:space-between;padding-top:4px;color:#75849a;font-size:14px}.ctz-ci-info-left span{margin-right:6px}.ctz-comment-list{padding:10px 0}.ctz-comment-child-count{padding:0 20px;height:50px;line-height:50px;font-size:16px;font-weight:bold;border-bottom:1px solid #ebeced;border-top:20px solid rgba(132,145,165,0.1)}.ctz-comment-count{font-size:16px;font-weight:bold;padding-right:16px}.ctz-comment-sort{border:2px solid #f8f8fa;background:#f8f8fa}.ctz-comment-sort button{box-sizing:border-box;margin:0px;min-width:0px;border-radius:2px;text-align:center;cursor:pointer;width:50px;height:24px;font-size:12px;line-height:24px;font-weight:600;background:transparent;color:#81858f}.ctz-comment-vote span{pointer-events:none}.ctz-comment-vote-up{color:#ee3a43}.ctz-stop-scroll{height:100% !important;overflow:hidden !important}#CTZ_OPEN_BUTTON{position:fixed;font-size:48px;background:#e1e1e1;color:#000;opacity:.6;width:48px;height:48px;line-height:44px;border-radius:8px;z-index:2000;text-align:center}#CTZ_DIALOG{position:fixed;top:0;left:0;width:100%;height:100%;background:#f5f5f5;z-index:2001;font-size:16px;transition:all .2s;flex-direction:column}#CTZ_DIALOG input[type='checkbox']{width:16px;height:16px}#CTZ_DIALOG textarea{box-sizing:border-box;margin:0;padding:4px 11px;font-size:14px;line-height:1.5;list-style:none;position:relative;display:inline-block;min-width:0;border-width:1px;border-style:solid;border-color:#d9d9d9;border-radius:6px;transition:all .2s}#CTZ_DIALOG a{color:inherit}.ctz-header,.ctz-footer{font-size:16px;display:flex;align-items:center;height:48px;padding:0 12px}.ctz-footer a{margin-right:32px}.ctz-top-operate{flex:1;padding:0 12px;font-size:12px}.ctz-version{font-size:16px}#CTZ_CLOSE_DIALOG{font-weight:bold;width:40px;height:40px;color:rgba(0,0,0,0.45);background:transparent;border:none;font-size:24px}.ctz-menu{height:36px;display:flex}.ctz-menu>a{border-radius:12px 12px 0 0;flex:1;text-align:center;cursor:pointer;transition:initial !important;position:relative;display:flex;align-items:center;justify-content:center}.ctz-menu>a span{border-radius:8px;transition:all .3s;margin:0 4px;flex:1;box-sizing:border-box;align-items:center;line-height:26px}.ctz-menu>a.target{background:#fff}.ctz-menu>a.target::after,.ctz-menu>a.target::before{position:absolute;bottom:-12px;content:' ';background:radial-gradient(circle at top left, transparent 12px, #fff 0) top left,radial-gradient(circle at top right, transparent 12px, #fff 0) top right,radial-gradient(circle at bottom right, transparent 12px, #fff 0) bottom right,radial-gradient(circle at bottom left, transparent 12px, #fff 0) bottom left;background-size:50% 50%;background-repeat:no-repeat;width:24px;height:24px}.ctz-menu>a.target::before{left:-12px;z-index:-1}.ctz-menu>a.target::after{right:-12px;z-index:-1}.ctz-content{flex:1;overflow:hidden;background:#fff;border-radius:12px;padding:8px 0}.ctz-content>div{height:100%;flex-direction:column}.ctz-content-top{height:28px;display:flex;padding-bottom:8px}.ctz-content-top a{flex:1;text-align:center;line-height:28px;margin:0 8px;border-radius:8px}.ctz-content-top a.target{background-color:#f5f5f5}.ctz-content-top~.ctz-content-center{padding-top:0}.ctz-content-center{flex:1;overflow-y:auto;padding:12px}.ctz-content-center ::-webkit-scrollbar{width:8px;height:8px}.ctz-content-center ::-webkit-scrollbar-track{border-radius:0}.ctz-content-center ::-webkit-scrollbar-thumb{background:#bbb;transition:all .2s;border-radius:8px}.ctz-content-center ::-webkit-scrollbar-thumb:hover{background-color:rgba(95,95,95,0.7)}.ctz-hidden-item-br{margin:12px 0;width:100%;height:1px;position:relative}.ctz-hidden-item-br::after{content:'';position:absolute;top:0;left:50%;transform:translateX(-50%);width:65%;height:1px;background:#d9d9d9}#CTZ_HIDDEN .ctz-content-center label{margin-right:12px;margin-bottom:4px}#CTZ_BASIS_SHOW label{margin:8px 0}#CTZ_BASIS_SHOW label b{display:inline-block;padding:0 4px;background:#f5f5f5;border-radius:2px;margin-right:2px}.ctz-suspension-pickup{position:fixed;bottom:60px;right:14px;text-align:center;height:40px;line-height:40px;width:68px;border-radius:4px;font-size:14px;background:#fff}.ctz-label{line-height:28px}.ctz-label::after{content:':'}.ctz-flex-wrap{display:flex;flex-wrap:wrap;line-height:24px}.ctz-flex-wrap label{margin-right:4px;display:flex;align-items:center}.ctz-flex-wrap label input[type='radio']{margin:0 4px 0 0}.ctz-label-tag{font-weight:normal;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff;margin:0 2px}.ctz-label-tag-Answer{background:#ec7259}.ctz-label-tag-ZVideo{background:#12c2e9}.ctz-label-tag-Article{background:#00965e}.ctz-label-tag-Pin{background:#9c27b0}#CTZ_HISTORY_LIST .ctz-set-content a,#CTZ_HISTORY_VIEW .ctz-set-content a{word-break:break-all;display:block;margin-bottom:12px;padding:6px 12px;border:1px solid #eee;border-radius:4px}.ctz-fetch-intercept .ctz-need-fetch{display:none}.ctz-fetch-intercept.ctz-fetch-intercept-close{color:#b0b0b0 !important;cursor:not-allowed}.ctz-fetch-intercept.ctz-fetch-intercept-close span.ctz-need-fetch{display:inline}.ctz-fetch-intercept.ctz-fetch-intercept-close div.ctz-need-fetch{display:block}.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-remove-block{cursor:not-allowed !important}.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-black-item .ctz-remove-block:hover,.ctz-fetch-intercept.ctz-fetch-intercept-close .ctz-black-item a:hover{background:transparent !important;color:#b0b0b0 !important}#CTZ_MESSAGE_BOX{position:fixed;left:0;top:10px;width:100%;z-index:2002}.ctz-message{margin:20px auto;width:70%;height:48px;display:flex;align-items:center;justify-content:center;font-size:14px;border-radius:8px;box-shadow:0 0 8px #d0d4d6,0 0 8px #e6eaec;margin-bottom:12px;background:#fff}.ctz-config-import-box{display:flex;flex-direction:column}.ctz-config-import-box>div,.ctz-config-import-box>textarea{margin-bottom:12px !important}.ctz-config-import-box textarea{height:120px;resize:vertical}#CTZ_LOADING_TOAST{position:fixed;top:50%;left:50%;width:100px;height:100px;background:rgba(0,0,0,0.25);color:#fff;transform:translate(-50%, -50%);border-radius:16px;z-index:2002;display:flex;flex-direction:column;align-items:center}#CTZ_LOADING_TOAST .ctz-loading-toast-text{padding-bottom:12px}#CTZ_LOADING_TOAST .ctz-loading-toast-icon{flex:1;position:relative;font-size:34px}#CTZ_LOADING_TOAST .ctz-loading-toast-icon span{position:absolute;top:50%;left:50%;animation:rotate 1.5s infinite}.ctz-preview{box-sizing:border-box;position:fixed;height:100%;width:100%;top:0;left:0;overflow-y:auto;z-index:200;background-color:rgba(18,18,18,0.4)}.ctz-preview div{display:flex;justify-content:center;align-items:center;min-height:100%;width:100%}.ctz-preview div img{cursor:zoom-out;user-select:none;max-width:100%}.ctz-comment-loading,.ctz-answer-loading,.ctz-list-loading{text-align:center;font-size:24px;color:#1677ff;position:relative;padding:0 0 12px;height:24px}.ctz-comment-loading span,.ctz-answer-loading span,.ctz-list-loading span{position:absolute;top:50%;left:50%;animation:rotate 1.5s infinite}.ctz-comment-end,.ctz-answer-end{text-align:center;padding:0 0 12px;color:#75849a}#CTZ_BUTTON_COMMENT_CLOSE{font-size:24px}#CTZ_TOP_SEARCH{width:100vw;display:flex;padding:6px 12px;height:50px;align-items:center;border-bottom:1px solid rgba(25,27,31,0.06);box-sizing:border-box}#CTZ_TOP_SEARCH input{flex:1;background-color:hsla(210,5%,93%,0.72);border-radius:16px;font-size:14px;height:30px;margin:0 10px;padding-left:8px;padding-right:0;border:1px solid #ebeced}#CTZ_TOP_SEARCH button{width:40px;color:#1772f6;font-size:16px}`;
  642. var INNER_VERSION = `2.9.2`;
  643. var initHTML = () => {
  644. document.body.appendChild(domC("div", { id: "CTZ_MAIN", innerHTML: INNER_HTML }));
  645. fnHaveTopSearch();
  646. openButtonPosition();
  647. dom(".ctz-version").innerText = `version: ${INNER_VERSION}`;
  648. dom(".ctz-menu").innerHTML = HEADER.map(({ href, value }) => `<a href="${href}"><span>${value}</span></a>`).join("");
  649. addBackgroundElement();
  650. dom("#CTZ_HIDDEN .ctz-content-center").innerHTML = HIDDEN_ARRAY.map(
  651. (itemArr) => itemArr.map(({ label, value }) => `<label class="dis-if-c"><input class="ctz-i" name="${value}" type="checkbox" value="on" />${label}</label>`).join("") + '<div class="ctz-hidden-item-br"></div>'
  652. ).join("");
  653. dom("#CTZ_BASIS_SHOW").innerHTML += BASIC_SHOW_CONTENT.map(
  654. ({ label, value, needFetch }) => `<label class="ctz-flex-wrap ${needFetch ? "ctz-fetch-intercept" : ""}"><span class="ctz-label">${label}${needFetch ? '<span class="ctz-need-fetch">(接口拦截已关闭,此功能无法使用)</span>' : ""}</span><input class="ctz-i" name="${value}" type="checkbox" value="on" /></label>`
  655. ).join("");
  656. myMenu.init();
  657. };
  658. var myScroll = {
  659. stop: () => dom("body").classList.add("ctz-stop-scroll"),
  660. on: () => dom("body").classList.remove("ctz-stop-scroll")
  661. };
  662. var echoData = async () => {
  663. const pfConfig = await myStorage.getConfig();
  664. const textSameName = {
  665. globalTitle: (e2) => e2.value = pfConfig.globalTitle || document.title,
  666. customizeCss: (e2) => e2.value = pfConfig.customizeCss || ""
  667. };
  668. const echoText = (even) => {
  669. textSameName[even.name] ? textSameName[even.name](even) : even.value = pfConfig[even.name];
  670. };
  671. const echo = {
  672. radio: (even) => pfConfig.hasOwnProperty(even.name) && even.value === pfConfig[even.name] && (even.checked = true),
  673. checkbox: (even) => even.checked = pfConfig[even.name] || false,
  674. text: echoText,
  675. number: echoText,
  676. range: (even) => {
  677. const nValue = pfConfig[even.name];
  678. const nodeRange = dom(`[name="${even.name}"]`);
  679. const min = nodeRange && nodeRange.min;
  680. const rangeNum = isNaN(+nValue) || !(+nValue > 0) ? min : nValue;
  681. even.value = rangeNum;
  682. const nodeNewOne = domById(even.name);
  683. nodeNewOne && (nodeNewOne.innerText = rangeNum);
  684. }
  685. };
  686. const doEcho = (item) => {
  687. echo[item.type] && echo[item.type](item);
  688. };
  689. const nodeArrInputClick = domA(`.${CLASS_INPUT_CLICK}`);
  690. for (let i2 = 0, len = nodeArrInputClick.length; i2 < len; i2++) {
  691. doEcho(nodeArrInputClick[i2]);
  692. }
  693. const nodeArrInputChange = domA(`.${CLASS_INPUT_CHANGE}`);
  694. for (let i2 = 0, len = nodeArrInputChange.length; i2 < len; i2++) {
  695. doEcho(nodeArrInputChange[i2]);
  696. }
  697. };
  698. var echoHistory = async () => {
  699. const history = await myStorage.getHistory();
  700. const { list, view } = history;
  701. const nodeList = dom("#CTZ_HISTORY_LIST .ctz-set-content");
  702. const nodeView = dom("#CTZ_HISTORY_VIEW .ctz-set-content");
  703. nodeList && (nodeList.innerHTML = list.join(""));
  704. nodeView && (nodeView.innerHTML = view.join(""));
  705. };
  706. var addHistoryView = async () => {
  707. const { href, origin, pathname, hash } = location;
  708. const question = "www.zhihu.com/question/";
  709. const article = "zhuanlan.zhihu.com/p/";
  710. const video = "www.zhihu.com/zvideo/";
  711. let name = href.replace(hash, "");
  712. setTimeout(async () => {
  713. if (!href.includes(question) && !href.includes(article) && !href.includes(video))
  714. return;
  715. href.includes(question) && dom(".QuestionHeader-title") && (name = `<b class="c-ec7259">「问题」</b>${dom(".QuestionHeader-title").innerText}`);
  716. href.includes(article) && dom(".Post-Title") && (name = `<b class="c-00965e">「文章」</b>${dom(".Post-Title").innerText}`);
  717. href.includes(video) && dom(".ZVideo-title") && (name = `<b class="c-12c2e9">「视频」</b>${dom(".ZVideo-title").innerText}`);
  718. const nA = `<a href="${origin + pathname}" target="_blank">${name}</a>`;
  719. const { view } = await myStorage.getHistory();
  720. if (!view.includes(nA)) {
  721. view.unshift(nA);
  722. await myStorage.setHistoryItem("view", view);
  723. }
  724. }, 500);
  725. };
  726. var myDialog = {
  727. open: (e2) => {
  728. e2 && e2.preventDefault();
  729. const nodeDialog = domById("CTZ_DIALOG");
  730. nodeDialog && (nodeDialog.style.display = "flex");
  731. myScroll.stop();
  732. echoData();
  733. echoHistory();
  734. },
  735. hide: () => {
  736. const nodeDialog = domById("CTZ_DIALOG");
  737. nodeDialog && (nodeDialog.style.display = "none");
  738. myScroll.on();
  739. }
  740. };
  741. var DN = "display:none!important;";
  742. var myHidden = {
  743. init: async function() {
  744. const content = await this.change();
  745. fnInitDomStyle("CTZ_STYLE_HIDDEN", content || "");
  746. },
  747. change: async function() {
  748. const config = await myStorage.getConfig();
  749. const cssHidden = Object.keys(this.hiddenItem).map((key) => config[key] ? this.hiddenItem[key] : "").join("");
  750. let cssHiddenMore = "";
  751. this.hiddenArray.forEach(({ keys, value }) => {
  752. let trueNumber = 0;
  753. keys.forEach((key) => config[key] && trueNumber++);
  754. trueNumber === keys.length && (cssHiddenMore += value);
  755. });
  756. return cssHidden + cssHiddenMore;
  757. },
  758. hiddenItem: {
  759. hiddenOpenApp: `.OpenInAppButton,.css-rg1dmv,.css-1gapyfo,.css-183aq3r,.css-wfkf2m{${DN}}`,
  760. hiddenLogo: `.MobileAppHeader-logo,a[aria-label="知乎"]{${DN}}`,
  761. hiddenHeader: `.MobileAppHeader,.ColumnPageHeader.Sticky{${DN}}`,
  762. hiddenItemActions: `.TopstoryItem .ContentItem-actions:not(.Sticky),.SearchMain .ContentItem-actions{${DN}}`,
  763. hiddenBottomSticky: `.ContentItem-actions.Sticky,.css-1tu4yh8{${DN}}`,
  764. hiddenReward: `.Reward{${DN}}`,
  765. hiddenListImg: `.RichContent-cover,.css-uw6cz9,.SearchItem-rightImg{${DN}}`,
  766. hiddenReadMoreText: ".ContentItem-more{font-size:0!important;}",
  767. hiddenAnswers: `.RichContent-inner,.css-3ny988,.Topstory-recommend .VideoAnswerPlayer{${DN}}`,
  768. hiddenListVideoContent: `.Topstory-recommend .ZVideoItem-video,.Topstory-recommend .VideoAnswerPlayer,.Topstory-recommend .ZVideoItem .RichContent{${DN}}`,
  769. hiddenZhuanlanActions: `.zhuanlan .RichContent-actions.is-fixed>.ContentItem-actions{${DN}}`,
  770. hiddenZhuanlanTitleImage: ".css-1ntkiwo,.TitleImage,.css-78p1r9,.ArticleItem .RichContent>div:first-of-type:not(.RichContent-cover)>div:last-of-type{display: none!important;}",
  771. hiddenDetailAvatar: `.AnswerItem .AuthorInfo .AuthorInfo-avatarWrapper{${DN}}.AnswerItem .AuthorInfo .AuthorInfo-content{margin-left:0!important;}`,
  772. hiddenDetailBadge: `.AnswerItem .AuthorInfo .AuthorInfo-detail{${DN}}`,
  773. hiddenDetailVoters: `.css-dvccr2{${DN}}`,
  774. hiddenWhoVoters: ".css-1vqda4a{display: none!important;}",
  775. hiddenDetailName: `.AnswerItem .AuthorInfo .AuthorInfo-head{${DN}}`,
  776. hiddenQuestionFollowing: `.QuestionHeader .FollowButton{${DN}}`,
  777. hiddenQuestionAnswer: `.QuestionHeader .FollowButton ~ a{${DN}}`,
  778. hiddenZhuanlanFollowButton: `.zhuanlan .FollowButton{${DN}}`,
  779. hiddenZhuanlanAvatarWrapper: `.zhuanlan .AuthorInfo-avatarWrapper{${DN}}`,
  780. hiddenZhuanlanAuthorInfoHead: `.zhuanlan .AuthorInfo-head{${DN}}`,
  781. hiddenZhuanlanAuthorInfoDetail: `.zhuanlan .AuthorInfo-detail{${DN}}`,
  782. hiddenAnswerItemActions: `.Question-main .ContentItem-actions{${DN}}`,
  783. hiddenAnswerItemTime: `.Question-main .ContentItem-time{${DN}margin: 0;}`,
  784. hiddenAnswerItemTimeButHaveIP: `.Question-main .ContentItem-time>a{${DN}}.Question-main .ContentItem-time:empty{${DN}margin: 0;}`,
  785. hiddenZhuanlanImage: `.zhuanlan .origin_image{${DN}}`,
  786. hiddenCommitImg: `.comment_img{${DN}}`,
  787. hiddenAnswerYanxuanRecommend: `.Question-mainEntity .KfeCollection-VipRecommendCard{${DN}}`,
  788. hiddenAD: `.TopstoryItem--advertCard,.Pc-card,.Pc-word,.RichText-ADLinkCardContainer,#div-gpt-ad-bannerAd,#div-gpt-ad-hotFeedAd,.MRelateFeedAd,.MHotFeedAd,.MBannerAd{${DN}}`,
  789. hiddenAnswerRelatedRecommend: `.Question-mainEntity .RelatedReadings{${DN}}`,
  790. hiddenAnswerHotRecommend: `.Question-mainEntity .HotQuestions{${DN}}`
  791. },
  792. hiddenArray: []
  793. };
  794. var myVersion = {
  795. init: async function() {
  796. const config = await myStorage.getConfig();
  797. fnInitDomStyle("CTZ_STYLE_VERSION", this.vQuestionTitleTag(config) + this.openButtonInvisible(config) + this.vCommentHeaderToBottom(config));
  798. },
  799. change: function() {
  800. this.init();
  801. },
  802. /** 内容标题添加类别显示 */
  803. vQuestionTitleTag: function({ questionTitleTag }) {
  804. const cssTag = "margin-right:6px;font-weight:normal;display:inline;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff";
  805. return fnReturnStr(
  806. `.AnswerItem .ContentItem-title::before{content:'问答';background:#ec7259}.TopstoryItem .PinItem::before{content:'想法';background:#9c27b0;${cssTag}}.PinItem>.ContentItem-title{margin-top:4px;}.ZvideoItem .ContentItem-title::before{content:'视频';background:#12c2e9}.ZVideoItem .ContentItem-title::before{content:'视频';background:#12c2e9}.ArticleItem .ContentItem-title::before{content:'文章';background:#00965e}.ContentItem .ContentItem-title::before{margin-right:6px;font-weight:normal;display:inline;padding:2px 4px;border-radius:4px;font-size:12px;color:#ffffff}.TopstoryQuestionAskItem .ContentItem-title::before{content:'提问';background:#533b77}`,
  807. questionTitleTag
  808. );
  809. },
  810. vCommentHeaderToBottom: function({ commentHeaderToBottom }) {
  811. return fnReturnStr(`#CTZ_COMMENT,#CTZ_COMMENT_CHILD{flex-direction: column-reverse!important;}`, commentHeaderToBottom);
  812. },
  813. /** 隐藏修改器唤起按钮 */
  814. openButtonInvisible: function({ openButtonInvisible }) {
  815. return fnReturnStr("#CTZ_OPEN_BUTTON{display: none!important;}", openButtonInvisible);
  816. }
  817. };
  818. var onInitStyleExtra = () => {
  819. myHidden.init();
  820. loadBackground();
  821. myVersion.init();
  822. loadFindTheme();
  823. };
  824. var myButtonOperate = {
  825. /** 清空历史记录 */
  826. buttonHistoryClear: async (target) => {
  827. const prevHistory = await myStorage.getHistory();
  828. const dataId = target.getAttribute("data-id");
  829. const isClear = confirm(`是否清空${target.innerText}`);
  830. if (!isClear)
  831. return;
  832. prevHistory[dataId] = [];
  833. await myStorage.setHistory(prevHistory);
  834. echoHistory();
  835. },
  836. /** 获取当前配置 */
  837. configExport: async () => {
  838. const config = await myStorage.get(NAME_CONFIG) ?? "";
  839. copy(config);
  840. message("已复制当前配置");
  841. },
  842. /** 恢复默认配置 */
  843. configReset: async function() {
  844. const isUse = confirm("是否启恢复默认配置?\n该功能会覆盖当前配置,建议先将配置获取保存");
  845. if (!isUse)
  846. return;
  847. const { filterKeywords = [], removeBlockUserContentList = [] } = await myStorage.getConfig();
  848. await myStorage.setConfig({
  849. ...CONFIG_DEFAULT,
  850. filterKeywords,
  851. removeBlockUserContentList
  852. });
  853. resetData();
  854. },
  855. /** 导入配置 */
  856. configImport: async function() {
  857. const nodeImport = dom("[name=textConfigImport]");
  858. const configImport = nodeImport ? nodeImport.value : "{}";
  859. const configThis = JSON.parse(configImport);
  860. const configPrev = await myStorage.getConfig();
  861. const nConfig = {
  862. ...configPrev,
  863. ...configThis
  864. };
  865. await myStorage.setConfig(nConfig);
  866. resetData();
  867. message("配置已导入");
  868. },
  869. /** 自定义样式 */
  870. styleCustom: async function() {
  871. const nodeText = dom('[name="textStyleCustom"]');
  872. const value = nodeText ? nodeText.value : "";
  873. await myStorage.updateConfig("customizeCss", value);
  874. myCustomStyle.change(value);
  875. },
  876. styleCustomReset: async function() {
  877. dom('[name="textStyleCustom"]').value = "";
  878. await myStorage.updateConfig("customizeCss", "");
  879. myCustomStyle.change("");
  880. }
  881. };
  882. var resetData = () => {
  883. onInitStyleExtra();
  884. echoData();
  885. onUseThemeDark();
  886. };
  887. var timeFormatter = (time, formatter = "YYYY-MM-DD HH:mm:ss") => {
  888. if (!time)
  889. return "";
  890. const date = new Date(time);
  891. const year = date.getFullYear();
  892. const month = date.getMonth() + 1;
  893. const day = date.getDate();
  894. const hour = date.getHours();
  895. const min = date.getMinutes();
  896. const sec = date.getSeconds();
  897. const preArr = (num) => String(num).length !== 2 ? "0" + String(num) : String(num);
  898. return formatter.replace(/YYYY/g, String(year)).replace(/MM/g, preArr(month)).replace(/DD/g, preArr(day)).replace(/HH/g, preArr(hour)).replace(/mm/g, preArr(min)).replace(/ss/g, preArr(sec));
  899. };
  900. var addTimeForQuestion = async () => {
  901. const { releaseTimeForQuestion } = await myStorage.getConfig();
  902. const className = "ctz-question-time";
  903. if (dom(`.${className}`))
  904. return;
  905. const nodeCreated = dom('[itemprop="dateCreated"]');
  906. const nodeModified = dom('[itemprop="dateModified"]');
  907. const nodeTitle = dom(".QuestionHeader-title");
  908. if (!(releaseTimeForQuestion && nodeCreated && nodeModified && nodeTitle))
  909. return;
  910. const createTime = timeFormatter(nodeCreated.content);
  911. const updateTime = timeFormatter(nodeModified.content);
  912. nodeTitle.appendChild(
  913. domC("div", {
  914. className,
  915. innerHTML: `<div>创建于:${createTime}</div>${updateTime !== createTime ? `<div>编辑于:${updateTime}</div>` : ""}`,
  916. style: "font-size: 14px;"
  917. })
  918. );
  919. };
  920. var addTimeForArticle = async () => {
  921. const { releaseTimeForArticle } = await myStorage.getConfig();
  922. const className = "ctz-article-create-time";
  923. if (dom(`.${className}`))
  924. return;
  925. const nodeContentTime = dom(".ContentItem-time");
  926. const nodeHeader = dom(".Post-Header");
  927. if (!(releaseTimeForArticle && nodeContentTime && nodeHeader))
  928. return;
  929. nodeHeader.appendChild(
  930. domC("span", {
  931. className,
  932. style: "color: #8590a6;line-height: 30px;",
  933. innerHTML: nodeContentTime.innerText || ""
  934. })
  935. );
  936. };
  937. var createTimeHTML = (createTime, updateTime) => {
  938. return `<div class="${CLASS_TIME_ITEM}" style="line-height: 24px;padding-top: 2px;font-size: 14px;"><div>创建于:${timeFormatter(+`${createTime}`)}</div>${createTime !== updateTime && updateTime ? `<div>编辑于:${timeFormatter(+`${updateTime}`)}</div>` : ""}</div>`;
  939. };
  940. var fnChanger = async (ev) => {
  941. const doCssVersion = ["questionTitleTag", "openButtonInvisible", "commentHeaderToBottom"];
  942. const { name, value, checked, type } = ev;
  943. const changeBackground = () => {
  944. myVersion.change();
  945. loadBackground();
  946. onUseThemeDark();
  947. };
  948. const ob = {
  949. [INPUT_NAME_THEME]: changeBackground,
  950. [INPUT_NAME_ThEME_LIGHT]: changeBackground,
  951. [INPUT_NAME_THEME_DARK]: changeBackground,
  952. releaseTimeForQuestion: addTimeForQuestion,
  953. releaseTimeForArticle: addTimeForArticle,
  954. haveTopSearch: fnHaveTopSearch
  955. };
  956. await myStorage.updateConfig(name, type === "checkbox" ? checked : value);
  957. const nodeName = domById(name);
  958. type === "range" && nodeName && (nodeName.innerText = value);
  959. if (/^hidden/.test(name)) {
  960. myHidden.init();
  961. return;
  962. }
  963. if (doCssVersion.includes(name)) {
  964. myVersion.change();
  965. return;
  966. }
  967. ob[name] && ob[name]();
  968. };
  969. function md5(s2) {
  970. function f12(t2, e2, n2) {
  971. var r2;
  972. !function(o3) {
  973. "use strict";
  974. function i2(t3, e3) {
  975. var n3 = (65535 & t3) + (65535 & e3);
  976. return (t3 >> 16) + (e3 >> 16) + (n3 >> 16) << 16 | 65535 & n3;
  977. }
  978. function a2(t3, e3, n3, r3, o4, a3) {
  979. return i2((u2 = i2(i2(e3, t3), i2(r3, a3))) << (c3 = o4) | u2 >>> 32 - c3, n3);
  980. var u2, c3;
  981. }
  982. function u(t3, e3, n3, r3, o4, i3, u2) {
  983. return a2(e3 & n3 | ~e3 & r3, t3, e3, o4, i3, u2);
  984. }
  985. function c2(t3, e3, n3, r3, o4, i3, u2) {
  986. return a2(e3 & r3 | n3 & ~r3, t3, e3, o4, i3, u2);
  987. }
  988. function s3(t3, e3, n3, r3, o4, i3, u2) {
  989. return a2(e3 ^ n3 ^ r3, t3, e3, o4, i3, u2);
  990. }
  991. function l2(t3, e3, n3, r3, o4, i3, u2) {
  992. return a2(n3 ^ (e3 | ~r3), t3, e3, o4, i3, u2);
  993. }
  994. function f(t3, e3) {
  995. var n3, r3, o4, a3, f2;
  996. t3[e3 >> 5] |= 128 << e3 % 32, t3[14 + (e3 + 64 >>> 9 << 4)] = e3;
  997. var d2 = 1732584193, p2 = -271733879, h3 = -1732584194, v2 = 271733878;
  998. for (n3 = 0; n3 < t3.length; n3 += 16)
  999. r3 = d2, o4 = p2, a3 = h3, f2 = v2, d2 = u(d2, p2, h3, v2, t3[n3], 7, -680876936), v2 = u(v2, d2, p2, h3, t3[n3 + 1], 12, -389564586), h3 = u(h3, v2, d2, p2, t3[n3 + 2], 17, 606105819), p2 = u(p2, h3, v2, d2, t3[n3 + 3], 22, -1044525330), d2 = u(d2, p2, h3, v2, t3[n3 + 4], 7, -176418897), v2 = u(v2, d2, p2, h3, t3[n3 + 5], 12, 1200080426), h3 = u(h3, v2, d2, p2, t3[n3 + 6], 17, -1473231341), p2 = u(p2, h3, v2, d2, t3[n3 + 7], 22, -45705983), d2 = u(d2, p2, h3, v2, t3[n3 + 8], 7, 1770035416), v2 = u(v2, d2, p2, h3, t3[n3 + 9], 12, -1958414417), h3 = u(h3, v2, d2, p2, t3[n3 + 10], 17, -42063), p2 = u(p2, h3, v2, d2, t3[n3 + 11], 22, -1990404162), d2 = u(d2, p2, h3, v2, t3[n3 + 12], 7, 1804603682), v2 = u(v2, d2, p2, h3, t3[n3 + 13], 12, -40341101), h3 = u(h3, v2, d2, p2, t3[n3 + 14], 17, -1502002290), d2 = c2(d2, p2 = u(p2, h3, v2, d2, t3[n3 + 15], 22, 1236535329), h3, v2, t3[n3 + 1], 5, -165796510), v2 = c2(v2, d2, p2, h3, t3[n3 + 6], 9, -1069501632), h3 = c2(h3, v2, d2, p2, t3[n3 + 11], 14, 643717713), p2 = c2(p2, h3, v2, d2, t3[n3], 20, -373897302), d2 = c2(d2, p2, h3, v2, t3[n3 + 5], 5, -701558691), v2 = c2(v2, d2, p2, h3, t3[n3 + 10], 9, 38016083), h3 = c2(h3, v2, d2, p2, t3[n3 + 15], 14, -660478335), p2 = c2(p2, h3, v2, d2, t3[n3 + 4], 20, -405537848), d2 = c2(d2, p2, h3, v2, t3[n3 + 9], 5, 568446438), v2 = c2(v2, d2, p2, h3, t3[n3 + 14], 9, -1019803690), h3 = c2(h3, v2, d2, p2, t3[n3 + 3], 14, -187363961), p2 = c2(p2, h3, v2, d2, t3[n3 + 8], 20, 1163531501), d2 = c2(d2, p2, h3, v2, t3[n3 + 13], 5, -1444681467), v2 = c2(v2, d2, p2, h3, t3[n3 + 2], 9, -51403784), h3 = c2(h3, v2, d2, p2, t3[n3 + 7], 14, 1735328473), d2 = s3(d2, p2 = c2(p2, h3, v2, d2, t3[n3 + 12], 20, -1926607734), h3, v2, t3[n3 + 5], 4, -378558), v2 = s3(v2, d2, p2, h3, t3[n3 + 8], 11, -2022574463), h3 = s3(h3, v2, d2, p2, t3[n3 + 11], 16, 1839030562), p2 = s3(p2, h3, v2, d2, t3[n3 + 14], 23, -35309556), d2 = s3(d2, p2, h3, v2, t3[n3 + 1], 4, -1530992060), v2 = s3(v2, d2, p2, h3, t3[n3 + 4], 11, 1272893353), h3 = s3(h3, v2, d2, p2, t3[n3 + 7], 16, -155497632), p2 = s3(p2, h3, v2, d2, t3[n3 + 10], 23, -1094730640), d2 = s3(d2, p2, h3, v2, t3[n3 + 13], 4, 681279174), v2 = s3(v2, d2, p2, h3, t3[n3], 11, -358537222), h3 = s3(h3, v2, d2, p2, t3[n3 + 3], 16, -722521979), p2 = s3(p2, h3, v2, d2, t3[n3 + 6], 23, 76029189), d2 = s3(d2, p2, h3, v2, t3[n3 + 9], 4, -640364487), v2 = s3(v2, d2, p2, h3, t3[n3 + 12], 11, -421815835), h3 = s3(h3, v2, d2, p2, t3[n3 + 15], 16, 530742520), d2 = l2(d2, p2 = s3(p2, h3, v2, d2, t3[n3 + 2], 23, -995338651), h3, v2, t3[n3], 6, -198630844), v2 = l2(v2, d2, p2, h3, t3[n3 + 7], 10, 1126891415), h3 = l2(h3, v2, d2, p2, t3[n3 + 14], 15, -1416354905), p2 = l2(p2, h3, v2, d2, t3[n3 + 5], 21, -57434055), d2 = l2(d2, p2, h3, v2, t3[n3 + 12], 6, 1700485571), v2 = l2(v2, d2, p2, h3, t3[n3 + 3], 10, -1894986606), h3 = l2(h3, v2, d2, p2, t3[n3 + 10], 15, -1051523), p2 = l2(p2, h3, v2, d2, t3[n3 + 1], 21, -2054922799), d2 = l2(d2, p2, h3, v2, t3[n3 + 8], 6, 1873313359), v2 = l2(v2, d2, p2, h3, t3[n3 + 15], 10, -30611744), h3 = l2(h3, v2, d2, p2, t3[n3 + 6], 15, -1560198380), p2 = l2(p2, h3, v2, d2, t3[n3 + 13], 21, 1309151649), d2 = l2(d2, p2, h3, v2, t3[n3 + 4], 6, -145523070), v2 = l2(v2, d2, p2, h3, t3[n3 + 11], 10, -1120210379), h3 = l2(h3, v2, d2, p2, t3[n3 + 2], 15, 718787259), p2 = l2(p2, h3, v2, d2, t3[n3 + 9], 21, -343485551), d2 = i2(d2, r3), p2 = i2(p2, o4), h3 = i2(h3, a3), v2 = i2(v2, f2);
  1000. return [d2, p2, h3, v2];
  1001. }
  1002. function d(t3) {
  1003. var e3, n3 = "", r3 = 32 * t3.length;
  1004. for (e3 = 0; e3 < r3; e3 += 8)
  1005. n3 += String.fromCharCode(t3[e3 >> 5] >>> e3 % 32 & 255);
  1006. return n3;
  1007. }
  1008. function p(t3) {
  1009. var e3, n3 = [];
  1010. for (n3[(t3.length >> 2) - 1] = void 0, e3 = 0; e3 < n3.length; e3 += 1)
  1011. n3[e3] = 0;
  1012. var r3 = 8 * t3.length;
  1013. for (e3 = 0; e3 < r3; e3 += 8)
  1014. n3[e3 >> 5] |= (255 & t3.charCodeAt(e3 / 8)) << e3 % 32;
  1015. return n3;
  1016. }
  1017. function h2(t3) {
  1018. var e3, n3, r3 = "0123456789abcdef", o4 = "";
  1019. for (n3 = 0; n3 < t3.length; n3 += 1)
  1020. e3 = t3.charCodeAt(n3), o4 += r3.charAt(e3 >>> 4 & 15) + r3.charAt(15 & e3);
  1021. return o4;
  1022. }
  1023. function v(t3) {
  1024. return unescape(encodeURIComponent(t3));
  1025. }
  1026. function A2(t3) {
  1027. return function(t4) {
  1028. return d(f(p(t4), 8 * t4.length));
  1029. }(v(t3));
  1030. }
  1031. function m(t3, e3) {
  1032. return function(t4, e4) {
  1033. var n3, r3, o4 = p(t4), i3 = [], a3 = [];
  1034. for (i3[15] = a3[15] = void 0, o4.length > 16 && (o4 = f(o4, 8 * t4.length)), n3 = 0; n3 < 16; n3 += 1)
  1035. i3[n3] = 909522486 ^ o4[n3], a3[n3] = 1549556828 ^ o4[n3];
  1036. return r3 = f(i3.concat(p(e4)), 512 + 8 * e4.length), d(f(a3.concat(r3), 640));
  1037. }(v(t3), v(e3));
  1038. }
  1039. function g2(t3, e3, n3) {
  1040. return e3 ? n3 ? m(e3, t3) : h2(m(e3, t3)) : n3 ? A2(t3) : h2(A2(t3));
  1041. }
  1042. void 0 === (r2 = function() {
  1043. return g2;
  1044. }.call(e2, n2, e2, t2)) || (t2.exports = r2);
  1045. }();
  1046. }
  1047. var o2 = {};
  1048. f12(o2);
  1049. return o2.exports(s2);
  1050. }
  1051. function zhihu_enc(s) {
  1052. function f1(__unused_webpack_module, exports) {
  1053. "use strict";
  1054. var __webpack_unused_export__;
  1055. function o(t2) {
  1056. return (o = "function" == typeof Symbol && "symbol" == typeof Symbol.A ? function(t3) {
  1057. return typeof t3;
  1058. } : function(t3) {
  1059. return t3 && "function" == typeof Symbol && t3.constructor === Symbol && t3 !== Symbol.prototype ? "symbol" : typeof t3;
  1060. })(t2);
  1061. }
  1062. function x(e2) {
  1063. return C(e2) || s(e2) || t();
  1064. }
  1065. function C(t2) {
  1066. if (Array.isArray(t2)) {
  1067. for (var e2 = 0, n2 = new Array(t2.length); e2 < t2.length; e2++)
  1068. n2[e2] = t2[e2];
  1069. return n2;
  1070. }
  1071. }
  1072. function s(t2) {
  1073. if (Symbol.A in Object(t2) || "[object Arguments]" === Object.prototype.toString.call(t2))
  1074. return Array.from(t2);
  1075. }
  1076. function t() {
  1077. throw new TypeError("Invalid attempt to spread non-iterable instance");
  1078. }
  1079. __webpack_unused_export__ = {
  1080. value: true
  1081. };
  1082. var A = "3.0", S = "undefined" != typeof window ? window : {}, h;
  1083. function i(t2, e2, n2) {
  1084. e2[n2] = 255 & t2 >>> 24, e2[n2 + 1] = 255 & t2 >>> 16, e2[n2 + 2] = 255 & t2 >>> 8, e2[n2 + 3] = 255 & t2;
  1085. }
  1086. function B(t2, e2) {
  1087. return (255 & t2[e2]) << 24 | (255 & t2[e2 + 1]) << 16 | (255 & t2[e2 + 2]) << 8 | 255 & t2[e2 + 3];
  1088. }
  1089. function Q(t2, e2) {
  1090. return (4294967295 & t2) << e2 | t2 >>> 32 - e2;
  1091. }
  1092. function G(t2) {
  1093. var e2 = new Array(4), n2 = new Array(4);
  1094. i(t2, e2, 0), n2[0] = h.zb[255 & e2[0]], n2[1] = h.zb[255 & e2[1]], n2[2] = h.zb[255 & e2[2]], n2[3] = h.zb[255 & e2[3]];
  1095. var r2 = B(n2, 0);
  1096. return r2 ^ Q(r2, 2) ^ Q(r2, 10) ^ Q(r2, 18) ^ Q(r2, 24);
  1097. }
  1098. var __g = {
  1099. x: function(t2, e2) {
  1100. for (var n2 = [], r2 = t2.length, o2 = 0; 0 < r2; r2 -= 16) {
  1101. for (var i2 = t2.slice(16 * o2, 16 * (o2 + 1)), a2 = new Array(16), u = 0; u < 16; u++)
  1102. a2[u] = i2[u] ^ e2[u];
  1103. e2 = __g.r(a2), n2 = n2.concat(e2), o2++;
  1104. }
  1105. return n2;
  1106. },
  1107. r: function(t2) {
  1108. var e2 = new Array(16), n2 = new Array(36);
  1109. n2[0] = B(t2, 0), n2[1] = B(t2, 4), n2[2] = B(t2, 8), n2[3] = B(t2, 12);
  1110. for (var r2 = 0; r2 < 32; r2++) {
  1111. var o2 = G(n2[r2 + 1] ^ n2[r2 + 2] ^ n2[r2 + 3] ^ h.zk[r2]);
  1112. n2[r2 + 4] = n2[r2] ^ o2;
  1113. }
  1114. return i(n2[35], e2, 0), i(n2[34], e2, 4), i(n2[33], e2, 8), i(n2[32], e2, 12), e2;
  1115. }
  1116. };
  1117. function l() {
  1118. this.C = [0, 0, 0, 0], this.s = 0, this.t = [], this.S = [], this.h = [], this.i = [], this.B = [], this.Q = false, this.G = [], this.D = [], this.w = ####, this.g = null, this.a = Date.now(), this.e = 0, this.T = 255, this.V = null, this.U = Date.now, this.M = new Array(32);
  1119. }
  1120. l.prototype.O = function(A, C, s) {
  1121. for (var t, S, h, i, B, Q, G, D, w, g, a, e, E, T, r, V, U, M, O, c, I; this.T < this.w; )
  1122. try {
  1123. switch (this.T) {
  1124. case 27:
  1125. this.C[this.c] = this.C[this.I] >> this.C[this.F], this.M[12] = 35, this.T = this.T * (this.C.length + (this.M[13] ? 3 : 9)) + 1;
  1126. break;
  1127. case 34:
  1128. this.C[this.c] = this.C[this.I] & this.C[this.F], this.T = this.T * (this.M[15] - 6) + 12;
  1129. break;
  1130. case 41:
  1131. this.C[this.c] = this.C[this.I] <= this.C[this.F], this.T = 8 * this.T + 27;
  1132. break;
  1133. case 48:
  1134. this.C[this.c] = !this.C[this.I], this.T = 7 * this.T + 16;
  1135. break;
  1136. case 50:
  1137. this.C[this.c] = this.C[this.I] | this.C[this.F], this.T = 6 * this.T + 52;
  1138. break;
  1139. case 57:
  1140. this.C[this.c] = this.C[this.I] >>> this.C[this.F], this.T = 7 * this.T - 47;
  1141. break;
  1142. case 64:
  1143. this.C[this.c] = this.C[this.I] << this.C[this.F], this.T = 5 * this.T + 32;
  1144. break;
  1145. case 71:
  1146. this.C[this.c] = this.C[this.I] ^ this.C[this.F], this.T = 6 * this.T - 74;
  1147. break;
  1148. case 78:
  1149. this.C[this.c] = this.C[this.I] & this.C[this.F], this.T = 4 * this.T + 40;
  1150. break;
  1151. case 80:
  1152. this.C[this.c] = this.C[this.I] < this.C[this.F], this.T = 5 * this.T - 48;
  1153. break;
  1154. case 87:
  1155. this.C[this.c] = -this.C[this.I], this.T = 3 * this.T + 91;
  1156. break;
  1157. case 94:
  1158. this.C[this.c] = this.C[this.I] > this.C[this.F], this.T = 4 * this.T - 24;
  1159. break;
  1160. case 101:
  1161. this.C[this.c] = this.C[this.I] in this.C[this.F], this.T = 3 * this.T + 49;
  1162. break;
  1163. case 108:
  1164. this.C[this.c] = o(this.C[this.I]), this.T = 2 * this.T + 136;
  1165. break;
  1166. case 110:
  1167. this.C[this.c] = this.C[this.I] !== this.C[this.F], this.T += 242;
  1168. break;
  1169. case 117:
  1170. this.C[this.c] = this.C[this.I] && this.C[this.F], this.T = 3 * this.T + 1;
  1171. break;
  1172. case 124:
  1173. this.C[this.c] = this.C[this.I] || this.C[this.F], this.T += 228;
  1174. break;
  1175. case 131:
  1176. this.C[this.c] = this.C[this.I] >= this.C[this.F], this.T = 3 * this.T - 41;
  1177. break;
  1178. case 138:
  1179. this.C[this.c] = this.C[this.I] == this.C[this.F], this.T = 2 * this.T + 76;
  1180. break;
  1181. case 140:
  1182. this.C[this.c] = this.C[this.I] % this.C[this.F], this.T += 212;
  1183. break;
  1184. case 147:
  1185. this.C[this.c] = this.C[this.I] / this.C[this.F], this.T += 205;
  1186. break;
  1187. case 154:
  1188. this.C[this.c] = this.C[this.I] * this.C[this.F], this.T += 198;
  1189. break;
  1190. case 161:
  1191. this.C[this.c] = this.C[this.I] - this.C[this.F], this.T += 191;
  1192. break;
  1193. case 168:
  1194. this.C[this.c] = this.C[this.I] + this.C[this.F], this.T = 2 * this.T + 16;
  1195. break;
  1196. case 254:
  1197. this.C[this.c] = eval(i), this.T += 20 < this.M[11] ? 98 : 89;
  1198. break;
  1199. case 255:
  1200. this.s = C || 0, this.M[26] = 52, this.T += this.M[13] ? 8 : 6;
  1201. break;
  1202. case 258:
  1203. g = {};
  1204. for (var F = 0; F < this.k; F++)
  1205. e = this.i.pop(), a = this.i.pop(), g[a] = e;
  1206. this.C[this.W] = g, this.T += 94;
  1207. break;
  1208. case 261:
  1209. this.D = s || [], this.M[11] = 68, this.T += this.M[26] ? 3 : 5;
  1210. break;
  1211. case 264:
  1212. this.M[15] = 16, this.T = "string" == typeof A ? 331 : 336;
  1213. break;
  1214. case 266:
  1215. this.C[this.I][i] = this.i.pop(), this.T += 86;
  1216. break;
  1217. case 278:
  1218. this.C[this.c] = this.C[this.I][i], this.T += this.M[22] ? 63 : 74;
  1219. break;
  1220. case 283:
  1221. this.C[this.c] = eval(String.fromCharCode(this.C[this.I]));
  1222. break;
  1223. case 300:
  1224. S = this.U(), this.M[0] = 66, this.T += this.M[11];
  1225. break;
  1226. case 331:
  1227. D = atob(A), w = D.charCodeAt(0) << 16 | D.charCodeAt(1) << 8 | D.charCodeAt(2);
  1228. for (var k = 3; k < w + 3; k += 3)
  1229. this.G.push(D.charCodeAt(k) << 16 | D.charCodeAt(k + 1) << 8 | D.charCodeAt(k + 2));
  1230. for (V = w + 3; V < D.length; )
  1231. E = D.charCodeAt(V) << 8 | D.charCodeAt(V + 1), T = D.slice(V + 2, V + 2 + E), this.D.push(T), V += E + 2;
  1232. this.M[21] = 8, this.T += 1e3 < V ? 21 : 35;
  1233. break;
  1234. case 336:
  1235. this.G = A, this.D = s, this.M[18] = 134, this.T += this.M[15];
  1236. break;
  1237. case 344:
  1238. this.T = 3 * this.T - 8;
  1239. break;
  1240. case 350:
  1241. U = 66, M = [], I = this.D[this.k];
  1242. for (var W = 0; W < I.length; W++)
  1243. M.push(String.fromCharCode(24 ^ I.charCodeAt(W) ^ U)), U = 24 ^ I.charCodeAt(W) ^ U;
  1244. r = parseInt(M.join("").split("|")[1]), this.C[this.W] = this.i.slice(this.i.length - r), this.i = this.i.slice(0, this.i.length - r), this.T += 2;
  1245. break;
  1246. case 352:
  1247. this.e = this.G[this.s++], this.T -= this.M[26];
  1248. break;
  1249. case 360:
  1250. this.a = S, this.T += this.M[0];
  1251. break;
  1252. case 368:
  1253. this.T -= 500 < S - this.a ? 24 : 8;
  1254. break;
  1255. case 380:
  1256. this.i.push(16383 & this.e), this.T -= 28;
  1257. break;
  1258. case 400:
  1259. this.i.push(this.S[16383 & this.e]), this.T -= 48;
  1260. break;
  1261. case 408:
  1262. this.T -= 64;
  1263. break;
  1264. case 413:
  1265. this.C[this.e >> 15 & 7] = (this.e >> 18 & 1) == 0 ? 32767 & this.e : this.S[32767 & this.e], this.T -= 61;
  1266. break;
  1267. case 418:
  1268. this.S[65535 & this.e] = this.C[this.e >> 16 & 7], this.T -= this.e >> 16 < 20 ? 66 : 80;
  1269. break;
  1270. case 423:
  1271. this.c = this.e >> 16 & 7, this.I = this.e >> 13 & 7, this.F = this.e >> 10 & 7, this.J = 1023 & this.e, this.T -= 255 + 6 * this.J + this.J % 5;
  1272. break;
  1273. case 426:
  1274. this.T += 5 * (this.e >> 19) - 18;
  1275. break;
  1276. case 428:
  1277. this.W = this.e >> 16 & 7, this.k = 65535 & this.e, this.t.push(this.s), this.h.push(this.S), this.s = this.C[this.W], this.S = [];
  1278. for (var J = 0; J < this.k; J++)
  1279. this.S.unshift(this.i.pop());
  1280. this.B.push(this.i), this.i = [], this.T -= 76;
  1281. break;
  1282. case 433:
  1283. this.s = this.t.pop(), this.S = this.h.pop(), this.i = this.B.pop(), this.T -= 81;
  1284. break;
  1285. case 438:
  1286. this.Q = this.C[this.e >> 16 & 7], this.T -= 86;
  1287. break;
  1288. case 440:
  1289. U = 66, M = [], I = this.D[16383 & this.e];
  1290. for (var b = 0; b < I.length; b++)
  1291. M.push(String.fromCharCode(24 ^ I.charCodeAt(b) ^ U)), U = 24 ^ I.charCodeAt(b) ^ U;
  1292. M = M.join("").split("|"), O = parseInt(M.shift()), this.i.push(O === 0 ? M.join("|") : O === 1 ? -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()) : O === true + true ? eval(M.join()) : 3 === O ? null : void 0), this.T -= 88;
  1293. break;
  1294. case 443:
  1295. this.b = this.e >> 2 & 65535, this.J = 3 & this.e, this.J === 0 ? this.s = this.b : this.J === 1 ? !!this.Q && (this.s = this.b) : 2 === this.J ? !this.Q && (this.s = this.b) : this.s = this.b, this.g = null, this.T -= 91;
  1296. break;
  1297. case 445:
  1298. this.i.push(this.C[this.e >> 14 & 7]), this.T -= 93;
  1299. break;
  1300. case 448:
  1301. this.W = this.e >> 16 & 7, this.k = this.e >> 2 & 4095, this.J = 3 & this.e, Q = this.J === 1 && this.i.pop(), G = this.i.slice(this.i.length - this.k, this.i.length), this.i = this.i.slice(0, this.i.length - this.k), c = 2 < G.length ? 3 : G.length, this.T += 6 * this.J + 1 + 10 * c;
  1302. break;
  1303. case 449:
  1304. this.C[3] = this.C[this.W](), this.T -= 97 - G.length;
  1305. break;
  1306. case 455:
  1307. this.C[3] = this.C[this.W][Q](), this.T -= 103 + G.length;
  1308. break;
  1309. case 453:
  1310. B = this.e >> 17 & 3, this.T = B === 0 ? 445 : B === 1 ? 380 : B === true + true ? 400 : 440;
  1311. break;
  1312. case 458:
  1313. this.J = this.e >> 17 & 3, this.c = this.e >> 14 & 7, this.I = this.e >> 11 & 7, i = this.i.pop(), this.T -= 12 * this.J + 180;
  1314. break;
  1315. case 459:
  1316. this.C[3] = this.C[this.W](G[0]), this.T -= 100 + 7 * G.length;
  1317. break;
  1318. case 461:
  1319. this.C[3] = new this.C[this.W](), this.T -= 109 - G.length;
  1320. break;
  1321. case 463:
  1322. U = 66, M = [], I = this.D[65535 & this.e];
  1323. for (var n = 0; n < I.length; n++)
  1324. M.push(String.fromCharCode(24 ^ I.charCodeAt(n) ^ U)), U = 24 ^ I.charCodeAt(n) ^ U;
  1325. M = M.join("").split("|"), O = parseInt(M.shift()), this.T += 10 * O + 3;
  1326. break;
  1327. case 465:
  1328. this.C[3] = this.C[this.W][Q](G[0]), this.T -= 13 * G.length + 100;
  1329. break;
  1330. case 466:
  1331. this.C[this.e >> 16 & 7] = M.join("|"), this.T -= 114 * M.length;
  1332. break;
  1333. case 468:
  1334. this.g = 65535 & this.e, this.T -= 116;
  1335. break;
  1336. case 469:
  1337. this.C[3] = this.C[this.W](G[0], G[1]), this.T -= 119 - G.length;
  1338. break;
  1339. case 471:
  1340. this.C[3] = new this.C[this.W](G[0]), this.T -= 118 + G.length;
  1341. break;
  1342. case 473:
  1343. throw this.C[this.e >> 16 & 7];
  1344. case 475:
  1345. this.C[3] = this.C[this.W][Q](G[0], G[1]), this.T -= 123;
  1346. break;
  1347. case 476:
  1348. this.C[this.e >> 16 & 7] = -1 !== M.join().indexOf(".") ? parseInt(M.join()) : parseFloat(M.join()), this.T -= this.M[21] < 10 ? 124 : 126;
  1349. break;
  1350. case 478:
  1351. t = [0].concat(x(this.S)), this.V = 65535 & this.e, h = this, this.C[3] = function(e2) {
  1352. var n2 = new l();
  1353. return n2.S = t, n2.S[0] = e2, n2.O(h.G, h.V, h.D), n2.C[3];
  1354. }, this.T -= 50 < this.M[3] ? 120 : 126;
  1355. break;
  1356. case 479:
  1357. this.C[3] = this.C[this.W].apply(null, G), this.M[3] = 168, this.T -= this.M[9] ? 127 : 128;
  1358. break;
  1359. case 481:
  1360. this.C[3] = new this.C[this.W](G[0], G[1]), this.T -= 10 * G.length + 109;
  1361. break;
  1362. case 483:
  1363. this.J = this.e >> 15 & 15, this.W = this.e >> 12 & 7, this.k = 4095 & this.e, this.T = 0 === this.J ? 258 : 350;
  1364. break;
  1365. case 485:
  1366. this.C[3] = this.C[this.W][Q].apply(null, G), this.T -= this.M[15] % 2 == 1 ? 143 : 133;
  1367. break;
  1368. case 486:
  1369. this.C[this.e >> 16 & 7] = eval(M.join()), this.T -= this.M[18];
  1370. break;
  1371. case 491:
  1372. this.C[3] = new this.C[this.W].apply(null, G), this.T -= this.M[8] / this.M[1] < 10 ? 139 : 130;
  1373. break;
  1374. case 496:
  1375. this.C[this.e >> 16 & 7] = null, this.T -= 10 < this.M[5] - this.M[3] ? 160 : 144;
  1376. break;
  1377. case 506:
  1378. this.C[this.e >> 16 & 7] = void 0, this.T -= this.M[18] % this.M[12] == 1 ? 154 : 145;
  1379. break;
  1380. default:
  1381. this.T = this.w;
  1382. }
  1383. } catch (A2) {
  1384. this.g && (this.s = this.g), this.T -= 114;
  1385. }
  1386. }, "undefined" != typeof window && (S.__ZH__ = S.__ZH__ || {}, h = S.__ZH__.zse = S.__ZH__.zse || {}, new l().O("ABt7CAAUSAAACADfSAAACAD1SAAACAAHSAAACAD4SAAACAACSAAACADCSAAACADRSAAACABXSAAACAAGSAAACADjSAAACAD9SAAACADwSAAACACASAAACADeSAAACABbSAAACADtSAAACAAJSAAACAB9SAAACACdSAAACADmSAAACABdSAAACAD8SAAACADNSAAACABaSAAACABPSAAACACQSAAACADHSAAACACfSAAACADFSAAACAC6SAAACACnSAAACAAnSAAACAAlSAAACACcSAAACADGSAAACAAmSAAACAAqSAAACAArSAAACACoSAAACADZSAAACACZSAAACAAPSAAACABnSAAACABQSAAACAC9SAAACABHSAAACAC/SAAACABhSAAACABUSAAACAD3SAAACABfSAAACAAkSAAACABFSAAACAAOSAAACAAjSAAACAAMSAAACACrSAAACAAcSAAACABySAAACACySAAACACUSAAACABWSAAACAC2SAAACAAgSAAACABTSAAACACeSAAACABtSAAACAAWSAAACAD/SAAACABeSAAACADuSAAACACXSAAACABVSAAACABNSAAACAB8SAAACAD+SAAACAASSAAACAAESAAACAAaSAAACAB7SAAACACwSAAACADoSAAACADBSAAACACDSAAACACsSAAACACPSAAACACOSAAACACWSAAACAAeSAAACAAKSAAACACSSAAACACiSAAACAA+SAAACADgSAAACADaSAAACADESAAACADlSAAACAABSAAACADASAAACADVSAAACAAbSAAACABuSAAACAA4SAAACADnSAAACAC0SAAACACKSAAACABrSAAACADySAAACAC7SAAACAA2SAAACAB4SAAACAATSAAACAAsSAAACAB1SAAACADkSAAACADXSAAACADLSAAACAA1SAAACADvSAAACAD7SAAACAB/SAAACABRSAAACAALSAAACACFSAAACABgSAAACADMSAAACACESAAACAApSAAACABzSAAACABJSAAACAA3SAAACAD5SAAACACTSAAACABmSAAACAAwSAAACAB6SAAACACRSAAACABqSAAACAB2SAAACABKSAAACAC+SAAACAAdSAAACAAQSAAACACuSAAACAAFSAAACACxSAAACACBSAAACAA/SAAACABxSAAACABjSAAACAAfSAAACAChSAAACABMSAAACAD2SAAACAAiSAAACADTSAAACAANSAAACAA8SAAACABESAAACADPSAAACACgSAAACABBSAAACABvSAAACABSSAAACAClSAAACABDSAAACACpSAAACADhSAAACAA5SAAACABwSAAACAD0SAAACACbSAAACAAzSAAACADsSAAACADISAAACADpSAAACAA6SAAACAA9SAAACAAvSAAACABkSAAACACJSAAACAC5SAAACABASAAACAARSAAACABGSAAACADqSAAACACjSAAACADbSAAACABsSAAACACqSAAACACmSAAACAA7SAAACACVSAAACAA0SAAACABpSAAACAAYSAAACADUSAAACABOSAAACACtSAAACAAtSAAACAAASAAACAB0SAAACADiSAAACAB3SAAACACISAAACADOSAAACACHSAAACACvSAAACADDSAAACAAZSAAACABcSAAACAB5SAAACADQSAAACAB+SAAACACLSAAACAADSAAACABLSAAACACNSAAACAAVSAAACACCSAAACABiSAAACADxSAAACAAoSAAACACaSAAACABCSAAACAC4SAAACAAxSAAACAC1SAAACAAuSAAACADzSAAACABYSAAACABlSAAACAC3SAAACAAISAAACAAXSAAACABISAAACAC8SAAACABoSAAACACzSAAACADSSAAACACGSAAACAD6SAAACADJSAAACACkSAAACABZSAAACADYSAAACADKSAAACADcSAAACAAySAAACADdSAAACACYSAAACACMSAAACAAhSAAACADrSAAACADWSAAAeIAAEAAACAB4SAAACAAySAAACABiSAAACABlSAAACABjSAAACABiSAAACAB3SAAACABkSAAACABnSAAACABrSAAACABjSAAACAB3SAAACABhSAAACABjSAAACABuSAAACABvSAAAeIABEAABCABkSAAACAAzSAAACABkSAAACAAySAAACABlSAAACAA3SAAACAAySAAACAA2SAAACABmSAAACAA1SAAACAAwSAAACABkSAAACAA0SAAACAAxSAAACAAwSAAACAAxSAAAeIABEAACCAAgSAAATgACVAAAQAAGEwADDAADSAAADAACSAAADAAASAAACANcIAADDAADSAAASAAATgADVAAATgAEUAAATgAFUAAATgAGUgAADAAASAAASAAATgADVAAATgAEUAAATgAFUAAATgAHUgAADAABSAAASAAATgADVAAATgAEUAAATgAFUAAATgAIUgAAcAgUSMAATgAJVAAATgAKUgAAAAAADAABSAAADAAAUAAACID/GwQPCAAYG2AREwAGDAABCIABGwQASMAADAAAUAAACID/GwQPCAAQG2AREwAHDAABCIACGwQASMAADAAAUAAACID/GwQPCAAIG2AREwAIDAABCIADGwQASMAADAAAUAAACID/GwQPEwAJDYAGDAAHG2ATDAAIG2ATDAAJG2ATKAAACAD/DIAACQAYGygSGwwPSMAASMAADAACSAAADAABUgAACAD/DIAACQAQGygSGwwPSMAASMAADAACCIABGwQASMAADAABUgAACAD/DIAACQAIGygSGwwPSMAASMAADAACCIACGwQASMAADAABUgAACAD/DIAAGwQPSMAASMAADAACCIADGwQASMAADAABUgAAKAAACAAgDIABGwQBEwANDAAAWQALGwQPDAABG2AREwAODAAODIAADQANGygSGwwTEwAPDYAPKAAACAAESAAATgACVAAAQAAGEwAQCAAESAAATgACVAAAQAAGEwAFDAAASAAADAAQSAAACAAASAAACAKsIAADCAAASAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAAASAAADAAFUgAACAABSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAABSAAADAAFUgAACAACSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAACSAAADAAFUgAACAADSAAADAAQUAAACID/GwQPSMAADAABUAAASAAASAAACAADSAAADAAFUgAADAAFSAAACAAASAAACAJ8IAACEwARDAARSAAACAANSAAACALdIAACEwASDAARSAAACAAXSAAACALdIAACEwATDAARDIASGwQQDAATG2AQEwAUDYAUKAAAWAAMSAAAWAANSAAAWAAOSAAAWAAPSAAAWAAQSAAAWAARSAAAWAASSAAAWAATSAAAWAAUSAAAWAAVSAAAWAAWSAAAWAAXSAAAWAAYSAAAWAAZSAAAWAAaSAAAWAAbSAAAWAAcSAAAWAAdSAAAWAAeSAAAWAAfSAAAWAAgSAAAWAAhSAAAWAAiSAAAWAAjSAAAWAAkSAAAWAAlSAAAWAAmSAAAWAAnSAAAWAAoSAAAWAApSAAAWAAqSAAAWAArSAAAeIAsEAAXWAAtSAAAWAAuSAAAWAAvSAAAWAAwSAAAeIAxEAAYCAAESAAATgACVAAAQAAGEwAZCAAkSAAATgACVAAAQAAGEwAaDAABSAAACAAASAAACAJ8IAACSMAASMAACAAASAAADAAZUgAADAABSAAACAAESAAACAJ8IAACSMAASMAACAABSAAADAAZUgAADAABSAAACAAISAAACAJ8IAACSMAASMAACAACSAAADAAZUgAADAABSAAACAAMSAAACAJ8IAACSMAASMAACAADSAAADAAZUgAACAAASAAADAAZUAAACIAASEAADIAYUEgAGwQQSMAASMAACAAASAAADAAaUgAACAABSAAADAAZUAAACIABSEAADIAYUEgAGwQQSMAASMAACAABSAAADAAaUgAACAACSAAADAAZUAAACIACSEAADIAYUEgAGwQQSMAASMAACAACSAAADAAaUgAACAADSAAADAAZUAAACIADSEAADIAYUEgAGwQQSMAASMAACAADSAAADAAaUgAACAAAEAAJDAAJCIAgGwQOMwAGOBG2DAAJCIABGwQASMAADAAaUAAAEAAbDAAJCIACGwQASMAADAAaUAAAEAAcDAAJCIADGwQASMAADAAaUAAAEAAdDAAbDIAcGwQQDAAdG2AQDAAJSAAADAAXUAAAG2AQEwAeDAAeSAAADAACSAAACALvIAACEwAfDAAJSAAADAAaUAAADIAfGwQQSMAASMAADAAJCIAEGwQASMAADAAaUgAADAAJCIAEGwQASMAADAAaUAAASAAASAAADAAJSAAADAAAUgAADAAJCIABGQQAEQAJOBCIKAAADAABTgAyUAAACIAQGwQEEwAVCAAQDIAVGwQBEwAKCAAAEAAhDAAhDIAKGwQOMwAGOBImDAAKSAAADAABTgAzQAAFDAAhCIABGQQAEQAhOBHoCAAASAAACAAQSAAADAABTgA0QAAJEwAiCAAQSAAATgACVAAAQAAGEwAjCAAAEAALDAALCIAQGwQOMwAGOBLSDAALSAAADAAiUAAADIALSEAADIAAUEgAGwQQCAAqG2AQSMAASMAADAALSAAADAAjUgAA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###VAAATgCEQAABCAB/G2ACSMAAT###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"));
  1387. var D = function(t2) {
  1388. return __g._encrypt(encodeURIComponent(t2));
  1389. };
  1390. exports.XL = A, exports.ZP = D;
  1391. }
  1392. var o = {};
  1393. f1(void 0, o);
  1394. return o.ZP(s);
  1395. }
  1396. var createCommentHeaders = (url) => {
  1397. function K() {
  1398. var t2 = new RegExp("d_c0=([^;]+)").exec(document.cookie);
  1399. return t2 && t2[1];
  1400. }
  1401. var z = function(t2) {
  1402. var e2 = new URL(t2, "https://www.zhihu.com");
  1403. return "" + e2.pathname + e2.search;
  1404. };
  1405. var S2 = function(t2, e2, n2, r2) {
  1406. var o2 = n2.zse93, i2 = n2.dc0, a2 = n2.xZst81, u = z(t2), c2 = "", s2 = [o2, u, i2, "", a2].filter(Boolean).join("+");
  1407. return {
  1408. source: s2,
  1409. signature: zhihu_enc(md5(s2))
  1410. };
  1411. }(url, void 0, {
  1412. zse93: "101_3_3.0",
  1413. dc0: K(),
  1414. xZst81: null
  1415. });
  1416. return {
  1417. "x-zse-93": "101_3_3.0",
  1418. "x-zse-96": "2.0_" + S2.signature
  1419. };
  1420. };
  1421. function formatDataToHump(data) {
  1422. if (!data)
  1423. return data;
  1424. if (Array.isArray(data)) {
  1425. return data.map((item) => {
  1426. return typeof item === "object" ? formatDataToHump(item) : item;
  1427. });
  1428. } else if (typeof data === "object") {
  1429. const nData = {};
  1430. Object.keys(data).forEach((prevKey) => {
  1431. const nKey = prevKey.replace(/\_(\w)/g, (_, $1) => $1.toUpperCase());
  1432. nData[nKey] = formatDataToHump(data[prevKey]);
  1433. });
  1434. return nData;
  1435. }
  1436. return data;
  1437. }
  1438. var requestComment = async ({
  1439. url,
  1440. answerId,
  1441. orderBy = "score",
  1442. offset = "",
  1443. type = "answers"
  1444. }) => {
  1445. if (!answerId && !url)
  1446. return void 0;
  1447. const nUrl = url || `https://www.zhihu.com/api/v4/comment_v5/${type}/${answerId}/root_comment?order_by=${orderBy}&limit=20&offset=${offset}`;
  1448. return fetch(nUrl, {
  1449. method: "GET",
  1450. headers: createCommentHeaders(nUrl)
  1451. }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1452. };
  1453. var requestCommentChild = async ({
  1454. url,
  1455. answerId,
  1456. orderBy = "ts",
  1457. offset = ""
  1458. }) => {
  1459. if (!answerId && !url)
  1460. return void 0;
  1461. const nUrl = url || `https://www.zhihu.com/api/v4/comment_v5/comment/${answerId}/child_comment?order_by=${orderBy}&limit=20&offset=${offset}`;
  1462. return fetch(nUrl, {
  1463. method: "GET",
  1464. headers: createCommentHeaders(nUrl)
  1465. }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1466. };
  1467. var commonRequest = async (url, method = "GET", headers = new Headers()) => {
  1468. if (!url)
  1469. return void 0;
  1470. return fetch(url, { method, headers }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1471. };
  1472. var requestVote = async (contentType, voteType, contentId) => {
  1473. const body = VoteTypeOb[voteType][contentType];
  1474. if (!body)
  1475. return void 0;
  1476. return fetch(`https://www.zhihu.com/api/v4/${contentType}/${contentId}/voters`, {
  1477. method: "POST",
  1478. headers: {
  1479. ...new Headers(),
  1480. "Content-Type": "application/json"
  1481. },
  1482. body
  1483. }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1484. };
  1485. var requestCommentVote = async (commendId, like = true) => {
  1486. if (!commendId)
  1487. return void 0;
  1488. return fetch(`https://www.zhihu.com/api/v4/comments/${commendId}/like`, {
  1489. method: like ? "POST" : "DELETE",
  1490. headers: new Headers()
  1491. }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1492. };
  1493. var requestAnswer = async (answerId) => {
  1494. if (!answerId)
  1495. return void 0;
  1496. const url = `https://www.zhihu.com/api/v4/answers/${answerId}?include=is_visible%2Cpaid_info%2Cpaid_info_content%2Cadmin_closed_comment%2Creward_info%2Cannotation_action%2Cannotation_detail%2Ccollapse_reason%2Cis_normal%2Cis_sticky%2Ccollapsed_by%2Csuggest_edit%2Ccomment_count%2Cthanks_count%2Cfavlists_count%2Ccan_comment%2Ccontent%2Ceditable_content%2Cvoteup_count%2Creshipment_settings%2Ccomment_permission%2Ccreated_time%2Cupdated_time%2Creview_info%2Crelevant_info%2Cquestion%2Cexcerpt%2Cattachment%2Cis_labeled%2Creaction_instruction%2Cip_info%2Crelationship.is_authorized%2Cvoting%2Cis_thanked%2Cis_author%2Cis_nothelp%3Bauthor.vip_info%2Cbadge%5B*%5D.topics%3Bsettings.table_of_content.enabled`;
  1497. return fetch(url, {
  1498. method: "GET",
  1499. headers: createCommentHeaders(url)
  1500. }).then((res) => res.json()).then((res) => formatDataToHump(res));
  1501. };
  1502. var myLoadingToast = {
  1503. open: () => domById("CTZ_LOADING_TOAST").style.display = "flex",
  1504. hide: () => domById("CTZ_LOADING_TOAST").style.display = "none"
  1505. };
  1506. var myPreview = {
  1507. // 开启预览弹窗
  1508. open: function(src, even, isVideo) {
  1509. const nameDom = isVideo ? this.evenPathVideo : this.evenPathImg;
  1510. const idDom = isVideo ? this.idVideo : this.idImg;
  1511. const nodeName = dom(nameDom);
  1512. const nodeId = domById(idDom);
  1513. nodeName && (nodeName.src = src);
  1514. nodeId && (nodeId.style.display = "block");
  1515. even && (this.even = even);
  1516. myScroll.stop();
  1517. },
  1518. // 关闭预览弹窗
  1519. hide: function(pEvent) {
  1520. if (this.even) {
  1521. this.even.click();
  1522. this.even = null;
  1523. }
  1524. pEvent.style.display = "none";
  1525. const nodeImg = dom(this.evenPathImg);
  1526. const nodeVideo = dom(this.evenPathVideo);
  1527. nodeImg && (nodeImg.src = "");
  1528. nodeVideo && (nodeVideo.src = "");
  1529. myScroll.on();
  1530. },
  1531. even: null,
  1532. evenPathImg: "#CTZ_PREVIEW_IMAGE img",
  1533. evenPathVideo: "#CTZ_PREVIEW_VIDEO video",
  1534. idImg: "CTZ_PREVIEW_IMAGE",
  1535. idVideo: "CTZ_PREVIEW_VIDEO"
  1536. };
  1537. var CLASS_BTN_CLOSE = "ctz-n-button-close";
  1538. var CLASS_BTN_COMMENT = "ctz-n-button-comment";
  1539. var CLASS_ACTIVE = "is-active";
  1540. var CLASS_VOTE_UP = "VoteButton--up";
  1541. var CLASS_VOTE_DOWN = "VoteButton--down";
  1542. var addListenImage = (event) => {
  1543. const target = event.target;
  1544. if (target.nodeName === "IMG") {
  1545. let src = target.src;
  1546. if (target.classList.contains("ztext-gif")) {
  1547. src = src.replace(".jpg", ".webp");
  1548. }
  1549. myPreview.open(src);
  1550. return;
  1551. }
  1552. };
  1553. var eventListenButton = (event) => {
  1554. addListenImage(event);
  1555. const target = event.target;
  1556. Object.keys(eventMainObject).forEach((key) => {
  1557. if (target.classList.contains(key)) {
  1558. event.preventDefault();
  1559. event.stopPropagation();
  1560. eventMainObject[key](target);
  1561. }
  1562. });
  1563. };
  1564. var eventMainObject = {
  1565. /** 展开更多 */
  1566. "ContentItem-expandButton": (currentNode) => {
  1567. const nodeRich = domP(currentNode, "class", "RichContent");
  1568. const nodeRichInner = nodeRich.querySelector(".RichContent-inner");
  1569. const nodeBtnOther = nodeRich.querySelector(`.${CLASS_BTN_CLOSE}`);
  1570. const nodeBtnTHis = nodeRich.querySelector(`.ContentItem-expandButton`);
  1571. nodeRich.classList.remove("is-collapsed");
  1572. nodeRichInner.style.maxHeight = "max-content";
  1573. nodeBtnOther.style.display = "block";
  1574. nodeBtnTHis.style.display = "none";
  1575. },
  1576. /** 收起 */
  1577. [CLASS_BTN_CLOSE]: (currentNode) => {
  1578. const nodeRich = domP(currentNode, "class", "RichContent");
  1579. const nodeRichInner = nodeRich.querySelector(".RichContent-inner");
  1580. const nodeBtnOther = nodeRich.querySelector(`.ContentItem-expandButton`);
  1581. const nodeActions = nodeRich.querySelector(".ContentItem-actions");
  1582. const nodeBtnTHis = nodeRich.querySelector(`.${CLASS_BTN_CLOSE}`);
  1583. nodeActions.style.cssText = "";
  1584. nodeRich.classList.add("is-collapsed");
  1585. nodeRichInner.style.maxHeight = "180px";
  1586. nodeBtnOther.style.display = "block";
  1587. nodeBtnTHis.style.display = "none";
  1588. },
  1589. /** 评论 */
  1590. [CLASS_BTN_COMMENT]: async (currentNode) => {
  1591. const nodeContentItem = domP(currentNode, "class", "ContentItem");
  1592. const dataZopJson = nodeContentItem.getAttribute("data-zop") || "{}";
  1593. const dataZop = JSON.parse(dataZopJson);
  1594. myListenComment.create(dataZop.itemId);
  1595. },
  1596. VoteButton: async (currentNode) => {
  1597. const nodeContentItem = domP(currentNode, "class", "ContentItem");
  1598. const contentType = nodeContentItem.querySelector('[itemprop="contentType"]').content;
  1599. const contentId = nodeContentItem.querySelector('[itemprop="contentId"]').content;
  1600. let voteType = 1 /* 中立 */;
  1601. const currentClassList = currentNode.classList;
  1602. if (!currentClassList.contains(CLASS_ACTIVE)) {
  1603. voteType = currentClassList.contains(CLASS_VOTE_UP) ? 0 /* 赞同 */ : 2 /* 反对 */;
  1604. }
  1605. const res = await requestVote(contentType, voteType, contentId);
  1606. if (!res)
  1607. return;
  1608. const { voting } = res;
  1609. nodeContentItem.querySelectorAll(".VoteButton").forEach((item) => {
  1610. item.classList.remove(CLASS_ACTIVE);
  1611. });
  1612. if (typeof voting !== "undefined") {
  1613. voting !== 0 && currentNode.classList.add(CLASS_ACTIVE);
  1614. }
  1615. }
  1616. };
  1617. var openLoading = (box, className) => {
  1618. if (box.querySelector(`.${className}`))
  1619. return;
  1620. box.appendChild(domC("div", { innerHTML: "<span>↻</span>", className }));
  1621. };
  1622. var removeByBox = (box, className) => {
  1623. const nodeFind = box.querySelector(`.${className}`);
  1624. nodeFind && nodeFind.remove();
  1625. };
  1626. var openEnd = (box, className) => {
  1627. if (box.querySelector(`.${className}`))
  1628. return;
  1629. box.appendChild(domC("div", { innerText: "----- 没有更多了 -----", className }));
  1630. };
  1631. var innerHTMLContentItemMeta = (data, options) => {
  1632. const { target } = data;
  1633. const { extraHTML = "", haveTime, config } = options;
  1634. const createdTime = data.createdTime || target.createdTime;
  1635. const updatedTime = data.updatedTime || target.updatedTime;
  1636. return `
  1637. <div class="ContentItem-meta">
  1638. <div class="AuthorInfo AnswerItem-authorInfo AnswerItem-authorInfo--related" itemprop="author" itemscope="" itemtype="http://schema.org/Person">
  1639. <div class="AuthorInfo AuthorInfo--mobile">
  1640. <meta itemprop="name" content="${target.author.name}" />
  1641. <meta itemprop="image" content="${target.author.avatarUrl}" />
  1642. <meta itemprop="url" content="https://www.zhihu.com/people/${target.author.urlToken}" />
  1643. <meta itemprop="zhihu:followerCount" />
  1644. <span class="UserLink AuthorInfo-avatarWrapper">
  1645. <a href="//www.zhihu.com/people/${target.author.urlToken}" target="_blank" class="UserLink-link" data-za-detail-view-element_name="User">
  1646. <img class="Avatar AuthorInfo-avatar" src="${target.author.avatarUrl}" srcset="${target.author.avatarUrl} 2x" alt="${target.author.name}" />
  1647. </a>
  1648. </span>
  1649. <div class="AuthorInfo-content">
  1650. <div class="AuthorInfo-head">
  1651. <span class="UserLink AuthorInfo-name">
  1652. <a href="//www.zhihu.com/people/${target.author.urlToken}" target="_blank" class="UserLink-link" data-za-detail-view-element_name="User">${target.author.name}</a>
  1653. </span>
  1654. </div>
  1655. <div class="AuthorInfo-detail">
  1656. <div class="AuthorInfo-badge"><div class="ztext AuthorInfo-badgeText">${target.author.headline}</div></div>
  1657. </div>
  1658. </div>
  1659. ${extraHTML}
  1660. </div>
  1661. </div>
  1662. ${haveTime ? createTimeHTML(`${createdTime}000`, `${updatedTime}000`) : ""}
  1663. ${config.showIP ? `<div>${target.ipInfo || ""}</div>` : ""}
  1664. <div class="LabelContainer-wrapper"></div>
  1665. </div>
  1666. `;
  1667. };
  1668. var innerHTMLRichInnerAndAction = (data, options) => {
  1669. const { moreLength = 400, moreMaxHeight = "180px" } = options || {};
  1670. const { target } = data;
  1671. const type = target.type;
  1672. const attachment = target.attachment;
  1673. const isVideo = type === "zvideo";
  1674. const isPin = type === "pin";
  1675. const innerHTML = isVideo ? `
  1676. <a
  1677. class="video-box"
  1678. href="https://link.zhihu.com/?target=https%3A//www.zhihu.com/video/${target.thumbnailExtraInfo.videoId}"
  1679. target="_blank"
  1680. data-video-id=""
  1681. data-video-playable=""
  1682. data-name=""
  1683. data-poster="${target.thumbnailExtraInfo.url}"
  1684. data-lens-id="${target.thumbnailExtraInfo.videoId}"
  1685. >
  1686. <img class="thumbnail" src="" />
  1687. <span class="content">
  1688. <span class="title">
  1689. <span class="z-ico-extern-gray"></span>
  1690. <span class="z-ico-extern-blue"></span>
  1691. </span>
  1692. <span class="url">
  1693. <span class="z-ico-video"></span>
  1694. https://www.zhihu.com/video/${target.thumbnailExtraInfo.videoId}
  1695. </span>
  1696. </span>
  1697. </a>
  1698. ` : isPin ? target.contentHtml || target.content : target.content;
  1699. const isMore = isVideo ? true : innerHTML.length > moreLength;
  1700. const vDomContent = domC("div", { innerHTML });
  1701. const styleFrame = "border:none;width: calc(100vw - 32px);height: calc((100vw - 32px)/1.8);";
  1702. vDomContent.querySelectorAll("img").forEach((item) => {
  1703. item.src = item.getAttribute("data-original") || item.getAttribute("data-actualsrc") || item.src || "";
  1704. });
  1705. vDomContent.querySelectorAll("a.video-box").forEach((item) => {
  1706. const nItem = item;
  1707. const nFrame = domC("iframe", {
  1708. style: styleFrame,
  1709. src: nItem.href
  1710. });
  1711. nItem.insertAdjacentElement("afterend", nFrame);
  1712. nItem.style.display = "none";
  1713. });
  1714. let contentHTML = vDomContent.innerHTML;
  1715. vDomContent.remove();
  1716. if (attachment && attachment.type === "video") {
  1717. const { hd, ld, sd } = attachment.video.videoInfo.playlist;
  1718. contentHTML += `
  1719. <div class="VideoAnswerPlayer">
  1720. <div class="VideoAnswerPlayer-video">
  1721. <div class="css-122y91a">
  1722. <div class="css-10klw3m">
  1723. <div class="_1fog6rx">
  1724. <div class="_1n8yr2n" tabindex="-1">
  1725. <div class="_190hxbq">
  1726. <video
  1727. class="_1k7bcr7"
  1728. preload="metadata"
  1729. playsinline=""
  1730. webkit-playsinline=""
  1731. x-webkit-airplay="deny"
  1732. src="${sd.url || ld.url || hd.url}"
  1733. style="object-fit: contain"
  1734. controls=""
  1735. ></video>
  1736. </div>
  1737. </div>
  1738. </div>
  1739. </div>
  1740. </div>
  1741. </div>
  1742. <a role="button" href="https://www.zhihu.com/zvideo/${attachment.video.zvideoId}?playTime=0.0&utm_id=0"
  1743. tabindex="0" aria-label="跳转到对应视频" class="VideoAnswerPlayer-stateBar" target="_blank">
  1744. <div class="VideoAnswerPlayer-state">
  1745. <div class="VideoAnswerPlayer-state--title">${attachment.video.title}</div>
  1746. <div class="VideoAnswerPlayer-state--data">${attachment.video.playCount} 播放 · ${attachment.video.voteupCount} 赞同</div>
  1747. </div>
  1748. </a>
  1749. </div>
  1750. `;
  1751. }
  1752. const voteCount = target.voteupCount || target.voteCount || 0;
  1753. const voting = target.relationship ? target.relationship.voting : 0;
  1754. return `
  1755. <meta itemprop="upvoteCount" content="${voteCount}" />
  1756. <meta itemprop="commentCount" content="${target.commentCount}" />
  1757. <meta itemprop="contentType" content="${CONTENT_TYPE_OBJ[type].voteFetchType}" />
  1758. <meta itemprop="contentId" content="${target.id}" />
  1759. <div class="RichContent ${isMore ? "is-collapsed" : ""} RichContent--unescapable">
  1760. <div class="RichContent-inner RichContent-inner--collapsed" style="${isMore ? `max-height: ${moreMaxHeight}` : ""}">${contentHTML}</div>
  1761. <div class="ContentItem-actions">
  1762. <button aria-label="赞同 ${voteCount}" aria-live="polite" type="button" class="Button VoteButton ${CLASS_VOTE_UP} ${voting === 1 ? CLASS_ACTIVE : ""}">
  1763. 赞同 ${voteCount}
  1764. </button>
  1765. <button aria-label="反对" aria-live="polite" type="button" class="Button VoteButton ${CLASS_VOTE_DOWN} VoteButton--mobileDown ${voting === -1 ? CLASS_ACTIVE : ""}">
  1766. </button>
  1767. <button class="ctz-n-button-comment Button Button--plain Button--withIcon Button--withLabel">评论 ${target.commentCount}</button>
  1768. ${isMore ? '<button class="ctz-n-button-close Button" style="display: none">收起 ▲</button>' : ""}
  1769. </div>
  1770. ${isMore ? '<button class="Button ContentItem-rightButton ContentItem-expandButton Button--plain">展开更多 ▼</button>' : ""}
  1771. </div>
  1772. `;
  1773. };
  1774. var createHTMLCopyLink = (link) => `<button class="ctz-button ctz-button-transparent ${CLASS_COPY_LINK}" data-link="${link}" style="margin: 0px 8px">获取链接</button>`;
  1775. var CONTENT_TYPE_OBJ = {
  1776. answer: {
  1777. name: "问题",
  1778. bTypeClass: "c-ec7259",
  1779. contentItem: "AnswerItem",
  1780. nType: "Answer",
  1781. voteFetchType: "answers" /* 回答 */,
  1782. formatData: (target) => {
  1783. return {
  1784. itemTitle: target.question.title,
  1785. itemHref: `https://www.zhihu.com/question/${target.question.id}`,
  1786. itemHref2: `https://www.zhihu.com/question/${target.question.id}/answer/${target.id}`
  1787. };
  1788. }
  1789. },
  1790. article: {
  1791. name: "文章",
  1792. bTypeClass: "c-00965e",
  1793. contentItem: "ArticleItem",
  1794. nType: "Post",
  1795. voteFetchType: "articles" /* 文章 */,
  1796. formatData: (target) => {
  1797. return {
  1798. itemTitle: target.title,
  1799. itemHref: `https://zhuanlan.zhihu.com/p/${target.id}`,
  1800. itemHref2: `https://zhuanlan.zhihu.com/p/${target.id}`
  1801. };
  1802. }
  1803. },
  1804. zvideo: {
  1805. name: "视频",
  1806. bTypeClass: "c-12c2e9",
  1807. contentItem: "ZVideoItem",
  1808. nType: "ZVideo",
  1809. voteFetchType: "zvideos" /* 视频 */,
  1810. formatData: (target) => {
  1811. return {
  1812. itemTitle: target.title,
  1813. itemHref: `https://www.zhihu.com/zvideo/${target.id}`,
  1814. itemHref2: `https://www.zhihu.com/zvideo/${target.id}`
  1815. };
  1816. }
  1817. },
  1818. pin: {
  1819. name: "想法",
  1820. bTypeClass: "c-9c27b0",
  1821. contentItem: "PinItem",
  1822. nType: "Pin",
  1823. voteFetchType: "",
  1824. formatData: (target) => {
  1825. return {
  1826. itemTitle: target.title || "",
  1827. itemHref: `https://www.zhihu.com/pin/${target.id}`,
  1828. itemHref2: `https://www.zhihu.com/pin/${target.id}`
  1829. };
  1830. }
  1831. }
  1832. };
  1833. var QUERY_LIST = ".ctz-comment-list";
  1834. var CLASS_LOADING = "ctz-comment-loading";
  1835. var ClASS_END = "ctz-comment-end";
  1836. var CLASS_VOTE = "ctz-comment-vote";
  1837. var CLASS_VOTE_UP2 = "ctz-comment-vote-up";
  1838. var ACTIVE_STYLE = "color: rgb(25, 27, 31);background: #fff;";
  1839. var myChangeCommentSort = {
  1840. /** 默认排序 */
  1841. score: () => {
  1842. dom('.ctz-comment-sort>button[name="score"]').style.cssText = ACTIVE_STYLE;
  1843. dom('.ctz-comment-sort>button[name="ts"]').style.cssText = "";
  1844. },
  1845. /** 时间排序 */
  1846. ts: () => {
  1847. dom('.ctz-comment-sort>button[name="ts"]').style.cssText = ACTIVE_STYLE;
  1848. dom('.ctz-comment-sort>button[name="score"]').style.cssText = "";
  1849. }
  1850. };
  1851. var eventVoteUp = async (currentNode) => {
  1852. if (!currentNode.classList.contains(CLASS_VOTE))
  1853. return;
  1854. const prevIsVoteUp = currentNode.classList.contains(CLASS_VOTE_UP2);
  1855. const commendId = currentNode.getAttribute("data-id");
  1856. const res = await requestCommentVote(commendId, !prevIsVoteUp);
  1857. if (!res)
  1858. return;
  1859. const nodeCount = currentNode.querySelector("span");
  1860. const prevCount = +nodeCount.innerText || 0;
  1861. if (prevIsVoteUp) {
  1862. currentNode.classList.remove(CLASS_VOTE_UP2);
  1863. nodeCount.innerText = String(prevCount - 1 >= 0 ? prevCount - 1 : 0);
  1864. } else {
  1865. currentNode.classList.add(CLASS_VOTE_UP2);
  1866. nodeCount.innerText = String(prevCount + 1);
  1867. }
  1868. };
  1869. var myListenComment = {
  1870. page: {
  1871. isEnd: true,
  1872. isStart: true,
  1873. next: "",
  1874. previous: "",
  1875. totals: 0
  1876. },
  1877. commentData: [],
  1878. answerId: void 0,
  1879. initOperate: function() {
  1880. const me = this;
  1881. domById(ID_CTZ_COMMENT)?.addEventListener("click", async (event) => {
  1882. const nodeCurrent = event.target;
  1883. const { id, name } = nodeCurrent;
  1884. if (id === ID_CTZ_COMMENT_CLOSE) {
  1885. dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`).scrollTop = 0;
  1886. domById(ID_CTZ_COMMENT).style.display = "none";
  1887. myScroll.on();
  1888. }
  1889. if (name === "comment-more") {
  1890. const idComment = nodeCurrent.getAttribute("data-id") || void 0;
  1891. const parentComment = me.commentData.find((i2) => `${i2.id}` === `${idComment}`);
  1892. myListenCommentChild.create(idComment, parentComment);
  1893. }
  1894. if (name === "score" || name === "ts") {
  1895. if (nodeCurrent.style.cssText)
  1896. return;
  1897. myChangeCommentSort[name] && myChangeCommentSort[name]();
  1898. me.create(me.answerId, void 0, name);
  1899. }
  1900. eventVoteUp(nodeCurrent);
  1901. });
  1902. dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`).onscroll = throttle(() => {
  1903. const { isEnd, next, totals } = me.page;
  1904. if (isEnd || !next || me.commentData.length >= totals)
  1905. return;
  1906. const nodeContentDiv = dom(`#${ID_CTZ_COMMENT} ${QUERY_LIST}`);
  1907. const bounding = nodeContentDiv.getBoundingClientRect();
  1908. if (bounding.bottom - 100 <= window.innerHeight) {
  1909. openLoading(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), CLASS_LOADING);
  1910. me.commentLoadMore();
  1911. }
  1912. }, 300);
  1913. },
  1914. /** 打开|创建评论弹窗 */
  1915. create: async function(answerId, _, orderBy = "score", type = "answers") {
  1916. myLoadingToast.open();
  1917. this.answerId = answerId;
  1918. const res = await requestComment({ answerId, orderBy, type });
  1919. myLoadingToast.hide();
  1920. if (!res)
  1921. return;
  1922. const nodeComment = domById(ID_CTZ_COMMENT);
  1923. nodeComment.querySelector(".ctz-comment-count>span").innerHTML = `${res.paging.totals}`;
  1924. const innerHTML = res.commentStatus.type ? `<div style="text-align:center;">${res.commentStatus.text}</div>` : createCommentHTML(res.data);
  1925. nodeComment.querySelector(QUERY_LIST).innerHTML = innerHTML;
  1926. myChangeCommentSort[orderBy]();
  1927. removeByBox(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), ClASS_END);
  1928. removeByBox(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), CLASS_LOADING);
  1929. nodeComment.style.display = "flex";
  1930. this.page = res.paging;
  1931. this.commentData = res.data;
  1932. if (res.paging.isEnd) {
  1933. openEnd(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), ClASS_END);
  1934. }
  1935. myScroll.stop();
  1936. },
  1937. /** 评论列表加载更多 */
  1938. commentLoadMore: async function() {
  1939. const res = await requestComment({ url: this.page.next });
  1940. if (!res || !res.data)
  1941. return;
  1942. const nodeCommentContentDiv = dom(`#${ID_CTZ_COMMENT} ${QUERY_LIST}`);
  1943. this.page = res.paging;
  1944. this.commentData = this.commentData.concat(res.data);
  1945. nodeCommentContentDiv.innerHTML += createCommentHTML(res.data);
  1946. removeByBox(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), CLASS_LOADING);
  1947. if (res.paging.isEnd) {
  1948. openEnd(dom(`#${ID_CTZ_COMMENT} .ctz-comment-content`), ClASS_END);
  1949. }
  1950. }
  1951. };
  1952. var myListenCommentChild = {
  1953. page: {
  1954. isEnd: true,
  1955. isStart: true,
  1956. next: "",
  1957. previous: "",
  1958. totals: 0
  1959. },
  1960. commentData: [],
  1961. answerId: void 0,
  1962. initOperate: function() {
  1963. const me = this;
  1964. domById(ID_CTZ_COMMENT_CHILD).addEventListener("click", (event) => {
  1965. const nodeCurrent = event.target;
  1966. if (nodeCurrent.id === ID_CTZ_COMMENT_BACK) {
  1967. dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`).scrollTop = 0;
  1968. domById(ID_CTZ_COMMENT_CHILD).style.display = "none";
  1969. }
  1970. eventVoteUp(nodeCurrent);
  1971. });
  1972. dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`).onscroll = throttle(() => {
  1973. const { isEnd, next, totals } = me.page;
  1974. if (isEnd || !next || me.commentData.length >= totals)
  1975. return;
  1976. const nodeContentDiv = dom(`#${ID_CTZ_COMMENT_CHILD} ${QUERY_LIST}`);
  1977. const bounding = nodeContentDiv.getBoundingClientRect();
  1978. if (bounding.bottom - 100 <= window.innerHeight) {
  1979. openLoading(domById(ID_CTZ_COMMENT_CHILD), CLASS_LOADING);
  1980. me.commentLoadMore();
  1981. }
  1982. }, 300);
  1983. },
  1984. create: async function(answerId, parentData) {
  1985. myLoadingToast.open();
  1986. this.answerId = answerId;
  1987. const res = await requestCommentChild({ answerId });
  1988. myLoadingToast.hide();
  1989. if (!res)
  1990. return;
  1991. const nodeComment = domById(ID_CTZ_COMMENT_CHILD);
  1992. const parentCommentHTML = parentData ? createCommentHTMLItem(parentData, false, false) : "";
  1993. nodeComment.querySelector(QUERY_LIST).innerHTML = parentCommentHTML + `<div class="ctz-comment-child-count">${res.paging.totals} 条回复</div>` + createCommentHTML(res.data);
  1994. removeByBox(dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`), ClASS_END);
  1995. removeByBox(dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`), CLASS_LOADING);
  1996. nodeComment.style.display = "flex";
  1997. this.page = res.paging;
  1998. this.commentData = res.data;
  1999. if (res.paging.isEnd) {
  2000. openEnd(dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`), ClASS_END);
  2001. }
  2002. myScroll.stop();
  2003. },
  2004. commentLoadMore: async function() {
  2005. const res = await requestComment({ url: this.page.next });
  2006. if (!res || !res.data)
  2007. return;
  2008. const nodeCommentContentDiv = dom(`#${ID_CTZ_COMMENT_CHILD} ${QUERY_LIST}`);
  2009. this.page = res.paging;
  2010. this.commentData = this.commentData.concat(res.data);
  2011. nodeCommentContentDiv.innerHTML += createCommentHTML(res.data);
  2012. removeByBox(dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`), CLASS_LOADING);
  2013. if (res.paging.isEnd) {
  2014. openEnd(dom(`#${ID_CTZ_COMMENT_CHILD} .ctz-comment-content`), ClASS_END);
  2015. }
  2016. }
  2017. };
  2018. var createCommentHTML = (data, isChild = false) => data.map((i2) => createCommentHTMLItem(i2, isChild)).join("");
  2019. var createCommentHTMLItem = (item, isChild = false, haveChild = true) => {
  2020. const { author, id, authorTag, content, createdTime, hot, likeCount, childComments = [], childCommentCount, childCommentNextOffset, replyToAuthor } = item;
  2021. const vDomContent = domC("div", { innerHTML: content });
  2022. vDomContent.querySelectorAll(".comment_img").forEach((i2) => {
  2023. const nItem = i2;
  2024. const nImage = domC("img", {
  2025. src: nItem.href,
  2026. style: " margin: 12px 0px 0px; display:block:width: 100px; height: 200px;"
  2027. });
  2028. nItem.insertAdjacentElement("afterend", nImage);
  2029. nItem.style.display = "none";
  2030. });
  2031. const contentHTML = vDomContent.innerHTML;
  2032. vDomContent.remove();
  2033. return `
  2034. <div data-id="${id}">
  2035. <div class="ctz-ci ${isChild ? "ctz-ci-child" : ""}">
  2036. <div class="ctz-ci-avatar">
  2037. <a href="//www.zhihu.com/people/${author.id}" target="_blank"><img class="Avatar" src="${author.avatarUrl}" srcset="${author.avatarUrl}" alt="invalid s" loading="lazy"></a>
  2038. </div>
  2039. <div class="ctz-ci-right">
  2040. <div class="ctz-ci-user">
  2041. <a href="//www.zhihu.com/people/${author.id}" target="_blank">${author.name}</a>
  2042. ${authorTag.map(createUserTagHTML).join("")}
  2043. ${replyToAuthor && replyToAuthor.name ? `<span>‣</span><a href="//www.zhihu.com/people/${replyToAuthor.id}" target="_blank">${replyToAuthor.name}</a>` : ""}
  2044. </div>
  2045. <div class="ctz-ci-content">${contentHTML}</div>
  2046. <div class="ctz-ci-info">
  2047. <div class="ctz-ci-info-left">
  2048. <span>${timeFormatter(+`${createdTime}000`, "YYYY-MM-DD")}</span>
  2049. ${hot ? '<span style="color: rgb(255, 150, 7);font-weight:bold;">热评</span>' : ""}
  2050. </div>
  2051. <div class="ctz-ci-info-right">
  2052. <span class="${CLASS_VOTE} ${item.liked ? CLASS_VOTE_UP2 : ""}" data-id="${id}">❤︎ <span>${likeCount}</span></span>
  2053. </div>
  2054. </div>
  2055. </div>
  2056. </div>
  2057. ${haveChild ? childComments.map((i2) => createCommentHTMLItem(i2, true)).join("") : ""}
  2058. ${haveChild && childCommentCount > childComments.length ? `<button class="ctz-comment-button" name="comment-more" data-next-offset="${childCommentNextOffset}" data-id="${id}">查看全部 ${childCommentCount} 条回复 ➤</button>` : ""}
  2059. </div>`;
  2060. };
  2061. var createUserTagHTML = (item) => {
  2062. const { hasBorder, borderColor, color, text } = item;
  2063. return `<div class="ctz-tag" style="${hasBorder ? `border: 1px solid ${borderColor};` : ""}color: ${color};">${text}</div>`;
  2064. };
  2065. var initOperate = () => {
  2066. const myOperation = {
  2067. [CLASS_INPUT_CLICK]: fnChanger,
  2068. [CLASS_INPUT_CHANGE]: fnChanger,
  2069. "ctz-button": (even) => {
  2070. myButtonOperate[even.name] && myButtonOperate[even.name](even);
  2071. }
  2072. };
  2073. const operation = (even) => {
  2074. const target = even.target;
  2075. const classList = target.classList;
  2076. for (let key in myOperation) {
  2077. classList.contains(key) && myOperation[key](even.target);
  2078. }
  2079. };
  2080. const nodeCTZContent = dom(".ctz-content");
  2081. if (nodeCTZContent) {
  2082. nodeCTZContent.addEventListener("click", operation);
  2083. nodeCTZContent.onchange = operation;
  2084. }
  2085. dom(".ctz-menu").onclick = myMenu.click;
  2086. domA(".ctz-content-top").forEach((i2) => {
  2087. i2.addEventListener("click", myMenu2.click);
  2088. });
  2089. domById("CTZ_OPEN_BUTTON").addEventListener("click", myDialog.open);
  2090. domById("CTZ_CLOSE_DIALOG").addEventListener("click", myDialog.hide);
  2091. myListenComment.initOperate();
  2092. myListenCommentChild.initOperate();
  2093. domById("CTZ_PREVIEW_IMAGE").addEventListener("click", function() {
  2094. myPreview.hide(this);
  2095. });
  2096. document.body.addEventListener("click", function(event) {
  2097. const target = event.target;
  2098. if (target.classList.contains(CLASS_COPY_LINK)) {
  2099. const link = target.getAttribute("data-link");
  2100. copy(link);
  2101. message("链接复制成功");
  2102. }
  2103. });
  2104. dom("#root").addEventListener("click", (event) => {
  2105. eventListenButton(event);
  2106. });
  2107. };
  2108. var Store = class {
  2109. constructor() {
  2110. /** 页面高度 */
  2111. this.pageHeight = 0;
  2112. /** 回答屏蔽的标签 */
  2113. this.hiddenTags = [];
  2114. /** 回答屏蔽的用户 */
  2115. this.hiddenUsers = [];
  2116. this.setPageHeight = this.setPageHeight.bind(this);
  2117. this.getPageHeight = this.getPageHeight.bind(this);
  2118. this.initSetHidden = this.initSetHidden.bind(this);
  2119. this.getHidden = this.getHidden.bind(this);
  2120. }
  2121. setPageHeight(height) {
  2122. this.pageHeight = height;
  2123. }
  2124. getPageHeight() {
  2125. return this.pageHeight;
  2126. }
  2127. async initSetHidden() {
  2128. const config = await myStorage.getConfig();
  2129. const nHiddenTags = Object.keys(HIDDEN_ANSWER_TAG).filter((i2) => !!config[i2]).map((i2) => HIDDEN_ANSWER_TAG[i2]);
  2130. this.hiddenTags = nHiddenTags;
  2131. const nHiddenUsers = Object.keys(HIDDEN_ANSWER_ACCOUNT).filter((i2) => !!config[i2]).map((i2) => HIDDEN_ANSWER_ACCOUNT[i2]);
  2132. config.removeAnonymousAnswer && nHiddenUsers.push("匿名用户");
  2133. this.hiddenUsers = nHiddenUsers;
  2134. }
  2135. getHidden() {
  2136. return {
  2137. hiddenTags: this.hiddenTags,
  2138. hiddenUsers: this.hiddenUsers
  2139. };
  2140. }
  2141. };
  2142. var store = new Store();
  2143. var CLASS_ANSWER_ITEM = "ctz-answer-item";
  2144. var myListenAnswer = {
  2145. isUpdated: false,
  2146. next: "",
  2147. end: false,
  2148. loading: false,
  2149. init: async function() {
  2150. this.isUpdated = /question\/\d+\/answers\/updated/.test(location.pathname);
  2151. const nodeQuestionMain = dom(".Question-main");
  2152. if (!nodeQuestionMain) {
  2153. setTimeout(() => {
  2154. fnLog("未找到 .Question-main, 等待重载...");
  2155. myListenAnswer.init();
  2156. }, 500);
  2157. return;
  2158. }
  2159. const config = await myStorage.getConfig();
  2160. const nodeJsonData = domById("js-initialData");
  2161. if (!nodeJsonData) {
  2162. return;
  2163. }
  2164. const pageJsData = JSON.parse(nodeJsonData.innerText || "{}");
  2165. nodesStopPropagation([".RichContent-inner", ".Question-main figure img", ".Question-main a"], [addListenImage]);
  2166. nodesStopPropagation([".RichContent-inner p"], [], "copy");
  2167. const nodeQuestionAnswerContent = dom(".QuestionAnswer-content");
  2168. if (nodeQuestionAnswerContent) {
  2169. const locArr = location.pathname.split("/");
  2170. const answerId = locArr[4];
  2171. const res = await requestAnswer(answerId);
  2172. if (!res)
  2173. return;
  2174. const nodeQuestionAnswerContent2 = dom(".QuestionAnswer-content");
  2175. nodeQuestionAnswerContent2.innerHTML = createListItemHTML({ target: res, targetType: "answer" }, config);
  2176. if (!dom(".Card.ViewAll")) {
  2177. const questions = pageJsData.initialState.entities.questions;
  2178. const question = questions[Object.keys(questions)[0]];
  2179. const nNode = domC("div", {
  2180. className: "Card ViewAll ViewAll--bottom",
  2181. innerHTML: `<a href="/question/${question.id}" class="QuestionMainAction ViewAll-QuestionMainAction" data-za-detail-view-element_name="ViewAll" style="color: rgb(23, 81, 153);">查看全部 ${question.answerCount || 0} 个回答</a>`
  2182. });
  2183. nNode.setAttribute("data-za-detail-view-path-module", "MessageItem");
  2184. nNode.setAttribute("data-za-extra-module", `{&quot;card&quot;:{&quot;content&quot;:{&quot;item_num&quot;:${question.answerCount || 0}}}}`);
  2185. insertAfter(nNode, nodeQuestionAnswerContent2.parentElement);
  2186. }
  2187. } else {
  2188. const matchArr = location.pathname.match(/question\/(\d+)\/?/);
  2189. const questionId = matchArr && matchArr.length ? matchArr[1] : "";
  2190. const currentQuestion = this.isUpdated ? pageJsData.initialState.question.updatedAnswers[questionId] : pageJsData.initialState.question.answers[questionId];
  2191. if (currentQuestion) {
  2192. const next = currentQuestion.next;
  2193. this.next = next;
  2194. this.end = !next;
  2195. }
  2196. const prevAnswers = pageJsData.initialState.entities.answers;
  2197. const prevDataList = Object.keys(prevAnswers).map((i2) => ({
  2198. target: formatDataToHump(prevAnswers[i2]),
  2199. targetType: "answer"
  2200. }));
  2201. const topCurrentData = prevDataList.pop();
  2202. if (this.isUpdated) {
  2203. const prevListDom = dom(".List div:nth-of-type(2)");
  2204. if (prevListDom) {
  2205. prevListDom.style.display = "none";
  2206. dom(".List").appendChild(domC("div", { className: "List" }));
  2207. }
  2208. }
  2209. const nodeTopList = dom(".List .List");
  2210. if (topCurrentData) {
  2211. if (nodeTopList) {
  2212. nodeTopList.innerHTML = createListItemHTML(topCurrentData, config);
  2213. const nodeLists = domA(".Question-main .List");
  2214. const nodeListContent = nodeLists[nodeLists.length - 1];
  2215. if (prevDataList.length) {
  2216. if (this.isUpdated) {
  2217. nodeListContent.innerHTML += createListHTML(prevDataList, config);
  2218. } else {
  2219. nodeListContent.innerHTML = createListHTML(prevDataList, config);
  2220. }
  2221. }
  2222. } else {
  2223. fnLog("nodeTopList is undefined");
  2224. }
  2225. }
  2226. this.checkListHeight();
  2227. }
  2228. setTimeout(() => {
  2229. const nodeAnswers = domA(".List-item");
  2230. if (nodeAnswers.length && !nodeAnswers[0].classList.contains(CLASS_ANSWER_ITEM)) {
  2231. fnLog("回答内容被覆盖,等待重载...");
  2232. myListenAnswer.init();
  2233. }
  2234. }, 500);
  2235. },
  2236. /** 滚动时回答内容处理 */
  2237. scroll: async function() {
  2238. const nodeAnswers = domA(".ContentItem");
  2239. const windowHeight = window.innerHeight;
  2240. for (let i2 = 0, len = nodeAnswers.length; i2 < len; i2++) {
  2241. const nodeItem = nodeAnswers[i2];
  2242. const nodeClose = nodeItem.querySelector(`.${CLASS_BTN_CLOSE}`);
  2243. if (!nodeClose || nodeClose.style.display === "none")
  2244. continue;
  2245. const bounding2 = nodeItem.getBoundingClientRect();
  2246. const nodeActions = nodeItem.querySelector(".ContentItem-actions");
  2247. if (bounding2.bottom < windowHeight || bounding2.top > windowHeight) {
  2248. if (nodeActions.style.cssText) {
  2249. nodeActions.style.cssText = "";
  2250. }
  2251. continue;
  2252. }
  2253. nodeActions.style.cssText += `position: fixed; bottom: 0; left: 0; width: 100%!important; margin: 0;box-shadow: 0 -1px 3px rgba(25,27,31,0.1);`;
  2254. }
  2255. const nodeLists = domA(".Question-main .List");
  2256. if (!nodeLists.length)
  2257. return;
  2258. const nodeListContent = nodeLists[nodeLists.length - 1];
  2259. const bounding = nodeListContent.getBoundingClientRect();
  2260. if (bounding.bottom - 200 <= window.innerHeight && !this.end && !this.loading) {
  2261. this.requestData(nodeListContent);
  2262. }
  2263. },
  2264. requestData: async function(nodeListContent) {
  2265. if (this.end)
  2266. return;
  2267. this.loading = true;
  2268. openLoading(nodeListContent, "ctz-answer-loading");
  2269. const res = await commonRequest(this.next);
  2270. removeByBox(nodeListContent, "ctz-answer-loading");
  2271. this.loading = false;
  2272. if (!res)
  2273. return;
  2274. fnLog(res);
  2275. const { paging, data } = res;
  2276. if (paging.next === this.next)
  2277. return;
  2278. this.end = paging.isEnd;
  2279. this.next = paging.next;
  2280. const config = await myStorage.getConfig();
  2281. nodeListContent.innerHTML += createListHTML(data, config);
  2282. paging.isEnd && openEnd(nodeListContent, "ctz-answer-end");
  2283. this.checkListHeight();
  2284. },
  2285. /** 检测元素高度 */
  2286. checkListHeight: function() {
  2287. const nodeLists = domA(".Question-main .List");
  2288. if (!nodeLists.length)
  2289. return;
  2290. const nodeListContent = nodeLists[nodeLists.length - 1];
  2291. if (nodeListContent.offsetHeight < window.innerHeight) {
  2292. this.requestData(nodeListContent);
  2293. }
  2294. }
  2295. };
  2296. var createListHTML = (data, config) => data.map((i2) => createListItemHTML(i2, config)).join("");
  2297. var createListItemHTML = (data, config) => {
  2298. const { releaseTimeForAnswer, copyAnswerLink } = config;
  2299. const { targetType, target } = data;
  2300. const { hiddenTags, hiddenUsers } = store.getHidden();
  2301. const answerTopCard = [];
  2302. target.labelInfo && answerTopCard.push(`本回答节选自${target.labelInfo.text}`);
  2303. for (let i2 = 0, len = hiddenTags.length; i2 < len; i2++) {
  2304. if (answerTopCard.join().includes(hiddenTags[i2]))
  2305. return "";
  2306. }
  2307. for (let i2 = 0, len = hiddenUsers.length; i2 < len; i2++) {
  2308. if (target.author.name === hiddenUsers[i2])
  2309. return "";
  2310. }
  2311. let extraHTML = "";
  2312. copyAnswerLink && (extraHTML += createHTMLCopyLink(`https://www.zhihu.com/question/${target.question.id}/answer/${target.id}`));
  2313. return `
  2314. <div class="List-item ${CLASS_ANSWER_ITEM}" tabindex="0">
  2315. <div
  2316. class="ContentItem AnswerItem ctz-self-item"
  2317. data-za-index="0"
  2318. data-zop='{"authorName":"${target.author.name}","itemId":${target.id},"title":"${target.question.title}","type":"${targetType}"}'
  2319. name="${target.id}"
  2320. itemprop="suggestedAnswer"
  2321. itemtype="http://schema.org/Answer"
  2322. itemscope=""
  2323. data-za-detail-view-path-module="AnswerItem"
  2324. data-za-detail-view-path-index="0"
  2325. data-za-extra-module='{"card":{"has_image":false,"has_video":false,"content":{"type":"${targetType}","token":"${target.id}","upvote_num":${target.voteupCount},"comment_num":${target.commentCount},"publish_timestamp":null,"parent_token":"${target.question.id}","author_member_hash_id":"${target.author.id}"}}}'
  2326. >
  2327. ${innerHTMLContentItemMeta(data, {
  2328. haveTime: releaseTimeForAnswer,
  2329. extraHTML,
  2330. config
  2331. })}
  2332. ${answerTopCard.length ? `<div class="KfeCollection-AnswerTopCard-Container">` + answerTopCard.map(
  2333. (i2) => `<div class="KfeCollection-OrdinaryLabel-newStyle-mobile" style="margin-right: 6px;"><div class="KfeCollection-OrdinaryLabel-content">${i2}</div></div>`
  2334. ).join("") + `</div>` : ""}
  2335. ${innerHTMLRichInnerAndAction(data)}
  2336. </div>
  2337. </div>`;
  2338. };
  2339. var fnListenArticle = () => {
  2340. nodesStopPropagation([".RichContent-actions .VoteButton", ".BottomActions-CommentBtn"], [clickCommit]);
  2341. nodesStopPropagation([".Post-content p"], [], "copy");
  2342. };
  2343. var clickCommit = (event) => {
  2344. const target = event.target;
  2345. if (target.classList.contains("BottomActions-CommentBtn")) {
  2346. const id = location.pathname.replace("/p/", "");
  2347. myListenComment.create(id, void 0, void 0, "articles");
  2348. }
  2349. };
  2350. var myListenListRecommend = {
  2351. next: "",
  2352. loading: false,
  2353. init: async function() {
  2354. const nodeTopStoryRecommend = dom(".TopstoryMain") || dom(".NotLoggedInTopstory");
  2355. if (!nodeTopStoryRecommend)
  2356. return;
  2357. const nodeJsonData = domById("js-initialData");
  2358. const config = await myStorage.getConfig();
  2359. if (!nodeJsonData) {
  2360. return;
  2361. }
  2362. const pageJsData = JSON.parse(nodeJsonData.innerText || "{}");
  2363. const next = pageJsData.initialState.topstory.recommend.next;
  2364. this.next = next;
  2365. const currentData = pageJsData.initialState.topstory.recommend.serverPayloadOrigin;
  2366. if (!currentData)
  2367. return;
  2368. const nodeTopstoryMain = dom(".TopstoryMain");
  2369. if (!nodeTopstoryMain)
  2370. return;
  2371. const nodeListContent = nodeTopstoryMain.querySelector('[role="list"]');
  2372. nodeListContent.innerHTML = createListHTML2(formatDataToHump(currentData.data), config);
  2373. },
  2374. scroll: function() {
  2375. const nodeTopstoryMain = dom(".TopstoryMain");
  2376. if (!nodeTopstoryMain)
  2377. return;
  2378. const bounding = nodeTopstoryMain.getBoundingClientRect();
  2379. if (bounding.bottom - 200 <= window.innerHeight && !this.loading) {
  2380. const nodeListContent = nodeTopstoryMain.querySelector('[role="list"]');
  2381. this.requestData(nodeListContent);
  2382. }
  2383. },
  2384. requestData: async function(nodeListContent) {
  2385. this.loading = true;
  2386. openLoading(nodeListContent, "ctz-list-loading");
  2387. const res = await commonRequest(this.next);
  2388. removeByBox(nodeListContent, "ctz-list-loading");
  2389. this.loading = false;
  2390. if (!res)
  2391. return;
  2392. fnLog(res);
  2393. const { paging, data } = res;
  2394. if (paging.next === this.next)
  2395. return;
  2396. this.next = paging.next;
  2397. const config = await myStorage.getConfig();
  2398. nodeListContent.innerHTML += createListHTML2(data, config);
  2399. this.checkListHeight();
  2400. },
  2401. checkListHeight: function() {
  2402. const nodeTopstoryMain = dom(".TopstoryMain");
  2403. if (!nodeTopstoryMain)
  2404. return;
  2405. if (nodeTopstoryMain.offsetHeight < window.innerHeight) {
  2406. const nodeListContent = nodeTopstoryMain.querySelector('[role="list"]');
  2407. this.requestData(nodeListContent);
  2408. }
  2409. }
  2410. };
  2411. var addHistoryItem = async (data) => {
  2412. const { target } = data;
  2413. const type = target.type;
  2414. const { name, bTypeClass, formatData } = CONTENT_TYPE_OBJ[type];
  2415. const pfHistory = await myStorage.getHistory();
  2416. const historyList = pfHistory.list;
  2417. const { itemHref2, itemTitle } = formatData(target);
  2418. let bType = `<b class="${bTypeClass}">「${name}」</b>`;
  2419. const itemA = `<a href="${itemHref2}" target="_blank">${bType + itemTitle}</a>`;
  2420. !historyList.includes(itemA) && historyList.unshift(itemA);
  2421. myStorage.setHistoryItem("list", historyList);
  2422. };
  2423. var createListHTML2 = (data, config) => data.filter((i2) => i2.target).map((i2) => createListItemHTML2(i2, config)).join("");
  2424. var createListItemHTML2 = (data, config) => {
  2425. const { releaseTimeForList, copyAnswerLink, showToAnswer, removeItemAboutVideo, removeItemAboutArticle } = config;
  2426. const { id, target, attachedInfo, brief } = data;
  2427. const type = target.type;
  2428. const { contentItem, nType, formatData } = CONTENT_TYPE_OBJ[type];
  2429. const { itemHref, itemHref2, itemTitle } = formatData(target);
  2430. addHistoryItem(data);
  2431. if (removeItemAboutVideo && type === "zvideo") {
  2432. fnLog("屏蔽视频");
  2433. return "";
  2434. }
  2435. if (removeItemAboutArticle && type === "article") {
  2436. fnLog("屏蔽文章");
  2437. return "";
  2438. }
  2439. let extraHTML = "";
  2440. copyAnswerLink && (extraHTML += createHTMLCopyLink(itemHref2));
  2441. showToAnswer && type === "answer" && (extraHTML += `<a href="${itemHref}" target="_blank" class="ctz-button ctz-button-transparent">直达问题</a>`);
  2442. return `
  2443. <div class="Card TopstoryItem TopstoryItem-isRecommend ctz-recommend-item" tabindex="0">
  2444. <div
  2445. class="Feed"
  2446. data-za-detail-view-path-module="FeedItem"
  2447. data-za-detail-view-path-index="0"
  2448. data-za-extra-module='{"card":{"card_type":"Feed","feed_id":"${id}","has_image":false,"has_video":false,"content":${brief}},"attached_info_bytes":"${attachedInfo}"}'
  2449. >
  2450. <div
  2451. class="ContentItem ${contentItem}"
  2452. data-zop='{"authorName":"${target.author.name}","itemId":${target.id},"title":"${itemTitle}","type":"${type}"}'
  2453. name="${target.id}"
  2454. itemprop="${type}"
  2455. itemtype="http://schema.org/${nType}"
  2456. itemscope=""
  2457. data-za-detail-view-path-module="${contentItem}"
  2458. data-za-detail-view-path-index="4"
  2459. data-za-extra-module='{"card":{"has_image":false,"has_video":false,"content":{"type":"${nType}","token":"${target.id}","upvote_num":${target.voteupCount},"comment_num":${target.commentCount},"publish_timestamp":null,"author_member_hash_id":"${target.author.id}"}}}'
  2460. >
  2461. <h2 class="ContentItem-title">
  2462. <div itemprop="zhihu:${type}" itemtype="http://schema.org/${nType}" itemscope="" style="display:inline;">
  2463. <meta itemprop="url" itemprop="name" content="${itemHref}" />
  2464. <meta content="${itemTitle}"/>
  2465. <a target="_blank" data-za-detail-view-element_name="Title" data-za-detail-view-id="2812" href="${itemHref2}">${itemTitle}</a>
  2466. </div>
  2467. </h2>
  2468. ${innerHTMLContentItemMeta(data, {
  2469. extraHTML,
  2470. haveTime: releaseTimeForList,
  2471. config
  2472. })}
  2473. ${innerHTMLRichInnerAndAction(data, { moreLength: 40, moreMaxHeight: "100px" })}
  2474. </div>
  2475. </div>
  2476. </div>`;
  2477. };
  2478. var addQuestionLogButton = async () => {
  2479. const { showQuestionLog } = await myStorage.getConfig();
  2480. const nodeBtnGroup = dom(".MobileQuestionButtonGroup");
  2481. const className = "ctz-question-log";
  2482. const prevBtn = dom(`.${className}`);
  2483. if (!showQuestionLog || !nodeBtnGroup || prevBtn)
  2484. return;
  2485. const nBtn = domC("button", {
  2486. innerHTML: "查看问题日志",
  2487. className: `ctz-button ctz-button-transparent ${className}`
  2488. });
  2489. nBtn.addEventListener("click", () => {
  2490. const findPath = location.pathname.match(/\/question\/\d+/);
  2491. if (findPath && findPath.length) {
  2492. const nPathname = findPath[0];
  2493. window.open(nPathname + "/log");
  2494. }
  2495. });
  2496. nodeBtnGroup.appendChild(nBtn);
  2497. };
  2498. (function() {
  2499. const { hostname, host, pathname } = location;
  2500. if (!HTML_HOOTS.includes(hostname) || window.frameElement)
  2501. return;
  2502. GM_registerMenuCommand("⚙️ 设置", () => {
  2503. myDialog.open();
  2504. });
  2505. store.initSetHidden();
  2506. async function onDocumentStart() {
  2507. if (!document.head || !document.body) {
  2508. fnLog("not find head and body, waiting for reload...");
  2509. setTimeout(() => {
  2510. fnLog("to reload...");
  2511. onDocumentStart();
  2512. }, 500);
  2513. return;
  2514. }
  2515. fnInitDomStyle("CTZ_STYLE", INNER_CSS);
  2516. addHistoryView();
  2517. onInitStyleExtra();
  2518. EXTRA_CLASS_HTML[host] && dom("html").classList.add(EXTRA_CLASS_HTML[host]);
  2519. initHTML();
  2520. initOperate();
  2521. echoData();
  2522. loadBackground();
  2523. myCustomStyle.init();
  2524. echoHistory();
  2525. setTimeout(() => {
  2526. myListenListRecommend.init();
  2527. }, 0);
  2528. if (host === "zhuanlan.zhihu.com") {
  2529. addTimeForArticle();
  2530. fnListenArticle();
  2531. }
  2532. if (/question/.test(pathname)) {
  2533. addTimeForQuestion();
  2534. addQuestionLogButton();
  2535. setTimeout(() => {
  2536. myListenAnswer.init();
  2537. }, 0);
  2538. }
  2539. const observer = new MutationObserver((MutationRecord) => {
  2540. const addedNode = MutationRecord[0].addedNodes[0];
  2541. const touchClose = (addedNode2) => {
  2542. if (!addedNode2)
  2543. return;
  2544. const domWrapper = addedNode2.querySelector(".MobileModal-wrapper");
  2545. if (!domWrapper)
  2546. return;
  2547. if (domWrapper.innerText.toLowerCase().includes("app")) {
  2548. const buttonClose = domWrapper.querySelector(".Button--secondary.Button--grey");
  2549. if (buttonClose) {
  2550. buttonClose.click();
  2551. setTimeout(() => touchClose(addedNode2), 100);
  2552. }
  2553. }
  2554. };
  2555. touchClose(addedNode);
  2556. });
  2557. observer.observe(document.body, {
  2558. characterData: false,
  2559. attributes: false,
  2560. attributeOldValue: false,
  2561. subtree: false,
  2562. childList: true
  2563. });
  2564. fnLog("function onDocumentStart init");
  2565. }
  2566. onDocumentStart();
  2567. window.addEventListener("load", () => {
  2568. const nodeSignModal = dom(".signFlowModal");
  2569. const nodeSignClose = nodeSignModal && nodeSignModal.querySelector(".Modal-closeButton");
  2570. nodeSignClose && nodeSignClose.click();
  2571. });
  2572. document.addEventListener("copy", function(event) {
  2573. let clipboardData = event.clipboardData || window.clipboardData;
  2574. if (!clipboardData)
  2575. return;
  2576. const selection = window.getSelection();
  2577. let text = selection ? selection.toString() : "";
  2578. if (text) {
  2579. event.preventDefault();
  2580. clipboardData.setData("text/plain", text);
  2581. }
  2582. });
  2583. window.addEventListener(
  2584. "scroll",
  2585. throttle(async () => {
  2586. myListenAnswer.scroll();
  2587. myListenListRecommend.scroll();
  2588. }, 100),
  2589. false
  2590. );
  2591. document.addEventListener("copy", function(event) {
  2592. let clipboardData = event.clipboardData || window.clipboardData;
  2593. if (!clipboardData)
  2594. return;
  2595. const selection = window.getSelection();
  2596. let text = selection ? selection.toString() : "";
  2597. if (text) {
  2598. event.preventDefault();
  2599. clipboardData.setData("text/plain", text);
  2600. }
  2601. });
  2602. })();
  2603. })();