// ==UserScript==
// @name 吉姆的知乎 · iPhone Safari
// @namespace local.jim.zhihu.iphone
// @version 1.44
// @homepageURL https://github.com/kieran107/zhihu-plugin
// @supportURL https://github.com/kieran107/zhihu-plugin/issues
// @updateURL https://raw.githubusercontent.com/kieran107/zhihu-plugin/main/%E5%90%89%E5%A7%86%E7%9A%84%E7%9F%A5%E4%B9%8E-iPhone.meta.js
// @downloadURL https://raw.githubusercontent.com/kieran107/zhihu-plugin/main/%E5%90%89%E5%A7%86%E7%9A%84%E7%9F%A5%E4%B9%8E-iPhone.user.js
// @description 面向 iPhone Safari 桌面网站的知乎阅读脚本:10 条推荐、两行摘要、单篇展开、原图预览、纯观看评论与系统深色模式,无设置弹窗。
// @description:en Zhihu reading layout for iPhone Safari in desktop website mode: 10-item feed, focused answers, original images, read-only comments and system theme.
// @compatible safari Tampermonkey
// @author Jim (kieran107); upstream: lyb233 / liuyubing
// @license MIT
// @match *://*.zhihu.com/*
// @grant unsafeWindow
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @noframes
// @run-at document-start
// ==/UserScript==
/*
MIT License
Copyright (c) lyb233 / liuyubing (upstream Zhihu Custom authors)
Copyright (c) 2026 Jim (kieran107) and contributors (iPhone adaptation)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Upstream: https://github.com/liuyubing233/zhihu-custom (5.21.4)
Reference: https://github.com/liuyubing233/zhihu-custom-mobile (2.9.4)
Changes and attribution: https://github.com/kieran107/zhihu-plugin/blob/main/THIRD_PARTY_NOTICES.md
*/
"use strict";
(() => {
// 预设来源:iPhone知乎-参数.md。由 发布更新.cjs 同步,请勿只改此处。
// BEGIN IPHONE_PRESET
const IPHONE_PRESET = {
"mobile": {
"enabled": true,
"pagePadding": 21,
"openInternalLinksInSameTab": false,
"hideSidebars": true,
"hideOpenApp": true,
"listImageMaxLines": 2,
"answerImageMaxLines": 2,
"floatingCollapse": true,
"readOnlyComments": true,
"compactFeed": true,
"feedBatchSize": 10,
"feedSummaryLines": 2
},
"script": {
"fetchInterceptStatus": true,
"theme": "2",
"themeLight": "8",
"themeDark": "1",
"fontSizeForList": "18",
"fontSizeForAnswer": "20",
"fontSizeForArticle": "18",
"fontSizeForListTitle": "21",
"fontSizeForAnswerTitle": "22",
"fontSizeForArticleTitle": "26",
"contentLineHeight": "33",
"answerOpen": "default",
"homeContentOpen": "0",
"linkShopping": "2",
"replaceZhidaToSearch": "removeLink",
"videoInAnswerArticle": "2",
"hiddenAD": true,
"hiddenQuestionAD": true,
"removeTopAD": true,
"hidden618HongBao": true,
"hiddenReward": true,
"hiddenHomeWriteArea": true,
"hiddenReadMoreText": true,
"hiddenSearchBoxTopSearch": true,
"hiddenSearchPageTopSearch": true,
"hiddenSelectedTextPopup": false,
"removeFromYanxuan": true,
"removeFromEBook": true,
"removeUnrealAnswer": false,
"removeItemAboutVideo": true,
"removeItemAboutArticle": true,
"removeLessVote": true,
"filterKeywords": [
"618",
"华为",
"精华",
"nas",
"新款"
],
"blockWordsAnswer": [],
"questionTitleTag": false,
"listTitleTagQuestion": false,
"listTitleTagArticle": false,
"listTitleTagVideo": false,
"listTitleTagPin": false,
"listItemCreatedAndModifiedTime": false,
"answerItemCreatedAndModifiedTime": false,
"questionCreatedAndModifiedTime": false,
"articleCreateTimeToTop": true,
"copyAnswerLink": false,
"topExportContent": false,
"showBlockUser": false,
"userHomeTopBlockUser": false,
"listOutPutNotInterested": true,
"highPerformanceRecommend": true,
"highPerformanceAnswer": true,
"suspensionPickUp": false,
"zoomImageType": "0",
"showGIFinDialog": false,
"cancelCommentAutoFocus": false,
"clickMarkCloseCommentDialog": true,
"saveHistory": false,
"customizeCss": "",
"hiddenAnswerRightFooter": true,
"hiddenDetailFollow": true,
"removeFollowVoteAnswer": true,
"removeFollowVoteArticle": true,
"removeFollowFQuestion": true,
"removeItemAboutAD": true,
"removeItemAboutPin": true,
"removeItemQuestionAsk": true,
"lessVoteNumber": "100",
"removeLessVoteDetail": false,
"lessVoteNumberDetail": "10",
"removeAnonymousAnswer": false,
"removeMyOperateAtFollow": true,
"suspensionPickupRight": "-50",
"suspensionSwitch": false,
"suspensionSwitchPo": "left: 1160px; top: 129px;",
"suspensionSwitchFollow": true,
"suspensionSwitchDefault": true,
"suspensionSwitchHot": false,
"suspensionSwitchColumnSquare": false,
"suspensionSwitchRingFeeds": false,
"versionHome": "600",
"versionAnswer": "600",
"versionArticle": "600",
"versionHomeIsPercent": false,
"versionHomePercent": "70",
"versionAnswerIsPercent": false,
"versionAnswerPercent": "70",
"versionArticleIsPercent": false,
"versionArticlePercent": "70",
"versionUserHome": "600",
"versionUserHomeIsPercent": false,
"versionUserHomePercent": "70",
"versionCollection": "600",
"versionCollectionIsPercent": false,
"versionCollectionPercent": "70",
"zoomImageSize": "600",
"globalTitle": "知乎",
"titleIco": "",
"fixedListItemMore": false,
"highlightOriginal": false,
"highlightListItem": false,
"zoomListVideoType": "0",
"zoomListVideoSize": "500",
"hotKey": false,
"colorText1": "",
"commitModalSizeSameVersion": true,
"listOutputToQuestion": false,
"userHomeContentTimeTop": false,
"zoomImageHeight": "1",
"zoomImageHeightSize": "541",
"suspensionOpen": "1",
"showBlockUserCommentTag": true,
"showBlockUserTag": true,
"keyEscCloseCommentDialog": true,
"openTagChooseAfterBlockedUser": false,
"removeBlockUserContent": true,
"replaceBlockUserContentWithStar": false,
"blockedUsers": [],
"localBlockedUsers": [],
"notInterestedList": [
"如何看待西门子最新广告【让慢热女滚】?",
"跑步机哪个牌子的好?",
"怎么预防春季花粉过敏呢?",
"怎么提亮肤色,让气色变好?",
"甲流和乙流哪个更严重?",
"断崖式衰老常发生在 3 个年龄段,普通人如何抗衰老?",
"为什么我美白那么久却还是白不了?",
"NBA摇钱树是库里,肖华却为何不捧他成为联盟第一人?",
"晒黑后如何美白?",
"2025 年了,你觉得好长焦还算是 4K+ 旗舰手机的刚需吗?",
"女性应该如何在不焦虑的前提下,优雅且科学地面对衰老?",
"为什么争议不断的 OLED 电视能持续受到市场和用户的欢迎?我们对家用电视的屏幕选购思路应该是什么?",
"有什么节能省钱又健康安全的大容量热水器推荐?格力润之恋空气能热水器值得买吗?",
"如何评价 iQOO 15 将搭载自研「手机显卡」和「机圈大力水手」?",
"Vidda C5无界 Master敢称 “20 万以内最强”,是真有料还是噱头?",
"电视机什么牌子的好?",
"“升起是电影院,降下是歌剧院”,海信卷曲屏激光电视在实际家用场景表现有多震撼?",
"如何看待马伊琍接受采访说女生嫁不出去是因为中国男生太不独立,思想上跟不上女性进步的脚步?",
"为什么这么多人推荐科大讯飞的智能助听器?性价比高吗?",
"40℃ 以上高温热浪频发,什么样的空调不会「热到罢工」? 格力新出的云佳 Pro 值得入手吗?",
"将军在互联网对风评如何?为什么有人说将军在中文互联网上的风评逐渐好转?",
"哪个牌子的护肤品好呀?想给妈妈买一套抗衰老的护肤品?",
"充电五分钟,续航200km?超充「超」在哪里?",
"成都,有啥消息吗,为啥突然这么多人卖房?",
"国外的女生为什么屁股都大?",
"如何看待喜力啤酒加盟赞助苏超?",
"如何看待38岁男子阿红假扮女性约会一千多名男性事件?",
"《北京欢迎你》当时基本去了整个华语乐坛,但为什么最顶尖的刘德华、张学友、周杰伦等没有去?",
"怎样评价波士顿圆脸?",
"如何评价 b站up主 峰哥亡命天涯?",
"如何评价说唱歌手揽佬SKAI ISYOURGOD?",
"如何评价up主“红警hbk08”?",
"苏超这么火,为什么豫超火不起来?",
"如何看待徕芬发布高速直线往复式剃须刀?产品有什么亮点?",
"为什么16-28岁女性对labubu欲罢不能?",
"为什么六大助听器公司不做骨传导助听器?",
"普通人如何才能参观中南海?",
"明明很想学习却总是拖到最后一刻才行动怎么办?",
"法国的数学水平那么强,为什么在 IMO 上的成绩却很一般?",
"如何评价蔡徐坤的新歌《Deadman》?",
"蜂鸟音乐指控邓紫棋侵权,要求 48 小时内下架重录歌曲,邓紫棋回应「不会下架」,这一指控合理吗?",
"你坚持使用美团外卖的理由是什么 ?",
"如何看待亮亮丽君夫妇中的女主又怀孕?"
],
"commentImageFullPage": true,
"suspensionHomeTab": false,
"suspensionHomeTabPo": "left: 20px; top: 100px;",
"suspensionHomeTabFixed": true,
"suspensionFind": false,
"suspensionFindPo": "left: 10px; top: 380px;",
"suspensionFindFixed": true,
"suspensionSearch": false,
"suspensionSearchPo": "left: 10px; top: 400px;",
"suspensionSearchFixed": true,
"suspensionUser": false,
"suspensionUserPo": "right: 60px; top: 100px;",
"suspensionUserFixed": true,
"suspensionOpenUseTop": false,
"suspensionOpenUseLeft": false,
"suspensionOpenLeft": "",
"suspensionOpenRight": "0px",
"suspensionOpenTop": "",
"suspensionOpenBottom": "0",
"globalTitleRemoveMessage": true,
"hiddenHeaderScroll": true,
"hiddenAppHeaderTabHome": true,
"hiddenAppHeaderTabFind": true,
"hiddenAppHeaderTabZhi": true,
"hiddenAppHeaderTabWaitingForYou": true,
"hiddenHomeCreatorEntrance": true,
"hiddenHomeQuanzi": true,
"hiddenYanXuanWriter": true,
"hiddenHomeRecommendFollow": true,
"hiddenHomeCategory": true,
"hiddenHomeCategoryMore": true,
"hiddenHomeFooter": true,
"hiddenHomeListTabVideo": false,
"hiddenListVideoContent": true,
"hiddenListImg": true,
"hiddenZhuanlanAuthorCard": true,
"hiddenUserHomeOtherCard": true,
"hiddenUserHomePublications": true,
"hiddenUserHomeCreateEntrance": true,
"hiddenUserHomeFollow": true,
"hiddenUserHomeLightList": true,
"hiddenUserHomeFooterOperate": true,
"hiddenUserHomeFooter": true,
"hiddenQuestionActions": false,
"hiddenQuestionTag": true,
"hiddenQuestionInvite": true,
"hiddenQuestionAnswer": false,
"hiddenAnswerItemTime": false,
"hiddenAnswerRightFooterAnswerAuthor": false,
"hiddenHeader": true,
"hiddenLogo": true,
"hiddenZhihuZhiShop": true,
"hiddenItemActions": false,
"justNumberInAction": true,
"topVote": true,
"hiddenCommitVote": false,
"hiddenCommitBottom": false,
"hiddenListAnswerInPerson": true,
"hiddenHotItemLabel": true,
"hiddenHotItemIndex": true,
"hiddenHotItemMetrics": true,
"hiddenHotTopNews": true,
"hiddenSearchPageFooter": true,
"hiddenSearchResultZhida": true,
"hiddenQuestionGoodQuestion": true,
"hiddenQuestionMore": true,
"hiddenAnswerRightFooterFavorites": false,
"hiddenAnswerRightFooterRelatedQuestions": false,
"hiddenAnswerRightFooterContentList": false,
"hiddenAnswerRightFooterFooter": false,
"hiddenQuestionComment": true,
"hiddenQuestionSpecial": true,
"hiddenQuestionFollowing": false,
"hiddenQuestionShare": true,
"hiddenQuestionViewAll": false,
"hiddenDetailVoters": true,
"hiddenTopicRightNumberBoard": false,
"hiddenTopicRightParentChild": false,
"hiddenAnswerBelongZhuanlan": true,
"hiddenAnswerKeepAsking": true,
"hiddenAnswerItemTimeButHaveIP": false,
"hiddenThanksInvite": true,
"hiddenAnswerDownTags": true,
"hiddenDetailBadge": false,
"hiddenDetailName": false,
"hiddenDetailAvatar": false,
"hiddenQuestionSide": true,
"hiddenAnswers": false,
"hiddenHeaderFollow": false,
"hiddenHeaderRecommend": false,
"hiddenHeaderHot": false,
"hiddenItemActionsIsFixed": false,
"hiddenItemActionsIsFixedSearch": false,
"hiddenHomeListTab": false,
"hiddenHomeListTabFollow": false,
"hiddenHomeListTabRecommend": false,
"hiddenHomeListTabHot": false,
"hiddenOpenButton": true,
"hiddenHeaderColumnSquare": true,
"hiddenHeaderConsult": true,
"hiddenHeaderEducationLearning": true,
"hiddenItemActionsSearch": false,
"hiddenZhuanlanActions": false,
"hiddenItemActionsCollection": false,
"hiddenHeaderZhida": true,
"hiddenItemActionsIsFixedUser": false,
"hiddenItemActionsUser": false,
"hiddenZhuanlanAvatarWrapper": false,
"hiddenHomeHotSearch": true,
"hiddenHeaderColumnRingFeeds": true,
"hiddenZhuanlanHotSearchCard": true,
"hiddenHeaderSquare": true,
"hiddenHeaderVipWeb": true,
"hiddenWriteArea": true,
"hiddenHomePayAsk": true
}
};
// END IPHONE_PRESET
const isIPhoneLayout = IPHONE_PRESET.mobile.enabled && (
/iPhone|iPod/.test(navigator.userAgent) ||
navigator.maxTouchPoints > 0 && Math.min(screen.width, screen.height) <= 600
);
var syncIPhonePageRoute = () => {
document.documentElement.classList.toggle("jimi-feed-route", isIPhoneLayout && /^\/(?:follow|hot)?$/.test(location.pathname));
document.documentElement.classList.toggle("jimi-profile-route", isIPhoneLayout && /^\/(?:people|org)\/[^/]+(?:\/|$)/.test(location.pathname));
};
// 留住当前文档与回答;用浏览器原生新标签页,避免站内路由先替换阅读页。
var handleIPhoneLinkClick = (event) => {
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
const link = event.target.closest?.("a[href]");
if (!link || link.hasAttribute("download")) return;
let url;
try { url = new URL(link.href, location.href); } catch { return; }
if (!/^https?:$/.test(url.protocol)) return;
if (IPHONE_PRESET.mobile.openInternalLinksInSameTab) {
if (/(^|\.)zhihu\.com$/.test(url.hostname)) link.target = "_self";
return;
}
if (url.hash && url.origin === location.origin && url.pathname === location.pathname && url.search === location.search) return;
link.target = "_blank";
link.relList.add("noopener");
event.stopImmediatePropagation(); // 保留默认打开动作,阻止原生点击路由改写当前页。
};
var initIPhoneLayout = () => {
if (!isIPhoneLayout) return;
window.addEventListener("click", blockIPhoneAnswerTextClick, true);
window.addEventListener("click", handleIPhoneLinkClick, true);
window.addEventListener("click", trackIPhoneCommentAnswer, true);
window.addEventListener("click", trackIPhoneAnswerMotion, true);
// 新触摸或视口改变时让出动画层,阅读与原生滚动优先。
window.addEventListener("touchstart", () => iPhoneAnswerMotion?.cancel(), { passive: true });
window.addEventListener("resize", () => {
iPhoneAnswerMotion?.cancel();
syncIPhoneAutoCollapse(true);
}, { passive: true });
document.documentElement.classList.add("jim-iphone");
syncIPhonePageRoute();
document.documentElement.classList.toggle("jimi-compact-feed", IPHONE_PRESET.mobile.compactFeed);
document.documentElement.classList.toggle("jimi-readonly-comments", IPHONE_PRESET.mobile.readOnlyComments);
const viewportContent = "width=device-width, initial-scale=1, viewport-fit=cover";
const setViewport = () => {
const metas = [...document.head.querySelectorAll('meta[name="viewport"]')];
if (!metas.length) {
const meta = document.createElement("meta");
meta.name = "viewport";
document.head.appendChild(meta);
metas.push(meta);
}
for (const meta of metas) {
if (meta.content !== viewportContent) meta.content = viewportContent;
}
const colors = [...document.head.querySelectorAll('meta[name="theme-color"]')];
if (!colors.length) {
const meta = document.createElement("meta");
meta.name = "theme-color";
document.head.appendChild(meta);
colors.push(meta);
}
const themeColor = getComputedStyle(document.documentElement).getPropertyValue("--jimi-page-bg").trim() ||
(document.documentElement.getAttribute("data-theme") === "dark" ? "#191a1c" : "#faf9f5");
for (const meta of colors) if (meta.content !== themeColor) meta.content = themeColor;
};
// 只响应相关 meta,避免知乎每次插入样式都强制读取布局。
new MutationObserver((changes) => {
const relevant = (node) => node.matches?.('meta[name="viewport"], meta[name="theme-color"]');
if (changes.some(change => relevant(change.target) || [...change.addedNodes, ...change.removedNodes].some(relevant))) setViewport();
}).observe(document.head, {
childList: true, subtree: true, attributes: true, attributeFilter: ["name", "content"]
});
// 复用原作的系统主题监听,浏览器工具栏颜色跟随页面实际主题。
new MutationObserver(setViewport).observe(document.documentElement, {
attributes: true, attributeFilter: ["data-theme"]
});
const { pagePadding, hideSidebars, hideOpenApp } = IPHONE_PRESET.mobile;
const listImageHeight = (Number(IPHONE_PRESET.script.fontSizeForList) || 17) * 1.67 * IPHONE_PRESET.mobile.listImageMaxLines;
const answerImageHeight = (Number(IPHONE_PRESET.script.contentLineHeight) || 31) * IPHONE_PRESET.mobile.answerImageMaxLines;
fnAppendStyle("JIMI_IPHONE_STYLE", `
html.jim-iphone { min-width: 0 !important; -webkit-text-size-adjust: 100%; }
html.jim-iphone body { min-width: 0 !important; margin: 0; width: 100%; }
html.jim-iphone #root { min-width: 0; max-width: 100%; }
html.jim-iphone, html.jim-iphone :is(body, #root, .App-main, .AppHeader, .Topstory,
.Topstory-container, .Topstory-mainColumn, .Topstory-recommend, #TopstoryContent, .ListShortcut) { background: var(--jimi-page-bg) !important; }
html.jim-iphone :is(.Topstory, .Topstory-container, .Topstory-mainColumn,
.Search-container, .SearchMain, .QuestionPage, .Question-main, .Question-mainColumn,
.QuestionHeader, .QuestionHeader-content, .QuestionHeader-main, .QuestionHeader-footer-inner,
.Post-Main, .Post-Row-Content, .Post-Row-Content-left, .Post-NormalMain,
.Post-NormalSub, .Post-NormalSub > div, .Post-content, .Post-RichTextContainer,
.Post-Header, .Post-Title, .Post-Author, .css-pi1fiy,
.Profile-main, .Profile-mainColumn, #ProfileHeader,
.CollectionsDetailPage, .CollectionsDetailPage-mainColumn) {
box-sizing: border-box !important; min-width: 0 !important;
width: 100% !important; max-width: 100% !important;
margin-left: 0 !important; margin-right: 0 !important;
}
html.jim-iphone :is(.Topstory-container, .Question-main, .Post-Row-Content,
.Profile-main, .CollectionsDetailPage) { display: block !important; padding: 0 !important; }
html.jim-iphone :is(.List-item, .TopstoryItem, .QuestionHeader-content,
.QuestionHeader-footer-inner, .Post-RichTextContainer, .Post-Header, .Post-Title, .Post-Author) {
padding-left: max(${pagePadding}px, env(safe-area-inset-left)) !important;
padding-right: max(${pagePadding}px, env(safe-area-inset-right)) !important;
box-sizing: border-box;
}
html.jim-iphone :is(.ContentItem, .RichContent, .RichContent-inner,
.RichText, .ztext, .AuthorInfo-content, .QuestionHeader-main) { min-width: 0; overflow-wrap: anywhere; }
html.jim-iphone .QuestionHeader-content { display: block !important; }
html.jim-iphone .QuestionHeader-tags { display: flex; flex-wrap: wrap; gap: 6px; }
html.jim-iphone .QuestionHeader-side { display: none !important; }
html.jim-iphone :is(.QuestionHeader-main, .QuestionHeader-footer-main) { padding: 0 !important; }
html.jim-iphone :is(.QuestionHeader-footer-main, .QuestionHeader-actions) { flex-wrap: wrap; gap: 8px; }
html.jim-iphone :is(.RichText, .ztext) :is(img, video, iframe, svg, figure) {
max-width: 100% !important; box-sizing: border-box;
}
html.jim-iphone :is(.RichText, .ztext) img { height: auto; }
html.jim-iphone :is(.RichText, .ztext) :is(pre, table) {
display: block; max-width: 100%; overflow-x: auto; overscroll-behavior-x: contain;
}
html.jim-iphone .TitleImage { max-width: 100% !important; height: auto !important; }
/* 列表图与展开正文分别按行高限高;查看大图的浮层不受影响。 */
html.jim-iphone .RichContent-cover { width: 90px; max-width: 30%; margin-left: 10px; }
html.jim-iphone :is(.RichContent-cover, .HotItem-img) {
height: ${listImageHeight}px !important; max-height: ${listImageHeight}px !important;
min-height: 0 !important; overflow: hidden;
}
html.jim-iphone .RichContent-cover-inner { height: 100% !important; padding-top: 0 !important; }
html.jim-iphone :is(.RichContent-cover, .HotItem-img) img {
width: 100% !important; height: 100% !important; max-height: 100% !important; object-fit: contain !important;
}
html.jim-iphone .RichContent.is-collapsed .RichContent-inner :is(figure, .Image-Wrapper-Preview, img:not(.Avatar)) {
height: auto !important; max-height: ${listImageHeight}px !important;
min-height: 0 !important; width: auto !important; object-fit: contain;
}
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichText :is(img:not(.Avatar), .Image-Wrapper-Preview, .RichText-ConditionalImagePortal, .GifPlayer) {
height: auto !important; max-height: ${answerImageHeight}px !important;
min-height: 0 !important; width: auto !important; max-width: 100% !important;
padding-top: 0 !important; padding-bottom: 0 !important; aspect-ratio: auto !important; object-fit: contain;
}
html.jim-iphone .HotItem { padding: 14px ${pagePadding}px !important; min-height: 0; height: auto; align-items: flex-start; gap: 8px; }
html.jim-iphone .HotItem-index { position: static; flex: 0 0 22px; width: 22px; }
html.jim-iphone .HotItem-title { line-height: 1.45; max-height: none; -webkit-line-clamp: 3; }
html.jim-iphone .HotItem-excerpt { display: none; }
html.jim-iphone .HotItem-metrics { position: static; margin-top: 8px; line-height: 1.5; }
html.jim-iphone .HotItem-img { flex: 0 0 86px; }
html.jim-iphone .HotItem-img img { width: 100%; height: 100%; object-fit: cover; }
html.jim-iphone .HotItem-img::after { width: 100% !important; height: 100% !important; }
html.jim-iphone .HotList-list { width: 100%; padding: 0; }
html.jim-iphone .HotItem { margin-left: 0; margin-right: 0; }
html.jim-iphone div:has(> .AppHeader) { position: static !important; height: auto !important; }
html.jim-iphone .App-main { padding-top: 0 !important; margin-top: 0 !important; }
html.jim-iphone .HotItem-content { min-width: 0; }
html.jim-iphone .HotItem-img { width: 86px; height: 70px; margin-left: 10px; }
html.jim-iphone .AppHeader { position: relative !important; height: auto !important; min-width: 0; }
/* 当前桌面页头使用 CSS-in-JS 包装;保留搜索和账户,导航横向滚动。 */
html.jim-iphone .AppHeader > div {
display: grid !important; grid-template-columns: auto minmax(0, 1fr) auto;
width: 100% !important; min-width: 0 !important; height: auto !important;
box-sizing: border-box; padding: 8px ${pagePadding}px 0 !important; gap: 6px 10px;
}
html.jim-iphone .AppHeader :is(.css-51utkw, .css-x84wzl) { display: contents !important; }
html.jim-iphone .AppHeader nav {
grid-column: 1 / -1; grid-row: 2; width: 100%; min-width: 0;
overflow-x: auto; white-space: nowrap; padding: 0 !important;
}
html.jim-iphone .AppHeader nav > a { flex-shrink: 0; min-height: 44px; }
html.jim-iphone .AppHeader .SearchBar { grid-row: 1; grid-column: 2; width: 100% !important; }
html.jim-iphone .AppHeader :is(.css-1vbrp2j, .SearchBar-askContainer, a[href="https://zhida.zhihu.com/"]) { display: none !important; }
html.jim-iphone .AppHeader-inner {
width: 100% !important; min-width: 0 !important; height: auto !important;
padding: 6px ${pagePadding}px !important; box-sizing: border-box;
flex-wrap: wrap !important; gap: 4px 8px;
}
html.jim-iphone .AppHeader .AppHeader-Tabs {
flex: 1 1 100%; order: 3; min-width: 0; margin: 0;
overflow-x: auto; white-space: nowrap; display: flex;
}
html.jim-iphone .AppHeader-Tabs .Tabs-item { flex-shrink: 0; padding: 0 12px; }
html.jim-iphone .AppHeader .SearchBar { flex: 1 1 130px; min-width: 0; }
html.jim-iphone .AppHeader :is(.SearchBar-tool, .SearchBar-input) { width: 100% !important; min-width: 0 !important; }
html.jim-iphone .AppHeader .SearchBar-askButton { display: none !important; }
html.jim-iphone .AppHeader .AppHeader-userInfo { flex: 0 1 auto; margin-left: 0; }
html.jim-iphone :is(.TopstoryTabs, .ProfileMain-tabs, .SearchTabs, .Tabs) {
max-width: 100%; overflow-x: auto; white-space: nowrap;
}
html.jim-iphone .TopstoryTabs-link { flex-shrink: 0; margin: 0 14px !important; }
html.jim-iphone .TopstoryItem .RichContent.is-collapsed .RichContent-inner { max-height: none !important; }
html.jim-iphone .ContentItem-more { min-width: 44px; min-height: 44px; display: inline-flex; align-items: center; }
/* 紧凑列表只改变预览;展开后仍使用知乎原生回答与操作。 */
html.jim-iphone {
color-scheme: light;
--jimi-feed-bg: #faf9f5; --jimi-feed-text: #141413; --jimi-feed-muted: #66645e; --jimi-feed-line: #dedcd3; --jimi-pill-bg: #f0eee6; --jimi-answer-text: #141413;
--jimi-liked: #326b9b; --jimi-focus: #b75c3b; --jimi-comment-open: #a14f33;
--jimi-avatar-gap: #faf9f5; --jimi-avatar-ring: #42413a; --jimi-preview-bg: #141413f0;
--jimi-like-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M7%2010H3v11h4m0-11%204-8h2v6h5a3%203%200%200%201%203%203l-1%207a3%203%200%200%201-3%203H7V10Z%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E");
--jimi-like-icon-filled: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M7%2010H3v11h4m0-11%204-8h2v6h5a3%203%200%200%201%203%203l-1%207a3%203%200%200%201-3%203H7V10Z%22%20fill%3D%22black%22%20stroke%3D%22black%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E");
--jimi-page-bg: var(--jimi-feed-bg); --jimi-feed-canvas: #d8d5cb; --jimi-grid-line: #92908759; --jimi-imprint-ink: #5d5b54;
--jimi-canvas-top: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20400%2096%22%20preserveAspectRatio%3D%22none%22%3E%3Cpath%20fill%3D%22%23d8d5cb%22%20d%3D%22M0%200H400V96H0z%22%2F%3E%3Cpath%20d%3D%22M200%200L0%2096M200%200L20%2096M200%200L40%2096M200%200L60%2096M200%200L80%2096M200%200L100%2096M200%200L120%2096M200%200L140%2096M200%200L160%2096M200%200L180%2096M200%200L200%2096M200%200L220%2096M200%200L240%2096M200%200L260%2096M200%200L280%2096M200%200L300%2096M200%200L320%2096M200%200L340%2096M200%200L360%2096M200%200L380%2096M200%200L400%2096M0.00%2096.00H400.00M34.48%2079.45H365.52M58.82%2067.76H341.18M76.92%2059.08H323.08M90.91%2052.36H309.09M102.04%2047.02H297.96M111.11%2042.67H288.89M118.64%2039.05H281.36M125.00%2036.00H275.00M130.43%2033.39H269.57M135.14%2031.14H264.86M139.24%2029.16H260.76M142.86%2027.43H257.14M146.07%2025.89H253.93M149.19%2024.39H250.81M152.32%2022.89H247.68M155.44%2021.39H244.56M158.57%2019.89H241.43M161.69%2018.39H238.31M164.82%2016.89H235.18M167.94%2015.39H232.06M171.07%2013.89H228.93M174.19%2012.39H225.81M177.32%2010.89H222.68M180.44%209.39H219.56M183.57%207.89H216.43M186.69%206.39H213.31M189.82%204.89H210.18M192.94%203.39H207.06M196.07%201.89H203.93M199.19%200.39H200.81%22%20fill%3D%22none%22%20stroke%3D%22%23929087%22%20stroke-opacity%3D%22.35%22%20stroke-width%3D%22.75%22%20vector-effect%3D%22non-scaling-stroke%22%2F%3E%3C%2Fsvg%3E");
--jimi-bar-bg: #e8e6dc; --jimi-bar-text: #141413; --jimi-bar-liked: #326b9b; --jimi-bar-border: #14141326; --jimi-bar-shadow: 0 0 8px #14141322, 0 0 24px #14141326; --jimi-slot-bg: #d3d0c6; --jimi-slot-shadow: inset 0 8px 10px -3px #1414132e, inset 0 -7px 10px -3px #faf9f5;
--jimi-card-shadow: 0 1px 2px #1414130d, 0 7px 18px -5px #14141326, inset 0 0 0 1px #1414130a;
--jimi-card-focus-shadow: 0 4px 10px #14141310, 0 16px 32px -8px #14141338, inset 0 0 0 1px #14141312;
}
html.jim-iphone[data-theme="dark"] {
color-scheme: dark;
--jimi-feed-bg: #191a1c; --jimi-feed-text: #f1f2f4; --jimi-feed-muted: #adb2ba; --jimi-feed-line: #333; --jimi-pill-bg: #242424; --jimi-answer-text: #e5e7eb;
--jimi-liked: #6aa6ff; --jimi-focus: #06f; --jimi-comment-open: #e4a080;
--jimi-avatar-gap: #fff; --jimi-avatar-ring: #161616; --jimi-preview-bg: rgba(0, 0, 0, .94);
--jimi-feed-canvas: #4b4f55; --jimi-grid-line: #c5c8ce1f; --jimi-imprint-ink: #c5c8ce;
--jimi-canvas-top: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20400%2096%22%20preserveAspectRatio%3D%22none%22%3E%3Cpath%20fill%3D%22%234b4f55%22%20d%3D%22M0%200H400V96H0z%22%2F%3E%3Cpath%20d%3D%22M200%200L0%2096M200%200L20%2096M200%200L40%2096M200%200L60%2096M200%200L80%2096M200%200L100%2096M200%200L120%2096M200%200L140%2096M200%200L160%2096M200%200L180%2096M200%200L200%2096M200%200L220%2096M200%200L240%2096M200%200L260%2096M200%200L280%2096M200%200L300%2096M200%200L320%2096M200%200L340%2096M200%200L360%2096M200%200L380%2096M200%200L400%2096M0.00%2096.00H400.00M34.48%2079.45H365.52M58.82%2067.76H341.18M76.92%2059.08H323.08M90.91%2052.36H309.09M102.04%2047.02H297.96M111.11%2042.67H288.89M118.64%2039.05H281.36M125.00%2036.00H275.00M130.43%2033.39H269.57M135.14%2031.14H264.86M139.24%2029.16H260.76M142.86%2027.43H257.14M146.07%2025.89H253.93M149.19%2024.39H250.81M152.32%2022.89H247.68M155.44%2021.39H244.56M158.57%2019.89H241.43M161.69%2018.39H238.31M164.82%2016.89H235.18M167.94%2015.39H232.06M171.07%2013.89H228.93M174.19%2012.39H225.81M177.32%2010.89H222.68M180.44%209.39H219.56M183.57%207.89H216.43M186.69%206.39H213.31M189.82%204.89H210.18M192.94%203.39H207.06M196.07%201.89H203.93M199.19%200.39H200.81%22%20fill%3D%22none%22%20stroke%3D%22%23c5c8ce%22%20stroke-opacity%3D%22.12%22%20stroke-width%3D%22.75%22%20vector-effect%3D%22non-scaling-stroke%22%2F%3E%3C%2Fsvg%3E");
--jimi-bar-bg: #2e3034; --jimi-bar-text: #faf9f5; --jimi-bar-liked: #83b2f3; --jimi-bar-border: #e8e6dc33; --jimi-bar-shadow: 0 0 8px #000b, 0 0 24px #000d; --jimi-slot-bg: #101113; --jimi-slot-shadow: inset 0 8px 10px -3px #000b, inset 0 -7px 10px -3px #ffffff0d;
--jimi-card-shadow: 0 2px 4px #0005, 0 8px 20px -4px #0008, inset 0 0 0 1px #ffffff0d;
--jimi-card-focus-shadow: 0 4px 10px #0004, 0 18px 36px -8px #000a, inset 0 0 0 1px #ffffff14;
}
/* 暖纸配色来源见 THIRD_PARTY_NOTICES.md;补齐原生正文和弹层的冷白/冷灰色。 */
html.jim-iphone[data-theme="light"] :is(body, .ContentItem-title, .QuestionHeader-title, .Post-Title, .RichText) { color: var(--jimi-feed-text) !important; }
html.jim-iphone[data-theme="light"] :is(.ContentItem-time, .ContentItem-time a, .Voters, .Voters button) { color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme="light"] .RichText :is(blockquote, hr, table, th, td) { border-color: var(--jimi-feed-line) !important; }
html.jim-iphone[data-theme="light"] .RichText :is(blockquote, pre, code) { background-color: var(--jimi-pill-bg) !important; color: var(--jimi-feed-text) !important; }
html.jim-iphone[data-theme="light"] :is(.PlaceHolder-inner, .PlaceHolder-bg, .skeleton) { background: var(--jimi-pill-bg) !important; }
html.jim-iphone[data-theme="light"] :is(.Modal-backdrop, .css-zbtg51 > .css-5ym188) { background: #141413a6 !important; }
html.jim-iphone[data-theme="light"] ::selection { background: #d9775733; color: var(--jimi-feed-text); }
html.jim-iphone.jimi-compact-feed:is(.jimi-feed-route, .jimi-profile-route, :has(.Topstory)) { --jimi-page-bg: var(--jimi-feed-canvas); }
/* Safari 顶栏需要可取色的实色 fixed 元素;12px 高于其细边框过滤阈值,伪元素底板仍负责完整纹理。 */
html.jim-iphone #JIMI_SAFARI_TINT {
position: fixed; top: 0; left: 0; right: 0; height: 12px; z-index: 1;
background: var(--jimi-page-bg); pointer-events: none;
}
/* 取色层只垫底,滚动正文必须能盖住它,避免顶部残留 12px 塔尖。 */
html.jim-iphone .App-main { position: relative; z-index: 2; }
html.jim-iphone.jimi-compact-feed:is(.jimi-feed-route, :has(.Topstory)) #JIMI_SAFARI_TINT {
background-image: var(--jimi-canvas-top); background-size: 100% 96px; background-repeat: no-repeat;
}
html.jim-iphone.jimi-compact-feed :is(.Topstory, .App-main > div:has(> #ProfileHeader)) {
position: relative; isolation: isolate;
--jimi-grid-size: calc(100vw / 20);
--jimi-grid-tail: mod(calc(100% - 96px), var(--jimi-grid-size));
}
html.jim-iphone.jimi-compact-feed .Topstory-mainColumnCard { box-shadow: none !important; }
/* 横线按透视递密,但最小间距为 1.5px,继续画到尖端;不截断、不填灰,避免空白与混叠。 */
html.jim-iphone.jimi-compact-feed :is(.Topstory, .App-main > div:has(> #ProfileHeader))::before {
content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
box-shadow: inset 0 -1px 0 var(--jimi-grid-line);
bottom: var(--jimi-grid-tail);
background:
var(--jimi-canvas-top) center top / 100% 96px no-repeat,
linear-gradient(to right, var(--jimi-grid-line) .75px, transparent .75px) 0 96px / var(--jimi-grid-size) var(--jimi-grid-size),
linear-gradient(to bottom, var(--jimi-grid-line) .75px, transparent .75px) 0 96px / var(--jimi-grid-size) var(--jimi-grid-size) var(--jimi-page-bg);
}
html.jim-iphone.jimi-compact-feed .Topstory :is(.Topstory-container, .Topstory-mainColumn,
.Topstory-mainColumnCard, .Topstory-content, .Topstory-recommend, .Topstory-follow, #TopstoryContent,
.ListShortcut, .jimi-feed-intro, .jimi-feed-outro) { background: transparent !important; }
html.jim-iphone.jimi-compact-feed .Topstory-container { margin-top: 0 !important; padding-top: 12px !important; }
html.jim-iphone.jimi-compact-feed .Topstory-container:has(.Topstory-recommend) { padding-top: 0 !important; }
html.jimi-compact-feed :is(.jimi-feed-intro, .jimi-feed-outro) {
box-sizing: border-box; background: var(--jimi-page-bg); text-align: center;
color: var(--jimi-feed-muted); padding: 20px 27px; margin: 0;
display: none; align-items: center; justify-content: center;
}
html.jimi-compact-feed .jimi-feed-intro:has(+ .Topstory-recommend) { display: block; height: 240px; padding: 0; pointer-events: none; }
/* 首尾只占位,文字印在底板层,让实色卡片从上方经过。 */
html.jimi-compact-feed .jimi-feed-intro :is(.jimi-feed-imprint, .jimi-feed-refresh-hint),
html.jimi-compact-feed .jimi-feed-outro > span {
position: fixed; left: 0; right: 0; z-index: -1; pointer-events: none; user-select: none;
display: flex; align-items: center; justify-content: center; color: var(--jimi-imprint-ink);
}
html.jimi-compact-feed .jimi-feed-imprint { top: 96px; height: 144px; flex-direction: column; gap: 6px; }
html.jimi-compact-feed .jimi-feed-refresh-hint { top: 42px; flex-direction: column; gap: 2px; margin: 0; font-size: 14px; line-height: 22px; }
html.jimi-compact-feed .jimi-feed-refresh-hint span { font-size: 20px; }
html.jimi-compact-feed .jimi-feed-brand { margin: 0; color: inherit; font-size: 42px; line-height: 1.25; font-weight: 650; letter-spacing: 1px; }
html.jimi-compact-feed .jimi-feed-tagline { margin: 0; font-size: 18px; line-height: 26px; letter-spacing: 2px; }
html.jimi-compact-feed .jimi-feed-outro > span { bottom: var(--jimi-grid-tail); height: 120px; }
@media (prefers-reduced-motion: reduce) {
html.jim-iphone #JIMI_SAFARI_TINT { background-image: none !important; }
html.jim-iphone.jimi-compact-feed :is(.Topstory, .App-main > div:has(> #ProfileHeader))::before,
html.jimi-compact-feed .jimi-feed-intro :is(.jimi-feed-imprint, .jimi-feed-refresh-hint),
html.jimi-compact-feed .jimi-feed-outro > span { position: absolute; }
}
html.jimi-compact-feed .Topstory-recommend.jimi-batch-full + .jimi-feed-outro { display: flex; height: 120px; font-size: 13px; line-height: 20px; letter-spacing: 1px; }
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem) {
margin: 0 12px 12px !important;
padding: 12px max(15px, calc(env(safe-area-inset-left) - 12px)) 12px max(15px, calc(env(safe-area-inset-right) - 12px)) !important;
border: 0 !important;
border-radius: 18px !important; box-shadow: var(--jimi-card-shadow) !important; background: var(--jimi-feed-bg) !important;
position: relative; overflow: visible !important; transition: transform 520ms cubic-bezier(.4, 0, .2, 1);
}
/* 阴影形状保持不变,只渐变透明度,避免逐帧插值长卡片的模糊阴影。 */
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem)::after {
content: ""; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
box-shadow: var(--jimi-card-focus-shadow); opacity: 0;
transition: opacity 520ms cubic-bezier(.4, 0, .2, 1);
}
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.jimi-reading-answer > .RichContent:not(.is-collapsed))::after { opacity: 1; }
/* 用前后卡片位移拉开视觉间距,不逐帧改变长回答高度或外边距。 */
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem):has(~ :is(.TopstoryItem, .jimi-profile-item) .jimi-reading-answer > .RichContent:not(.is-collapsed)) { transform: translateY(-24px); }
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.jimi-reading-answer > .RichContent:not(.is-collapsed)) ~ :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem) { transform: translateY(24px); }
/* 动画只作用于视口内的独立底框、裁切和透明度,不插值正文布局高度。 */
.jimi-answer-surface {
position: fixed; pointer-events: none; z-index: 1000; border-radius: 18px;
background: var(--jimi-feed-bg); box-shadow: var(--jimi-card-shadow);
contain: layout style; margin: 0; padding: 0;
}
.jimi-answer-surface::after {
content: ""; position: absolute; inset: 0; border-radius: inherit;
box-shadow: var(--jimi-card-focus-shadow); opacity: var(--jimi-surface-shadow, 0);
}
html.jim-iphone.jimi-answer-changing :is(.TopstoryItem, .jimi-profile-item).jimi-answer-morph {
z-index: 1001; background: transparent !important; box-shadow: none !important;
}
html.jim-iphone :is(.TopstoryItem, .jimi-profile-item).jimi-answer-morph::after { opacity: 0 !important; }
html.jim-iphone:is(.jimi-answer-changing, .jimi-answer-instant) :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem),
html.jim-iphone:is(.jimi-answer-changing, .jimi-answer-instant) :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem)::after { transition: none; }
@media (prefers-reduced-motion: reduce) {
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem),
html.jim-iphone.jimi-compact-feed :is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem)::after { transition: none; }
}
html.jimi-compact-feed :is(.TopstoryItem, .Profile-main .List-item):has(.AnswerItem > .RichContent.is-collapsed .ContentItem-more):not(.jimi-feed-item) { visibility: hidden; }
html.jimi-compact-feed .jimi-feed-answer { padding-bottom: 0; border-bottom: 0; }
html.jim-iphone .AnswerItem.jimi-read-answer:has(> .RichContent.is-collapsed) { opacity: .55; }
html.jimi-compact-feed .jimi-feed-item :is(.FeedSource, .TopstoryItem-topic) { display: none !important; }
html.jimi-compact-feed .jimi-feed-answer:has(> .RichContent.is-collapsed) > :is(.ContentItem-title, .ContentItem-meta, .AnswerItem-authorInfo, .RichContent) { display: none !important; }
html.jimi-compact-feed .jimi-feed-preview { display: none; }
html.jimi-compact-feed .jimi-feed-answer:has(> .RichContent.is-collapsed) > .jimi-feed-preview {
display: block; width: 100%; min-height: 44px; border: 0; padding: 0; margin: 0;
background: transparent !important; color: var(--jimi-feed-text); text-align: left;
font: inherit; cursor: pointer; touch-action: manipulation; -webkit-appearance: none;
}
html.jimi-compact-feed .jimi-feed-preview:focus-visible { outline: 2px solid var(--jimi-focus); outline-offset: 5px; border-radius: 4px; }
html.jimi-compact-feed .jimi-feed-preview:active { opacity: .65; }
html.jimi-compact-feed .jimi-feed-title {
display: block; font-size: ${IPHONE_PRESET.script.fontSizeForListTitle}px; font-weight: 600;
line-height: 1.4; overflow-wrap: anywhere; color: var(--jimi-feed-text) !important;
}
html.jimi-compact-feed .jimi-feed-excerpt {
display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: ${IPHONE_PRESET.mobile.feedSummaryLines};
margin-top: 8px; font-size: ${IPHONE_PRESET.script.fontSizeForList}px; font-weight: 400;
line-height: 1.5; color: var(--jimi-feed-muted) !important; overflow: hidden; overflow-wrap: anywhere;
}
html.jimi-compact-feed .jimi-feed-excerpt:empty { display: none; }
html.jimi-compact-feed .jimi-feed-meta {
display: flex; align-items: center; gap: 7px; margin-top: 10px; min-width: 0;
font-size: 14px; font-weight: 400; line-height: 24px; color: var(--jimi-feed-muted) !important;
}
html.jimi-compact-feed .jimi-feed-avatar { width: 24px !important; height: 24px !important; flex: 0 0 24px; border-radius: 50%; object-fit: cover; }
html.jimi-compact-feed .jimi-feed-avatar[hidden] { display: none !important; }
html.jimi-compact-feed .jimi-feed-author { min-width: 0; max-width: 60%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
html.jimi-compact-feed .jimi-feed-votes { flex: 0 0 auto; white-space: nowrap; }
html.jimi-compact-feed .jimi-feed-votes:empty { display: none; }
html.jimi-compact-feed .jimi-feed-item .ContentItem-title { margin: 0 0 14px; line-height: 1.45; font-weight: 600; }
html.jimi-compact-feed .jimi-feed-item .ContentItem-title > div { display: inline; }
html.jim-iphone .AnswerItem .ContentItem-title .jimi-not-interested {
display: inline-block; float: none; border: 0 !important; border-radius: 0; padding: 0 !important;
min-height: 24px !important; background: transparent !important; box-shadow: none !important;
color: var(--jimi-feed-muted) !important; font-size: 13px !important; font-weight: 400;
line-height: inherit; vertical-align: 3px; text-decoration: underline; text-underline-offset: 3px;
}
html.jim-iphone .AnswerItem:has(> .RichContent:not(.is-collapsed)) > :is(.ContentItem-meta, .AnswerItem-authorInfo),
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) :is(.Voters, .css-dvccr2) { display: none !important; }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner .RichText :is(a, a *, .highlight-wrap, [data-highlight-id]) {
color: inherit !important; text-decoration: none !important; border-bottom: 0 !important;
background: transparent !important; box-shadow: none !important; cursor: text !important;
}
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner .RichText :is(a, .highlight-wrap, [data-highlight-id])::after,
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner .RichText :is(a, .highlight-wrap, [data-highlight-id])::before,
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner .RichContent-EntityWord svg { display: none !important; }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-time { display: block !important; }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-time > a { display: block; }
html.jim-iphone .jimi-answer-ip { display: block; color: var(--jimi-feed-muted); }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner { font-size: ${IPHONE_PRESET.script.fontSizeForAnswer}px !important; }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner :is(.RichText, blockquote) { color: var(--jimi-answer-text) !important; line-height: ${IPHONE_PRESET.script.contentLineHeight}px !important; }
html.jim-iphone .jimi-batch-extra,
html.jim-iphone .Topstory-recommend.jimi-batch-full > :not(.TopstoryItem) { display: none !important; }
html.jim-iphone .Topstory-container:has(.jimi-batch-full) { margin-bottom: 0 !important; }
html.jim-iphone :is(.jimi-iphone-collapse, .jimi-action-dock) { display: none; }
html.jim-iphone .RichContent:not(.is-collapsed):has(> .jimi-action-dock) { position: relative; padding-bottom: 2px; }
html.jim-iphone .RichContent:not(.is-collapsed) > .jimi-action-dock {
display: block; position: absolute; bottom: 0; left: -2px; right: -2px; height: 64px; border-radius: 20px;
background: var(--jimi-slot-bg); box-shadow: var(--jimi-slot-shadow);
scroll-margin-top: max(12px, env(safe-area-inset-top)); pointer-events: none;
}
/* 外壳属于当前正文,上界留出两行;原生按钮仍在 React 原位置,sticky 到文末自然归位。 */
html.jim-iphone .RichContent:not(.is-collapsed) > .jimi-action-host {
position: sticky; bottom: max(12px, env(safe-area-inset-bottom)); z-index: 3;
height: 60px; margin: ${Number(IPHONE_PRESET.script.contentLineHeight) * 2}px 0 0; padding: 0; overflow: visible;
}
/* 只压缩发布时间后的留白,保留 sticky 上界的两行高度与槽内 2px 窄边。 */
html.jim-iphone .RichContent:not(.is-collapsed):has(> .jimi-action-dock) > :is(.ContentItem-time, :has(> .ContentItem-time)) {
margin-bottom: calc(1px - ${Number(IPHONE_PRESET.script.contentLineHeight)}px) !important;
}
html.jim-iphone :is(.ContentItem-actions, .RichContent-actions) {
box-sizing: border-box; max-width: 100%; width: auto !important;
padding-left: 0 !important; padding-right: 0 !important;
margin-left: 0 !important; margin-right: 0 !important;
}
html.jim-iphone .AnswerItem .ContentItem-actions {
position: static !important; inset: auto !important; transform: none !important;
transition: none !important; animation: none !important;
}
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-actions > :not(.jimi-answer-author):not(.jimi-iphone-collapse):not(:has(.VoteButton)):not(:has(.Zi--Comment, .ZDI--ChatBubbleFill24)),
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-actions .VoteButton--down,
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-actions + .Sticky--holder { display: none !important; }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-actions {
display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0;
width: 100% !important; height: 60px !important; padding: 5px !important; margin: 0 !important;
border: 1px solid var(--jimi-bar-border) !important; border-radius: 18px; overflow: visible;
background: var(--jimi-bar-bg) !important; box-shadow: var(--jimi-bar-shadow) !important;
}
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) > .ContentItem-actions.jimi-action-host {
position: sticky !important; bottom: max(12px, env(safe-area-inset-bottom)) !important; margin-top: ${Number(IPHONE_PRESET.script.contentLineHeight) * 2}px !important;
}
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed):not(:has(button[data-zop-retract-question="true"])) .ContentItem-actions { grid-template-columns: repeat(3, minmax(0, 1fr)); }
html.jim-iphone .AnswerItem > .RichContent:not(.is-collapsed) .ContentItem-actions > :is(.jimi-answer-author, .jimi-iphone-collapse, :has(.VoteButton), :has(.Zi--Comment, .ZDI--ChatBubbleFill24)) {
grid-row: 1; box-sizing: border-box; min-width: 0; width: 100%; height: 48px; margin: 0 !important;
padding: 0 4px; border: 0 !important; border-radius: 12px;
background: transparent !important; color: var(--jimi-bar-text); box-shadow: none;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
html.jim-iphone .AnswerItem .ContentItem-actions > :has(.VoteButton) { grid-column: 2; }
html.jim-iphone .AnswerItem .ContentItem-actions > :has(.Zi--Comment, .ZDI--ChatBubbleFill24) { grid-column: 3; }
html.jim-iphone .AnswerItem .ContentItem-actions > :has(.VoteButton) > span { display: block; height: 100%; }
html.jim-iphone .AnswerItem .ContentItem-actions :is(.VoteButton:not(.VoteButton--down), button:has(.Zi--Comment, .ZDI--ChatBubbleFill24), .jimi-iphone-collapse) {
display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 0;
box-sizing: border-box; width: 100%; height: 48px; min-height: 44px !important; margin: 0; padding: 0 4px;
border: 0 !important; border-radius: 12px; background: transparent !important;
color: var(--jimi-bar-text); font-size: 0; line-height: 0; cursor: pointer; touch-action: manipulation;
}
html.jim-iphone .AnswerItem .ContentItem-actions :is(.VoteButton, button:has(.Zi--Comment, .ZDI--ChatBubbleFill24)) > span:has(svg) { display: none !important; }
html.jim-iphone .AnswerItem .ContentItem-actions button[data-jimi-label]::after {
content: attr(data-jimi-label); display: block; font-size: 13px; line-height: 17px;
max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;
}
html.jim-iphone .AnswerItem .ContentItem-actions button[data-jimi-label]::before {
content: ""; display: block; width: 23px; height: 23px; margin-bottom: 2px; background: currentColor;
-webkit-mask: var(--jimi-action-icon) center / contain no-repeat; mask: var(--jimi-action-icon) center / contain no-repeat;
}
html.jim-iphone .AnswerItem .ContentItem-actions .VoteButton:not(.VoteButton--down) { --jimi-action-icon: var(--jimi-like-icon); }
html.jim-iphone .AnswerItem .ContentItem-actions button:has(.Zi--Comment, .ZDI--ChatBubbleFill24) { --jimi-action-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22M5%203h14a2%202%200%200%201%202%202v11a2%202%200%200%201-2%202H9l-6%204V5a2%202%200%200%201%202-2Z%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
html.jim-iphone .AnswerItem .ContentItem-actions .jimi-iphone-collapse { grid-column: 1; --jimi-action-icon: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%3E%3Cpath%20d%3D%22m5%2015%207-7%207%207M5%204h14%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.7%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%2F%3E%3C%2Fsvg%3E"); }
html.jim-iphone .AnswerItem .ContentItem-actions .VoteButton[aria-pressed="true"] { --jimi-like-icon: var(--jimi-like-icon-filled); color: var(--jimi-bar-liked) !important; }
html.jim-iphone .AnswerItem .ContentItem-actions button[data-jimi-label="收起评论"] { color: var(--jimi-comment-open) !important; }
html.jim-iphone .AnswerItem .ContentItem-actions > .jimi-answer-author {
grid-column: 1; display: flex; align-items: center; justify-content: center; text-decoration: none;
}
html.jim-iphone .AnswerItem .ContentItem-actions:has(> .jimi-iphone-collapse) > .jimi-answer-author { grid-column: 4; }
html.jim-iphone .jimi-answer-author img { width: 34px !important; height: 34px !important; flex: 0 0 34px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--jimi-avatar-gap), 0 0 0 3px var(--jimi-avatar-ring); }
html.jim-iphone .jimi-answer-author img[hidden] { display: none; }
html.jim-iphone .jimi-answer-author span { display: none; }
html.jim-iphone .jimi-answer-author:has(img[hidden])::before { content: "人"; font-size: 20px; color: var(--jimi-feed-muted); }
html.jim-iphone .ContentItem-actions :is(button, a):focus-visible { outline: 2px solid var(--jimi-focus); outline-offset: -2px; }
html.jim-iphone .ContentItem-actions :is(button, a):active { opacity: .65; }
html.jim-iphone :is(.ContentItem-actions button, .TopstoryTabs a, .AppHeader button,
.Modal-closeButton, .jimi-button) { min-height: 44px; touch-action: manipulation; }
html.jim-iphone :is(input, textarea, [contenteditable="true"]) { font-size: 16px !important; }
html.jim-iphone .Modal-wrapper { padding: 8px; box-sizing: border-box; }
html.jim-iphone :is(.Modal-wrapper .Modal, .css-1aq8hf9) {
width: calc(100vw - 16px) !important; min-width: 0 !important;
max-width: calc(100vw - 16px) !important; max-height: 90vh; max-height: 90dvh;
box-sizing: border-box;
}
html.jim-iphone :is(.Modal-content, .Comments-container, .CommentsV2,
.css-16zdamy, .css-18ld3w0) { min-width: 0 !important; max-width: 100% !important; }
html.jim-iphone .Modal-closeButton { right: 8px !important; top: 8px !important; z-index: 2; }
/* 页内评论与全部回复弹窗共用回答的颜色、细边线和 14px 圆角。 */
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) {
border: 1px solid var(--jimi-feed-line) !important; border-radius: 14px !important;
background: var(--jimi-feed-bg) !important; color: var(--jimi-feed-text) !important;
box-shadow: none !important; overflow: hidden;
}
html.jim-iphone[data-theme] .css-u76jt1 { margin: 16px 0 0 !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) :is(div, span, p, a, button) {
color: inherit !important; background-color: transparent !important; border-color: var(--jimi-feed-line) !important;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) svg { fill: currentColor !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-1onritu {
padding: 12px 14px !important; min-height: 44px; box-sizing: border-box;
display: flex; align-items: center; flex-wrap: wrap; gap: 12px;
border-bottom: 1px solid var(--jimi-feed-line) !important; box-shadow: none !important; font-size: 17px; line-height: 1.4; font-weight: 500;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-1onritu :is(.css-hmd01z, .css-1k10w8f, .css-1jm49l2) { font-size: inherit !important; line-height: inherit !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-u3vsx3 {
height: 36px; align-items: stretch; flex-shrink: 0;
border: 1px solid var(--jimi-feed-line) !important; border-radius: 14px; overflow: hidden;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-u3vsx3 > div {
display: flex; align-items: center; justify-content: center; height: auto; padding: 0 10px;
font-size: 14px; line-height: 1.4; cursor: pointer;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-u3vsx3 > .css-m0zh86 { background: var(--jimi-pill-bg) !important; }
html.jim-iphone[data-theme] :is(.css-18ld3w0, .css-16zdamy) { padding: 0 14px !important; }
html.jim-iphone[data-theme] :is(.css-18ld3w0, .css-16zdamy) > [data-id] + [data-id] { border-top: 1px solid var(--jimi-feed-line); }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) :is(.css-jp43l4, .css-13445jb, .css-8axkqi) { padding: 16px 0 !important; }
html.jim-iphone[data-theme] .css-1aq8hf9 .css-8axkqi { border-bottom: 0 !important; }
html.jim-iphone[data-theme] .css-34podr > [data-id] { padding: 0 14px; border-bottom: 0 !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) [data-id] [data-id] {
margin: 0 0 8px 34px; padding: 0 10px; border-radius: 14px; background: var(--jimi-pill-bg) !important;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-1kwt8l8 { margin: 0 !important; padding: 10px 0 !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-1jll2aj { margin-right: 10px; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .Avatar { width: 24px; height: 24px; border-radius: 50%; object-fit: cover; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-14nvvry { min-width: 0; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-swj9d4 { font-size: 16px; line-height: 1.4; font-weight: 500; color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-swj9d4 a { font-size: inherit !important; line-height: inherit !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-8v0dsd { font-size: 13px; line-height: 18px; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .CommentContent {
margin-top: 8px; font-size: 17px !important; font-weight: 400 !important; line-height: 1.65 !important; overflow-wrap: anywhere;
}
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .CommentContent p { margin: 0 0 .5em; font: inherit !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 { margin-top: 8px; font-size: 15px; line-height: 1.4; color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 :is(div, span, button) { font-size: inherit !important; line-height: inherit !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 button.Button--red:has(.Zi--Heart, .ZDI--HeartFill24) { --jimi-like-icon: var(--jimi-like-icon-filled); color: var(--jimi-liked) !important; }
/* 数字是按钮内的文本节点:让它和图标包装按中心对齐,避免 inline-flex 基线撑高按钮。 */
html.jim-iphone :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 button:has(.Zi--Heart, .ZDI--HeartFill24) {
display: inline-flex; align-items: center; justify-content: center; gap: 4px; vertical-align: middle;
}
html.jim-iphone :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 button > span:has(.Zi--Heart, .ZDI--HeartFill24) {
display: inline-flex; align-items: center; flex: none;
}
/* 保留原生点赞节点与事件,只把红心绘制替换为回答栏相同的拇指图标。 */
html.jim-iphone :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 button > span:has(.Zi--Heart, .ZDI--HeartFill24)::before {
content: ""; display: block; flex: none; width: 1.2em; height: 1.2em; background: currentColor;
-webkit-mask: var(--jimi-like-icon) center / contain no-repeat; mask: var(--jimi-like-icon) center / contain no-repeat;
}
html.jim-iphone :is(.css-u76jt1, .css-1aq8hf9) .css-140jo2 :is(.Zi--Heart, .ZDI--HeartFill24) { display: none !important; }
html.jim-iphone[data-theme] :is(.css-u76jt1, .css-1aq8hf9) .css-7dh30y {
display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; line-height: 1.4;
margin: 0 0 12px 34px; min-height: 40px; padding: 6px 12px; border: 0 !important; border-radius: 14px;
background: var(--jimi-pill-bg) !important; color: var(--jimi-feed-muted) !important; font-size: 15px;
}
html.jim-iphone[data-theme] .css-1aq8hf9 :is(.css-1e7fksk, .Modal-content, .css-tpyajk) { border-radius: inherit; }
html.jim-iphone[data-theme] .css-1aq8hf9 .Modal-content { padding: 0 !important; }
html.jim-iphone[data-theme] .css-1aq8hf9 .css-tpyajk > .css-1onritu { padding-right: 48px !important; }
html.jim-iphone[data-theme] .css-1aq8hf9 > button[aria-label="关闭"] {
position: absolute; top: 0; right: 4px; width: 44px; height: 44px; color: var(--jimi-feed-muted) !important;
}
html.jimi-readonly-comments :is(.css-1fo89v5, .css-59erns, .css-a3pqj1, .css-1ij6qqc) { display: none !important; }
html.jim-iphone[data-theme] .css-kt4t4n {
position: static !important; transform: none !important; box-shadow: none !important;
background: var(--jimi-feed-bg) !important; padding: 8px 0 !important; border: 0 !important;
}
html.jim-iphone[data-theme] .css-kt4t4n .css-1503iqi { color: var(--jimi-feed-muted) !important; font-size: 15px; }
/* 复用原生收起评论按钮,悬浮范围限制在当前评论区。 */
html.jimi-readonly-comments[data-theme] .css-kt4t4n {
position: sticky !important; bottom: max(12px, env(safe-area-inset-bottom)); z-index: 4;
width: 120px !important; height: 52px; margin: 8px auto 0 0 !important; padding: 0 !important;
background: transparent !important;
}
html.jimi-readonly-comments .css-kt4t4n .css-p1wstz {
position: static !important; display: block !important; opacity: 1 !important;
width: 100% !important; height: 52px; margin: 0 !important; transform: none !important;
}
html.jimi-readonly-comments[data-theme] .css-kt4t4n .css-1503iqi {
position: static !important; display: flex; align-items: center; justify-content: center; gap: 4px;
box-sizing: border-box; width: 100%; height: 52px; margin: 0; padding: 0 8px;
border: 1px solid var(--jimi-bar-border) !important; border-radius: 18px; background: var(--jimi-bar-bg) !important;
box-shadow: var(--jimi-bar-shadow);
color: var(--jimi-bar-text) !important; font-size: 15px; line-height: 1.2; white-space: nowrap; touch-action: manipulation;
}
html.jimi-readonly-comments .css-1503iqi svg { fill: currentColor !important; }
html.jimi-readonly-comments .css-79elbk:has(> .css-u76jt1) > .css-l8iyjs { display: none !important; }
html.jimi-readonly-comments[data-theme] .css-1aq8hf9 .css-tpyajk > .css-1onritu { padding-right: 14px !important; }
html.jimi-readonly-comments[data-theme] .css-1aq8hf9 > button[aria-label="关闭"] {
display: flex; align-items: center; justify-content: center; box-sizing: border-box;
top: auto; left: 12px; right: auto; bottom: 12px; width: 120px; height: 52px; padding: 0 8px;
border: 1px solid var(--jimi-bar-border) !important; border-radius: 18px; background: var(--jimi-bar-bg) !important;
box-shadow: var(--jimi-bar-shadow);
color: var(--jimi-bar-text) !important; font-size: 15px; line-height: 1.2; white-space: nowrap; touch-action: manipulation;
}
html.jimi-readonly-comments .css-1aq8hf9 > button[aria-label="关闭"] svg { display: none; }
html.jimi-readonly-comments .css-1aq8hf9 > button[aria-label="关闭"]::after { content: "收起评论"; }
html.jimi-readonly-comments .css-1aq8hf9 :is(.css-18ld3w0, .css-16zdamy) { padding-bottom: 72px !important; }
/* 原生操作提示不遮挡阅读;按钮状态继续由知乎更新。 */
html.jim-iphone :is(.Notification, .rv-toast, [class*="Toast_module_toast__"]) { display: none !important; }
html.jim-iphone #JIMI_PREVIEW_IMAGE { background: var(--jimi-preview-bg); }
html.jim-iphone .jimi-preview img { width: auto; height: auto; max-width: 100%; max-height: 90vh; max-height: 90dvh; object-fit: contain; }
html.jim-iphone .jimi-preview video { max-width: 100%; max-height: 90vh; }
html.jim-iphone .Post-content :is(.css-kjzwqj, .css-c0fani, .css-yq5nsh) {
width: 100% !important; max-width: 100%; min-width: 0; display: block !important;
margin: 0 !important; padding: 0 !important; box-sizing: border-box;
}
html.jim-iphone .Post-content .css-1ni4jcm { display: none !important; }
html.jim-iphone .Post-Header :is(.Post-Title, .Post-Author) { padding-left: 0 !important; padding-right: 0 !important; }
html.jim-iphone .css-14zbeoe { min-width: 0; flex: 1; }
html.jim-iphone .css-16xeo9u { flex-wrap: wrap; gap: 8px; }
html.jim-iphone .css-dza3t2 { flex: 1 1 100%; min-width: 0; }
html.jim-iphone .css-pcc2vs { overflow-x: auto; min-width: 0; }
html.jim-iphone .css-zkfaav { flex: 1 1 100%; justify-content: flex-end; white-space: nowrap; }
html.jim-iphone .css-16xeo9u button { min-height: 44px; flex-shrink: 0; white-space: nowrap; }
html.jim-iphone .css-kt4t4n { width: 100%; max-width: 100%; margin-left: 0 !important; margin-right: 0 !important; box-sizing: border-box; }
html.jim-iphone .Post-SideActions { display: none !important; }
/* 作者主页:资料、原生分类与阅读卡片;沿用推荐页的纸面和主题变量。 */
html.jim-iphone[data-theme] :is(#ProfileHeader, .Profile-main, .Profile-mainColumn,
.ProfileMain, .ProfileMain .ListShortcut, .ProfileMain .ListShortcut > div) { background: transparent !important; }
html.jim-iphone[data-theme] #ProfileHeader { margin: 12px 0 !important; padding: 0 12px; }
html.jim-iphone[data-theme] #ProfileHeader > .Card {
margin: 0; border: 0; border-radius: 18px; overflow: hidden;
background: var(--jimi-feed-bg) !important; box-shadow: var(--jimi-card-shadow) !important;
}
html.jim-iphone[data-theme] .ProfileHeader-userCover { display: none !important; }
html.jim-iphone[data-theme] .ProfileHeader-wrapper { padding: 20px 15px 15px !important; background: transparent !important; }
html.jim-iphone[data-theme] .ProfileHeader-main { position: relative; display: flex; align-items: flex-start; gap: 15px; min-height: 0; padding: 0 !important; margin: 0 !important; }
html.jim-iphone[data-theme] .ProfileHeader-avatar {
position: static !important; flex: 0 0 64px; width: 64px !important; height: 64px !important;
margin: 0; padding: 0; border: 0; border-radius: 50%;
}
html.jim-iphone[data-theme] .ProfileHeader-avatar .Avatar {
width: 64px !important; height: 64px !important; box-sizing: border-box;
border: 2px solid var(--jimi-feed-bg); border-radius: 50%; object-fit: cover;
box-shadow: 0 0 0 1px var(--jimi-avatar-ring);
}
html.jim-iphone[data-theme] .ProfileHeader-content { flex: 1; width: auto; min-width: 0; border: 0 !important; padding: 0 !important; margin: 0 !important; }
html.jim-iphone[data-theme] .ProfileHeader-contentHead { display: block; padding: 0 !important; margin: 0; }
html.jim-iphone[data-theme] .ProfileHeader-title { display: block; margin: 0; line-height: 1.4; }
html.jim-iphone[data-theme] .ProfileHeader-name { display: block; font-size: 26px; font-weight: 650; color: var(--jimi-feed-text); overflow-wrap: anywhere; }
html.jim-iphone[data-theme] .ProfileHeader-headline { display: block; margin: 6px 0 0; font-size: 16px; line-height: 1.6; color: var(--jimi-feed-muted); white-space: normal; }
html.jim-iphone[data-theme] .ProfileHeader-headline:empty { display: none; }
html.jim-iphone[data-theme] .ProfileHeader-contentBody { font-size: 15px; line-height: 1.65; color: var(--jimi-feed-muted); transition: none !important; }
html.jim-iphone[data-theme] :is(.ProfileHeader-info, .ProfileHeader-detail) { padding: 10px 0 0 !important; }
html.jim-iphone[data-theme] .ProfileHeader-detailItem { display: flex; flex-wrap: wrap; gap: 4px 10px; margin-bottom: 10px; }
html.jim-iphone[data-theme] .ProfileHeader-detailLabel { width: auto; min-width: 60px; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .ProfileHeader-detailValue { flex: 1 1 130px; min-width: 0; width: auto; overflow-wrap: anywhere; }
html.jim-iphone[data-theme] .ProfileHeader-contentFooter { display: flex; flex-direction: column; align-items: stretch; gap: 10px; margin-top: 8px; padding: 0 !important; }
html.jim-iphone[data-theme] .ProfileHeader-expandButton { display: inline-flex; align-items: center; align-self: flex-start; min-height: 44px; margin: 0; padding: 0; font-size: 14px; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .ProfileHeader-buttons { position: static !important; width: auto; display: flex; flex-wrap: wrap; gap: 8px; float: none; margin: 0; }
html.jim-iphone[data-theme] .ProfileHeader-buttons .Button {
display: inline-flex; align-items: center; justify-content: center; gap: 5px; min-height: 44px;
max-width: 100%; margin: 0 !important; padding: 0 12px; border-radius: 12px;
font-size: 15px; line-height: 1.4; color: var(--jimi-feed-text) !important;
border: 1px solid var(--jimi-feed-line) !important; background: var(--jimi-bar-bg) !important;
}
html.jim-iphone[data-theme] .ProfileHeader-buttons .FollowButton { color: var(--jimi-liked) !important; }
html.jim-iphone[data-theme] .ProfileMain { margin: 0; border: 0; box-shadow: none !important; overflow: visible; }
html.jim-iphone[data-theme] .ProfileMain-header {
display: flex; align-items: center; min-width: 0; margin: 0 12px 12px; padding: 0 8px;
border: 0; border-radius: 18px; background: var(--jimi-feed-bg) !important; box-shadow: var(--jimi-card-shadow);
}
html.jim-iphone[data-theme] .ProfileMain-tabs {
flex: 1; display: flex; width: auto; min-width: 0; margin: 0; padding: 0 !important;
border: 0; background: transparent !important; overflow-x: auto; scrollbar-width: none; overscroll-behavior-x: contain;
}
html.jim-iphone .ProfileMain-tabs::-webkit-scrollbar { display: none; }
html.jim-iphone[data-theme] .ProfileMain-tabs .Tabs-item { flex: 0 0 auto; padding: 0 10px; }
html.jim-iphone[data-theme] .ProfileMain-tabs .Tabs-link { display: flex; align-items: center; gap: 5px; min-height: 52px; padding: 0; font-size: 16px; color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme] .ProfileMain-tabs .Tabs-link.is-active { font-weight: 600; color: var(--jimi-feed-text) !important; }
html.jim-iphone[data-theme] .ProfileMain-tabs .Tabs-link.is-active::after { background: var(--jimi-feed-muted) !important; height: 2px; bottom: 8px; }
html.jim-iphone[data-theme] .ProfileMain-tabs .Tabs-meta { margin: 0; font-size: 12px; font-weight: 400; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .ProfileMain-header > :not(.ProfileMain-tabs) { position: static !important; flex: 0 0 auto; width: auto; background: var(--jimi-feed-bg) !important; }
html.jim-iphone[data-theme] .ProfileMain-header > :not(.ProfileMain-tabs)::before { display: none !important; }
html.jim-iphone[data-theme] :is(.ProfileHeader, .ProfileMain-header) svg { color: inherit !important; fill: currentColor !important; }
html.jim-iphone[data-theme] .ProfileMain-header button { background: transparent !important; display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme] #ProfileMain .ProfileMain-header button { background: transparent !important; color: var(--jimi-feed-muted) !important; }
html.jim-iphone[data-theme] #ProfileMain .ProfileMain-header button svg { color: var(--jimi-feed-muted) !important; fill: currentColor !important; }
html.jim-iphone[data-theme] .Profile-main .List-header { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 8px 27px 16px; border: 0; }
html.jim-iphone[data-theme] .Profile-main .List-headerText { margin: 0; font-size: 17px; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .Profile-main .List-headerOptions { margin-left: auto; font-size: 14px; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .Profile-main .List-item:not(.jimi-answer-morph) {
margin: 0 12px 12px; padding: 15px !important; border: 0; border-radius: 18px;
box-shadow: var(--jimi-card-shadow); background: var(--jimi-feed-bg) !important; overflow: visible;
}
html.jim-iphone[data-theme] .Profile-main .List-itemMeta { margin: 0 0 10px; font-size: 13px; line-height: 1.5; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .Profile-main .ActivityItem-meta { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 4px 8px; color: var(--jimi-feed-muted); }
html.jim-iphone[data-theme] .Profile-main .ActivityItem-metaTitle { color: inherit; }
html.jim-iphone[data-theme] .Profile-main .ContentItem-title { font-size: ${IPHONE_PRESET.script.fontSizeForListTitle}px; line-height: 1.4; overflow-wrap: anywhere; }
html.jim-iphone[data-theme] .Profile-main .RichContent.is-collapsed .RichContent-inner { max-height: none !important; }
html.jim-iphone[data-theme] .Profile-main :is(.Pagination, .EmptyState) { padding: 20px 15px; color: var(--jimi-feed-muted); background: transparent !important; }
html.jim-iphone[data-theme] .Profile-main .Pagination { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
html.jim-iphone[data-theme] .Profile-main .Pagination button { min-width: 44px; min-height: 44px; margin: 0; }
${hideSidebars ? `html.jim-iphone :is(.GlobalSideBar, .Topstory-sideBar, .Topstory-container > [data-za-detail-view-path-module="RightSideBar"], .Question-sideColumn,
.SearchSideBar, .Profile-sideColumn, .CollectionsDetailPage-sideColumn, .Post-Row-Content-right) { display: none !important; }` : ""}
${hideOpenApp ? `html.jim-iphone :is(.OpenInAppButton, .OpenInAppBanner, .DownloadGuide,
.MobileAppHeader-downloadLink, .AppBanner, .css-rg1dmv, .css-1gapyfo, .css-183aq3r, .css-wfkf2m) { display: none !important; }` : ""}
`);
setViewport();
};
// 推荐只展示过滤后的前 N 条;到底停止加载,刷新交给浏览器原生操作。
var iPhoneFeedBatch = { root: null, count: 0, full: false };
var isIPhoneBatchPage = () => isIPhoneLayout && Number(IPHONE_PRESET.mobile.feedBatchSize) > 0 &&
location.hostname === "www.zhihu.com" && location.pathname === "/";
var syncIPhoneFeedBatch = () => {
const root = isIPhoneBatchPage() && document.querySelector('.Topstory-recommend');
if (!root) {
iPhoneFeedBatch.root?.classList.remove("jimi-batch-full");
Object.assign(iPhoneFeedBatch, { root: null, full: false, count: 0 });
return;
}
const limit = Math.max(1, Math.min(100, Math.floor(Number(IPHONE_PRESET.mobile.feedBatchSize))));
let count = 0;
for (const item of root.querySelectorAll('.TopstoryItem.jimi-listened')) {
item.classList.remove("jimi-batch-extra");
if (item.classList.contains("jimi-hidden-item") || !item.querySelector('.ContentItem') || getComputedStyle(item).display === "none") continue;
item.classList.toggle("jimi-batch-extra", count++ >= limit);
}
iPhoneFeedBatch.root = root;
iPhoneFeedBatch.count = Math.min(count, limit);
iPhoneFeedBatch.full = count >= limit;
root.classList.toggle("jimi-batch-full", iPhoneFeedBatch.full);
};
var shouldStopIPhoneFeedRequest = (input, options) => {
if (!isIPhoneBatchPage() || !iPhoneFeedBatch.full) return false;
try {
const url = new URL(typeof input === "string" ? input : input.url || input.href, location.href);
return (options?.method || input.method || "GET").toUpperCase() === "GET" &&
url.origin === location.origin && url.pathname === "/api/v3/feed/topstory/recommend" && url.searchParams.get("action") === "down";
} catch { return false; }
};
var iPhoneFeedAuthors = new Map();
var cacheIPhoneFeedAuthors = (items) => {
if (!isIPhoneLayout || !IPHONE_PRESET.mobile.compactFeed || !Array.isArray(items)) return;
for (const item of items) {
const target = item?.target;
if (target?.type !== "answer" || !target.id || !target.author) continue;
iPhoneFeedAuthors.set(String(target.id), target.author);
}
// 只保留近期头像资料,与原作长列表模式一起控制内存,不保存回答正文。
while (iPhoneFeedAuthors.size > 200) iPhoneFeedAuthors.delete(iPhoneFeedAuthors.keys().next().value);
};
var formatIPhoneFeedVotes = (value) => value !== null && value !== undefined && value !== "" && Number.isFinite(Number(value)) && Number(value) >= 0
? `${Number(value)} 人赞同` : "";
var iPhoneAvatarObserver;
var iPhoneAvatarTargets = new Set();
var loadIPhoneFeedAvatar = async (content) => {
if (!content.isConnected || content.dataset.avatarRequested) return;
const id = String(parseJSONAttr(content.getAttribute("data-zop"))?.itemId || "");
const member = parseJSONAttr(content.getAttribute("data-za-extra-module"))?.card?.content?.author_member_hash_id;
if (!id || typeof member !== "string" || !/^[a-zA-Z0-9_-]{1,100}$/.test(member)) return;
content.dataset.avatarRequested = "true";
const cached = iPhoneFeedAuthors.get(id);
if (cached?.avatar_url || cached?.avatarUrl) return;
try {
// 首屏数据或 Safari 沙箱可能漏过 fetch 拦截;只在条目接近可见区域时补取作者。
const response = await fetch(`/api/v4/members/${encodeURIComponent(member)}?include=avatar_url`, { credentials: "same-origin" });
if (!response.ok) return;
const author = await response.json();
cacheIPhoneFeedAuthors([{ target: { type: "answer", id, author } }]);
syncIPhoneFeed();
} catch {
// 网络失败时保留作者文字;同一卡片不循环重试。
}
};
var observeIPhoneFeedAvatar = (content) => {
if (content.dataset.avatarRequested) return;
if (!iPhoneAvatarObserver) iPhoneAvatarObserver = new IntersectionObserver((entries) => {
for (const { target, isIntersecting } of entries) {
if (!isIntersecting) continue;
iPhoneAvatarObserver.unobserve(target);
iPhoneAvatarTargets.delete(target);
loadIPhoneFeedAvatar(target);
}
}, { rootMargin: "300px" });
iPhoneAvatarObserver.observe(content);
iPhoneAvatarTargets.add(content);
};
var iPhoneFeedMetadataObserver;
var syncIPhoneFeed = () => {
if (!isIPhoneLayout || !IPHONE_PRESET.mobile.compactFeed) return;
const root = document.querySelector('.Topstory-recommend');
const hasAnswers = root?.querySelector('.TopstoryItem .AnswerItem');
// 首批回答到达后再插入首尾,避免 React 初次接管空列表时移除并重建。
if (hasAnswers && !root.previousElementSibling?.classList.contains('jimi-feed-intro')) {
const intro = document.createElement('header');
intro.className = 'jimi-feed-intro';
intro.innerHTML = '
↑上拉刷新
';
root.before(intro);
}
if (hasAnswers && !root.nextElementSibling?.classList.contains('jimi-feed-outro')) {
const outro = document.createElement('footer');
outro.className = 'jimi-feed-outro';
outro.innerHTML = '已到底部了';
root.after(outro);
}
for (const target of iPhoneAvatarTargets) {
if (target.isConnected) continue;
iPhoneAvatarObserver.unobserve(target);
iPhoneAvatarTargets.delete(target);
}
for (const content of document.querySelectorAll('.TopstoryItem .AnswerItem, .Profile-main .List-item .AnswerItem')) {
const rich = content.querySelector(':scope > .RichContent');
if (!rich?.classList.contains("is-collapsed") || !rich.querySelector('.ContentItem-more')) continue;
const zop = parseJSONAttr(content.getAttribute("data-zop")) || {};
const card = parseJSONAttr(content.getAttribute("data-za-extra-module"))?.card?.content || {};
const title = content.querySelector('.ContentItem-title a')?.textContent.trim();
if (!title) continue;
const author = iPhoneFeedAuthors.get(String(zop.itemId)) || {};
const authorName = zop.authorName || author.name || content.querySelector('.AuthorInfo-name')?.textContent.trim() || "";
let excerpt = content.querySelector('.RichContent-inner .RichText')?.textContent.replace(/\s+/g, " ").trim() || "";
if (authorName && (excerpt.startsWith(authorName + ":") || excerpt.startsWith(authorName + ":"))) excerpt = excerpt.slice(authorName.length + 1).trim();
const votes = formatIPhoneFeedVotes(card.upvote_num ?? content.querySelector('meta[itemprop="upvoteCount"]')?.content);
const avatar = author.avatar_url || author.avatarUrl || content.querySelector('.AuthorInfo-avatar')?.src || "";
let preview = content.querySelector(':scope > .jimi-feed-preview');
if (!preview) {
preview = document.createElement("button");
preview.type = "button";
preview.className = "jimi-feed-preview";
preview.setAttribute("aria-expanded", "false");
preview.innerHTML = '
';
preview.onclick = () => content.querySelector('.RichContent.is-collapsed .ContentItem-more')?.click();
content.prepend(preview);
// 主页的作者与计数可能在 React 接管后才写入;只观察原生资料属性,避免自触发。
iPhoneFeedMetadataObserver ||= new MutationObserver(syncIPhoneFeed);
iPhoneFeedMetadataObserver.observe(content, { attributes: true, attributeFilter: ["data-zop", "data-za-extra-module"] });
}
const signature = JSON.stringify([title, excerpt, authorName, votes, avatar]);
if (preview.dataset.signature !== signature) {
preview.dataset.signature = signature;
preview.setAttribute("aria-label", `展开回答:${title}`);
preview.querySelector('.jimi-feed-title').textContent = title;
preview.querySelector('.jimi-feed-excerpt').textContent = excerpt;
preview.querySelector('.jimi-feed-author').textContent = authorName;
preview.querySelector('.jimi-feed-author').title = authorName;
preview.querySelector('.jimi-feed-votes').textContent = votes;
const image = preview.querySelector('img');
image.hidden = !/^https:\/\//.test(avatar);
image.onerror = () => {
image.hidden = true;
iPhoneFeedAuthors.delete(String(zop.itemId));
observeIPhoneFeedAvatar(content);
};
if (!image.hidden && image.getAttribute("src") !== avatar) image.src = avatar;
}
content.classList.add("jimi-feed-answer");
const item = content.closest('.TopstoryItem, .Profile-main .List-item');
item.classList.add("jimi-feed-item");
if (item.closest('.Profile-main')) item.classList.add("jimi-profile-item");
if (!avatar) observeIPhoneFeedAvatar(content);
}
};
var blockIPhoneAnswerTextClick = (event) => {
const target = event.target;
const image = target.closest?.('.RichContent-inner .RichText img:is(.origin_image, .content_image), .Post-RichTextContainer img:is(.origin_image, .content_image)');
if (image && !image.closest('.GifPlayer')) {
// 原生大图层把 62px 小图做 GPU 放大,Safari 会模糊;复用现有预览层按实际尺寸排版原图。
event.preventDefault();
event.stopImmediatePropagation();
myPreview.open(getPreviewImageSrc(image));
return;
}
if (target.closest?.('img, video, audio, .VideoAnswerPlayer, .VideoCard')) return;
if (!target.closest?.('.AnswerItem > .RichContent:not(.is-collapsed) .RichContent-inner .RichText :is(a, .highlight-wrap, [data-highlight-id])')) return;
event.preventDefault();
event.stopImmediatePropagation();
};
var iPhoneObservedAnswers = new WeakSet();
var iPhoneOpenAnswers = new Set();
var iPhoneActiveAnswer;
var iPhoneCommentAnswer;
var iPhoneAutoCollapse;
var iPhoneAnswerMotion;
var iPhoneAnswerClick = false;
var trackIPhoneAnswerMotion = (event) => {
if (iPhoneAnswerClick) return;
const button = event.target.closest?.('.ContentItem-more, button[data-zop-retract-question="true"]');
const rich = button?.closest('.AnswerItem > .RichContent');
const item = rich?.closest('.TopstoryItem, .jimi-profile-item');
if (!item) return;
// 直接切换时让原生点击继续;同步重放同一按钮会被浏览器的 click 重入保护忽略。
if (!item.animate || window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) {
if (!rich.classList.contains('is-collapsed')) closeIPhoneAnswerComments(rich);
return;
}
event.preventDefault();
event.stopImmediatePropagation();
if (rich.classList.contains('is-collapsed')) changeIPhoneAnswer(rich, () => button.click());
else collapseIPhoneAnswer(rich);
};
var changeIPhoneAnswer = (rich, change, animated = true) => {
const apply = () => {
iPhoneAnswerClick = true;
try { change(); } finally { iPhoneAnswerClick = false; }
};
if (!animated) {
const root = document.documentElement;
return new Promise(resolve => {
// 边界收起直接更新原生状态;同一帧禁用邻卡/阴影过渡,完成保位后再恢复。
root.classList.add('jimi-answer-instant');
try { apply(); } finally {
requestAnimationFrame(() => {
root.getBoundingClientRect();
root.classList.remove('jimi-answer-instant');
resolve();
});
}
});
}
const item = rich.closest('.TopstoryItem, .jimi-profile-item');
// ponytail: 复用 Safari 原生 WAAPI;减少动态效果或不支持时直接切换,不加载动画库。
if (!item?.animate || window.matchMedia?.('(prefers-reduced-motion: reduce)').matches || iPhoneAnswerMotion?.updating) {
apply();
return Promise.resolve();
}
if (iPhoneAnswerMotion) {
const previous = iPhoneAnswerMotion;
const collapsed = rich.classList.contains('is-collapsed');
previous.cancel();
return previous.done.then(() => {
// 同一个按钮连点时,上一操作已完成相同切换就不再重放。
if (rich.classList.contains('is-collapsed') === collapsed) return changeIPhoneAnswer(rich, change);
});
}
const opening = rich.classList.contains('is-collapsed');
if (opening && iPhoneActiveAnswer && iPhoneActiveAnswer !== rich && !iPhoneActiveAnswer.classList.contains('is-collapsed')) {
const previous = iPhoneActiveAnswer.closest('.TopstoryItem, .jimi-profile-item')?.getBoundingClientRect();
// 仍在屏幕内的旧回答先平滑收起;屏幕外的回答沿用切换时的直接收起。
if (previous?.bottom > 0 && previous.top < innerHeight) {
return collapseIPhoneAnswer(iPhoneActiveAnswer, item).then(() => changeIPhoneAnswer(rich, change));
}
}
const root = document.documentElement;
const answer = rich.closest('.AnswerItem');
const animations = [];
const state = { updating: false, cancelled: false, anchors: [],
cancel() { state.cancelled = true; animations.forEach(animation => animation.cancel()); } };
const animate = (element, frames, duration, delay = 0, pseudoElement = null) => {
const animation = element.animate(frames, { duration, delay, easing: 'cubic-bezier(.4, 0, .2, 1)', fill: 'both', pseudoElement });
animations.push(animation);
return animation;
};
const visible = rect => rect.bottom > 0 && rect.top < innerHeight;
const frame = rect => {
const top = Math.max(-32, Math.min(rect.top, innerHeight + 32));
return { top, height: Math.max(1, Math.min(rect.bottom, innerHeight + 32) - top), left: rect.left, width: rect.width };
};
iPhoneAnswerMotion = state;
resetIPhoneAutoCollapse();
state.done = (async () => {
let surface;
try {
// 先淡出文字与底栏;保留真实内容节点,图片、评论和按钮均不复制。
await animate(answer, [{ opacity: getComputedStyle(answer).opacity }, { opacity: 0 }], 100).finished.catch(() => {});
const before = new Map([...document.querySelectorAll(':is(.TopstoryItem, .jimi-profile-item):has(.AnswerItem)')]
.map(row => [row, row.getBoundingClientRect()]));
const oldFrame = frame(item.getBoundingClientRect());
root.classList.add('jimi-answer-changing');
item.classList.add('jimi-answer-morph');
surface = document.createElement('div');
surface.className = 'jimi-answer-surface';
surface.setAttribute('aria-hidden', 'true');
surface.style.setProperty('--jimi-surface-shadow', opening ? '0' : '1');
Object.assign(surface.style, { top: `${oldFrame.top}px`, left: `${oldFrame.left}px`, width: `${oldFrame.width}px`, height: `${oldFrame.height}px` });
(item.closest('.Topstory, .Profile-main') || document.body).append(surface);
state.updating = true;
apply();
await Promise.resolve();
syncIPhoneAnswerFocus();
syncIPhoneExpandedAnswers();
syncIPhoneCollapseButtons();
await Promise.resolve();
state.anchors.forEach(restore => restore());
state.updating = false;
if (state.cancelled || !item.isConnected) return;
const rect = item.getBoundingClientRect(), nextFrame = frame(rect);
const contentRect = answer.getBoundingClientRect();
const clip = bounds => `inset(${Math.max(0, nextFrame.top - contentRect.top)}px 0 ${Math.max(0, contentRect.bottom - nextFrame.top - bounds.height)}px 0)`;
const geometry = bounds => ({ top: `${bounds.top}px`, left: `${bounds.left}px`, width: `${bounds.width}px`, height: `${bounds.height}px` });
// 只有无子节点的浮层改变高度;长文高度一次到位,段落不参加逐帧排版。
animate(surface, [geometry(oldFrame), geometry(nextFrame)], 420);
animate(surface, [{ opacity: opening ? 0 : 1 }, { opacity: opening ? 1 : 0 }], 420, 0, '::after');
animate(answer, [{ clipPath: clip(oldFrame), transform: `translateY(${oldFrame.top - nextFrame.top}px)` },
{ clipPath: clip(nextFrame), transform: 'translateY(0)' }], 420);
animate(answer, [{ opacity: 0 }, { opacity: 1 }], 280, 100);
const actions = rich.querySelector('.ContentItem-actions');
if (!rich.classList.contains('is-collapsed') && actions) animate(actions, [{ opacity: 0 }, { opacity: 1 }], 240, 160);
for (const [row, old] of before) {
if (row === item || !row.isConnected) continue;
const now = row.getBoundingClientRect();
if (!visible(old) && !visible(now)) continue;
// 只让可见邻卡移过屏幕边缘,避免长文把几千像素的位移挤在最初几帧。
const y = new DOMMatrix(getComputedStyle(row).transform).m42;
const offset = old.top - now.top;
const travel = Math.max(-innerHeight, Math.min(offset, innerHeight));
const end = visible(now) ? 0 : offset - travel;
animate(row, [{ transform: `translateY(${y + end + travel}px)` },
{ transform: `translateY(${y + end}px)` }], 420);
}
await Promise.all(animations.map(animation => animation.finished.catch(() => {})));
} finally {
animations.forEach(animation => animation.cancel());
surface?.remove();
item.classList.remove('jimi-answer-morph');
root.classList.remove('jimi-answer-changing');
if (iPhoneAnswerMotion === state) iPhoneAnswerMotion = undefined;
syncIPhoneAutoCollapse(true);
}
})();
return state.done;
};
var resetIPhoneAutoCollapse = () => {
iPhoneAutoCollapse?.observer.disconnect();
iPhoneAutoCollapse = undefined;
};
var syncIPhoneAutoCollapse = (resized = false) => {
if (!isIPhoneLayout || iPhoneAnswerMotion || !IPHONE_PRESET.mobile.floatingCollapse || typeof IntersectionObserver === "undefined") return;
const rich = iPhoneActiveAnswer;
const actions = rich?.querySelector('.ContentItem-actions');
const host = rich?.querySelector(':scope > .jimi-action-host');
if (!rich?.isConnected || rich.classList.contains('is-collapsed') || !actions || !host) {
resetIPhoneAutoCollapse();
return;
}
const commentsOpen = actions.querySelector('button:has(.Zi--Comment, .ZDI--ChatBubbleFill24)')?.textContent.includes("收起评论");
const previous = iPhoneAutoCollapse;
if (!resized && previous?.rich === rich && previous.actions === actions) {
previous.commentsOpen = commentsOpen;
if (commentsOpen) { previous.armed = false; previous.commentHold = false; }
return;
}
resetIPhoneAutoCollapse();
const state = { rich, actions, armed: !resized && previous?.rich === rich && previous.armed && !commentsOpen && !previous.commentHold, commentsOpen,
commentHold: !commentsOpen && previous?.rich === rich && previous.commentHold };
// 上边界约为背景标题下沿;下边界比正常悬浮位低 6px,避开 sticky 的像素抖动。
const bottom = Math.max(0, (parseFloat(getComputedStyle(host).bottom) || 12) - 6);
state.observer = new IntersectionObserver((entries) => {
if (iPhoneAutoCollapse !== state) return;
if (!rich.isConnected || rich.classList.contains('is-collapsed')) { resetIPhoneAutoCollapse(); return; }
for (const entry of entries) {
if (entry.target !== actions || !entry.rootBounds) continue;
if (state.commentHold || state.commentsOpen) { state.armed = false; continue; }
const rect = entry.boundingClientRect, bounds = entry.rootBounds;
const inside = entry.isIntersecting && rect.top >= bounds.top && rect.bottom <= bounds.bottom;
if (inside) { state.armed = true; continue; }
// 先进入阅读范围才启用,避免刚展开、旋转屏幕或打开评论时立即被收起。
if (!state.armed) continue;
const above = rect.top < bounds.top;
if (!above && rect.bottom <= bounds.bottom) continue;
const item = rich.closest('.TopstoryItem, .jimi-profile-item') || rich.closest('.AnswerItem');
let anchor = item;
if (above) {
for (let next = item?.nextElementSibling; next; next = next.nextElementSibling) {
if (next.getClientRects().length) { anchor = next; break; }
}
}
collapseIPhoneAnswer(rich, anchor, false);
break;
}
}, { rootMargin: `-180px 0px -${bottom}px 0px`, threshold: [0, 1] });
iPhoneAutoCollapse = state;
state.observer.observe(actions);
};
var trackIPhoneCommentAnswer = (event) => {
const button = event.target.closest?.('.ContentItem-actions button:has(.Zi--Comment, .ZDI--ChatBubbleFill24), .css-7dh30y');
if (!button || button.closest('.css-1aq8hf9')) return;
const rich = button.closest('.AnswerItem')?.querySelector(':scope > .RichContent');
iPhoneCommentAnswer = rich;
const dock = rich?.querySelector(':scope > .jimi-action-dock');
if (!event.isTrusted || !dock || !button.closest('.ContentItem-actions') || button.textContent.includes("收起评论")) return;
event.preventDefault();
event.stopImmediatePropagation();
if (iPhoneAutoCollapse?.rich === rich) {
iPhoneAutoCollapse.commentHold = true;
iPhoneAutoCollapse.armed = false;
}
dock.scrollIntoView({ block: "start", behavior: "instant" });
requestAnimationFrame(() => {
if (rich.isConnected && !rich.classList.contains('is-collapsed')) {
rich.querySelector('.ContentItem-actions button:has(.Zi--Comment, .ZDI--ChatBubbleFill24)')?.click();
}
});
};
var closeIPhoneAnswerComments = (rich) => {
const answer = rich.closest('.AnswerItem');
const close = answer?.querySelector('.css-1503iqi');
const toggle = rich.querySelector('.ContentItem-actions button:has(.Zi--Comment, .ZDI--ChatBubbleFill24)');
// 少量评论时知乎不生成底部关闭按钮,仍可用当前原生评论按钮收起。
if (close) close.click();
else if (toggle?.textContent.includes("收起评论")) toggle.click();
if (iPhoneCommentAnswer === rich) closeCommentDialog();
};
var collapseIPhoneAnswer = (rich, anchor, animated = true) => {
return changeIPhoneAnswer(rich, () => {
const top = anchor?.getBoundingClientRect().top;
if (iPhoneAutoCollapse?.rich === rich) resetIPhoneAutoCollapse();
closeIPhoneAnswerComments(rich);
rich.querySelector('button[data-zop-retract-question="true"]')?.click();
// 开始新动画前抵消原生收起跳转,边界收起保住当前/下一张卡片。
if (anchor) {
const restore = () => { if (anchor.isConnected) window.scrollBy(0, anchor.getBoundingClientRect().top - top); };
if (iPhoneAnswerMotion?.updating) iPhoneAnswerMotion.anchors.push(restore);
else requestAnimationFrame(restore);
}
}, animated);
};
var syncIPhoneAnswerFocus = () => {
if (!isIPhoneLayout) return;
// 仅协调原生可展开/收起的回答,不把详情页本来就完整显示的短回答强制裁断。
const open = new Set([...document.querySelectorAll('.AnswerItem > .RichContent:not(.is-collapsed)')]
.filter(rich => rich.querySelector('button[data-zop-retract-question="true"]') && rich.getClientRects().length));
const fresh = [...open].filter(rich => !iPhoneOpenAnswers.has(rich));
const active = (iPhoneActiveAnswer ? fresh.at(-1) : fresh[0]) || (open.has(iPhoneActiveAnswer) ? iPhoneActiveAnswer : open.values().next().value);
for (const rich of iPhoneOpenAnswers) if (!open.has(rich)) closeIPhoneAnswerComments(rich);
if (iPhoneCommentAnswer && (!iPhoneCommentAnswer.isConnected || iPhoneCommentAnswer.classList.contains('is-collapsed'))) {
closeIPhoneAnswerComments(iPhoneCommentAnswer);
if (!iPhoneCommentAnswer.isConnected) iPhoneCommentAnswer = undefined;
}
if (iPhoneActiveAnswer !== active) iPhoneActiveAnswer?.closest('.AnswerItem')?.classList.remove('jimi-reading-answer');
const anchor = active?.closest('.AnswerItem');
anchor?.classList.add('jimi-reading-answer');
// 仅标记本页实际展开过的回答;收起才淡化,重新展开恢复原色。
anchor?.classList.add('jimi-read-answer');
iPhoneActiveAnswer = active;
if (iPhoneAutoCollapse && iPhoneAutoCollapse.rich !== active) resetIPhoneAutoCollapse();
iPhoneOpenAnswers = open;
const others = [...open].filter(rich => rich !== active);
if (!others.length) return;
others.forEach(rich => collapseIPhoneAnswer(rich, anchor));
};
var formatIPhoneAnswerIP = (value) => typeof value === "string"
? value.replace(/^[\s·・•||]+/, "").replace(/^IP\s*属地[::\s]*/, "").trim() : "";
var syncIPhoneAnswerIP = (rich) => {
const time = rich.querySelector('.ContentItem-time');
if (!time?.querySelector(':scope > a')) return;
// 保留原生日期链接与文本节点的父节点,只整理回答自身的属地。
// React 可能把分隔符与属地拆成两个文本节点,合并读取但不移动节点。
const nativeIP = [...time.childNodes].filter(node => node.nodeType === 3 && node.textContent.trim());
if (nativeIP.length) {
const region = formatIPhoneAnswerIP(nativeIP.map(node => node.textContent).join(""));
const label = region ? `IP 属地:${region}` : "";
nativeIP.forEach((node, index) => {
const text = index === nativeIP.length - 1 ? label : "";
if (node.textContent !== text) node.textContent = text;
});
time.querySelector('.jimi-answer-ip')?.remove();
return;
}
const id = String(parseJSONAttr(rich.closest('.AnswerItem')?.getAttribute('data-zop'))?.itemId || "");
const answer = store.getJsInitialData()?.initialState?.entities?.answers?.[id] || store.getUserAnswer().find(item => String(item.id) === id);
const region = formatIPhoneAnswerIP(answer?.ipInfo ?? answer?.ip_info);
let line = time.querySelector('.jimi-answer-ip');
if (!region) { line?.remove(); return; }
if (!line) {
line = document.createElement('span');
line.className = 'jimi-answer-ip';
time.append(line);
}
const label = `IP 属地:${region}`;
if (line.textContent !== label) line.textContent = label;
};
var syncIPhoneExpandedAnswers = () => {
if (!isIPhoneLayout) return;
for (const rich of document.querySelectorAll('.AnswerItem > .RichContent:not(.is-collapsed)')) {
syncIPhoneAnswerIP(rich);
if (!iPhoneObservedAnswers.has(rich)) {
// 知乎滚动时会替换操作栏,页面高度未必变化;在重绘前补回作者与收起位置。
new MutationObserver((changes) => {
if (changes?.every(change => change.type === 'attributes' && change.target !== rich && !change.target.matches('.VoteButton'))) return;
syncIPhoneAnswerFocus();
syncIPhoneExpandedAnswers();
syncIPhoneCollapseButtons();
}).observe(rich, { childList: true, characterData: true, subtree: true, attributes: true, attributeFilter: ['class', 'aria-label'] });
iPhoneObservedAnswers.add(rich);
}
// 保留 React 管理的正文节点和图片查看器,只取消文字链接与划线入口。
for (const text of rich.querySelectorAll('.RichContent-inner .RichText :is(a, .highlight-wrap, [data-highlight-id])')) {
if (text.hasAttribute("href")) text.removeAttribute("href");
if (text.tabIndex !== -1) text.tabIndex = -1;
}
const actions = rich.querySelector('.ContentItem-actions');
if (!actions) continue;
const vote = actions.querySelector('.VoteButton:not(.VoteButton--down)');
const comment = actions.querySelector('button:has(.Zi--Comment, .ZDI--ChatBubbleFill24)');
for (const [button, fallback] of [[vote, "赞同"], [comment, "评论"]]) {
if (!button) continue;
const text = button.textContent.replace(/[\s,,\u200b]/g, "");
const label = text.match(/[\d.]+(?:万|亿|[kKwW])?/)?.[0] || (text.includes("收起评论") ? "收起评论" : fallback);
if (button.dataset.jimiLabel !== label) button.dataset.jimiLabel = label;
}
if (vote) {
const pressed = vote.classList.contains('is-active') || (vote.getAttribute('aria-label') || vote.textContent).includes("已赞同");
if (vote.getAttribute('aria-pressed') !== String(pressed)) vote.setAttribute('aria-pressed', String(pressed));
}
const answer = rich.closest('.AnswerItem');
const link = answer.querySelector('.AuthorInfo-name a');
const zop = parseJSONAttr(answer.getAttribute("data-zop")) || {};
const cached = iPhoneFeedAuthors.get(String(zop.itemId)) || {};
const name = link?.textContent.trim() || zop.authorName || cached.name || "作者";
const avatar = answer.querySelector('.AuthorInfo-avatar')?.src || cached.avatar_url || cached.avatarUrl || "";
const href = link?.getAttribute("href") || "";
let author = actions.querySelector(':scope > .jimi-answer-author');
if (!author) {
author = document.createElement("a");
author.className = "jimi-answer-author";
author.innerHTML = '
';
actions.prepend(author);
}
const signature = JSON.stringify([name, avatar, href]);
if (author.dataset.signature === signature) continue;
author.dataset.signature = signature;
author.querySelector('span').textContent = name;
author.title = name;
author.setAttribute("aria-label", `作者:${name}`);
if (href) author.setAttribute("href", href);
else author.removeAttribute("href");
const image = author.querySelector('img');
image.hidden = !/^https:\/\//.test(avatar);
image.onerror = () => { image.hidden = true; };
if (!image.hidden && image.getAttribute("src") !== avatar) image.src = avatar;
}
};
var syncIPhoneCollapseButtons = () => {
if (!isIPhoneLayout || !IPHONE_PRESET.mobile.floatingCollapse) return;
for (const content of document.querySelectorAll('.AnswerItem .RichContent:not(.is-collapsed)')) {
if (!content.querySelector('button[data-zop-retract-question="true"]')) continue;
const actions = content.querySelector('.ContentItem-actions');
let host = actions;
while (host && host.parentElement !== content) host = host.parentElement;
if (!host) continue;
host.classList.add("jimi-action-host");
let dock = content.querySelector(':scope > .jimi-action-dock');
if (!dock) {
dock = document.createElement("div");
dock.className = "jimi-action-dock";
dock.setAttribute("aria-hidden", "true");
}
if (host.previousElementSibling !== dock) host.before(dock);
let button = content.querySelector('.jimi-iphone-collapse');
if (!button) {
button = document.createElement("button");
button.type = "button";
button.className = "jimi-iphone-collapse";
button.dataset.jimiLabel = "收起";
button.setAttribute("aria-label", "收起当前回答");
button.onclick = () => {
const preview = content.closest('.jimi-feed-answer')?.querySelector('.jimi-feed-preview');
collapseIPhoneAnswer(content).then(() => {
if (preview?.getClientRects().length) preview.focus({ preventScroll: true });
});
};
}
// 只移动自有按钮;原生作者/赞同/评论继续留在 React 管理的操作栏内。
if (button.parentElement !== actions) actions.append(button);
}
syncIPhoneAutoCollapse();
};
var judgeBrowserType = () => {
const userAgent = navigator.userAgent;
if (userAgent.includes("Firefox")) return "Firefox";
if (userAgent.includes("Edg")) return "Edge";
if (userAgent.includes("Chrome")) return "Chrome";
return "Safari";
};
var isSafari = judgeBrowserType() === "Safari";
var windowResize = () => {
window.dispatchEvent(new Event("resize"));
};
var dom = (n, find = document) => find ? find.querySelector(n) : void 0;
var domById = (id) => document.getElementById(id);
var domA = (n, find = document) => find.querySelectorAll(n);
var domC = (name, attrObjs) => {
const node = document.createElement(name);
for (let key in attrObjs) {
node[key] = attrObjs[key];
}
return node;
};
var domP = (node, attrName, attrValue) => {
const nodeP = node.parentElement;
if (!nodeP) return void 0;
if (!attrName || !attrValue) return nodeP;
if (nodeP === document.body) return void 0;
const attrValueList = (nodeP.getAttribute(attrName) || "").split(" ");
return attrValueList.includes(attrValue) ? nodeP : domP(nodeP, attrName, attrValue);
};
var insertAfter = (newElement, targetElement) => {
const parent = targetElement.parentNode;
if (parent.lastChild === targetElement) {
parent.appendChild(newElement);
} else {
parent.insertBefore(newElement, targetElement.nextSibling);
}
};
var fnReturnStr = (str, isHave = false, strFalse = "") => isHave ? str : strFalse;
var fnLog = (...str) => console.log("%c「吉姆的知乎 · iPhone」", "color: green;font-weight: bold;", ...str);
var fnAppendStyle = (id, innerHTML) => {
const element = domById(id);
if (element) {
if (element.textContent !== innerHTML) element.textContent = innerHTML;
} else document.head.appendChild(domC("style", { id, type: "text/css", textContent: innerHTML }));
};
var createButtonFontSize12 = (innerHTML, extraCLass = "", extra = {}) => domC("button", {
innerHTML,
className: `jimi-button ${extraCLass}`,
style: "margin-left: 8px;font-size: 12px;",
...extra
});
var myPreview = {
open: function(src, even, isVideo) {
const nameDom = isVideo ? this.evenPathVideo : this.evenPathImg;
const idDom = isVideo ? this.idVideo : this.idImg;
const nodeName = dom(nameDom);
const nodeId = domById(idDom);
nodeName && (nodeName.src = src);
nodeId && (nodeId.style.display = "block");
even && (this.even = even);
myScroll.stop();
},
hide: function(pEvent) {
if (this.even) {
this.even.click();
this.even = null;
}
pEvent.style.display = "none";
const nodeImg = dom(this.evenPathImg);
const nodeVideo = dom(this.evenPathVideo);
nodeImg && (nodeImg.src = "");
nodeVideo && (nodeVideo.src = "");
myScroll.on();
},
even: null,
evenPathImg: "#JIMI_PREVIEW_IMAGE img",
evenPathVideo: "#JIMI_PREVIEW_VIDEO video",
idImg: "JIMI_PREVIEW_IMAGE",
idVideo: "JIMI_PREVIEW_VIDEO"
};
var getPreviewImageSrc = (image) => {
// 点击时再取地址,避免缓存懒加载占位图;不拼接或猜测 CDN 原图地址。
const sources = [image.getAttribute("data-original"), image.currentSrc, image.src, image.getAttribute("data-actualsrc")];
return sources.find((src) => /^(https?:)?\/\//.test(src || "")) || image.src ||
image.style.backgroundImage?.match(/url\(["']?(.+?)["']?\)/)?.[1] || "";
};
var initImagePreview = async () => {
const { zoomImageType } = await myStorage.getConfig();
const images = [domA(".TitleImage:not(.jimi-processed)"), domA(".ArticleItem-image:not(.jimi-processed)"), domA(".ztext figure .content_image:not(.jimi-processed)")];
for (let i = 0, imageLen = images.length; i < imageLen; i++) {
const ev = images[i];
for (let index2 = 0, len = ev.length; index2 < len; index2++) {
const nodeItem = ev[index2];
nodeItem.classList.add("jimi-processed");
nodeItem.onclick = () => myPreview.open(getPreviewImageSrc(nodeItem));
}
}
if (zoomImageType === "2" /* 自定义尺寸 */) {
const originImages = domA(".origin_image:not(.jimi-processed)");
for (let i = 0, len = originImages.length; i < len; i++) {
const nodeItem = originImages[i];
nodeItem.src = nodeItem.getAttribute("data-original") || nodeItem.src;
nodeItem.classList.add("jimi-processed");
nodeItem.style.cssText = "max-width: 100%;";
}
}
};
var HTML_HOOTS = ["www.zhihu.com", "zhuanlan.zhihu.com"];
var CLASS_NOT_INTERESTED = "jimi-not-interested";
var CLASS_TO_QUESTION = "jimi-to-question";
var CLASS_TIME_ITEM = "jimi-list-item-time";
var CLASS_LISTENED = "jimi-listened";
var CLASS_ZHIHU_COMMENT_DIALOG = "css-1aq8hf9";
var EXTRA_CLASS_HTML = {
"zhuanlan.zhihu.com": "zhuanlan",
"www.zhihu.com": "zhihu"
};
var BLOCKED_USER_LIST_TYPE = {
zhihu: "zhihu",
local: "local"
};
var BLOCKED_USER_LIST_CONFIG_KEY = {
zhihu: "blockedUsers",
local: "localBlockedUsers"
};
var mergeTags = (a, b) => [.../* @__PURE__ */ new Set([...a || [], ...b || []])];
var mergeBlockedUser = (prev, next) => ({
...prev,
...next,
tags: mergeTags(prev?.tags, next.tags)
});
var mergeBlockedUsers = (users) => {
const map = /* @__PURE__ */ new Map();
users.forEach((user) => {
if (!user.id) return;
map.set(user.id, mergeBlockedUser(map.get(user.id), user));
});
return [...map.values()];
};
var getAllBlockedUsers = (config) => mergeBlockedUsers([...config.blockedUsers || [], ...config.localBlockedUsers || []]);
var findBlockedUserWithType = (config, id) => {
const zhihuUser = (config.blockedUsers || []).find((item) => item.id === id);
if (zhihuUser) return { user: zhihuUser, listType: BLOCKED_USER_LIST_TYPE.zhihu };
const localUser = (config.localBlockedUsers || []).find((item) => item.id === id);
if (localUser) return { user: localUser, listType: BLOCKED_USER_LIST_TYPE.local };
};
var isZhihuBlockListFullText = (text) => /(黑名单|屏蔽).*(上限|数量|已满|最多)|limit|maximum|too many/i.test(text);
var isZhihuBlockListFullResponse = async (res) => {
if (res.ok) return false;
try {
return isZhihuBlockListFullText(await res.clone().text());
} catch {
return false;
}
};
var updateItemAfterBlock = async (userInfo, listType = BLOCKED_USER_LIST_TYPE.zhihu) => {
const config = await myStorage.getConfig();
const listKey = BLOCKED_USER_LIST_CONFIG_KEY[listType];
const otherListKey = listType === BLOCKED_USER_LIST_TYPE.zhihu ? BLOCKED_USER_LIST_CONFIG_KEY.local : BLOCKED_USER_LIST_CONFIG_KEY.zhihu;
const prevList = config[listKey] || [];
const prevUser = prevList.find((item) => item.id === userInfo.id);
const nextUser = mergeBlockedUser(prevUser, userInfo);
await myStorage.updateConfig({
...config,
[listKey]: [nextUser, ...prevList.filter((item) => item.id !== userInfo.id)],
[otherListKey]: (config[otherListKey] || []).filter((item) => item.id !== userInfo.id)
});
};
var removeItemAfterBlock = async (userInfo, listType = BLOCKED_USER_LIST_TYPE.zhihu) => {
const config = await myStorage.getConfig();
const listKey = BLOCKED_USER_LIST_CONFIG_KEY[listType];
const blockedUsers = config[listKey] || [];
const itemIndex = blockedUsers.findIndex((i) => i.id === userInfo.id);
if (itemIndex >= 0) {
blockedUsers.splice(itemIndex, 1);
await myStorage.updateConfigItem(listKey, blockedUsers);
}
};
var getXSRFToken = () => document.cookie.match(/(?<=_xsrf=)[\w-]+(?=;)/)?.[0] || "";
var addBlockUser = (userInfo) => {
const { name, urlToken } = userInfo;
return new Promise((resolve) => {
const headers = store.getFetchHeaders();
fetch(`https://www.zhihu.com/api/v4/members/${urlToken}/actions/block`, {
method: "POST",
headers: new Headers({
...headers,
"x-xsrftoken": getXSRFToken()
}),
credentials: "include"
}).then(async (res) => {
if (res.ok) {
await updateItemAfterBlock(userInfo, BLOCKED_USER_LIST_TYPE.zhihu);
resolve(BLOCKED_USER_LIST_TYPE.zhihu);
return;
}
if (await isZhihuBlockListFullResponse(res)) {
await updateItemAfterBlock(userInfo, BLOCKED_USER_LIST_TYPE.local);
fnLog("知乎黑名单已满,已添加至本地黑名单");
resolve(BLOCKED_USER_LIST_TYPE.local);
return;
}
fnLog(`屏蔽用户失败:${name}`);
resolve(void 0);
}).catch(() => {
fnLog(`屏蔽用户失败:${name}`);
resolve(void 0);
});
});
};
var removeBlockUser = (info) => {
return new Promise((resolve) => {
const { urlToken } = info;
const headers = store.getFetchHeaders();
fetch(`https://www.zhihu.com/api/v4/members/${urlToken}/actions/block`, {
method: "DELETE",
headers: new Headers({
...headers,
"x-xsrftoken": getXSRFToken()
}),
credentials: "include"
}).then(async () => {
await removeItemAfterBlock(info, BLOCKED_USER_LIST_TYPE.zhihu);
resolve();
});
});
};
var interceptResponseForBlocked = async (res, opt) => {
if (/\/api\/v4\/members\/[^/]+\/actions\/block/.test(res.url)) {
if (dom(".ProfileHeader-contentFooter .MemberButtonGroup")) {
const jsInitData = store.getJsInitialData();
let userInfo = void 0;
try {
const currentUserInfo = jsInitData.initialState.entities.users;
Object.entries(currentUserInfo).forEach(([key, value]) => {
if (value.name && location.pathname.includes(key)) {
const { id, name, urlToken } = value;
userInfo = { id, name, urlToken };
}
});
} catch {
}
if (opt && userInfo) {
if (opt.method === "POST") {
if (res.ok) {
updateItemAfterBlock(userInfo, BLOCKED_USER_LIST_TYPE.zhihu);
} else if (await isZhihuBlockListFullResponse(res)) {
updateItemAfterBlock(userInfo, BLOCKED_USER_LIST_TYPE.local);
fnLog("知乎黑名单已满,已添加至本地黑名单");
}
}
opt.method === "DELETE" && res.ok && removeItemAfterBlock(userInfo, BLOCKED_USER_LIST_TYPE.zhihu);
}
}
}
};
var CLASS_TOP_BLOCK = "jimi-top-block-in-user-home";
var blockObserver;
var index = 0;
var topBlockUser = async () => {
const { userHomeTopBlockUser } = await myStorage.getConfig();
const nodeUserHeaderOperate = dom(".ProfileHeader-contentFooter .MemberButtonGroup");
const nodeFooterOperations = dom(".Profile-footerOperations");
if (!nodeUserHeaderOperate || !userHomeTopBlockUser || !nodeFooterOperations) return;
const isMe = nodeUserHeaderOperate.innerText.includes("编辑个人资料");
if (isMe) return;
const domProfileHeader = domById("ProfileHeader");
if (!domProfileHeader || !domProfileHeader.dataset.zaExtraModule) {
setTimeout(topBlockUser, 500);
return;
}
const isBlocked = nodeUserHeaderOperate.innerText.includes("已屏蔽");
const domFind = dom(`.${CLASS_TOP_BLOCK}`);
domFind && domFind.remove();
const nDomButton = domC("button", {
className: `Button Button--primary Button--red ${CLASS_TOP_BLOCK}`,
innerText: isBlocked ? "解除屏蔽" : "屏蔽用户"
});
const domUnblock = nodeUserHeaderOperate.firstChild;
const domBlock = nodeFooterOperations.firstChild;
nDomButton.onclick = function() {
if (isBlocked) {
domUnblock.click();
} else {
domBlock.click();
}
};
nodeUserHeaderOperate.insertBefore(nDomButton, domUnblock);
blockObserver && blockObserver.disconnect();
blockObserver = new MutationObserver(() => {
topBlockUser();
});
blockObserver.observe(nodeFooterOperations, {
attributes: false,
childList: true,
characterData: false,
characterDataOldValue: false,
subtree: true
});
if (index === 0) {
index++;
setTimeout(topBlockUser, 1e3);
}
};
var VERSION_MIN_WIDTH = isIPhoneLayout ? 0 : 600;
var mySize = {
init: function() {
fnAppendStyle("JIMI_STYLE_VERSION", this.content());
},
content: function() {
const config = applyCodePreset();
const {
commitModalSizeSameVersion,
versionArticle,
versionArticleIsPercent,
versionArticlePercent,
zoomImageType,
zoomImageHeight,
zoomImageHeightSize,
zoomImageSize,
zoomListVideoSize,
zoomListVideoType,
fixedListItemMore,
listTitleTagQuestion,
listTitleTagArticle,
listTitleTagVideo,
listTitleTagPin,
themeDark = 1 /* 深色一 */,
themeLight = 0 /* 默认 */,
suspensionHomeTabPo,
suspensionHomeTab,
suspensionFindPo,
suspensionUserPo,
suspensionSearchPo,
highlightListItem,
linkShopping,
fontSizeForList,
fontSizeForAnswer,
fontSizeForArticle,
fontSizeForListTitle,
fontSizeForAnswerTitle,
fontSizeForArticleTitle,
contentLineHeight
} = config;
const dark = isDark();
const formatVersionPercentSize = (name) => isIPhoneLayout ? "100%" : !config[`${name}IsPercent`] ? `${config[name] || "1000"}px` : `${config[`${name}Percent`] || "70"}vw`;
const versionSizeHome = formatVersionPercentSize("versionHome");
const versionSizeAnswer = formatVersionPercentSize("versionAnswer");
const versionSizeArticle = formatVersionPercentSize("versionArticle");
const versionSizeUserHome = formatVersionPercentSize("versionUserHome");
const versionSizeCollection = formatVersionPercentSize("versionCollection");
const NAME_HOME = ".Topstory-mainColumn,.SearchMain";
const NAME_ANSWER = ".QuestionPage,.QuestionHeader-footer-inner,.QuestionHeader .QuestionHeader-content,.QuestionPage>div";
const NAME_ARTICLE = ".Post-NormalSub>div,.zhuanlan .Post-Row-Content,.zhuanlan .css-pi1fiy";
const NAME_USER_HOME = '#ProfileHeader,[itemprop="people"] .Profile-main';
const NAME_COLLECTION = ".CollectionsDetailPage";
const xxxWidth = `${NAME_HOME}{width: ${versionSizeHome}!important;}${NAME_ANSWER}{width: ${versionSizeAnswer}!important;margin: 0 auto; padding: 0;}${NAME_ARTICLE}{width: ${versionSizeArticle}!important;}.zhuanlan .Post-SideActions{right: ${!versionArticleIsPercent ? `calc(50vw - ${+(versionArticle || "1000") / 2 + 150}px)` : `calc(50vw - ${+(versionArticlePercent || "70") / 2}vw + 150px)`}}${NAME_USER_HOME}{width: ${versionSizeUserHome}!important;}${NAME_COLLECTION}{width: ${versionSizeCollection}!important}${NAME_HOME},${NAME_ANSWER},${NAME_ARTICLE},${NAME_USER_HOME},${NAME_COLLECTION},.${CLASS_ZHIHU_COMMENT_DIALOG},.Topstory-body .${CLASS_ZHIHU_COMMENT_DIALOG},.PostIndex-body .${CLASS_ZHIHU_COMMENT_DIALOG}{min-width: ${VERSION_MIN_WIDTH}px!important;}` + fnReturnStr(
`.Topstory-body .${CLASS_ZHIHU_COMMENT_DIALOG}{width: ${versionSizeHome}!important;max-width:100vw;}.PostIndex-body .${CLASS_ZHIHU_COMMENT_DIALOG}{width: ${versionSizeArticle}!important;max-width:100vw;}` + fnReturnStr(`.${CLASS_ZHIHU_COMMENT_DIALOG}{width: ${versionSizeAnswer}!important;max-width:100vw;}`, location.pathname.includes("question")) + fnReturnStr(`.${CLASS_ZHIHU_COMMENT_DIALOG}{width: ${versionSizeCollection}!important;max-width:100vw;}`, location.pathname.includes("collection")) + fnReturnStr(`.${CLASS_ZHIHU_COMMENT_DIALOG}{width: ${versionSizeUserHome}!important;max-width:100vw;}`, location.pathname.includes("people")),
commitModalSizeSameVersion
);
const xxxHiddenListArticleTopImg = zoomImageHeight === "1" /* 开启 */ || zoomImageType === "2" /* 自定义尺寸 */ ? ".ContentItem .css-75aco3{display: none;}" : "";
const xxxImage = `img.lazy,img.origin_image,.GifPlayer img,.ArticleItem-image,.ztext figure .content_image,.ztext figure .origin_image,.TitleImage{${(zoomImageHeight === "1" /* 开启 */ ? `max-height: ${zoomImageHeightSize}px!important;width: auto!important;` : "") || (zoomImageType === "2" /* 自定义尺寸 */ ? `width: ${zoomImageSize}px!important;cursor: zoom-in!important;max-width: 100%!important;` : "")}}` + xxxHiddenListArticleTopImg;
const xxxVideo = `.ZVideoItem>div:first-of-type{${fnReturnStr(`width: ${zoomListVideoSize}px!important;`, zoomListVideoType === "2" /* 自定义尺寸 */)}}`;
const xxxListMore = fnReturnStr(
`.Topstory-container .ContentItem-actions .ShareMenu ~ div.ContentItem-action{visibility: visible!important;position: absolute;top: 20px;right: 10px;}`,
fixedListItemMore
);
const xxxTitleTag = fnReturnStr(
`.AnswerItem .ContentItem-title::before{content:'「问答」';color:#ec7259;font-size:14px;}.TopstoryQuestionAskItem .ContentItem-title::before{content:'「提问」';font-size:14px;color:#533b77}`,
listTitleTagQuestion
) + fnReturnStr(`.ArticleItem .ContentItem-title::before{content:'「文章」';font-size:14px;color:#00965e}`, listTitleTagArticle) + fnReturnStr(
`.ZvideoItem .ContentItem-title::before{content:'「视频」';font-size:14px;color:#12c2e9}.ZVideoItem .ContentItem-title::before{content:'「视频」';font-size:14px;color:#12c2e9}`,
listTitleTagVideo
) + fnReturnStr(
`.TopstoryItem .PinItem::before{content:'「想法」';font-size:14px;color:#9c27b0;margin-right:6px;font-weight:normal;display:inline;}.PinItem>.ContentItem-title{margin-top:4px;}`,
listTitleTagPin
);
const xxxSusHomeTab = fnReturnStr(
`.Topstory-container .TopstoryTabs{${suspensionHomeTabPo}position:fixed;z-index:100;display:flex;flex-direction:column;height:initial!important;}.Topstory-container .TopstoryTabs>a{font-size:0 !important;border-radius:50%}.Topstory-container .TopstoryTabs>a::after{font-size:16px !important;display:inline-block;padding:6px 8px;margin-bottom:4px;border:1px solid #999999;color:#999999;background: ${dark ? THEME_CONFIG_DARK[themeDark].background : THEME_CONFIG_LIGHT[themeLight].background || "transparent"};}.Topstory-container .TopstoryTabs>a.TopstoryTabs-link {margin:0!important}.Topstory-container .TopstoryTabs>a.TopstoryTabs-link.is-active::after{color:#0066ff!important;border-color:#0066ff!important;}.Topstory [aria-controls='Topstory-recommend']::after{content:'推';}.Topstory [aria-controls='Topstory-follow']::after{content:'关';border-top-left-radius:4px;border-top-right-radius:4px;}.Topstory [aria-controls='Topstory-hot']::after{content:'热';}.Topstory [aria-controls="Topstory-zvideo"]::after{content:'视';border-bottom-left-radius:4px;border-bottom-right-radius:4px}.Topstory-tabs{border-color: transparent!important;}`,
suspensionHomeTab
);
const xxxSusHeader = `.position-suspensionFind{${suspensionFindPo}}.position-suspensionUser{${suspensionUserPo}}.position-suspensionSearch{${suspensionSearchPo}}.position-suspensionFind .Tabs-link{border:1px solid #999999;color:#999999;background: ${dark ? THEME_CONFIG_DARK[themeDark].background : THEME_CONFIG_LIGHT[themeLight].background || "transparent"};}.position-suspensionFind .Tabs-link.is-active{color:#0066ff!important;border-color:#0066ff!important;}.position-suspensionUser .css-1m60na {display: none;}.position-suspensionUser .css-1n0eufo{margin-right: 0;}`;
const xxxHighlight = highlightListItem ? `.List-item:focus,.TopstoryItem:focus,.HotItem:focus{box-shadow:0 0 0 2px #fff,0 0 0 5px rgba(0, 102, 255, 0.3)!important;outline:none!important;transition:box-shadow 0.3s!important;}` : `.List-item:focus,.Card:focus::before{box-shadow: none!important;}`;
const cssShoppingLinkObj = {
["0" /* 默认 */]: "",
["1" /* 仅文字 */]: '.MCNLinkCard-imageContainer,.MCNLinkCard-button,.MCNLinkCard-source,.ecommerce-ad-commodity-img,.ecommerce-ad-commodity-box-icon,.RichText-MCNLinkCardContainer .BottomInfo,.CPSCommonCard-imageBox,.RedPacketCard-imageBox,.CPSCommonCard-tool,.CPSCommonCard-subtitle,.RedPacketCard-subtitle,.RedPacketCard-tool{display: none!important;}.MCNLinkCard,.MCNLinkCard-card,.ecommerce-ad-commodity,.RichText-MCNLinkCardContainer .GoodsRecommendCard,.CPSCommonCard,.RedPacketCard-info,.RedPacketCard{min-height: 0!important;background: transparent!important;width:100%!important;max-width:100%!important;}.MCNLinkCard-cardContainer,.ecommerce-ad-commodity,.ecommerce-ad-commodity-main,.RedPacketCard,.CPSCommonCard{padding: 0!important;}.MCNLinkCard,.MCNLinkCard-info{margin: 0!important;}.MCNLinkCard-info,.ecommerce-ad-commodity-main{flex-direction: row!important;}.MCNLinkCard-price{padding-left: 12px;}.ecommerce-ad-commodity-box .ecommerce-ad-commodity{height: auto!important;}.ecommerce-ad-commodity-box-main-second{width: auto!important;}.MCNLinkCard-titleContainer,.ecommerce-ad-commodity-main-content-des span,.CPSCommonCard-title,.RedPacketCard-title{color: #fd8d55!important;justify-content: start!important;}.MCNLinkCard-titleContainer::before,.ecommerce-ad-commodity-main-content-des span::before,.CPSCommonCard-title::before,.RedPacketCard-title::before{content: "购物链接:"}.MCNLinkCard-title{color: #fd8d55!important;}',
["2" /* 隐藏 */]: "a.MCNLinkCard,.RichText-ADLinkCardContainer,.ecommerce-ad-commodity-box,.ecommerce-ad-box,.RichText-MCNLinkCardContainer{display: none!important;}"
};
const xxxShoppingLink = cssShoppingLinkObj[linkShopping || "0" /* 默认 */];
const xxxFontSize = fnReturnStr(
`.Topstory-body .RichContent-inner,.Topstory-body .jimi-list-item-time,.Topstory-body .CommentContent,.SearchResult-Card .RichContent-inner,.SearchResult-Card .CommentContent,.HotItem-excerpt--multiLine{font-size: ${fontSizeForList}px!important;}`,
!!fontSizeForList
) + fnReturnStr(`.QuestionPage .RichContent-inner,.QuestionPage .jimi-list-item-time,.QuestionPage .CommentContent{font-size: ${fontSizeForAnswer}px}`, !!fontSizeForAnswer) + fnReturnStr(`.zhuanlan .Post-RichTextContainer,.zhuanlan .jimi-article-create-time,.zhuanlan .CommentContent{font-size: ${fontSizeForArticle}px}`, !!fontSizeForArticle) + fnReturnStr(`.zhuanlan .Post-Main .Post-Title{font-size: ${fontSizeForArticleTitle}px;}`, !!fontSizeForArticleTitle) + fnReturnStr(`.ContentItem-title,.HotItem-title{font-size: ${fontSizeForListTitle}px!important;}`, !!fontSizeForListTitle) + fnReturnStr(`.QuestionHeader-title{font-size: ${fontSizeForAnswerTitle}px!important;}`, !!fontSizeForAnswerTitle) + fnReturnStr(`p {line-height: ${contentLineHeight}px;}`, !!contentLineHeight);
return xxxFontSize + xxxHighlight + xxxImage + xxxListMore + xxxShoppingLink + xxxSusHeader + xxxSusHomeTab + xxxTitleTag + xxxVideo + xxxWidth;
}
};
var changeSizeBeforeResize = async () => {
const { suspensionPickupRight, suspensionPickUp } = await myStorage.getConfig();
if (!suspensionPickUp) return;
const prevContentBox = domById("TopstoryContent") || dom(".Question-mainColumn") || domById("SearchMain") || dom(".Profile-mainColumn") || dom(".CollectionsDetailPage-mainColumn") || document.body;
const nodeContentBox = prevContentBox.offsetWidth > document.body.offsetWidth ? document.body : prevContentBox;
let suspensionRight = +(suspensionPickupRight || 0);
if (nodeContentBox) {
suspensionRight = window.innerWidth - nodeContentBox.getBoundingClientRect().width - nodeContentBox.getBoundingClientRect().left + +(suspensionPickupRight || 0);
}
fnAppendStyle(
"JIMI_STYLE_CHANGE_AFTER_RESIZE",
fnReturnStr(`.ContentItem-actions.Sticky.is-fixed button[data-zop-retract-question="true"]{right: ${suspensionRight}px;}`, suspensionPickUp)
);
};
var CLASS_BLOCK_USER_BOX = "jimi-block-user-box";
var CLASS_BTN_ADD_BLOCKED = "jimi-block-add-blocked";
var CLASS_BTN_REMOVE_BLOCKED = "jimi-block-remove-blocked";
var createBlockedUserTagHTML = (showBlockTagType, userInfo) => `黑名单${showBlockTagType && userInfo && userInfo.tags && userInfo.tags.length ? ":" + userInfo.tags.join("、") : ""}`;
var answerAddBlockButton = async (contentItem) => {
const nodeUser = contentItem.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
if (!nodeUser || !nodeUser.offsetHeight) return;
if (nodeUser.querySelector(`.${CLASS_BLOCK_USER_BOX}`)) return;
const userUrl = nodeUser.querySelector('meta[itemprop="url"]').content;
const userName = nodeUser.querySelector('meta[itemprop="name"]').content;
const mo = contentItem.getAttribute("data-za-extra-module") || "{}";
if (!JSON.parse(mo).card) return;
const aContent = JSON.parse(mo).card.content;
const userId = aContent.author_member_hash_id || "";
if (!userUrl.replace(/https:\/\/www.zhihu.com\/people\//, "")) return;
const config = await myStorage.getConfig();
const { showBlockUserTag, showBlockUser, showBlockUserTagType } = config;
const blockedUserInfo = findBlockedUserWithType(config, userId);
let currentBlockedSource = blockedUserInfo?.listType;
let currentBlockedUser = blockedUserInfo?.user;
const nBlackBox = domC("div", {
className: CLASS_BLOCK_USER_BOX,
innerHTML: changeBlockedUsersBox(!!blockedUserInfo, showBlockUser, showBlockUserTag, showBlockUserTagType, currentBlockedUser)
});
nBlackBox.onclick = async function(ev) {
const target = ev.target;
const matched = userUrl.match(/(?<=people\/)[\w\W]+/);
const urlToken = matched ? matched[0] : "";
const nextUserInfo = { id: userId, name: userName, urlToken };
const me = this;
if (target.classList.contains(CLASS_BTN_ADD_BLOCKED)) {
const listType = await addBlockUser(nextUserInfo);
if (!listType) return;
currentBlockedSource = listType;
currentBlockedUser = nextUserInfo;
me.innerHTML = changeBlockedUsersBox(true, showBlockUser, showBlockUserTag, showBlockUserTagType, currentBlockedUser);
return;
}
if (target.classList.contains(CLASS_BTN_REMOVE_BLOCKED)) {
if (currentBlockedSource === BLOCKED_USER_LIST_TYPE.local) {
await removeItemAfterBlock(nextUserInfo, BLOCKED_USER_LIST_TYPE.local);
} else {
await removeBlockUser(nextUserInfo);
}
currentBlockedSource = void 0;
currentBlockedUser = void 0;
me.innerHTML = changeBlockedUsersBox(false, showBlockUser, showBlockUserTag, showBlockUserTagType);
return;
}
};
nodeUser.appendChild(nBlackBox);
};
var changeBlockedUsersBox = (isBlocked, showBlock, showBlockTag, showBlockTagType, userInfo) => {
if (isBlocked) {
return fnReturnStr(createBlockedUserTagHTML(showBlockTagType, userInfo), showBlockTag) + fnReturnStr(``, showBlock);
} else {
return fnReturnStr(``, showBlock);
}
};
var CLASS_CAN_COPY = "jimi-can-copy";
var canCopy = () => {
domA(`.RichContent-inner:not(.${CLASS_CAN_COPY})`).forEach((item) => {
item.classList.add(CLASS_CAN_COPY);
item.oncopy = (event) => {
eventCopy(event);
return true;
};
});
};
var eventCopy = (event) => {
let clipboardData = event.clipboardData;
if (!clipboardData) return;
const selection = window.getSelection();
if (!selection) return;
const range = selection.getRangeAt(0);
const container = document.createElement("div");
container.appendChild(range.cloneContents());
const html = container.innerHTML;
let text = selection ? selection.toString() : "";
if (text) {
event.preventDefault();
clipboardData.setData("text/html", html);
clipboardData.setData("text/plain", text);
}
};
var copy = async (value) => {
if (navigator.clipboard && navigator.permissions) {
await navigator.clipboard.writeText(value);
} else {
const domTextarea = domC("textArea", {
value,
style: "width: 0px;position: fixed;left: -999px;top: 10px;"
});
domTextarea.setAttribute("readonly", "readonly");
document.body.appendChild(domTextarea);
domTextarea.select();
document.execCommand("copy");
document.body.removeChild(domTextarea);
}
};
var initLinkChanger = () => {
const esName = ["a.external", "a.LinkCard"];
for (let i = 0, len = esName.length; i < len; i++) {
const name = esName[i];
const links = domA(`${name}:not(.jimi-link-changed)`);
for (let index2 = 0, linkLen = links.length; index2 < linkLen; index2++) {
const item = links[index2];
if (!item.hasAttribute("href")) continue;
const hrefFormat = item.href.replace(/^(https|http):\/\/link\.zhihu\.com\/\?target\=/, "") || "";
let href = "";
try {
href = decodeURIComponent(hrefFormat);
} catch {
href = hrefFormat;
}
item.href = href;
item.classList.add("jimi-link-changed");
}
}
};
var addAnswerCopyLink = async (contentItem) => {
const { copyAnswerLink } = await myStorage.getConfig();
if (!copyAnswerLink) return;
const prevButton = contentItem.querySelector(`.jimi-copy-answer-link`);
prevButton && prevButton.remove();
const nodeUser = contentItem.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
if (!nodeUser) return;
const nDomButton = createButtonFontSize12("获取回答链接", "jimi-copy-answer-link");
nDomButton.onclick = function() {
const metaUrl = contentItem.querySelector(':scope>[itemprop="url"]');
if (!metaUrl) return;
const link = metaUrl.getAttribute("content") || "";
if (link) {
copy(link);
return;
}
};
nodeUser.appendChild(nDomButton);
};
var addNotInterestedItem = async (name) => {
const { notInterestedList = [] } = await myStorage.getConfig();
if (!notInterestedList.includes(name)) {
await myStorage.updateConfigItem("notInterestedList", [name, ...notInterestedList]);
}
};
var INNER_HTML = ``;
var INNER_CSS = `[theme-dark='0'] .jimi-button:hover,[theme-dark='1'] .jimi-button:hover,[theme-dark='2'] .jimi-button:hover,[theme-dark='3'] .jimi-button:hover,[theme-dark='4'] .jimi-button:hover,[theme-dark='7'] .jimi-button:hover{color:#62605e}[theme-dark='5'] .jimi-button:hover{color:#62605e}[theme-dark='6'] .jimi-button:hover{color:#62605e}.jimi-button{outline:none;position:relative;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;transition:all .3s;user-select:none;touch-action:manipulation;font-size:13px;height:24px;padding:0px 8px;border-radius:4px;border:1px solid transparent;background-color:#fff;border-color:rgba(150,162,170,0.4);font-weight:400;box-sizing:border-box}.jimi-button:hover{font-weight:600;background:#eeeeee}.jimi-button:active{background:#e0e0e0;font-weight:400}.jimi-button-red{color:#ff3b30 !important;border:1px solid #ff3b30 !important}.jimi-button-red:hover{color:#ff453a !important;border:1px solid #ff453a !important}.jimi-button:disabled{border-color:#d0d0d0;background-color:rgba(0,0,0,0.08);color:#b0b0b0;cursor:not-allowed}.Profile-mainColumn,.Collections-mainColumn,.CollectionsDetailPage-mainColumn{flex:1}#root .css-1liaddi{margin-right:0}.ContentItem-title div{display:inline}.css-1acwmmj:empty{display:none !important}.css-hr0k1l::after{content:'点击键盘左、右按键切换图片';position:absolute;bottom:20px;left:50%;transform:translateX(-50%);color:#fff}.HotLanding-contentItemCount.HotLanding-contentItemCountWithoutSub{margin-top:12px}body[data-suspension-pickup='true'] .ContentItem-actions.Sticky.is-fixed button[data-zop-retract-question='true']{position:fixed;bottom:50px;background:#fff;padding:6px 12px;box-shadow:0 2px 8px #c9c9c9,0 -2px 8px #ffffff;border-radius:8px}body[data-suspension-pickup='true'] .ContentItem-actions.Sticky.is-fixed button[data-zop-retract-question='true']:hover{background:#fff;color:#007aff !important;font-weight:600}body[data-suspension-pickup='true'] .ContentItem-actions.Sticky.is-fixed button[data-zop-retract-question='true']:active{font-weight:200 !important}.Topstory-container,.css-knqde,.Search-container{width:fit-content !important}.QuestionPage .Question-mainColumn,.QuestionHeader-main{flex:1}.QuestionPage{padding:0}.QuestionPage .List-item{border-bottom:1px dashed #ddd}.QuestionPage .Question-mainColumn{width:initial}.Post-Row-Content .Post-Row-Content-right{width:auto}.QuestionHeader{min-width:auto}.QuestionHeader .QuestionHeader-content{margin:0 auto;padding:0;max-width:initial !important}.GifPlayer.isPlaying img{cursor:pointer !important}.AppHeader-inner{margin:0 auto !important;padding:0 !important;min-width:min-content !important;width:fit-content !important}.zhuanlan .Post-Row-Content-left{flex:1}.zhuanlan .Post-Row-Content-right{margin-left:10px}.zhuanlan .css-1pariuy,.zhuanlan .css-44kk6u{max-width:none}.zhuanlan .css-9w3zhd,.zhuanlan .css-12tmx22,.zhuanlan .css-1bcbfml{width:auto}.Topstory-content>div{width:auto !important}.gear{width:24px;height:24px;position:relative;border-radius:50%;box-sizing:border-box;border:6px solid #8e8e93;background:transparent}.gear_line_1,.gear_line_2,.gear_line_3,.gear_line_4{position:absolute;box-sizing:border-box;width:30px;height:6px;border-radius:2px;border-left:6px solid #8e8e93;border-right:6px solid #8e8e93;left:50%;top:50%;transform:translate(-50%, -50%)}.gear_line_2{transform:translate(-50%, -50%) rotate(45deg)}.gear_line_3{transform:translate(-50%, -50%) rotate(90deg)}.gear_line_4{transform:translate(-50%, -50%) rotate(135deg)}.jimi-zhida{color:#09408e;margin:0 2px}.jimi-zhida span{font-size:10px;display:inline-block;vertical-align:top;height:15px;line-height:15px}#JIMI_HIDDEN{padding-top:0 !important}.jimi-button-black{margin-left:8px}.jimi-blocked-content-replacement{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jimi-blocked-content-replacement-text{display:inline-block;line-height:22px}.jimi-block-user-box button{font-size:12px;margin-left:8px}.jimi-video-download{position:absolute;top:20px;left:20px;font-size:24px;color:#fff;cursor:pointer}.jimi-loading{animation:loadingAnimation 2s infinite;font-size:24px;color:#91919d;cursor:none}@keyframes loadingAnimation{from{transform:rotate(0)}to{transform:rotate(360deg)}}.jimi-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)}.jimi-preview div{display:flex;justify-content:center;align-items:center;min-height:100%;width:100%}.jimi-preview div img{cursor:zoom-out;user-select:none}.jimi-question-time{font-size:13px !important;font-weight:normal !important;line-height:24px}.jimi-stop-scroll{height:100% !important;overflow:hidden !important}.jimi-export-collection-box{float:right;text-align:right}.jimi-export-collection-box p{font-size:13px;color:#666;margin:4px 0}.jimi-people-export-progress{display:inline-flex;align-items:center;gap:6px;margin-left:8px;color:#666;font-size:12px;vertical-align:middle}.jimi-people-export-progress-track{display:inline-block;width:90px;height:6px;overflow:hidden;border-radius:4px;background:#e5e5e5}.jimi-people-export-progress-bar{display:block;width:0;height:100%;transition:width .2s;background:#007aff}.jimi-pdf-dialog-item{padding:12px;border-bottom:1px solid #eee;margin:12px;background:#ffffff}.jimi-pdf-dialog-title{margin:0 0 1.4em;font-size:20px;font-weight:bold}.jimi-pdf-box-content{width:100%;background:#ffffff}.jimi-pdf-view{width:100%;background:#ffffff;word-break:break-all;white-space:pre-wrap;font-size:13px;overflow-x:hidden}.jimi-pdf-view a{color:#0066ff}.jimi-pdf-view img{max-width:100%}.jimi-pdf-view p{margin:1.4em 0}`;
var CLASS_PEOPLE_EXPORT_PROGRESS = "jimi-people-export-progress";
var PROFILE_EXPORT_LIMIT = 20;
var parseJSONAttr = (value) => {
if (!value) return void 0;
try {
return JSON.parse(value);
} catch {
return void 0;
}
};
var normalizeContentId = (value) => {
if (value === void 0 || value === null) return "";
const str = String(value);
const matched = str.match(/\d+/g);
return matched ? matched[matched.length - 1] : str;
};
var getVisibleProfileItems = (contentClassName) => Array.from(domA(`.Profile-main .ListShortcut .List-item .${contentClassName}`)).filter((item) => item.offsetParent || item.getClientRects().length);
var getProfileItemId = (contentItem, type) => {
const dataZop = parseJSONAttr(contentItem.getAttribute("data-zop"));
const dataZaExtra = parseJSONAttr(contentItem.getAttribute("data-za-extra-module"));
const attrId = dataZop?.itemId || dataZaExtra?.card?.content?.token;
if (attrId) return normalizeContentId(attrId);
const hrefSelector = type === "answer" ? 'a[href*="/answer/"]' : 'a[href*="/p/"]';
const link = contentItem.querySelector(hrefSelector);
const href = link ? link.href || link.getAttribute("href") || "" : "";
const matched = href.match(type === "answer" ? /\/answer\/(\d+)/ : /\/p\/(\d+)/);
return matched ? matched[1] : "";
};
var getExportDataId = (item) => normalizeContentId(item && item.id);
var mergeProfileExportData = (...dataList) => {
const data = [];
const dataMap = /* @__PURE__ */ new Map();
dataList.forEach((list) => {
list.forEach((item) => {
const id = getExportDataId(item);
if (!id) {
data.push(item);
return;
}
if (!dataMap.has(id)) {
dataMap.set(id, item);
data.push(item);
}
});
});
return data;
};
var orderProfileExportData = (data, visibleItems, type) => {
const visibleIds = visibleItems.map((item) => getProfileItemId(item, type)).filter(Boolean);
if (!visibleIds.length || visibleIds.length !== visibleItems.length) return data.slice(0, visibleItems.length);
const dataMap = /* @__PURE__ */ new Map();
data.forEach((item) => {
const id = getExportDataId(item);
id && dataMap.set(id, item);
});
const orderedData = visibleIds.map((id) => dataMap.get(id)).filter(Boolean);
return orderedData.length === visibleIds.length ? orderedData : data.slice(0, visibleItems.length);
};
var createProfileExportProgress = (eventBtn) => {
let nodeProgress = eventBtn.parentElement?.querySelector(`.${CLASS_PEOPLE_EXPORT_PROGRESS}`);
if (!nodeProgress) {
nodeProgress = domC("span", {
className: CLASS_PEOPLE_EXPORT_PROGRESS,
innerHTML: `已加载 0/0`
});
insertAfter(nodeProgress, eventBtn);
}
return nodeProgress;
};
var updateProfileExportProgress = (nodeProgress, loaded, total) => {
const nodeText = nodeProgress.querySelector(".jimi-people-export-progress-text");
const nodeBar = nodeProgress.querySelector(".jimi-people-export-progress-bar");
const countLoaded = Math.min(loaded, total);
const percent = total ? Math.floor(countLoaded / total * 100) : 0;
nodeText.innerText = `已加载 ${countLoaded}/${total}`;
nodeBar.style.width = `${percent}%`;
};
var getProfileUrlToken = (requestUrl) => {
const apiMatched = requestUrl.match(/\/api\/v4\/members\/([^/]+)\/(?:answers|articles)/);
if (apiMatched) return apiMatched[1];
const pathMatched = location.pathname.match(/\/(?:people|org)\/([^/]+)/);
return pathMatched ? pathMatched[1] : "";
};
var normalizeProfileExportUrl = (urlValue) => {
if (!urlValue) return "";
const url = new URL(urlValue, location.origin);
if (location.protocol === "https:" && url.protocol === "http:") {
url.protocol = "https:";
}
return url.href;
};
var createProfileExportUrl = (apiPath, requestUrl, offset, limit) => {
const token = getProfileUrlToken(requestUrl);
if (!token) return "";
const url = new URL(requestUrl || `/api/v4/members/${token}/${apiPath}`, location.origin);
url.pathname = `/api/v4/members/${token}/${apiPath}`;
url.searchParams.set("offset", String(offset));
url.searchParams.set("limit", String(limit));
return normalizeProfileExportUrl(url.href);
};
var getExportFetchHeaders = () => {
const headers = new Headers(store.getFetchHeaders());
["vod-authorization", "content-encoding", "Content-Type", "content-type"].forEach((name) => headers.delete(name));
return headers;
};
var fetchProfileExportData = async (apiPath, requestUrl, targetCount, nodeProgress) => {
const data = [];
let offset = 0;
let nextUrl = createProfileExportUrl(apiPath, requestUrl, offset, Math.min(Math.max(targetCount, 1), PROFILE_EXPORT_LIMIT));
while (nextUrl && data.length < targetCount) {
const response = await fetch(nextUrl, {
method: "GET",
headers: getExportFetchHeaders()
});
if (!response.ok) throw new Error(`request failed: ${response.status}`);
const res = await response.json();
const currentData = Array.isArray(res.data) ? res.data : [];
data.push(...currentData);
updateProfileExportProgress(nodeProgress, data.length, targetCount);
if (!currentData.length || res.paging?.is_end) break;
offset += currentData.length;
nextUrl = normalizeProfileExportUrl(res.paging?.next || createProfileExportUrl(apiPath, requestUrl, offset, PROFILE_EXPORT_LIMIT));
}
return data.slice(0, targetCount);
};
var runPeopleExport = async ({
eventBtn,
type,
apiPath,
contentClassName,
loadingText,
buttonText,
emptyText,
requestUrl,
cacheData,
toHTML
}) => {
const visibleItems = getVisibleProfileItems(contentClassName);
const total = visibleItems.length;
const nodeProgress = createProfileExportProgress(eventBtn);
eventBtn.innerText = loadingText;
eventBtn.disabled = true;
updateProfileExportProgress(nodeProgress, 0, total);
if (!total) {
eventBtn.innerText = buttonText;
eventBtn.disabled = false;
fnLog(emptyText);
return;
}
try {
const fetchedData = await fetchProfileExportData(apiPath, requestUrl, total, nodeProgress);
const exportData = orderProfileExportData(mergeProfileExportData(fetchedData, cacheData), visibleItems, type);
updateProfileExportProgress(nodeProgress, exportData.length, total);
if (!exportData.length) throw new Error("empty export data");
if (exportData.length < total) {
fnLog(`仅加载到 ${exportData.length}/${total} 条内容,已导出可加载部分`);
}
loadIframePrint(eventBtn, exportData.map(toHTML), buttonText);
} catch (error) {
eventBtn.innerText = buttonText;
eventBtn.disabled = false;
fnLog("个人主页内容导出失败,请稍后重试");
console.error(error);
}
};
var loadIframePrint = (eventBtn, arrHTML, btnText) => {
let max = 0;
let finish = 0;
let error = 0;
const innerHTML = arrHTML.join("");
const iframe = dom(".jimi-pdf-box-content");
if (!iframe.contentWindow) return;
const doc = iframe.contentWindow.document;
doc.body.innerHTML = "";
if (!doc.head.querySelector("style")) {
doc.write(``);
}
doc.write(``);
const nodePDFView = doc.querySelector(".jimi-pdf-view");
const domInner = domC("div", { innerHTML });
max = domInner.querySelectorAll("img").length;
domInner.querySelectorAll("img").forEach((imageItem) => {
const dataOriginal = imageItem.getAttribute("data-original");
if (!dataOriginal) {
imageItem.setAttribute("data-original", imageItem.src);
}
imageItem.src = "";
});
nodePDFView.appendChild(domInner);
const doPrint = () => {
eventBtn.innerText = btnText;
eventBtn.disabled = false;
iframe.contentWindow.print();
};
const imageLoaded = () => {
eventBtn.innerText = `资源加载进度 ${Math.floor(finish / max * 100)}%:${finish}/${max}${error > 0 ? `,${error}张图片资源已失效` : ""}`;
if (finish + error === max) {
doPrint();
}
};
if (nodePDFView.querySelectorAll("img").length) {
nodePDFView.querySelectorAll("img").forEach((imageItem, index2) => {
setTimeout(function() {
imageItem.src = imageItem.getAttribute("data-original");
imageItem.onload = function() {
finish++;
imageLoaded();
};
imageItem.onerror = function() {
error++;
imageLoaded();
};
}, Math.floor(index2 / 5) * 100);
});
} else {
doPrint();
}
};
var myCollectionExport = {
init: async function() {
const { fetchInterceptStatus } = await myStorage.getConfig();
if (!fetchInterceptStatus) return;
const { pathname } = location;
const elementBox = domC("div", { className: `${this.className}`, innerHTML: this.element });
const nodeThis = dom(`.${this.className}`);
nodeThis && nodeThis.remove();
const elementTypeSpan = this.elementTypeSpan;
const nodeCollection = elementBox.querySelector('[name="jimi-export-collection"]');
nodeCollection && (nodeCollection.onclick = function() {
const me = this;
me.innerText = "加载中...";
me.disabled = true;
const matched = pathname.match(/(?<=\/collection\/)\d+/);
const id = matched ? matched[0] : "";
if (!id) return;
const nodeCurrent = dom(".Pagination .PaginationButton--current");
const offset = 20 * (nodeCurrent ? Number(nodeCurrent.innerText) - 1 : 0);
const fetchHeaders = store.getFetchHeaders();
fetch(`/api/v4/collections/${id}/items?offset=${offset}&limit=20`, {
method: "GET",
headers: new Headers(fetchHeaders)
}).then((response) => {
return response.json();
}).then((res) => {
const collectionsHTMLMap = (res.data || []).map((item) => {
const { type, url, question, content, title } = item.content;
switch (type) {
case "zvideo":
return `${elementTypeSpan(type)}${title}
`;
case "answer":
case "article":
default:
return `${elementTypeSpan(type)}${title || question.title}
${content}
`;
}
});
loadIframePrint(me, collectionsHTMLMap, "导出此页内容");
});
});
const nodePageHeaderTitle = dom(".CollectionDetailPageHeader-title");
nodePageHeaderTitle && nodePageHeaderTitle.appendChild(elementBox);
},
className: "jimi-export-collection-box",
element: `仅对此页内容进行导出
`,
elementTypeSpan: (type) => {
const typeObj = {
answer: '「问题」',
zvideo: '「视频」',
article: '「文章」'
};
return typeObj[type] || "";
}
};
var printAnswer = (contentItem) => {
const boxItem = contentItem.classList.contains("AnswerItem") ? contentItem.parentElement : contentItem;
const prevButton = boxItem.querySelector(".jimi-answer-print");
if (prevButton) return;
const nodeUser = boxItem.querySelector(".AnswerItem-authorInfo>.AuthorInfo");
if (!nodeUser) return;
const nButton = createButtonFontSize12("导出回答", "jimi-answer-print");
nButton.onclick = function() {
const nodeUser2 = boxItem.querySelector(".AuthorInfo-name .UserLink-link");
const nodeContent = boxItem.querySelector(".RichContent-inner");
const innerHTML = `${JSON.parse(boxItem.querySelector(".AnswerItem").getAttribute("data-zop") || "{}").title}
${nodeUser2.outerHTML + nodeContent.innerHTML}`;
loadIframePrint(this, [innerHTML], "导出回答");
};
nodeUser.appendChild(nButton);
};
var printArticle = async (contentItem) => {
const { topExportContent } = await myStorage.getConfig();
const prevButton = contentItem.querySelector(".jimi-article-print");
if (prevButton || !topExportContent) return;
const nodeHeader = contentItem.querySelector(".ArticleItem-authorInfo") || contentItem.querySelector(".Post-Header .Post-Title");
if (!nodeHeader) return;
const nButton = createButtonFontSize12("导出文章", "jimi-article-print", { style: "margin: 12px 0;" });
nButton.onclick = function() {
const nodeTitle = contentItem.querySelector(".ContentItem-title>span") || contentItem.querySelector(".Post-Header .Post-Title");
const nodeUser = contentItem.querySelector(".AuthorInfo-name");
const nodeContent = contentItem.querySelector(".RichContent-inner") || contentItem.querySelector(".Post-RichTextContainer");
const innerHTML = `${nodeTitle.innerHTML}
${nodeUser.innerHTML + nodeContent.innerHTML}`;
loadIframePrint(this, [innerHTML], "导出文章");
};
insertAfter(nButton, nodeHeader);
setTimeout(() => {
printArticle(contentItem);
}, 500);
};
var printPeopleAnswer = async () => {
const { fetchInterceptStatus } = await myStorage.getConfig();
const nodeListHeader = dom(".Profile-main .List-headerText");
const prevButton = dom(`.jimi-people-answer-print`);
if (!nodeListHeader || prevButton || !fetchInterceptStatus) return;
const nButton = createButtonFontSize12("导出此页回答", "jimi-people-answer-print");
nButton.onclick = async function() {
await runPeopleExport({
eventBtn: this,
type: "answer",
apiPath: "answers",
contentClassName: "AnswerItem",
loadingText: "加载回答内容中...",
buttonText: "导出此页回答",
emptyText: "当前页面没有可导出的回答",
requestUrl: store.getUserAnswerRequestUrl(),
cacheData: store.getUserAnswer(),
toHTML: (item) => `${item.question?.title || ""}
${item.content || ""}
`
});
};
nodeListHeader.appendChild(nButton);
setTimeout(() => {
printPeopleAnswer();
}, 500);
};
var printPeopleArticles = async () => {
const { fetchInterceptStatus } = await myStorage.getConfig();
const nodeListHeader = dom(".Profile-main .List-headerText");
const prevButton = dom(".jimi-people-export-articles-once");
if (!nodeListHeader || prevButton || !fetchInterceptStatus) return;
const nButton = createButtonFontSize12("导出此页文章", "jimi-people-export-articles-once");
nButton.onclick = async function() {
await runPeopleExport({
eventBtn: this,
type: "article",
apiPath: "articles",
contentClassName: "ArticleItem",
loadingText: "加载文章内容中...",
buttonText: "导出此页文章",
emptyText: "当前页面没有可导出的文章",
requestUrl: store.getUserArticleRequestUrl(),
cacheData: store.getUserArticle(),
toHTML: (item) => `${item.title || ""}
${item.content || ""}
`
});
};
nodeListHeader.appendChild(nButton);
setTimeout(() => {
printPeopleArticles();
}, 500);
};
var updateItemTime = (contentItem) => {
const nodeBox = contentItem.querySelector(".ContentItem-meta");
if (!nodeBox || contentItem.querySelector(`.${CLASS_TIME_ITEM}`)) return;
const dateCreated = contentItem.querySelector('[itemprop="dateCreated"]');
const datePublished = contentItem.querySelector('[itemprop="datePublished"]');
const dateModified = contentItem.querySelector('[itemprop="dateModified"]');
let innerHTML = "";
const create = dateCreated ? dateCreated.content || "" : "";
const published = datePublished ? datePublished.content || "" : "";
const modified = dateModified ? dateModified.content || "" : "";
create && (innerHTML += `创建时间:${formatTime(create, "YYYY-MM-DD HH:mm:ss", true)}`);
published && (innerHTML += `发布时间:${formatTime(published, "YYYY-MM-DD HH:mm:ss", true)}`);
modified && modified !== published && modified !== create && (innerHTML += `|最后修改时间:${formatTime(modified, "YYYY-MM-DD HH:mm:ss", true)}`);
nodeBox.appendChild(
domC("div", {
className: CLASS_TIME_ITEM,
innerHTML,
style: "line-height: 24px;padding-top: 2px;font-size: 13px;color: rgb(132, 145, 165);display:inline-block;"
})
);
};
var questionTimeout;
var questionFindIndex = 0;
var resetQuestionTime = () => {
if (questionFindIndex > 5 || !dom(".jimi-question-time")) {
return;
}
questionFindIndex++;
clearTimeout(questionTimeout);
questionTimeout = setTimeout(addQuestionTime, 500);
};
var addQuestionTime = async () => {
const nodeTime = dom(".jimi-question-time");
nodeTime && nodeTime.remove();
const { questionCreatedAndModifiedTime } = await myStorage.getConfig();
const nodeCreated = dom('[itemprop="dateCreated"]');
const nodeModified = dom('[itemprop="dateModified"]');
const nodeBox = dom(".QuestionPage .QuestionHeader-title");
if (!questionCreatedAndModifiedTime || !nodeCreated || !nodeModified || !nodeBox) {
resetQuestionTime();
return;
}
const create = nodeCreated.content || "";
const modified = nodeModified.content || "";
nodeBox && nodeBox.appendChild(
domC("div", {
className: "jimi-question-time",
innerHTML: `创建时间:${formatTime(create, "YYYY-MM-DD HH:mm:ss", true)}` + (modified && modified !== create ? `|最后修改时间:${formatTime(modified, "YYYY-MM-DD HH:mm:ss", true)}` : ""),
style: "color: rgb(132, 145, 165);"
})
);
resetQuestionTime();
};
var addArticleTime = async () => {
const { articleCreateTimeToTop } = await myStorage.getConfig();
const nodeT = dom(".jimi-article-time");
if (nodeT) return;
const nodeContentTime = dom(".ContentItem-time");
const nodeBox = dom(".Post-Header");
if (!articleCreateTimeToTop || !nodeContentTime || !nodeBox) return;
nodeBox.appendChild(
domC("span", {
className: "jimi-article-time",
style: "line-height: 30px;color: rgb(132, 145, 165);",
innerHTML: nodeContentTime.innerText || ""
})
);
setTimeout(() => {
addArticleTime();
}, 500);
};
var CLASS_VIDEO_ONE = ".css-1h1xzpn";
var CLASS_VIDEO_TWO = ".VideoAnswerPlayer-video";
var CLASS_VIDEO_TWO_BOX = ".VideoAnswerPlayer";
var ANSWER_VIDEO_SELECTOR = "video, .video-box, .VideoAnswerPlayer, [data-video-id]";
var answerHasVideo = (answer) => !!(answer.attachment?.video || /